176 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			176 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
| /**
 | |
|  * @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
 | 
