Commit 0b7024ac authored by Dmitry Torokhov's avatar Dmitry Torokhov

Input: add match() method to input hanlders

Get rid of blacklist in input handler structure and instead allow
handlers to define their own match() method to perform fine-grained
filtering of supported devices.
Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
parent 1e87a430
...@@ -1323,6 +1323,21 @@ static void kbd_event(struct input_handle *handle, unsigned int event_type, ...@@ -1323,6 +1323,21 @@ static void kbd_event(struct input_handle *handle, unsigned int event_type,
schedule_console_callback(); schedule_console_callback();
} }
static bool kbd_match(struct input_handler *handler, struct input_dev *dev)
{
int i;
if (test_bit(EV_SND, dev->evbit))
return true;
if (test_bit(EV_KEY, dev->evbit))
for (i = KEY_RESERVED; i < BTN_MISC; i++)
if (test_bit(i, dev->keybit))
return true;
return false;
}
/* /*
* When a keyboard (or other input device) is found, the kbd_connect * When a keyboard (or other input device) is found, the kbd_connect
* function is called. The function then looks at the device, and if it * function is called. The function then looks at the device, and if it
...@@ -1334,14 +1349,6 @@ static int kbd_connect(struct input_handler *handler, struct input_dev *dev, ...@@ -1334,14 +1349,6 @@ static int kbd_connect(struct input_handler *handler, struct input_dev *dev,
{ {
struct input_handle *handle; struct input_handle *handle;
int error; int error;
int i;
for (i = KEY_RESERVED; i < BTN_MISC; i++)
if (test_bit(i, dev->keybit))
break;
if (i == BTN_MISC && !test_bit(EV_SND, dev->evbit))
return -ENODEV;
handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
if (!handle) if (!handle)
...@@ -1407,6 +1414,7 @@ MODULE_DEVICE_TABLE(input, kbd_ids); ...@@ -1407,6 +1414,7 @@ MODULE_DEVICE_TABLE(input, kbd_ids);
static struct input_handler kbd_handler = { static struct input_handler kbd_handler = {
.event = kbd_event, .event = kbd_event,
.match = kbd_match,
.connect = kbd_connect, .connect = kbd_connect,
.disconnect = kbd_disconnect, .disconnect = kbd_disconnect,
.start = kbd_start, .start = kbd_start,
......
...@@ -723,12 +723,13 @@ EXPORT_SYMBOL(input_set_keycode); ...@@ -723,12 +723,13 @@ EXPORT_SYMBOL(input_set_keycode);
if (i != BITS_TO_LONGS(max)) \ if (i != BITS_TO_LONGS(max)) \
continue; continue;
static const struct input_device_id *input_match_device(const struct input_device_id *id, static const struct input_device_id *input_match_device(struct input_handler *handler,
struct input_dev *dev) struct input_dev *dev)
{ {
const struct input_device_id *id;
int i; int i;
for (; id->flags || id->driver_info; id++) { for (id = handler->id_table; id->flags || id->driver_info; id++) {
if (id->flags & INPUT_DEVICE_ID_MATCH_BUS) if (id->flags & INPUT_DEVICE_ID_MATCH_BUS)
if (id->bustype != dev->id.bustype) if (id->bustype != dev->id.bustype)
...@@ -756,6 +757,7 @@ static const struct input_device_id *input_match_device(const struct input_devic ...@@ -756,6 +757,7 @@ static const struct input_device_id *input_match_device(const struct input_devic
MATCH_BIT(ffbit, FF_MAX); MATCH_BIT(ffbit, FF_MAX);
MATCH_BIT(swbit, SW_MAX); MATCH_BIT(swbit, SW_MAX);
if (!handler->match || handler->match(handler, dev))
return id; return id;
} }
...@@ -767,10 +769,7 @@ static int input_attach_handler(struct input_dev *dev, struct input_handler *han ...@@ -767,10 +769,7 @@ static int input_attach_handler(struct input_dev *dev, struct input_handler *han
const struct input_device_id *id; const struct input_device_id *id;
int error; int error;
if (handler->blacklist && input_match_device(handler->blacklist, dev)) id = input_match_device(handler, dev);
return -ENODEV;
id = input_match_device(handler->id_table, dev);
if (!id) if (!id)
return -ENODEV; return -ENODEV;
......
...@@ -775,6 +775,20 @@ static void joydev_cleanup(struct joydev *joydev) ...@@ -775,6 +775,20 @@ static void joydev_cleanup(struct joydev *joydev)
input_close_device(handle); input_close_device(handle);
} }
static bool joydev_match(struct input_handler *handler, struct input_dev *dev)
{
/* Avoid touchpads and touchscreens */
if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_TOUCH, dev->keybit))
return false;
/* Avoid tablets, digitisers and similar devices */
if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_DIGI, dev->keybit))
return false;
return true;
}
static int joydev_connect(struct input_handler *handler, struct input_dev *dev, static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
const struct input_device_id *id) const struct input_device_id *id)
{ {
...@@ -894,22 +908,6 @@ static void joydev_disconnect(struct input_handle *handle) ...@@ -894,22 +908,6 @@ static void joydev_disconnect(struct input_handle *handle)
put_device(&joydev->dev); put_device(&joydev->dev);
} }
static const struct input_device_id joydev_blacklist[] = {
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
INPUT_DEVICE_ID_MATCH_KEYBIT,
.evbit = { BIT_MASK(EV_KEY) },
.keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
}, /* Avoid itouchpads and touchscreens */
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
INPUT_DEVICE_ID_MATCH_KEYBIT,
.evbit = { BIT_MASK(EV_KEY) },
.keybit = { [BIT_WORD(BTN_DIGI)] = BIT_MASK(BTN_DIGI) },
}, /* Avoid tablets, digitisers and similar devices */
{ } /* Terminating entry */
};
static const struct input_device_id joydev_ids[] = { static const struct input_device_id joydev_ids[] = {
{ {
.flags = INPUT_DEVICE_ID_MATCH_EVBIT | .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
...@@ -936,13 +934,13 @@ MODULE_DEVICE_TABLE(input, joydev_ids); ...@@ -936,13 +934,13 @@ MODULE_DEVICE_TABLE(input, joydev_ids);
static struct input_handler joydev_handler = { static struct input_handler joydev_handler = {
.event = joydev_event, .event = joydev_event,
.match = joydev_match,
.connect = joydev_connect, .connect = joydev_connect,
.disconnect = joydev_disconnect, .disconnect = joydev_disconnect,
.fops = &joydev_fops, .fops = &joydev_fops,
.minor = JOYDEV_MINOR_BASE, .minor = JOYDEV_MINOR_BASE,
.name = "joydev", .name = "joydev",
.id_table = joydev_ids, .id_table = joydev_ids,
.blacklist = joydev_blacklist,
}; };
static int __init joydev_init(void) static int __init joydev_init(void)
......
...@@ -1200,6 +1200,8 @@ struct input_handle; ...@@ -1200,6 +1200,8 @@ struct input_handle;
* it may not sleep * it may not sleep
* @filter: similar to @event; separates normal event handlers from * @filter: similar to @event; separates normal event handlers from
* "filters". * "filters".
* @match: called after comparing device's id with handler's id_table
* to perform fine-grained matching between device and handler
* @connect: called when attaching a handler to an input device * @connect: called when attaching a handler to an input device
* @disconnect: disconnects a handler from input device * @disconnect: disconnects a handler from input device
* @start: starts handler for given handle. This function is called by * @start: starts handler for given handle. This function is called by
...@@ -1211,8 +1213,6 @@ struct input_handle; ...@@ -1211,8 +1213,6 @@ struct input_handle;
* @name: name of the handler, to be shown in /proc/bus/input/handlers * @name: name of the handler, to be shown in /proc/bus/input/handlers
* @id_table: pointer to a table of input_device_ids this driver can * @id_table: pointer to a table of input_device_ids this driver can
* handle * handle
* @blacklist: pointer to a table of input_device_ids this driver should
* ignore even if they match @id_table
* @h_list: list of input handles associated with the handler * @h_list: list of input handles associated with the handler
* @node: for placing the driver onto input_handler_list * @node: for placing the driver onto input_handler_list
* *
...@@ -1235,6 +1235,7 @@ struct input_handler { ...@@ -1235,6 +1235,7 @@ struct input_handler {
void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value); void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
bool (*filter)(struct input_handle *handle, unsigned int type, unsigned int code, int value); bool (*filter)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
bool (*match)(struct input_handler *handler, struct input_dev *dev);
int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id); int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id);
void (*disconnect)(struct input_handle *handle); void (*disconnect)(struct input_handle *handle);
void (*start)(struct input_handle *handle); void (*start)(struct input_handle *handle);
...@@ -1244,7 +1245,6 @@ struct input_handler { ...@@ -1244,7 +1245,6 @@ struct input_handler {
const char *name; const char *name;
const struct input_device_id *id_table; const struct input_device_id *id_table;
const struct input_device_id *blacklist;
struct list_head h_list; struct list_head h_list;
struct list_head node; struct list_head node;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment