diff options
-rw-r--r-- | drivers/char/keyboard.c | 278 |
1 files changed, 147 insertions, 131 deletions
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 157f23ad434f..54109dc9240c 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -133,7 +133,7 @@ static struct input_handler kbd_handler; static DEFINE_SPINLOCK(kbd_event_lock); 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 bool dead_key_next; static int npadch = -1; /* -1 or number assembled on pad */ static unsigned int diacr; static char rep; /* flag telling character repeat */ @@ -345,8 +345,8 @@ static void to_utf8(struct vc_data *vc, uint c) /* 110***** 10****** */ put_queue(vc, 0xc0 | (c >> 6)); put_queue(vc, 0x80 | (c & 0x3f)); - } else if (c < 0x10000) { - if (c >= 0xD800 && c < 0xE000) + } else if (c < 0x10000) { + if (c >= 0xD800 && c < 0xE000) return; if (c == 0xFFFF) return; @@ -354,7 +354,7 @@ static void to_utf8(struct vc_data *vc, uint c) put_queue(vc, 0xe0 | (c >> 12)); put_queue(vc, 0x80 | ((c >> 6) & 0x3f)); put_queue(vc, 0x80 | (c & 0x3f)); - } else if (c < 0x110000) { + } else if (c < 0x110000) { /* 11110*** 10****** 10****** 10****** */ put_queue(vc, 0xf0 | (c >> 18)); put_queue(vc, 0x80 | ((c >> 12) & 0x3f)); @@ -453,6 +453,7 @@ static void fn_enter(struct vc_data *vc) } diacr = 0; } + put_queue(vc, 13); if (vc_kbd_mode(kbd, VC_CRLF)) put_queue(vc, 10); @@ -462,6 +463,7 @@ static void fn_caps_toggle(struct vc_data *vc) { if (rep) return; + chg_vc_kbd_led(kbd, VC_CAPSLOCK); } @@ -469,12 +471,14 @@ static void fn_caps_on(struct vc_data *vc) { if (rep) return; + set_vc_kbd_led(kbd, VC_CAPSLOCK); } static void fn_show_ptregs(struct vc_data *vc) { struct pt_regs *regs = get_irq_regs(); + if (regs) show_regs(regs); } @@ -499,7 +503,7 @@ static void fn_hold(struct vc_data *vc) static void fn_num(struct vc_data *vc) { - if (vc_kbd_mode(kbd,VC_APPLIC)) + if (vc_kbd_mode(kbd, VC_APPLIC)) applkey(vc, 'P', 1); else fn_bare_num(vc); @@ -594,7 +598,7 @@ static void fn_boot_it(struct vc_data *vc) static void fn_compose(struct vc_data *vc) { - dead_key_next = 1; + dead_key_next = true; } static void fn_spawn_con(struct vc_data *vc) @@ -653,7 +657,7 @@ static void k_unicode(struct vc_data *vc, unsigned int value, char up_flag) value = handle_diacr(vc, value); if (dead_key_next) { - dead_key_next = 0; + dead_key_next = false; diacr = value; return; } @@ -675,6 +679,7 @@ static void k_deadunicode(struct vc_data *vc, unsigned int value, char up_flag) { if (up_flag) return; + diacr = (diacr ? handle_diacr(vc, value) : value); } @@ -694,25 +699,24 @@ static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag) static void k_dead(struct vc_data *vc, unsigned char value, char up_flag) { static const unsigned char ret_diacr[NR_DEAD] = {'`', '\'', '^', '~', '"', ',' }; - value = ret_diacr[value]; - k_deadunicode(vc, value, up_flag); + + k_deadunicode(vc, ret_diacr[value], up_flag); } static void k_cons(struct vc_data *vc, unsigned char value, char up_flag) { if (up_flag) return; + set_console(value); } static void k_fn(struct vc_data *vc, unsigned char value, char up_flag) { - unsigned v; - if (up_flag) return; - v = value; - if (v < ARRAY_SIZE(func_table)) { + + if ((unsigned)value < ARRAY_SIZE(func_table)) { if (func_table[value]) puts_queue(vc, func_table[value]); } else @@ -725,6 +729,7 @@ static void k_cur(struct vc_data *vc, unsigned char value, char up_flag) if (up_flag) return; + applkey(vc, cur_chars[value], vc_kbd_mode(kbd, VC_CKMODE)); } @@ -742,43 +747,45 @@ static void k_pad(struct vc_data *vc, unsigned char value, char up_flag) return; } - if (!vc_kbd_led(kbd, VC_NUMLOCK)) + if (!vc_kbd_led(kbd, VC_NUMLOCK)) { + switch (value) { - case KVAL(K_PCOMMA): - case KVAL(K_PDOT): - k_fn(vc, KVAL(K_REMOVE), 0); - return; - case KVAL(K_P0): - k_fn(vc, KVAL(K_INSERT), 0); - return; - case KVAL(K_P1): - k_fn(vc, KVAL(K_SELECT), 0); - return; - case KVAL(K_P2): - k_cur(vc, KVAL(K_DOWN), 0); - return; - case KVAL(K_P3): - k_fn(vc, KVAL(K_PGDN), 0); - return; - case KVAL(K_P4): - k_cur(vc, KVAL(K_LEFT), 0); - return; - case KVAL(K_P6): - k_cur(vc, KVAL(K_RIGHT), 0); - return; - case KVAL(K_P7): - k_fn(vc, KVAL(K_FIND), 0); - return; - case KVAL(K_P8): - k_cur(vc, KVAL(K_UP), 0); - return; - case KVAL(K_P9): - k_fn(vc, KVAL(K_PGUP), 0); - return; - case KVAL(K_P5): - applkey(vc, 'G', vc_kbd_mode(kbd, VC_APPLIC)); - return; + case KVAL(K_PCOMMA): + case KVAL(K_PDOT): + k_fn(vc, KVAL(K_REMOVE), 0); + return; + case KVAL(K_P0): + k_fn(vc, KVAL(K_INSERT), 0); + return; + case KVAL(K_P1): + k_fn(vc, KVAL(K_SELECT), 0); + return; + case KVAL(K_P2): + k_cur(vc, KVAL(K_DOWN), 0); + return; + case KVAL(K_P3): + k_fn(vc, KVAL(K_PGDN), 0); + return; + case KVAL(K_P4): + k_cur(vc, KVAL(K_LEFT), 0); + return; + case KVAL(K_P6): + k_cur(vc, KVAL(K_RIGHT), 0); + return; + case KVAL(K_P7): + k_fn(vc, KVAL(K_FIND), 0); + return; + case KVAL(K_P8): + k_cur(vc, KVAL(K_UP), 0); + return; + case KVAL(K_P9): + k_fn(vc, KVAL(K_PGUP), 0); + return; + case KVAL(K_P5): + applkey(vc, 'G', vc_kbd_mode(kbd, VC_APPLIC)); + return; } + } put_queue(vc, pad_chars[value]); if (value == KVAL(K_PENTER) && vc_kbd_mode(kbd, VC_CRLF)) @@ -864,6 +871,7 @@ static void k_lock(struct vc_data *vc, unsigned char value, char up_flag) { if (up_flag || rep) return; + chg_vc_kbd_lock(kbd, value); } @@ -872,6 +880,7 @@ static void k_slock(struct vc_data *vc, unsigned char value, char up_flag) k_shift(vc, value, up_flag); if (up_flag || rep) return; + chg_vc_kbd_slock(kbd, value); /* try to make Alt, oops, AltGr and such work */ if (!key_maps[kbd->lockstate ^ kbd->slockstate]) { @@ -909,7 +918,7 @@ static void k_brlcommit(struct vc_data *vc, unsigned int pattern, char up_flag) static void k_brl(struct vc_data *vc, unsigned char value, char up_flag) { - static unsigned pressed,committing; + static unsigned pressed, committing; static unsigned long releasestart; if (kbd->kbdmode != VC_UNICODE) { @@ -926,32 +935,28 @@ static void k_brl(struct vc_data *vc, unsigned char value, char up_flag) if (value > 8) return; - if (up_flag) { - if (brl_timeout) { - if (!committing || - time_after(jiffies, - releasestart + msecs_to_jiffies(brl_timeout))) { - committing = pressed; - releasestart = jiffies; - } - pressed &= ~(1 << (value - 1)); - if (!pressed) { - if (committing) { - k_brlcommit(vc, committing, 0); - committing = 0; - } - } - } else { - if (committing) { - k_brlcommit(vc, committing, 0); - committing = 0; - } - pressed &= ~(1 << (value - 1)); - } - } else { + if (!up_flag) { pressed |= 1 << (value - 1); if (!brl_timeout) committing = pressed; + } else if (brl_timeout) { + if (!committing || + time_after(jiffies, + releasestart + msecs_to_jiffies(brl_timeout))) { + committing = pressed; + releasestart = jiffies; + } + pressed &= ~(1 << (value - 1)); + if (!pressed && committing) { + k_brlcommit(vc, committing, 0); + committing = 0; + } + } else { + if (committing) { + k_brlcommit(vc, committing, 0); + committing = 0; + } + pressed &= ~(1 << (value - 1)); } } @@ -972,6 +977,7 @@ void setledstate(struct kbd_struct *kbd, unsigned int led) kbd->ledmode = LED_SHOW_IOCTL; } else kbd->ledmode = LED_SHOW_FLAGS; + set_leds(); } @@ -1059,7 +1065,7 @@ static const unsigned short x86_keycodes[256] = 332,340,365,342,343,344,345,346,356,270,341,368,369,370,371,372 }; #ifdef CONFIG_SPARC -static int sparc_l1_a_state = 0; +static int sparc_l1_a_state; extern void sun_do_break(void); #endif @@ -1069,53 +1075,54 @@ static int emulate_raw(struct vc_data *vc, unsigned int keycode, int code; switch (keycode) { - case KEY_PAUSE: - put_queue(vc, 0xe1); - put_queue(vc, 0x1d | up_flag); - put_queue(vc, 0x45 | up_flag); - break; - case KEY_HANGEUL: - if (!up_flag) - put_queue(vc, 0xf2); - break; + case KEY_PAUSE: + put_queue(vc, 0xe1); + put_queue(vc, 0x1d | up_flag); + put_queue(vc, 0x45 | up_flag); + break; - case KEY_HANJA: - if (!up_flag) - put_queue(vc, 0xf1); - break; + case KEY_HANGEUL: + if (!up_flag) + put_queue(vc, 0xf2); + break; - case KEY_SYSRQ: - /* - * Real AT keyboards (that's what we're trying - * to emulate here emit 0xe0 0x2a 0xe0 0x37 when - * pressing PrtSc/SysRq alone, but simply 0x54 - * when pressing Alt+PrtSc/SysRq. - */ - if (test_bit(KEY_LEFTALT, key_down) || - test_bit(KEY_RIGHTALT, key_down)) { - put_queue(vc, 0x54 | up_flag); - } else { - put_queue(vc, 0xe0); - put_queue(vc, 0x2a | up_flag); - put_queue(vc, 0xe0); - put_queue(vc, 0x37 | up_flag); - } - break; + case KEY_HANJA: + if (!up_flag) + put_queue(vc, 0xf1); + break; - default: - if (keycode > 255) - return -1; + case KEY_SYSRQ: + /* + * Real AT keyboards (that's what we're trying + * to emulate here emit 0xe0 0x2a 0xe0 0x37 when + * pressing PrtSc/SysRq alone, but simply 0x54 + * when pressing Alt+PrtSc/SysRq. + */ + if (test_bit(KEY_LEFTALT, key_down) || + test_bit(KEY_RIGHTALT, key_down)) { + put_queue(vc, 0x54 | up_flag); + } else { + put_queue(vc, 0xe0); + put_queue(vc, 0x2a | up_flag); + put_queue(vc, 0xe0); + put_queue(vc, 0x37 | up_flag); + } + break; - code = x86_keycodes[keycode]; - if (!code) - return -1; + default: + if (keycode > 255) + return -1; - if (code & 0x100) - put_queue(vc, 0xe0); - put_queue(vc, (code & 0x7f) | up_flag); + code = x86_keycodes[keycode]; + if (!code) + return -1; - break; + if (code & 0x100) + put_queue(vc, 0xe0); + put_queue(vc, (code & 0x7f) | up_flag); + + break; } return 0; @@ -1138,6 +1145,7 @@ static int emulate_raw(struct vc_data *vc, unsigned int keycode, unsigned char u static void kbd_rawcode(unsigned char data) { struct vc_data *vc = vc_cons[fg_console].d; + kbd = kbd_table + vc->vc_num; if (kbd->kbdmode == VC_RAW) put_queue(vc, data); @@ -1147,10 +1155,12 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) { struct vc_data *vc = vc_cons[fg_console].d; unsigned short keysym, *key_map; - unsigned char type, raw_mode; + unsigned char type; + bool raw_mode; struct tty_struct *tty; int shift_final; struct keyboard_notifier_param param = { .vc = vc, .value = keycode, .down = down }; + int rc; tty = vc->vc_tty; @@ -1168,7 +1178,8 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) rep = (down == 2); - if ((raw_mode = (kbd->kbdmode == VC_RAW)) && !hw_raw) + raw_mode = (kbd->kbdmode == VC_RAW); + if (raw_mode && !hw_raw) if (emulate_raw(vc, keycode, !down << 7)) if (keycode < BTN_MISC && printk_ratelimit()) pr_warning("can't emulate rawmode for keycode %d\n", @@ -1176,7 +1187,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) #ifdef CONFIG_SPARC if (keycode == KEY_A && sparc_l1_a_state) { - sparc_l1_a_state = 0; + sparc_l1_a_state = false; sun_do_break(); } #endif @@ -1198,7 +1209,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) put_queue(vc, (keycode >> 7) | 0x80); put_queue(vc, keycode | 0x80); } - raw_mode = 1; + raw_mode = true; } if (down) @@ -1221,29 +1232,32 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) param.ledstate = kbd->ledflagstate; key_map = key_maps[shift_final]; - 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); + rc = atomic_notifier_call_chain(&keyboard_notifier_list, + KBD_KEYCODE, ¶m); + if (rc == NOTIFY_STOP || !key_map) { + atomic_notifier_call_chain(&keyboard_notifier_list, + KBD_UNBOUND_KEYCODE, ¶m); compute_shiftstate(); kbd->slockstate = 0; return; } - if (keycode >= NR_KEYS) - if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8) - keysym = U(K(KT_BRL, keycode - KEY_BRL_DOT1 + 1)); - else - return; - else + if (keycode < NR_KEYS) keysym = key_map[keycode]; + else if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8) + keysym = U(K(KT_BRL, keycode - KEY_BRL_DOT1 + 1)); + else + return; 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); + rc = atomic_notifier_call_chain(&keyboard_notifier_list, + KBD_UNICODE, ¶m); + if (rc != NOTIFY_STOP) + if (down && !raw_mode) + to_utf8(vc, keysym); return; } @@ -1257,9 +1271,11 @@ 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) + param.value = keysym; + rc = atomic_notifier_call_chain(&keyboard_notifier_list, + KBD_KEYSYM, ¶m); + if (rc == NOTIFY_STOP) return; if (raw_mode && type != KT_SPEC && type != KT_SHIFT) |