more fixes to 1049
[k8sterm.git] / src / keymaps.c
blob56b25584de56dff2f268f2d464f2a53b7ae07c8a
1 ////////////////////////////////////////////////////////////////////////////////
2 typedef struct {
3 KeySym src;
4 KeySym dst;
5 } KeyTransDef;
8 static KeyTransDef *keytrans = NULL;
9 static int keytrans_size = 0;
10 static int keytrans_used = 0;
13 typedef struct {
14 KeySym key;
15 uint32_t mask;
16 int kp;
17 char *str;
18 } KeyInfoDef;
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);
33 keytrans = NULL;
34 keytrans_size = 0;
35 keytrans_used = 0;
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) k8t_die("invalid keysym: '%s'", src);
44 if (ksdst == NoSymbol) k8t_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) {
49 // replace
50 keytrans[f].dst = ksdst;
51 return;
55 if (keytrans_used >= keytrans_size) {
56 int newsize = keytrans_size+64;
57 KeyTransDef *n = realloc(keytrans, sizeof(KeyTransDef)*newsize);
59 if (n == NULL) k8t_die("out of memory");
60 keytrans_size = newsize;
61 keytrans = n;
63 keytrans[keytrans_used].src = kssrc;
64 keytrans[keytrans_used].dst = ksdst;
65 ++keytrans_used;
69 ////////////////////////////////////////////////////////////////////////////////
70 static void parsekeyname (const char *str, KeySym *ks, uint32_t *mask, int *kp) {
71 char *s = alloca(strlen(str)+1);
73 if (s == NULL) k8t_die("out of memory");
74 strcpy(s, str);
75 *kp = 0;
76 *ks = NoSymbol;
77 *mask = XK_NO_MOD;
79 while (*s) {
80 char *e, oc;
81 uint32_t mm = 0;
82 int mod = 1;
84 while (*s && isspace(*s)) ++s;
85 for (e = s; *e && !isspace(*e) && *e != '+'; ++e) ;
86 oc = *e; *e = 0;
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;
94 else {
95 mod = 0;
96 if ((*ks = XStringToKeysym(s)) == NoSymbol) break;
97 //fprintf(stderr, "[%s]\n", s);
100 *e = oc;
101 s = e;
102 while (*s && isspace(*s)) ++s;
103 if (mod) {
104 if (*s != '+') { *ks = NoSymbol; break; }
105 ++s;
106 if (mm != 0) {
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;
111 } else {
112 if (*s) { *ks = NoSymbol; break; }
115 if (*ks == NoSymbol) k8t_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);
123 keybinds = NULL;
124 keybinds_size = 0;
125 keybinds_used = 0;
129 static void keybind_add (const char *key, const char *act) {
130 KeySym ks;
131 uint32_t mask;
132 int kp;
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) {
138 // replace or remove
139 free(keybinds[f].str);
140 if (act == NULL || !act[0]) {
141 // remove
142 for (int c = f+1; c < keybinds_used; ++c) keybinds[c-1] = keybinds[c];
143 } else {
144 // replace
145 if ((keybinds[f].str = strdup(act)) == NULL) k8t_die("out of memory");
147 return;
151 if (keybinds_used >= keybinds_size) {
152 int newsize = keybinds_size+64;
153 KeyInfoDef *n = realloc(keybinds, sizeof(KeyInfoDef)*newsize);
155 if (n == NULL) k8t_die("out of memory");
156 keybinds_size = newsize;
157 keybinds = n;
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) k8t_die("out of memory");
163 ++keybinds_used;
167 ////////////////////////////////////////////////////////////////////////////////
168 static void keymap_reset (void) {
169 if (keymap) free(keymap);
170 keymap = NULL;
171 keymap_size = 0;
172 keymap_used = 0;
176 static void keymap_add (const char *key, const char *act) {
177 KeySym ks;
178 uint32_t mask;
179 int kp;
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) {
185 // replace or remove
186 free(keymap[f].str);
187 if (act == NULL) {
188 // remove
189 for (int c = f+1; c < keymap_used; ++c) keymap[c-1] = keymap[c];
190 } else {
191 // replace
192 if ((keymap[f].str = strdup(act)) == NULL) k8t_die("out of memory");
194 return;
198 if (keymap_used >= keymap_size) {
199 int newsize = keymap_size+128;
200 KeyInfoDef *n = realloc(keymap, sizeof(KeyInfoDef)*newsize);
202 if (n == NULL) k8t_die("out of memory");
203 keymap_size = newsize;
204 keymap = n;
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) k8t_die("out of memory");
210 ++keymap_used;