143 lines
3.3 KiB
C
143 lines
3.3 KiB
C
/*
|
|
* 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 */
|
|
|