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>
45 Eina_List *event_list;
47 pthread_mutex_t event_list_lock;
48 int evt_pipe[PIPE_MAX];
49 int tcb_pipe[PIPE_MAX];
50 Ecore_Fd_Handler *event_handler;
51 Ecore_Fd_Handler *tcb_handler;
53 int (*event_cb)(enum event_state state, struct event_data *event, void *data);
56 enum event_state event_state;
57 struct event_data event_data;
64 .event_handler = NULL,
69 .event_state = EVENT_STATE_DEACTIVATE,
78 HAPI int event_init(void)
81 ret = pthread_mutex_init(&s_info.event_list_lock, NULL);
83 ErrPrint("Mutex: %s\n", strerror(ret));
84 return LB_STATUS_ERROR_FAULT;
86 return LB_STATUS_SUCCESS;
89 HAPI int event_fini(void)
92 ret = pthread_mutex_destroy(&s_info.event_list_lock);
94 ErrPrint("Mutex destroy failed: %s\n", strerror(ret));
95 return LB_STATUS_SUCCESS;
98 static inline int processing_input_event(struct input_event *event)
100 struct event_data *item;
102 switch (event->type) {
104 switch (event->code) {
106 if (s_info.event_data.x < 0 || s_info.event_data.y < 0) {
107 /* Waiting full event packet */
111 item = malloc(sizeof(*item));
115 memcpy(item, &s_info.event_data, sizeof(*item));
117 CRITICAL_SECTION_BEGIN(&s_info.event_list_lock);
118 s_info.event_list = eina_list_append(s_info.event_list, item);
119 CRITICAL_SECTION_END(&s_info.event_list_lock);
122 if (write(s_info.evt_pipe[PIPE_WRITE], &event_ch, sizeof(event_ch)) != sizeof(event_ch)) {
123 ErrPrint("Unable to send an event: %s\n", strerror(errno));
124 return LB_STATUS_ERROR_IO;
134 DbgPrint("EV_SYN, SYN_DROPPED\n");
138 DbgPrint("EV_SYN, 0x%x\n", event->code);
147 switch (event->code) {
150 case ABS_MT_POSITION_X:
151 s_info.event_data.x = event->value - s_info.x;
153 case ABS_MT_POSITION_Y:
154 s_info.event_data.y = event->value - s_info.y;
158 case ABS_MT_TRACKING_ID:
159 s_info.event_data.device = event->value;
161 case ABS_MT_TOUCH_MAJOR:
163 case ABS_MT_TOUCH_MINOR:
165 case ABS_MT_WIDTH_MAJOR:
167 case ABS_MT_WIDTH_MINOR:
170 DbgPrint("EV_ABS, 0x%x\n", event->code);
191 DbgPrint("0x%X, 0x%X\n", event->type, event->code);
195 return LB_STATUS_SUCCESS;
198 static void *event_thread_main(void *data)
202 struct input_event input_event;
203 char *ptr = (char *)&input_event;
206 char event_ch = EVENT_CH;
208 DbgPrint("Initiated\n");
212 FD_SET(s_info.handle, &set);
213 ret = select(s_info.handle + 1, &set, NULL, NULL, NULL);
216 if (errno == EINTR) {
217 DbgPrint("Select receives INTR\n");
220 ErrPrint("Error: %s\n", strerror(errno));
222 } else if (ret == 0) {
223 ErrPrint("Timeout expired\n");
224 ret = LB_STATUS_ERROR_TIMEOUT;
228 if (!FD_ISSET(s_info.handle, &set)) {
229 ErrPrint("Unexpected handle is toggled\n");
230 ret = LB_STATUS_ERROR_INVALID;
234 readsize = read(s_info.handle, ptr + offset, sizeof(input_event) - offset);
236 ErrPrint("Unable to read device: %s / fd: %d / offset: %d / size: %d - %d\n", strerror(errno), s_info.handle, offset, sizeof(input_event), readsize);
237 ret = LB_STATUS_ERROR_FAULT;
242 if (offset == sizeof(input_event)) {
244 if (processing_input_event(&input_event) < 0) {
245 ret = LB_STATUS_ERROR_FAULT;
251 if (write(s_info.tcb_pipe[PIPE_WRITE], &event_ch, sizeof(event_ch)) != sizeof(event_ch))
252 ErrPrint("Unable to write PIPE: %s\n", strerror(errno));
257 static inline int reclaim_tcb_resources(void)
260 struct event_data *event;
263 if (close(s_info.handle) < 0)
264 ErrPrint("Unable to release the fd: %s\n", strerror(errno));
267 DbgPrint("Event handler deactivated\n");
269 status = pthread_join(s_info.tid, &ret);
271 ErrPrint("Failed to join a thread: %s\n", strerror(errno));
273 DbgPrint("Thread returns: %d\n", (int)ret);
275 ecore_main_fd_handler_del(s_info.event_handler);
276 s_info.event_handler = NULL;
278 ecore_main_fd_handler_del(s_info.tcb_handler);
279 s_info.tcb_handler = NULL;
281 CLOSE_PIPE(s_info.tcb_pipe);
282 CLOSE_PIPE(s_info.evt_pipe);
284 EINA_LIST_FREE(s_info.event_list, event) {
285 if (s_info.event_cb) {
286 if (s_info.event_state == EVENT_STATE_DEACTIVATE) {
287 s_info.event_state = EVENT_STATE_ACTIVATE;
288 } else if (s_info.event_state == EVENT_STATE_ACTIVATE) {
289 s_info.event_state = EVENT_STATE_ACTIVATED;
291 s_info.event_cb(s_info.event_state, event, s_info.cbdata);
296 if (s_info.event_state != EVENT_STATE_DEACTIVATE) {
297 s_info.event_state = EVENT_STATE_DEACTIVATE;
300 s_info.event_cb(s_info.event_state, &s_info.event_data, s_info.cbdata);
303 s_info.event_data.x = -1;
304 s_info.event_data.y = -1;
305 return LB_STATUS_SUCCESS;
308 static Eina_Bool event_deactivate_cb(void *data, Ecore_Fd_Handler *handler)
313 fd = ecore_main_fd_handler_fd_get(handler);
315 ErrPrint("Invalid fd\n");
316 return ECORE_CALLBACK_CANCEL;
319 if (read(fd, &event_ch, sizeof(event_ch)) != sizeof(event_ch)) {
320 ErrPrint("Unable to read event ch: %s\n", strerror(errno));
321 return ECORE_CALLBACK_CANCEL;
324 DbgPrint("Deactivated event received: %c\n", event_ch);
325 reclaim_tcb_resources();
326 return ECORE_CALLBACK_CANCEL;
329 static Eina_Bool event_read_cb(void *data, Ecore_Fd_Handler *handler)
332 struct event_data *item;
335 fd = ecore_main_fd_handler_fd_get(handler);
337 ErrPrint("Invalid fd\n");
338 return ECORE_CALLBACK_CANCEL;
341 if (read(fd, &event_ch, sizeof(event_ch)) != sizeof(event_ch)) {
342 ErrPrint("Unable to read event ch: %s\n", strerror(errno));
343 return ECORE_CALLBACK_CANCEL;
346 CRITICAL_SECTION_BEGIN(&s_info.event_list_lock);
347 item = eina_list_nth(s_info.event_list, 0);
349 s_info.event_list = eina_list_remove(s_info.event_list, item);
351 ErrPrint("Unable to get event\n");
352 CRITICAL_SECTION_END(&s_info.event_list_lock);
354 if (item && s_info.event_cb) {
355 switch (s_info.event_state) {
356 case EVENT_STATE_DEACTIVATE:
357 s_info.event_state = EVENT_STATE_ACTIVATE;
359 case EVENT_STATE_ACTIVATE:
360 s_info.event_state = EVENT_STATE_ACTIVATED;
362 case EVENT_STATE_ACTIVATED:
366 s_info.event_cb(s_info.event_state, item, s_info.cbdata);
370 return ECORE_CALLBACK_RENEW;
374 * x, y is the starting point.
376 HAPI int event_activate(int x, int y, int (*event_cb)(enum event_state state, struct event_data *event, void *data), void *data)
380 if (s_info.handle >= 0) {
381 DbgPrint("Already activated\n");
382 return LB_STATUS_SUCCESS;
385 s_info.handle = open(INPUT_PATH, O_RDONLY);
386 if (s_info.handle < 0) {
387 ErrPrint("Unable to access the device: %s\n", strerror(errno));
388 return LB_STATUS_ERROR_IO;
391 if (fcntl(s_info.handle, F_SETFD, FD_CLOEXEC) < 0)
392 ErrPrint("Error: %s\n", strerror(errno));
394 if (fcntl(s_info.handle, F_SETFL, O_NONBLOCK) < 0)
395 ErrPrint("Error: %s\n", strerror(errno));
397 status = pipe2(s_info.evt_pipe, O_NONBLOCK | O_CLOEXEC);
399 ErrPrint("Unable to prepare evt pipe: %s\n", strerror(errno));
400 if (close(s_info.handle) < 0)
401 ErrPrint("Failed to close handle: %s\n", strerror(errno));
403 return LB_STATUS_ERROR_FAULT;
406 status = pipe2(s_info.tcb_pipe, O_NONBLOCK | O_CLOEXEC);
408 ErrPrint("Unable to prepare tcb pipe: %s\n", strerror(errno));
409 if (close(s_info.handle) < 0)
410 ErrPrint("Failed to close handle: %s\n", strerror(errno));
412 CLOSE_PIPE(s_info.evt_pipe);
413 return LB_STATUS_ERROR_FAULT;
416 s_info.event_handler = ecore_main_fd_handler_add(s_info.evt_pipe[PIPE_READ], ECORE_FD_READ, event_read_cb, NULL, NULL, NULL);
417 if (!s_info.event_handler) {
418 if (close(s_info.handle) < 0)
419 ErrPrint("Failed to close handle: %s\n", strerror(errno));
422 CLOSE_PIPE(s_info.tcb_pipe);
423 CLOSE_PIPE(s_info.evt_pipe);
424 return LB_STATUS_ERROR_FAULT;
427 s_info.tcb_handler = ecore_main_fd_handler_add(s_info.tcb_pipe[PIPE_READ], ECORE_FD_READ, event_deactivate_cb, NULL, NULL, NULL);
428 if (!s_info.event_handler) {
429 ecore_main_fd_handler_del(s_info.event_handler);
430 s_info.event_handler = NULL;
432 if (close(s_info.handle) < 0)
433 ErrPrint("Failed to close handle: %s\n", strerror(errno));
436 CLOSE_PIPE(s_info.tcb_pipe);
437 CLOSE_PIPE(s_info.evt_pipe);
438 return LB_STATUS_ERROR_FAULT;
441 status = pthread_create(&s_info.tid, NULL, event_thread_main, NULL);
443 ErrPrint("Failed to initiate the thread: %s\n", strerror(status));
444 ecore_main_fd_handler_del(s_info.event_handler);
445 s_info.event_handler = NULL;
447 ecore_main_fd_handler_del(s_info.tcb_handler);
448 s_info.tcb_handler = NULL;
450 if (close(s_info.handle) < 0)
451 ErrPrint("close: %s\n", strerror(errno));
454 CLOSE_PIPE(s_info.tcb_pipe);
455 CLOSE_PIPE(s_info.evt_pipe);
456 return LB_STATUS_ERROR_FAULT;
459 s_info.event_cb = event_cb;
460 s_info.cbdata = data;
464 DbgPrint("Event handler activated\n");
465 return LB_STATUS_SUCCESS;
468 HAPI int event_deactivate(void)
470 if (s_info.handle < 0) {
471 ErrPrint("Event handler is not actiavated\n");
472 return LB_STATUS_SUCCESS;
475 return reclaim_tcb_resources();
478 HAPI int event_is_activated(void)
480 return s_info.handle >= 0;