Bugs are fixed and new features are introduced
[platform/framework/web/data-provider-master.git] / src / event.c
1 #define _GNU_SOURCE
2 #include <stdio.h>
3 #include <errno.h>
4 #include <pthread.h>
5 #include <unistd.h>
6 #include <fcntl.h>
7 #include <string.h>
8 #include <sys/stat.h>
9 #include <sys/types.h>
10
11 #include <linux/input.h>
12
13 #include <Eina.h>
14 #include <Ecore.h>
15 #include <dlog.h>
16
17 #include "util.h"
18 #include "debug.h"
19 #include "conf.h"
20 #include "event.h"
21
22 #define CRITICAL_SECTION_BEGIN(lock) do { \
23         int ret; \
24         ret = pthread_mutex_lock(&lock); \
25         if (ret != 0) { \
26                 ErrPrint("Unable to get lock: %s\n", strerror(ret)); \
27         } \
28 } while (0)
29
30 #define CRITICAL_SECTION_END(lock) do { \
31         int ret; \
32         ret = pthread_mutex_unlock(&lock); \
33         if (ret != 0) { \
34                 ErrPrint("Unable to unlock: %s\n", strerror(ret)); \
35         } \
36 } while (0)
37
38 #define CANCEL_SECTION_BEGIN() do { \
39         int ret; \
40         ret = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); \
41         if (ret != 0) \
42                 ErrPrint("Unable to set cancelate state: %s\n", strerror(ret)); \
43 } while (0)
44
45 #define CANCEL_SECTION_END() do { \
46         int ret; \
47         ret = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); \
48         if (ret != 0) \
49                 ErrPrint("Unable to set cancelate state: %s\n", strerror(ret)); \
50 } while (0)
51
52 #define PIPE_READ       0
53 #define PIPE_WRITE      1
54 #define EVENT_CH        'e'
55
56 int errno;
57
58 static struct info {
59         pthread_t tid;
60         Eina_List *event_list;
61         int handle;
62         pthread_mutex_t event_list_lock;
63         int evt_pipe[2];
64         Ecore_Fd_Handler *event_handler;
65
66         int (*event_cb)(enum event_state state, struct event_data *event, void *data);
67         void *cbdata;
68
69         enum event_state event_state;
70         struct event_data event_data;
71
72         int x;
73         int y;
74 } s_info = {
75         .event_list = NULL,
76         .handle = -1,
77         .event_handler = NULL,
78
79         .event_cb = NULL,
80         .cbdata = NULL,
81
82         .event_state = EVENT_STATE_DEACTIVATE,
83
84         .event_data = {
85                 .x = 0,
86                 .y = 0,
87                 .device = -1,
88         },
89 };
90
91 HAPI int event_init(void)
92 {
93         int ret;
94         ret = pthread_mutex_init(&s_info.event_list_lock, NULL);
95         if (ret != 0) {
96                 ErrPrint("Mutex: %s\n", strerror(ret));
97                 return -EFAULT;
98         }
99         return 0;
100 }
101
102 HAPI int event_fini(void)
103 {
104         int ret;
105         ret = pthread_mutex_destroy(&s_info.event_list_lock);
106         if (ret != 0)
107                 ErrPrint("Mutex destroy failed: %s\n", strerror(ret));
108         return 0;
109 }
110
111 static inline int processing_input_event(struct input_event *event)
112 {
113         struct event_data *item;
114
115         switch (event->type) {
116         case EV_SYN:
117                 switch (event->code) {
118                 case SYN_REPORT:
119                         if (s_info.event_data.x < 0 || s_info.event_data.y < 0) {
120                                 /* Waiting full event packet */
121                                 break;
122                         }
123
124                         item = malloc(sizeof(*item));
125                         if (item) {
126                                 char event_ch;
127
128                                 memcpy(item, &s_info.event_data, sizeof(*item));
129
130                                 CRITICAL_SECTION_BEGIN(s_info.event_list_lock);
131                                 s_info.event_list = eina_list_append(s_info.event_list, item);
132                                 CRITICAL_SECTION_END(s_info.event_list_lock);
133
134                                 event_ch = EVENT_CH;
135                                 if (write(s_info.evt_pipe[PIPE_WRITE], &event_ch, sizeof(event_ch)) != sizeof(event_ch)) {
136                                         ErrPrint("Unable to send an event: %s\n", strerror(errno));
137                                         return -EIO;
138                                 }
139                         }
140                         break;
141                 case SYN_CONFIG:
142                         break;
143                 case SYN_MT_REPORT:
144                         break;
145                 /*
146                 case SYN_DROPPED:
147                         DbgPrint("EV_SYN, SYN_DROPPED\n");
148                         break;
149                 */
150                 default:
151                         DbgPrint("EV_SYN, 0x%x\n", event->code);
152                         break;
153                 }
154                 break;
155         case EV_KEY:
156                 break;
157         case EV_REL:
158                 break;
159         case EV_ABS:
160                 switch (event->code) {
161                 case ABS_DISTANCE:
162                         break;
163                 case ABS_MT_POSITION_X:
164                         s_info.event_data.x = event->value - s_info.x;
165                         break;
166                 case ABS_MT_POSITION_Y:
167                         s_info.event_data.y = event->value - s_info.y;
168                         break;
169                 case ABS_MT_SLOT:
170                         break;
171                 case ABS_MT_TRACKING_ID:
172                         s_info.event_data.device = event->value;
173                         break;
174                 case ABS_MT_TOUCH_MAJOR:
175                         break;
176                 case ABS_MT_TOUCH_MINOR:
177                         break;
178                 case ABS_MT_WIDTH_MAJOR:
179                         break;
180                 case ABS_MT_WIDTH_MINOR:
181                         break;
182                 default:
183                         DbgPrint("EV_ABS, 0x%x\n", event->code);
184                         break;
185                 }
186                 break;
187         case EV_MSC:
188                 break;
189         case EV_SW:
190                 break;
191         case EV_LED:
192                 break;
193         case EV_SND:
194                 break;
195         case EV_REP:
196                 break;
197         case EV_FF:
198                 break;
199         case EV_PWR:
200                 break;
201         case EV_FF_STATUS:
202                 break;
203         default:
204                 DbgPrint("0x%X, 0x%X\n", event->type, event->code);
205                 break;
206         }
207
208         return 0;
209 }
210
211 static void *event_main(void *data)
212 {
213         fd_set set;
214         int ret = 0;
215         struct input_event input_event;
216         char *ptr = (char *)&input_event;
217         int offset = 0;
218         int readsize = 0;
219
220         DbgPrint("event_main initiated\n");
221
222         while (1) {
223                 CANCEL_SECTION_BEGIN();
224                 FD_ZERO(&set);
225                 FD_SET(s_info.handle, &set);
226                 ret = select(s_info.handle + 1, &set, NULL, NULL, NULL);
227                 if (ret < 0) {
228                         ret = -errno;
229                         if (errno == EINTR) {
230                                 DbgPrint("Select receives INTR\n");
231                                 CANCEL_SECTION_END();
232                                 continue;
233                         }
234                         ErrPrint("Error: %s\n", strerror(errno));
235                         CANCEL_SECTION_END();
236                         return (void *)ret;
237                 } else if (ret == 0) {
238                         ErrPrint("Timeout expired\n");
239                         CANCEL_SECTION_END();
240                         return (void *)-ETIMEDOUT;
241                 }
242                 CANCEL_SECTION_END();
243
244                 if (!FD_ISSET(s_info.handle, &set)) {
245                         ErrPrint("Unexpected handle is toggled\n");
246                         ret = -EINVAL;
247                         break;
248                 }
249
250                 readsize = read(s_info.handle, ptr + offset, sizeof(input_event) - offset);
251                 if (readsize < 0) {
252                         ErrPrint("Unable to read device: %s / fd: %d / offset: %d / size: %d - %d\n", strerror(errno), s_info.handle, offset, sizeof(input_event), readsize);
253                         ret = -EFAULT;
254                         break;
255                 }
256
257                 offset += readsize;
258                 if (offset == sizeof(input_event)) {
259                         offset = 0;
260                         if (processing_input_event(&input_event) < 0) {
261                                 ret = -EFAULT;
262                                 break;
263                         }
264                 }
265         }
266
267         return (void *)ret;
268 }
269
270 static Eina_Bool event_read_cb(void *data, Ecore_Fd_Handler *handler)
271 {
272         int fd;
273         struct event_data *item;
274         char event_ch;
275
276         fd = ecore_main_fd_handler_fd_get(handler);
277         if (fd < 0) {
278                 ErrPrint("Invalid fd\n");
279                 return ECORE_CALLBACK_CANCEL;
280         }
281
282         if (read(fd, &event_ch, sizeof(event_ch)) != sizeof(event_ch)) {
283                 ErrPrint("Unable to read event ch: %s\n", strerror(errno));
284                 return ECORE_CALLBACK_CANCEL;
285         }
286
287         CRITICAL_SECTION_BEGIN(s_info.event_list_lock);
288         item = eina_list_nth(s_info.event_list, 0);
289         if (item)
290                 s_info.event_list = eina_list_remove(s_info.event_list, item);
291         else
292                 ErrPrint("Unable to get event\n");
293         CRITICAL_SECTION_END(s_info.event_list_lock);
294
295         if (item && s_info.event_cb) {
296                 switch (s_info.event_state) {
297                 case EVENT_STATE_DEACTIVATE:
298                         s_info.event_state = EVENT_STATE_ACTIVATE;
299                         break;
300                 case EVENT_STATE_ACTIVATE:
301                         s_info.event_state = EVENT_STATE_ACTIVATED;
302                         break;
303                 case EVENT_STATE_ACTIVATED:
304                 default:
305                         break;
306                 }
307                 s_info.event_cb(s_info.event_state, item, s_info.cbdata);
308         }
309
310         free(item);
311         return ECORE_CALLBACK_RENEW;
312 }
313
314 HAPI int event_activate(int x, int y, int (*event_cb)(enum event_state state, struct event_data *event, void *data), void *data)
315 {
316         int status;
317
318         if (s_info.handle >= 0) {
319                 DbgPrint("Already activated\n");
320                 return 0;
321         }
322
323         s_info.handle = open(INPUT_PATH, O_RDONLY);
324         if (s_info.handle < 0) {
325                 ErrPrint("Unable to access the device: %s\n", strerror(errno));
326                 return -EIO;
327         }
328
329         if (fcntl(s_info.handle, F_SETFD, FD_CLOEXEC) < 0)
330                 ErrPrint("Error: %s\n", strerror(errno));
331
332         if (fcntl(s_info.handle, F_SETFL, O_NONBLOCK) < 0)
333                 ErrPrint("Error: %s\n", strerror(errno));
334
335         status = pipe2(s_info.evt_pipe, O_NONBLOCK | O_CLOEXEC);
336         if (status < 0) {
337                 ErrPrint("Unable to prepare evt pipe: %s\n", strerror(errno));
338                 if (close(s_info.handle) < 0)
339                         ErrPrint("Failed to close handle: %s\n", strerror(errno));
340                 s_info.handle = -1;
341                 return -EFAULT;
342         }
343
344         s_info.event_handler = ecore_main_fd_handler_add(s_info.evt_pipe[PIPE_READ], ECORE_FD_READ, event_read_cb, NULL, NULL, NULL);
345         if (!s_info.event_handler) {
346                 if (close(s_info.handle) < 0)
347                         ErrPrint("Failed to close handle: %s\n", strerror(errno));
348
349                 if (close(s_info.evt_pipe[PIPE_READ]) < 0)
350                         ErrPrint("Failed to close handle: %s\n", strerror(errno));
351
352                 if (close(s_info.evt_pipe[PIPE_WRITE]) < 0)
353                         ErrPrint("Failed to close handle: %s\n", strerror(errno));
354
355                 s_info.handle = -1;
356                 return -EFAULT;
357         }
358
359         status = pthread_create(&s_info.tid, NULL, event_main, NULL);
360         if (status != 0) {
361                 ErrPrint("Failed to initiate the thread: %s\n", strerror(status));
362                 ecore_main_fd_handler_del(s_info.event_handler);
363                 s_info.event_handler = NULL;
364
365                 if (close(s_info.handle) < 0)
366                         ErrPrint("close: %s\n", strerror(errno));
367                 s_info.handle = -1;
368
369                 if (close(s_info.evt_pipe[PIPE_READ]) < 0)
370                         ErrPrint("close: %s\n", strerror(errno));
371
372                 if (close(s_info.evt_pipe[PIPE_WRITE]) < 0)
373                         ErrPrint("close: %s\n", strerror(errno));
374
375                 return -EFAULT;
376         }
377
378         s_info.event_cb = event_cb;
379         s_info.cbdata = data;
380         s_info.x = x;
381         s_info.y = y;
382
383         DbgPrint("Event handler activated\n");
384         return 0;
385 }
386
387 HAPI int event_deactivate(void)
388 {
389         int status;
390         struct event_data *event;
391         void *ret;
392
393         if (s_info.handle < 0) {
394                 ErrPrint("Event handler is not actiavated\n");
395                 return 0;
396         }
397
398         status = pthread_cancel(s_info.tid);
399         if (status != 0)
400                 ErrPrint("Failed to cacnel a thread: %s\n", strerror(errno));
401
402         status = pthread_join(s_info.tid, &ret);
403         if (status != 0)
404                 ErrPrint("Failed to join a thread: %s\n", strerror(errno));
405         else if (ret == PTHREAD_CANCELED)
406                 DbgPrint("Thread is canceled\n");
407
408         ecore_main_fd_handler_del(s_info.event_handler);
409         s_info.event_handler = NULL;
410
411         if (close(s_info.evt_pipe[PIPE_READ]) < 0)
412                 ErrPrint("Failed to close: %s\n", strerror(errno));
413
414         if (close(s_info.evt_pipe[PIPE_WRITE]) < 0)
415                 ErrPrint("Failed to close: %s\n", strerror(errno));
416
417         if (close(s_info.handle) < 0)
418                 ErrPrint("Unable to release the fd: %s\n", strerror(errno));
419
420         s_info.handle = -1;
421         DbgPrint("Event handler deactivated\n");
422
423         EINA_LIST_FREE(s_info.event_list, event) {
424                 if (s_info.event_cb) {
425                         if (s_info.event_state == EVENT_STATE_DEACTIVATE) {
426                                 s_info.event_state = EVENT_STATE_ACTIVATE;
427                         } else if (s_info.event_state == EVENT_STATE_ACTIVATE) {
428                                 s_info.event_state = EVENT_STATE_ACTIVATED;
429                         }
430                         s_info.event_cb(s_info.event_state, event, s_info.cbdata);
431                 }
432                 free(event);
433         }
434
435         if (s_info.event_state != EVENT_STATE_DEACTIVATE) {
436                 s_info.event_state = EVENT_STATE_DEACTIVATE;
437
438                 if (s_info.event_cb)
439                         s_info.event_cb(s_info.event_state, &s_info.event_data, s_info.cbdata);
440         }
441
442         s_info.event_data.x = -1;
443         s_info.event_data.y = -1;
444
445         return 0;
446 }
447
448 HAPI int event_is_activated(void)
449 {
450         return s_info.handle >= 0;
451 }
452
453 /* End of a file */