/* ChibiOS/GFX - Copyright (C) 2012 Joel Bodenmann aka Tectu 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 . */ /** * @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 */ /** @} */