1 /*	Public domain	*/
2 
3 #ifndef _AGAR_GUI_KEYBOARD_H_
4 #define _AGAR_GUI_KEYBOARD_H_
5 #include <agar/gui/input_device.h>
6 #include <agar/gui/begin.h>
7 
8 typedef enum ag_keyboard_action {
9 	AG_KEY_PRESSED  = 1,
10 	AG_KEY_RELEASED = 0
11 } AG_KeyboardAction;
12 
13 typedef enum ag_key_sym {
14 	AG_KEY_NONE		= 0x0000,	/* Start of ASCII range */
15 	AG_KEY_ASCII_START	= 0x0000,
16 /*	AG_KEY_ASCII_SOH	= 0x0001, */
17 /*	AG_KEY_ASCII_STX	= 0x0002, */
18 /*	AG_KEY_ASCII_ETX	= 0x0003, */
19 /*	AG_KEY_ASCII_EOT	= 0x0004, */
20 /*	AG_KEY_ASCII_ENQ	= 0x0005, */
21 /*	AG_KEY_ASCII_ACK	= 0x0006, */
22 /*	AG_KEY_ASCII_BEL	= 0x0007, */
23 	AG_KEY_BACKSPACE	= 0x0008,
24 	AG_KEY_TAB		= 0x0009,
25 /*	AG_KEY_ASCII_NEWLINE	= 0x000a, */
26 /*	AG_KEY_ASCII_VT		= 0x000b, */
27 	AG_KEY_CLEAR		= 0x000c,
28 	AG_KEY_RETURN		= 0x000d,
29 /*	AG_KEY_ASCII_SO		= 0x000e, */
30 /*	AG_KEY_ASCII_SI		= 0x000f, */
31 /*	AG_KEY_ASCII_DLE	= 0x0010, */
32 /*	AG_KEY_ASCII_DC1	= 0x0011, */
33 /*	AG_KEY_ASCII_DC2	= 0x0012, */
34 	AG_KEY_PAUSE		= 0x0013,
35 /*	AG_KEY_ASCII_DC4	= 0x0014, */
36 /*	AG_KEY_ASCII_NAK	= 0x0015, */
37 /*	AG_KEY_ASCII_SYN	= 0x0016, */
38 /*	AG_KEY_ASCII_ETB	= 0x0017, */
39 /*	AG_KEY_ASCII_CAN	= 0x0018, */
40 /*	AG_KEY_ASCII_EM		= 0x0019, */
41 /*	AG_KEY_ASCII_SUB	= 0x001a, */
42 	AG_KEY_ESCAPE		= 0x001b,
43 /*	AG_KEY_ASCII_FS		= 0x001c, */
44 /*	AG_KEY_ASCII_GS		= 0x001d, */
45 /*	AG_KEY_ASCII_RS		= 0x001e, */
46 /*	AG_KEY_ASCII_US		= 0x001f, */
47 	AG_KEY_SPACE		= 0x0020,
48 	AG_KEY_EXCLAIM		= 0x0021,	/* ! */
49 	AG_KEY_QUOTEDBL		= 0x0022,	/* " */
50 	AG_KEY_HASH		= 0x0023,	/* # */
51 	AG_KEY_DOLLAR		= 0x0024,	/* $ */
52 	AG_KEY_PERCENT		= 0x0025,	/* % */
53 	AG_KEY_AMPERSAND	= 0x0026,	/* & */
54 	AG_KEY_QUOTE		= 0x0027,	/* ' */
55 	AG_KEY_LEFTPAREN	= 0x0028,	/* ( */
56 	AG_KEY_RIGHTPAREN	= 0x0029,	/* ) */
57 	AG_KEY_ASTERISK		= 0x002a,	/* * */
58 	AG_KEY_PLUS		= 0x002b,	/* + */
59 	AG_KEY_COMMA		= 0x002c,	/* , */
60 	AG_KEY_MINUS		= 0x002d,	/* - */
61 	AG_KEY_PERIOD		= 0x002e,	/* . */
62 	AG_KEY_SLASH		= 0x002f,	/* / */
63 	AG_KEY_0		= 0x0030,	/* 0 */
64 	AG_KEY_1		= 0x0031,	/* 1 */
65 	AG_KEY_2		= 0x0032,	/* 2 */
66 	AG_KEY_3		= 0x0033,	/* 3 */
67 	AG_KEY_4		= 0x0034,	/* 4 */
68 	AG_KEY_5		= 0x0035,	/* 5 */
69 	AG_KEY_6		= 0x0036,	/* 6 */
70 	AG_KEY_7		= 0x0037,	/* 7 */
71 	AG_KEY_8		= 0x0038,	/* 8 */
72 	AG_KEY_9		= 0x0039,	/* 9 */
73 	AG_KEY_COLON		= 0x003a,	/* : */
74 	AG_KEY_SEMICOLON	= 0x003b,	/* ; */
75 	AG_KEY_LESS		= 0x003c,	/* < */
76 	AG_KEY_EQUALS		= 0x003d,	/* = */
77 	AG_KEY_GREATER		= 0x003e,	/* > */
78 	AG_KEY_QUESTION		= 0x003f,	/* ? */
79 	AG_KEY_AT		= 0x0040,	/* @ */
80 #if 0
81 	AG_KEY_UPPER_A		= 0x0041,	/* A */
82 	AG_KEY_UPPER_B		= 0x0042,	/* B */
83 	AG_KEY_UPPER_C		= 0x0043,	/* C */
84 	AG_KEY_UPPER_D		= 0x0044,	/* D */
85 	AG_KEY_UPPER_E		= 0x0045,	/* E */
86 	AG_KEY_UPPER_F		= 0x0046,	/* F */
87 	AG_KEY_UPPER_G		= 0x0047,	/* G */
88 	AG_KEY_UPPER_H		= 0x0048,	/* H */
89 	AG_KEY_UPPER_I		= 0x0049,	/* I */
90 	AG_KEY_UPPER_J		= 0x004a,	/* J */
91 	AG_KEY_UPPER_K		= 0x004b,	/* K */
92 	AG_KEY_UPPER_L		= 0x004c,	/* L */
93 	AG_KEY_UPPER_M		= 0x004d,	/* M */
94 	AG_KEY_UPPER_N		= 0x004e,	/* N */
95 	AG_KEY_UPPER_O		= 0x004f,	/* O */
96 	AG_KEY_UPPER_P		= 0x0050,	/* P */
97 	AG_KEY_UPPER_Q		= 0x0051,	/* Q */
98 	AG_KEY_UPPER_R		= 0x0052,	/* R */
99 	AG_KEY_UPPER_S		= 0x0053,	/* S */
100 	AG_KEY_UPPER_T		= 0x0054,	/* T */
101 	AG_KEY_UPPER_U		= 0x0055,	/* U */
102 	AG_KEY_UPPER_V		= 0x0056,	/* V */
103 	AG_KEY_UPPER_W		= 0x0057,	/* W */
104 	AG_KEY_UPPER_X		= 0x0058,	/* X */
105 	AG_KEY_UPPER_Y		= 0x0059,	/* Y */
106 	AG_KEY_UPPER_Z		= 0x005a,	/* Z */
107 #endif
108 	AG_KEY_LEFTBRACKET	= 0x005b,	/* [ */
109 	AG_KEY_BACKSLASH	= 0x005c,	/* \ */
110 	AG_KEY_RIGHTBRACKET	= 0x005d,	/* ] */
111 	AG_KEY_CARET		= 0x005e,	/* ^ */
112 	AG_KEY_UNDERSCORE	= 0x005f,	/* _ */
113 	AG_KEY_BACKQUOTE	= 0x0060,	/* ` */
114 	AG_KEY_A		= 0x0061,	/* a */
115 	AG_KEY_B		= 0x0062,	/* b */
116 	AG_KEY_C		= 0x0063,	/* c */
117 	AG_KEY_D		= 0x0064,	/* d */
118 	AG_KEY_E		= 0x0065,	/* e */
119 	AG_KEY_F		= 0x0066,	/* f */
120 	AG_KEY_G		= 0x0067,	/* g */
121 	AG_KEY_H		= 0x0068,	/* h */
122 	AG_KEY_I		= 0x0069,	/* i */
123 	AG_KEY_J		= 0x006a,	/* j */
124 	AG_KEY_K		= 0x006b,	/* k */
125 	AG_KEY_L		= 0x006c,	/* l */
126 	AG_KEY_M		= 0x006d,	/* m */
127 	AG_KEY_N		= 0x006e,	/* n */
128 	AG_KEY_O		= 0x006f,	/* o */
129 	AG_KEY_P		= 0x0070,	/* p */
130 	AG_KEY_Q		= 0x0071,	/* q */
131 	AG_KEY_R		= 0x0072,	/* r */
132 	AG_KEY_S		= 0x0073,	/* s */
133 	AG_KEY_T		= 0x0074,	/* t */
134 	AG_KEY_U		= 0x0075,	/* u */
135 	AG_KEY_V		= 0x0076,	/* v */
136 	AG_KEY_W		= 0x0077,	/* w */
137 	AG_KEY_X		= 0x0078,	/* x */
138 	AG_KEY_Y		= 0x0079,	/* y */
139 	AG_KEY_Z		= 0x007a,	/* z */
140 	AG_KEY_DELETE		= 0x007f,
141 	AG_KEY_ASCII_END	= 0x007f,	/* End of ASCII range */
142 	AG_KEY_KP0		= 0x0100,
143 	AG_KEY_KP1		= 0x0101,
144 	AG_KEY_KP2		= 0x0102,
145 	AG_KEY_KP3		= 0x0103,
146 	AG_KEY_KP4		= 0x0104,
147 	AG_KEY_KP5		= 0x0105,
148 	AG_KEY_KP6		= 0x0106,
149 	AG_KEY_KP7		= 0x0107,
150 	AG_KEY_KP8		= 0x0108,
151 	AG_KEY_KP9		= 0x0109,
152 	AG_KEY_KP_PERIOD	= 0x010a,
153 	AG_KEY_KP_DIVIDE	= 0x010b,
154 	AG_KEY_KP_MULTIPLY	= 0x010c,
155 	AG_KEY_KP_MINUS		= 0x010d,
156 	AG_KEY_KP_PLUS		= 0x010e,
157 	AG_KEY_KP_ENTER		= 0x010f,
158 	AG_KEY_KP_EQUALS	= 0x0110,
159 	AG_KEY_UP		= 0x0111,
160 	AG_KEY_DOWN		= 0x0112,
161 	AG_KEY_RIGHT		= 0x0113,
162 	AG_KEY_LEFT		= 0x0114,
163 	AG_KEY_INSERT		= 0x0115,
164 	AG_KEY_HOME		= 0x0116,
165 	AG_KEY_END		= 0x0117,
166 	AG_KEY_PAGEUP		= 0x0118,
167 	AG_KEY_PAGEDOWN		= 0x0119,
168 	AG_KEY_F1		= 0x011a,
169 	AG_KEY_F2		= 0x011b,
170 	AG_KEY_F3		= 0x011c,
171 	AG_KEY_F4		= 0x011d,
172 	AG_KEY_F5		= 0x011e,
173 	AG_KEY_F6		= 0x011f,
174 	AG_KEY_F7		= 0x0120,
175 	AG_KEY_F8		= 0x0121,
176 	AG_KEY_F9		= 0x0122,
177 	AG_KEY_F10		= 0x0123,
178 	AG_KEY_F11		= 0x0124,
179 	AG_KEY_F12		= 0x0125,
180 	AG_KEY_F13		= 0x0126,
181 	AG_KEY_F14		= 0x0127,
182 	AG_KEY_F15		= 0x0128,
183 	AG_KEY_NUMLOCK		= 0x012c,
184 	AG_KEY_CAPSLOCK		= 0x012d,
185 	AG_KEY_SCROLLOCK	= 0x012e,
186 	AG_KEY_RSHIFT		= 0x012f,
187 	AG_KEY_LSHIFT		= 0x0130,
188 	AG_KEY_RCTRL		= 0x0131,
189 	AG_KEY_LCTRL		= 0x0132,
190 	AG_KEY_RALT		= 0x0133,
191 	AG_KEY_LALT		= 0x0134,
192 	AG_KEY_RMETA		= 0x0135,
193 	AG_KEY_LMETA		= 0x0136,
194 	AG_KEY_LSUPER		= 0x0137,
195 	AG_KEY_RSUPER		= 0x0138,
196 	AG_KEY_MODE		= 0x0139,
197 	AG_KEY_COMPOSE		= 0x013a,
198 	AG_KEY_HELP		= 0x013b,
199 	AG_KEY_PRINT		= 0x013c,
200 	AG_KEY_SYSREQ		= 0x013d,
201 	AG_KEY_BREAK		= 0x013e,
202 	AG_KEY_MENU		= 0x013f,
203 	AG_KEY_POWER		= 0x0140,
204 	AG_KEY_EURO		= 0x0141,
205 	AG_KEY_UNDO		= 0x0142,
206 	AG_KEY_GRAVE		= 0x0143,
207 	AG_KEY_KP_CLEAR		= 0x0144,
208 	AG_KEY_COMMAND		= 0x0145,
209 	AG_KEY_FUNCTION		= 0x0146,
210 	AG_KEY_VOLUME_UP	= 0x0147,
211 	AG_KEY_VOLUME_DOWN	= 0x0148,
212 	AG_KEY_VOLUME_MUTE	= 0x0149,
213 	AG_KEY_F16		= 0x014a,
214 	AG_KEY_F17		= 0x014b,
215 	AG_KEY_F18		= 0x014c,
216 	AG_KEY_F19		= 0x014d,
217 	AG_KEY_F20		= 0x014e,
218 	AG_KEY_F21		= 0x014f,
219 	AG_KEY_F22		= 0x0150,
220 	AG_KEY_F23		= 0x0151,
221 	AG_KEY_F24		= 0x0152,
222 	AG_KEY_F25		= 0x0153,
223 	AG_KEY_F26		= 0x0154,
224 	AG_KEY_F27		= 0x0155,
225 	AG_KEY_F28		= 0x0156,
226 	AG_KEY_F29		= 0x0157,
227 	AG_KEY_F30		= 0x0158,
228 	AG_KEY_F31		= 0x0159,
229 	AG_KEY_F32		= 0x015a,
230 	AG_KEY_F33		= 0x015b,
231 	AG_KEY_F34		= 0x015c,
232 	AG_KEY_F35		= 0x015d,
233 	AG_KEY_BEGIN		= 0x015e,
234 	AG_KEY_RESET		= 0x015f,
235 	AG_KEY_STOP		= 0x0160,
236 	AG_KEY_USER		= 0x0161,
237 	AG_KEY_SYSTEM		= 0x0162,
238 	AG_KEY_PRINT_SCREEN	= 0x0163,
239 	AG_KEY_CLEAR_LINE	= 0x0164,
240 	AG_KEY_CLEAR_DISPLAY	= 0x0165,
241 	AG_KEY_INSERT_LINE	= 0x0166,
242 	AG_KEY_DELETE_LINE	= 0x0167,
243 	AG_KEY_INSERT_CHAR	= 0x0168,
244 	AG_KEY_DELETE_CHAR	= 0x0169,
245 	AG_KEY_PREV		= 0x016a,
246 	AG_KEY_NEXT		= 0x016b,
247 	AG_KEY_SELECT		= 0x016c,
248 	AG_KEY_EXECUTE		= 0x016d,
249 	AG_KEY_REDO		= 0x016e,
250 	AG_KEY_FIND		= 0x016f,
251 	AG_KEY_MODE_SWITCH	= 0x0170,
252 	AG_KEY_LAST		= 0x0171,
253 	AG_KEY_ANY		= 0xffff	/* For matching */
254 } AG_KeySym;
255 
256 typedef unsigned int AG_KeyMod;
257 
258 #define AG_KEYMOD_NONE		0x0000
259 #define AG_KEYMOD_LSHIFT	0x0001
260 #define AG_KEYMOD_RSHIFT	0x0002
261 #define AG_KEYMOD_LCTRL		0x0040
262 #define AG_KEYMOD_RCTRL		0x0080
263 #define AG_KEYMOD_LALT		0x0100
264 #define AG_KEYMOD_RALT		0x0200
265 #define AG_KEYMOD_LMETA		0x0400
266 #define AG_KEYMOD_RMETA		0x0800
267 #define AG_KEYMOD_NUMLOCK	0x1000
268 #define AG_KEYMOD_CAPSLOCK	0x2000
269 #define AG_KEYMOD_MODE		0x4000
270 #define AG_KEYMOD_ANY		0xffff		/* As argument for matching */
271 #define AG_KEYMOD_CTRL		(AG_KEYMOD_LCTRL|AG_KEYMOD_RCTRL)
272 #define AG_KEYMOD_SHIFT		(AG_KEYMOD_LSHIFT|AG_KEYMOD_RSHIFT)
273 #define AG_KEYMOD_ALT		(AG_KEYMOD_LALT|AG_KEYMOD_RALT)
274 #define AG_KEYMOD_META		(AG_KEYMOD_LMETA|AG_KEYMOD_RMETA)
275 
276 struct ag_window;
277 
278 typedef struct ag_key {
279 	enum ag_key_sym sym;	/* Translated key */
280 	int mod;		/* Key modifier */
281 	Uint32 uch;		/* Corresponding Unicode character */
282 } AG_Key;
283 
284 typedef struct ag_keyboard {
285 	struct ag_input_device _inherit;
286 	Uint flags;
287 	int *keyState;		/* Key state */
288 	Uint keyCount;
289 	Uint modState;		/* Modifiers state */
290 } AG_Keyboard;
291 
292 __BEGIN_DECLS
293 extern AG_ObjectClass agKeyboardClass;
294 
295 AG_Keyboard *AG_KeyboardNew(void *, const char *);
296 
297 int AG_KeyboardUpdate(AG_Keyboard *, AG_KeyboardAction, AG_KeySym, Uint32);
298 int AG_ProcessKey(AG_Keyboard *, struct ag_window *, AG_KeyboardAction,
299                   AG_KeySym, Uint32);
300 
301 const char *AG_LookupKeyName(AG_KeySym);
302 AG_KeySym   AG_LookupKeySym(const char *);
303 
304 void AG_InitGlobalKeys(void);
305 void AG_DestroyGlobalKeys(void);
306 void AG_BindStdGlobalKeys(void);
307 void AG_BindGlobalKey(AG_KeySym, AG_KeyMod, void (*)(void));
308 void AG_BindGlobalKeyEv(AG_KeySym, AG_KeyMod, void (*)(AG_Event *));
309 int  AG_UnbindGlobalKey(AG_KeySym, AG_KeyMod);
310 void AG_ClearGlobalKeys(void);
311 int  AG_ExecGlobalKeys(AG_KeySym, AG_KeyMod);
312 
313 /* Compare unsided modifier state against a string of flags. */
314 static __inline__ int
AG_CompareKeyMods(Uint modState,const char * flags)315 AG_CompareKeyMods(Uint modState, const char *flags)
316 {
317 	const char *c;
318 
319 	for (c = &flags[0]; *c != '\0'; c++) {
320 		switch (*c) {
321 		case 'C':
322 			if (modState & AG_KEYMOD_LCTRL ||
323 			    modState & AG_KEYMOD_RCTRL) {
324 				return (1);
325 			}
326 			break;
327 		case 'A':
328 			if (modState & AG_KEYMOD_LALT ||
329 			    modState & AG_KEYMOD_RALT) {
330 				return (1);
331 			}
332 			break;
333 		case 'S':
334 			if (modState & AG_KEYMOD_LSHIFT ||
335 			    modState & AG_KEYMOD_RSHIFT) {
336 				return (1);
337 			}
338 			break;
339 		case 'M':
340 			if (modState & AG_KEYMOD_LMETA ||
341 			    modState & AG_KEYMOD_RMETA) {
342 				return (1);
343 			}
344 			break;
345 		}
346 	}
347 	return (0);
348 }
349 __END_DECLS
350 
351 #include <agar/gui/close.h>
352 #endif /* _AGAR_GUI_KEYBOARD_H_ */
353