aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2015-06-06 14:44:39 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2015-06-16 17:59:46 -0400
commiteeb64c14275e52740d6410632e62e0ad9b88ca70 (patch)
tree22b808cc11a63db51f10464613b6d1ed93b6536c
parent5235552273e6b68abbed3b3047af6344e2e60c2c (diff)
tty/vt/keyboard: define LED triggers for VT keyboard lock states
In addition to defining triggers for VT LED states, let's define triggers for VT keyboard lock states, such as "kbd-shiftlock", "kbd-altgrlock", etc. This permits to fix #7063 from userland by using a modifier to implement proper CapsLock behavior and have the keyboard caps lock led show that modifier state. Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org> Tested-by: Pavel Machek <pavel@ucw.cz> Acked-by: Pavel Machek <pavel@ucw.cz> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
-rw-r--r--drivers/tty/vt/keyboard.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index fc080bf1c4d2..6f0336fff501 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -130,7 +130,7 @@ static char rep; /* flag telling character repeat */
130 130
131static int shift_state = 0; 131static int shift_state = 0;
132 132
133static unsigned char ledstate = 0xff; /* undefined */ 133static unsigned int ledstate = -1U; /* undefined */
134static unsigned char ledioctl; 134static unsigned char ledioctl;
135 135
136/* 136/*
@@ -975,7 +975,7 @@ static void kbd_led_trigger_activate(struct led_classdev *cdev)
975 container_of(cdev->trigger, struct kbd_led_trigger, trigger); 975 container_of(cdev->trigger, struct kbd_led_trigger, trigger);
976 976
977 tasklet_disable(&keyboard_tasklet); 977 tasklet_disable(&keyboard_tasklet);
978 if (ledstate != 0xff) 978 if (ledstate != -1U)
979 led_trigger_event(&trigger->trigger, 979 led_trigger_event(&trigger->trigger,
980 ledstate & trigger->mask ? 980 ledstate & trigger->mask ?
981 LED_FULL : LED_OFF); 981 LED_FULL : LED_OFF);
@@ -990,11 +990,23 @@ static void kbd_led_trigger_activate(struct led_classdev *cdev)
990 .mask = BIT(_led_bit), \ 990 .mask = BIT(_led_bit), \
991 } 991 }
992 992
993#define KBD_LOCKSTATE_TRIGGER(_led_bit, _name) \
994 KBD_LED_TRIGGER((_led_bit) + 8, _name)
995
993static struct kbd_led_trigger kbd_led_triggers[] = { 996static struct kbd_led_trigger kbd_led_triggers[] = {
994 KBD_LED_TRIGGER(VC_SCROLLOCK, "kbd-scrollock"), 997 KBD_LED_TRIGGER(VC_SCROLLOCK, "kbd-scrollock"),
995 KBD_LED_TRIGGER(VC_NUMLOCK, "kbd-numlock"), 998 KBD_LED_TRIGGER(VC_NUMLOCK, "kbd-numlock"),
996 KBD_LED_TRIGGER(VC_CAPSLOCK, "kbd-capslock"), 999 KBD_LED_TRIGGER(VC_CAPSLOCK, "kbd-capslock"),
997 KBD_LED_TRIGGER(VC_KANALOCK, "kbd-kanalock"), 1000 KBD_LED_TRIGGER(VC_KANALOCK, "kbd-kanalock"),
1001
1002 KBD_LOCKSTATE_TRIGGER(VC_SHIFTLOCK, "kbd-shiftlock"),
1003 KBD_LOCKSTATE_TRIGGER(VC_ALTGRLOCK, "kbd-altgrlock"),
1004 KBD_LOCKSTATE_TRIGGER(VC_CTRLLOCK, "kbd-ctrllock"),
1005 KBD_LOCKSTATE_TRIGGER(VC_ALTLOCK, "kbd-altlock"),
1006 KBD_LOCKSTATE_TRIGGER(VC_SHIFTLLOCK, "kbd-shiftllock"),
1007 KBD_LOCKSTATE_TRIGGER(VC_SHIFTRLOCK, "kbd-shiftrlock"),
1008 KBD_LOCKSTATE_TRIGGER(VC_CTRLLLOCK, "kbd-ctrlllock"),
1009 KBD_LOCKSTATE_TRIGGER(VC_CTRLRLOCK, "kbd-ctrlrlock"),
998}; 1010};
999 1011
1000static void kbd_propagate_led_state(unsigned int old_state, 1012static void kbd_propagate_led_state(unsigned int old_state,
@@ -1073,7 +1085,7 @@ static void kbd_init_leds(void)
1073 */ 1085 */
1074static unsigned char getledstate(void) 1086static unsigned char getledstate(void)
1075{ 1087{
1076 return ledstate; 1088 return ledstate & 0xff;
1077} 1089}
1078 1090
1079void setledstate(struct kbd_struct *kb, unsigned int led) 1091void setledstate(struct kbd_struct *kb, unsigned int led)
@@ -1183,11 +1195,12 @@ void vt_kbd_con_stop(int console)
1183 */ 1195 */
1184static void kbd_bh(unsigned long dummy) 1196static void kbd_bh(unsigned long dummy)
1185{ 1197{
1186 unsigned char leds; 1198 unsigned int leds;
1187 unsigned long flags; 1199 unsigned long flags;
1188 1200
1189 spin_lock_irqsave(&led_lock, flags); 1201 spin_lock_irqsave(&led_lock, flags);
1190 leds = getleds(); 1202 leds = getleds();
1203 leds |= (unsigned int)kbd->lockstate << 8;
1191 spin_unlock_irqrestore(&led_lock, flags); 1204 spin_unlock_irqrestore(&led_lock, flags);
1192 1205
1193 if (leds != ledstate) { 1206 if (leds != ledstate) {
@@ -1539,10 +1552,8 @@ static void kbd_start(struct input_handle *handle)
1539{ 1552{
1540 tasklet_disable(&keyboard_tasklet); 1553 tasklet_disable(&keyboard_tasklet);
1541 1554
1542 if (ledstate != 0xff) { 1555 if (ledstate != -1U)
1543 unsigned int state = ledstate; 1556 kbd_update_leds_helper(handle, &ledstate);
1544 kbd_update_leds_helper(handle, &state);
1545 }
1546 1557
1547 tasklet_enable(&keyboard_tasklet); 1558 tasklet_enable(&keyboard_tasklet);
1548} 1559}