Implemented kb shortcuts

This commit is contained in:
lucic71 2022-06-28 19:40:51 +03:00
parent 704d81fe91
commit 87f174c728
6 changed files with 160 additions and 38 deletions

View File

@ -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

View File

@ -17,5 +17,6 @@
#define SCANCODE_RSHIFT 0X36
#define SCANCODE_ALT 0X38
#define SCANCODE_CAPS 0x3A
#define SCANCODE_BACKSPACE 0x0E
#endif

View File

@ -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));
}

View File

@ -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

View File

@ -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);
}

View File

@ -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;
}