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: Dmitry Torokhov <dtor@mail.ru>
This commit is contained in:
Родитель
1e87a43080
Коммит
0b7024ac4d
|
@ -1323,6 +1323,21 @@ static void kbd_event(struct input_handle *handle, unsigned int event_type,
|
|||
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
|
||||
* 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,
|
|||
{
|
||||
struct input_handle *handle;
|
||||
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);
|
||||
if (!handle)
|
||||
|
@ -1407,6 +1414,7 @@ MODULE_DEVICE_TABLE(input, kbd_ids);
|
|||
|
||||
static struct input_handler kbd_handler = {
|
||||
.event = kbd_event,
|
||||
.match = kbd_match,
|
||||
.connect = kbd_connect,
|
||||
.disconnect = kbd_disconnect,
|
||||
.start = kbd_start,
|
||||
|
|
|
@ -723,12 +723,13 @@ EXPORT_SYMBOL(input_set_keycode);
|
|||
if (i != BITS_TO_LONGS(max)) \
|
||||
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)
|
||||
{
|
||||
const struct input_device_id *id;
|
||||
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->bustype != dev->id.bustype)
|
||||
|
@ -756,7 +757,8 @@ static const struct input_device_id *input_match_device(const struct input_devic
|
|||
MATCH_BIT(ffbit, FF_MAX);
|
||||
MATCH_BIT(swbit, SW_MAX);
|
||||
|
||||
return id;
|
||||
if (!handler->match || handler->match(handler, dev))
|
||||
return id;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
@ -767,10 +769,7 @@ static int input_attach_handler(struct input_dev *dev, struct input_handler *han
|
|||
const struct input_device_id *id;
|
||||
int error;
|
||||
|
||||
if (handler->blacklist && input_match_device(handler->blacklist, dev))
|
||||
return -ENODEV;
|
||||
|
||||
id = input_match_device(handler->id_table, dev);
|
||||
id = input_match_device(handler, dev);
|
||||
if (!id)
|
||||
return -ENODEV;
|
||||
|
||||
|
|
|
@ -775,6 +775,20 @@ static void joydev_cleanup(struct joydev *joydev)
|
|||
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,
|
||||
const struct input_device_id *id)
|
||||
{
|
||||
|
@ -894,22 +908,6 @@ static void joydev_disconnect(struct input_handle *handle)
|
|||
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[] = {
|
||||
{
|
||||
.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
|
||||
|
@ -936,13 +934,13 @@ MODULE_DEVICE_TABLE(input, joydev_ids);
|
|||
|
||||
static struct input_handler joydev_handler = {
|
||||
.event = joydev_event,
|
||||
.match = joydev_match,
|
||||
.connect = joydev_connect,
|
||||
.disconnect = joydev_disconnect,
|
||||
.fops = &joydev_fops,
|
||||
.minor = JOYDEV_MINOR_BASE,
|
||||
.name = "joydev",
|
||||
.id_table = joydev_ids,
|
||||
.blacklist = joydev_blacklist,
|
||||
};
|
||||
|
||||
static int __init joydev_init(void)
|
||||
|
|
|
@ -1200,6 +1200,8 @@ struct input_handle;
|
|||
* it may not sleep
|
||||
* @filter: similar to @event; separates normal event handlers from
|
||||
* "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
|
||||
* @disconnect: disconnects a handler from input device
|
||||
* @start: starts handler for given handle. This function is called by
|
||||
|
@ -1211,8 +1213,6 @@ struct input_handle;
|
|||
* @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
|
||||
* 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
|
||||
* @node: for placing the driver onto input_handler_list
|
||||
*
|
||||
|
@ -1235,6 +1235,7 @@ struct input_handler {
|
|||
|
||||
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 (*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);
|
||||
void (*disconnect)(struct input_handle *handle);
|
||||
void (*start)(struct input_handle *handle);
|
||||
|
@ -1244,7 +1245,6 @@ struct input_handler {
|
|||
const char *name;
|
||||
|
||||
const struct input_device_id *id_table;
|
||||
const struct input_device_id *blacklist;
|
||||
|
||||
struct list_head h_list;
|
||||
struct list_head node;
|
||||
|
|
Загрузка…
Ссылка в новой задаче