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