mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 05:37:54 +00:00
parent
71c3fa53da
commit
cd764a6aa6
@ -45,10 +45,15 @@ hid xml tag:
|
||||
|
||||
!...
|
||||
!<hid>
|
||||
! <screen width="1024" height="768"/>
|
||||
! <touchscreen width="1024" height="768" multitouch="no"/>
|
||||
!<hid/>
|
||||
!...
|
||||
|
||||
If a touchscreen is multi-touch-capable than the multitouch attribute gears
|
||||
which type of Genode input events are generated. If set to 'no' (default)
|
||||
than absolute events are generated and no multitouch events. If set to 'yes'
|
||||
solely multitouch events are generated.
|
||||
|
||||
Storage
|
||||
~~~~~~~
|
||||
|
||||
|
@ -3781,7 +3781,8 @@ static inline void dump_stack(void) { }
|
||||
enum input_event_type {
|
||||
EVENT_TYPE_PRESS, EVENT_TYPE_RELEASE, /* key press and release */
|
||||
EVENT_TYPE_MOTION, /* any type of (pointer) motion */
|
||||
EVENT_TYPE_WHEEL /* mouse scroll wheel */
|
||||
EVENT_TYPE_WHEEL, /* mouse scroll wheel */
|
||||
EVENT_TYPE_TOUCH /* touchscreen events */
|
||||
};
|
||||
|
||||
struct input_handle;
|
||||
@ -3822,13 +3823,13 @@ typedef void (*genode_input_event_cb)(enum input_event_type type,
|
||||
* \return 0 on success; !0 otherwise
|
||||
*/
|
||||
void genode_input_register(genode_input_event_cb handler, unsigned long res_x,
|
||||
unsigned long res_y);
|
||||
unsigned long res_y, bool multitouch);
|
||||
|
||||
|
||||
void genode_evdev_event(struct input_handle *handle, unsigned int type,
|
||||
unsigned int code, int value);
|
||||
|
||||
void start_input_service(void *ep, unsigned long res_x, unsigned long res_y);
|
||||
void start_input_service(void *ep, void *);
|
||||
|
||||
|
||||
/******************
|
||||
|
@ -37,7 +37,8 @@ struct Services
|
||||
* Screen resolution used by touch devices to convert touchscreen
|
||||
* absolute coordinates to screen absolute coordinates
|
||||
*/
|
||||
unsigned long screen_width = 0;
|
||||
bool multitouch = false;
|
||||
unsigned long screen_width = 0;
|
||||
unsigned long screen_height = 0;
|
||||
|
||||
Services()
|
||||
@ -49,9 +50,10 @@ struct Services
|
||||
hid = true;
|
||||
|
||||
try {
|
||||
Genode::Xml_node node_screen = node_hid.sub_node("screen");
|
||||
Genode::Xml_node node_screen = node_hid.sub_node("touchscreen");
|
||||
node_screen.attribute("width").value(&screen_width);
|
||||
node_screen.attribute("height").value(&screen_height);
|
||||
multitouch = node_screen.attribute("multitouch").has_value("yes");
|
||||
} catch (...) {
|
||||
screen_width = screen_height = 0;
|
||||
PDBG("Could not read screen resolution in config node");
|
||||
|
@ -4,6 +4,7 @@
|
||||
* \author Dirk Vogt <dvogt@os.inf.tu-dresden.de>
|
||||
* \author Sebastian Sumpf <sebastian.sumpf@genode-labs.com>
|
||||
* \author Christian Menard <christian.menard@ksyslabs.org>
|
||||
* \author Alexander Boettcher <alexander.boettcher@genode-labs.com>
|
||||
* \date 2009-04-20
|
||||
*
|
||||
* The original implementation was in the L4Env from the TUD:OS group
|
||||
@ -12,7 +13,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2014 Genode Labs GmbH
|
||||
* Copyright (C) 2009-2015 Genode Labs GmbH
|
||||
* Copyright (C) 2014 Ksys Labs LLC
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
@ -28,9 +29,41 @@
|
||||
/* Callback function to Genode subsystem */
|
||||
static genode_input_event_cb handler;;
|
||||
|
||||
static unsigned long screen_x = 0;
|
||||
static unsigned long screen_y = 0;
|
||||
static unsigned long screen_x = 0;
|
||||
static unsigned long screen_y = 0;
|
||||
static bool disable_multitouch = true;
|
||||
static bool disable_absolute = false;
|
||||
|
||||
static struct slot
|
||||
{
|
||||
int id; /* current tracking id */
|
||||
int x; /* last reported x axis */
|
||||
int y; /* last reported y axis */
|
||||
int event; /* last reported ABS_MT_ event */
|
||||
} slots[16];
|
||||
|
||||
|
||||
static bool transform(struct input_handle *handle, int x, int y,
|
||||
int * arg_ax, int * arg_ay)
|
||||
{
|
||||
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 || !max_y_norm || !arg_ax || !arg_ay ||
|
||||
x < min_x_dev || y < min_y_dev || x > max_x_dev || y > max_y_dev) {
|
||||
printk("Ignore input source with coordinates out of range\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
*arg_ax = screen_x * (x - min_x_dev) / (max_x_norm);
|
||||
*arg_ay = screen_y * (y - min_y_dev) / (max_y_norm);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void genode_evdev_event(struct input_handle *handle, unsigned int type,
|
||||
unsigned int code, int value)
|
||||
@ -39,8 +72,8 @@ void genode_evdev_event(struct input_handle *handle, unsigned int type,
|
||||
static unsigned long count = 0;
|
||||
#endif
|
||||
|
||||
static int last_ax = -1; /* store the last absolute x value */
|
||||
|
||||
static int slot = 0; /* store current input slot */
|
||||
|
||||
/* filter sound events */
|
||||
if (test_bit(EV_SND, handle->dev->evbit)) return;
|
||||
|
||||
@ -60,8 +93,12 @@ void genode_evdev_event(struct input_handle *handle, unsigned int type,
|
||||
case EV_KEY:
|
||||
arg_keycode = code;
|
||||
|
||||
/* map BTN_TOUCH events to BTN_LEFT */
|
||||
if (code == BTN_TOUCH)
|
||||
/* don't generate press/release events for multitouch devices */
|
||||
if (code == BTN_TOUCH && !disable_multitouch)
|
||||
return;
|
||||
|
||||
/* map BTN_TOUCH events to BTN_LEFT for absolute events */
|
||||
if (code == BTN_TOUCH && !disable_absolute)
|
||||
arg_keycode = BTN_LEFT;
|
||||
|
||||
switch (value) {
|
||||
@ -83,68 +120,117 @@ void genode_evdev_event(struct input_handle *handle, unsigned int type,
|
||||
case EV_ABS:
|
||||
switch (code) {
|
||||
|
||||
case ABS_WHEEL:
|
||||
|
||||
if (disable_absolute) return;
|
||||
|
||||
arg_type = EVENT_TYPE_WHEEL;
|
||||
arg_ry = value;
|
||||
break;
|
||||
|
||||
case ABS_X:
|
||||
case ABS_MT_POSITION_X:
|
||||
|
||||
if (code == ABS_X && disable_absolute) return;
|
||||
if (code == ABS_MT_POSITION_X && disable_multitouch) return;
|
||||
|
||||
if (((slots[slot].event == ABS_MT_POSITION_X) ||
|
||||
(slots[slot].event == ABS_X)) && (slots[slot].y != -1)) {
|
||||
|
||||
arg_keycode = slot;
|
||||
arg_type = code == ABS_X ? EVENT_TYPE_MOTION : EVENT_TYPE_TOUCH;
|
||||
arg_ax = slots[slot].x;
|
||||
arg_ay = slots[slot].y;
|
||||
|
||||
if (screen_x && screen_y &&
|
||||
!transform(handle, arg_ax, arg_ay, &arg_ax, &arg_ay))
|
||||
return;
|
||||
|
||||
if (handler)
|
||||
handler(arg_type, arg_keycode, arg_ax, arg_ay, arg_rx, arg_ry);
|
||||
}
|
||||
|
||||
slots[slot].event = code;
|
||||
|
||||
/*
|
||||
* Don't create an input event yet. Store the value and wait for the
|
||||
* subsequent Y event.
|
||||
*/
|
||||
last_ax = value;
|
||||
slots[slot].x = value;
|
||||
return;
|
||||
|
||||
case ABS_Y:
|
||||
case ABS_MT_POSITION_Y:
|
||||
|
||||
if (code == ABS_Y && disable_absolute) return;
|
||||
if (code == ABS_MT_POSITION_Y && disable_multitouch) return;
|
||||
|
||||
slots[slot].event = code;
|
||||
slots[slot].y = value;
|
||||
|
||||
if (slots[slot].x == -1)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Create a unified input event with absolute positions on x and y
|
||||
* axis.
|
||||
*/
|
||||
arg_type = EVENT_TYPE_MOTION;
|
||||
arg_ax = last_ax;
|
||||
arg_ay = value;
|
||||
arg_keycode = slot;
|
||||
arg_type = code == ABS_Y ? EVENT_TYPE_MOTION : EVENT_TYPE_TOUCH;
|
||||
arg_ax = slots[slot].x;
|
||||
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 (screen_x && screen_y &&
|
||||
!transform(handle, arg_ax, value, &arg_ax, &arg_ay))
|
||||
return;
|
||||
|
||||
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;
|
||||
}
|
||||
break;
|
||||
|
||||
arg_ax = screen_x * (last_ax - min_x_dev) / (max_x_norm);
|
||||
arg_ay = screen_y * (value - min_y_dev) / (max_y_norm);
|
||||
}
|
||||
case ABS_MT_TRACKING_ID:
|
||||
|
||||
last_ax = -1;
|
||||
if (arg_ax == -1) {
|
||||
printk("Ignore absolute Y event without a preceeding X event\n");
|
||||
if (disable_multitouch) return;
|
||||
|
||||
if (value != -1) {
|
||||
if (slots[slot].id != -1)
|
||||
dde_kit_printf("warning:: old tracking id in use and got new one\n");
|
||||
|
||||
slots[slot].id = value;
|
||||
return;
|
||||
}
|
||||
|
||||
/* send end of slot usage event for clients */
|
||||
arg_keycode = slot;
|
||||
arg_type = EVENT_TYPE_TOUCH;
|
||||
arg_ax = slots[slot].x < 0 ? 0 : slots[slot].x;
|
||||
arg_ay = slots[slot].y < 0 ? 0 : slots[slot].y;
|
||||
arg_rx = arg_ry = -1;
|
||||
|
||||
if (screen_x && screen_y)
|
||||
transform(handle, arg_ax, arg_ay, &arg_ax, &arg_ay);
|
||||
|
||||
slots[slot].event = slots[slot].x = slots[slot].y = -1;
|
||||
slots[slot].id = value;
|
||||
|
||||
break;
|
||||
|
||||
case ABS_WHEEL:
|
||||
case ABS_MT_SLOT:
|
||||
|
||||
/*
|
||||
* 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;
|
||||
if (disable_multitouch) return;
|
||||
|
||||
if (value >= sizeof(slots) / sizeof(slots[0])) {
|
||||
dde_kit_printf("warning: drop slot id %d\n", value);
|
||||
return;
|
||||
}
|
||||
|
||||
slot = value;
|
||||
return;
|
||||
|
||||
default:
|
||||
|
||||
printk("Unknown absolute event code %d - not handled\n", code);
|
||||
return;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
@ -194,10 +280,18 @@ void genode_evdev_event(struct input_handle *handle, unsigned int type,
|
||||
|
||||
|
||||
void genode_input_register(genode_input_event_cb h, unsigned long res_x,
|
||||
unsigned long res_y)
|
||||
unsigned long res_y, bool multitouch)
|
||||
{
|
||||
unsigned i = 0;
|
||||
for (i = 0; i < sizeof(slots) / sizeof(slots[0]); i++)
|
||||
slots[i].id = slots[i].event = slots[i].x = slots[i].y = -1;
|
||||
|
||||
handler = h;
|
||||
|
||||
/* XXX make it per usb device configurable XXX */
|
||||
screen_x = res_x;
|
||||
screen_y = res_y;
|
||||
|
||||
disable_multitouch = !multitouch;
|
||||
disable_absolute = !disable_multitouch;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <lx_emul.h>
|
||||
#include <extern_c_end.h>
|
||||
|
||||
#include "platform.h"
|
||||
#undef RELEASE
|
||||
|
||||
using namespace Genode;
|
||||
@ -65,6 +66,7 @@ static void input_callback(enum input_event_type type,
|
||||
case EVENT_TYPE_RELEASE: t = Input::Event::RELEASE; break;
|
||||
case EVENT_TYPE_MOTION: t = Input::Event::MOTION; break;
|
||||
case EVENT_TYPE_WHEEL: t = Input::Event::WHEEL; break;
|
||||
case EVENT_TYPE_TOUCH: t = Input::Event::TOUCH; break;
|
||||
}
|
||||
|
||||
input_session().submit(Input::Event(t, code,
|
||||
@ -73,11 +75,13 @@ static void input_callback(enum input_event_type type,
|
||||
}
|
||||
|
||||
|
||||
void start_input_service(void *ep_ptr, unsigned long res_x, unsigned long res_y)
|
||||
void start_input_service(void *ep_ptr, void * service_ptr)
|
||||
{
|
||||
Rpc_entrypoint *ep = static_cast<Rpc_entrypoint *>(ep_ptr);
|
||||
Services *service = static_cast<Services *>(service_ptr);
|
||||
|
||||
env()->parent()->announce(ep->manage(&input_root(ep)));
|
||||
|
||||
genode_input_register(input_callback, res_x, res_y);
|
||||
genode_input_register(input_callback, service->screen_width,
|
||||
service->screen_height, service->multitouch);
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ extern "C" void module_ch_driver_init();
|
||||
extern "C" void module_mt_driver_init();
|
||||
extern "C" void module_raw_driver_init();
|
||||
|
||||
extern "C" void start_input_service(void *ep, unsigned long, unsigned long);
|
||||
extern "C" void start_input_service(void *ep, void *services);
|
||||
|
||||
Routine *Routine::_current = 0;
|
||||
Routine *Routine::_dead = 0;
|
||||
@ -94,8 +94,7 @@ void start_usb_driver(Server::Entrypoint &ep)
|
||||
Services services;
|
||||
|
||||
if (services.hid)
|
||||
start_input_service(&ep.rpc_ep(), services.screen_width,
|
||||
services.screen_height);
|
||||
start_input_service(&ep.rpc_ep(), &services);
|
||||
|
||||
Timer::init(ep);
|
||||
Irq::init(ep);
|
||||
|
Loading…
Reference in New Issue
Block a user