Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 71384
b: refs/heads/master
c: 41ab439
h: refs/heads/master
v: v3
  • Loading branch information
Samuel Thibault authored and Linus Torvalds committed Oct 19, 2007
1 parent ca60f93 commit b8ad81e
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 7 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c18479fe017b9d3b65b7682f2b9e711389441186
refs/heads/master: 41ab4396e19fba338baf28044d3e48385744b930
42 changes: 36 additions & 6 deletions trunk/drivers/char/keyboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include <linux/sysrq.h>
#include <linux/input.h>
#include <linux/reboot.h>
#include <linux/notifier.h>

extern void ctrl_alt_del(void);

Expand Down Expand Up @@ -81,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,\
Expand Down Expand Up @@ -159,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.
Expand Down Expand Up @@ -1130,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;

Expand Down Expand Up @@ -1217,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, &param) == NOTIFY_STOP || !key_map) {
atomic_notifier_call_chain(&keyboard_notifier_list, KBD_UNBOUND_KEYCODE, &param);
compute_shiftstate();
kbd->slockstate = 0;
return;
Expand All @@ -1237,16 +1258,16 @@ 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, &param) == NOTIFY_STOP)
return;
if (down && !raw_mode)
to_utf8(vc, keysym);
return;
}

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)) {
Expand All @@ -1255,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, &param) == 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, &param);

if (type != KT_SLOCK)
kbd->slockstate = 0;
}
Expand Down
11 changes: 11 additions & 0 deletions trunk/include/linux/keyboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,21 @@
#define MAX_NR_OF_USER_KEYMAPS 256 /* should be at least 7 */

#ifdef __KERNEL__
struct notifier_block;
extern const int NR_TYPES;
extern const int max_vals[];
extern unsigned short *key_maps[MAX_NR_KEYMAPS];
extern unsigned short plain_map[NR_KEYS];

struct keyboard_notifier_param {
struct vc_data *vc; /* VC on which the keyboard press was done */
int down; /* Pressure of the key? */
int shift; /* Current shift mask */
unsigned int value; /* keycode, unicode value or keysym */
};

extern int register_keyboard_notifier(struct notifier_block *nb);
extern int unregister_keyboard_notifier(struct notifier_block *nb);
#endif

#define MAX_NR_FUNC 256 /* max nr of strings assigned to keys */
Expand Down
9 changes: 9 additions & 0 deletions trunk/include/linux/notifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -231,5 +231,14 @@ static inline int notifier_to_errno(int ret)
#define PM_SUSPEND_PREPARE 0x0003 /* Going to suspend the system */
#define PM_POST_SUSPEND 0x0004 /* Suspend finished */

/* Console keyboard events.
* Note: KBD_KEYCODE is always sent before KBD_UNBOUND_KEYCODE, KBD_UNICODE and
* KBD_KEYSYM. */
#define KBD_KEYCODE 0x0001 /* Keyboard keycode, called before any other */
#define KBD_UNBOUND_KEYCODE 0x0002 /* Keyboard keycode which is not bound to any other */
#define KBD_UNICODE 0x0003 /* Keyboard unicode */
#define KBD_KEYSYM 0x0004 /* Keyboard keysym */
#define KBD_POST_KEYSYM 0x0005 /* Called after keyboard keysym interpretation */

#endif /* __KERNEL__ */
#endif /* _LINUX_NOTIFIER_H */

0 comments on commit b8ad81e

Please sign in to comment.