modify logging to simplify i18n
[voxelands-alt.git] / src / client / events_x11.c
bloba32dfe1263c0b1e4b34c8f3b3097340185689b75
1 /************************************************************************
2 * events_x11.c
3 * voxelands - 3d voxel world sandbox game
4 * Copyright (C) Lisa 'darkrose' Milne 2016 <lisa@ltmnet.com>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>
18 ************************************************************************/
20 #include "common.h"
21 #define _WM_EXPOSE_ALL
22 #include "wm.h"
24 #ifndef WIN32
26 #include <wctype.h>
27 #include <string.h>
29 int xkey_to_char(uint32_t *ch, XEvent *event)
31 KeySym keysym;
32 wchar_t buff[6];
33 char* kc;
34 int l;
35 l = XwcLookupString(wm_data.ic,&event->xkey,buff,4,&keysym,NULL);
36 if (l == 1) {
37 *ch = buff[0];
38 }else{
39 kc = XKeysymToString(keysym);
40 if (kc && utf8_strlen(kc) == 1)
41 *ch = utf8_toutf32(kc,-1);
44 return 0;
47 int xevent_to_sym(sym_t *s, XEvent *event)
49 int sym;
50 char* kc;
52 sym = XLookupKeysym(&event->xkey, 0);
54 switch (sym) {
55 case XK_Shift_L:
56 case XK_Shift_R:
57 s->type = SYM_TYPE_MOD;
58 s->sym = SYM_MOD_SHIFT;
59 break;
60 case XK_Control_L:
61 case XK_Control_R:
62 s->type = SYM_TYPE_MOD;
63 s->sym = SYM_MOD_CTRL;
64 break;
65 case XK_Alt_L:
66 case XK_Alt_R:
67 s->type = SYM_TYPE_MOD;
68 s->sym = SYM_MOD_ALT;
69 break;
70 case XK_Super_L:
71 case XK_Super_R:
72 s->type = SYM_TYPE_MOD;
73 s->sym = SYM_MOD_SUPER;
74 break;
75 case XK_space:
76 case XK_KP_Space:
77 s->type = SYM_TYPE_SKEY;
78 s->sym = SYM_KEY_SPACE;
79 break;
80 case XK_Escape:
81 s->type = SYM_TYPE_SKEY;
82 s->sym = SYM_KEY_ESCAPE;
83 break;
84 case XK_Tab:
85 case XK_KP_Tab:
86 s->type = SYM_TYPE_SKEY;
87 s->sym = SYM_KEY_TAB;
88 break;
89 case XK_KP_0:
90 s->type = SYM_TYPE_SKEY;
91 s->sym = SYM_KEY_KP0;
92 break;
93 case XK_KP_1:
94 s->type = SYM_TYPE_SKEY;
95 s->sym = SYM_KEY_KP1;
96 break;
97 case XK_KP_2:
98 s->type = SYM_TYPE_SKEY;
99 s->sym = SYM_KEY_KP2;
100 break;
101 case XK_KP_3:
102 s->type = SYM_TYPE_SKEY;
103 s->sym = SYM_KEY_KP3;
104 break;
105 case XK_KP_4:
106 s->type = SYM_TYPE_SKEY;
107 s->sym = SYM_KEY_KP4;
108 break;
109 case XK_KP_5:
110 s->type = SYM_TYPE_SKEY;
111 s->sym = SYM_KEY_KP5;
112 break;
113 case XK_KP_6:
114 s->type = SYM_TYPE_SKEY;
115 s->sym = SYM_KEY_KP6;
116 break;
117 case XK_KP_7:
118 s->type = SYM_TYPE_SKEY;
119 s->sym = SYM_KEY_KP7;
120 break;
121 case XK_KP_8:
122 s->type = SYM_TYPE_SKEY;
123 s->sym = SYM_KEY_KP8;
124 break;
125 case XK_KP_9:
126 s->type = SYM_TYPE_SKEY;
127 s->sym = SYM_KEY_KP9;
128 break;
129 case XK_Left:
130 case XK_KP_Left:
131 s->type = SYM_TYPE_SKEY;
132 s->sym = SYM_KEY_LEFT;
133 break;
134 case XK_Up:
135 case XK_KP_Up:
136 s->type = SYM_TYPE_SKEY;
137 s->sym = SYM_KEY_UP;
138 break;
139 case XK_Right:
140 case XK_KP_Right:
141 s->type = SYM_TYPE_SKEY;
142 s->sym = SYM_KEY_RIGHT;
143 break;
144 case XK_Down:
145 case XK_KP_Down:
146 s->type = SYM_TYPE_SKEY;
147 s->sym = SYM_KEY_DOWN;
148 break;
149 case XK_F1:
150 case XK_KP_F1:
151 s->type = SYM_TYPE_SKEY;
152 s->sym = SYM_KEY_F1;
153 break;
154 case XK_F2:
155 case XK_KP_F2:
156 s->type = SYM_TYPE_SKEY;
157 s->sym = SYM_KEY_F2;
158 break;
159 case XK_F3:
160 case XK_KP_F3:
161 s->type = SYM_TYPE_SKEY;
162 s->sym = SYM_KEY_F3;
163 break;
164 case XK_F4:
165 case XK_KP_F4:
166 s->type = SYM_TYPE_SKEY;
167 s->sym = SYM_KEY_F4;
168 break;
169 case XK_F5:
170 s->type = SYM_TYPE_SKEY;
171 s->sym = SYM_KEY_F5;
172 break;
173 case XK_F6:
174 s->type = SYM_TYPE_SKEY;
175 s->sym = SYM_KEY_F6;
176 break;
177 case XK_F7:
178 s->type = SYM_TYPE_SKEY;
179 s->sym = SYM_KEY_F7;
180 break;
181 case XK_F8:
182 s->type = SYM_TYPE_SKEY;
183 s->sym = SYM_KEY_F8;
184 break;
185 case XK_F9:
186 s->type = SYM_TYPE_SKEY;
187 s->sym = SYM_KEY_F9;
188 break;
189 case XK_F10:
190 s->type = SYM_TYPE_SKEY;
191 s->sym = SYM_KEY_F10;
192 break;
193 case XK_F11:
194 s->type = SYM_TYPE_SKEY;
195 s->sym = SYM_KEY_F11;
196 break;
197 case XK_F12:
198 s->type = SYM_TYPE_SKEY;
199 s->sym = SYM_KEY_F12;
200 break;
201 case XK_BackSpace:
202 s->type = SYM_TYPE_SKEY;
203 s->sym = SYM_KEY_BCKSPC;
204 break;
205 case XK_Return:
206 case XK_KP_Enter:
207 s->type = SYM_TYPE_SKEY;
208 s->sym = SYM_KEY_RETURN;
209 break;
210 case XK_Delete:
211 case XK_KP_Delete:
212 s->type = SYM_TYPE_SKEY;
213 s->sym = SYM_KEY_DELETE;
214 break;
215 case XK_KP_Equal:
216 s->type = SYM_TYPE_SKEY;
217 s->sym = SYM_KEY_KPEQ;
218 break;
219 case XK_KP_Multiply:
220 s->type = SYM_TYPE_SKEY;
221 s->sym = SYM_KEY_KPMUL;
222 break;
223 case XK_KP_Add:
224 s->type = SYM_TYPE_SKEY;
225 s->sym = SYM_KEY_KPADD;
226 break;
227 case XK_KP_Subtract:
228 s->type = SYM_TYPE_SKEY;
229 s->sym = SYM_KEY_KPSUB;
230 break;
231 case XK_KP_Decimal:
232 s->type = SYM_TYPE_SKEY;
233 s->sym = SYM_KEY_KPDOT;
234 break;
235 case XK_KP_Divide:
236 s->type = SYM_TYPE_SKEY;
237 s->sym = SYM_KEY_KPDIV;
238 break;
239 /* stuff we don't care about */
240 case XK_Linefeed:
241 case XK_Clear:
242 case XK_Pause:
243 case XK_Scroll_Lock:
244 case XK_Sys_Req:
245 case XK_Home:
246 case XK_Prior:
247 /* case XK_KP_Prior: same as non-kp
248 case XK_Page_Up: same as Prior
249 case XK_KP_Page_Up: same as non-kp */
250 case XK_Next:
251 /* case XK_KP_Next: same as non-kp
252 case XK_Page_Down: same as Next
253 case XK_KP_Page_Down: same as non-kp */
254 case XK_Mode_switch:
255 /* case XK_script_switch: same as Mode_switch */
256 case XK_End:
257 case XK_Begin:
258 case XK_Select:
259 case XK_Print:
260 case XK_Execute:
261 case XK_Insert:
262 case XK_Undo:
263 case XK_Redo:
264 case XK_Menu:
265 case XK_Find:
266 case XK_Cancel:
267 case XK_Help:
268 case XK_Break:
269 case XK_Num_Lock:
270 case XK_KP_Home:
271 case XK_KP_End:
272 case XK_KP_Begin:
273 case XK_KP_Insert:
274 break;
275 default:
276 s->type = SYM_TYPE_KEY;
277 kc = XKeysymToString(sym);
278 if (kc && utf8_strlen(kc) == 1) {
279 s->sym = utf8_toutf32(kc,-1);
280 if (!iswgraph(s->sym))
281 s->sym = 0;
285 if (!s->sym) {
286 char buff[5];
287 int l;
288 KeySym keysym;
289 l = XLookupString(&event->xkey, buff, 5, &keysym, NULL);
290 if (l>0 && utf8_strlen(buff) == 1)
291 s->sym = utf8_toutf32(buff,-1);
294 return 0;
297 /* read and act on events */
298 void events_main()
300 XEvent event;
301 event_t e;
302 int rm[2];
303 while (XPending(wm_data.dpy) > 0) {
304 XNextEvent(wm_data.dpy, &event);
305 if (XFilterEvent(&event,None) == True)
306 continue;
307 e.type = EVENT_NONE;
308 e.sym.type = SYM_TYPE_NONE;
309 e.sym.sym = 0;
310 e.sym.ch = 0;
311 switch (event.type) {
312 case Expose:
313 if (event.xexpose.count != 0)
314 break;
315 break;
316 case ConfigureNotify:
317 if ((event.xconfigure.width != wm_data.size.width) || (event.xconfigure.height != wm_data.size.height)) {
318 wm_data.size.width = event.xconfigure.width;
319 wm_data.size.height = event.xconfigure.height;
320 wm_resize();
322 break;
323 case ButtonPress:
324 e.type = EVENT_BUTTON_DOWN;
325 e.sym.type = SYM_TYPE_MOUSE;
326 if (event.xbutton.button == 1) {
327 e.sym.sym = MOUSE_BUTTON_LEFT;
328 events_handle(&e);
329 }else if (event.xbutton.button == 2) {
330 e.sym.sym = MOUSE_BUTTON_CENTRE;
331 events_handle(&e);
332 }else if (event.xbutton.button == 3) {
333 e.sym.sym = MOUSE_BUTTON_RIGHT;
334 events_handle(&e);
335 }else if (event.xbutton.button == 4) {
336 e.sym.sym = MOUSE_BUTTON_UP;
337 events_handle(&e);
338 }else if (event.xbutton.button == 5) {
339 e.sym.sym = MOUSE_BUTTON_DOWN;
340 events_handle(&e);
342 break;
343 case ButtonRelease:
344 e.type = EVENT_BUTTON_UP;
345 e.sym.type = SYM_TYPE_MOUSE;
346 if (event.xbutton.button == 1) {
347 e.sym.sym = MOUSE_BUTTON_LEFT;
348 events_handle(&e);
349 }else if (event.xbutton.button == 2) {
350 e.sym.sym = MOUSE_BUTTON_CENTRE;
351 events_handle(&e);
352 }else if (event.xbutton.button == 3) {
353 e.sym.sym = MOUSE_BUTTON_RIGHT;
354 events_handle(&e);
356 break;
357 case MotionNotify:
358 e.type = EVENT_MOUSE_MOTION;
359 e.x = event.xmotion.x;
360 e.y = event.xmotion.y;
361 events_get_mouse(rm);
362 e.rx = e.x-rm[0];
363 e.ry = e.y-rm[1];
364 if (e.rx > -100 && e.rx < 100 && e.ry > -100 && e.ry < 100) {
365 events_handle(&e);
366 if (events_get_mousegrab()) {
367 if (e.x < 5 || e.x > (wm_data.size.width-5))
368 XWarpPointer(wm_data.dpy, None, wm_data.win, 0, 0, 0, 0, wm_data.size.width/2, e.y);
369 if (e.y < 5 || e.y > (wm_data.size.height-5))
370 XWarpPointer(wm_data.dpy, None, wm_data.win, 0, 0, 0, 0, e.x, wm_data.size.height/2);
373 break;
374 case KeyPress:
375 e.type = EVENT_KEY_DOWN;
376 xevent_to_sym(&e.sym,&event);
377 xkey_to_char(&e.sym.ch,&event);
378 if (e.sym.sym) {
379 char buffs[6];
380 char buffc[6];
381 utf8_fromutf32(buffs,6,e.sym.sym);
382 utf8_fromutf32(buffc,6,e.sym.ch);
383 vlprintf(CN_INFO,"P %u %u '%s' '%s'\n",e.sym.sym,e.sym.ch,buffs,buffc);
385 if (e.sym.sym)
386 events_handle(&e);
387 break;
388 case KeyRelease:
389 if (XEventsQueued(wm_data.dpy, QueuedAfterReading)) {
390 XEvent nev;
391 XPeekEvent(wm_data.dpy, &nev);
392 if (
393 nev.type == KeyPress
394 && nev.xkey.time == event.xkey.time
395 && nev.xkey.keycode == event.xkey.keycode
397 break;
400 e.type = EVENT_KEY_DOWN;
401 xevent_to_sym(&e.sym,&event);
402 if (e.sym.sym) {
403 char buffs[6];
404 char buffc[6];
405 utf8_fromutf32(buffs,6,e.sym.sym);
406 utf8_fromutf32(buffc,6,e.sym.ch);
407 vlprintf(CN_INFO,"R %u %u '%s' '%s'\n",e.sym.sym,e.sym.ch,buffs,buffc);
409 if (e.sym.sym)
410 events_handle(&e);
411 break;
412 case MappingNotify:
413 XRefreshKeyboardMapping(&event.xmapping);
414 break;
415 case ClientMessage:
416 if (strstr(XGetAtomName(wm_data.dpy, event.xclient.message_type),"WM_PROTOCOLS"))
417 client_state(VLSTATE_EXIT);
418 break;
419 default:;
422 events_trigger_active();
424 #endif