Mon 14 Oct 23:06:38 CEST 2024
This commit is contained in:
parent
0a4c242310
commit
37615a46d7
163
kernel/keyboard.c
Normal file
163
kernel/keyboard.c
Normal file
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
Copyright (C) 2015-2019 The University of Notre Dame
|
||||
This software is distributed under the GNU General Public License.
|
||||
See the file LICENSE for details.
|
||||
*/
|
||||
|
||||
#include "console.h"
|
||||
#include "ioports.h"
|
||||
#include "interrupt.h"
|
||||
#include "kernel/ascii.h"
|
||||
#include "kernelcore.h"
|
||||
#include "event_queue.h"
|
||||
|
||||
#define KEYBOARD_PORT 0x60
|
||||
|
||||
#define KEYMAP_SHIFT 1
|
||||
#define KEYMAP_ALT 2
|
||||
#define KEYMAP_CTRL 3
|
||||
#define KEYMAP_CAPSLOCK 4
|
||||
#define KEYMAP_NUMLOCK 5
|
||||
#define KEYMAP_ALPHA 6
|
||||
#define KEYMAP_NUMPAD 8
|
||||
#define KEYMAP_ALTGR 9
|
||||
|
||||
/* sent before certain keys such as up, down, left, or right. */
|
||||
#define KEYCODE_EXTRA (uint8_t)0xE0
|
||||
#define KEYCODE_UP (uint8_t)0x48
|
||||
#define KEYCODE_DOWN (uint8_t)0x42
|
||||
#define KEYCODE_LEFT (uint8_t)0x4B
|
||||
#define KEYCODE_RIGHT (uint8_t)0x4D
|
||||
|
||||
#define BUFFER_SIZE 256
|
||||
|
||||
struct keymap {
|
||||
char normal;
|
||||
char shifted;
|
||||
char ctrled;
|
||||
char special;
|
||||
};
|
||||
|
||||
static struct keymap keymap[] = {
|
||||
#include "keymap.de.pc.c"
|
||||
};
|
||||
|
||||
static int shift_mode = 0;
|
||||
static int alt_mode = 0;
|
||||
static int altgr_mode = 0;
|
||||
static int ctrl_mode = 0;
|
||||
static int capslock_mode = 0;
|
||||
static int numlock_mode = 0;
|
||||
|
||||
static void keyboard_interrupt_l2( uint8_t code )
|
||||
{
|
||||
int direction;
|
||||
int event;
|
||||
|
||||
if(code & 0x80) {
|
||||
direction = 0;
|
||||
event = EVENT_KEY_UP;
|
||||
code = code & 0x7f;
|
||||
} else {
|
||||
direction = 1;
|
||||
event = EVENT_KEY_DOWN;
|
||||
}
|
||||
|
||||
struct keymap *k = &keymap[code];
|
||||
if(k->special == KEYMAP_SHIFT) {
|
||||
shift_mode = direction;
|
||||
} else if(k->special == KEYMAP_ALT) {
|
||||
alt_mode = direction;
|
||||
} else if(k->special == KEYMAP_ALTGR) {
|
||||
// @blab+ ALTGR hack
|
||||
altgr_mode = direction;
|
||||
} else if(k->special == KEYMAP_CTRL) {
|
||||
ctrl_mode = direction;
|
||||
} else if(k->special == KEYMAP_CAPSLOCK) {
|
||||
if(direction == 0) capslock_mode = !capslock_mode;
|
||||
} else if(k->special == KEYMAP_NUMLOCK) {
|
||||
if(direction == 0) numlock_mode = !numlock_mode;
|
||||
} else {
|
||||
if(direction && ctrl_mode && alt_mode && k->normal == ASCII_DEL) {
|
||||
reboot();
|
||||
} else if(capslock_mode) {
|
||||
if(k->special==KEYMAP_ALPHA && !shift_mode) {
|
||||
event_queue_post_root(event,k->shifted,0,0);
|
||||
} else {
|
||||
event_queue_post_root(event,k->normal,0,0);
|
||||
}
|
||||
} else if(numlock_mode) {
|
||||
if(k->special==KEYMAP_NUMPAD && !shift_mode) {
|
||||
event_queue_post_root(event,k->shifted,0,0);
|
||||
} else {
|
||||
event_queue_post_root(event,k->normal,0,0);
|
||||
}
|
||||
} else if(shift_mode) {
|
||||
event_queue_post_root(event,k->shifted,0,0);
|
||||
} else if(ctrl_mode) {
|
||||
event_queue_post_root(event,k->ctrled,0,0);
|
||||
} else if(altgr_mode) {
|
||||
// @blab+ ALTGR hack
|
||||
event_queue_post_root(event,k->special,0,0);
|
||||
} else {
|
||||
event_queue_post_root(event,k->normal,0,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int expect_extra = 0;
|
||||
|
||||
static void keyboard_interrupt(int i, int intr_code)
|
||||
{
|
||||
uint8_t code = inb(KEYBOARD_PORT);
|
||||
uint8_t c = KEY_INVALID;
|
||||
|
||||
// printf("[%x]",code);
|
||||
|
||||
if(code == KEYCODE_EXTRA) {
|
||||
expect_extra = 1;
|
||||
return;
|
||||
} else if(expect_extra) {
|
||||
expect_extra = 0;
|
||||
switch(code) {
|
||||
// @blab+ ALTGR hack
|
||||
case 0x38:
|
||||
case 0xb8:
|
||||
// keymap: use next reserved row (normally nulled)
|
||||
// {KEY_INVALID, KEY_INVALID, KEY_INVALID, KEYMAP_ALT},#
|
||||
// ..
|
||||
// {KEY_INVALID, KEY_INVALID, KEY_INVALID, KEYMAP_ALTGR},
|
||||
c = code+3;
|
||||
break;
|
||||
case KEYCODE_UP:
|
||||
c = KEY_UP;
|
||||
break;
|
||||
case KEYCODE_DOWN:
|
||||
c = KEY_DOWN;
|
||||
break;
|
||||
case KEYCODE_LEFT:
|
||||
c = KEY_LEFT;
|
||||
break;
|
||||
case KEYCODE_RIGHT:
|
||||
c = KEY_RIGHT;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
c = code;
|
||||
}
|
||||
|
||||
keyboard_interrupt_l2(c);
|
||||
}
|
||||
|
||||
void keyboard_init()
|
||||
{
|
||||
interrupt_register(33, keyboard_interrupt);
|
||||
interrupt_enable(33);
|
||||
printf("keyboard: ready\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user