* [PATCH 0/2] input: add generic filter for input events
@ 2008-11-04 2:01 Peter Hutterer
2008-11-04 2:01 ` [PATCH 1/2] input: add filter callback to input handlers Peter Hutterer
0 siblings, 1 reply; 3+ messages in thread
From: Peter Hutterer @ 2008-11-04 2:01 UTC (permalink / raw)
To: linux-input
The mac_hid module provides a virtual device to emulate right and/or middle
mouse button clicks on certain key presses. This emulation however only hooks
into keyboard.c, but not into evdev.c.
Consumers that listen to all evdev devices (such as the X server) thus receive
both the emulated mouse button event and the original key event. They do not
know that these events are associated.
These patches provide input handlers with an additional "filter" callback.
This filter function is invoked before the event is passed to the handlers and
can opt to discard the event. The mac_hid module registers such a filter
function and re-routes the event as mouse click through the virtual device.
This is a first stab in the dark at the attempt to fix this issue. Comments
are much appreciated.
Cheers,
Peter
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 1/2] input: add filter callback to input handlers.
2008-11-04 2:01 [PATCH 0/2] input: add generic filter for input events Peter Hutterer
@ 2008-11-04 2:01 ` Peter Hutterer
2008-11-04 2:01 ` [PATCH 2/2] macintosh: add input handler to mac_hid module Peter Hutterer
0 siblings, 1 reply; 3+ messages in thread
From: Peter Hutterer @ 2008-11-04 2:01 UTC (permalink / raw)
To: linux-input; +Cc: Peter Hutterer
From: Peter Hutterer <peter.hutterer@redhat.com>
The filter is called on all handlers before the event is passed to the
handlers for delivery. This allows such handlers to redirect the event to a
different device or trigger other actions based on the event.
If a filter returns non-zero, the event is discarded and not passed to the
event handlers.
Signed-off-by: Peter Hutterer <peter.hutterer@redhat.com>
---
drivers/input/input.c | 44 ++++++++++++++++++++++++++++++++++++++++++--
include/linux/input.h | 2 ++
2 files changed, 44 insertions(+), 2 deletions(-)
diff --git a/drivers/input/input.c b/drivers/input/input.c
index c13ced3..fa19e6a 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -132,6 +132,44 @@ static void input_start_autorepeat(struct input_dev *dev, int code)
}
}
+/**
+ * input_filter_event() - filter the event
+ * @dev: device that generated the event
+ * @type: type of the event
+ * @code: event code
+ * @value: value of the event
+ *
+ * This function takes the event and runs through all filter-handlers. The
+ * handlers may indicate that the event is to be filtered and not propagated
+ * any further.
+ * Returns 1, if the event is not to be sent to the actual event handlers.
+ */
+int input_filter_event(struct input_dev *dev, unsigned int type,
+ unsigned int code, int value)
+{
+ struct input_handle *handle;
+ int retval = 0;
+
+ rcu_read_lock();
+
+ handle = rcu_dereference(dev->grab);
+ if (handle) {
+ if (handle->handler->filter)
+ retval = handle->handler->filter(handle, type,
+ code, value);
+ else
+ retval = 0;
+ } else
+ list_for_each_entry_rcu(handle, &dev->h_list, d_node)
+ if (handle->open && handle->handler->filter)
+ if (handle->handler->filter(handle, type,
+ code, value))
+ retval = 1;
+ rcu_read_unlock();
+
+ return retval;
+}
+
#define INPUT_IGNORE_EVENT 0
#define INPUT_PASS_TO_HANDLERS 1
#define INPUT_PASS_TO_DEVICE 2
@@ -248,8 +286,10 @@ static void input_handle_event(struct input_dev *dev,
if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event)
dev->event(dev, type, code, value);
- if (disposition & INPUT_PASS_TO_HANDLERS)
- input_pass_event(dev, type, code, value);
+ if (disposition & INPUT_PASS_TO_HANDLERS) {
+ if (!input_filter_event(dev, type, code, value))
+ input_pass_event(dev, type, code, value);
+ }
}
/**
diff --git a/include/linux/input.h b/include/linux/input.h
index a5802c9..30a5b8a 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -1154,6 +1154,7 @@ struct input_handle;
* @start: starts handler for given handle. This function is called by
* input core right after connect() method and also when a process
* that "grabbed" a device releases it
+ * @filter: filter the given event and do not call @event.
* @fops: file operations this driver implements
* @minor: beginning of range of 32 minors for devices this driver
* can provide
@@ -1178,6 +1179,7 @@ struct input_handler {
void *private;
void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
+ int (*filter)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id);
void (*disconnect)(struct input_handle *handle);
void (*start)(struct input_handle *handle);
--
1.6.0.3
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 2/2] macintosh: add input handler to mac_hid module.
2008-11-04 2:01 ` [PATCH 1/2] input: add filter callback to input handlers Peter Hutterer
@ 2008-11-04 2:01 ` Peter Hutterer
0 siblings, 0 replies; 3+ messages in thread
From: Peter Hutterer @ 2008-11-04 2:01 UTC (permalink / raw)
To: linux-input; +Cc: Peter Hutterer
From: Peter Hutterer <peter.hutterer@redhat.com>
Register an input handler on all devices for macintosh mouse button emulation.
If an event from another device passes as key event to trigger the mouse
button emulation, the button event is sent through the emulation device and
the original event is discarded by the filter.
This replaces the existing emulation code in keyboard.c.
Signed-off-by: Peter Hutterer <peter.hutterer@redhat.com>
---
drivers/char/keyboard.c | 5 --
drivers/macintosh/mac_hid.c | 88 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 88 insertions(+), 5 deletions(-)
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 7b3a212..3d1f657 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -1170,11 +1170,6 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
rep = (down == 2);
-#ifdef CONFIG_MAC_EMUMOUSEBTN
- if (mac_hid_mouse_emulate_buttons(1, keycode, down))
- return;
-#endif /* CONFIG_MAC_EMUMOUSEBTN */
-
if ((raw_mode = (kbd->kbdmode == VC_RAW)) && !hw_raw)
if (emulate_raw(vc, keycode, !down << 7))
if (keycode < BTN_MISC && printk_ratelimit())
diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c
index cc9f275..cfbe038 100644
--- a/drivers/macintosh/mac_hid.c
+++ b/drivers/macintosh/mac_hid.c
@@ -15,6 +15,7 @@
#include <linux/module.h>
#include <linux/kbd_kern.h>
+#define mac_hid_MINOR_BASE 64
static struct input_dev *emumousebtn;
static int emumousebtn_input_register(void);
@@ -151,3 +152,90 @@ static int __init mac_hid_init(void)
}
device_initcall(mac_hid_init);
+
+static void mac_hid_event(struct input_handle *handle,
+ unsigned int type, unsigned int code, int value)
+{
+ return;
+}
+
+
+static int mac_hid_filter(struct input_handle *handle, unsigned int type,
+ unsigned int code, int value)
+{
+ return mac_hid_mouse_emulate_buttons(1, code, value);
+}
+
+static int mac_hid_connect(struct input_handler *handler, struct input_dev *dev,
+ const struct input_device_id *id)
+{
+ struct input_handle *handle;
+ int error;
+
+ handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
+ if (!handle)
+ return -ENOMEM;
+
+ handle->dev = input_get_device(dev);
+ handle->handler = handler;
+ handle->name = "mac_hid";
+
+ error = input_register_handle(handle);
+ if (error)
+ goto err_free_handle;
+
+ error = input_open_device(handle);
+ if (error)
+ goto err_unregister_handle;
+
+ return 0;
+
+err_unregister_handle:
+ input_unregister_handle(handle);
+err_free_handle:
+ kfree(handle);
+ return error;
+}
+
+static void mac_hid_disconnect(struct input_handle *handle)
+{
+ input_close_device(handle);
+ input_unregister_handle(handle);
+ kfree(handle);
+}
+
+
+static const struct input_device_id mac_hid_ids[] = {
+ { .driver_info = 1 }, /* Matches all devices */
+ { }, /* Terminating zero entry */
+};
+
+MODULE_DEVICE_TABLE(input, mac_hid_ids);
+
+static struct input_handler mac_hid_handler = {
+ .event = mac_hid_event,
+ .connect = mac_hid_connect,
+ .disconnect = mac_hid_disconnect,
+ .filter = mac_hid_filter,
+ .fops = NULL,
+ .minor = mac_hid_MINOR_BASE,
+ .name = "mac_hid",
+ .id_table = mac_hid_ids,
+};
+
+static int __init mac_hid_init_ih(void)
+{
+ return input_register_handler(&mac_hid_handler);
+}
+
+static void __exit mac_hid_exit_ih(void)
+{
+ input_unregister_handler(&mac_hid_handler);
+}
+
+module_init(mac_hid_init_ih);
+module_exit(mac_hid_exit_ih);
+
+MODULE_AUTHOR("Peter Hutterer <peter.hutterer@redhat.com>");
+MODULE_DESCRIPTION("Mac HID fake device");
+MODULE_LICENSE("GPL");
--
1.6.0.3
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2008-11-04 2:02 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-11-04 2:01 [PATCH 0/2] input: add generic filter for input events Peter Hutterer
2008-11-04 2:01 ` [PATCH 1/2] input: add filter callback to input handlers Peter Hutterer
2008-11-04 2:01 ` [PATCH 2/2] macintosh: add input handler to mac_hid module Peter Hutterer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).