summaryrefslogtreecommitdiff
path: root/src/frame-mtdev.c
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2010-12-30 17:58:01 +0100
committerHenrik Rydberg <rydberg@euromail.se>2010-12-30 17:58:01 +0100
commitf0aba58c91933a4702a7cc74f7daf4192868f570 (patch)
tree648c41fe09adb72344769dd6242638cbad835482 /src/frame-mtdev.c
Initial load of utouch-framev1.0.0
Compiles and runs on mtdev. ABI proof. Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'src/frame-mtdev.c')
-rw-r--r--src/frame-mtdev.c189
1 files changed, 189 insertions, 0 deletions
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 @@
1/*****************************************************************************
2 *
3 * utouch-frame - Touch Frame Library
4 *
5 * Copyright (C) 2010 Canonical Ltd.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 ****************************************************************************/
21
22#include <utouch/frame-mtdev.h>
23#include "frame-impl.h"
24#include <linux/input.h>
25#include <errno.h>
26#include <math.h>
27
28int utouch_frame_is_supported_mtdev(const struct evemu_device *dev)
29{
30
31 /* only support pure absolute devices at this time */
32 if (evemu_has_event(dev, EV_REL, REL_X) ||
33 evemu_has_event(dev, EV_REL, REL_Y))
34 return 0;
35
36 if (evemu_has_event(dev, EV_ABS, ABS_MT_POSITION_X) &&
37 evemu_has_event(dev, EV_ABS, ABS_MT_POSITION_Y))
38 return 1;
39
40 return evemu_has_event(dev, EV_ABS, ABS_X) &&
41 evemu_has_event(dev, EV_ABS, ABS_Y) &&
42 evemu_has_event(dev, EV_KEY, BTN_TOUCH) &&
43 evemu_has_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP);
44}
45
46int utouch_frame_init_mtdev(utouch_frame_handle fh,
47 const struct evemu_device *dev)
48{
49 struct utouch_surface *s = fh->surface;
50 float tmp;
51
52 if (!utouch_frame_is_supported_mtdev(dev))
53 return -ENODEV;
54
55#ifdef INPUT_PROP_POINTER
56 s->needs_pointer = evemu_has_prop(dev, INPUT_PROP_POINTER);
57 s->is_direct = evemu_has_prop(dev, INPUT_PROP_DIRECT);
58 s->is_buttonpad = evemu_has_prop(dev, INPUT_PROP_BUTTONPAD);
59 s->is_semi_mt = evemu_has_prop(dev, INPUT_PROP_SEMI_MT);
60#endif
61 s->use_touch_major = evemu_has_event(dev, EV_ABS, ABS_MT_TOUCH_MAJOR);
62 s->use_touch_minor = evemu_has_event(dev, EV_ABS, ABS_MT_TOUCH_MINOR);
63 s->use_width_major = evemu_has_event(dev, EV_ABS, ABS_MT_WIDTH_MAJOR);
64 s->use_width_minor = evemu_has_event(dev, EV_ABS, ABS_MT_WIDTH_MINOR);
65 s->use_orientation = evemu_has_event(dev, EV_ABS, ABS_MT_ORIENTATION);
66 s->use_pressure = evemu_has_event(dev, EV_ABS, ABS_MT_PRESSURE);
67#ifdef ABS_MT_DISTANCE
68 s->use_distance = evemu_has_event(dev, EV_ABS, ABS_MT_DISTANCE);
69#endif
70
71
72 s->min_x = evemu_get_abs_minimum(dev, ABS_MT_POSITION_X);
73 s->min_y = evemu_get_abs_minimum(dev, ABS_MT_POSITION_Y);
74 s->max_x = evemu_get_abs_maximum(dev, ABS_MT_POSITION_X);
75 s->max_y = evemu_get_abs_maximum(dev, ABS_MT_POSITION_Y);
76 if (s->min_x == s->max_x) {
77 s->min_x = 0;
78 s->max_x = 1024;
79 }
80 if (s->min_y == s->max_y) {
81 s->min_y = 0;
82 s->max_y = 768;
83 }
84
85 s->max_pressure = evemu_get_abs_maximum(dev, ABS_MT_PRESSURE);
86 if (s->use_pressure && s->max_pressure == 0)
87 s->max_pressure = 256;
88
89 fh->max_orient = evemu_get_abs_maximum(dev, ABS_MT_ORIENTATION);
90 if (s->use_orientation && fh->max_orient == 0)
91 fh->max_orient = 1;
92
93 tmp = evemu_get_abs_resolution(dev, ABS_MT_POSITION_X);
94 if (tmp > 0)
95 s->phys_width = (s->max_x - s->min_x) / tmp;
96 else if (s->needs_pointer)
97 s->phys_width = 100;
98 else
99 s->phys_width = 250;
100
101 tmp = evemu_get_abs_resolution(dev, ABS_MT_POSITION_Y);
102 if (tmp > 0)
103 s->phys_height = (s->max_y - s->min_y) / tmp;
104 else if (s->needs_pointer)
105 s->phys_height = 65;
106 else
107 s->phys_height = 160;
108
109 tmp = evemu_get_abs_resolution(dev, ABS_MT_PRESSURE);
110 if (tmp > 0)
111 s->phys_pressure = s->max_pressure / tmp;
112 else
113 s->phys_pressure = 10;
114
115 return 0;
116}
117
118static float touch_angle(utouch_frame_handle fh, int orient)
119{
120 return orient / fh->max_orient * M_PI_2;
121}
122
123static int handle_abs_event(utouch_frame_handle fh,
124 const struct input_event *ev)
125{
126 struct utouch_contact *t = utouch_frame_get_current_slot(fh);
127
128 switch (ev->code) {
129 case ABS_MT_SLOT:
130 utouch_frame_set_current_slot(fh, ev->value);
131 return 1;
132 case ABS_MT_POSITION_X:
133 t->x = ev->value;
134 return 1;
135 case ABS_MT_POSITION_Y:
136 t->y = ev->value;
137 return 1;
138 case ABS_MT_TOUCH_MAJOR:
139 t->touch_major = ev->value;
140 return 1;
141 case ABS_MT_TOUCH_MINOR:
142 t->touch_minor = ev->value;
143 return 1;
144 case ABS_MT_WIDTH_MAJOR:
145 t->width_major = ev->value;
146 return 1;
147 case ABS_MT_WIDTH_MINOR:
148 t->width_minor = ev->value;
149 return 1;
150 case ABS_MT_ORIENTATION:
151 t->orientation = touch_angle(fh, ev->value);
152 return 1;
153 case ABS_MT_PRESSURE:
154 t->pressure = ev->value;
155 return 1;
156#ifdef ABS_MT_DISTANCE
157 case ABS_MT_DISTANCE:
158 t->distance = ev->value;
159 return 1;
160#endif
161 case ABS_MT_TOOL_TYPE:
162 t->tool_type = ev->value;
163 return 1;
164 case ABS_MT_TRACKING_ID:
165 t->id = ev->value;
166 return 1;
167 default:
168 return 0;
169 }
170}
171
172static utouch_frame_time_t get_evtime_ms(const struct input_event *syn)
173{
174 static const utouch_frame_time_t ms = 1000;
175 return syn->time.tv_usec / ms + syn->time.tv_sec * ms;
176}
177
178const struct utouch_frame *
179utouch_frame_pump_mtdev(utouch_frame_handle fh, const struct input_event *ev)
180{
181 const struct utouch_frame *f = 0;
182
183 if (ev->type == EV_SYN && ev->code == SYN_REPORT)
184 f = utouch_frame_sync(fh, get_evtime_ms(ev));
185 else if (ev->type == EV_ABS)
186 handle_abs_event(fh, ev);
187
188 return f;
189}