X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fchar%2Fkeyboard.c;h=fc54d234507ace68d0470122f8c3dba967b977e5;hb=e58b7dab272ecee09cd7bafb89d6b224cd17bbe3;hp=2ce0af1bd588a0c103cc39b6f25a95a8b734b74e;hpb=2fe83b3ad12d43799af5f3156886eca443a88bac;p=linux-2.6 diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 2ce0af1bd5..fc54d23450 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -38,9 +38,11 @@ #include #include #include +#include #include #include #include +#include extern void ctrl_alt_del(void); @@ -80,7 +82,8 @@ void compute_shiftstate(void); typedef void (k_handler_fn)(struct vc_data *vc, unsigned char value, char up_flag); static k_handler_fn K_HANDLERS; -static k_handler_fn *k_handler[16] = { K_HANDLERS }; +k_handler_fn *k_handler[16] = { K_HANDLERS }; +EXPORT_SYMBOL_GPL(k_handler); #define FN_HANDLERS\ fn_null, fn_enter, fn_show_ptregs, fn_show_mem,\ @@ -126,7 +129,7 @@ int shift_state = 0; */ static struct input_handler kbd_handler; -static unsigned long key_down[NBITS(KEY_MAX)]; /* keyboard key bitmap */ +static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */ static unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */ static int dead_key_next; static int npadch = -1; /* -1 or number assembled on pad */ @@ -158,6 +161,23 @@ static int sysrq_alt_use; #endif static int sysrq_alt; +/* + * Notifier list for console keyboard events + */ +static ATOMIC_NOTIFIER_HEAD(keyboard_notifier_list); + +int register_keyboard_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&keyboard_notifier_list, nb); +} +EXPORT_SYMBOL_GPL(register_keyboard_notifier); + +int unregister_keyboard_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&keyboard_notifier_list, nb); +} +EXPORT_SYMBOL_GPL(unregister_keyboard_notifier); + /* * Translation of scancodes to keycodes. We set them on only the first * keyboard in the list that accepts the scancode and keycode. @@ -403,9 +423,12 @@ static unsigned int handle_diacr(struct vc_data *vc, unsigned int ch) return d; if (kbd->kbdmode == VC_UNICODE) - to_utf8(vc, conv_8bit_to_uni(d)); - else if (d < 0x100) - put_queue(vc, d); + to_utf8(vc, d); + else { + int c = conv_uni_to_8bit(d); + if (c != -1) + put_queue(vc, c); + } return ch; } @@ -417,9 +440,12 @@ static void fn_enter(struct vc_data *vc) { if (diacr) { if (kbd->kbdmode == VC_UNICODE) - to_utf8(vc, conv_8bit_to_uni(diacr)); - else if (diacr < 0x100) - put_queue(vc, diacr); + to_utf8(vc, diacr); + else { + int c = conv_uni_to_8bit(diacr); + if (c != -1) + put_queue(vc, c); + } diacr = 0; } put_queue(vc, 13); @@ -627,9 +653,12 @@ static void k_unicode(struct vc_data *vc, unsigned int value, char up_flag) return; } if (kbd->kbdmode == VC_UNICODE) - to_utf8(vc, conv_8bit_to_uni(value)); - else if (value < 0x100) - put_queue(vc, value); + to_utf8(vc, value); + else { + int c = conv_uni_to_8bit(value); + if (c != -1) + put_queue(vc, c); + } } /* @@ -646,7 +675,12 @@ static void k_deadunicode(struct vc_data *vc, unsigned int value, char up_flag) static void k_self(struct vc_data *vc, unsigned char value, char up_flag) { - k_unicode(vc, value, up_flag); + unsigned int uni; + if (kbd->kbdmode == VC_UNICODE) + uni = value; + else + uni = conv_8bit_to_uni(value); + k_unicode(vc, uni, up_flag); } static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag) @@ -1022,10 +1056,6 @@ static const unsigned short x86_keycodes[256] = 308,310,313,314,315,317,318,319,320,357,322,323,324,325,276,330, 332,340,365,342,343,344,345,346,356,270,341,368,369,370,371,372 }; -#ifdef CONFIG_MAC_EMUMOUSEBTN -extern int mac_hid_mouse_emulate_buttons(int, int, int); -#endif /* CONFIG_MAC_EMUMOUSEBTN */ - #ifdef CONFIG_SPARC static int sparc_l1_a_state = 0; extern void sun_do_break(void); @@ -1119,6 +1149,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) unsigned char type, raw_mode; struct tty_struct *tty; int shift_final; + struct keyboard_notifier_param param = { .vc = vc, .value = keycode, .down = down }; tty = vc->vc_tty; @@ -1206,10 +1237,11 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) return; } - shift_final = (shift_state | kbd->slockstate) ^ kbd->lockstate; + param.shift = shift_final = (shift_state | kbd->slockstate) ^ kbd->lockstate; key_map = key_maps[shift_final]; - if (!key_map) { + if (atomic_notifier_call_chain(&keyboard_notifier_list, KBD_KEYCODE, ¶m) == NOTIFY_STOP || !key_map) { + atomic_notifier_call_chain(&keyboard_notifier_list, KBD_UNBOUND_KEYCODE, ¶m); compute_shiftstate(); kbd->slockstate = 0; return; @@ -1226,6 +1258,9 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) type = KTYP(keysym); if (type < 0xf0) { + param.value = keysym; + if (atomic_notifier_call_chain(&keyboard_notifier_list, KBD_UNICODE, ¶m) == NOTIFY_STOP) + return; if (down && !raw_mode) to_utf8(vc, keysym); return; @@ -1233,9 +1268,6 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) type -= 0xf0; - if (raw_mode && type != KT_SPEC && type != KT_SHIFT) - return; - if (type == KT_LETTER) { type = KT_LATIN; if (vc_kbd_led(kbd, VC_CAPSLOCK)) { @@ -1244,9 +1276,18 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) keysym = key_map[keycode]; } } + param.value = keysym; + + if (atomic_notifier_call_chain(&keyboard_notifier_list, KBD_KEYSYM, ¶m) == NOTIFY_STOP) + return; + + if (raw_mode && type != KT_SPEC && type != KT_SHIFT) + return; (*k_handler[type])(vc, keysym & 0xff, !down); + atomic_notifier_call_chain(&keyboard_notifier_list, KBD_POST_KEYSYM, ¶m); + if (type != KT_SLOCK) kbd->slockstate = 0; } @@ -1336,12 +1377,12 @@ static void kbd_start(struct input_handle *handle) static const struct input_device_id kbd_ids[] = { { .flags = INPUT_DEVICE_ID_MATCH_EVBIT, - .evbit = { BIT(EV_KEY) }, + .evbit = { BIT_MASK(EV_KEY) }, }, { .flags = INPUT_DEVICE_ID_MATCH_EVBIT, - .evbit = { BIT(EV_SND) }, + .evbit = { BIT_MASK(EV_SND) }, }, { }, /* Terminating entry */ @@ -1370,7 +1411,7 @@ int __init kbd_init(void) kbd_table[i].lockstate = KBD_DEFLOCK; kbd_table[i].slockstate = 0; kbd_table[i].modeflags = KBD_DEFMODE; - kbd_table[i].kbdmode = VC_XLATE; + kbd_table[i].kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE; } error = input_register_handler(&kbd_handler);