revert async compositior
[framework/uifw/ecore.git] / src / lib / ecore_fb / ecore_fb_ts.c
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 #else
242         ptr = (char *)&(_ecore_fb_ts_event);
243         ptr += _ecore_fb_ts_event_byte_count;
244         num = sizeof(Ecore_Fb_Ts_Event) - _ecore_fb_ts_event_byte_count;
245         v = read(_ecore_fb_ts_fd, ptr, num);
246         if (v < 0) return 1;
247         _ecore_fb_ts_event_byte_count += v;
248         if (v < num) return 1;
249         _ecore_fb_ts_event_byte_count = 0;
250         if (_ecore_fb_ts_apply_cal)
251           {
252              x = ((_ecore_fb_ts_cal.xscale * _ecore_fb_ts_event.x) >> 8) + _ecore_fb_ts_cal.xtrans;
253              y = ((_ecore_fb_ts_cal.yscale * _ecore_fb_ts_event.y) >> 8) + _ecore_fb_ts_cal.ytrans;
254           }
255         else
256           {
257              x = _ecore_fb_ts_event.x;
258              y = _ecore_fb_ts_event.y;
259           }
260         pressure = _ecore_fb_ts_event.pressure;
261 #endif
262         t = ecore_loop_time_get();
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 = e->x;
275              e->root.y = e->y;
276              e->window = 1;
277              e->event_window = e->window;
278              e->root_window = e->window;
279              e->same_screen = 1;
280              e->timestamp = ecore_loop_time_get() * 1000.0;
281              ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, NULL, NULL);
282           }
283         if ((pressure) && (!prev_pressure))
284           {
285              /* DOWN: mouse is down, but was not now */
286              Ecore_Event_Mouse_Button *e;
287
288              e = calloc(1, sizeof(Ecore_Event_Mouse_Button));
289              if (!e) goto retry;
290              e->x = x;
291              e->y = y;
292              e->root.x = e->x;
293              e->root.y = e->y;
294              e->buttons = 1;
295              if ((t - last_time) <= _ecore_fb_double_click_time)
296                {
297                   e->double_click = 1;
298                   did_double = 1;
299                }
300              else
301                {
302                   did_double = 0;
303                   did_triple = 0;
304                }
305              if ((t - last_last_time) <= (2 * _ecore_fb_double_click_time))
306                {
307                   did_triple = 1;
308                   e->triple_click = 1;
309                }
310              else
311                {
312                   did_triple = 0;
313                }
314              e->window = 1;
315              e->event_window = e->window;
316              e->root_window = e->window;
317              e->same_screen = 1;
318              e->timestamp = ecore_loop_time_get() * 1000.0;
319              ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, e, NULL, NULL);
320           }
321         else if ((!pressure) && (prev_pressure))
322           {
323              /* UP: mouse was down, but is not now */
324              Ecore_Event_Mouse_Button *e;
325
326              e = calloc(1, sizeof(Ecore_Event_Mouse_Button));
327              if (!e) goto retry;
328              e->x = prev_x;
329              e->y = prev_y;
330              e->root.x = e->x;
331              e->root.y = e->y;
332              e->buttons = 1;
333              if (did_double)
334                 e->double_click = 1;
335              if (did_triple)
336                 e->triple_click = 1;
337              e->window = 1;
338              e->event_window = e->window;
339              e->root_window = e->window;
340              e->same_screen = 1;
341              e->timestamp = ecore_loop_time_get() * 1000.0;
342              ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, e, NULL, NULL);
343           }
344         if (did_triple)
345           {
346              last_time = 0;
347              last_last_time = 0;
348           }
349         else
350           {
351              last_last_time = last_time;
352              last_time = t;
353           }
354 retry:
355         prev_x = x;
356         prev_y = y;
357         prev_pressure = pressure;
358      }
359    while (v > 0);
360    return 1;
361 }
362