| |
| /****************************************************************************** |
| *(C) Copyright 2014 Marvell International Ltd. |
| * All Rights Reserved |
| ******************************************************************************/ |
| /* ------------------------------------------------------------------------------------------------------------------- |
| * |
| * Filename: mgui_onkey.c |
| * |
| * Authors: Tomer Eliyahu |
| * |
| * Description: MGUI onkey interface |
| * |
| * HISTORY: |
| * |
| * Jun 14, 2015 - Initial Version |
| * |
| * Notes: |
| * |
| ******************************************************************************/ |
| |
| /****************************************************************************** |
| * Include files |
| ******************************************************************************/ |
| #include <stdio.h> |
| #include <unistd.h> |
| #include <sys/types.h> |
| #include <fcntl.h> |
| #include <linux/input.h> |
| #include <pthread.h> |
| #include "mgui.h" |
| #include "mgui_utils.h" |
| #include "mgui_onkey.h" |
| |
| #define ONKEY_DEV "/dev/input/event0" |
| |
| static void *mgui_onkey_handler(void *arg) |
| { |
| struct mgui_onkey_context *onkey = (struct mgui_onkey_context *)arg; |
| struct mgui_context *mgui = onkey->mgui; |
| struct input_event data; |
| unsigned int press = 0; |
| int fd = -1; |
| struct mgui_event e = {.id = MGUI_ONKEY_EVENT,}; |
| |
| pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); |
| |
| fd = open(ONKEY_DEV, O_RDONLY); |
| if (fd < 0) { |
| MGUI_EMSG("Error open %s\n", ONKEY_DEV); |
| e.id = MGUI_EXIT_EVENT; |
| write(mgui->pipes_fd[1], &e, sizeof(struct mgui_event)); |
| return arg; |
| } |
| |
| do { |
| read(fd, &data, sizeof(data)); |
| |
| if ((data.type != EV_KEY) || (data.code != KEY_POWER) || (!!data.value == press)) |
| continue; |
| if (!!data.value) { |
| /* key pressed */ |
| press = 1; |
| } else { |
| /* key released, dispatch event */ |
| press = 0; |
| MGUI_IMSG("onkey pressed\n"); |
| // TODO - we might need a mutex here |
| write(mgui->pipes_fd[1], &e, sizeof(struct mgui_event)); |
| } |
| } while (1); |
| |
| close(fd); |
| return arg; |
| } |
| |
| |
| int mgui_onkey_exit(struct mgui_onkey_context *onkey) |
| { |
| int ret = 0; |
| void *res; |
| |
| ret = pthread_cancel(onkey->tid); |
| if (ret) { |
| MGUI_EMSG("pthread cancle error %d\n", ret); |
| goto out; |
| } |
| |
| ret = pthread_join(onkey->tid, &res); |
| if (ret) { |
| MGUI_EMSG("pthread join error %d\n", ret); |
| goto out; |
| } |
| if (res != PTHREAD_CANCELED) { |
| MGUI_EMSG("thread not cancelled error %d\n", (int)res); |
| goto out; |
| } |
| |
| MGUI_IMSG("exit done\n"); |
| out: |
| free(onkey); |
| return ret; |
| } |
| |
| struct mgui_onkey_context *mgui_onkey_init(struct mgui_context *ctx) |
| { |
| struct mgui_onkey_context *onkey; |
| int ret; |
| |
| onkey = malloc(sizeof(*onkey)); |
| if (!onkey) { |
| MGUI_EMSG("memory allocation failed\n"); |
| return NULL; |
| } |
| |
| onkey->mgui = ctx; |
| |
| ret = pthread_create(&onkey->tid, NULL, mgui_onkey_handler, onkey); |
| if (ret != 0) { |
| MGUI_EMSG("pthread create error %d\n", ret); |
| goto out_pthread_create; |
| } |
| |
| MGUI_IMSG("init done\n"); |
| return onkey; |
| |
| out_pthread_create: |
| free(onkey); |
| return NULL; |
| } |