2 * Copyright 2013 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.1 (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
8 * http://floralicense.org/license/
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.
25 #include <sys/types.h>
27 #include <linux/input.h>
32 #include <livebox-errno.h>
41 #if !defined(ABS_MT_TOOL_X)
42 #define ABS_MT_TOOL_X 0x3c /* Center X tool position */
45 #if !defined(ABS_MT_TOOL_Y)
46 #define ABS_MT_TOOL_Y 0x3d /* Center Y tool position */
53 Eina_List *event_list;
55 pthread_mutex_t event_list_lock;
56 int evt_pipe[PIPE_MAX];
57 int tcb_pipe[PIPE_MAX];
58 Ecore_Fd_Handler *event_handler;
60 struct event_data event_data;
62 Eina_List *event_listener_list;
63 Eina_List *reactivate_list;
67 .event_handler = NULL,
76 .event_listener_list = NULL,
77 .reactivate_list = NULL,
80 struct event_listener {
81 int (*event_cb)(enum event_state state, struct event_data *event, void *data);
84 enum event_state state;
86 struct timeval tv; /* Recording Activate / Deactivate time */
91 static int activate_thread(void);
93 HAPI int event_init(void)
96 ret = pthread_mutex_init(&s_info.event_list_lock, NULL);
98 ErrPrint("Mutex: %s\n", strerror(ret));
99 return LB_STATUS_ERROR_FAULT;
101 return LB_STATUS_SUCCESS;
104 HAPI int event_fini(void)
107 ret = pthread_mutex_destroy(&s_info.event_list_lock);
109 ErrPrint("Mutex destroy failed: %s\n", strerror(ret));
111 return LB_STATUS_SUCCESS;
114 static inline int processing_input_event(struct input_event *event)
116 struct event_data *item;
118 switch (event->type) {
120 switch (event->code) {
126 if (s_info.event_data.x < 0 || s_info.event_data.y < 0) {
127 /* Waiting full event packet */
131 item = malloc(sizeof(*item));
133 char event_ch = EVENT_CH;
135 if (gettimeofday(&s_info.event_data.tv, NULL) < 0) {
136 ErrPrint("gettimeofday: %s\n", strerror(errno));
139 memcpy(item, &s_info.event_data, sizeof(*item));
141 CRITICAL_SECTION_BEGIN(&s_info.event_list_lock);
142 s_info.event_list = eina_list_append(s_info.event_list, item);
143 CRITICAL_SECTION_END(&s_info.event_list_lock);
145 if (write(s_info.evt_pipe[PIPE_WRITE], &event_ch, sizeof(event_ch)) != sizeof(event_ch)) {
146 ErrPrint("Unable to send an event: %s\n", strerror(errno));
147 return LB_STATUS_ERROR_IO;
153 ErrPrint("Heap: %s\n", strerror(errno));
156 if (s_info.event_data.device < 0) {
157 s_info.event_data.x = -1;
158 s_info.event_data.y = -1;
163 DbgPrint("EV_SYN, SYN_DROPPED\n");
167 DbgPrint("EV_SYN, 0x%x\n", event->code);
176 switch (event->code) {
178 s_info.event_data.distance = event->value;
183 case ABS_MT_POSITION_X:
184 s_info.event_data.x = event->value;
186 case ABS_MT_POSITION_Y:
187 s_info.event_data.y = event->value;
190 s_info.event_data.slot = event->value;
192 case ABS_MT_TRACKING_ID:
193 s_info.event_data.device = event->value;
195 case ABS_MT_TOUCH_MAJOR:
196 s_info.event_data.touch.major = event->value;
198 case ABS_MT_TOUCH_MINOR:
199 s_info.event_data.touch.minor = event->value;
201 case ABS_MT_WIDTH_MAJOR:
202 s_info.event_data.width.major = event->value;
204 case ABS_MT_WIDTH_MINOR:
205 s_info.event_data.width.minor = event->value;
208 DbgPrint("EV_ABS, 0x%x\n", event->code);
229 DbgPrint("0x%X, 0x%X\n", event->type, event->code);
233 return LB_STATUS_SUCCESS;
236 static void *event_thread_main(void *data)
240 struct input_event input_event;
241 char *ptr = (char *)&input_event;
246 DbgPrint("Initiated\n");
250 FD_SET(s_info.handle, &set);
251 FD_SET(s_info.tcb_pipe[PIPE_READ], &set);
253 fd = s_info.handle > s_info.tcb_pipe[PIPE_READ] ? s_info.handle : s_info.tcb_pipe[PIPE_READ];
254 ret = select(fd + 1, &set, NULL, NULL, NULL);
257 if (errno == EINTR) {
258 DbgPrint("Select receives INTR\n");
261 ErrPrint("Error: %s\n", strerror(errno));
263 } else if (ret == 0) {
264 ErrPrint("Timeout expired\n");
265 ret = LB_STATUS_ERROR_TIMEOUT;
269 if (FD_ISSET(s_info.handle, &set)) {
270 readsize = read(s_info.handle, ptr + offset, sizeof(input_event) - offset);
272 ErrPrint("Unable to read device: %s / fd: %d / offset: %d / size: %d - %d\n", strerror(errno), s_info.handle, offset, sizeof(input_event), readsize);
273 ret = LB_STATUS_ERROR_FAULT;
278 if (offset == sizeof(input_event)) {
280 if (processing_input_event(&input_event) < 0) {
281 ret = LB_STATUS_ERROR_FAULT;
287 if (FD_ISSET(s_info.tcb_pipe[PIPE_READ], &set)) {
290 if (read(s_info.tcb_pipe[PIPE_READ], &event_ch, sizeof(event_ch)) != sizeof(event_ch)) {
291 ErrPrint("Unable to read TCB_PIPE: %s\n", strerror(errno));
294 ret = LB_STATUS_ERROR_CANCEL;
302 static inline void clear_all_listener_list(void)
304 struct event_listener *listener;
305 enum event_state next_state;
309 s_info.event_handler = NULL;
310 CLOSE_PIPE(s_info.evt_pipe);
312 while (s_info.event_listener_list) {
313 EINA_LIST_FOREACH_SAFE(s_info.event_listener_list, l, n, listener) {
314 switch (listener->state) {
315 case EVENT_STATE_ACTIVATE:
316 next_state = EVENT_STATE_ACTIVATED;
318 case EVENT_STATE_ACTIVATED:
319 next_state = EVENT_STATE_DEACTIVATE;
321 case EVENT_STATE_DEACTIVATE:
322 next_state = EVENT_STATE_DEACTIVATED;
324 case EVENT_STATE_DEACTIVATED:
326 s_info.event_listener_list = eina_list_remove(s_info.event_listener_list, listener);
331 if (listener->event_cb(listener->state, &s_info.event_data, listener->cbdata) < 0) {
332 if (eina_list_data_find(s_info.event_listener_list, listener)) {
333 s_info.event_listener_list = eina_list_remove(s_info.event_listener_list, listener);
339 listener->state = next_state;
344 static Eina_Bool event_read_cb(void *data, Ecore_Fd_Handler *handler)
347 struct event_data *item;
349 struct event_listener *listener;
352 enum event_state next_state;
353 enum event_state cur_state;
354 struct event_data modified_item;
356 fd = ecore_main_fd_handler_fd_get(handler);
358 ErrPrint("Invalid fd\n");
359 return ECORE_CALLBACK_CANCEL;
362 if (read(fd, &event_ch, sizeof(event_ch)) != sizeof(event_ch)) {
363 ErrPrint("Unable to read event ch: %s\n", strerror(errno));
364 return ECORE_CALLBACK_CANCEL;
367 CRITICAL_SECTION_BEGIN(&s_info.event_list_lock);
368 item = eina_list_nth(s_info.event_list, 0);
370 s_info.event_list = eina_list_remove(s_info.event_list, item);
372 CRITICAL_SECTION_END(&s_info.event_list_lock);
375 EINA_LIST_FOREACH_SAFE(s_info.event_listener_list, l, n, listener) {
376 switch (listener->state) {
377 case EVENT_STATE_ACTIVATE:
378 if (timercmp(&listener->tv, &item->tv, >)) {
379 /* Ignore previous events before activating this listener */
383 next_state = EVENT_STATE_ACTIVATED;
384 cur_state = listener->state;
386 case EVENT_STATE_DEACTIVATE:
387 if (timercmp(&listener->tv, &item->tv, >)) {
388 /* Consuming all events occurred while activating this listener */
389 cur_state = EVENT_STATE_ACTIVATED;
390 next_state = EVENT_STATE_ACTIVATED;
394 cur_state = listener->state;
395 next_state = EVENT_STATE_DEACTIVATED;
397 case EVENT_STATE_ACTIVATED:
398 cur_state = listener->state;
399 next_state = listener->state;
401 case EVENT_STATE_DEACTIVATED:
403 /* Remove this from the list */
404 /* Check the item again. the listener can be deleted from the callback */
405 if (eina_list_data_find(s_info.event_listener_list, listener)) {
406 s_info.event_listener_list = eina_list_remove(s_info.event_listener_list, listener);
413 memcpy(&modified_item, item, sizeof(modified_item));
414 modified_item.x -= listener->x;
415 modified_item.y -= listener->y;
417 if (listener->event_cb(cur_state, &modified_item, listener->cbdata) < 0) {
418 if (eina_list_data_find(s_info.event_listener_list, listener)) {
419 s_info.event_listener_list = eina_list_remove(s_info.event_listener_list, listener);
425 listener->state = next_state;
431 if (s_info.handle < 0 && !s_info.event_list) {
432 /* This callback must has to clear all listeners in this case */
433 clear_all_listener_list();
435 EINA_LIST_FREE(s_info.reactivate_list, listener) {
436 s_info.event_listener_list = eina_list_append(s_info.event_listener_list, listener);
439 if (s_info.event_listener_list) {
440 if (activate_thread() < 0) {
441 EINA_LIST_FREE(s_info.event_listener_list, listener) {
442 (void)listener->event_cb(EVENT_STATE_ERROR, NULL, listener->cbdata);
447 return ECORE_CALLBACK_CANCEL;
450 return ECORE_CALLBACK_RENEW;
453 static int activate_thread(void)
457 s_info.handle = open(INPUT_PATH, O_RDONLY);
458 if (s_info.handle < 0) {
459 ErrPrint("Unable to access the device: %s\n", strerror(errno));
460 return LB_STATUS_ERROR_IO;
463 if (fcntl(s_info.handle, F_SETFD, FD_CLOEXEC) < 0) {
464 ErrPrint("Error: %s\n", strerror(errno));
467 if (fcntl(s_info.handle, F_SETFL, O_NONBLOCK) < 0) {
468 ErrPrint("Error: %s\n", strerror(errno));
471 status = pipe2(s_info.evt_pipe, O_NONBLOCK | O_CLOEXEC);
473 ErrPrint("Unable to prepare evt pipe: %s\n", strerror(errno));
474 if (close(s_info.handle) < 0) {
475 ErrPrint("Failed to close handle: %s\n", strerror(errno));
478 return LB_STATUS_ERROR_FAULT;
481 status = pipe2(s_info.tcb_pipe, O_NONBLOCK | O_CLOEXEC);
483 ErrPrint("Unable to prepare tcb pipe: %s\n", strerror(errno));
484 if (close(s_info.handle) < 0) {
485 ErrPrint("Failed to close handle: %s\n", strerror(errno));
488 CLOSE_PIPE(s_info.evt_pipe);
489 return LB_STATUS_ERROR_FAULT;
492 s_info.event_handler = ecore_main_fd_handler_add(s_info.evt_pipe[PIPE_READ], ECORE_FD_READ, event_read_cb, NULL, NULL, NULL);
493 if (!s_info.event_handler) {
494 if (close(s_info.handle) < 0) {
495 ErrPrint("Failed to close handle: %s\n", strerror(errno));
499 CLOSE_PIPE(s_info.tcb_pipe);
500 CLOSE_PIPE(s_info.evt_pipe);
501 return LB_STATUS_ERROR_FAULT;
504 status = pthread_create(&s_info.tid, NULL, event_thread_main, NULL);
506 ErrPrint("Failed to initiate the thread: %s\n", strerror(status));
507 ecore_main_fd_handler_del(s_info.event_handler);
508 s_info.event_handler = NULL;
510 if (close(s_info.handle) < 0) {
511 ErrPrint("close: %s\n", strerror(errno));
515 CLOSE_PIPE(s_info.tcb_pipe);
516 CLOSE_PIPE(s_info.evt_pipe);
517 return LB_STATUS_ERROR_FAULT;
520 DbgPrint("Event handler activated\n");
521 return LB_STATUS_SUCCESS;
525 * x, y is the starting point.
527 HAPI int event_activate(int x, int y, int (*event_cb)(enum event_state state, struct event_data *event, void *data), void *data)
529 struct event_listener *listener;
530 int ret = LB_STATUS_SUCCESS;
532 listener = malloc(sizeof(*listener));
534 ErrPrint("Heap: %s\n", strerror(errno));
535 return LB_STATUS_ERROR_MEMORY;
538 if (gettimeofday(&listener->tv, NULL) < 0) {
539 ErrPrint("gettimeofday: %s\n", strerror(errno));
541 return LB_STATUS_ERROR_FAULT;
544 listener->event_cb = event_cb;
545 listener->cbdata = data;
546 listener->state = EVENT_STATE_ACTIVATE;
550 if (s_info.handle < 0) {
553 * We don't need to lock to access event_list here.
554 * If the _sinfo.handle is greater than 0, the event_list will not be touched.
555 * But if the s_info.handle is less than 0, it means, there is not thread,
556 * so we can access the event_list without lock.
558 if (s_info.event_list) {
559 DbgPrint("Event thread is deactivating now. activating will be delayed\n");
560 s_info.reactivate_list = eina_list_append(s_info.reactivate_list, listener);
562 s_info.event_listener_list = eina_list_append(s_info.event_listener_list, listener);
564 if ((ret = activate_thread()) < 0) {
565 s_info.event_listener_list = eina_list_remove(s_info.event_listener_list, listener);
570 s_info.event_listener_list = eina_list_append(s_info.event_listener_list, listener);
576 HAPI int event_deactivate(int (*event_cb)(enum event_state state, struct event_data *event, void *data), void *data)
580 char event_ch = EVENT_CH;
581 struct event_listener *listener = NULL;
585 EINA_LIST_FOREACH(s_info.event_listener_list, l, listener) {
586 if (listener->event_cb == event_cb && listener->cbdata == data) {
587 listener->state = EVENT_STATE_DEACTIVATE;
590 keep_thread += (listener->state == EVENT_STATE_ACTIVATE || listener->state == EVENT_STATE_ACTIVATED);
594 ErrPrint("Listener is not registered\n");
595 return LB_STATUS_ERROR_NOT_EXIST;
598 if (s_info.handle < 0) {
599 ErrPrint("Event handler is not actiavated\n");
601 return LB_STATUS_SUCCESS;
605 return LB_STATUS_SUCCESS;
608 /* Terminating thread */
609 if (write(s_info.tcb_pipe[PIPE_WRITE], &event_ch, sizeof(event_ch)) != sizeof(event_ch)) {
610 ErrPrint("Unable to write tcb_pipe: %s\n", strerror(errno));
613 status = pthread_join(s_info.tid, &ret);
615 ErrPrint("Failed to join a thread: %s\n", strerror(errno));
617 DbgPrint("Thread returns: %d\n", (int)ret);
620 if (close(s_info.handle) < 0) {
621 ErrPrint("Unable to release the fd: %s\n", strerror(errno));
625 DbgPrint("Event handler deactivated\n");
627 CLOSE_PIPE(s_info.tcb_pipe);
629 if (!eina_list_count(s_info.event_list)) {
630 ecore_main_fd_handler_del(s_info.event_handler);
631 clear_all_listener_list();
634 s_info.event_data.x = -1;
635 s_info.event_data.y = -1;
636 return LB_STATUS_SUCCESS;
639 HAPI int event_is_activated(void)
641 return s_info.handle >= 0;