From f0aba58c91933a4702a7cc74f7daf4192868f570 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Thu, 30 Dec 2010 17:58:01 +0100 Subject: Initial load of utouch-frame Compiles and runs on mtdev. ABI proof. Signed-off-by: Henrik Rydberg --- src/frame-mtdev.c | 189 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 src/frame-mtdev.c (limited to 'src/frame-mtdev.c') diff --git a/src/frame-mtdev.c b/src/frame-mtdev.c new file mode 100644 index 0000000..ed5dc9e --- /dev/null +++ b/src/frame-mtdev.c @@ -0,0 +1,189 @@ +/***************************************************************************** + * + * utouch-frame - Touch Frame Library + * + * Copyright (C) 2010 Canonical Ltd. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + ****************************************************************************/ + +#include +#include "frame-impl.h" +#include +#include +#include + +int utouch_frame_is_supported_mtdev(const struct evemu_device *dev) +{ + + /* only support pure absolute devices at this time */ + if (evemu_has_event(dev, EV_REL, REL_X) || + evemu_has_event(dev, EV_REL, REL_Y)) + return 0; + + if (evemu_has_event(dev, EV_ABS, ABS_MT_POSITION_X) && + evemu_has_event(dev, EV_ABS, ABS_MT_POSITION_Y)) + return 1; + + return evemu_has_event(dev, EV_ABS, ABS_X) && + evemu_has_event(dev, EV_ABS, ABS_Y) && + evemu_has_event(dev, EV_KEY, BTN_TOUCH) && + evemu_has_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP); +} + +int utouch_frame_init_mtdev(utouch_frame_handle fh, + const struct evemu_device *dev) +{ + struct utouch_surface *s = fh->surface; + float tmp; + + if (!utouch_frame_is_supported_mtdev(dev)) + return -ENODEV; + +#ifdef INPUT_PROP_POINTER + s->needs_pointer = evemu_has_prop(dev, INPUT_PROP_POINTER); + s->is_direct = evemu_has_prop(dev, INPUT_PROP_DIRECT); + s->is_buttonpad = evemu_has_prop(dev, INPUT_PROP_BUTTONPAD); + s->is_semi_mt = evemu_has_prop(dev, INPUT_PROP_SEMI_MT); +#endif + s->use_touch_major = evemu_has_event(dev, EV_ABS, ABS_MT_TOUCH_MAJOR); + s->use_touch_minor = evemu_has_event(dev, EV_ABS, ABS_MT_TOUCH_MINOR); + s->use_width_major = evemu_has_event(dev, EV_ABS, ABS_MT_WIDTH_MAJOR); + s->use_width_minor = evemu_has_event(dev, EV_ABS, ABS_MT_WIDTH_MINOR); + s->use_orientation = evemu_has_event(dev, EV_ABS, ABS_MT_ORIENTATION); + s->use_pressure = evemu_has_event(dev, EV_ABS, ABS_MT_PRESSURE); +#ifdef ABS_MT_DISTANCE + s->use_distance = evemu_has_event(dev, EV_ABS, ABS_MT_DISTANCE); +#endif + + + s->min_x = evemu_get_abs_minimum(dev, ABS_MT_POSITION_X); + s->min_y = evemu_get_abs_minimum(dev, ABS_MT_POSITION_Y); + s->max_x = evemu_get_abs_maximum(dev, ABS_MT_POSITION_X); + s->max_y = evemu_get_abs_maximum(dev, ABS_MT_POSITION_Y); + if (s->min_x == s->max_x) { + s->min_x = 0; + s->max_x = 1024; + } + if (s->min_y == s->max_y) { + s->min_y = 0; + s->max_y = 768; + } + + s->max_pressure = evemu_get_abs_maximum(dev, ABS_MT_PRESSURE); + if (s->use_pressure && s->max_pressure == 0) + s->max_pressure = 256; + + fh->max_orient = evemu_get_abs_maximum(dev, ABS_MT_ORIENTATION); + if (s->use_orientation && fh->max_orient == 0) + fh->max_orient = 1; + + tmp = evemu_get_abs_resolution(dev, ABS_MT_POSITION_X); + if (tmp > 0) + s->phys_width = (s->max_x - s->min_x) / tmp; + else if (s->needs_pointer) + s->phys_width = 100; + else + s->phys_width = 250; + + tmp = evemu_get_abs_resolution(dev, ABS_MT_POSITION_Y); + if (tmp > 0) + s->phys_height = (s->max_y - s->min_y) / tmp; + else if (s->needs_pointer) + s->phys_height = 65; + else + s->phys_height = 160; + + tmp = evemu_get_abs_resolution(dev, ABS_MT_PRESSURE); + if (tmp > 0) + s->phys_pressure = s->max_pressure / tmp; + else + s->phys_pressure = 10; + + return 0; +} + +static float touch_angle(utouch_frame_handle fh, int orient) +{ + return orient / fh->max_orient * M_PI_2; +} + +static int handle_abs_event(utouch_frame_handle fh, + const struct input_event *ev) +{ + struct utouch_contact *t = utouch_frame_get_current_slot(fh); + + switch (ev->code) { + case ABS_MT_SLOT: + utouch_frame_set_current_slot(fh, ev->value); + return 1; + case ABS_MT_POSITION_X: + t->x = ev->value; + return 1; + case ABS_MT_POSITION_Y: + t->y = ev->value; + return 1; + case ABS_MT_TOUCH_MAJOR: + t->touch_major = ev->value; + return 1; + case ABS_MT_TOUCH_MINOR: + t->touch_minor = ev->value; + return 1; + case ABS_MT_WIDTH_MAJOR: + t->width_major = ev->value; + return 1; + case ABS_MT_WIDTH_MINOR: + t->width_minor = ev->value; + return 1; + case ABS_MT_ORIENTATION: + t->orientation = touch_angle(fh, ev->value); + return 1; + case ABS_MT_PRESSURE: + t->pressure = ev->value; + return 1; +#ifdef ABS_MT_DISTANCE + case ABS_MT_DISTANCE: + t->distance = ev->value; + return 1; +#endif + case ABS_MT_TOOL_TYPE: + t->tool_type = ev->value; + return 1; + case ABS_MT_TRACKING_ID: + t->id = ev->value; + return 1; + default: + return 0; + } +} + +static utouch_frame_time_t get_evtime_ms(const struct input_event *syn) +{ + static const utouch_frame_time_t ms = 1000; + return syn->time.tv_usec / ms + syn->time.tv_sec * ms; +} + +const struct utouch_frame * +utouch_frame_pump_mtdev(utouch_frame_handle fh, const struct input_event *ev) +{ + const struct utouch_frame *f = 0; + + if (ev->type == EV_SYN && ev->code == SYN_REPORT) + f = utouch_frame_sync(fh, get_evtime_ms(ev)); + else if (ev->type == EV_ABS) + handle_abs_event(fh, ev); + + return f; +} -- cgit v1.2.3