svn update: 60286 (latest:60286)
[profile/ivi/ecore.git] / src / lib / ecore_fb / ecore_fb_ps2.c
1 typedef struct _Ecore_Fb_Ps2_Event Ecore_Fb_Ps2_Event;
2 struct _Ecore_Fb_Ps2_Event
3 {
4    unsigned char button;
5    unsigned char x;
6    unsigned char y;
7    unsigned char z;
8 };
9
10 static int _ecore_fb_ps2_event_byte_count = 0;
11 static Ecore_Fb_Ps2_Event _ecore_fb_ps2_event;
12 static int _ecore_fb_ps2_fd = 0;
13 static Eina_Bool _ecore_fb_ps2_fd_handler(void *data, Ecore_Fd_Handler *fd_handler);
14
15 int
16 ecore_fb_ps2_init(void)
17 {
18    _ecore_fb_ps2_fd = open("/dev/psaux", O_RDWR);
19    if (_ecore_fb_ps2_fd >= 0)
20      {
21         prev_flags = fcntl(_ecore_fb_ps2_fd, F_GETFL);
22         fcntl(_ecore_fb_ps2_fd, F_SETFL, prev_flags | O_NONBLOCK);
23         _ecore_fb_ts_fd_handler_handle = ecore_main_fd_handler_add(_ecore_fb_ps2_fd,
24                                                                    ECORE_FD_READ,
25                                                                    _ecore_fb_ps2_fd_handler, NULL, NULL, NULL);
26         if (!_ecore_fb_ts_fd_handler_handle)
27           {
28              close(_ecore_fb_ps2_fd);
29              return 0;
30           }
31         return 1;
32      }
33    return 0;
34 }
35
36 void
37 ecore_fb_ps2_shutdown(void)
38 {
39    if (_ecore_fb_ps2_fd > 0) close(_ecore_fb_ps2_fd);
40    _ecore_fb_ps2_fd = 0;
41 }
42
43 static Eina_Bool
44 _ecore_fb_ps2_fd_handler(void *data __UNUSED__, Ecore_Fd_Handler *fd_handler __UNUSED__)
45 {
46    static int prev_x = 0, prev_y = 0, prev_button = 0;
47    static double last_time = 0;
48    static double last_last_time = 0;
49    int v = 0;
50
51    do
52      {
53         int x, y, button, i;
54         int num;
55         char *ptr;
56         double t;
57         static int did_double = 0;
58         static int did_triple = 0;
59
60         ptr = (char *)&(_ecore_fb_ps2_event);
61         ptr += _ecore_fb_ps2_event_byte_count;
62         num = sizeof(Ecore_Fb_Ps2_Event) - _ecore_fb_ps2_event_byte_count;
63         v = read(_ecore_fb_ps2_fd, ptr, num);
64         if (v < 0) return EINA_TRUE;
65         _ecore_fb_ps2_event_byte_count += v;
66         if (v < num) return EINA_TRUE;
67         t = ecore_time_get();
68         _ecore_fb_ps2_event_byte_count = 0;
69         if (_ecore_fb_ps2_event.button & 0x10)
70            x = prev_x + (0xffffff00 | _ecore_fb_ps2_event.x);
71         else
72            x = prev_x + _ecore_fb_ps2_event.x;
73         if (_ecore_fb_ps2_event.button & 0x20)
74            y = prev_y - (0xffffff00 | _ecore_fb_ps2_event.y);
75         else
76            y = prev_y - _ecore_fb_ps2_event.y;
77         button = _ecore_fb_ps2_event.button & 0x7;
78         if (x < 0) x = 0;
79         if (y < 0) y = 0;
80         if (x >= _ecore_fb_console_w) x = _ecore_fb_console_w - 1;
81         if (y >= _ecore_fb_console_h) y = _ecore_fb_console_h - 1;
82         /* add event to queue */
83         /* always add a move event */
84         if (1)
85           {
86              /* MOVE: mouse is down and was */
87              Ecore_Fb_Event_Mouse_Move *e;
88
89              e = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Move));
90              if (!e) goto retry;
91              e->x = x;
92              e->y = y;
93              ecore_event_add(ECORE_FB_EVENT_MOUSE_MOVE, e, NULL, NULL);
94           }
95         for (i = 1; i <= 3; i++)
96           {
97              int mask;
98
99              mask = 1 << (i - 1);
100              if (((button & mask)) && (!(prev_button & mask)))
101                {
102                   /* DOWN: mouse is down, but was not now */
103                   Ecore_Fb_Event_Mouse_Button_Down *e;
104
105                   e = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Button_Down));
106                   if (!e) goto retry;
107                   e->x = x;
108                   e->y = y;
109                   e->button = i;
110                   if ((t - last_time) <= _ecore_fb_double_click_time)
111                     {
112                        e->double_click = 1;
113                        did_double = 1;
114                     }
115                   else
116                     {
117                        did_double = 0;
118                        did_triple = 0;
119                     }
120                   if ((t - last_last_time) <= (2 * _ecore_fb_double_click_time))
121                     {
122                        did_triple = 1;
123                        e->triple_click = 1;
124                     }
125                   else
126                     {
127                        did_triple = 0;
128                     }
129                   ecore_event_add(ECORE_FB_EVENT_MOUSE_BUTTON_DOWN, e, NULL, NULL);
130                }
131              else if ((!(button & mask)) && ((prev_button & mask)))
132                {
133                   /* UP: mouse was down, but is not now */
134                   Ecore_Fb_Event_Mouse_Button_Up *e;
135
136                   e = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Button_Up));
137                   if (!e) goto retry;
138                   e->x = x;
139                   e->y = y;
140                   e->button = i;
141                   if (did_double)
142                      e->double_click = 1;
143                   if (did_triple)
144                      e->triple_click = 1;
145                   ecore_event_add(ECORE_FB_EVENT_MOUSE_BUTTON_UP, e, NULL, NULL);
146                }
147           }
148         if (did_triple)
149           {
150              last_time = 0;
151              last_last_time = 0;
152           }
153         else
154           {
155              last_last_time = last_time;
156              last_time = t;
157           }
158         retry:
159         prev_x = x;
160         prev_y = y;
161         prev_button = button;
162      }
163    while (v > 0);
164    return EINA_TRUE;
165 }
166 /**
167  * @defgroup Ecore_FB_Click_Group Framebuffer Double Click Functions
168  *
169  * Functions that deal with the double click time of the framebuffer.
170  */
171
172 /**
173  * Sets the timeout for a double and triple clicks to be flagged.
174  *
175  * This sets the time between clicks before the double_click flag is
176  * set in a button down event. If 3 clicks occur within double this
177  * time, the triple_click flag is also set.
178  *
179  * @param   t The time in seconds
180  * @ingroup Ecore_FB_Click_Group
181  */
182 EAPI void
183 ecore_fb_double_click_time_set(double t)
184 {
185    if (t < 0.0) t = 0.0;
186    _ecore_fb_double_click_time = t;
187 }
188
189 /**
190  * Retrieves the double and triple click flag timeout.
191  *
192  * See @ref ecore_x_double_click_time_set for more information.
193  *
194  * @return  The timeout for double clicks in seconds.
195  * @ingroup Ecore_FB_Click_Group
196  */
197 EAPI double
198 ecore_fb_double_click_time_get(void)
199 {
200    return _ecore_fb_double_click_time;
201 }
202