1 /**
2  * \file ui-event.h
3  * \brief Utility functions relating to UI events
4  *
5  * Copyright (c) 2011 Andi Sidwell
6  *
7  * This work is free software; you can redistribute it and/or modify it
8  * under the terms of either:
9  *
10  * a) the GNU General Public License as published by the Free Software
11  *    Foundation, version 2, or
12  *
13  * b) the "Angband licence":
14  *    This software may be copied and distributed for educational, research,
15  *    and not for profit purposes provided that this copyright and statement
16  *    are included in all such copies.  Other copyrights may also apply.
17  */
18 #ifndef INCLUDED_UI_EVENT_H
19 #define INCLUDED_UI_EVENT_H
20 
21 /**
22  * The various UI events that can occur.
23  */
24 typedef enum
25 {
26 	EVT_NONE	= 0x0000,
27 
28 	/* Basic events */
29 	EVT_KBRD	= 0x0001,	/* Keypress */
30 	EVT_MOUSE	= 0x0002,	/* Mousepress */
31 	EVT_RESIZE	= 0x0004,	/* Display resize */
32 
33 	EVT_BUTTON	= 0x0008,	/* Button press */
34 
35 	/* 'Abstract' events */
36 	EVT_ESCAPE	= 0x0010,	/* Get out of this menu */
37 	EVT_MOVE	= 0x0020,	/* Menu movement */
38 	EVT_SELECT	= 0x0040,	/* Menu selection */
39 	EVT_SWITCH	= 0x0080	/* Menu switch */
40 } ui_event_type;
41 
42 
43 /**
44  * Key modifiers.
45  */
46 #define KC_MOD_CONTROL  0x01
47 #define KC_MOD_SHIFT    0x02
48 #define KC_MOD_ALT      0x04
49 #define KC_MOD_META     0x08
50 #define KC_MOD_KEYPAD   0x10
51 
52 
53 /**
54  * The game assumes that in certain cases, the effect of a modifer key will
55  * be encoded in the keycode itself (e.g. 'A' is shift-'a').  In these cases
56  * (specified below), a keypress' 'mods' value should not encode them also.
57  *
58  * If the character has come from the keypad:
59  *   Include all mods
60  * Else if the character is in the range 0x01-0x1F, and the keypress was
61  * from a key that without modifiers would be in the range 0x40-0x5F:
62  *   CONTROL is encoded in the keycode, and should not be in mods
63  * Else if the character is in the range 0x21-0x2F, 0x3A-0x60 or 0x7B-0x7E:
64  *   SHIFT is often used to produce these should not be encoded in mods
65  *
66  * (All ranges are inclusive.)
67  *
68  * You can use these macros for part of the above conditions.
69  */
70 #define MODS_INCLUDE_CONTROL(v) \
71 	(((v) >= 0x01 && (v) <= 0x1F) ? false : true)
72 
73 #define MODS_INCLUDE_SHIFT(v) \
74 	((((v) >= 0x21 && (v) <= 0x2F) || \
75 			((v) >= 0x3A && (v) <= 0x60) || \
76 			((v) >= 0x7B && (v) <= 0x7E)) ? false : true)
77 
78 
79 /**
80  * If keycode you're trying to apply control to is between 0x40-0x5F
81  * inclusive, then you should take 0x40 from the keycode and leave
82  * KC_MOD_CONTROL unset.  Otherwise, leave the keycode alone and set
83  * KC_MOD_CONTROL in mods.
84  *
85  * This macro returns true in the former case and false in the latter.
86  */
87 #define ENCODE_KTRL(v) \
88 	(((v) >= 0x40 && (v) <= 0x5F) ? true : false)
89 
90 
91 /**
92  * Given a character X, turn it into a control character.
93  */
94 #define KTRL(X) \
95 	((X) & 0x1F)
96 
97 
98 /**
99  * Given a control character X, turn it into its uppercase ASCII equivalent.
100  */
101 #define UN_KTRL(X) \
102 	((X) + 64)
103 
104 
105 /**
106  * Keyset mappings for various keys.
107  */
108 #define ARROW_DOWN    0x80
109 #define ARROW_LEFT    0x81
110 #define ARROW_RIGHT   0x82
111 #define ARROW_UP      0x83
112 
113 #define KC_F1         0x84
114 #define KC_F2         0x85
115 #define KC_F3         0x86
116 #define KC_F4         0x87
117 #define KC_F5         0x88
118 #define KC_F6         0x89
119 #define KC_F7         0x8A
120 #define KC_F8         0x8B
121 #define KC_F9         0x8C
122 #define KC_F10        0x8D
123 #define KC_F11        0x8E
124 #define KC_F12        0x8F
125 #define KC_F13        0x90
126 #define KC_F14        0x91
127 #define KC_F15        0x92
128 
129 #define KC_HELP       0x93
130 #define KC_HOME       0x94
131 #define KC_PGUP       0x95
132 #define KC_END        0x96
133 #define KC_PGDOWN     0x97
134 #define KC_INSERT     0x98
135 #define KC_PAUSE      0x99
136 #define KC_BREAK      0x9a
137 #define KC_BEGIN      0x9b
138 #define KC_ENTER      0x9c /* ASCII \r */
139 #define KC_TAB        0x9d /* ASCII \t */
140 #define KC_DELETE     0x9e
141 #define KC_BACKSPACE  0x9f /* ASCII \h */
142 #define ESCAPE        0xE000
143 
144 /* we have up until 0x9F before we start edging into displayable Unicode */
145 /* then we could move into private use area 1, 0xE000 onwards */
146 
147 /**
148  * Analogous to isdigit() etc in ctypes
149  */
150 #define isarrow(c)  ((c >= ARROW_DOWN) && (c <= ARROW_UP))
151 
152 
153 /**
154  * Type capable of holding any input key we might want to use.
155  */
156 typedef u32b keycode_t;
157 
158 
159 /**
160  * Struct holding all relevant info for keypresses.
161  */
162 struct keypress {
163 	ui_event_type type;
164 	keycode_t code;
165 	byte mods;
166 };
167 
168 /**
169  * Null keypress constant, for safe initializtion.
170  */
171 static struct keypress const KEYPRESS_NULL = {
172 	.type = EVT_NONE,
173 	.code = 0,
174 	.mods = 0
175 };
176 
177 /**
178  * Struct holding all relevant info for mouse clicks.
179  */
180 struct mouseclick {
181 	ui_event_type type;
182 	byte x;
183 	byte y;
184 	byte button;
185 	byte mods;
186 };
187 
188 /**
189  * Union type to hold information about any given event.
190  */
191 typedef union {
192 	ui_event_type type;
193 	struct mouseclick mouse;
194 	struct keypress key;
195 } ui_event;
196 
197 /**
198  * Easy way to initialise a ui_event without seeing the gory bits.
199  */
200 #define EVENT_EMPTY		{ 0 }
201 
202 
203 /*** Functions ***/
204 
205 /**
206  * Given a string (and that string's length), return the corresponding keycode
207  */
208 keycode_t keycode_find_code(const char *str, size_t len);
209 
210 /**
211  * Given a keycode, return its description
212  */
213 const char *keycode_find_desc(keycode_t kc);
214 
215 /**
216  * Given a keycode, return whether it corresponds to a printable character.
217  */
218 bool keycode_isprint(keycode_t kc);
219 
220 /**
221  * Convert a string of keypresses into their textual representation
222  */
223 void keypress_to_text(char *buf, size_t len, const struct keypress *src,
224 	bool expand_backslash);
225 
226 /**
227  * Convert a textual representation of keypresses into actual keypresses
228  */
229 void keypress_from_text(struct keypress *buf, size_t len, const char *str);
230 
231 /**
232  * Convert a keypress into something the user can read (not designed to be used
233  * internally
234  */
235 void keypress_to_readable(char *buf, size_t len, struct keypress src);
236 
237 
238 extern bool char_matches_key(wchar_t c, keycode_t key);
239 
240 
241 #endif /* INCLUDED_UI_EVENT_H */
242