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