Skip to content
This repository has been archived by the owner on Dec 14, 2022. It is now read-only.

Commit

Permalink
Input: add match() method to input hanlders
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
dtor committed Feb 4, 2010
1 parent 1e87a43 commit 0b7024a
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 35 deletions.
24 changes: 16 additions & 8 deletions drivers/char/keyboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand Down Expand Up @@ -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,
Expand Down
13 changes: 6 additions & 7 deletions drivers/input/input.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand All @@ -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;

Expand Down
32 changes: 15 additions & 17 deletions drivers/input/joydev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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 |
Expand All @@ -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)
Expand Down
6 changes: 3 additions & 3 deletions include/linux/input.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
*
Expand All @@ -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);
Expand All @@ -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;
Expand Down

0 comments on commit 0b7024a

Please sign in to comment.