Implemented kb shortcuts
This commit is contained in:
parent
704d81fe91
commit
87f174c728
|
@ -6,6 +6,7 @@
|
|||
/*
|
||||
* kb_init:
|
||||
* Initializes the keyboard module and registers the IRQ.
|
||||
* It alsor registers some keyboard shortcuts.
|
||||
*
|
||||
* Currently this drive only supports PS2 keyboards with
|
||||
* scan code set 1.
|
||||
|
@ -14,35 +15,4 @@
|
|||
|
||||
void kb_init(void);
|
||||
|
||||
/*
|
||||
* kb_shortcut_struct:
|
||||
* Data type used to register a keyboard shortcut.
|
||||
*
|
||||
*/
|
||||
|
||||
struct kb_shortcut_struct {
|
||||
|
||||
uint8_t scancode;
|
||||
uint8_t keystate;
|
||||
void (*handler) (void *);
|
||||
void *arg;
|
||||
|
||||
};
|
||||
|
||||
typedef struct kb_shortcut_struct kb_shortcut_t;
|
||||
|
||||
/*
|
||||
* register_shortcut:
|
||||
* Registers a keyboard shortcut.
|
||||
*
|
||||
* @param scancode - Scancode for shortcut
|
||||
* @param keystate - Keystate for shortcut
|
||||
* @param handler - Handler routine for shortcut
|
||||
* @param arg - Argument for handler
|
||||
*
|
||||
*/
|
||||
|
||||
int register_shortcut(uint8_t scancode, uint8_t keystate,
|
||||
void (*handler) (void *), void *arg);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -17,5 +17,6 @@
|
|||
#define SCANCODE_RSHIFT 0X36
|
||||
#define SCANCODE_ALT 0X38
|
||||
#define SCANCODE_CAPS 0x3A
|
||||
#define SCANCODE_BACKSPACE 0x0E
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "kernel/kb.h"
|
||||
#include "kb_tables.h"
|
||||
#include "kb_codes.h"
|
||||
#include "kb_shortcut.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
@ -19,10 +20,14 @@
|
|||
uint8_t keycode[KEYCODE_TABLE_SIZE];
|
||||
uint8_t keyshift[KEYCODE_TABLE_SIZE];
|
||||
|
||||
/* TO BE IMPLEMENTED */
|
||||
/*
|
||||
* kb_shortcut - Table containing shortcuts
|
||||
* kb_shortcut_ptr - Index pointer to an available entry
|
||||
*
|
||||
*/
|
||||
|
||||
__attribute__ ((unused)) kb_shortcut_t kb_shortcut[SHORTCUT_TABLE_SIZE];
|
||||
__attribute__ ((unused)) size_t kb_shortcut_ptr;
|
||||
kb_shortcut_t kb_shortcut[SHORTCUT_TABLE_SIZE];
|
||||
size_t kb_shortcut_ptr;
|
||||
|
||||
/*
|
||||
* keystate:
|
||||
|
@ -93,7 +98,11 @@ static inline int _is_pressed(uint8_t keystate) {
|
|||
*
|
||||
*/
|
||||
|
||||
static inline int _is_backspace(uint8_t scancode) { return scancode == 0x0E; }
|
||||
static inline int _is_backspace(uint8_t scancode) {
|
||||
|
||||
return scancode == SCANCODE_BACKSPACE;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* _is_sequence_released:
|
||||
|
@ -107,8 +116,9 @@ static inline int _is_backspace(uint8_t scancode) { return scancode == 0x0E; }
|
|||
static inline int _is_sequence_released(uint8_t scancode,
|
||||
uint8_t prev_scancode) {
|
||||
|
||||
return ((scancode & 0x80) && !(prev_scancode & 0x80) &&
|
||||
((scancode & 0x7F) == prev_scancode));
|
||||
return
|
||||
((scancode & SCANCODE_RELEASED) && !(prev_scancode & SCANCODE_RELEASED)
|
||||
&& ((scancode & ~SCANCODE_RELEASED) == prev_scancode));
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
#ifndef KB_SHORTCUT_H_
|
||||
#define KB_SHORTCUT_H_
|
||||
|
||||
/* Typedef for shortcut handler routine. */
|
||||
|
||||
typedef void (* shortcut_handler_t) (void *);
|
||||
|
||||
/*
|
||||
* kb_shortcut_struct:
|
||||
* Data type used to register a keyboard shortcut.
|
||||
*
|
||||
*/
|
||||
|
||||
struct kb_shortcut_struct {
|
||||
|
||||
uint8_t scancode;
|
||||
uint8_t keystate;
|
||||
shortcut_handler_t handler;
|
||||
void *arg;
|
||||
|
||||
};
|
||||
|
||||
typedef struct kb_shortcut_struct kb_shortcut_t;
|
||||
|
||||
/*
|
||||
* _register_shortcut:
|
||||
* Registers a keyboard shortcut.
|
||||
*
|
||||
* @param scancode - Scancode for shortcut
|
||||
* @param keystate - Keystate for shortcut
|
||||
* @param handler - Handler routine for shortcut
|
||||
* @param arg - Argument for handler
|
||||
*
|
||||
* @return - 0 if successful
|
||||
* 1 else
|
||||
*
|
||||
*/
|
||||
|
||||
int _register_shortcut(uint8_t scancode, uint8_t keystate,
|
||||
shortcut_handler_t handler, void *arg);
|
||||
|
||||
/*
|
||||
* _execute_shortcut:
|
||||
* Finds and executes a shortcut.
|
||||
*
|
||||
* @param scancode - Scancode for shortcut
|
||||
* @param keystate - Keystate for shortcut
|
||||
*
|
||||
* @return - 0 if successful
|
||||
* 1 else
|
||||
*
|
||||
*/
|
||||
|
||||
int _execute_shortcut(uint8_t scancode, uint8_t keystate);
|
||||
|
||||
#endif
|
|
@ -1,7 +1,9 @@
|
|||
#include "kernel/kb.h"
|
||||
#include "kernel/screen.h"
|
||||
#include "kernel/log.h"
|
||||
|
||||
#include "kb_internals.h"
|
||||
#include "kb_shortcut.h"
|
||||
|
||||
#include "i386/context.h"
|
||||
#include "i386/irq.h"
|
||||
|
@ -9,7 +11,6 @@
|
|||
#include "lib/memio.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* kb_intrpt_handler:
|
||||
|
@ -19,6 +20,10 @@
|
|||
* update the keystate and convert a current scancode if its corresponding
|
||||
* key has not yet been released.
|
||||
*
|
||||
* Aftter the _is_sequence_released check, the routine checks if there is
|
||||
* and shortcut associated with the current scancode and keystate, if so
|
||||
* it executes it and returns.
|
||||
*
|
||||
* It also supports special characters, ex: backspace.
|
||||
*
|
||||
*/
|
||||
|
@ -37,6 +42,9 @@ void kb_intrpt_handler(__attribute__ ((unused)) context_t context) {
|
|||
|
||||
}
|
||||
|
||||
if (!_execute_shortcut(scancode, keystate))
|
||||
return;
|
||||
|
||||
uint8_t asciicode = _to_ascii(scancode);
|
||||
|
||||
if (_is_backspace(scancode))
|
||||
|
@ -54,6 +62,7 @@ void kb_intrpt_handler(__attribute__ ((unused)) context_t context) {
|
|||
* --------
|
||||
*
|
||||
* Fill the translation tables and register the keyboard interrupt.
|
||||
* Register shortcuts.
|
||||
*
|
||||
* keycode and keyshift will be filled with the default value 0xFF. Later,
|
||||
* keycode will be filled with the corresponding ascii codes for each
|
||||
|
@ -148,6 +157,9 @@ void kb_init(void) {
|
|||
keyshift['.'] = '>';
|
||||
keyshift['/'] = '?';
|
||||
|
||||
_register_shortcut(SCANCODE_BACKSPACE, KEYSTATE_CTRL_PRESSED,
|
||||
reg_dump, (void *) 0);
|
||||
|
||||
register_irq(IRQ1, kb_intrpt_handler);
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
#include "kb_internals.h"
|
||||
|
||||
#include "kb_codes.h"
|
||||
|
||||
/*
|
||||
* _register_shortcut:
|
||||
* -------------------
|
||||
*
|
||||
* Make sure that PRESSED bit is set in keystate. If there is already a
|
||||
* handler for the same scancode and keystate, update its handler routine
|
||||
* and its handler routine argument.
|
||||
*
|
||||
* Otherwise put the handler on the next free position. THe routine returns
|
||||
* a positive number if an error occurs.
|
||||
*
|
||||
*/
|
||||
|
||||
int _register_shortcut(uint8_t scancode, uint8_t keystate,
|
||||
void (*handler) (void *), void *arg) {
|
||||
|
||||
keystate |= KEYSTATE_PRESSED;
|
||||
|
||||
size_t i = 0;
|
||||
for ( ; i < kb_shortcut_ptr; i++)
|
||||
if (kb_shortcut[i].scancode == scancode &&
|
||||
kb_shortcut[i].keystate == keystate)
|
||||
break;
|
||||
|
||||
if (i < kb_shortcut_ptr) {
|
||||
|
||||
kb_shortcut[i].handler = handler;
|
||||
kb_shortcut[i].arg = arg;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
if (kb_shortcut_ptr == SHORTCUT_TABLE_SIZE)
|
||||
// TODO: a robust error handler
|
||||
return 1;
|
||||
|
||||
kb_shortcut[kb_shortcut_ptr] =
|
||||
(kb_shortcut_t) {scancode, keystate, handler, arg};
|
||||
|
||||
kb_shortcut_ptr++;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* _execute_shortcut:
|
||||
* ------------------
|
||||
*
|
||||
* Find the corresponding handler for scancode and keystate and execute it.
|
||||
*
|
||||
*/
|
||||
|
||||
int _execute_shortcut(uint8_t scancode, uint8_t keystate) {
|
||||
|
||||
size_t i = 0;
|
||||
for ( ; i < kb_shortcut_ptr; i++)
|
||||
if (kb_shortcut[i].scancode == scancode &&
|
||||
kb_shortcut[i].keystate == keystate)
|
||||
break;
|
||||
|
||||
if (i < kb_shortcut_ptr && kb_shortcut[i].handler) {
|
||||
kb_shortcut[i].handler(kb_shortcut[i].arg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
Loading…
Reference in New Issue