You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
252 lines
6.8 KiB
C
252 lines
6.8 KiB
C
2 years ago
|
/**
|
||
|
* @file evdev.c
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
/*********************
|
||
|
* INCLUDES
|
||
|
*********************/
|
||
|
#include "evdev.h"
|
||
|
#if USE_EVDEV != 0 || USE_BSD_EVDEV
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <unistd.h>
|
||
|
#include <fcntl.h>
|
||
|
#if USE_BSD_EVDEV
|
||
|
#include <dev/evdev/input.h>
|
||
|
#else
|
||
|
#include <linux/input.h>
|
||
|
#endif
|
||
|
|
||
|
#if USE_XKB
|
||
|
#include "xkb.h"
|
||
|
#endif /* USE_XKB */
|
||
|
|
||
|
/*********************
|
||
|
* DEFINES
|
||
|
*********************/
|
||
|
|
||
|
/**********************
|
||
|
* TYPEDEFS
|
||
|
**********************/
|
||
|
|
||
|
/**********************
|
||
|
* STATIC PROTOTYPES
|
||
|
**********************/
|
||
|
int map(int x, int in_min, int in_max, int out_min, int out_max);
|
||
|
|
||
|
/**********************
|
||
|
* STATIC VARIABLES
|
||
|
**********************/
|
||
|
int evdev_fd = -1;
|
||
|
int evdev_root_x;
|
||
|
int evdev_root_y;
|
||
|
int evdev_button;
|
||
|
|
||
|
int evdev_key_val;
|
||
|
|
||
|
/**********************
|
||
|
* MACROS
|
||
|
**********************/
|
||
|
|
||
|
/**********************
|
||
|
* GLOBAL FUNCTIONS
|
||
|
**********************/
|
||
|
|
||
|
/**
|
||
|
* Initialize the evdev interface
|
||
|
*/
|
||
|
void evdev_init(void)
|
||
|
{
|
||
|
if (!evdev_set_file(EVDEV_NAME)) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
#if USE_XKB
|
||
|
xkb_init();
|
||
|
#endif
|
||
|
}
|
||
|
/**
|
||
|
* 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
|
||
|
*/
|
||
|
bool evdev_set_file(char* dev_name)
|
||
|
{
|
||
|
if(evdev_fd != -1) {
|
||
|
close(evdev_fd);
|
||
|
}
|
||
|
#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 to open evdev interface:");
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
#if USE_BSD_EVDEV
|
||
|
fcntl(evdev_fd, F_SETFL, O_NONBLOCK);
|
||
|
#else
|
||
|
fcntl(evdev_fd, F_SETFL, O_ASYNC | O_NONBLOCK);
|
||
|
#endif
|
||
|
|
||
|
evdev_root_x = 0;
|
||
|
evdev_root_y = 0;
|
||
|
evdev_key_val = 0;
|
||
|
evdev_button = LV_INDEV_STATE_REL;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
/**
|
||
|
* Get the current position and state of the evdev
|
||
|
* @param data store the evdev data here
|
||
|
*/
|
||
|
void evdev_read(lv_indev_drv_t * drv, lv_indev_data_t * data)
|
||
|
{
|
||
|
struct input_event in;
|
||
|
|
||
|
while(read(evdev_fd, &in, sizeof(struct input_event)) > 0) {
|
||
|
if(in.type == EV_REL) {
|
||
|
if(in.code == REL_X)
|
||
|
#if EVDEV_SWAP_AXES
|
||
|
evdev_root_y += in.value;
|
||
|
#else
|
||
|
evdev_root_x += in.value;
|
||
|
#endif
|
||
|
else if(in.code == REL_Y)
|
||
|
#if EVDEV_SWAP_AXES
|
||
|
evdev_root_x += in.value;
|
||
|
#else
|
||
|
evdev_root_y += in.value;
|
||
|
#endif
|
||
|
} else if(in.type == EV_ABS) {
|
||
|
if(in.code == ABS_X)
|
||
|
#if EVDEV_SWAP_AXES
|
||
|
evdev_root_y = in.value;
|
||
|
#else
|
||
|
evdev_root_x = in.value;
|
||
|
#endif
|
||
|
else if(in.code == ABS_Y)
|
||
|
#if EVDEV_SWAP_AXES
|
||
|
evdev_root_x = in.value;
|
||
|
#else
|
||
|
evdev_root_y = in.value;
|
||
|
#endif
|
||
|
else if(in.code == ABS_MT_POSITION_X)
|
||
|
#if EVDEV_SWAP_AXES
|
||
|
evdev_root_y = in.value;
|
||
|
#else
|
||
|
evdev_root_x = in.value;
|
||
|
#endif
|
||
|
else if(in.code == ABS_MT_POSITION_Y)
|
||
|
#if EVDEV_SWAP_AXES
|
||
|
evdev_root_x = in.value;
|
||
|
#else
|
||
|
evdev_root_y = in.value;
|
||
|
#endif
|
||
|
else if(in.code == ABS_MT_TRACKING_ID) {
|
||
|
if(in.value == -1)
|
||
|
evdev_button = LV_INDEV_STATE_REL;
|
||
|
else if(in.value == 0)
|
||
|
evdev_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;
|
||
|
else if(in.value == 1)
|
||
|
evdev_button = LV_INDEV_STATE_PR;
|
||
|
} else if(drv->type == LV_INDEV_TYPE_KEYPAD) {
|
||
|
#if USE_XKB
|
||
|
data->key = xkb_process_key(in.code, in.value != 0);
|
||
|
#else
|
||
|
switch(in.code) {
|
||
|
case KEY_BACKSPACE:
|
||
|
data->key = LV_KEY_BACKSPACE;
|
||
|
break;
|
||
|
case KEY_ENTER:
|
||
|
data->key = LV_KEY_ENTER;
|
||
|
break;
|
||
|
case KEY_PREVIOUS:
|
||
|
data->key = LV_KEY_PREV;
|
||
|
break;
|
||
|
case KEY_NEXT:
|
||
|
data->key = LV_KEY_NEXT;
|
||
|
break;
|
||
|
case KEY_UP:
|
||
|
data->key = LV_KEY_UP;
|
||
|
break;
|
||
|
case KEY_LEFT:
|
||
|
data->key = LV_KEY_LEFT;
|
||
|
break;
|
||
|
case KEY_RIGHT:
|
||
|
data->key = LV_KEY_RIGHT;
|
||
|
break;
|
||
|
case KEY_DOWN:
|
||
|
data->key = LV_KEY_DOWN;
|
||
|
break;
|
||
|
case KEY_TAB:
|
||
|
data->key = LV_KEY_NEXT;
|
||
|
break;
|
||
|
default:
|
||
|
data->key = 0;
|
||
|
break;
|
||
|
}
|
||
|
#endif /* USE_XKB */
|
||
|
if (data->key != 0) {
|
||
|
/* Only record button state when actual output is produced to prevent widgets from refreshing */
|
||
|
data->state = (in.value) ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
|
||
|
}
|
||
|
evdev_key_val = data->key;
|
||
|
evdev_button = data->state;
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(drv->type == LV_INDEV_TYPE_KEYPAD) {
|
||
|
/* No data retrieved */
|
||
|
data->key = evdev_key_val;
|
||
|
data->state = evdev_button;
|
||
|
return;
|
||
|
}
|
||
|
if(drv->type != LV_INDEV_TYPE_POINTER)
|
||
|
return ;
|
||
|
/*Store the collected data*/
|
||
|
|
||
|
#if EVDEV_CALIBRATE
|
||
|
data->point.x = map(evdev_root_x, EVDEV_HOR_MIN, EVDEV_HOR_MAX, 0, drv->disp->driver->hor_res);
|
||
|
data->point.y = map(evdev_root_y, EVDEV_VER_MIN, EVDEV_VER_MAX, 0, drv->disp->driver->ver_res);
|
||
|
#else
|
||
|
data->point.x = evdev_root_x;
|
||
|
data->point.y = evdev_root_y;
|
||
|
#endif
|
||
|
|
||
|
data->state = evdev_button;
|
||
|
|
||
|
if(data->point.x < 0)
|
||
|
data->point.x = 0;
|
||
|
if(data->point.y < 0)
|
||
|
data->point.y = 0;
|
||
|
if(data->point.x >= drv->disp->driver->hor_res)
|
||
|
data->point.x = drv->disp->driver->hor_res - 1;
|
||
|
if(data->point.y >= drv->disp->driver->ver_res)
|
||
|
data->point.y = drv->disp->driver->ver_res - 1;
|
||
|
|
||
|
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
|