summaryrefslogtreecommitdiff
path: root/drivers/tty
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2015-06-06 11:44:39 -0700
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2015-06-16 14:59:46 -0700
commiteeb64c14275e52740d6410632e62e0ad9b88ca70 (patch)
tree22b808cc11a63db51f10464613b6d1ed93b6536c /drivers/tty
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>
Diffstat (limited to 'drivers/tty')
-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 */
static int shift_state = 0;
-static unsigned char ledstate = 0xff; /* undefined */
+static unsigned int ledstate = -1U; /* undefined */
static unsigned char ledioctl;
/*
@@ -975,7 +975,7 @@ static void kbd_led_trigger_activate(struct led_classdev *cdev)
container_of(cdev->trigger, struct kbd_led_trigger, trigger);
tasklet_disable(&keyboard_tasklet);
- if (ledstate != 0xff)
+ if (ledstate != -1U)
led_trigger_event(&trigger->trigger,
ledstate & trigger->mask ?
LED_FULL : LED_OFF);
@@ -990,11 +990,23 @@ static void kbd_led_trigger_activate(struct led_classdev *cdev)
.mask = BIT(_led_bit), \
}
+#define KBD_LOCKSTATE_TRIGGER(_led_bit, _name) \
+ KBD_LED_TRIGGER((_led_bit) + 8, _name)
+
static struct kbd_led_trigger kbd_led_triggers[] = {
KBD_LED_TRIGGER(VC_SCROLLOCK, "kbd-scrollock"),
KBD_LED_TRIGGER(VC_NUMLOCK, "kbd-numlock"),
KBD_LED_TRIGGER(VC_CAPSLOCK, "kbd-capslock"),
KBD_LED_TRIGGER(VC_KANALOCK, "kbd-kanalock"),
+
+ KBD_LOCKSTATE_TRIGGER(VC_SHIFTLOCK, "kbd-shiftlock"),
+ KBD_LOCKSTATE_TRIGGER(VC_ALTGRLOCK, "kbd-altgrlock"),
+ KBD_LOCKSTATE_TRIGGER(VC_CTRLLOCK, "kbd-ctrllock"),
+ KBD_LOCKSTATE_TRIGGER(VC_ALTLOCK, "kbd-altlock"),
+ KBD_LOCKSTATE_TRIGGER(VC_SHIFTLLOCK, "kbd-shiftllock"),
+ KBD_LOCKSTATE_TRIGGER(VC_SHIFTRLOCK, "kbd-shiftrlock"),
+ KBD_LOCKSTATE_TRIGGER(VC_CTRLLLOCK, "kbd-ctrlllock"),
+ KBD_LOCKSTATE_TRIGGER(VC_CTRLRLOCK, "kbd-ctrlrlock"),
};
static void kbd_propagate_led_state(unsigned int old_state,
@@ -1073,7 +1085,7 @@ static void kbd_init_leds(void)
*/
static unsigned char getledstate(void)
{
- return ledstate;
+ return ledstate & 0xff;
}
void setledstate(struct kbd_struct *kb, unsigned int led)
@@ -1183,11 +1195,12 @@ void vt_kbd_con_stop(int console)
*/
static void kbd_bh(unsigned long dummy)
{
- unsigned char leds;
+ unsigned int leds;
unsigned long flags;
spin_lock_irqsave(&led_lock, flags);
leds = getleds();
+ leds |= (unsigned int)kbd->lockstate << 8;
spin_unlock_irqrestore(&led_lock, flags);
if (leds != ledstate) {
@@ -1539,10 +1552,8 @@ static void kbd_start(struct input_handle *handle)
{
tasklet_disable(&keyboard_tasklet);
- if (ledstate != 0xff) {
- unsigned int state = ledstate;
- kbd_update_leds_helper(handle, &state);
- }
+ if (ledstate != -1U)
+ kbd_update_leds_helper(handle, &ledstate);
tasklet_enable(&keyboard_tasklet);
}