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:
parent
1e87a43080
commit
0b7024ac4d
|
@ -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,
|
||||||
{
|
{
|
||||||
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);
|
||||||
|
|
||||||
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);
|
||||||
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,7 +757,8 @@ 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);
|
||||||
|
|
||||||
return id;
|
if (!handler->match || handler->match(handler, dev))
|
||||||
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
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;
|
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)
|
||||||
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)
|
||||||
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);
|
||||||
|
|
||||||
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;
|
||||||
* 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;
|
||||||
* @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 {
|
||||||
|
|
||||||
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 {
|
||||||
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;
|
||||||
|
|
Loading…
Reference in New Issue