Input: introduce input_inject_event() function

Create input_inject_event() function which is to be used by input
handlers as opposed to input_event() which is reserved for drivers
implementing input devices. The difference is that if device is
"grabbed" by some process input_inject_event() will ignore events
unless sent from the handle that is currently owns the device.

Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
This commit is contained in:
Dmitry Torokhov 2006-07-06 00:22:43 -04:00
parent c7e8dc6ee6
commit 0e739d2876
4 changed files with 49 additions and 21 deletions

View File

@ -223,13 +223,13 @@ static void kd_nosound(unsigned long ignored)
{ {
struct list_head *node; struct list_head *node;
list_for_each(node,&kbd_handler.h_list) { list_for_each(node, &kbd_handler.h_list) {
struct input_handle *handle = to_handle_h(node); struct input_handle *handle = to_handle_h(node);
if (test_bit(EV_SND, handle->dev->evbit)) { if (test_bit(EV_SND, handle->dev->evbit)) {
if (test_bit(SND_TONE, handle->dev->sndbit)) if (test_bit(SND_TONE, handle->dev->sndbit))
input_event(handle->dev, EV_SND, SND_TONE, 0); input_inject_event(handle, EV_SND, SND_TONE, 0);
if (test_bit(SND_BELL, handle->dev->sndbit)) if (test_bit(SND_BELL, handle->dev->sndbit))
input_event(handle->dev, EV_SND, SND_BELL, 0); input_inject_event(handle, EV_SND, SND_BELL, 0);
} }
} }
} }
@ -247,11 +247,11 @@ void kd_mksound(unsigned int hz, unsigned int ticks)
struct input_handle *handle = to_handle_h(node); struct input_handle *handle = to_handle_h(node);
if (test_bit(EV_SND, handle->dev->evbit)) { if (test_bit(EV_SND, handle->dev->evbit)) {
if (test_bit(SND_TONE, handle->dev->sndbit)) { if (test_bit(SND_TONE, handle->dev->sndbit)) {
input_event(handle->dev, EV_SND, SND_TONE, hz); input_inject_event(handle, EV_SND, SND_TONE, hz);
break; break;
} }
if (test_bit(SND_BELL, handle->dev->sndbit)) { if (test_bit(SND_BELL, handle->dev->sndbit)) {
input_event(handle->dev, EV_SND, SND_BELL, 1); input_inject_event(handle, EV_SND, SND_BELL, 1);
break; break;
} }
} }
@ -272,15 +272,15 @@ int kbd_rate(struct kbd_repeat *rep)
unsigned int d = 0; unsigned int d = 0;
unsigned int p = 0; unsigned int p = 0;
list_for_each(node,&kbd_handler.h_list) { list_for_each(node, &kbd_handler.h_list) {
struct input_handle *handle = to_handle_h(node); struct input_handle *handle = to_handle_h(node);
struct input_dev *dev = handle->dev; struct input_dev *dev = handle->dev;
if (test_bit(EV_REP, dev->evbit)) { if (test_bit(EV_REP, dev->evbit)) {
if (rep->delay > 0) if (rep->delay > 0)
input_event(dev, EV_REP, REP_DELAY, rep->delay); input_inject_event(handle, EV_REP, REP_DELAY, rep->delay);
if (rep->period > 0) if (rep->period > 0)
input_event(dev, EV_REP, REP_PERIOD, rep->period); input_inject_event(handle, EV_REP, REP_PERIOD, rep->period);
d = dev->rep[REP_DELAY]; d = dev->rep[REP_DELAY];
p = dev->rep[REP_PERIOD]; p = dev->rep[REP_PERIOD];
} }
@ -988,7 +988,7 @@ static inline unsigned char getleds(void)
* interrupt routines for this thing allows us to easily mask * interrupt routines for this thing allows us to easily mask
* this when we don't want any of the above to happen. * this when we don't want any of the above to happen.
* This allows for easy and efficient race-condition prevention * This allows for easy and efficient race-condition prevention
* for kbd_start => input_event(dev, EV_LED, ...) => ... * for kbd_start => input_inject_event(dev, EV_LED, ...) => ...
*/ */
static void kbd_bh(unsigned long dummy) static void kbd_bh(unsigned long dummy)
@ -998,11 +998,11 @@ static void kbd_bh(unsigned long dummy)
if (leds != ledstate) { if (leds != ledstate) {
list_for_each(node, &kbd_handler.h_list) { list_for_each(node, &kbd_handler.h_list) {
struct input_handle * handle = to_handle_h(node); struct input_handle *handle = to_handle_h(node);
input_event(handle->dev, EV_LED, LED_SCROLLL, !!(leds & 0x01)); input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01));
input_event(handle->dev, EV_LED, LED_NUML, !!(leds & 0x02)); input_inject_event(handle, EV_LED, LED_NUML, !!(leds & 0x02));
input_event(handle->dev, EV_LED, LED_CAPSL, !!(leds & 0x04)); input_inject_event(handle, EV_LED, LED_CAPSL, !!(leds & 0x04));
input_sync(handle->dev); input_inject_event(handle, EV_SYN, SYN_REPORT, 0);
} }
} }
@ -1310,10 +1310,10 @@ static void kbd_start(struct input_handle *handle)
tasklet_disable(&keyboard_tasklet); tasklet_disable(&keyboard_tasklet);
if (leds != 0xff) { if (leds != 0xff) {
input_event(handle->dev, EV_LED, LED_SCROLLL, !!(leds & 0x01)); input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01));
input_event(handle->dev, EV_LED, LED_NUML, !!(leds & 0x02)); input_inject_event(handle, EV_LED, LED_NUML, !!(leds & 0x02));
input_event(handle->dev, EV_LED, LED_CAPSL, !!(leds & 0x04)); input_inject_event(handle, EV_LED, LED_CAPSL, !!(leds & 0x04));
input_sync(handle->dev); input_inject_event(handle, EV_SYN, SYN_REPORT, 0);
} }
tasklet_enable(&keyboard_tasklet); tasklet_enable(&keyboard_tasklet);
} }

View File

@ -256,7 +256,7 @@ static ssize_t evdev_write(struct file * file, const char __user * buffer, size_
if (evdev_event_from_user(buffer + retval, &event)) if (evdev_event_from_user(buffer + retval, &event))
return -EFAULT; return -EFAULT;
input_event(list->evdev->handle.dev, event.type, event.code, event.value); input_inject_event(&list->evdev->handle, event.type, event.code, event.value);
retval += evdev_event_size(); retval += evdev_event_size();
} }
@ -424,8 +424,8 @@ static long evdev_ioctl_handler(struct file *file, unsigned int cmd,
if (get_user(v, ip + 1)) if (get_user(v, ip + 1))
return -EFAULT; return -EFAULT;
input_event(dev, EV_REP, REP_DELAY, u); input_inject_event(&evdev->handle, EV_REP, REP_DELAY, u);
input_event(dev, EV_REP, REP_PERIOD, v); input_inject_event(&evdev->handle, EV_REP, REP_PERIOD, v);
return 0; return 0;

View File

@ -35,6 +35,16 @@ static LIST_HEAD(input_handler_list);
static struct input_handler *input_table[8]; static struct input_handler *input_table[8];
/**
* input_event() - report new input event
* @handle: device that generated the event
* @type: type of the event
* @code: event code
* @value: value of the event
*
* This function should be used by drivers implementing various input devices
* See also input_inject_event()
*/
void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
{ {
struct input_handle *handle; struct input_handle *handle;
@ -183,6 +193,23 @@ void input_event(struct input_dev *dev, unsigned int type, unsigned int code, in
} }
EXPORT_SYMBOL(input_event); EXPORT_SYMBOL(input_event);
/**
* input_inject_event() - send input event from input handler
* @handle: input handle to send event through
* @type: type of the event
* @code: event code
* @value: value of the event
*
* Similar to input_event() but will ignore event if device is "grabbed" and handle
* injecting event is not the one that owns the device.
*/
void input_inject_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
{
if (!handle->dev->grab || handle->dev->grab == handle)
input_event(handle->dev, type, code, value);
}
EXPORT_SYMBOL(input_inject_event);
static void input_repeat_key(unsigned long data) static void input_repeat_key(unsigned long data)
{ {
struct input_dev *dev = (void *) data; struct input_dev *dev = (void *) data;

View File

@ -1053,6 +1053,7 @@ void input_close_device(struct input_handle *);
int input_flush_device(struct input_handle* handle, struct file* file); int input_flush_device(struct input_handle* handle, struct file* file);
void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value); void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value);
void input_inject_event(struct input_handle *handle, unsigned int type, unsigned int code, int value);
static inline void input_report_key(struct input_dev *dev, unsigned int code, int value) static inline void input_report_key(struct input_dev *dev, unsigned int code, int value)
{ {