/* * Put utf8 character to tty flip buffer. * UTF-8 is defined for words of up to 31 bits, * but we need only 16 bits here */ static void to_utf8(struct tty_port *port, ushort c) { if (c < 0x80) /* 0******* */ kbd_put_queue(port, c); else if (c < 0x800) { /* 110***** 10****** */ kbd_put_queue(port, 0xc0 | (c >> 6)); kbd_put_queue(port, 0x80 | (c & 0x3f)); } else {
/* * Normal character handler. */ static void k_self(struct kbd_data *kbd, unsigned char value) { if (kbd->diacr) value = handle_diacr(kbd, value); kbd_put_queue(kbd->port, value); }
/* * We have a combining character DIACR here, followed by the character CH. * If the combination occurs in the table, return the corresponding value. * Otherwise, if CH is a space or equals DIACR, return DIACR. * Otherwise, conclude that DIACR was not combining after all, * queue it and return CH. */ static unsigned int handle_diacr(struct kbd_data *kbd, unsigned int ch) { int i, d; d = kbd->diacr; kbd->diacr = 0; for (i = 0; i < kbd->accent_table_size; i++) { if (kbd->accent_table[i].diacr == d && kbd->accent_table[i].base == ch) return kbd->accent_table[i].result; } if (ch == ' ' || ch == d) return d; kbd_put_queue(kbd->port, d); return ch; }
void handle_keyboard_event (unsigned char scancode) { unsigned char keycode; /* Convert scancode to keycode */ PRINTF ("scancode %x\n", scancode); if (scancode == 0xe0) { e0 = 1; /* special charakters */ return; } if (e0 == 1) { e0 = 0; /* delete flag */ if (!(((scancode & 0x7F) == 0x38) || /* the right ctrl key */ ((scancode & 0x7F) == 0x1D) || /* the right alt key */ ((scancode & 0x7F) == 0x35) || /* the right '/' key */ ((scancode & 0x7F) == 0x1C))) /* the right enter key */ /* we swallow unknown e0 codes */ return; } /* special cntrl keys */ switch (scancode) { case 0x2A: case 0x36: /* shift pressed */ shift = 1; return; /* do nothing else */ case 0xAA: case 0xB6: /* shift released */ shift = 0; return; /* do nothing else */ case 0x38: /* alt pressed */ alt = 1; return; /* do nothing else */ case 0xB8: /* alt released */ alt = 0; return; /* do nothing else */ case 0x1d: /* ctrl pressed */ ctrl = 1; return; /* do nothing else */ case 0x9d: /* ctrl released */ ctrl = 0; return; /* do nothing else */ case 0x46: /* scrollock pressed */ scroll_lock = ~scroll_lock; kbd_set_leds (); return; /* do nothing else */ case 0x3A: /* capslock pressed */ caps_lock = ~caps_lock; kbd_set_leds (); return; case 0x45: /* numlock pressed */ num_lock = ~num_lock; kbd_set_leds (); return; case 0xC6: /* scroll lock released */ case 0xC5: /* num lock released */ case 0xBA: /* caps lock released */ return; /* just swallow */ } if ((scancode & 0x80) == 0x80) /* key released */ return; /* now, decide which table we need */ if (scancode > (sizeof (kbd_plain_xlate) / sizeof (kbd_plain_xlate[0]))) { /* scancode not in list */ PRINTF ("unkown scancode %X\n", scancode); return; /* swallow it */ } /* setup plain code first */ keycode = kbd_plain_xlate[scancode]; if (caps_lock == 1) { /* caps_lock is pressed, overwrite plain code */ if (scancode > (sizeof (kbd_shift_xlate) / sizeof (kbd_shift_xlate[0]))) { /* scancode not in list */ PRINTF ("unkown caps-locked scancode %X\n", scancode); return; /* swallow it */ } keycode = kbd_shift_xlate[scancode]; if (keycode < 'A') { /* we only want the alphas capital */ keycode = kbd_plain_xlate[scancode]; } } if (shift == 1) { /* shift overwrites caps_lock */ if (scancode > (sizeof (kbd_shift_xlate) / sizeof (kbd_shift_xlate[0]))) { /* scancode not in list */ PRINTF ("unkown shifted scancode %X\n", scancode); return; /* swallow it */ } keycode = kbd_shift_xlate[scancode]; } if (ctrl == 1) { /* ctrl overwrites caps_lock and shift */ if (scancode > (sizeof (kbd_ctrl_xlate) / sizeof (kbd_ctrl_xlate[0]))) { /* scancode not in list */ PRINTF ("unkown ctrl scancode %X\n", scancode); return; /* swallow it */ } keycode = kbd_ctrl_xlate[scancode]; } /* check if valid keycode */ if (keycode == 0xff) { PRINTF ("unkown scancode %X\n", scancode); return; /* swallow unknown codes */ } kbd_put_queue (keycode); PRINTF ("%x\n", keycode); }