mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* overriding keyboard driver in a module
@ 2005-07-07  1:41 Genadz Batsyan
  2005-07-07  5:25 ` Dmitry Torokhov
  0 siblings, 1 reply; 2+ messages in thread
From: Genadz Batsyan @ 2005-07-07  1:41 UTC (permalink / raw)
  To: linux-kernel

I'm writing a little tool to allow intercepting keyboard events and 
substituting them with other events / swallowing events / emitting additional 
events on a low level before normal processing by kernel.
http://kbd-mangler.sourceforge.net/

Currently to have precedense over the keyboard driver I'm using a patch 
against drivers/input/keyboard/atkbd.c

Well, I guess, patching kernel is unthinkable for most linux users, so I 
thought, maybe there is a way to do it without the kernel patch.
Is it possible to write a kernel module to intercept keyboard events
and have precedense over the kernel driver?

If anyone is interested, below is my patch.
 I know it's damn dirty (especially the last_dev thingy :-)
but take it easy, it's my first kernel undertaking, a product of a few days, 
and most importantly - it works.

Any kind of suggestions would be appreciated a lot.

-----------------------

--- linux-2.6.11.6-orig/drivers/input/keyboard/atkbd.c	2005-03-26 
04:28:48.000000000 +0100
+++ linux-2.6.11.6-patched/drivers/input/keyboard/atkbd.c	2005-07-01 
22:15:52.000000000 +0200
@@ -34,6 +34,10 @@
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
 
+
+#define CONFIG_KBD_INTERCEPTOR 1
+
+
 static int atkbd_set = 2;
 module_param_named(set, atkbd_set, int, 0);
 MODULE_PARM_DESC(set, "Select keyboard code set (2 = default, 3 = PS/2 
native)");
@@ -229,18 +233,79 @@
 ATKBD_DEFINE_ATTR(softraw);
 
 
-static void atkbd_report_key(struct input_dev *dev, struct pt_regs *regs, int 
code, int value)
+
+
+
+#ifdef CONFIG_KBD_INTERCEPTOR
+
+typedef int (*KBD_INTERCEPTOR)(int *, int *);
+
+static KBD_INTERCEPTOR kbd_interceptor;
+static struct input_dev *last_dev;
+
+#endif
+
+
+
+
+static void _atkbd_report_key(struct input_dev *dev, int code, int value)
 {
-	input_regs(dev, regs);
 	if (value == 3) {
 		input_report_key(dev, code, 1);
 		input_sync(dev);
 		input_report_key(dev, code, 0);
 	} else
 		input_event(dev, EV_KEY, code, value);
+}
+
+static void atkbd_report_key(struct input_dev *dev, struct pt_regs *regs, int 
code, int value)
+{
+	input_regs(dev, regs);
+
+#ifdef CONFIG_KBD_INTERCEPTOR
+        if (kbd_interceptor && kbd_interceptor(&code, &value))
+        {
+                return;
+        }
+#endif
+	_atkbd_report_key(dev, code, value);
 	input_sync(dev);
 }
 
+#ifdef CONFIG_KBD_INTERCEPTOR
+KBD_INTERCEPTOR kbd_set_interceptor(KBD_INTERCEPTOR interceptor)
+{
+        KBD_INTERCEPTOR old = kbd_interceptor;
+        kbd_interceptor = interceptor;
+        return old;
+}
+
+void kbd_emit_key(int code, int down)
+{
+    if (last_dev)
+        _atkbd_report_key(last_dev, code, down);
+    else
+        printk("kbd_emit_key: input_dev not set\n");
+}
+void kbd_emit_sync()
+{
+    if (last_dev)
+        input_sync(last_dev);
+    else
+        printk("kbd_emit_key: input_dev not set\n");
+}
+
+
+EXPORT_SYMBOL(kbd_set_interceptor);
+EXPORT_SYMBOL(kbd_emit_key);
+EXPORT_SYMBOL(kbd_emit_sync);
+
+#endif
+
+
+
+
+
 /*
  * atkbd_interrupt(). Here takes place processing of data received from
  * the keyboard into events.
@@ -660,6 +725,10 @@
 {
 	struct atkbd *atkbd = serio->private;
 
+#ifdef CONFIG_KBD_INTERCEPTOR
+        last_dev = NULL;
+#endif
+
 	atkbd_disable(atkbd);
 
 	/* make sure we don't have a command in flight */
@@ -847,6 +916,10 @@
 
 	input_register_device(&atkbd->dev);
 
+#ifdef CONFIG_KBD_INTERCEPTOR
+	last_dev = &atkbd->dev;
+#endif
+
 	device_create_file(&serio->dev, &atkbd_attr_extra);
 	device_create_file(&serio->dev, &atkbd_attr_scroll);
 	device_create_file(&serio->dev, &atkbd_attr_set);
@@ -1097,6 +1170,9 @@
 
 int __init atkbd_init(void)
 {
+#ifdef CONFIG_KBD_INTERCEPTOR
+        last_dev = NULL;
+#endif
 	serio_register_driver(&atkbd_drv);
 	return 0;
 }




^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2005-07-07  5:25 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-07-07  1:41 overriding keyboard driver in a module Genadz Batsyan
2005-07-07  5:25 ` Dmitry Torokhov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®