aboutsummaryrefslogtreecommitdiffstats
path: root/include/ginput.h
blob: de2c617bd337b2a9cc1f4838fa88bcc785d539dd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
/*
    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 */
/** @} */