1 ////////////////////////////////////////////////////////////////////////////////
8 static KeyTransDef
*keytrans
= NULL
;
9 static int keytrans_size
= 0;
10 static int keytrans_used
= 0;
21 static KeyInfoDef
*keybinds
= NULL
;
22 static int keybinds_size
= 0;
23 static int keybinds_used
= 0;
25 static KeyInfoDef
*keymap
= NULL
;
26 static int keymap_size
= 0;
27 static int keymap_used
= 0;
30 ////////////////////////////////////////////////////////////////////////////////
31 static void keytrans_reset (void) {
32 if (keytrans
) free(keytrans
);
39 static void keytrans_add (const char *src
, const char *dst
) {
40 KeySym kssrc
= XStringToKeysym(src
);
41 KeySym ksdst
= XStringToKeysym(dst
);
43 if (kssrc
== NoSymbol
) die("invalid keysym: '%s'", src
);
44 if (ksdst
== NoSymbol
) die("invalid keysym: '%s'", dst
);
45 if (kssrc
== ksdst
) return; // idiot
47 for (int f
= 0; f
< keytrans_used
; ++f
) {
48 if (keytrans
[f
].src
== kssrc
) {
50 keytrans
[f
].dst
= ksdst
;
55 if (keytrans_used
>= keytrans_size
) {
56 int newsize
= keytrans_size
+64;
57 KeyTransDef
*n
= realloc(keytrans
, sizeof(KeyTransDef
)*newsize
);
59 if (n
== NULL
) die("out of memory");
60 keytrans_size
= newsize
;
63 keytrans
[keytrans_used
].src
= kssrc
;
64 keytrans
[keytrans_used
].dst
= ksdst
;
69 ////////////////////////////////////////////////////////////////////////////////
70 static void parsekeyname (const char *str
, KeySym
*ks
, uint
*mask
, int *kp
) {
71 char *s
= alloca(strlen(str
)+1);
73 if (s
== NULL
) die("out of memory");
84 while (*s
&& isspace(*s
)) ++s
;
85 for (e
= s
; *e
&& !isspace(*e
) && *e
!= '+'; ++e
) ;
88 if (strcasecmp(s
, "alt") == 0) mm
= Mod1Mask
;
89 else if (strcasecmp(s
, "win") == 0) mm
= Mod4Mask
;
90 else if (strcasecmp(s
, "ctrl") == 0) mm
= ControlMask
;
91 else if (strcasecmp(s
, "shift") == 0) mm
= ShiftMask
;
92 else if (strcasecmp(s
, "any") == 0) mm
= XK_NO_MOD
; //!
93 else if (strcasecmp(s
, "kpad") == 0) *kp
= 1;
96 if ((*ks
= XStringToKeysym(s
)) == NoSymbol
) break;
97 //fprintf(stderr, "[%s]\n", s);
102 while (*s
&& isspace(*s
)) ++s
;
104 if (*s
!= '+') { *ks
= NoSymbol
; break; }
107 if (mm
== XK_NO_MOD
) *mask
= XK_ANY_MOD
;
108 else if (*mask
== XK_NO_MOD
) *mask
= mm
;
109 else if (*mask
!= XK_ANY_MOD
) *mask
|= mm
;
112 if (*s
) { *ks
= NoSymbol
; break; }
115 if (*ks
== NoSymbol
) die("invalid key name: '%s'", str
);
116 //fprintf(stderr, "mask=0x%08x, kp=%d\n", *mask, *kp);
120 ////////////////////////////////////////////////////////////////////////////////
121 static void keybinds_reset (void) {
122 if (keybinds
) free(keybinds
);
129 static void keybind_add (const char *key
, const char *act
) {
134 parsekeyname(key
, &ks
, &mask
, &kp
);
136 for (int f
= 0; f
< keybinds_used
; ++f
) {
137 if (keybinds
[f
].key
== ks
&& keybinds
[f
].mask
== mask
) {
139 free(keybinds
[f
].str
);
140 if (act
== NULL
|| !act
[0]) {
142 for (int c
= f
+1; c
< keybinds_used
; ++c
) keybinds
[c
-1] = keybinds
[c
];
145 if ((keybinds
[f
].str
= strdup(act
)) == NULL
) die("out of memory");
151 if (keybinds_used
>= keybinds_size
) {
152 int newsize
= keybinds_size
+64;
153 KeyInfoDef
*n
= realloc(keybinds
, sizeof(KeyInfoDef
)*newsize
);
155 if (n
== NULL
) die("out of memory");
156 keybinds_size
= newsize
;
159 keybinds
[keybinds_used
].key
= ks
;
160 keybinds
[keybinds_used
].mask
= mask
;
161 keybinds
[keybinds_used
].kp
= 0;
162 if ((keybinds
[keybinds_used
].str
= strdup(act
)) == NULL
) die("out of memory");
167 ////////////////////////////////////////////////////////////////////////////////
168 static void keymap_reset (void) {
169 if (keymap
) free(keymap
);
176 static void keymap_add (const char *key
, const char *act
) {
181 parsekeyname(key
, &ks
, &mask
, &kp
);
183 for (int f
= 0; f
< keymap_used
; ++f
) {
184 if (keymap
[f
].key
== ks
&& keymap
[f
].mask
== mask
&& keymap
[f
].kp
== kp
) {
189 for (int c
= f
+1; c
< keymap_used
; ++c
) keymap
[c
-1] = keymap
[c
];
192 if ((keymap
[f
].str
= strdup(act
)) == NULL
) die("out of memory");
198 if (keymap_used
>= keymap_size
) {
199 int newsize
= keymap_size
+128;
200 KeyInfoDef
*n
= realloc(keymap
, sizeof(KeyInfoDef
)*newsize
);
202 if (n
== NULL
) die("out of memory");
203 keymap_size
= newsize
;
206 keymap
[keymap_used
].key
= ks
;
207 keymap
[keymap_used
].mask
= mask
;
208 keymap
[keymap_used
].kp
= kp
;
209 if ((keymap
[keymap_used
].str
= strdup(act
)) == NULL
) die("out of memory");