aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ginput
diff options
context:
space:
mode:
authorJoel Bodenmann <joel@embedded.pro>2016-08-23 23:10:04 +0200
committerJoel Bodenmann <joel@embedded.pro>2016-08-23 23:10:04 +0200
commitac5e96cca18884727b165f4245e42887ef0e3a21 (patch)
tree7f7d9f9e6994c16aa55c7cf67917787c2356dece /drivers/ginput
parent2db86d4f6730e972f649f985d948a51ea08aea41 (diff)
downloaduGFX-ac5e96cca18884727b165f4245e42887ef0e3a21.tar.gz
uGFX-ac5e96cca18884727b165f4245e42887ef0e3a21.tar.bz2
uGFX-ac5e96cca18884727b165f4245e42887ef0e3a21.zip
Adding Linux event input touch driver
Diffstat (limited to 'drivers/ginput')
-rw-r--r--drivers/ginput/touch/Linux-Event/driver.mk1
-rw-r--r--drivers/ginput/touch/Linux-Event/gmouse_lld_linux_event.c142
-rw-r--r--drivers/ginput/touch/Linux-Event/gmouse_lld_linux_event_board_template.h32
3 files changed, 175 insertions, 0 deletions
diff --git a/drivers/ginput/touch/Linux-Event/driver.mk b/drivers/ginput/touch/Linux-Event/driver.mk
new file mode 100644
index 00000000..20446f99
--- /dev/null
+++ b/drivers/ginput/touch/Linux-Event/driver.mk
@@ -0,0 +1 @@
+GFXSRC += $(GFXLIB)/drivers/ginput/touch/Linux-Event/gmouse_lld_linux_event.c
diff --git a/drivers/ginput/touch/Linux-Event/gmouse_lld_linux_event.c b/drivers/ginput/touch/Linux-Event/gmouse_lld_linux_event.c
new file mode 100644
index 00000000..e1989e03
--- /dev/null
+++ b/drivers/ginput/touch/Linux-Event/gmouse_lld_linux_event.c
@@ -0,0 +1,142 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+#include "gfx.h"
+
+#include <linux/input.h>
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#if GFX_USE_GINPUT && GINPUT_NEED_MOUSE
+
+#define GMOUSE_DRIVER_VMT GMOUSEVMT_LINUX_EVENT
+#include "src/ginput/ginput_driver_mouse.h"
+
+// Include the board file
+#include "gmouse_lld_linux_event_board.h"
+
+// Private area definition
+// We need to store the last reading ourselves because we only get events
+// from the Linux system. When touching the touchscreen and then moving around,
+// we only get one z = 1 event. However, the GINPUT module expects z = 1 to be
+// true for the entire touch duration.
+typedef struct privStruct {
+ int fd;
+ GMouseReading lastReading;
+} privStruct;
+
+static bool_t _init(GMouse* m, unsigned driverInstance)
+{
+ (void)driverInstance;
+
+ // Retrive the private area struct
+ privStruct* priv = (privStruct*)(m+1);
+
+ // Open the device
+ priv->fd = open(GMOUSE_LINUX_EVENT_DEVICE, O_RDONLY | O_NONBLOCK);
+ if (priv->fd < 0) {
+ fprintf(stderr, "GINPUT Mouse: Cannot open input device (%s)\n", GMOUSE_LINUX_EVENT_DEVICE);
+ return FALSE;
+ }
+
+ // Initialize
+ priv->lastReading.buttons = 0;
+ priv->lastReading.x = 0;
+ priv->lastReading.y = 0;
+ priv->lastReading.z = 0;
+
+ return TRUE;
+}
+
+static bool_t _read(GMouse* m, GMouseReading* pdr)
+{
+ int i;
+ int rb;
+ struct input_event ev[64];
+ privStruct* priv;
+
+ // Retrive the private area struct
+ priv = (privStruct*)(m+1);
+
+ // Assume not touched
+ pdr->buttons = 0;
+ pdr->z = priv->lastReading.z;
+ pdr->x = priv->lastReading.x;
+ pdr->y = priv->lastReading.y;
+
+ // Read
+ rb = read(priv->fd, ev, sizeof(struct input_event)*64);
+
+ // Parse
+ if (rb > 0) {
+ for (i = 0; i < (int)(rb / sizeof(struct input_event)); i++) {
+ if (ev[i].type == EV_KEY && ev[i].code == 330 && ev[i].value == 1) {
+ pdr->z = 1;
+ }
+ else if (ev[i].type == EV_KEY && ev[i].code == 330 && ev[i].value == 0) {
+ pdr->z = 0;
+ }
+ else if (ev[i].type == EV_ABS && ev[i].code == 0 && ev[i].value > 0) {
+ pdr->x = ev[i].value;
+ }
+ else if (ev[i].type == EV_ABS && ev[i].code == 1 && ev[i].value > 0) {
+ pdr->y = ev[i].value;
+ }
+ }
+ }
+
+ // Store the current reading
+ priv->lastReading.x = pdr->x;
+ priv->lastReading.y = pdr->y;
+ priv->lastReading.z = pdr->z;
+ priv->lastReading.buttons = pdr->buttons;
+
+ return TRUE;
+}
+
+const GMouseVMT const GMOUSE_DRIVER_VMT[1] = {{
+ {
+ GDRIVER_TYPE_TOUCH,
+ #if GMOUSE_LINUX_EVENT_FINGERMODE
+ GMOUSE_VFLG_DEFAULTFINGER |
+ #endif
+
+ #if GMOUSE_LINUX_EVENT_SELF_CALIBRATE
+ GMOUSE_VFLG_TOUCH | GMOUSE_VFLG_ONLY_DOWN | GMOUSE_VFLG_POORUPDOWN ,
+ #else
+ GMOUSE_VFLG_TOUCH | GMOUSE_VFLG_ONLY_DOWN | GMOUSE_VFLG_POORUPDOWN |GMOUSE_VFLG_CALIBRATE,
+ #endif
+ sizeof(GMouse) + sizeof(privStruct),
+ _gmouseInitDriver,
+ _gmousePostInitDriver,
+ _gmouseDeInitDriver
+ },
+ 1, // z_max - (currently?) not supported
+ 0, // z_min - (currently?) not supported
+ 1, // z_touchon
+ 0, // z_touchoff
+ { // pen_jitter
+ 0, // calibrate
+ 0, // click
+ 0 // move
+ },
+ { // finger_jitter
+ 0, // calibrate
+ 0, // click
+ 0 // move
+ },
+ _init, // init
+ 0, // deinit
+ _read, // get
+ 0, // calsave
+ 0 // calload
+}};
+
+#endif /* GFX_USE_GINPUT && GINPUT_NEED_MOUSE */
+
diff --git a/drivers/ginput/touch/Linux-Event/gmouse_lld_linux_event_board_template.h b/drivers/ginput/touch/Linux-Event/gmouse_lld_linux_event_board_template.h
new file mode 100644
index 00000000..c6bf5a7b
--- /dev/null
+++ b/drivers/ginput/touch/Linux-Event/gmouse_lld_linux_event_board_template.h
@@ -0,0 +1,32 @@
+/*
+ * This file is subject to the terms of the GFX License. If a copy of
+ * the license was not distributed with this file, you can obtain one at:
+ *
+ * http://ugfx.org/license.html
+ */
+
+#ifndef _GINPUT_LLD_MOUSE_BOARD_H
+#define _GINPUT_LLD_MOUSE_BOARD_H
+
+// Resolution and Accuracy Settings
+#define GMOUSE_LINUX_EVENT_PEN_CALIBRATE_ERROR 8
+#define GMOUSE_LINUX_EVENT_PEN_CLICK_ERROR 6
+#define GMOUSE_LINUX_EVENT_PEN_MOVE_ERROR 4
+#define GMOUSE_LINUX_EVENT_FINGER_CALIBRATE_ERROR 14
+#define GMOUSE_LINUX_EVENT_FINGER_CLICK_ERROR 18
+#define GMOUSE_LINUX_EVENT_FINGER_MOVE_ERROR 14
+
+#define GMOUSE_LINUX_EVENT_NUM_EVENT 64
+
+// The linux device input used for touchscreen
+#define GMOUSE_LINUX_EVENT_DEVICE "/dev/input/event0"
+
+// Set this to TRUE if you want self-calibration.
+// NOTE: This is not as accurate as real calibration.
+// It requires the orientation of the touch panel to match the display.
+// It requires the active area of the touch panel to exactly match the display size.
+#define GMOUSE_LINUX_EVENT_SELF_CALIBRATE FALSE
+
+#define GMOUSE_LINUX_EVENT_FINGERMODE TRUE
+
+#endif /* _GINPUT_LLD_MOUSE_BOARD_H */