diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/ecore/src/lib/ecore_fb/ecore_fb_ts.c | 355 |
1 files changed, 355 insertions, 0 deletions
diff --git a/libraries/ecore/src/lib/ecore_fb/ecore_fb_ts.c b/libraries/ecore/src/lib/ecore_fb/ecore_fb_ts.c new file mode 100644 index 0000000..395e768 --- /dev/null +++ b/libraries/ecore/src/lib/ecore_fb/ecore_fb_ts.c | |||
@@ -0,0 +1,355 @@ | |||
1 | #ifdef HAVE_CONFIG_H | ||
2 | # include <config.h> | ||
3 | #endif | ||
4 | |||
5 | #ifdef HAVE_TSLIB | ||
6 | # include <tslib.h> | ||
7 | # include <errno.h> | ||
8 | #endif | ||
9 | |||
10 | #include "Ecore_Fb.h" | ||
11 | #include "ecore_fb_private.h" | ||
12 | |||
13 | typedef struct _Ecore_Fb_Ts_Event Ecore_Fb_Ts_Event; | ||
14 | typedef struct _Ecore_Fb_Ts_Calibrate Ecore_Fb_Ts_Calibrate; | ||
15 | typedef struct _Ecore_Fb_Ts_Backlight Ecore_Fb_Ts_Backlight; | ||
16 | typedef struct _Ecore_Fb_Ts_Contrast Ecore_Fb_Ts_Contrast; | ||
17 | typedef struct _Ecore_Fb_Ts_Led Ecore_Fb_Ts_Led; | ||
18 | typedef struct _Ecore_Fb_Ts_Flite Ecore_Fb_Ts_Flite; | ||
19 | |||
20 | struct _Ecore_Fb_Ts_Event | ||
21 | { | ||
22 | unsigned short pressure; | ||
23 | unsigned short x; | ||
24 | unsigned short y; | ||
25 | unsigned short _unused; | ||
26 | }; | ||
27 | |||
28 | struct _Ecore_Fb_Ts_Calibrate | ||
29 | { | ||
30 | int xscale; | ||
31 | int xtrans; | ||
32 | int yscale; | ||
33 | int ytrans; | ||
34 | int xyswap; | ||
35 | }; | ||
36 | |||
37 | struct _Ecore_Fb_Ts_Backlight | ||
38 | { | ||
39 | int on; | ||
40 | unsigned char brightness; | ||
41 | }; | ||
42 | |||
43 | struct _Ecore_Fb_Ts_Contrast | ||
44 | { | ||
45 | unsigned char contrast; | ||
46 | }; | ||
47 | |||
48 | struct _Ecore_Fb_Ts_Led | ||
49 | { | ||
50 | unsigned char on; | ||
51 | unsigned char blink_time; | ||
52 | unsigned char on_time; | ||
53 | unsigned char off_time; | ||
54 | }; | ||
55 | |||
56 | struct _Ecore_Fb_Ts_Flite | ||
57 | { | ||
58 | unsigned char mode; | ||
59 | unsigned char pwr; | ||
60 | unsigned char brightness; | ||
61 | }; | ||
62 | |||
63 | static Eina_Bool _ecore_fb_ts_fd_handler(void *data, Ecore_Fd_Handler *fd_handler); | ||
64 | static int _ecore_fb_ts_fd = -1; | ||
65 | static int _ecore_fb_ts_event_byte_count = 0; | ||
66 | static int _ecore_fb_ts_apply_cal = 0; | ||
67 | static Ecore_Fb_Ts_Event _ecore_fb_ts_event; | ||
68 | static Ecore_Fb_Ts_Calibrate _ecore_fb_ts_cal = {1,1,0,0,0}; | ||
69 | static Ecore_Fd_Handler *_ecore_fb_ts_fd_handler_handle = NULL; | ||
70 | |||
71 | #ifdef HAVE_TSLIB | ||
72 | struct tsdev *_ecore_fb_tslib_tsdev = NULL; | ||
73 | struct ts_sample _ecore_fb_tslib_event; | ||
74 | #endif | ||
75 | |||
76 | static double _ecore_fb_double_click_time = 0.25; | ||
77 | static void *_ecore_fb_ts_event_window = NULL; | ||
78 | |||
79 | EAPI int | ||
80 | ecore_fb_ts_init(void) | ||
81 | { | ||
82 | #ifdef HAVE_TSLIB | ||
83 | char *tslib_tsdevice = NULL; | ||
84 | if ( (tslib_tsdevice = getenv("TSLIB_TSDEVICE")) ) | ||
85 | { | ||
86 | printf( "ECORE_FB: TSLIB_TSDEVICE = '%s'\n", tslib_tsdevice ); | ||
87 | _ecore_fb_tslib_tsdev = ts_open( tslib_tsdevice, 1 ); /* 1 = nonblocking, 0 = blocking */ | ||
88 | |||
89 | if ( !_ecore_fb_tslib_tsdev ) | ||
90 | { | ||
91 | printf( "ECORE_FB: Can't ts_open (%s)\n", strerror( errno ) ); | ||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | if ( ts_config( _ecore_fb_tslib_tsdev ) ) | ||
96 | { | ||
97 | printf( "ECORE_FB: Can't ts_config (%s)\n", strerror( errno ) ); | ||
98 | return 0; | ||
99 | } | ||
100 | _ecore_fb_ts_fd = ts_fd( _ecore_fb_tslib_tsdev ); | ||
101 | if ( _ecore_fb_ts_fd < 0 ) | ||
102 | { | ||
103 | printf( "ECORE_FB: Can't open touchscreen (%s)\n", strerror( errno ) ); | ||
104 | return 0; | ||
105 | } | ||
106 | } | ||
107 | #else | ||
108 | _ecore_fb_ts_fd = open("/dev/touchscreen/0", O_RDONLY); | ||
109 | #endif | ||
110 | if (_ecore_fb_ts_fd >= 0) | ||
111 | { | ||
112 | _ecore_fb_ts_fd_handler_handle = ecore_main_fd_handler_add(_ecore_fb_ts_fd, | ||
113 | ECORE_FD_READ, | ||
114 | _ecore_fb_ts_fd_handler, NULL, | ||
115 | NULL, NULL); | ||
116 | if (!_ecore_fb_ts_fd_handler_handle) | ||
117 | { | ||
118 | close(_ecore_fb_ts_fd); | ||
119 | return 0; | ||
120 | } | ||
121 | // FIXME _ecore_fb_kbd_fd = open("/dev/touchscreen/key", O_RDONLY); | ||
122 | return 1; | ||
123 | } | ||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | EAPI void | ||
128 | ecore_fb_ts_shutdown(void) | ||
129 | { | ||
130 | if (_ecore_fb_ts_fd_handler_handle) | ||
131 | ecore_main_fd_handler_del(_ecore_fb_ts_fd_handler_handle); | ||
132 | if (_ecore_fb_ts_fd >= 0) close(_ecore_fb_ts_fd); | ||
133 | _ecore_fb_ts_fd = -1; | ||
134 | _ecore_fb_ts_fd_handler_handle = NULL; | ||
135 | _ecore_fb_ts_event_window = NULL; | ||
136 | } | ||
137 | |||
138 | EAPI void | ||
139 | ecore_fb_ts_event_window_set(void *window) | ||
140 | { | ||
141 | _ecore_fb_ts_event_window = window; | ||
142 | } | ||
143 | |||
144 | EAPI void * | ||
145 | ecore_fb_ts_event_window_get(void) | ||
146 | { | ||
147 | return _ecore_fb_ts_event_window; | ||
148 | } | ||
149 | |||
150 | /** | ||
151 | * @defgroup Ecore_FB_Calibrate_Group Framebuffer Calibration Functions | ||
152 | * | ||
153 | * Functions that calibrate the screen. | ||
154 | */ | ||
155 | |||
156 | |||
157 | /** | ||
158 | * Calibrates the touschreen using the given parameters. | ||
159 | * @param xscale X scaling, where 256 = 1.0 | ||
160 | * @param xtrans X translation. | ||
161 | * @param yscale Y scaling. | ||
162 | * @param ytrans Y translation. | ||
163 | * @param xyswap Swap X & Y flag. | ||
164 | * @ingroup Ecore_FB_Calibrate_Group | ||
165 | */ | ||
166 | EAPI void | ||
167 | ecore_fb_touch_screen_calibrate_set(int xscale, int xtrans, int yscale, int ytrans, int xyswap) | ||
168 | { | ||
169 | Ecore_Fb_Ts_Calibrate cal; | ||
170 | |||
171 | if (_ecore_fb_ts_fd < 0) return; | ||
172 | cal.xscale = xscale; | ||
173 | cal.xtrans = xtrans; | ||
174 | cal.yscale = yscale; | ||
175 | cal.ytrans = ytrans; | ||
176 | cal.xyswap = xyswap; | ||
177 | if (ioctl(_ecore_fb_ts_fd, TS_SET_CAL, (void *)&cal)) | ||
178 | { | ||
179 | _ecore_fb_ts_cal = cal; | ||
180 | _ecore_fb_ts_apply_cal = 1; | ||
181 | } | ||
182 | } | ||
183 | |||
184 | /** | ||
185 | * Retrieves the calibration parameters of the touchscreen. | ||
186 | * @param xscale Pointer to an integer in which to store the X scaling. | ||
187 | * Note that 256 = 1.0. | ||
188 | * @param xtrans Pointer to an integer in which to store the X translation. | ||
189 | * @param yscale Pointer to an integer in which to store the Y scaling. | ||
190 | * @param ytrans Pointer to an integer in which to store the Y translation. | ||
191 | * @param xyswap Pointer to an integer in which to store the Swap X & Y flag. | ||
192 | * @ingroup Ecore_FB_Calibrate_Group | ||
193 | */ | ||
194 | EAPI void | ||
195 | ecore_fb_touch_screen_calibrate_get(int *xscale, int *xtrans, int *yscale, int *ytrans, int *xyswap) | ||
196 | { | ||
197 | Ecore_Fb_Ts_Calibrate cal; | ||
198 | |||
199 | if (_ecore_fb_ts_fd < 0) return; | ||
200 | if (!_ecore_fb_ts_apply_cal) | ||
201 | { | ||
202 | if (ioctl(_ecore_fb_ts_fd, TS_GET_CAL, (void *)&cal)) | ||
203 | _ecore_fb_ts_cal = cal; | ||
204 | } | ||
205 | else | ||
206 | cal = _ecore_fb_ts_cal; | ||
207 | if (xscale) *xscale = cal.xscale; | ||
208 | if (xtrans) *xtrans = cal.xtrans; | ||
209 | if (yscale) *yscale = cal.yscale; | ||
210 | if (ytrans) *ytrans = cal.ytrans; | ||
211 | if (xyswap) *xyswap = cal.xyswap; | ||
212 | } | ||
213 | |||
214 | static Eina_Bool | ||
215 | _ecore_fb_ts_fd_handler(void *data __UNUSED__, Ecore_Fd_Handler *fd_handler __UNUSED__) | ||
216 | { | ||
217 | static int prev_x = 0, prev_y = 0, prev_pressure = 0; | ||
218 | static double last_time = 0; | ||
219 | static double last_last_time = 0; | ||
220 | int v = 0; | ||
221 | |||
222 | do | ||
223 | { | ||
224 | int x, y, pressure; | ||
225 | int num; | ||
226 | char *ptr; | ||
227 | double t = 0.0; | ||
228 | static int did_double = 0; | ||
229 | static int did_triple = 0; | ||
230 | |||
231 | #ifdef HAVE_TSLIB | ||
232 | if (_ecore_fb_ts_apply_cal) | ||
233 | num = ts_read_raw(_ecore_fb_tslib_tsdev, &_ecore_fb_tslib_event, 1); | ||
234 | else | ||
235 | num = ts_read(_ecore_fb_tslib_tsdev, &_ecore_fb_tslib_event, 1); | ||
236 | if (num != 1) return 1; /* no more samples at this time */ | ||
237 | x = _ecore_fb_tslib_event.x; | ||
238 | y = _ecore_fb_tslib_event.y; | ||
239 | pressure = _ecore_fb_tslib_event.pressure; | ||
240 | v = 1; /* loop, there might be more samples */ | ||
241 | t = ecore_time_get(); | ||
242 | #else | ||
243 | ptr = (char *)&(_ecore_fb_ts_event); | ||
244 | ptr += _ecore_fb_ts_event_byte_count; | ||
245 | num = sizeof(Ecore_Fb_Ts_Event) - _ecore_fb_ts_event_byte_count; | ||
246 | v = read(_ecore_fb_ts_fd, ptr, num); | ||
247 | if (v < 0) return 1; | ||
248 | _ecore_fb_ts_event_byte_count += v; | ||
249 | if (v < num) return 1; | ||
250 | _ecore_fb_ts_event_byte_count = 0; | ||
251 | if (_ecore_fb_ts_apply_cal) | ||
252 | { | ||
253 | x = ((_ecore_fb_ts_cal.xscale * _ecore_fb_ts_event.x) >> 8) + _ecore_fb_ts_cal.xtrans; | ||
254 | y = ((_ecore_fb_ts_cal.yscale * _ecore_fb_ts_event.y) >> 8) + _ecore_fb_ts_cal.ytrans; | ||
255 | } | ||
256 | else | ||
257 | { | ||
258 | x = _ecore_fb_ts_event.x; | ||
259 | y = _ecore_fb_ts_event.y; | ||
260 | } | ||
261 | pressure = _ecore_fb_ts_event.pressure; | ||
262 | #endif | ||
263 | /* add event to queue */ | ||
264 | /* always add a move event */ | ||
265 | if ((pressure) || (prev_pressure)) | ||
266 | { | ||
267 | /* MOVE: mouse is down and was */ | ||
268 | Ecore_Event_Mouse_Move *e; | ||
269 | |||
270 | e = calloc(1, sizeof(Ecore_Event_Mouse_Move)); | ||
271 | if (!e) goto retry; | ||
272 | e->x = x; | ||
273 | e->y = y; | ||
274 | e->root.x = x; | ||
275 | e->root.y = y; | ||
276 | e->window = (Ecore_Window)_ecore_fb_ts_event_window; | ||
277 | e->event_window = e->window; | ||
278 | e->root_window = e->window; | ||
279 | e->same_screen = 1; | ||
280 | ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, NULL, NULL); | ||
281 | } | ||
282 | if ((pressure) && (!prev_pressure)) | ||
283 | { | ||
284 | /* DOWN: mouse is down, but was not now */ | ||
285 | Ecore_Event_Mouse_Button *e; | ||
286 | |||
287 | e = calloc(1, sizeof(Ecore_Event_Mouse_Button)); | ||
288 | if (!e) goto retry; | ||
289 | e->x = x; | ||
290 | e->y = y; | ||
291 | e->buttons = 1; | ||
292 | if ((t - last_time) <= _ecore_fb_double_click_time) | ||
293 | { | ||
294 | e->double_click = 1; | ||
295 | did_double = 1; | ||
296 | } | ||
297 | else | ||
298 | { | ||
299 | did_double = 0; | ||
300 | did_triple = 0; | ||
301 | } | ||
302 | if ((t - last_last_time) <= (2 * _ecore_fb_double_click_time)) | ||
303 | { | ||
304 | did_triple = 1; | ||
305 | e->triple_click = 1; | ||
306 | } | ||
307 | else | ||
308 | { | ||
309 | did_triple = 0; | ||
310 | } | ||
311 | e->window = (Ecore_Window)_ecore_fb_ts_event_window; | ||
312 | e->event_window = e->window; | ||
313 | e->root_window = e->window; | ||
314 | e->same_screen = 1; | ||
315 | ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, e, NULL, NULL); | ||
316 | } | ||
317 | else if ((!pressure) && (prev_pressure)) | ||
318 | { | ||
319 | /* UP: mouse was down, but is not now */ | ||
320 | Ecore_Event_Mouse_Button *e; | ||
321 | |||
322 | e = calloc(1, sizeof(Ecore_Event_Mouse_Button)); | ||
323 | if (!e) goto retry; | ||
324 | e->x = prev_x; | ||
325 | e->y = prev_y; | ||
326 | e->buttons = 1; | ||
327 | if (did_double) | ||
328 | e->double_click = 1; | ||
329 | if (did_triple) | ||
330 | e->triple_click = 1; | ||
331 | e->window = (Ecore_Window)_ecore_fb_ts_event_window; | ||
332 | e->event_window = e->window; | ||
333 | e->root_window = e->window; | ||
334 | e->same_screen = 1; | ||
335 | ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, e, NULL, NULL); | ||
336 | } | ||
337 | if (did_triple) | ||
338 | { | ||
339 | last_time = 0; | ||
340 | last_last_time = 0; | ||
341 | } | ||
342 | else | ||
343 | { | ||
344 | last_last_time = last_time; | ||
345 | last_time = t; | ||
346 | } | ||
347 | retry: | ||
348 | prev_x = x; | ||
349 | prev_y = y; | ||
350 | prev_pressure = pressure; | ||
351 | } | ||
352 | while (v > 0); | ||
353 | return 1; | ||
354 | } | ||
355 | |||