1 /************************************************************************
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 ************************************************************************/
21 #define _WM_EXPOSE_ALL
27 typedef struct bind_s {
34 static uint32_t kmap_strtosym(char* str
, sym_t
*sym
)
37 if (utf8_strlen(str
) == 1) {
38 sym
->type
= SYM_TYPE_KEY
;
39 sym
->sym
= utf8_toutf32(str
,-1);
42 }else if (!strcmp(str
,"space")) {
43 sym
->type
= SYM_TYPE_SKEY
;
44 sym
->sym
= SYM_KEY_SPACE
;
47 }else if (!strcmp(str
,"ctrl")) {
48 sym
->type
= SYM_TYPE_MOD
;
49 sym
->sym
= SYM_MOD_CTRL
;
51 }else if (!strcmp(str
,"alt")) {
52 sym
->type
= SYM_TYPE_MOD
;
53 sym
->sym
= SYM_MOD_ALT
;
55 }else if (!strcmp(str
,"shift")) {
56 sym
->type
= SYM_TYPE_MOD
;
57 sym
->sym
= SYM_MOD_SHIFT
;
59 }else if (!strcmp(str
,"super")) {
60 sym
->type
= SYM_TYPE_MOD
;
61 sym
->sym
= SYM_MOD_SUPER
;
63 }else if (!strcmp(str
,"mouse-left")) {
64 sym
->type
= SYM_TYPE_MOUSE
;
65 sym
->sym
= MOUSE_BUTTON_LEFT
;
67 }else if (!strcmp(str
,"mouse-centre")) {
68 sym
->type
= SYM_TYPE_MOUSE
;
69 sym
->sym
= MOUSE_BUTTON_RIGHT
;
71 }else if (!strcmp(str
,"mouse-right")) {
72 sym
->type
= SYM_TYPE_MOUSE
;
73 sym
->sym
= MOUSE_BUTTON_LEFT
;
75 }else if (!strcmp(str
,"scroll-up")) {
76 sym
->type
= SYM_TYPE_MOUSE
;
77 sym
->sym
= MOUSE_BUTTON_UP
;
79 }else if (!strcmp(str
,"scroll-down")) {
80 sym
->type
= SYM_TYPE_MOUSE
;
81 sym
->sym
= MOUSE_BUTTON_DOWN
;
83 }else if (!strcmp(str
,"mouse-motion")) {
84 sym
->type
= SYM_TYPE_MOUSE
;
85 sym
->sym
= MOUSE_MOTION
;
87 }else if (!strcmp(str
,"esc")) {
88 sym
->type
= SYM_TYPE_SKEY
;
89 sym
->sym
= SYM_KEY_ESCAPE
;
91 }else if (!strcmp(str
,"tab")) {
92 sym
->type
= SYM_TYPE_SKEY
;
93 sym
->sym
= SYM_KEY_TAB
;
96 }else if (!strcmp(str
,"up")) {
97 sym
->type
= SYM_TYPE_SKEY
;
98 sym
->sym
= SYM_KEY_UP
;
100 }else if (!strcmp(str
,"down")) {
101 sym
->type
= SYM_TYPE_SKEY
;
102 sym
->sym
= SYM_KEY_DOWN
;
104 }else if (!strcmp(str
,"right")) {
105 sym
->type
= SYM_TYPE_SKEY
;
106 sym
->sym
= SYM_KEY_RIGHT
;
108 }else if (!strcmp(str
,"left")) {
109 sym
->type
= SYM_TYPE_SKEY
;
110 sym
->sym
= SYM_KEY_LEFT
;
112 }else if (!strncmp(str
,"kp",2)) {
113 sym
->type
= SYM_TYPE_SKEY
;
117 sym
->sym
= SYM_KEY_KP0
;
120 sym
->sym
= SYM_KEY_KP1
;
123 sym
->sym
= SYM_KEY_KP2
;
126 sym
->sym
= SYM_KEY_KP3
;
129 sym
->sym
= SYM_KEY_KP4
;
132 sym
->sym
= SYM_KEY_KP5
;
135 sym
->sym
= SYM_KEY_KP6
;
138 sym
->sym
= SYM_KEY_KP7
;
141 sym
->sym
= SYM_KEY_KP8
;
144 sym
->sym
= SYM_KEY_KP9
;
149 }else if (str
[0] == 'f' || str
[0] == 'F') {
150 int i
= strtol(str
+1,NULL
,10);
154 sym
->type
= SYM_TYPE_SKEY
;
155 sym
->sym
= SYM_KEY_F1
+i
;
160 /* convert a string to sym + modifiers */
161 int kmap_strtobind(bind_t
*bind
, char* str
)
169 if (snprintf(bind
->str
,256,"%s",str
) >= 256)
173 bind
->sym
.type
= SYM_TYPE_NONE
;
177 /* special unbound case */
178 if (!strcmp(str
,"???"))
181 /* single utf8 char is simple */
182 if (utf8_strlen(str
) == 1) {
183 bind
->sym
.type
= SYM_TYPE_KEY
;
184 bind
->sym
.sym
= utf8_toutf32(str
,-1);
190 e
= utf8_strchr(bind
->str
,'+',NULL
);
193 if (kmap_strtosym(str
,&bind
->sym
)) {
194 strcpy(bind
->str
,"???");
202 e
= utf8_strchr(b
,'+',NULL
);
204 /* odd case '+' key */
221 if (kmap_strtosym(b
,&s
)) {
222 strcpy(bind
->str
,"???");
224 bind
->sym
.type
= SYM_TYPE_NONE
;
234 bind
->sym
.type
= s
.type
;
235 bind
->sym
.sym
= s
.sym
;
241 strcpy(bind
->str
,"???");
243 bind
->sym
.type
= SYM_TYPE_NONE
;
252 if (bind
->sym
.type
!= SYM_TYPE_NONE
)
259 int kmap_bindtostr(char* str
, int size
, bind_t
*bind
)
263 /* special unbound case */
264 if (bind
->sym
.type
== SYM_TYPE_NONE
&& bind
->mods
== 0) {
271 if ((bind
->mods
&SYM_MOD_CTRL
) == SYM_MOD_CTRL
) {
273 strappend(str
,size
,"+");
274 strappend(str
,size
,"ctrl");
276 if ((bind
->mods
&SYM_MOD_ALT
) == SYM_MOD_ALT
) {
278 strappend(str
,size
,"+");
279 strappend(str
,size
,"alt");
281 if ((bind
->mods
&SYM_MOD_SHIFT
) == SYM_MOD_SHIFT
) {
283 strappend(str
,size
,"+");
284 strappend(str
,size
,"shift");
286 if ((bind
->mods
&SYM_MOD_SUPER
) == SYM_MOD_SUPER
) {
288 strappend(str
,size
,"+");
289 strappend(str
,size
,"super");
292 switch (bind
->sym
.type
) {
294 if (!utf8_fromutf32(buff
,6,bind
->sym
.ch
))
297 strappend(str
,size
,"+");
298 strappend(str
,size
,buff
);
301 switch (bind
->sym
.sym
) {
302 case MOUSE_BUTTON_LEFT
:
304 strappend(str
,size
,"+");
305 strappend(str
,size
,"mouse-left");
307 case MOUSE_BUTTON_CENTRE
:
309 strappend(str
,size
,"+");
310 strappend(str
,size
,"mouse-centre");
312 case MOUSE_BUTTON_RIGHT
:
314 strappend(str
,size
,"+");
315 strappend(str
,size
,"mouse-right");
317 case MOUSE_BUTTON_UP
:
319 strappend(str
,size
,"+");
320 strappend(str
,size
,"scroll-up");
322 case MOUSE_BUTTON_DOWN
:
324 strappend(str
,size
,"+");
325 strappend(str
,size
,"scroll-down");
329 strappend(str
,size
,"+");
330 strappend(str
,size
,"mouse-motion");
337 switch (bind
->sym
.sym
) {
340 strappend(str
,size
,"+");
341 strappend(str
,size
,"space");
345 strappend(str
,size
,"+");
346 strappend(str
,size
,"escape");
350 strappend(str
,size
,"+");
351 strappend(str
,size
,"tab");
355 strappend(str
,size
,"+");
356 strappend(str
,size
,"kp0");
360 strappend(str
,size
,"+");
361 strappend(str
,size
,"kp1");
365 strappend(str
,size
,"+");
366 strappend(str
,size
,"kp2");
370 strappend(str
,size
,"+");
371 strappend(str
,size
,"kp3");
375 strappend(str
,size
,"+");
376 strappend(str
,size
,"kp4");
380 strappend(str
,size
,"+");
381 strappend(str
,size
,"kp5");
385 strappend(str
,size
,"+");
386 strappend(str
,size
,"kp6");
390 strappend(str
,size
,"+");
391 strappend(str
,size
,"kp7");
395 strappend(str
,size
,"+");
396 strappend(str
,size
,"kp8");
400 strappend(str
,size
,"+");
401 strappend(str
,size
,"kp9");
405 strappend(str
,size
,"+");
406 strappend(str
,size
,"up");
410 strappend(str
,size
,"+");
411 strappend(str
,size
,"down");
415 strappend(str
,size
,"+");
416 strappend(str
,size
,"left");
420 strappend(str
,size
,"+");
421 strappend(str
,size
,"right");
425 strappend(str
,size
,"+");
426 strappend(str
,size
,"f1");
430 strappend(str
,size
,"+");
431 strappend(str
,size
,"f2");
435 strappend(str
,size
,"+");
436 strappend(str
,size
,"f3");
440 strappend(str
,size
,"+");
441 strappend(str
,size
,"f4");
445 strappend(str
,size
,"+");
446 strappend(str
,size
,"f5");
450 strappend(str
,size
,"+");
451 strappend(str
,size
,"f6");
455 strappend(str
,size
,"+");
456 strappend(str
,size
,"f7");
460 strappend(str
,size
,"+");
461 strappend(str
,size
,"f8");
465 strappend(str
,size
,"+");
466 strappend(str
,size
,"f9");
470 strappend(str
,size
,"+");
471 strappend(str
,size
,"f10");
475 strappend(str
,size
,"+");
476 strappend(str
,size
,"f11");
480 strappend(str
,size
,"+");
481 strappend(str
,size
,"f12");
496 /* check if two bindings match */
497 int kmap_equal(bind_t
*b1
, bind_t
*b2
)
501 if (b1
->sym
.type
!= b2
->sym
.type
)
503 if (b1
->sym
.sym
!= b2
->sym
.sym
)
505 if (b1
->mods
!= b2
->mods
)
510 /* does the event binding trigger the action binding? */
511 int kmap_triggers(bind_t
*eb
, bind_t
*ab
)
515 if (eb
->sym
.type
!= ab
->sym
.type
)
517 if (eb
->sym
.sym
!= ab
->sym
.sym
)
519 if ((eb
->mods
&ab
->mods
) != ab
->mods
)