aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ginput/driver_mouse.h197
-rw-r--r--src/ginput/ginput_ginput.c14
-rw-r--r--src/ginput/ginput_mouse.c714
-rw-r--r--src/ginput/ginput_mouse.h1
-rw-r--r--src/ginput/sys_options.h45
5 files changed, 475 insertions, 496 deletions
diff --git a/src/ginput/driver_mouse.h b/src/ginput/driver_mouse.h
index 21d87dac..a0f0f807 100644
--- a/src/ginput/driver_mouse.h
+++ b/src/ginput/driver_mouse.h
@@ -19,67 +19,81 @@
#if GINPUT_NEED_MOUSE || defined(__DOXYGEN__)
-#include "ginput_lld_mouse_config.h"
+// Include the GDRIVER infrastructure
+#include "src/gdriver/sys_defs.h"
-// GEVENT_MOUSE or GEVENT_TOUCH - What type of device is this.
-#ifndef GINPUT_MOUSE_EVENT_TYPE
- #define GINPUT_MOUSE_EVENT_TYPE GEVENT_MOUSE
-#endif
-
-// TRUE/FALSE - Does the mouse/touch driver require calibration?
-#ifndef GINPUT_MOUSE_NEED_CALIBRATION
- #define GINPUT_MOUSE_NEED_CALIBRATION FALSE
-#endif
-
-// TRUE/FALSE - Should the calibration happen at the extremes of the panel?
-#ifndef GINPUT_MOUSE_CALIBRATE_EXTREMES
- #define GINPUT_MOUSE_CALIBRATE_EXTREMES FALSE
-#endif
-
-// TRUE/FALSE - Can the mouse/touch driver itself save calibration data?
-#ifndef GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE
- #define GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE FALSE
-#endif
-
-// n or -1 - n means to test calibration result (+/- pixels), -1 means not to.
-#ifndef GINPUT_MOUSE_MAX_CALIBRATION_ERROR
- #define GINPUT_MOUSE_MAX_CALIBRATION_ERROR -1
-#endif
-
-// n - How many times to read (and average) per poll
-#ifndef GINPUT_MOUSE_READ_CYCLES
- #define GINPUT_MOUSE_READ_CYCLES 1
-#endif
-
-// n - Millisecs between poll's
-#ifndef GINPUT_MOUSE_POLL_PERIOD
- #define GINPUT_MOUSE_POLL_PERIOD 25
-#endif
-
-// n - Movement allowed without discarding the CLICK or CLICKCXT event (+/- pixels)
-#ifndef GINPUT_MOUSE_MAX_CLICK_JITTER
- #define GINPUT_MOUSE_MAX_CLICK_JITTER 1
-#endif
-
-// n - Movement allowed without discarding the MOVE event (+/- pixels)
-#ifndef GINPUT_MOUSE_MAX_MOVE_JITTER
- #define GINPUT_MOUSE_MAX_MOVE_JITTER 0
-#endif
-
-// ms - Millisecs seperating a CLICK from a CXTCLICK
-#ifndef GINPUT_MOUSE_CLICK_TIME
- #define GINPUT_MOUSE_CLICK_TIME 700
-#endif
-
-// true/false - Whether the mouse driver internally handles screen rotation
-#ifndef GINPUT_MOUSE_NO_ROTATION
- #define GINPUT_MOUSE_NO_ROTATION FALSE
-#endif
-
-typedef struct MouseReading_t {
+typedef struct GMouseReading {
coord_t x, y, z;
uint16_t buttons;
- } MouseReading;
+ } GMouseReading;
+
+#if !GINPUT_TOUCH_NOCALIBRATE
+ typedef struct GMouseCalibration {
+ float ax;
+ float bx;
+ float cx;
+ float ay;
+ float by;
+ float cy;
+ } GMouseCalibration;
+#endif
+
+typedef struct GMouse {
+ GDriver d; // The driver overheads and vmt
+ GMouseReading r; // The current position and state
+ uint16_t flags; // Flags
+ #define GMOUSE_FLG_ACTIVE 0x0001 // Mouse is currently active
+ #define GMOUSE_FLG_CLICK_TIMER 0x0002 // Currently timing a click event
+ #define GMOUSE_FLG_INDELTA 0x0004 // Currently in a up/down transition test
+ #define GMOUSE_FLG_CLIP 0x0008 // Clip reading to the display
+ #define GMOUSE_FLG_CALIBRATE 0x0010 // Calibrate readings
+ #define GMOUSE_FLG_CAL_INPROGRESS 0x0020 // Calibrate is currently in progress
+ #define GMOUSE_FLG_CAL_SAVED 0x0040 // Calibration has been saved
+ #define GMOUSE_FLG_FINGERMODE 0x0080 // Mouse is currently in finger mode
+ #define GMOUSE_FLG_NEEDREAD 0x0100 // The mouse needs reading
+ point clickpos; // The position of the last click event
+ systemticks_t clicktime; // The time of the last click event
+ GDisplay * display; // The display the mouse is associated with
+ #if !GINPUT_TOUCH_NOCALIBRATE
+ GMouseCalibrationSaveRoutine fnsavecal; // The calibration load routine
+ GMouseCalibrationLoadRoutine fnloadcal; // The calibration save routine
+ GMouseCalibration caldata; // The calibration data
+ #endif
+ // Other driver specific fields may follow.
+} GMouse;
+
+typedef struct GMouseJitter {
+ coord_t calibrate; // Maximum error for a calibration to succeed
+ coord_t click; // Movement allowed without discarding the CLICK or CLICKCXT event
+ coord_t move; // Movement allowed without discarding the MOVE event
+} GMouseJitter;
+
+typedef struct GMouseVMT {
+ GDriverVMT d; // Device flags are part of the general vmt
+ #define GMOUSE_VFLG_TOUCH 0x0001 // This is a touch device (rather than a mouse). Button 1 is calculated from z value.
+ #define GMOUSE_VFLG_NOPOLL 0x0002 // Do not poll this device - it is purely interrupt driven
+ #define GMOUSE_VFLG_SELFROTATION 0x0004 // This device returns readings that are aligned with the display orientation
+ #define GMOUSE_VFLG_DEFAULTFINGER 0x0008 // Default to finger mode
+ #define GMOUSE_VFLG_CALIBRATE 0x0010 // This device requires calibration
+ #define GMOUSE_VFLG_CAL_EXTREMES 0x0020 // Use edge to edge calibration
+ #define GMOUSE_VFLG_CAL_TEST 0x0040 // Test the results of the calibration
+ #define GMOUSE_VFLG_ONLY_DOWN 0x0100 // This device returns a valid position only when the mouse is down
+ #define GMOUSE_VFLG_POORUPDOWN 0x0200 // Position readings during up/down are unreliable
+ coord_t z_max; // TOUCH: Maximum possible z value (fully touched)
+ coord_t z_min; // TOUCH: Minimum possible z value (touch off screen). Note may also be > z_max
+ coord_t z_touchon; // TOUCH: z values between z_max and this are a solid touch on
+ coord_t z_touchoff; // TOUCH: z values between z_min and this are a solid touch off
+
+ GMouseJitter pen_jitter; // PEN MODE: Jitter settings
+ GMouseJitter finger_jitter; // FINGER MODE: Jitter settings
+
+ bool_t (*init)(GMouse *m); // Required
+ void (*get)(GMouse *m, GMouseReading *prd); // Required
+ void (*calsave)(GMouse *m, void *buf, size_t sz); // Optional
+ const char *(*calload)(GMouse *m); // Optional: Can return NULL if no data is saved. Buffer is automatically gfxFree()'d afterwards.
+} GMouseVMT;
+
+#define gmvmt(m) ((const GMouseVMT const *)((m)->d.vmt))
/*===========================================================================*/
/* External declarations. */
@@ -88,91 +102,30 @@ typedef struct MouseReading_t {
#ifdef __cplusplus
extern "C" {
#endif
-
- /**
- * @brief Initialise the mouse/touch.
- *
- * @notapi
- */
- void ginput_lld_mouse_init(void);
-
- /**
- * @brief Read the mouse/touch position.
- *
- * @param[in] pt A pointer to the structure to fill
- *
- * @note For drivers that don't support returning a position
- * when the touch is up (most touch devices), it should
- * return the previous position with the new Z value.
- * The z value is the pressure for those touch devices
- * that support it (-100 to 100 where > 0 is touched)
- * or, 0 or 100 for those drivers that don't.
- *
- * @notapi
- */
- void ginput_lld_mouse_get_reading(MouseReading *pt);
-
- #if GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE
- /**
- * @brief Load calibration data from a storage area on the touch controller.
- *
- * @param[in] instance The mouse instance number
- *
- * @note The instance parameter is currently always 0 as we only support
- * one mouse/touch device at a time.
- * @note This routine should only be provided if the driver has its own
- * storage area where calibration data can be stored. The drivers
- * option.h file should define GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE = TRUE
- * if it supports this.
- *
- * @notapi
- */
- const char *ginput_lld_mouse_calibration_load(uint16_t instance);
- /**
- * @brief Save calibration data to a storage area on the touch controller.
- *
- * @param[in] instance The mouse instance number
- * @param[in] calbuf The calibration data to be saved
- * @param[in] sz The size of the calibration data
- *
- * @note The instance parameter is currently always 0 as we only support
- * one mouse/touch device at a time.
- * @note This routine should only be provided if the driver has its own
- * storage area where calibration data can be stored. The drivers
- * option.h file should define GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE = TRUE
- * if it supports this.
- *
- * @notapi
- */
- void ginput_lld_mouse_calibration_save(uint16_t instance, const uint8_t *calbuf, size_t sz);
- #endif
-
/**
* @brief Wakeup the high level code so that it attempts another read
*
* @note This routine is provided to low level drivers by the high level code
- * @note Particularly useful if GINPUT_MOUSE_POLL_PERIOD = TIME_INFINITE
*
* @notapi
*/
- void ginputMouseWakeup(void);
+ void ginputMouseWakeup(GMouse *m);
/**
* @brief Wakeup the high level code so that it attempts another read
*
* @note This routine is provided to low level drivers by the high level code
- * @note Particularly useful if GINPUT_MOUSE_POLL_PERIOD = TIME_INFINITE
*
* @iclass
* @notapi
*/
- void ginputMouseWakeupI(void);
+ void ginputMouseWakeupI(GMouse *m);
#ifdef __cplusplus
}
#endif
-#endif /* GINPUT_NEED_MOUSE || GINPUT_NEED_TOUCH */
+#endif /* GINPUT_NEED_MOUSE */
#endif /* _LLD_GINPUT_MOUSE_H */
/** @} */
diff --git a/src/ginput/ginput_ginput.c b/src/ginput/ginput_ginput.c
index 4197fa25..191ae025 100644
--- a/src/ginput/ginput_ginput.c
+++ b/src/ginput/ginput_ginput.c
@@ -16,10 +16,16 @@
#if GFX_USE_GINPUT
+#if GINPUT_NEED_MOUSE
+ extern void _gmouseInit(void);
+ extern void _gmouseDeinit(void);
+#endif
+
void _ginputInit(void)
{
- /* ToDo */
-
+ #if GINPUT_NEED_MOUSE
+ _gmouseInit();
+ #endif
/**
* This should really call an init routine for each ginput sub-system.
* Maybe we'll do this later.
@@ -28,7 +34,9 @@ void _ginputInit(void)
void _ginputDeinit(void)
{
-
+ #if GINPUT_NEED_MOUSE
+ _gmouseDeinit();
+ #endif
}
#endif /* GFX_USE_GINPUT */
diff --git a/src/ginput/ginput_mouse.c b/src/ginput/ginput_mouse.c
index a0daba98..ee6f51b6 100644
--- a/src/ginput/ginput_mouse.c
+++ b/src/ginput/ginput_mouse.c
@@ -19,106 +19,29 @@
#include "driver_mouse.h"
-#if GINPUT_MOUSE_NEED_CALIBRATION
+#if !GINPUT_TOUCH_NOCALIBRATE
#if !defined(GFX_USE_GDISP) || !GFX_USE_GDISP
#error "GINPUT: GFX_USE_GDISP must be defined when mouse or touch calibration is required"
#endif
#include <string.h> // Required for memcpy
- #define GINPUT_MOUSE_CALIBRATION_FONT "* Double"
- #define GINPUT_MOUSE_CALIBRATION_FONT2 "* Narrow"
- #define GINPUT_MOUSE_CALIBRATION_TEXT "Calibration"
- #define GINPUT_MOUSE_CALIBRATION_ERROR_TEXT "Failed - Please try again!"
- #define GINPUT_MOUSE_CALIBRATION_SAME_TEXT "Error: Same Reading - Check Driver!"
+ #define CALIBRATION_FONT "* Double"
+ #define CALIBRATION_FONT2 "* Narrow"
+ #define CALIBRATION_TEXT "Calibration"
+ #define CALIBRATION_ERROR_TEXT "Failed - Please try again!"
+ #define CALIBRATION_SAME_TEXT "Error: Same Reading - Check Driver!"
+ #define CALIBRATION_BACKGROUND Blue
+ #define CALIBRATION_COLOR1 White
+ #define CALIBRATION_COLOR2 RGB2COLOR(184,158,131)
- #if GINPUT_MOUSE_MAX_CALIBRATION_ERROR < 0
- #define GINPUT_MOUSE_CALIBRATION_POINTS 3
- #else
- #define GINPUT_MOUSE_CALIBRATION_POINTS 4
- #endif
-
- typedef struct Calibration_t {
- float ax;
- float bx;
- float cx;
- float ay;
- float by;
- float cy;
- } Calibration;
#endif
-typedef struct MousePoint_t {
- coord_t x, y;
-} MousePoint;
-
static GTIMER_DECL(MouseTimer);
-static struct MouseConfig_t {
- MouseReading t;
- MousePoint movepos;
- MousePoint clickpos;
- systemticks_t clicktime;
- uint16_t last_buttons;
- uint16_t flags;
- #define FLG_INIT_DONE 0x8000
- #define FLG_CLICK_TIMER 0x0001
- #define FLG_IN_CAL 0x0010
- #define FLG_CAL_OK 0x0020
- #define FLG_CAL_SAVED 0x0040
- #define FLG_CAL_FREE 0x0080
- #define FLG_CAL_RAW 0x0100
- #if GINPUT_MOUSE_NEED_CALIBRATION
- GMouseCalibrationSaveRoutine fnsavecal;
- GMouseCalibrationLoadRoutine fnloadcal;
- Calibration caldata;
- #endif
- GDisplay * display;
-} MouseConfig;
-
-void _tsOrientClip(MouseReading *pt, GDisplay *g, bool_t doClip) {
- coord_t w, h;
-
- w = gdispGGetWidth(g);
- h = gdispGGetHeight(g);
-
- #if GDISP_NEED_CONTROL && !GINPUT_MOUSE_NO_ROTATION
- switch(gdispGGetOrientation(g)) {
- case GDISP_ROTATE_0:
- break;
- case GDISP_ROTATE_90:
- {
- coord_t t = pt->x;
- pt->x = w - 1 - pt->y;
- pt->y = t;
- }
- break;
- case GDISP_ROTATE_180:
- pt->x = w - 1 - pt->x;
- pt->y = h - 1 - pt->y;
- break;
- case GDISP_ROTATE_270:
- {
- coord_t t = pt->y;
- pt->y = h - 1 - pt->x;
- pt->x = t;
- }
- break;
- default:
- break;
- }
- #endif
-
- if (doClip) {
- if (pt->x < 0) pt->x = 0;
- else if (pt->x >= w) pt->x = w-1;
- if (pt->y < 0) pt->y = 0;
- else if (pt->y >= h) pt->y = h-1;
- }
-}
-
-#if GINPUT_MOUSE_NEED_CALIBRATION
- static inline void _tsSetIdentity(Calibration *c) {
+#if !GINPUT_TOUCH_NOCALIBRATE
+ /*
+ static inline void CalibrationSetIdentity(MouseCalibration *c) {
c->ax = 1;
c->bx = 0;
c->cx = 0;
@@ -126,334 +49,427 @@ void _tsOrientClip(MouseReading *pt, GDisplay *g, bool_t doClip) {
c->by = 1;
c->cy = 0;
}
-
- static inline void _tsDrawCross(const MousePoint *pp) {
- gdispGDrawLine(MouseConfig.display, pp->x-15, pp->y, pp->x-2, pp->y, White);
- gdispGDrawLine(MouseConfig.display, pp->x+2, pp->y, pp->x+15, pp->y, White);
- gdispGDrawLine(MouseConfig.display, pp->x, pp->y-15, pp->x, pp->y-2, White);
- gdispGDrawLine(MouseConfig.display, pp->x, pp->y+2, pp->x, pp->y+15, White);
-
- gdispGDrawLine(MouseConfig.display, pp->x-15, pp->y+15, pp->x-7, pp->y+15, RGB2COLOR(184,158,131));
- gdispGDrawLine(MouseConfig.display, pp->x-15, pp->y+7, pp->x-15, pp->y+15, RGB2COLOR(184,158,131));
-
- gdispGDrawLine(MouseConfig.display, pp->x-15, pp->y-15, pp->x-7, pp->y-15, RGB2COLOR(184,158,131));
- gdispGDrawLine(MouseConfig.display, pp->x-15, pp->y-7, pp->x-15, pp->y-15, RGB2COLOR(184,158,131));
-
- gdispGDrawLine(MouseConfig.display, pp->x+7, pp->y+15, pp->x+15, pp->y+15, RGB2COLOR(184,158,131));
- gdispGDrawLine(MouseConfig.display, pp->x+15, pp->y+7, pp->x+15, pp->y+15, RGB2COLOR(184,158,131));
-
- gdispGDrawLine(MouseConfig.display, pp->x+7, pp->y-15, pp->x+15, pp->y-15, RGB2COLOR(184,158,131));
- gdispGDrawLine(MouseConfig.display, pp->x+15, pp->y-15, pp->x+15, pp->y-7, RGB2COLOR(184,158,131));
+ */
+
+ static inline void CalibrationCrossDraw(GMouse *m, const point *pp) {
+ gdispGDrawLine(m->display, pp->x-15, pp->y, pp->x-2, pp->y, CALIBRATION_COLOR1);
+ gdispGDrawLine(m->display, pp->x+2, pp->y, pp->x+15, pp->y, CALIBRATION_COLOR1);
+ gdispGDrawLine(m->display, pp->x, pp->y-15, pp->x, pp->y-2, CALIBRATION_COLOR1);
+ gdispGDrawLine(m->display, pp->x, pp->y+2, pp->x, pp->y+15, CALIBRATION_COLOR1);
+ gdispGDrawLine(m->display, pp->x-15, pp->y+15, pp->x-7, pp->y+15, CALIBRATION_COLOR2);
+ gdispGDrawLine(m->display, pp->x-15, pp->y+7, pp->x-15, pp->y+15, CALIBRATION_COLOR2);
+ gdispGDrawLine(m->display, pp->x-15, pp->y-15, pp->x-7, pp->y-15, CALIBRATION_COLOR2);
+ gdispGDrawLine(m->display, pp->x-15, pp->y-7, pp->x-15, pp->y-15, CALIBRATION_COLOR2);
+ gdispGDrawLine(m->display, pp->x+7, pp->y+15, pp->x+15, pp->y+15, CALIBRATION_COLOR2);
+ gdispGDrawLine(m->display, pp->x+15, pp->y+7, pp->x+15, pp->y+15, CALIBRATION_COLOR2);
+ gdispGDrawLine(m->display, pp->x+7, pp->y-15, pp->x+15, pp->y-15, CALIBRATION_COLOR2);
+ gdispGDrawLine(m->display, pp->x+15, pp->y-15, pp->x+15, pp->y-7, CALIBRATION_COLOR2);
}
- static inline void _tsClearCross(const MousePoint *pp) {
- gdispGFillArea(MouseConfig.display, pp->x - 15, pp->y - 15, 42, 42, Blue);
+ static inline void CalibrationCrossClear(GMouse *m, const point *pp) {
+ gdispGFillArea(m->display, pp->x - 15, pp->y - 15, 32, 32, CALIBRATION_BACKGROUND);
}
- static inline void _tsTransform(MouseReading *pt, const Calibration *c) {
+ static inline void CalibrationTransform(GMouseReading *pt, const GMouseCalibration *c) {
pt->x = (coord_t) (c->ax * pt->x + c->bx * pt->y + c->cx);
pt->y = (coord_t) (c->ay * pt->x + c->by * pt->y + c->cy);
}
- static inline void _tsDo3PointCalibration(const MousePoint *cross, const MousePoint *points, GDisplay *g, Calibration *c) {
+ static inline void CalibrationCalculate(GMouse *m, const point *cross, const point *points) {
float dx;
coord_t c0, c1, c2;
+ (void) m;
+
+ // Work on x values
+ c0 = cross[0].x;
+ c1 = cross[1].x;
+ c2 = cross[2].x;
#if GDISP_NEED_CONTROL
- /* Convert all cross points back to GDISP_ROTATE_0 convention
- * before calculating the calibration matrix.
- */
- switch(gdispGGetOrientation(g)) {
- case GDISP_ROTATE_90:
- c0 = cross[0].y;
- c1 = cross[1].y;
- c2 = cross[2].y;
- break;
- case GDISP_ROTATE_180:
- c0 = c1 = c2 = gdispGGetWidth(g) - 1;
- c0 -= cross[0].x;
- c1 -= cross[1].x;
- c2 -= cross[2].x;
- break;
- case GDISP_ROTATE_270:
- c0 = c1 = c2 = gdispGGetHeight(g) - 1;
- c0 -= cross[0].y;
- c1 -= cross[1].y;
- c2 -= cross[2].y;
- break;
- case GDISP_ROTATE_0:
- default:
- c0 = cross[0].x;
- c1 = cross[1].x;
- c2 = cross[2].x;
- break;
+ if (!(gmvmt(m)->d.flags & GMOUSE_VFLG_SELFROTATION)) {
+ /* Convert all cross points back to GDISP_ROTATE_0 convention
+ * before calculating the calibration matrix.
+ */
+ switch(gdispGGetOrientation(m->display)) {
+ case GDISP_ROTATE_90:
+ c0 = cross[0].y;
+ c1 = cross[1].y;
+ c2 = cross[2].y;
+ break;
+ case GDISP_ROTATE_180:
+ c0 = c1 = c2 = gdispGGetWidth(m->display) - 1;
+ c0 -= cross[0].x;
+ c1 -= cross[1].x;
+ c2 -= cross[2].x;
+ break;
+ case GDISP_ROTATE_270:
+ c0 = c1 = c2 = gdispGGetHeight(m->display) - 1;
+ c0 -= cross[0].y;
+ c1 -= cross[1].y;
+ c2 -= cross[2].y;
+ break;
+ default:
+ break;
+ }
}
- #else
- (void) g;
-
- c0 = cross[0].x;
- c1 = cross[1].x;
- c2 = cross[2].x;
#endif
/* Compute all the required determinants */
dx = (float)(points[0].x - points[2].x) * (float)(points[1].y - points[2].y)
- (float)(points[1].x - points[2].x) * (float)(points[0].y - points[2].y);
- c->ax = ((float)(c0 - c2) * (float)(points[1].y - points[2].y)
- - (float)(c1 - c2) * (float)(points[0].y - points[2].y)) / dx;
- c->bx = ((float)(c1 - c2) * (float)(points[0].x - points[2].x)
- - (float)(c0 - c2) * (float)(points[1].x - points[2].x)) / dx;
- c->cx = (c0 * ((float)points[1].x * (float)points[2].y - (float)points[2].x * (float)points[1].y)
- - c1 * ((float)points[0].x * (float)points[2].y - (float)points[2].x * (float)points[0].y)
- + c2 * ((float)points[0].x * (float)points[1].y - (float)points[1].x * (float)points[0].y)) / dx;
+ m->caldata.ax = ((float)(c0 - c2) * (float)(points[1].y - points[2].y)
+ - (float)(c1 - c2) * (float)(points[0].y - points[2].y)) / dx;
+ m->caldata.bx = ((float)(c1 - c2) * (float)(points[0].x - points[2].x)
+ - (float)(c0 - c2) * (float)(points[1].x - points[2].x)) / dx;
+ m->caldata.cx = (c0 * ((float)points[1].x * (float)points[2].y - (float)points[2].x * (float)points[1].y)
+ - c1 * ((float)points[0].x * (float)points[2].y - (float)points[2].x * (float)points[0].y)
+ + c2 * ((float)points[0].x * (float)points[1].y - (float)points[1].x * (float)points[0].y)) / dx;
+
+ // Work on y values
+ c0 = cross[0].y;
+ c1 = cross[1].y;
+ c2 = cross[2].y;
#if GDISP_NEED_CONTROL
- switch(gdispGGetOrientation(g)) {
- case GDISP_ROTATE_90:
- c0 = c1 = c2 = gdispGGetWidth(g) - 1;
- c0 -= cross[0].x;
- c1 -= cross[1].x;
- c2 -= cross[2].x;
- break;
- case GDISP_ROTATE_180:
- c0 = c1 = c2 = gdispGGetHeight(g) - 1;
- c0 -= cross[0].y;
- c1 -= cross[1].y;
- c2 -= cross[2].y;
- break;
- case GDISP_ROTATE_270:
- c0 = cross[0].x;
- c1 = cross[1].x;
- c2 = cross[2].x;
- break;
- case GDISP_ROTATE_0:
- default:
- c0 = cross[0].y;
- c1 = cross[1].y;
- c2 = cross[2].y;
- break;
+ if (!(gmvmt(m)->d.flags & GMOUSE_VFLG_SELFROTATION)) {
+ switch(gdispGGetOrientation(m->display)) {
+ case GDISP_ROTATE_90:
+ c0 = c1 = c2 = gdispGGetWidth(m->display) - 1;
+ c0 -= cross[0].x;
+ c1 -= cross[1].x;
+ c2 -= cross[2].x;
+ break;
+ case GDISP_ROTATE_180:
+ c0 = c1 = c2 = gdispGGetHeight(m->display) - 1;
+ c0 -= cross[0].y;
+ c1 -= cross[1].y;
+ c2 -= cross[2].y;
+ break;
+ case GDISP_ROTATE_270:
+ c0 = cross[0].x;
+ c1 = cross[1].x;
+ c2 = cross[2].x;
+ break;
+ default:
+ break;
+ }
}
- #else
- c0 = cross[0].y;
- c1 = cross[1].y;
- c2 = cross[2].y;
#endif
- c->ay = ((float)(c0 - c2) * (float)(points[1].y - points[2].y)
- - (float)(c1 - c2) * (float)(points[0].y - points[2].y)) / dx;
- c->by = ((float)(c1 - c2) * (float)(points[0].x - points[2].x)
- - (float)(c0 - c2) * (float)(points[1].x - points[2].x)) / dx;
- c->cy = (c0 * ((float)points[1].x * (float)points[2].y - (float)points[2].x * (float)points[1].y)
- - c1 * ((float)points[0].x * (float)points[2].y - (float)points[2].x * (float)points[0].y)
- + c2 * ((float)points[0].x * (float)points[1].y - (float)points[1].x * (float)points[0].y)) / dx;
+ m->caldata.ay = ((float)(c0 - c2) * (float)(points[1].y - points[2].y)
+ - (float)(c1 - c2) * (float)(points[0].y - points[2].y)) / dx;
+ m->caldata.by = ((float)(c1 - c2) * (float)(points[0].x - points[2].x)
+ - (float)(c0 - c2) * (float)(points[1].x - points[2].x)) / dx;
+ m->caldata.cy = (c0 * ((float)points[1].x * (float)points[2].y - (float)points[2].x * (float)points[1].y)
+ - c1 * ((float)points[0].x * (float)points[2].y - (float)points[2].x * (float)points[0].y)
+ + c2 * ((float)points[0].x * (float)points[1].y - (float)points[1].x * (float)points[0].y)) / dx;
}
#endif
-#if GINPUT_MOUSE_READ_CYCLES > 1
- static void get_raw_reading(MouseReading *pt) {
- int32_t x, y, z;
- unsigned i;
-
- x = y = z = 0;
- for(i = 0; i < GINPUT_MOUSE_READ_CYCLES; i++) {
- ginput_lld_mouse_get_reading(pt);
- x += pt->x;
- y += pt->y;
- z += pt->z;
+static void GetMouseReading(GMouse *m) {
+ GMouseReading r;
+
+ // Get the raw reading.
+ gmvmt(m)->get(m, &r);
+ m->flags &= ~GMOUSE_FLG_NEEDREAD;
+
+ // If touch then calculate button 0 from z
+ if ((gmvmt(m)->d.flags & GMOUSE_VFLG_TOUCH)) {
+ if (gmvmt(m)->z_min <= gmvmt(m)->z_max) {
+ if (r.z >= gmvmt(m)->z_touchon) r.buttons |= GINPUT_MOUSE_BTN_LEFT;
+ else if (r.z <= gmvmt(m)->z_touchoff) r.buttons &= ~GINPUT_MOUSE_BTN_LEFT;
+ else return; // bad transitional reading
+ } else {
+ if (r.z <= gmvmt(m)->z_touchon) r.buttons |= GINPUT_MOUSE_BTN_LEFT;
+ else if (r.z >= gmvmt(m)->z_touchoff) r.buttons &= ~GINPUT_MOUSE_BTN_LEFT;
+ else return; // bad transitional reading
}
+ }
+
+ // Double check up & down events if needed
+ if ((gmvmt(m)->d.flags & GMOUSE_VFLG_POORUPDOWN)) {
+ // Are we in a transition test
+ if ((m->flags & GMOUSE_FLG_INDELTA)) {
+ if (!((r.buttons ^ m->r.buttons) & GINPUT_MOUSE_BTN_LEFT)) {
+ // Transition failed
+ m->flags &= ~GMOUSE_FLG_INDELTA;
+ return;
+ }
+ // Transition succeeded
+ m->flags &= ~GMOUSE_FLG_INDELTA;
- /* Take the average of the readings */
- pt->x = x / GINPUT_MOUSE_READ_CYCLES;
- pt->y = y / GINPUT_MOUSE_READ_CYCLES;
- pt->z = z / GINPUT_MOUSE_READ_CYCLES;
+ // Should we start a transition test
+ } else if (((r.buttons ^ m->r.buttons) & GINPUT_MOUSE_BTN_LEFT)) {
+ m->flags |= GMOUSE_FLG_INDELTA;
+ return;
+ }
}
-#else
- #define get_raw_reading(pt) ginput_lld_mouse_get_reading(pt)
-#endif
-static void get_calibrated_reading(MouseReading *pt) {
- get_raw_reading(pt);
+ // If the mouse is up we may need to keep our previous position
+ if ((gmvmt(m)->d.flags & GMOUSE_VFLG_ONLY_DOWN) && !(r.buttons & GINPUT_MOUSE_BTN_LEFT)) {
+ r.x = m->r.x;
+ r.y = m->r.y;
- #if GINPUT_MOUSE_NEED_CALIBRATION
- _tsTransform(pt, &MouseConfig.caldata);
- #endif
+ } else {
+ coord_t w, h;
- _tsOrientClip(pt, MouseConfig.display, !(MouseConfig.flags & FLG_CAL_RAW));
-}
+ #if !GINPUT_TOUCH_NOCALIBRATE
+ // Do we need to calibrate the reading?
+ if ((m->flags & GMOUSE_FLG_CALIBRATE))
+ CalibrationTransform(&r, &m->caldata);
+ #endif
-static void MousePoll(void *param) {
- (void) param;
- GSourceListener *psl;
- GEventMouse *pe;
- unsigned meta;
- uint16_t upbtns, dnbtns;
- uint32_t cdiff;
- uint32_t mdiff;
-
- // Save the last mouse state
- MouseConfig.last_buttons = MouseConfig.t.buttons;
-
- // Get the new mouse reading
- get_calibrated_reading(&MouseConfig.t);
-
- // Calculate out new event meta value and handle CLICK and CXTCLICK
- dnbtns = MouseConfig.t.buttons & ~MouseConfig.last_buttons;
- upbtns = ~MouseConfig.t.buttons & MouseConfig.last_buttons;
- meta = GMETA_NONE;
-
- // As the touch moves up we need to return a point at the old position because some
- // controllers return garbage with the mouse up
- if ((upbtns & GINPUT_MOUSE_BTN_LEFT)) {
- MouseConfig.t.x = MouseConfig.movepos.x;
- MouseConfig.t.y = MouseConfig.movepos.y;
- }
+ // We can't clip or rotate if we don't have a display
+ if (m->display) {
+
+ // We now need display information
+ w = gdispGGetWidth(m->display);
+ h = gdispGGetHeight(m->display);
+
+ #if GDISP_NEED_CONTROL
+ // Do we need to rotate the reading to match the display
+ if (!(gmvmt(m)->d.flags & GMOUSE_VFLG_SELFROTATION)) {
+ coord_t t;
+
+ switch(gdispGGetOrientation(m->display)) {
+ case GDISP_ROTATE_0:
+ break;
+ case GDISP_ROTATE_90:
+ t = r.x;
+ r.x = w - 1 - r.y;
+ r.y = t;
+ break;
+ case GDISP_ROTATE_180:
+ r.x = w - 1 - r.x;
+ r.y = h - 1 - r.y;
+ break;
+ case GDISP_ROTATE_270:
+ t = r.y;
+ r.y = h - 1 - r.x;
+ r.x = t;
+ break;
+ default:
+ break;
+ }
+ }
+ #endif
- // Calculate the position difference from our movement reference (update the reference if out of range)
- mdiff = (MouseConfig.t.x - MouseConfig.movepos.x) * (MouseConfig.t.x - MouseConfig.movepos.x) +
- (MouseConfig.t.y - MouseConfig.movepos.y) * (MouseConfig.t.y - MouseConfig.movepos.y);
- if (mdiff > GINPUT_MOUSE_MAX_MOVE_JITTER * GINPUT_MOUSE_MAX_MOVE_JITTER) {
- MouseConfig.movepos.x = MouseConfig.t.x;
- MouseConfig.movepos.y = MouseConfig.t.y;
- }
-
- // Check if the click has moved outside the click area and if so cancel the click
- if ((MouseConfig.flags & FLG_CLICK_TIMER)) {
- cdiff = (MouseConfig.t.x - MouseConfig.clickpos.x) * (MouseConfig.t.x - MouseConfig.clickpos.x) +
- (MouseConfig.t.y - MouseConfig.clickpos.y) * (MouseConfig.t.y - MouseConfig.clickpos.y);
- if (cdiff > GINPUT_MOUSE_MAX_CLICK_JITTER * GINPUT_MOUSE_MAX_CLICK_JITTER)
- MouseConfig.flags &= ~FLG_CLICK_TIMER;
+ // Do we need to clip the reading to the display
+ if ((m->flags & GMOUSE_FLG_CLIP)) {
+ if (r.x < 0) r.x = 0;
+ else if (r.x >= w) r.x = w-1;
+ if (r.y < 0) r.y = 0;
+ else if (r.y >= h) r.y = h-1;
+ }
+ }
}
- // Mouse down
- if ((dnbtns & (GINPUT_MOUSE_BTN_LEFT|GINPUT_MOUSE_BTN_RIGHT))) {
- MouseConfig.clickpos.x = MouseConfig.t.x;
- MouseConfig.clickpos.y = MouseConfig.t.y;
- MouseConfig.clicktime = gfxSystemTicks();
- MouseConfig.flags |= FLG_CLICK_TIMER;
- if ((dnbtns & GINPUT_MOUSE_BTN_LEFT))
- meta |= GMETA_MOUSE_DOWN;
- }
+ {
+ const GMouseJitter *pj;
+ uint32_t diff;
+
+ // Are we in pen or finger mode
+ pj = (m->flags & GMOUSE_FLG_FINGERMODE) ? &gmvmt(m)->finger_jitter : &gmvmt(m)->pen_jitter;
+
+ // Is this just movement jitter
+ if (pj->move > 0) {
+ diff = (uint32_t)(r.x - m->r.x) * (uint32_t)(r.x - m->r.x) + (uint32_t)(r.y - m->r.y) * (uint32_t)(r.y - m->r.y);
+ if (diff > (uint32_t)pj->move * (uint32_t)pj->move) {
+ r.x = m->r.x;
+ r.y = m->r.y;
+ }
+ }
- // Mouse up
- if ((upbtns & (GINPUT_MOUSE_BTN_LEFT|GINPUT_MOUSE_BTN_RIGHT))) {
- if ((upbtns & GINPUT_MOUSE_BTN_LEFT))
- meta |= GMETA_MOUSE_UP;
- if ((MouseConfig.flags & FLG_CLICK_TIMER)) {
- if ((upbtns & GINPUT_MOUSE_BTN_LEFT)
- #if GINPUT_MOUSE_CLICK_TIME != TIME_INFINITE
- && gfxSystemTicks() - MouseConfig.clicktime < gfxMillisecondsToTicks(GINPUT_MOUSE_CLICK_TIME)
- #endif
- )
- meta |= GMETA_MOUSE_CLICK;
- else
- meta |= GMETA_MOUSE_CXTCLICK;
- MouseConfig.flags &= ~FLG_CLICK_TIMER;
+ // Check if the click has moved outside the click area and if so cancel the click
+ if (pj->click > 0 && (m->flags & GMOUSE_FLG_CLICK_TIMER)) {
+ diff = (uint32_t)(r.x - m->clickpos.x) * (uint32_t)(r.x - m->clickpos.x) + (uint32_t)(r.y - m->clickpos.y) * (uint32_t)(r.y - m->clickpos.y);
+ if (diff > (uint32_t)pj->click * (uint32_t)pj->click)
+ m->flags &= ~GMOUSE_FLG_CLICK_TIMER;
}
}
- // Send the event to the listeners that are interested.
- psl = 0;
- while ((psl = geventGetSourceListener((GSourceHandle)(&MouseConfig), psl))) {
- if (!(pe = (GEventMouse *)geventGetEventBuffer(psl))) {
- // This listener is missing - save the meta events that have happened
- psl->srcflags |= meta;
- continue;
+ {
+ GSourceListener *psl;
+ GEventMouse *pe;
+ unsigned meta;
+ uint16_t upbtns, dnbtns;
+
+ // Calculate out new event meta value and handle CLICK and CXTCLICK
+ dnbtns = r.buttons & ~m->r.buttons;
+ upbtns = ~r.buttons & m->r.buttons;
+ meta = GMETA_NONE;
+
+ // Mouse down
+ if ((dnbtns & (GINPUT_MOUSE_BTN_LEFT|GINPUT_MOUSE_BTN_RIGHT))) {
+ m->clickpos.x = r.x;
+ m->clickpos.y = r.y;
+ m->clicktime = gfxSystemTicks();
+ m->flags |= GMOUSE_FLG_CLICK_TIMER;
+ if ((dnbtns & GINPUT_MOUSE_BTN_LEFT))
+ meta |= GMETA_MOUSE_DOWN;
}
- // If we haven't really moved (and there are no meta events) don't bother sending the event
- if (mdiff <= GINPUT_MOUSE_MAX_MOVE_JITTER * GINPUT_MOUSE_MAX_MOVE_JITTER && !psl->srcflags
- && !meta && MouseConfig.last_buttons == MouseConfig.t.buttons && !(psl->listenflags & GLISTEN_MOUSENOFILTER))
- continue;
-
- // Send the event if we are listening for it
- if (((MouseConfig.t.buttons & GINPUT_MOUSE_BTN_LEFT) && (psl->listenflags & GLISTEN_MOUSEDOWNMOVES))
- || (!(MouseConfig.t.buttons & GINPUT_MOUSE_BTN_LEFT) && (psl->listenflags & GLISTEN_MOUSEUPMOVES))
- || (meta && (psl->listenflags & GLISTEN_MOUSEMETA))) {
- pe->type = GINPUT_MOUSE_EVENT_TYPE;
- pe->instance = 0;
- pe->x = MouseConfig.t.x;
- pe->y = MouseConfig.t.y;
- pe->z = MouseConfig.t.z;
- pe->current_buttons = MouseConfig.t.buttons;
- pe->last_buttons = MouseConfig.last_buttons;
- pe->meta = meta;
- if (psl->srcflags) {
- pe->current_buttons |= GINPUT_MISSED_MOUSE_EVENT;
- pe->meta |= psl->srcflags;
- psl->srcflags = 0;
+ // Mouse up
+ if ((upbtns & (GINPUT_MOUSE_BTN_LEFT|GINPUT_MOUSE_BTN_RIGHT))) {
+ if ((upbtns & GINPUT_MOUSE_BTN_LEFT))
+ meta |= GMETA_MOUSE_UP;
+ if ((m->flags & GMOUSE_FLG_CLICK_TIMER)) {
+ if ((upbtns & GINPUT_MOUSE_BTN_LEFT)
+ #if GINPUT_TOUCH_CLICK_TIME != TIME_INFINITE
+ && gfxSystemTicks() - m->clicktime < gfxMillisecondsToTicks(GINPUT_TOUCH_CLICK_TIME)
+ #endif
+ )
+ meta |= GMETA_MOUSE_CLICK;
+ else
+ meta |= GMETA_MOUSE_CXTCLICK;
+ m->flags &= ~GMOUSE_FLG_CLICK_TIMER;
+ }
+ }
+
+ // Send the event to the listeners that are interested.
+ psl = 0;
+ while ((psl = geventGetSourceListener((GSourceHandle)m, psl))) {
+ if (!(pe = (GEventMouse *)geventGetEventBuffer(psl))) {
+ // This listener is missing - save the meta events that have happened
+ psl->srcflags |= meta;
+ continue;
+ }
+
+ // If we haven't really moved (and there are no meta events) don't bother sending the event
+ if (!meta && !psl->srcflags && !(psl->listenflags & GLISTEN_MOUSENOFILTER)
+ && r.x == m->r.x && r.y == m->r.y && r.buttons == m->r.buttons)
+ continue;
+
+ // Send the event if we are listening for it
+ if (((r.buttons & GINPUT_MOUSE_BTN_LEFT) && (psl->listenflags & GLISTEN_MOUSEDOWNMOVES))
+ || (!(r.buttons & GINPUT_MOUSE_BTN_LEFT) && (psl->listenflags & GLISTEN_MOUSEUPMOVES))
+ || (meta && (psl->listenflags & GLISTEN_MOUSEMETA))) {
+ pe->type = (gmvmt(m)->d.flags & GMOUSE_VFLG_TOUCH) ? GEVENT_TOUCH : GEVENT_MOUSE;
+ pe->x = r.x;
+ pe->y = r.y;
+ pe->z = r.z;
+ pe->current_buttons = r.buttons;
+ pe->last_buttons = m->r.buttons;
+ pe->meta = meta;
+ if (psl->srcflags) {
+ pe->current_buttons |= GINPUT_MISSED_MOUSE_EVENT;
+ pe->meta |= psl->srcflags;
+ psl->srcflags = 0;
+ }
+ pe->display = m->display;
+ geventSendEvent(psl);
}
- pe->display = MouseConfig.display;
- geventSendEvent(psl);
}
}
+
+ // Finally save the results
+ m->r.x = r.x;
+ m->r.y = r.y;
+ m->r.z = r.z;
+ m->r.buttons = r.buttons;
+}
+
+static void MousePoll(void *param) {
+ GMouse * m;
+ (void) param;
+
+ for(m = (GMouse *)gdriverGetNext(GDRIVER_TYPE_MOUSE, 0); m; m = (GMouse *)gdriverGetNext(GDRIVER_TYPE_MOUSE, (GDriver *)m)) {
+ if (!(gmvmt(m)->d.flags & GMOUSE_VFLG_NOPOLL) || (m->flags & GMOUSE_FLG_NEEDREAD))
+ GetMouseReading(m);
+ }
+}
+
+void _gmouseInit(void) {
+ // GINPUT_MOUSE_DRIVER_LIST is defined - create each driver instance
+ #if defined(GINPUT_MOUSE_DRIVER_LIST)
+ {
+ int i;
+
+ extern GDriverVMTList GINPUT_MOUSE_DRIVER_LIST;
+ static const struct GDriverVMT const * dclist[] = {GINPUT_MOUSE_DRIVER_LIST};
+ static const unsigned dnlist[] = {GDISP_CONTROLLER_DISPLAYS};
+
+ for(i = 0; i < sizeof(dclist)/sizeof(dclist[0]); i++)
+ gdriverRegister(dclist[i]);
+ }
+
+ // One and only one display
+ #else
+ {
+ extern GDriverVMTList GINPUTMOUSEVMT_OnlyOne;
+
+ gdriverRegister(GINPUTMOUSEVMT_OnlyOne);
+ }
+ #endif
+}
+
+void _gmouseDeinit(void) {
}
GSourceHandle ginputGetMouse(uint16_t instance) {
+ GMouse *m;
#if GINPUT_MOUSE_NEED_CALIBRATION
- Calibration *pc;
+ GCalibration *pc;
#endif
- // We only support a single mouse instance currently
- // Instance 9999 is the same as instance 0 except that it installs
- // a special "raw" calibration if there isn't one we can load.
- if (instance && instance != 9999)
- return 0;
+ if (!(m = (GMouse *)gdriverGetInstance(GDRIVER_TYPE_MOUSE, instance)))
+ return 0;
// Make sure we have a valid mouse display
- if (!MouseConfig.display)
- MouseConfig.display = GDISP;
+ if (!m->display)
+ m->display = GDISP;
// Do we need to initialise the mouse subsystem?
- if (!(MouseConfig.flags & FLG_INIT_DONE)) {
+ if (!(m->flags & FLG_INIT_DONE)) {
ginput_lld_mouse_init();
#if GINPUT_MOUSE_NEED_CALIBRATION
#if GINPUT_MOUSE_LLD_CALIBRATION_LOADSAVE
- if (!MouseConfig.fnloadcal) {
- MouseConfig.fnloadcal = ginput_lld_mouse_calibration_load;
- MouseConfig.flags &= ~FLG_CAL_FREE;
+ if (!m->fnloadcal) {
+ m->fnloadcal = ginput_lld_mouse_calibration_load;
+ m->flags &= ~FLG_CAL_FREE;
}
- if (!MouseConfig.fnsavecal)
- MouseConfig.fnsavecal = ginput_lld_mouse_calibration_save;
+ if (!m->fnsavecal)
+ m->fnsavecal = ginput_lld_mouse_calibration_save;
#endif
- if (MouseConfig.fnloadcal && (pc = (Calibration *)MouseConfig.fnloadcal(instance))) {
- memcpy(&MouseConfig.caldata, pc, sizeof(MouseConfig.caldata));
- MouseConfig.flags |= (FLG_CAL_OK|FLG_CAL_SAVED);
- if ((MouseConfig.flags & FLG_CAL_FREE))
+ if (m->fnloadcal && (pc = (Calibration *)m->fnloadcal(instance))) {
+ memcpy(&m->caldata, pc, sizeof(m->caldata));
+ m->flags |= (FLG_CAL_OK|FLG_CAL_SAVED);
+ if ((m->flags & FLG_CAL_FREE))
gfxFree((void *)pc);
} else if (instance == 9999) {
- _tsSetIdentity(&MouseConfig.caldata);
- MouseConfig.flags |= (FLG_CAL_OK|FLG_CAL_SAVED|FLG_CAL_RAW);
+ CalibrationSetIdentity(&m->caldata);
+ m->flags |= (FLG_CAL_OK|FLG_CAL_SAVED|FLG_CAL_RAW);
} else
ginputCalibrateMouse(instance);
#endif
// Get the first reading
- MouseConfig.last_buttons = 0;
- get_calibrated_reading(&MouseConfig.t);
+ m->last_buttons = 0;
+ get_calibrated_reading(&m->t);
// Mark init as done and start the Poll timer
- MouseConfig.flags |= FLG_INIT_DONE;
+ m->flags |= FLG_INIT_DONE;
gtimerStart(&MouseTimer, MousePoll, 0, TRUE, GINPUT_MOUSE_POLL_PERIOD);
}
// Return our structure as the handle
- return (GSourceHandle)&MouseConfig;
+ return (GSourceHandle)m;
}
void ginputSetMouseDisplay(uint16_t instance, GDisplay *g) {
if (instance)
return;
- MouseConfig.display = g ? g : GDISP;
+ m->display = g ? g : GDISP;
}
GDisplay *ginputGetMouseDisplay(uint16_t instance) {
if (instance)
return 0;
- return MouseConfig.display;
+ return m->display;
}
bool_t ginputGetMouseStatus(uint16_t instance, GEventMouse *pe) {
@@ -461,16 +477,15 @@ bool_t ginputGetMouseStatus(uint16_t instance, GEventMouse *pe) {
// so we add a sleep here to prevent 100% polled applications from locking up.
gfxSleepMilliseconds(1);
- if (instance || (MouseConfig.flags & (FLG_INIT_DONE|FLG_IN_CAL)) != FLG_INIT_DONE)
+ if (instance || (m->flags & (FLG_INIT_DONE|FLG_IN_CAL)) != FLG_INIT_DONE)
return FALSE;
pe->type = GINPUT_MOUSE_EVENT_TYPE;
- pe->instance = instance;
- pe->x = MouseConfig.t.x;
- pe->y = MouseConfig.t.y;
- pe->z = MouseConfig.t.z;
- pe->current_buttons = MouseConfig.t.buttons;
- pe->last_buttons = MouseConfig.last_buttons;
+ pe->x = m->t.x;
+ pe->y = m->t.y;
+ pe->z = m->t.z;
+ pe->current_buttons = m->t.buttons;
+ pe->last_buttons = m->last_buttons;
if (pe->current_buttons & ~pe->last_buttons & GINPUT_MOUSE_BTN_LEFT)
pe->meta = GMETA_MOUSE_DOWN;
else if (~pe->current_buttons & pe->last_buttons & GINPUT_MOUSE_BTN_LEFT)
@@ -481,9 +496,10 @@ bool_t ginputGetMouseStatus(uint16_t instance, GEventMouse *pe) {
}
bool_t ginputCalibrateMouse(uint16_t instance) {
- #if !GINPUT_MOUSE_NEED_CALIBRATION
+ #if GINPUT_TOUCH_NOCALIBRATE
+
(void) instance;
-
+
return FALSE;
#else
@@ -500,7 +516,7 @@ bool_t ginputCalibrateMouse(uint16_t instance) {
{(width - (width / 4)) , (height - (height / 4))},
{(width / 2), (height / 2)}}; /* Check point */
#endif
- MousePoint points[GINPUT_MOUSE_CALIBRATION_POINTS];
+ MousePoint points[4];
const MousePoint *pc;
MousePoint *pt;
int32_t px, py;
@@ -532,7 +548,7 @@ bool_t ginputCalibrateMouse(uint16_t instance) {
gdispGFillStringBox(MouseConfig.display, 0, 5, width, 30, GINPUT_MOUSE_CALIBRATION_TEXT, font1, White, Blue, justifyCenter);
for(i = 0, pt = points, pc = cross; i < GINPUT_MOUSE_CALIBRATION_POINTS; i++, pt++, pc++) {
- _tsDrawCross(pc);
+ CalibrationCrossDraw(pc);
do {
@@ -555,7 +571,7 @@ bool_t ginputCalibrateMouse(uint16_t instance) {
pt->x = px / j;
pt->y = py / j;
- _tsClearCross(pc);
+ CalibrationCrossClear(pc);
if (i >= 1 && pt->x == (pt-1)->x && pt->y == (pt-1)->y) {
gdispGFillStringBox(MouseConfig.display, 0, 35, width, 40, GINPUT_MOUSE_CALIBRATION_SAME_TEXT, font2, Red, Yellow, justifyCenter);
@@ -566,7 +582,7 @@ bool_t ginputCalibrateMouse(uint16_t instance) {
}
/* Apply 3 point calibration algorithm */
- _tsDo3PointCalibration(cross, points, MouseConfig.display, &MouseConfig.caldata);
+ CalibrationCalculate(&MouseConfig, cross, points);
/* Verification of correctness of calibration (optional) :
* See if the 4th point (Middle of the screen) coincides with the calibrated
@@ -577,7 +593,7 @@ bool_t ginputCalibrateMouse(uint16_t instance) {
/* Transform the co-ordinates */
MouseConfig.t.x = points[3].x;
MouseConfig.t.y = points[3].y;
- _tsTransform(&MouseConfig.t, &MouseConfig.caldata);
+ CalibrationTransform(&MouseConfig.t, &MouseConfig.caldata);
_tsOrientClip(&MouseConfig.t, MouseConfig.display, FALSE);
/* Calculate the delta */
@@ -601,7 +617,7 @@ bool_t ginputCalibrateMouse(uint16_t instance) {
MouseConfig.flags &= ~FLG_IN_CAL;
if ((MouseConfig.flags & FLG_INIT_DONE))
gtimerStart(&MouseTimer, MousePoll, 0, TRUE, GINPUT_MOUSE_POLL_PERIOD);
-
+
// Save the calibration data (if possible)
if (MouseConfig.fnsavecal) {
MouseConfig.fnsavecal(instance, (const uint8_t *)&MouseConfig.caldata, sizeof(MouseConfig.caldata));
@@ -614,7 +630,7 @@ bool_t ginputCalibrateMouse(uint16_t instance) {
#else
gdispGClear(MouseConfig.display, Black);
#endif
-
+
return TRUE;
#endif
}
@@ -666,12 +682,14 @@ bool_t ginputRequireMouseCalibrationStorage(uint16_t instance) {
}
/* Wake up the mouse driver from an interrupt service routine (there may be new readings available) */
-void ginputMouseWakeup(void) {
+void ginputMouseWakeup(GMouse *m) {
+ m->flags |= GMOUSE_FLG_NEEDREAD;
gtimerJab(&MouseTimer);
}
/* Wake up the mouse driver from an interrupt service routine (there may be new readings available) */
-void ginputMouseWakeupI(void) {
+void ginputMouseWakeupI(GMouse *m) {
+ m->flags |= GMOUSE_FLG_NEEDREAD;
gtimerJabI(&MouseTimer);
}
diff --git a/src/ginput/ginput_mouse.h b/src/ginput/ginput_mouse.h
index 61ad35e0..6cae66d1 100644
--- a/src/ginput/ginput_mouse.h
+++ b/src/ginput/ginput_mouse.h
@@ -33,7 +33,6 @@
/* This type definition is also used by touch */
typedef struct GEventMouse_t {
GEventType type; // The type of this event (GEVENT_MOUSE or GEVENT_TOUCH)
- uint16_t instance; // The mouse/touch instance
coord_t x, y, z; // The position of the mouse.
// - For touch devices, Z is the current pressure if supported (otherwise 0)
// - For mice, Z is the 3rd dimension if supported (otherwise 0)
diff --git a/src/ginput/sys_options.h b/src/ginput/sys_options.h
index c606262b..7ccc7b78 100644
--- a/src/ginput/sys_options.h
+++ b/src/ginput/sys_options.h
@@ -73,40 +73,41 @@
* @{
*/
/**
- * @brief Use a custom board definition for the mouse/touch driver even if a board definition exists.
+ * @brief Turn off touch mouse support.
* @details Defaults to FALSE
- * @details If TRUE, add ginput_lld_mouse_board.h to your project directory and customise it.
- * @note Not all GINPUT mouse/touch low level drivers use board definition files.
+ * @note Touch device handling requires a lot of code. If your mouse doesn't require it
+ * this can be turned off to save a lot of space.
*/
- #ifndef GINPUT_MOUSE_USE_CUSTOM_BOARD
- #define GINPUT_MOUSE_USE_CUSTOM_BOARD FALSE
+ #ifndef GINPUT_TOUCH_NOTOUCH
+ #define GINPUT_TOUCH_NOTOUCH FALSE
#endif
/**
- * @brief Use a custom board definition for the keyboard driver even if a board definition exists.
+ * @brief Turn off calibration support.
* @details Defaults to FALSE
- * @details If TRUE, add ginput_lld_keyboard_board.h to your project directory and customise it.
- * @note Not all GINPUT keyboard low level drivers use board definition files.
+ * @note Calibration requires a lot of code. If your mouse doesn't require it
+ * this can be turned off to save a lot of space.
*/
- #ifndef GINPUT_KEYBOARD_USE_CUSTOM_BOARD
- #define GINPUT_KEYBOARD_USE_CUSTOM_BOARD FALSE
+ #ifndef GINPUT_TOUCH_NOCALIBRATE
+ #define GINPUT_TOUCH_NOCALIBRATE FALSE
#endif
/**
- * @brief Use a custom board definition for the toggle driver even if a board definition exists.
- * @details Defaults to FALSE
- * @details If TRUE, add ginput_lld_toggle_board.h to your project directory and customise it.
- * @note Not all GINPUT toggle low level drivers use board definition files.
+ * @brief Milliseconds between mouse polls.
+ * @details Defaults to 25 millseconds
+ * @note How often mice should be polled. More often leads to smoother mouse movement
+ * but increases CPU usage. If no mouse drivers need polling the poll is not
+ * started.
*/
- #ifndef GINPUT_TOGGLE_USE_CUSTOM_BOARD
- #define GINPUT_TOGGLE_USE_CUSTOM_BOARD FALSE
+ #ifndef GINPUT_MOUSE_POLL_PERIOD
+ #define GINPUT_MOUSE_POLL_PERIOD 25
#endif
+
/**
- * @brief Use a custom board definition for the dial driver even if a board definition exists.
- * @details Defaults to FALSE
- * @details If TRUE, add ginput_lld_dial_board.h to your project directory and customise it.
- * @note Not all GINPUT dial low level drivers use board definition files.
+ * @brief Milliseconds separating a CLICK from a CXTCLICK.
+ * @details Defaults to 700 millseconds
+ * @note How long it takes for a click to turn into a CXTCLICK on a touch device.
*/
- #ifndef GINPUT_DIAL_USE_CUSTOM_BOARD
- #define GINPUT_DIAL_USE_CUSTOM_BOARD FALSE
+ #ifndef GINPUT_TOUCH_CLICK_TIME
+ #define GINPUT_TOUCH_CLICK_TIME 700
#endif
/** @} */