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,
77 .event_listener_list = NULL,
78 .reactivate_list = NULL,
81 struct event_listener {
82 int (*event_cb)(enum event_state state, struct event_data *event, void *data);
85 enum event_state state;
87 #if defined(_USE_ECORE_TIME_GET)
90 struct timeval tv; /* Recording Activate / Deactivate time */
96 static int activate_thread(void);
98 HAPI int event_init(void)
101 ret = pthread_mutex_init(&s_info.event_list_lock, NULL);
103 ErrPrint("Mutex: %s\n", strerror(ret));
104 return LB_STATUS_ERROR_FAULT;
106 return LB_STATUS_SUCCESS;
109 HAPI int event_fini(void)
112 ret = pthread_mutex_destroy(&s_info.event_list_lock);
114 ErrPrint("Mutex destroy failed: %s\n", strerror(ret));
116 return LB_STATUS_SUCCESS;
119 static inline int processing_input_event(struct input_event *event)
121 struct event_data *item;
123 switch (event->type) {
125 switch (event->code) {
131 if (s_info.event_data.x < 0 || s_info.event_data.y < 0) {
132 /* Waiting full event packet */
136 item = malloc(sizeof(*item));
138 char event_ch = EVENT_CH;
140 #if defined(_USE_ECORE_TIME_GET)
141 s_info.event_data.tv = ecore_time_get();
143 if (gettimeofday(&s_info.event_data.tv, NULL) < 0) {
144 ErrPrint("gettimeofday: %s\n", strerror(errno));
148 memcpy(item, &s_info.event_data, sizeof(*item));
150 CRITICAL_SECTION_BEGIN(&s_info.event_list_lock);
151 s_info.event_list = eina_list_append(s_info.event_list, item);
152 CRITICAL_SECTION_END(&s_info.event_list_lock);
154 if (write(s_info.evt_pipe[PIPE_WRITE], &event_ch, sizeof(event_ch)) != sizeof(event_ch)) {
155 ErrPrint("Unable to send an event: %s\n", strerror(errno));
156 return LB_STATUS_ERROR_IO;
162 ErrPrint("Heap: %s\n", strerror(errno));
165 if (s_info.event_data.device < 0) {
166 s_info.event_data.x = -1;
167 s_info.event_data.y = -1;
168 s_info.event_data.slot = -1;
173 DbgPrint("EV_SYN, SYN_DROPPED\n");
177 DbgPrint("EV_SYN, 0x%x\n", event->code);
182 DbgPrint("EV_KEY: 0x%X\n", event->value);
183 s_info.event_data.keycode = event->value;
188 switch (event->code) {
190 s_info.event_data.distance = event->value;
195 case ABS_MT_POSITION_X:
196 s_info.event_data.x = event->value;
198 case ABS_MT_POSITION_Y:
199 s_info.event_data.y = event->value;
202 s_info.event_data.slot = event->value;
204 case ABS_MT_TRACKING_ID:
205 s_info.event_data.device = event->value;
207 case ABS_MT_TOUCH_MAJOR:
208 s_info.event_data.touch.major = event->value;
210 case ABS_MT_TOUCH_MINOR:
211 s_info.event_data.touch.minor = event->value;
213 case ABS_MT_WIDTH_MAJOR:
214 s_info.event_data.width.major = event->value;
216 case ABS_MT_WIDTH_MINOR:
217 s_info.event_data.width.minor = event->value;
220 DbgPrint("EV_ABS, 0x%x\n", event->code);
241 DbgPrint("0x%X, 0x%X\n", event->type, event->code);
245 return LB_STATUS_SUCCESS;
248 static void *event_thread_main(void *data)
252 struct input_event input_event;
253 char *ptr = (char *)&input_event;
258 DbgPrint("Initiated\n");
262 FD_SET(s_info.handle, &set);
263 FD_SET(s_info.tcb_pipe[PIPE_READ], &set);
265 fd = s_info.handle > s_info.tcb_pipe[PIPE_READ] ? s_info.handle : s_info.tcb_pipe[PIPE_READ];
266 ret = select(fd + 1, &set, NULL, NULL, NULL);
269 if (errno == EINTR) {
270 DbgPrint("Select receives INTR\n");
273 ErrPrint("Error: %s\n", strerror(errno));
275 } else if (ret == 0) {
276 ErrPrint("Timeout expired\n");
277 ret = LB_STATUS_ERROR_TIMEOUT;
281 if (FD_ISSET(s_info.handle, &set)) {
282 readsize = read(s_info.handle, ptr + offset, sizeof(input_event) - offset);
284 ErrPrint("Unable to read device: %s / fd: %d / offset: %d / size: %d - %d\n", strerror(errno), s_info.handle, offset, sizeof(input_event), readsize);
285 ret = LB_STATUS_ERROR_FAULT;
290 if (offset == sizeof(input_event)) {
292 if (processing_input_event(&input_event) < 0) {
293 ret = LB_STATUS_ERROR_FAULT;
299 if (FD_ISSET(s_info.tcb_pipe[PIPE_READ], &set)) {
302 if (read(s_info.tcb_pipe[PIPE_READ], &event_ch, sizeof(event_ch)) != sizeof(event_ch)) {
303 ErrPrint("Unable to read TCB_PIPE: %s\n", strerror(errno));
306 ret = LB_STATUS_ERROR_CANCEL;
314 static inline void clear_all_listener_list(void)
316 struct event_listener *listener;
317 enum event_state next_state;
321 s_info.event_handler = NULL;
322 CLOSE_PIPE(s_info.evt_pipe);
324 while (s_info.event_listener_list) {
325 EINA_LIST_FOREACH_SAFE(s_info.event_listener_list, l, n, listener) {
326 switch (listener->state) {
327 case EVENT_STATE_ACTIVATE:
328 next_state = EVENT_STATE_ACTIVATED;
330 case EVENT_STATE_ACTIVATED:
331 next_state = EVENT_STATE_DEACTIVATE;
333 case EVENT_STATE_DEACTIVATE:
334 next_state = EVENT_STATE_DEACTIVATED;
336 case EVENT_STATE_DEACTIVATED:
338 s_info.event_listener_list = eina_list_remove(s_info.event_listener_list, listener);
343 if (listener->event_cb(listener->state, &s_info.event_data, listener->cbdata) < 0) {
344 if (eina_list_data_find(s_info.event_listener_list, listener)) {
345 s_info.event_listener_list = eina_list_remove(s_info.event_listener_list, listener);
351 listener->state = next_state;
356 static Eina_Bool event_read_cb(void *data, Ecore_Fd_Handler *handler)
359 struct event_data *item;
361 struct event_listener *listener;
364 enum event_state next_state;
365 enum event_state cur_state;
366 struct event_data modified_item;
368 fd = ecore_main_fd_handler_fd_get(handler);
370 ErrPrint("Invalid fd\n");
371 return ECORE_CALLBACK_CANCEL;
374 if (read(fd, &event_ch, sizeof(event_ch)) != sizeof(event_ch)) {
375 ErrPrint("Unable to read event ch: %s\n", strerror(errno));
376 return ECORE_CALLBACK_CANCEL;
379 CRITICAL_SECTION_BEGIN(&s_info.event_list_lock);
380 item = eina_list_nth(s_info.event_list, 0);
382 s_info.event_list = eina_list_remove(s_info.event_list, item);
384 CRITICAL_SECTION_END(&s_info.event_list_lock);
387 EINA_LIST_FOREACH_SAFE(s_info.event_listener_list, l, n, listener) {
388 switch (listener->state) {
389 case EVENT_STATE_ACTIVATE:
390 #if defined(_USE_ECORE_TIME_GET)
391 if (listener->tv > item->tv) {
395 if (timercmp(&listener->tv, &item->tv, >)) {
396 /* Ignore previous events before activating this listener */
401 next_state = EVENT_STATE_ACTIVATED;
402 cur_state = listener->state;
404 case EVENT_STATE_DEACTIVATE:
405 #if defined(_USE_ECORE_TIME_GET)
406 if (listener->tv > item->tv) {
407 /* Consuming all events occurred while activating this listener */
408 cur_state = EVENT_STATE_ACTIVATED;
409 next_state = EVENT_STATE_ACTIVATED;
413 if (timercmp(&listener->tv, &item->tv, >)) {
414 /* Consuming all events occurred while activating this listener */
415 cur_state = EVENT_STATE_ACTIVATED;
416 next_state = EVENT_STATE_ACTIVATED;
421 cur_state = listener->state;
422 next_state = EVENT_STATE_DEACTIVATED;
424 case EVENT_STATE_ACTIVATED:
425 cur_state = listener->state;
426 next_state = listener->state;
428 case EVENT_STATE_DEACTIVATED:
430 /* Remove this from the list */
431 /* Check the item again. the listener can be deleted from the callback */
432 if (eina_list_data_find(s_info.event_listener_list, listener)) {
433 s_info.event_listener_list = eina_list_remove(s_info.event_listener_list, listener);
440 memcpy(&modified_item, item, sizeof(modified_item));
441 modified_item.x -= listener->x;
442 modified_item.y -= listener->y;
444 if (listener->event_cb(cur_state, &modified_item, listener->cbdata) < 0) {
445 if (eina_list_data_find(s_info.event_listener_list, listener)) {
446 s_info.event_listener_list = eina_list_remove(s_info.event_listener_list, listener);
452 listener->state = next_state;
458 if (s_info.handle < 0 && !s_info.event_list) {
459 /* This callback must has to clear all listeners in this case */
460 clear_all_listener_list();
462 EINA_LIST_FREE(s_info.reactivate_list, listener) {
463 s_info.event_listener_list = eina_list_append(s_info.event_listener_list, listener);
466 if (s_info.event_listener_list) {
467 if (activate_thread() < 0) {
468 EINA_LIST_FREE(s_info.event_listener_list, listener) {
469 (void)listener->event_cb(EVENT_STATE_ERROR, NULL, listener->cbdata);
474 return ECORE_CALLBACK_CANCEL;
477 return ECORE_CALLBACK_RENEW;
480 static int activate_thread(void)
484 s_info.handle = open(INPUT_PATH, O_RDONLY);
485 if (s_info.handle < 0) {
486 ErrPrint("Unable to access the device: %s\n", strerror(errno));
487 return LB_STATUS_ERROR_IO;
490 if (fcntl(s_info.handle, F_SETFD, FD_CLOEXEC) < 0) {
491 ErrPrint("Error: %s\n", strerror(errno));
494 if (fcntl(s_info.handle, F_SETFL, O_NONBLOCK) < 0) {
495 ErrPrint("Error: %s\n", strerror(errno));
498 status = pipe2(s_info.evt_pipe, O_CLOEXEC);
500 ErrPrint("Unable to prepare evt pipe: %s\n", strerror(errno));
501 if (close(s_info.handle) < 0) {
502 ErrPrint("Failed to close handle: %s\n", strerror(errno));
505 return LB_STATUS_ERROR_FAULT;
508 status = pipe2(s_info.tcb_pipe, O_CLOEXEC);
510 ErrPrint("Unable to prepare tcb pipe: %s\n", strerror(errno));
511 if (close(s_info.handle) < 0) {
512 ErrPrint("Failed to close handle: %s\n", strerror(errno));
515 CLOSE_PIPE(s_info.evt_pipe);
516 return LB_STATUS_ERROR_FAULT;
519 s_info.event_handler = ecore_main_fd_handler_add(s_info.evt_pipe[PIPE_READ], ECORE_FD_READ, event_read_cb, NULL, NULL, NULL);
520 if (!s_info.event_handler) {
521 if (close(s_info.handle) < 0) {
522 ErrPrint("Failed to close handle: %s\n", strerror(errno));
526 CLOSE_PIPE(s_info.tcb_pipe);
527 CLOSE_PIPE(s_info.evt_pipe);
528 return LB_STATUS_ERROR_FAULT;
531 status = pthread_create(&s_info.tid, NULL, event_thread_main, NULL);
533 ErrPrint("Failed to initiate the thread: %s\n", strerror(status));
534 ecore_main_fd_handler_del(s_info.event_handler);
535 s_info.event_handler = NULL;
537 if (close(s_info.handle) < 0) {
538 ErrPrint("close: %s\n", strerror(errno));
542 CLOSE_PIPE(s_info.tcb_pipe);
543 CLOSE_PIPE(s_info.evt_pipe);
544 return LB_STATUS_ERROR_FAULT;
547 DbgPrint("Event handler activated\n");
548 return LB_STATUS_SUCCESS;
552 * x, y is the starting point.
554 HAPI int event_activate(int x, int y, int (*event_cb)(enum event_state state, struct event_data *event, void *data), void *data)
556 struct event_listener *listener;
557 int ret = LB_STATUS_SUCCESS;
559 listener = malloc(sizeof(*listener));
561 ErrPrint("Heap: %s\n", strerror(errno));
562 return LB_STATUS_ERROR_MEMORY;
565 #if defined(_USE_ECORE_TIME_GET)
566 listener->tv = ecore_time_get();
568 if (gettimeofday(&listener->tv, NULL) < 0) {
569 ErrPrint("gettimeofday: %s\n", strerror(errno));
571 return LB_STATUS_ERROR_FAULT;
575 listener->event_cb = event_cb;
576 listener->cbdata = data;
577 listener->state = EVENT_STATE_ACTIVATE;
581 if (s_info.handle < 0) {
584 * We don't need to lock to access event_list here.
585 * If the _sinfo.handle is greater than 0, the event_list will not be touched.
586 * But if the s_info.handle is less than 0, it means, there is not thread,
587 * so we can access the event_list without lock.
589 if (s_info.event_list) {
590 DbgPrint("Event thread is deactivating now. activating will be delayed\n");
591 s_info.reactivate_list = eina_list_append(s_info.reactivate_list, listener);
593 s_info.event_listener_list = eina_list_append(s_info.event_listener_list, listener);
595 if ((ret = activate_thread()) < 0) {
596 s_info.event_listener_list = eina_list_remove(s_info.event_listener_list, listener);
601 s_info.event_listener_list = eina_list_append(s_info.event_listener_list, listener);
607 HAPI int event_deactivate(int (*event_cb)(enum event_state state, struct event_data *event, void *data), void *data)
611 char event_ch = EVENT_CH;
612 struct event_listener *listener = NULL;
616 EINA_LIST_FOREACH(s_info.event_listener_list, l, listener) {
617 if (listener->event_cb == event_cb && listener->cbdata == data) {
618 listener->state = EVENT_STATE_DEACTIVATE;
621 keep_thread += (listener->state == EVENT_STATE_ACTIVATE || listener->state == EVENT_STATE_ACTIVATED);
625 ErrPrint("Listener is not registered\n");
626 return LB_STATUS_ERROR_NOT_EXIST;
629 if (s_info.handle < 0) {
630 ErrPrint("Event handler is not actiavated\n");
632 return LB_STATUS_SUCCESS;
636 return LB_STATUS_SUCCESS;
639 /* Terminating thread */
640 if (write(s_info.tcb_pipe[PIPE_WRITE], &event_ch, sizeof(event_ch)) != sizeof(event_ch)) {
641 ErrPrint("Unable to write tcb_pipe: %s\n", strerror(errno));
644 status = pthread_join(s_info.tid, &ret);
646 ErrPrint("Failed to join a thread: %s\n", strerror(errno));
648 DbgPrint("Thread returns: %p\n", ret);
651 if (close(s_info.handle) < 0) {
652 ErrPrint("Unable to release the fd: %s\n", strerror(errno));
656 DbgPrint("Event handler deactivated\n");
658 CLOSE_PIPE(s_info.tcb_pipe);
660 if (!eina_list_count(s_info.event_list)) {
661 ecore_main_fd_handler_del(s_info.event_handler);
662 clear_all_listener_list();
665 s_info.event_data.x = -1;
666 s_info.event_data.y = -1;
667 s_info.event_data.slot = -1;
668 return LB_STATUS_SUCCESS;
671 HAPI int event_is_activated(void)
673 return s_info.handle >= 0;