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