2012-05-24 21:31:02 +02:00
|
|
|
/*
|
|
|
|
* \brief Input service and event handler
|
|
|
|
* \author Christian Helmuth
|
2014-07-11 16:08:59 +02:00
|
|
|
* \author Dirk Vogt <dvogt@os.inf.tu-dresden.de>
|
|
|
|
* \author Sebastian Sumpf <sebastian.sumpf@genode-labs.com>
|
|
|
|
* \author Christian Menard <christian.menard@ksyslabs.org>
|
2012-05-24 21:31:02 +02:00
|
|
|
* \date 2009-04-20
|
|
|
|
*
|
|
|
|
* The original implementation was in the L4Env from the TUD:OS group
|
|
|
|
* (l4/pkg/input/lib/src/l4evdev.c). This file was released under the terms of
|
|
|
|
* the GNU General Public License version 2.
|
|
|
|
*/
|
|
|
|
|
2012-06-20 08:42:16 +02:00
|
|
|
/*
|
2014-07-11 16:08:59 +02:00
|
|
|
* Copyright (C) 2009-2014 Genode Labs GmbH
|
|
|
|
* Copyright (C) 2014 Ksys Labs LLC
|
2012-06-20 08:42:16 +02:00
|
|
|
*
|
|
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
|
|
* under the terms of the GNU General Public License version 2.
|
|
|
|
*/
|
|
|
|
|
2012-05-24 21:31:02 +02:00
|
|
|
/* Linux */
|
|
|
|
#include <linux/input.h>
|
|
|
|
|
|
|
|
/* Local */
|
|
|
|
#include <lx_emul.h>
|
|
|
|
|
|
|
|
/* Callback function to Genode subsystem */
|
|
|
|
static genode_input_event_cb handler;;
|
|
|
|
|
2014-12-02 16:04:47 +01:00
|
|
|
static unsigned long screen_x = 0;
|
|
|
|
static unsigned long screen_y = 0;
|
|
|
|
|
|
|
|
|
2012-05-24 21:31:02 +02:00
|
|
|
void genode_evdev_event(struct input_handle *handle, unsigned int type,
|
|
|
|
unsigned int code, int value)
|
|
|
|
{
|
|
|
|
#if DEBUG_EVDEV
|
|
|
|
static unsigned long count = 0;
|
|
|
|
#endif
|
|
|
|
|
2014-07-11 16:08:59 +02:00
|
|
|
static int last_ax = -1; /* store the last absolute x value */
|
|
|
|
|
2012-05-24 21:31:02 +02:00
|
|
|
/* filter sound events */
|
|
|
|
if (test_bit(EV_SND, handle->dev->evbit)) return;
|
|
|
|
|
|
|
|
/* filter input_repeat_key() */
|
|
|
|
if ((type == EV_KEY) && (value == 2)) return;
|
|
|
|
|
|
|
|
/* filter EV_SYN */
|
|
|
|
if (type == EV_SYN) return;
|
|
|
|
|
|
|
|
/* generate arguments and call back */
|
|
|
|
enum input_event_type arg_type;
|
|
|
|
unsigned arg_keycode = KEY_UNKNOWN;
|
|
|
|
int arg_ax = 0, arg_ay = 0, arg_rx = 0, arg_ry = 0;
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
|
|
|
case EV_KEY:
|
|
|
|
arg_keycode = code;
|
2014-07-11 16:08:59 +02:00
|
|
|
|
|
|
|
/* map BTN_TOUCH events to BTN_LEFT */
|
|
|
|
if (code == BTN_TOUCH)
|
|
|
|
arg_keycode = BTN_LEFT;
|
|
|
|
|
2012-05-24 21:31:02 +02:00
|
|
|
switch (value) {
|
|
|
|
|
|
|
|
case 0:
|
|
|
|
arg_type = EVENT_TYPE_RELEASE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
arg_type = EVENT_TYPE_PRESS;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
printk("Unknown key event value %d - not handled\n", value);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EV_ABS:
|
|
|
|
switch (code) {
|
|
|
|
|
|
|
|
case ABS_X:
|
2014-07-11 16:08:59 +02:00
|
|
|
case ABS_MT_POSITION_X:
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Don't create an input event yet. Store the value and wait for the
|
|
|
|
* subsequent Y event.
|
|
|
|
*/
|
|
|
|
last_ax = value;
|
|
|
|
return;
|
2012-05-24 21:31:02 +02:00
|
|
|
|
|
|
|
case ABS_Y:
|
2014-07-11 16:08:59 +02:00
|
|
|
case ABS_MT_POSITION_Y:
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Create a unified input event with absolute positions on x and y
|
|
|
|
* axis.
|
|
|
|
*/
|
2012-05-24 21:31:02 +02:00
|
|
|
arg_type = EVENT_TYPE_MOTION;
|
2014-07-11 16:08:59 +02:00
|
|
|
arg_ax = last_ax;
|
2014-12-02 16:04:47 +01:00
|
|
|
arg_ay = value;
|
|
|
|
|
|
|
|
/* transform if requested */
|
|
|
|
if (screen_x && screen_y) {
|
|
|
|
int const min_x_dev = input_abs_get_min(handle->dev, ABS_X);
|
|
|
|
int const min_y_dev = input_abs_get_min(handle->dev, ABS_Y);
|
|
|
|
int const max_x_dev = input_abs_get_max(handle->dev, ABS_X);
|
|
|
|
int const max_y_dev = input_abs_get_max(handle->dev, ABS_Y);
|
|
|
|
int const max_y_norm = max_y_dev - min_y_dev;
|
|
|
|
int const max_x_norm = max_x_dev - min_x_dev;
|
|
|
|
|
|
|
|
if ((max_x_norm == 0) || (max_y_norm == 0) ||
|
|
|
|
(last_ax < min_x_dev) || (value < min_y_dev) ||
|
|
|
|
(last_ax > max_x_dev) || (value > max_y_dev))
|
|
|
|
{
|
|
|
|
printk("Ignore input source with coordinates out of range\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
arg_ax = screen_x * (last_ax - min_x_dev) / (max_x_norm);
|
|
|
|
arg_ay = screen_y * (value - min_y_dev) / (max_y_norm);
|
|
|
|
}
|
|
|
|
|
2014-07-11 16:08:59 +02:00
|
|
|
last_ax = -1;
|
|
|
|
if (arg_ax == -1) {
|
|
|
|
printk("Ignore absolute Y event without a preceeding X event\n");
|
|
|
|
return;
|
|
|
|
}
|
2012-05-24 21:31:02 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case ABS_WHEEL:
|
2014-07-11 16:08:59 +02:00
|
|
|
|
2012-05-24 21:31:02 +02:00
|
|
|
/*
|
|
|
|
* XXX I do not know, how to handle this correctly. At least, this
|
|
|
|
* scheme works on Qemu.
|
|
|
|
*/
|
|
|
|
arg_type = EVENT_TYPE_WHEEL;
|
|
|
|
arg_ry = value;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
printk("Unknown absolute event code %d - not handled\n", code);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EV_REL:
|
|
|
|
switch (code) {
|
|
|
|
|
|
|
|
case REL_X:
|
|
|
|
arg_type = EVENT_TYPE_MOTION;
|
|
|
|
arg_rx = value;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case REL_Y:
|
|
|
|
arg_type = EVENT_TYPE_MOTION;
|
|
|
|
arg_ry = value;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case REL_HWHEEL:
|
|
|
|
arg_type = EVENT_TYPE_WHEEL;
|
|
|
|
arg_rx = value;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case REL_WHEEL:
|
|
|
|
arg_type = EVENT_TYPE_WHEEL;
|
|
|
|
arg_ry = value;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
printk("Unknown relative event code %d - not handled\n", code);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
printk("Unknown event type %d - not handled\n", type);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (handler)
|
|
|
|
handler(arg_type, arg_keycode, arg_ax, arg_ay, arg_rx, arg_ry);
|
2014-06-02 13:50:17 +02:00
|
|
|
|
2012-05-24 21:31:02 +02:00
|
|
|
#if DEBUG_EVDEV
|
2014-12-02 16:04:47 +01:00
|
|
|
printk("event[%ld]. dev: %s, type: %d, code: %d, value: %d a=%d,%d "
|
|
|
|
"r=%d,%d\n", count++, handle->dev->name, type, code, value, arg_ax,
|
|
|
|
arg_ay, arg_rx, arg_ry);
|
2012-05-24 21:31:02 +02:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-12-02 16:04:47 +01:00
|
|
|
void genode_input_register(genode_input_event_cb h, unsigned long res_x,
|
|
|
|
unsigned long res_y)
|
|
|
|
{
|
|
|
|
handler = h;
|
|
|
|
|
|
|
|
screen_x = res_x;
|
|
|
|
screen_y = res_y;
|
|
|
|
}
|