ugfx/include/ginput.h

340 lines
13 KiB
C

/*
ChibiOS/GFX - Copyright (C) 2012
Joel Bodenmann aka Tectu <joel@unormal.org>
This file is part of ChibiOS/GFX.
ChibiOS/GFX is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS/GFX is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file ginput.h
* @brief GINPUT GFX User Input subsystem header file.
*
* @addtogroup GINPUT
* @{
*/
#ifndef _GINPUT_H
#define _GINPUT_H
#ifndef GFX_USE_GINPUT
#define GFX_USE_GINPUT FALSE
#endif
#if GFX_USE_GINPUT || defined(__DOXYGEN__)
/**
* @name GINPUT more complex functionality to be compiled
* @{
*/
/**
* @brief Should mouse functions be included.
* @details Defaults to FALSE
*/
#ifndef GINPUT_NEED_MOUSE
#define GINPUT_NEED_MOUSE FALSE
#endif
/**
* @brief Should touch functions be included.
* @details Defaults to FALSE
*/
#ifndef GINPUT_NEED_TOUCH
#define GINPUT_NEED_TOUCH FALSE
#endif
/**
* @brief Should keyboard functions be included.
* @details Defaults to FALSE
*/
#ifndef GINPUT_NEED_KEYBOARD
#define GINPUT_NEED_KEYBOARD FALSE
#endif
/**
* @brief Should hardware toggle/switch/button (pio) functions be included.
* @details Defaults to FALSE
*/
#ifndef GINPUT_NEED_TOGGLE
#define GINPUT_NEED_TOGGLE FALSE
#endif
/**
* @brief Should analog dial functions be included.
* @details Defaults to FALSE
*/
#ifndef GINPUT_NEED_DIAL
#define GINPUT_NEED_DIAL FALSE
#endif
/** @} */
/*===========================================================================*/
/* Low Level Driver details and error checks. */
/*===========================================================================*/
#ifndef GFX_USE_GDISP
#define GFX_USE_GDISP FALSE
#endif
#if GINPUT_NEED_TOUCH || !GFX_USE_GDISP
#error "GINPUT: GFX_USE_GDISP must be defined for touch functions"
#endif
#if GFX_USE_GDISP
#include "gdisp.h"
#else
// We require some basic type definitions normally kept in gdisp.h
typedef int16_t coord_t;
#endif
#ifndef GFX_USE_GEVENT
#define GFX_USE_GEVENT TRUE
#include "gevent.h"
#elif !GFX_USE_GEVENT
#error "GINPUT: GFX_USE_GEVENT must be defined"
#endif
#ifndef GFX_USE_GTIMER
#define GFX_USE_GTIMER TRUE
#include "gtimer.h"
#elif !GFX_USE_GTIMER
#error "GINPUT: GFX_USE_GTIMER must be defined"
#endif
/*===========================================================================*/
/* Type definitions */
/*===========================================================================*/
// Event types for various ginput sources
#define GEVENT_MOUSE (GEVENT_GINPUT_FIRST+0)
#define GEVENT_TOUCH (GEVENT_GINPUT_FIRST+1)
#define GEVENT_KEYBOARD (GEVENT_GINPUT_FIRST+2)
#define GEVENT_TOGGLE (GEVENT_GINPUT_FIRST+3)
#define GEVENT_DIAL (GEVENT_GINPUT_FIRST+4)
#if GINPUT_NEED_MOUSE || GINPUT_NEED_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)
uint16_t current_buttons; // A bit is set if the button is down.
// - For touch only bit 0 is relevant
// - For mice the order of the buttons is (from 0 to n) left, right, middle, any other buttons
// - Bit 15 being set indicates that an important mouse event has been missed.
#define GINPUT_TOUCH_PRESSED 0x0001
#define GINPUT_MOUSE_BTN_LEFT 0x0001
#define GINPUT_MOUSE_BTN_RIGHT 0x0002
#define GINPUT_MOUSE_BTN_MIDDLE 0x0004
#define GINPUT_MOUSE_BTN_4 0x0008
#define GINPUT_MISSED_MOUSE_EVENT 0x8000
uint16_t last_buttons; // The value of current_buttons on the last event
enum GMouseMeta_e {
GMETA_NONE, // There is no meta event currently happenning
GMETA_DOWN, GMETA_UP, // Button 0 has just gone up or down
GMETA_CLICK, // Button 0 has just gone through a short down - up cycle
GMETA_CXTCLICK // For mice - The right button has just been depressed
// For touch - a long press has just occurred
} meta;
} GEventMouse, GEventTouch;
// Mouse/Touch Listen Flags - passed to geventAddSourceToListener()
#define GLISTEN_MOUSEMETA 0x0001 // Create events for meta events such as CLICK and CXTCLICK
#define GLISTEN_MOUSEDOWNMOVES 0x0002 // Creates mouse move events when the primary mouse button is down (touch is on the surface)
#define GLISTEN_MOUSEUPMOVES 0x0004 // Creates mouse move events when the primary mouse button is up (touch is off the surface - if the hardware allows).
#define GLISTEN_TOUCHMETA 0x0001 // Ditto for touch
#define GLISTEN_TOUCHDOWNMOVES 0x0002
#define GLISTEN_TOUCHUPMOVES 0x0004
#endif
#if GINPUT_NEED_KEYBOARD
typedef struct GEventKeyboard_t {
GEventType type; // The type of this event (GEVENT_KEYBOARD)
uint16_t instance; // The keyboard instance
char c; // The Ascii code for the current key press.
// The only possible values are 0(NUL), 8(BS), 9(TAB), 13(CR), 27(ESC), 32(SPACE) to 126(~), 127(DEL)
// 0 indicates an extended only key.
uint16_t code; // An extended keyboard code. Codes less than 128 match their ascii equivelent.
#define GKEY_NULL 0
#define GKEY_BACKSPACE 8
#define GKEY_TAB 9
#define GKEY_CR 13
#define GKEY_ESC 27
#define GKEY_SPACE 32
#define GKEY_DEL 127
#define GKEY_UP 0x0101
#define GKEY_DOWN 0x0102
#define GKEY_LEFT 0x0103
#define GKEY_RIGHT 0x0104
#define GKEY_HOME 0x0105
#define GKEY_END 0x0106
#define GKEY_PAGEUP 0x0107
#define GKEY_PAGEDOWN 0x0108
#define GKEY_INSERT 0x0109
#define GKEY_DELETE 0x010A
#define GKEY_SHIFT 0x0201
#define GKEY_CNTRL 0x0202
#define GKEY_ALT 0x0203
#define GKEY_WINKEY 0x0204
#define GKEY_RCLKEY 0x0205
#define GKEY_FNKEY 0x0206
#define GKEY_FN1 0x0301
#define GKEY_FN2 0x0302
#define GKEY_FN3 0x0303
#define GKEY_FN4 0x0304
#define GKEY_FN5 0x0305
#define GKEY_FN6 0x0306
#define GKEY_FN7 0x0307
#define GKEY_FN8 0x0308
#define GKEY_FN9 0x0309
#define GKEY_FN10 0x030A
#define GKEY_FN11 0x030B
#define GKEY_FN12 0x030C
uint16_t current_buttons; // A bit is set to indicate various meta status.
#define GMETA_KEYDN 0x0001
#define GMETA_SHIFT 0x0002
#define GMETA_CNTRL 0x0004
#define GMETA_ALT 0x0008
#define GMETA_WINKEY 0x0010
#define GMETA_RCLKKEY 0x0020
#define GMETA_FNKEY 0x0040
#define GMETA_MISSED_EVENT 0x8000
uint16_t last_buttons; // The value of current_buttons on the last event
} GEventKeyboard;
// Keyboard Listen Flags - passed to geventAddSourceToListener()
#define GLISTEN_KEYREPEATS 0x0001 // Return key repeats (where the key is held down to get a repeat character)
#define GLISTEN_KEYCODES 0x0002 // Return all key presses including extended code key presses (not just ascii codes)
#define GLISTEN_KEYALL 0x0004 // Return keyup's, keydown's and everything in between (but not repeats unless GLISTEN_KEYREPEATS is set).
#define GLISTEN_KEYSINGLE 0x8000 // Return only when one particular extended code key is pressed or released. The particular extended code is OR'd into this value
// eg. (GLISTEN_KEYSINGLE | GKEY_CR)
// No other flags may be set with this flag.
#endif
#if GINPUT_NEED_TOGGLE
typedef struct GEventToggle_t {
GEventType type; // The type of this event (GEVENT_TOGGLE)
uint16_t instance; // The toggle instance
BOOL on; // True if the toggle/button is on
} GEventToggle;
#endif
#if GINPUT_NEED_DIAL
typedef struct GEventDial_t {
GEventType type; // The type of this event (GEVENT_DIAL)
uint16_t instance; // The dial instance
uint16_t value; // The dial value
} GEventDial;
#endif
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
/* How to use...
1. Get source handles for all the inputs you are interested in.
- Attempting to get a handle for one instance of an input more than once will return the same handle
2. Create a listener
3. Assign inputs to your listener.
- Inputs can be assigned or released from a listener at any time.
- An input can be assigned to more than one listener.
4. Loop on getting listener events
5. When complete destroy the listener
*/
#if GINPUT_NEED_MOUSE
/* Mouse Functions */
GSourceHandle ginputGetMouse(uint16_t instance); // Instance = 0 to n-1
/* Get the current mouse position and button status.
* Unlike a listener event, this status cannot record meta events such as "CLICK"
* Returns FALSE on error (eg invalid instance)
*/
BOOL ginputGetMouseStatus(uint16_t instance, GEventMouse *pmouse);
#endif
#if GINPUT_NEED_TOUCH
/* Touch Functions */
GSourceHandle ginputGetTouch(uint16_t instance); // Instance = 0 to n-1
/* Get the current touch position and button status.
* Unlike a listener event, this status cannot record meta events such as "CLICK"
* Returns FALSE on error (eg invalid instance)
*/
BOOL ginputGetTouchStatus(uint16_t instance, GEventTouch *ptouch);
/* Run a touch calibration.
* Returns FALSE if the driver doesn't support it or if the handle is invalid.
*/
BOOL ginputCalibrateTouch(uint16_t instance);
/* Set the routines to save and fetch calibration data.
* This function should be called before first calling ginputGetTouch() for a particular instance
* as the gdispGetTouch() routine may attempt to fetch calibration data and perform a startup calibration if there is no way to get it.
* If this is called after gdispGetTouch() has been called and the driver requires calibration storage, it will immediately save the data is has already obtained.
* The 'requireFree' parameter indicates if the fetch buffer must be free()'d to deallocate the buffer provided by the Fetch routine.
*/
typedef void (*)(uint16_t instance, const uint8_t *calbuf, size_t sz) GTouchCalibrationSaveRoutine; // Save calibration data
typedef const char * (*)(uint16_t instance) GTouchCalibrationFetchRoutine; // Fetch calibration data (returns NULL if not data saved)
void ginputSetTouchCalibrationRoutines(uint16_t instance, GTouchCalibrationSaveRoutine fnsave, GTouchCalibrationFetchRoutine fnfetch, BOOL requireFree);
/* Test if a particular touch instance requires routines to save its calibration data. */
BOOL ginputRequireTouchCalibrationStorage(uint16_t instance);
#endif
#if GINPUT_NEED_KEYBOARD
/* Keyboard Functions */
GSourceHandle ginputGetKeyboard(uint16_t instance); // Instance = 0 to n-1
/* Get the current keyboard button status.
* Returns FALSE on error (eg invalid instance)
*/
BOOL ginputGetKeyboardStatus(uint16_t instance, GEventKeyboard *pkeyboard);
#endif
#if GINPUT_NEED_TOGGLE
/* Hardware Toggle/Switch/Button Functions */
GSourceHandle ginputGetToggle(uint16_t instance); // Instance = 0 to n-1
void ginputInvertToggle(uint16_t instance, BOOL invert); // If invert is true, invert the on/off sense for the toggle
/* Get the current toggle status.
* Returns FALSE on error (eg invalid instance)
*/
BOOL ginputGetToggleStatus(uint16_t instance, GEventToggle *ptoggle);
#endif
#if GINPUT_NEED_DIAL
/* Dial Functions */
GSourceHandle ginputGetDial(uint16_t instance); // Instance = 0 to n-1
void ginputResetDialRange(uint16_t instance); // Reset the maximum value back to the hardware default.
uint16_t ginputGetDialRange(uint16_t instance); // Get the maximum value. The readings are scaled to be 0...max-1. 0 means over the full uint16_t range.
void ginputSetDialRange(uint16_t instance, uint16_t max); // Set the maximum value.
void ginputSetDialSensitivity(uint16_t instance, uint16_t diff); // Set the level change required before a dial event is generated.
// - This is done after range scaling
/* Get the current keyboard button status.
* Returns FALSE on error (eg invalid instance)
*/
BOOL ginputGetDialStatus(uint16_t instance, GEventDial *pdial);
#endif
#ifdef __cplusplus
}
#endif
#endif /* GFX_USE_GINPUT */
#endif /* _GINPUT_H */
/** @} */