Add KDGETKEYSRL and KDSETKEYSRL to the console to control the soft release
key mask in input_dev.
Signed-off-by: Giel de Nijs <[email protected]>
---
Index: linux-2.6.21.1/drivers/char/vt_ioctl.c
===================================================================
--- linux-2.6.21.1.orig/drivers/char/vt_ioctl.c 2007-05-10 19:19:32.000000000 +0200
+++ linux-2.6.21.1/drivers/char/vt_ioctl.c 2007-05-11 19:21:52.000000000 +0200
@@ -181,6 +181,29 @@
return kc;
}
+static int
+do_kbkeysrl_ioctl(int cmd, struct kbkeysrl __user *user_kbks, int perm)
+{
+ struct kbkeysrl tmp;
+ int srl = 0;
+
+ if (copy_from_user(&tmp, user_kbks, sizeof(struct kbkeysrl)))
+ return -EFAULT;
+ switch (cmd) {
+ case KDGETKEYSRL:
+ srl = getkeysrl(tmp.scancode);
+ if (srl >= 0)
+ srl = put_user(srl, &user_kbks->srl);
+ break;
+ case KDSETKEYSRL:
+ if (!perm)
+ return -EPERM;
+ srl = setkeysrl(tmp.scancode, tmp.srl);
+ break;
+ }
+ return srl;
+}
+
static inline int
do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
{
@@ -571,6 +594,12 @@
perm=0;
return do_kbkeycode_ioctl(cmd, up, perm);
+ case KDGETKEYSRL:
+ case KDSETKEYSRL:
+ if(!capable(CAP_SYS_TTY_CONFIG))
+ perm=0;
+ return do_kbkeysrl_ioctl(cmd, up, perm);
+
case KDGKBENT:
case KDSKBENT:
return do_kdsk_ioctl(cmd, up, perm, kbd);
Index: linux-2.6.21.1/include/linux/kbd_kern.h
===================================================================
--- linux-2.6.21.1.orig/include/linux/kbd_kern.h 2007-05-10 19:20:18.000000000 +0200
+++ linux-2.6.21.1/include/linux/kbd_kern.h 2007-05-10 19:25:59.000000000 +0200
@@ -143,6 +143,8 @@
int getkeycode(unsigned int scancode);
int setkeycode(unsigned int scancode, unsigned int keycode);
+int getkeysrl(unsigned int scancode);
+int setkeysrl(unsigned int scancode, int srl);
void compute_shiftstate(void);
/* defkeymap.c */
Index: linux-2.6.21.1/include/linux/kd.h
===================================================================
--- linux-2.6.21.1.orig/include/linux/kd.h 2007-05-10 19:20:27.000000000 +0200
+++ linux-2.6.21.1/include/linux/kd.h 2007-05-10 19:38:52.000000000 +0200
@@ -144,6 +144,13 @@
#define KDFONTOP 0x4B72 /* font operations */
+struct kbkeysrl {
+ unsigned int scancode;
+ int srl;
+};
+#define KDGETKEYSRL 0x4B82 /* read kernel soft release key table entry */
+#define KDSETKEYSRL 0x4B83 /* write kernel soft release key table entry */
+
struct console_font_op {
unsigned int op; /* operation code KD_FONT_OP_* */
unsigned int flags; /* KD_FONT_FLAG_* */
Index: linux-2.6.21.1/drivers/char/keyboard.c
===================================================================
--- linux-2.6.21.1.orig/drivers/char/keyboard.c 2007-05-10 19:19:39.000000000 +0200
+++ linux-2.6.21.1/drivers/char/keyboard.c 2007-05-10 19:39:46.000000000 +0200
@@ -162,7 +162,7 @@
* Translation of scancodes to keycodes. We set them on only the first attached
* keyboard - for per-keyboard setting, /dev/input/event is more useful.
*/
-int getkeycode(unsigned int scancode)
+struct input_dev *find_first_keyboard(void)
{
struct list_head *node;
struct input_dev *dev = NULL;
@@ -175,6 +175,13 @@
}
}
+ return dev;
+}
+
+int getkeycode(unsigned int scancode)
+{
+ struct input_dev *dev = find_first_keyboard();
+
if (!dev)
return -ENODEV;
@@ -186,18 +193,9 @@
int setkeycode(unsigned int scancode, unsigned int keycode)
{
- struct list_head *node;
- struct input_dev *dev = NULL;
+ struct input_dev *dev = find_first_keyboard();
unsigned int i, oldkey;
- list_for_each(node, &kbd_handler.h_list) {
- struct input_handle *handle = to_handle_h(node);
- if (handle->dev->keycodesize) {
- dev = handle->dev;
- break;
- }
- }
-
if (!dev)
return -ENODEV;
@@ -221,6 +219,48 @@
}
/*
+ * Read/write the soft release bit for scancodes of a keyboard. The soft release
+ * bit is used to mark keys that don't generate a hardware release event.
+ * Here, we only handle the first attached keyboard.
+ */
+int getkeysrl(unsigned int scancode)
+{
+ struct input_dev *dev = find_first_keyboard();
+
+ if (!dev)
+ return -ENODEV;
+
+ if (scancode >= dev->keycodemax)
+ return -EINVAL;
+
+ if (!dev->keysrlmask) /* driver doesn't support soft release */
+ return -EINVAL;
+
+ return !! test_bit(scancode, dev->keysrlmask);
+}
+
+int setkeysrl(unsigned int scancode, int srl)
+{
+ struct input_dev *dev = find_first_keyboard();
+
+ if (!dev)
+ return -ENODEV;
+
+ if (scancode >= dev->keycodemax)
+ return -EINVAL;
+
+ if (!dev->keysrlmask) /* driver doesn't support soft release */
+ return -EINVAL;
+
+ if (srl)
+ set_bit(scancode, dev->keysrlmask);
+ else
+ clear_bit(scancode, dev->keysrlmask);
+
+ return 0;
+}
+
+/*
* Making beeps and bells.
*/
static void kd_nosound(unsigned long ignored)
Index: linux-2.6.21.1/include/linux/compat_ioctl.h
===================================================================
--- linux-2.6.21.1.orig/include/linux/compat_ioctl.h 2007-05-10 20:28:43.000000000 +0200
+++ linux-2.6.21.1/include/linux/compat_ioctl.h 2007-05-10 20:30:08.000000000 +0200
@@ -172,6 +172,8 @@
ULONG_IOCTL(KDSIGACCEPT)
COMPATIBLE_IOCTL(KDGETKEYCODE)
COMPATIBLE_IOCTL(KDSETKEYCODE)
+COMPATIBLE_IOCTL(KDGETKEYSRL)
+COMPATIBLE_IOCTL(KDSETKEYSRL)
ULONG_IOCTL(KIOCSOUND)
ULONG_IOCTL(KDMKTONE)
COMPATIBLE_IOCTL(KDGKBTYPE)
--
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[Index of Archives]
[Kernel Newbies]
[Netfilter]
[Bugtraq]
[Photo]
[Stuff]
[Gimp]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[Linux Security]
[Linux RAID]
[Video 4 Linux]
[Linux for the blind]
[Linux Resources]