176 lines
4.4 KiB
C
176 lines
4.4 KiB
C
|
/**
|
||
|
* @file libinput.c
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
/*********************
|
||
|
* INCLUDES
|
||
|
*********************/
|
||
|
#include "libinput_drv.h"
|
||
|
#if USE_LIBINPUT != 0
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <unistd.h>
|
||
|
#include <linux/limits.h>
|
||
|
#include <fcntl.h>
|
||
|
#include <errno.h>
|
||
|
#include <stdbool.h>
|
||
|
#include <poll.h>
|
||
|
#include <libinput.h>
|
||
|
|
||
|
/*********************
|
||
|
* DEFINES
|
||
|
*********************/
|
||
|
|
||
|
/**********************
|
||
|
* TYPEDEFS
|
||
|
**********************/
|
||
|
|
||
|
/**********************
|
||
|
* STATIC PROTOTYPES
|
||
|
**********************/
|
||
|
static int open_restricted(const char *path, int flags, void *user_data);
|
||
|
static void close_restricted(int fd, void *user_data);
|
||
|
|
||
|
/**********************
|
||
|
* STATIC VARIABLES
|
||
|
**********************/
|
||
|
static int libinput_fd;
|
||
|
static int libinput_button;
|
||
|
static const int timeout = 0; // do not block
|
||
|
static const nfds_t nfds = 1;
|
||
|
static struct pollfd fds[1];
|
||
|
static lv_point_t most_recent_touch_point = { .x = 0, .y = 0};
|
||
|
|
||
|
static struct libinput *libinput_context;
|
||
|
static struct libinput_device *libinput_device;
|
||
|
const static struct libinput_interface interface = {
|
||
|
.open_restricted = open_restricted,
|
||
|
.close_restricted = close_restricted,
|
||
|
};
|
||
|
|
||
|
/**********************
|
||
|
* MACROS
|
||
|
**********************/
|
||
|
|
||
|
/**********************
|
||
|
* GLOBAL FUNCTIONS
|
||
|
**********************/
|
||
|
|
||
|
/**
|
||
|
* reconfigure the device file for libinput
|
||
|
* @param dev_name set the libinput device filename
|
||
|
* @return true: the device file set complete
|
||
|
* false: the device file doesn't exist current system
|
||
|
*/
|
||
|
bool libinput_set_file(char* dev_name)
|
||
|
{
|
||
|
// This check *should* not be necessary, yet applications crashes even on NULL handles.
|
||
|
// citing libinput.h:libinput_path_remove_device:
|
||
|
// > If no matching device exists, this function does nothing.
|
||
|
if (libinput_device) {
|
||
|
libinput_device = libinput_device_unref(libinput_device);
|
||
|
libinput_path_remove_device(libinput_device);
|
||
|
}
|
||
|
|
||
|
libinput_device = libinput_path_add_device(libinput_context, dev_name);
|
||
|
if(!libinput_device) {
|
||
|
perror("unable to add device to libinput context:");
|
||
|
return false;
|
||
|
}
|
||
|
libinput_device = libinput_device_ref(libinput_device);
|
||
|
if(!libinput_device) {
|
||
|
perror("unable to reference device within libinput context:");
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
libinput_button = LV_INDEV_STATE_REL;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Initialize the libinput interface
|
||
|
*/
|
||
|
void libinput_init(void)
|
||
|
{
|
||
|
libinput_device = NULL;
|
||
|
libinput_context = libinput_path_create_context(&interface, NULL);
|
||
|
if(!libinput_set_file(LIBINPUT_NAME)) {
|
||
|
perror("unable to add device \"" LIBINPUT_NAME "\" to libinput context:");
|
||
|
return;
|
||
|
}
|
||
|
libinput_fd = libinput_get_fd(libinput_context);
|
||
|
|
||
|
/* prepare poll */
|
||
|
fds[0].fd = libinput_fd;
|
||
|
fds[0].events = POLLIN;
|
||
|
fds[0].revents = 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the current position and state of the libinput
|
||
|
* @param indev_drv driver object itself
|
||
|
* @param data store the libinput data here
|
||
|
* @return false: because the points are not buffered, so no more data to be read
|
||
|
*/
|
||
|
bool libinput_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
|
||
|
{
|
||
|
struct libinput_event *event;
|
||
|
struct libinput_event_touch *touch_event = NULL;
|
||
|
int rc = 0;
|
||
|
|
||
|
rc = poll(fds, nfds, timeout);
|
||
|
switch (rc){
|
||
|
case -1:
|
||
|
perror(NULL);
|
||
|
case 0:
|
||
|
goto report_most_recent_state;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
libinput_dispatch(libinput_context);
|
||
|
while((event = libinput_get_event(libinput_context)) != NULL) {
|
||
|
enum libinput_event_type type = libinput_event_get_type(event);
|
||
|
switch (type) {
|
||
|
case LIBINPUT_EVENT_TOUCH_MOTION:
|
||
|
case LIBINPUT_EVENT_TOUCH_DOWN:
|
||
|
touch_event = libinput_event_get_touch_event(event);
|
||
|
most_recent_touch_point.x = libinput_event_touch_get_x_transformed(touch_event, LV_HOR_RES);
|
||
|
most_recent_touch_point.y = libinput_event_touch_get_y_transformed(touch_event, LV_VER_RES);
|
||
|
libinput_button = LV_INDEV_STATE_PR;
|
||
|
break;
|
||
|
case LIBINPUT_EVENT_TOUCH_UP:
|
||
|
libinput_button = LV_INDEV_STATE_REL;
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
libinput_event_destroy(event);
|
||
|
}
|
||
|
report_most_recent_state:
|
||
|
data->point.x = most_recent_touch_point.x;
|
||
|
data->point.y = most_recent_touch_point.y;
|
||
|
data->state = libinput_button;
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**********************
|
||
|
* STATIC FUNCTIONS
|
||
|
**********************/
|
||
|
|
||
|
static int open_restricted(const char *path, int flags, void *user_data)
|
||
|
{
|
||
|
int fd = open(path, flags);
|
||
|
return fd < 0 ? -errno : fd;
|
||
|
}
|
||
|
|
||
|
static void close_restricted(int fd, void *user_data)
|
||
|
{
|
||
|
close(fd);
|
||
|
}
|
||
|
|
||
|
#endif
|