Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0e739d28 authored by Dmitry Torokhov's avatar Dmitry Torokhov
Browse files

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: default avatarDmitry Torokhov <dtor@mail.ru>
parent c7e8dc6e
Loading
Loading
Loading
Loading
+18 −18
Original line number Diff line number Diff line
@@ -227,9 +227,9 @@ static void kd_nosound(unsigned long ignored)
		struct input_handle *handle = to_handle_h(node);
		if (test_bit(EV_SND, handle->dev->evbit)) {
			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))
				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);
			if (test_bit(EV_SND, handle->dev->evbit)) {
				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;
				}
				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;
				}
			}
@@ -278,9 +278,9 @@ int kbd_rate(struct kbd_repeat *rep)

		if (test_bit(EV_REP, dev->evbit)) {
			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)
				input_event(dev, EV_REP, REP_PERIOD, rep->period);
				input_inject_event(handle, EV_REP, REP_PERIOD, rep->period);
			d = dev->rep[REP_DELAY];
			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
 * this when we don't want any of the above to happen.
 * 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)
@@ -999,10 +999,10 @@ static void kbd_bh(unsigned long dummy)
	if (leds != ledstate) {
		list_for_each(node, &kbd_handler.h_list) {
			struct input_handle *handle = to_handle_h(node);
			input_event(handle->dev, EV_LED, LED_SCROLLL, !!(leds & 0x01));
			input_event(handle->dev, EV_LED, LED_NUML,    !!(leds & 0x02));
			input_event(handle->dev, EV_LED, LED_CAPSL,   !!(leds & 0x04));
			input_sync(handle->dev);
			input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01));
			input_inject_event(handle, EV_LED, LED_NUML,    !!(leds & 0x02));
			input_inject_event(handle, EV_LED, LED_CAPSL,   !!(leds & 0x04));
			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);
	if (leds != 0xff) {
		input_event(handle->dev, EV_LED, LED_SCROLLL, !!(leds & 0x01));
		input_event(handle->dev, EV_LED, LED_NUML,    !!(leds & 0x02));
		input_event(handle->dev, EV_LED, LED_CAPSL,   !!(leds & 0x04));
		input_sync(handle->dev);
		input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01));
		input_inject_event(handle, EV_LED, LED_NUML,    !!(leds & 0x02));
		input_inject_event(handle, EV_LED, LED_CAPSL,   !!(leds & 0x04));
		input_inject_event(handle, EV_SYN, SYN_REPORT, 0);
	}
	tasklet_enable(&keyboard_tasklet);
}
+3 −3
Original line number Diff line number Diff line
@@ -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))
			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();
	}

@@ -424,8 +424,8 @@ static long evdev_ioctl_handler(struct file *file, unsigned int cmd,
			if (get_user(v, ip + 1))
				return -EFAULT;

			input_event(dev, EV_REP, REP_DELAY, u);
			input_event(dev, EV_REP, REP_PERIOD, v);
			input_inject_event(&evdev->handle, EV_REP, REP_DELAY, u);
			input_inject_event(&evdev->handle, EV_REP, REP_PERIOD, v);

			return 0;

+27 −0
Original line number Diff line number Diff line
@@ -35,6 +35,16 @@ static LIST_HEAD(input_handler_list);

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)
{
	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);

/**
 * 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)
{
	struct input_dev *dev = (void *) data;
+1 −0
Original line number Diff line number Diff line
@@ -1053,6 +1053,7 @@ void input_close_device(struct input_handle *);
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_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)
{