diff --git a/boards/base/Linux-Framebuffer-Touch/board.mk b/boards/base/Linux-Framebuffer-Touch/board.mk new file mode 100644 index 00000000..813e6ef0 --- /dev/null +++ b/boards/base/Linux-Framebuffer-Touch/board.mk @@ -0,0 +1,7 @@ +GFXINC += $(GFXLIB)/boards/base/Linux-Framebuffer-Touch +GFXSRC += +GFXDEFS += -DGFX_USE_OS_LINUX=TRUE +GFXLIBS += rt + +include $(GFXLIB)/boards/base/Linux-Framebuffer/board.mk +include $(GFXLIB)/drivers/ginput/touch/Linux-Event/driver.mk diff --git a/boards/base/Linux-Framebuffer-Touch/gmouse_lld_linux_event_board.h b/boards/base/Linux-Framebuffer-Touch/gmouse_lld_linux_event_board.h new file mode 100644 index 00000000..c6bf5a7b --- /dev/null +++ b/boards/base/Linux-Framebuffer-Touch/gmouse_lld_linux_event_board.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 */ diff --git a/docs/releases.txt b/docs/releases.txt index 09950cbc..14e1051b 100644 --- a/docs/releases.txt +++ b/docs/releases.txt @@ -11,6 +11,7 @@ FIX: Fixed potential crash when GDISP_NEED_TEXT_WORDWRAP is turned on FEATURE: Added SDL driver FEATURE: Added ILI9225 driver FEATURE: Added ST7735 driver +FEATURE: Added Linux event input driver *** Release 2.6 *** 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 + +#include +#include +#include + +#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 */