blob: 274829eb72fe3913072650a48c3d8c8124b01614 [file] [log] [blame]
/******************************************************************************
*(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;
}