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