728 lines
18 KiB
C
728 lines
18 KiB
C
|
|
/**
|
||
|
|
* @file evdev.c
|
||
|
|
*
|
||
|
|
*/
|
||
|
|
|
||
|
|
/*********************
|
||
|
|
* INCLUDES
|
||
|
|
*********************/
|
||
|
|
#include "evdev.h"
|
||
|
|
#if defined(USE_EVDEV) && USE_EVDEV
|
||
|
|
|
||
|
|
#include <stdio.h>
|
||
|
|
#include <unistd.h>
|
||
|
|
#include <fcntl.h>
|
||
|
|
#include <linux/input.h>
|
||
|
|
#include <libevdev-1.0/libevdev/libevdev.h>
|
||
|
|
#include <dirent.h>
|
||
|
|
|
||
|
|
#include "main.h"
|
||
|
|
#include "kalman_filter.h"
|
||
|
|
/*********************
|
||
|
|
* DEFINES
|
||
|
|
*********************/
|
||
|
|
|
||
|
|
#define PSENSOR_IOCTL_MAGIC 'p'
|
||
|
|
#define PSENSOR_IOCTL_GET_ENABLED _IOR(PSENSOR_IOCTL_MAGIC, 1, int *)
|
||
|
|
#define PSENSOR_IOCTL_ENABLE _IOW(PSENSOR_IOCTL_MAGIC, 2, int *)
|
||
|
|
#define PSENSOR_IOCTL_DISABLE _IOW(PSENSOR_IOCTL_MAGIC, 3, int *)
|
||
|
|
|
||
|
|
#define LIGHTSENSOR_IOCTL_MAGIC 'l'
|
||
|
|
#define LIGHTSENSOR_IOCTL_GET_ENABLED _IOR(LIGHTSENSOR_IOCTL_MAGIC, 1, int *)
|
||
|
|
#define LIGHTSENSOR_IOCTL_ENABLE _IOW(LIGHTSENSOR_IOCTL_MAGIC, 2, int *)
|
||
|
|
#define LIGHTSENSOR_IOCTL_SET_RATE _IOW(LIGHTSENSOR_IOCTL_MAGIC, 3, short)
|
||
|
|
|
||
|
|
/**********************
|
||
|
|
* TYPEDEFS
|
||
|
|
**********************/
|
||
|
|
|
||
|
|
typedef struct evdev_record
|
||
|
|
{
|
||
|
|
int x;
|
||
|
|
int y;
|
||
|
|
int button;
|
||
|
|
} evdev_record_t;
|
||
|
|
|
||
|
|
/**********************
|
||
|
|
* STATIC PROTOTYPES
|
||
|
|
**********************/
|
||
|
|
int map(int x, int in_min, int in_max, int out_min, int out_max);
|
||
|
|
|
||
|
|
/**********************
|
||
|
|
* STATIC VARIABLES
|
||
|
|
**********************/
|
||
|
|
static struct libevdev *evdev = NULL;
|
||
|
|
static int evdev_fd = -1;
|
||
|
|
static int evdev_min_x = DEFAULT_EVDEV_HOR_MIN;
|
||
|
|
static int evdev_max_x = DEFAULT_EVDEV_HOR_MAX;
|
||
|
|
static int evdev_min_y = DEFAULT_EVDEV_VER_MIN;
|
||
|
|
static int evdev_max_y = DEFAULT_EVDEV_VER_MAX;
|
||
|
|
static int evdev_calibrate = 0;
|
||
|
|
static evdev_record_t evdev_val[2];
|
||
|
|
static int touch_up = 0;
|
||
|
|
static pthread_t evdev_tid;
|
||
|
|
static pthread_mutex_t evdev_lock;
|
||
|
|
|
||
|
|
static int evdev_key_val;
|
||
|
|
static int evdev_button;
|
||
|
|
|
||
|
|
static int evdev_rot;
|
||
|
|
|
||
|
|
#define FILE_DEBUG 0
|
||
|
|
#if FILE_DEBUG
|
||
|
|
static FILE *raw_point;
|
||
|
|
static FILE *lv_raw_point;
|
||
|
|
static FILE *lv_fix_point;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
static KalmanFilter kfx;
|
||
|
|
static KalmanFilter kfy;
|
||
|
|
|
||
|
|
#if USE_SENSOR
|
||
|
|
static int psensor_event_id = -1;
|
||
|
|
static int lsensor_event_id = -1;
|
||
|
|
static int psensor_fd = -1;
|
||
|
|
static int lsensor_fd = -1;
|
||
|
|
#endif
|
||
|
|
/**********************
|
||
|
|
* MACROS
|
||
|
|
**********************/
|
||
|
|
|
||
|
|
/**********************
|
||
|
|
* GLOBAL FUNCTIONS
|
||
|
|
**********************/
|
||
|
|
|
||
|
|
#define TP_NAME_LEN (32)
|
||
|
|
static char tp_event[TP_NAME_LEN] = EVDEV_NAME;
|
||
|
|
static void *evdev_thread(void *arg);
|
||
|
|
/**
|
||
|
|
* Get touchscreen device event no
|
||
|
|
*/
|
||
|
|
int evdev_get_tp_event(void)
|
||
|
|
{
|
||
|
|
int fd = 0, len = 0;
|
||
|
|
int i = 0, input_dev_num = 0;
|
||
|
|
DIR *pDir;
|
||
|
|
struct dirent *ent = NULL;
|
||
|
|
char file_name[TP_NAME_LEN];
|
||
|
|
char tp_name[TP_NAME_LEN];
|
||
|
|
char *path = "/sys/class/input";
|
||
|
|
|
||
|
|
if ((pDir = opendir(path)) == NULL)
|
||
|
|
{
|
||
|
|
printf("%s: open %s filed\n", __func__, path);
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
while ((ent = readdir(pDir)) != NULL)
|
||
|
|
{
|
||
|
|
if (strstr(ent->d_name, "input"))
|
||
|
|
input_dev_num++;
|
||
|
|
// printf("%s: %s input deveices %d\n",
|
||
|
|
// __func__,
|
||
|
|
// ent->d_name,
|
||
|
|
// input_dev_num);
|
||
|
|
}
|
||
|
|
closedir(pDir);
|
||
|
|
|
||
|
|
for (i = 0; i < input_dev_num; i++)
|
||
|
|
{
|
||
|
|
sprintf(file_name, "/sys/class/input/input%d/name", i);
|
||
|
|
fd = open(file_name, O_RDONLY);
|
||
|
|
if (fd == -1)
|
||
|
|
{
|
||
|
|
printf("%s: open %s failed\n", __func__, file_name);
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
len = read(fd, tp_name, TP_NAME_LEN);
|
||
|
|
close(fd);
|
||
|
|
if (len <= 0)
|
||
|
|
{
|
||
|
|
printf("%s: read %s failed\n", __func__, file_name);
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (len >= TP_NAME_LEN)
|
||
|
|
len = TP_NAME_LEN - 1;
|
||
|
|
|
||
|
|
tp_name[len] = '\0';
|
||
|
|
|
||
|
|
#if USE_SENSOR
|
||
|
|
if (strstr(tp_name, "lightsensor"))
|
||
|
|
{
|
||
|
|
lsensor_event_id = i;
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (strstr(tp_name, "proximity"))
|
||
|
|
{
|
||
|
|
psensor_event_id = i;
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
#else
|
||
|
|
/*
|
||
|
|
* There is a 'ts' in the 'lightsensor', skip it to avoid being
|
||
|
|
* treated as a touch device
|
||
|
|
*/
|
||
|
|
if (strstr(tp_name, "lightsensor"))
|
||
|
|
continue;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
if (strstr(tp_name, "ts") || strstr(tp_name, "gsl"))
|
||
|
|
{
|
||
|
|
sprintf(tp_event, "/dev/input/event%d", i);
|
||
|
|
printf("%s: %s = %s%s\n", __func__, file_name, tp_name, tp_event);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
#if USE_SENSOR
|
||
|
|
void evdev_sensor_read(lv_indev_t *drv, lv_indev_data_t *data)
|
||
|
|
{
|
||
|
|
struct input_event in;
|
||
|
|
struct timeval tv;
|
||
|
|
int drv_fd = *(int *)lv_indev_get_user_data(drv);
|
||
|
|
fd_set rdfs;
|
||
|
|
int ret;
|
||
|
|
|
||
|
|
FD_ZERO(&rdfs);
|
||
|
|
FD_SET(drv_fd, &rdfs);
|
||
|
|
|
||
|
|
tv.tv_sec = 0;
|
||
|
|
tv.tv_usec = 0;
|
||
|
|
|
||
|
|
data->continue_reading = 1;
|
||
|
|
if (select(drv_fd + 1, &rdfs, NULL, NULL, &tv) <= 0)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ((ret = read(drv_fd, &in, sizeof(in))) > 0)
|
||
|
|
{
|
||
|
|
if (in.type == EV_ABS)
|
||
|
|
{
|
||
|
|
if (in.code == ABS_DISTANCE)
|
||
|
|
{
|
||
|
|
if (in.value == 0)
|
||
|
|
data->state = LV_INDEV_STATE_RELEASED;
|
||
|
|
else
|
||
|
|
data->state = LV_INDEV_STATE_PRESSED;
|
||
|
|
data->continue_reading = 0;
|
||
|
|
}
|
||
|
|
else if (in.code == ABS_MISC)
|
||
|
|
{
|
||
|
|
if (in.value == 0)
|
||
|
|
data->state = LV_INDEV_STATE_RELEASED;
|
||
|
|
else
|
||
|
|
data->state = LV_INDEV_STATE_PRESSED;
|
||
|
|
data->key = in.value;
|
||
|
|
data->continue_reading = 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void *evdev_get_psensor(void)
|
||
|
|
{
|
||
|
|
return &psensor_fd;
|
||
|
|
}
|
||
|
|
|
||
|
|
int evdev_init_psensor(void)
|
||
|
|
{
|
||
|
|
char event_name[64];
|
||
|
|
int fd, ret, enable = 1;
|
||
|
|
|
||
|
|
if (psensor_event_id == -1)
|
||
|
|
{
|
||
|
|
if (evdev_get_tp_event() < 0)
|
||
|
|
{
|
||
|
|
printf("%s get event failed\n", __func__);
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
if (psensor_event_id == -1)
|
||
|
|
{
|
||
|
|
printf("%s get psensor event failed\n", __func__);
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
fd = open("/dev/psensor", O_RDWR);
|
||
|
|
if (fd < 0)
|
||
|
|
{
|
||
|
|
printf("can't open /dev/psensor!\n");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
ret = ioctl(fd, PSENSOR_IOCTL_ENABLE, &enable);
|
||
|
|
if (ret < 0)
|
||
|
|
{
|
||
|
|
printf("eanble /dev/psensor failed %d!\n", ret);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
printf("enable /dev/psensor successfully!\n");
|
||
|
|
}
|
||
|
|
close(fd);
|
||
|
|
|
||
|
|
snprintf(event_name, sizeof(event_name),
|
||
|
|
"/dev/input/event%d", psensor_event_id);
|
||
|
|
fd = open(event_name, O_RDONLY);
|
||
|
|
if (fd < 0)
|
||
|
|
{
|
||
|
|
printf("can't open %s\n", event_name);
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
psensor_fd = fd;
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
void *evdev_get_lsensor(void)
|
||
|
|
{
|
||
|
|
return &lsensor_fd;
|
||
|
|
}
|
||
|
|
|
||
|
|
int evdev_init_lsensor(void)
|
||
|
|
{
|
||
|
|
char event_name[64];
|
||
|
|
int fd, ret, enable = 1;
|
||
|
|
|
||
|
|
if (lsensor_event_id == -1)
|
||
|
|
{
|
||
|
|
if (evdev_get_tp_event() < 0)
|
||
|
|
{
|
||
|
|
printf("%s get event failed\n", __func__);
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
if (lsensor_event_id == -1)
|
||
|
|
{
|
||
|
|
printf("%s get lsensor event failed\n", __func__);
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
fd = open("/dev/lightsensor", O_RDWR);
|
||
|
|
if (fd < 0)
|
||
|
|
{
|
||
|
|
printf("can't open /dev/lightsensor!\n");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
ret = ioctl(fd, LIGHTSENSOR_IOCTL_ENABLE, &enable);
|
||
|
|
if (ret < 0)
|
||
|
|
{
|
||
|
|
printf("eanble /dev/lightsensor failed %d!\n", ret);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
printf("enable /dev/lightsensor successfully!\n");
|
||
|
|
}
|
||
|
|
close(fd);
|
||
|
|
|
||
|
|
snprintf(event_name, sizeof(event_name),
|
||
|
|
"/dev/input/event%d", lsensor_event_id);
|
||
|
|
fd = open(event_name, O_RDONLY);
|
||
|
|
if (fd < 0)
|
||
|
|
{
|
||
|
|
printf("can't open %s\n", event_name);
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
lsensor_fd = fd;
|
||
|
|
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Initialize the evdev interface
|
||
|
|
*/
|
||
|
|
int evdev_init(lv_display_t *disp, int rot)
|
||
|
|
{
|
||
|
|
const char *event_name;
|
||
|
|
int rc = 1;
|
||
|
|
evdev_rot = rot;
|
||
|
|
|
||
|
|
#if FILE_DEBUG
|
||
|
|
raw_point = fopen("/tmp/raw_point.txt", "wb+");
|
||
|
|
lv_raw_point = fopen("/tmp/lv_raw_point.txt", "wb+");
|
||
|
|
lv_fix_point = fopen("/tmp/lv_fix_point.txt", "wb+");
|
||
|
|
#endif
|
||
|
|
|
||
|
|
event_name = getenv("LV_EVENT_NAME");
|
||
|
|
if (event_name)
|
||
|
|
{
|
||
|
|
strncpy(tp_event, event_name, TP_NAME_LEN);
|
||
|
|
}
|
||
|
|
else if (evdev_get_tp_event() < 0)
|
||
|
|
{
|
||
|
|
printf("%s get tp event failed\n", __func__);
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
return evdev_set_file(disp, tp_event);
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* reconfigure the device file for evdev
|
||
|
|
* @param dev_name set the evdev device filename
|
||
|
|
* @return true: the device file set complete
|
||
|
|
* false: the device file doesn't exist current system
|
||
|
|
*/
|
||
|
|
int evdev_set_file(lv_display_t *disp, char *dev_name)
|
||
|
|
{
|
||
|
|
int disp_hor;
|
||
|
|
int disp_ver;
|
||
|
|
int rc = 1;
|
||
|
|
|
||
|
|
if (evdev_fd != -1)
|
||
|
|
close(evdev_fd);
|
||
|
|
evdev_fd = -1;
|
||
|
|
if (evdev)
|
||
|
|
libevdev_free(evdev);
|
||
|
|
evdev = NULL;
|
||
|
|
|
||
|
|
#if USE_BSD_EVDEV
|
||
|
|
evdev_fd = open(dev_name, O_RDWR | O_NOCTTY);
|
||
|
|
#else
|
||
|
|
evdev_fd = open(dev_name, O_RDWR | O_NOCTTY | O_NDELAY);
|
||
|
|
#endif
|
||
|
|
|
||
|
|
if (evdev_fd == -1)
|
||
|
|
{
|
||
|
|
perror("unable open evdev interface:");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
rc = libevdev_new_from_fd(evdev_fd, &evdev);
|
||
|
|
if (rc < 0)
|
||
|
|
{
|
||
|
|
printf("Failed to init libevdev (%s)\n", strerror(-rc));
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if (libevdev_has_event_type(evdev, EV_ABS))
|
||
|
|
{
|
||
|
|
const struct input_absinfo *abs;
|
||
|
|
if (libevdev_has_event_code(evdev, EV_ABS, ABS_MT_POSITION_X))
|
||
|
|
{
|
||
|
|
abs = libevdev_get_abs_info(evdev, ABS_MT_POSITION_X);
|
||
|
|
printf("EV_ABS ABS_MT_POSITION_X\n");
|
||
|
|
printf("\tMin\t%6d\n", abs->minimum);
|
||
|
|
printf("\tMax\t%6d\n", abs->maximum);
|
||
|
|
if ((evdev_rot == 0) || (evdev_rot == 180))
|
||
|
|
{
|
||
|
|
evdev_min_x = abs->minimum;
|
||
|
|
evdev_max_x = abs->maximum;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
evdev_min_y = abs->minimum;
|
||
|
|
evdev_max_y = abs->maximum;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (libevdev_has_event_code(evdev, EV_ABS, ABS_MT_POSITION_Y))
|
||
|
|
{
|
||
|
|
abs = libevdev_get_abs_info(evdev, ABS_MT_POSITION_Y);
|
||
|
|
printf("EV_ABS ABS_MT_POSITION_Y\n");
|
||
|
|
printf("\tMin\t%6d\n", abs->minimum);
|
||
|
|
printf("\tMax\t%6d\n", abs->maximum);
|
||
|
|
if ((evdev_rot == 0) || (evdev_rot == 180))
|
||
|
|
{
|
||
|
|
evdev_min_y = abs->minimum;
|
||
|
|
evdev_max_y = abs->maximum;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
evdev_min_x = abs->minimum;
|
||
|
|
evdev_max_x = abs->maximum;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
fcntl(evdev_fd, F_SETFL, O_ASYNC | O_NONBLOCK);
|
||
|
|
|
||
|
|
memset(evdev_val, 0, sizeof(evdev_val));
|
||
|
|
evdev_key_val = 0;
|
||
|
|
evdev_button = LV_INDEV_STATE_REL;
|
||
|
|
|
||
|
|
disp_hor = lv_display_get_horizontal_resolution(disp);
|
||
|
|
disp_ver = lv_display_get_vertical_resolution(disp);
|
||
|
|
if ((evdev_min_x != 0) ||
|
||
|
|
(evdev_max_x != disp_hor) ||
|
||
|
|
(evdev_min_y != 0) ||
|
||
|
|
(evdev_max_y != disp_ver))
|
||
|
|
{
|
||
|
|
evdev_calibrate = 1;
|
||
|
|
printf("calibrate [%d,%d]x[%d,%d] to %dx%d\n",
|
||
|
|
evdev_min_x, evdev_max_x,
|
||
|
|
evdev_min_y, evdev_max_y,
|
||
|
|
disp_hor, disp_ver);
|
||
|
|
}
|
||
|
|
printf("evdev_calibrate = %d\n", evdev_calibrate);
|
||
|
|
|
||
|
|
pthread_mutex_init(&evdev_lock, NULL);
|
||
|
|
pthread_create(&evdev_tid, NULL, evdev_thread, NULL);
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Get the current position and state of the evdev
|
||
|
|
* @param data store the evdev data here
|
||
|
|
* @return false: because the points are not buffered, so no more data to be read
|
||
|
|
*/
|
||
|
|
|
||
|
|
static void *evdev_thread(void *arg)
|
||
|
|
{
|
||
|
|
int type = LV_INDEV_TYPE_POINTER;
|
||
|
|
struct input_event in;
|
||
|
|
int x = 0;
|
||
|
|
int y = 0;
|
||
|
|
int button = 0;
|
||
|
|
fd_set rdfs;
|
||
|
|
|
||
|
|
FD_ZERO(&rdfs);
|
||
|
|
FD_SET(evdev_fd, &rdfs);
|
||
|
|
|
||
|
|
while (1)
|
||
|
|
{
|
||
|
|
select(evdev_fd + 1, &rdfs, NULL, NULL, NULL);
|
||
|
|
|
||
|
|
while (read(evdev_fd, &in, sizeof(struct input_event)) > 0)
|
||
|
|
{
|
||
|
|
if (in.type == EV_REL)
|
||
|
|
{
|
||
|
|
if (in.code == REL_X)
|
||
|
|
#if EVDEV_SWAP_AXES
|
||
|
|
y += in.value;
|
||
|
|
#else
|
||
|
|
x += in.value;
|
||
|
|
#endif
|
||
|
|
else if (in.code == REL_Y)
|
||
|
|
#if EVDEV_SWAP_AXES
|
||
|
|
x += in.value;
|
||
|
|
#else
|
||
|
|
y += in.value;
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
else if (in.type == EV_ABS)
|
||
|
|
{
|
||
|
|
if (in.code == ABS_X)
|
||
|
|
#if EVDEV_SWAP_AXES
|
||
|
|
y = in.value;
|
||
|
|
#else
|
||
|
|
x = in.value;
|
||
|
|
#endif
|
||
|
|
else if (in.code == ABS_Y)
|
||
|
|
#if EVDEV_SWAP_AXES
|
||
|
|
x = in.value;
|
||
|
|
#else
|
||
|
|
y = in.value;
|
||
|
|
#endif
|
||
|
|
else if (in.code == ABS_MT_POSITION_X)
|
||
|
|
#if EVDEV_SWAP_AXES
|
||
|
|
y = in.value;
|
||
|
|
#else
|
||
|
|
x = in.value;
|
||
|
|
#endif
|
||
|
|
else if (in.code == ABS_MT_POSITION_Y)
|
||
|
|
#if EVDEV_SWAP_AXES
|
||
|
|
x = in.value;
|
||
|
|
#else
|
||
|
|
y = in.value;
|
||
|
|
#endif
|
||
|
|
else if (in.code == ABS_MT_TRACKING_ID)
|
||
|
|
{
|
||
|
|
if (in.value == -1)
|
||
|
|
{
|
||
|
|
button = LV_INDEV_STATE_REL;
|
||
|
|
touch_up = 1;
|
||
|
|
}
|
||
|
|
else/* if ((in.value == 0) || (in.value == 1)) */
|
||
|
|
{
|
||
|
|
button = LV_INDEV_STATE_PR;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else if (in.type == EV_KEY)
|
||
|
|
{
|
||
|
|
if (in.code == BTN_MOUSE || in.code == BTN_TOUCH)
|
||
|
|
{
|
||
|
|
if (in.value == 0)
|
||
|
|
{
|
||
|
|
evdev_button = LV_INDEV_STATE_REL;
|
||
|
|
button = LV_INDEV_STATE_REL;
|
||
|
|
}
|
||
|
|
else if (in.value == 1)
|
||
|
|
{
|
||
|
|
evdev_button = LV_INDEV_STATE_PR;
|
||
|
|
button = LV_INDEV_STATE_PR;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else if (type == LV_INDEV_TYPE_KEYPAD)
|
||
|
|
{
|
||
|
|
switch (in.code)
|
||
|
|
{
|
||
|
|
case KEY_BACKSPACE:
|
||
|
|
evdev_key_val = LV_KEY_BACKSPACE;
|
||
|
|
break;
|
||
|
|
case KEY_ENTER:
|
||
|
|
evdev_key_val = LV_KEY_ENTER;
|
||
|
|
break;
|
||
|
|
case KEY_UP:
|
||
|
|
evdev_key_val = LV_KEY_UP;
|
||
|
|
break;
|
||
|
|
case KEY_LEFT:
|
||
|
|
evdev_key_val = LV_KEY_PREV;
|
||
|
|
break;
|
||
|
|
case KEY_RIGHT:
|
||
|
|
evdev_key_val = LV_KEY_NEXT;
|
||
|
|
break;
|
||
|
|
case KEY_DOWN:
|
||
|
|
evdev_key_val = LV_KEY_DOWN;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
evdev_key_val = 0;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
pthread_mutex_lock(&evdev_lock);
|
||
|
|
evdev_val[0] = evdev_val[1];
|
||
|
|
evdev_val[1].x = x;
|
||
|
|
evdev_val[1].y = y;
|
||
|
|
evdev_val[1].button = button;
|
||
|
|
pthread_mutex_unlock(&evdev_lock);
|
||
|
|
|
||
|
|
#if FILE_DEBUG
|
||
|
|
fprintf(raw_point, "%d\t%d\t%d\n", x, y, button);
|
||
|
|
fflush(raw_point);
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
void evdev_read(lv_indev_t *drv, lv_indev_data_t *data)
|
||
|
|
{
|
||
|
|
int type = lv_indev_get_type(drv);
|
||
|
|
lv_display_t *disp = lv_indev_get_display(drv);
|
||
|
|
int hor_res = lv_display_get_horizontal_resolution(disp);
|
||
|
|
int ver_res = lv_display_get_vertical_resolution(disp);
|
||
|
|
int raw_x, raw_y, button_state;
|
||
|
|
int x, y;
|
||
|
|
int tmp;
|
||
|
|
int first_point = 0;
|
||
|
|
|
||
|
|
if (type == LV_INDEV_TYPE_KEYPAD)
|
||
|
|
{
|
||
|
|
/* No data retrieved */
|
||
|
|
data->key = evdev_key_val;
|
||
|
|
data->state = evdev_button;
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (type != LV_INDEV_TYPE_POINTER)
|
||
|
|
return;
|
||
|
|
/*Store the collected data*/
|
||
|
|
|
||
|
|
pthread_mutex_lock(&evdev_lock);
|
||
|
|
|
||
|
|
raw_x = evdev_val[1].x;
|
||
|
|
raw_y = evdev_val[1].y;
|
||
|
|
button_state = evdev_val[1].button;
|
||
|
|
if (evdev_val[0].button == LV_INDEV_STATE_REL)
|
||
|
|
{
|
||
|
|
first_point = 1;
|
||
|
|
touch_up = 0;
|
||
|
|
}
|
||
|
|
else if (button_state && touch_up)
|
||
|
|
{
|
||
|
|
/* Some times evdev_read may lost the touch up events due to
|
||
|
|
* the renderer has different period with touch screen report events,
|
||
|
|
* so add a global variable touch_up to make sure the evdev_read will
|
||
|
|
* not lost any touch up events.
|
||
|
|
*/
|
||
|
|
first_point = 1;
|
||
|
|
touch_up = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
pthread_mutex_unlock(&evdev_lock);
|
||
|
|
|
||
|
|
switch (evdev_rot)
|
||
|
|
{
|
||
|
|
case 0:
|
||
|
|
default:
|
||
|
|
break;
|
||
|
|
case 90:
|
||
|
|
tmp = raw_x;
|
||
|
|
raw_x = raw_y;
|
||
|
|
raw_y = evdev_max_y - tmp;
|
||
|
|
break;
|
||
|
|
case 180:
|
||
|
|
tmp = raw_x;
|
||
|
|
raw_x = evdev_max_x - raw_y;
|
||
|
|
raw_y = evdev_max_y - tmp;
|
||
|
|
break;
|
||
|
|
case 270:
|
||
|
|
tmp = raw_x;
|
||
|
|
raw_x = evdev_max_x - raw_y;
|
||
|
|
raw_y = tmp;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (evdev_calibrate)
|
||
|
|
{
|
||
|
|
raw_x = map(raw_x, evdev_min_x, evdev_max_x,
|
||
|
|
0, hor_res);
|
||
|
|
raw_y = map(raw_y, evdev_min_y, evdev_max_y,
|
||
|
|
0, ver_res);
|
||
|
|
}
|
||
|
|
|
||
|
|
KalmanUpdate(&kfx, raw_x * 1.0, first_point);
|
||
|
|
KalmanUpdate(&kfy, raw_y * 1.0, first_point);
|
||
|
|
|
||
|
|
x = (int)kfx.v;
|
||
|
|
y = (int)kfy.v;
|
||
|
|
|
||
|
|
data->point.x = x;
|
||
|
|
data->point.y = y;
|
||
|
|
data->state = button_state;
|
||
|
|
|
||
|
|
if (data->point.x < 0)
|
||
|
|
data->point.x = 0;
|
||
|
|
if (data->point.y < 0)
|
||
|
|
data->point.y = 0;
|
||
|
|
if (data->point.x >= hor_res)
|
||
|
|
data->point.x = hor_res - 1;
|
||
|
|
if (data->point.y >= ver_res)
|
||
|
|
data->point.y = ver_res - 1;
|
||
|
|
|
||
|
|
#if FILE_DEBUG
|
||
|
|
if (data->state)
|
||
|
|
{
|
||
|
|
fprintf(lv_raw_point, "%d\t%d\t%d\n", raw_x, raw_y, button_state);
|
||
|
|
fflush(lv_raw_point);
|
||
|
|
fprintf(lv_fix_point, "%d\t%d\t%d\n", data->point.x, data->point.y,
|
||
|
|
data->state);
|
||
|
|
fflush(lv_fix_point);
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
return ;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**********************
|
||
|
|
* STATIC FUNCTIONS
|
||
|
|
**********************/
|
||
|
|
int map(int x, int in_min, int in_max, int out_min, int out_max)
|
||
|
|
{
|
||
|
|
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
|
||
|
|
}
|
||
|
|
|
||
|
|
#endif
|