1 /*======================================================================*\
2 |* Editor mined *|
3 |* keyboard mapping tables *|
4 \*======================================================================*/
5
6 #include "mined.h"
7 #include "termprop.h"
8
9
10 #if defined (msdos)
11 #define noCJKkeymaps
12 #endif
13
14
15 #define use_CJKkeymaps
16
17 #if defined (noCJKkeymaps) || defined (NOCJK)
18 #undef use_CJKkeymaps
19 #endif
20
21
22 /*======================================================================*\
23 |* Keyboard mapping tables format and type *|
24 \*======================================================================*/
25
26 #ifndef NOSTRINGTABLES
27 #define keymapping_stringtables
28 #endif
29
30
31 #ifdef keymapping_stringtables
32 #define keymaptableelem char
33 #else
34 #define keymaptableelem struct keymap
35 struct keymap {
36 char * fk;
37 char * fp;
38 };
39 #endif
40 #define keymaptabletype keymaptableelem *
41
42
43 struct keymapping {
44 keymaptabletype table;
45 char * shortcut;
46 };
47
48
49 /*======================================================================*\
50 |* Keyboard mapping tables *|
51 \*======================================================================*/
52
53 #define use_keymap_tables
54
55
56 #ifdef use_keymap_tables
57
58 #ifndef use_concatenated_keymaps
59 #define use_concatenated_keymaps
60 #endif
61
62 #define no_extern_keymap_tables
63
64 #ifdef extern_keymap_tables
65
66 # include "keymapsx.h"
67 # ifdef keymapping_stringtables
68 /* link with keymaps1/*.o */
69 # else
70 /* link with keymaps0/*.o from keymaps0/*.h */
71 # endif
72
73 #else
74
75 # ifdef keymapping_stringtables
76 # ifdef use_concatenated_keymaps
77 # include "keymaps.t"
78 # else
79 # include "keymapsc.h"
80 /* #includes keymaps1/*.c, link with -Ikeymaps1 */
81 # endif
82 # else
83 # include "keymapsi.h"
84 /* #includes keymaps0/*.h, link with -Ikeymaps0 */
85 # endif
86
87 #endif
88
89 #endif
90
91
92 /*======================================================================*\
93 |* Table of tables *|
94 \*======================================================================*/
95
96 static struct keymapping keymappingtable [] = {
97 # ifdef use_keymap_tables
98 # include "keymapsk.t"
99 # else
100 {0, "--"}, /* some compilers don't like empty arrays */
101 # endif
102 };
103
104 static unsigned int keymappingtable_len = arrlen (keymappingtable);
105
106
107 /*======================================================================*\
108 |* Input method switching *|
109 \*======================================================================*/
110
111 char * keyboard_mapping = "--";
112 char * last_keyboard_mapping = "--";
113 static char * next_keyboard_mapping = "";
114
115 static keymaptabletype keyboard_map = (keymaptabletype) NIL_PTR;
116 static keymaptabletype last_keyboard_map = (keymaptabletype) NIL_PTR;
117
118 /**
119 Notify user of changed input method
120 */
121 static
122 void
notify_input_method()123 notify_input_method ()
124 {
125 menuitemtype * km = lookup_Keymap_menuitem (keyboard_mapping);
126 char * source = NIL_PTR;
127
128 switch (km->extratag ? km->extratag [0] : ' ') {
129 case 'U': source = "UnicodeData"; break;
130 case 'H': source = "Unihan"; break;
131 case 'C': source = "cxterm"; break;
132 case 'M': source = "m17n"; break;
133 case 'Y': source = "yudit"; break;
134 case 'V': source = "vim"; break;
135 case 'X': source = "X"; break;
136 }
137 if (source) {
138 build_string (text_buffer, "Input method: %s (source: %s)",
139 km->itemname, source);
140 } else {
141 build_string (text_buffer, "Input method: %s", km->itemname);
142 }
143 status_uni (text_buffer);
144 }
145
146 /**
147 Set keymap.
148 */
149 static
150 void
set_keymap(new_keymap,current,next)151 set_keymap (new_keymap, current, next)
152 keymaptabletype new_keymap;
153 char * current;
154 char * next;
155 {
156 last_keyboard_map = keyboard_map;
157 last_keyboard_mapping = keyboard_mapping;
158 keyboard_map = new_keymap;
159 keyboard_mapping = current;
160 next_keyboard_mapping = next;
161
162 if (! loading && ! stat_visible && ! input_active) {
163 notify_input_method ();
164 }
165 }
166
167 /**
168 Exchange current and previous keyboard mapping; set previous active.
169 With HOP, reset keyboard mapping to none.
170 */
171 void
toggleKEYMAP()172 toggleKEYMAP ()
173 {
174 if (allow_keymap) {
175 if (hop_flag > 0) {
176 set_keymap ((keymaptabletype) NIL_PTR, "--", keymappingtable [0].shortcut);
177 } else {
178 set_keymap (last_keyboard_map, last_keyboard_mapping, last_keyboard_mapping);
179 }
180 flags_changed = True;
181 } else {
182 error ("Keyboard mapping not active");
183 }
184 }
185
186 /**
187 Set keyboard mapping.
188 */
189 static
190 FLAG
selectKEYMAP(script)191 selectKEYMAP (script)
192 char * script;
193 {
194 if (script == NIL_PTR || * script == '\0') {
195 set_keymap ((keymaptabletype) NIL_PTR, "--", keymappingtable [0].shortcut);
196 flags_changed = True;
197 return True;
198 } else {
199 /* map alternative shortcuts */
200 int i;
201 if (strisprefix ("el", script)) {
202 script = "gr";
203 } else if (strisprefix ("ru", script)) {
204 script = "cy";
205 }
206 /* map shortcut to keymap */
207 for (i = 0; i < keymappingtable_len; i ++) {
208 if (strisprefix (keymappingtable [i].shortcut, script)) {
209 set_keymap (keymappingtable [i].table,
210 keymappingtable [i].shortcut,
211 i + 1 == keymappingtable_len ?
212 "" : keymappingtable [i + 1].shortcut);
213 flags_changed = True;
214 return True;
215 }
216 }
217 return False;
218 }
219 }
220
221 /**
222 Set keyboard mapping.
223 */
224 FLAG
setKEYMAP(script)225 setKEYMAP (script)
226 char * script;
227 {
228 if (script != NIL_PTR && * script == '-') {
229 /* set keymap as secondary map */
230 script ++;
231 (void) selectKEYMAP (script);
232 (void) selectKEYMAP (NIL_PTR);
233 } else if (script != NIL_PTR) {
234 char * secondary = strchr (script, '-');
235 if (secondary != NIL_PTR) {
236 secondary ++;
237 (void) selectKEYMAP (secondary);
238 }
239 return selectKEYMAP (script);
240 }
241 return True;
242 }
243
244 #ifdef not_used
245 /**
246 Cycle through keyboard mappings.
247 */
248 void
cycleKEYMAP()249 cycleKEYMAP ()
250 {
251 (void) selectKEYMAP (next_keyboard_mapping);
252 }
253 #endif
254
255 /**
256 Enable keyboard mapping interactively.
257 With HOP, cycle through keyboard mappings.
258 */
259 void
setupKEYMAP()260 setupKEYMAP ()
261 {
262 if (allow_keymap) {
263 if (hop_flag > 0) {
264 hop_flag = 0;
265 (void) selectKEYMAP (next_keyboard_mapping);
266 } else {
267 handleKeymapmenu ();
268 }
269 } else {
270 error ("Keyboard mapping not active");
271 }
272 }
273
274
275 /*======================================================================*\
276 |* Key mapping lookup *|
277 \*======================================================================*/
278
279 /*
280 Look up key sequence in keyboard mapping table.
281 Similar to findkeyin but with modified parameter details.
282 * if matchmode == 0 (not used):
283 * mapkb (str) >= 0: key sequence str found
284 * * mapped set to mapped string
285 * == -1: key sequence prefix recognised
286 * (str is prefix of some table entry)
287 * == -2: key sequence not found
288 * (str is not contained in table)
289 * * found == index of exact match if found
290 * if matchmode == 1:
291 * return -1 if any prefix detected (even if other exact match found)
292 * if matchmode == 2:
293 * don't return -1, only report exact or no match
294 */
295 static
296 int
mapkb(str,kbmap,matchmode,found,mapped)297 mapkb (str, kbmap, matchmode, found, mapped)
298 char * str;
299 keymaptabletype kbmap;
300 int matchmode;
301 char * * found;
302 char * * mapped;
303 {
304 #ifdef keymapping_stringtables
305
306 int lastmatch = 0; /* last index with string matching prefix */
307 register int i;
308 int ret = -2;
309 int len = strlen (str);
310
311 * found = NIL_PTR;
312
313 if (* kbmap == '\0') {
314 return ret;
315 }
316
317 i = lastmatch;
318 do {
319 if (strncmp (str, kbmap, len) == 0) {
320 /* str is prefix of current entry */
321 lastmatch = i;
322 if (len == strlen (kbmap)) {
323 /* str is equal to current entry */
324 * found = kbmap;
325 * mapped = kbmap + len + 1;
326 if (matchmode == 1) {
327 /* return index unless other prefix
328 was or will be found */
329 if (ret == -2) {
330 ret = i;
331 }
332 } else {
333 return i;
334 }
335 } else {
336 /* str is partial prefix of current entry */
337 if (matchmode == 1) {
338 /* return -1 but continue to search
339 for exact match */
340 ret = -1;
341 } else if (matchmode != 2) {
342 return -1;
343 } else {
344 }
345 }
346 }
347 ++ i;
348 kbmap += strlen (kbmap) + 1;
349 kbmap += strlen (kbmap) + 1;
350 if (* kbmap == '\0') {
351 i = 0;
352 return ret;
353 }
354 } while (i != lastmatch);
355
356 return ret;
357
358 #else
359
360 int lastmatch = 0; /* last index with string matching prefix */
361 register int i;
362 int ret = -2;
363
364 * found = NIL_PTR;
365
366 if (kbmap [0].fk == NIL_PTR) {
367 return ret;
368 }
369
370 i = lastmatch;
371 do {
372 if (strncmp (str, kbmap [i].fk, strlen (str)) == 0) {
373 /* str is prefix of current entry */
374 lastmatch = i;
375 if (strlen (str) == strlen (kbmap [i].fk)) {
376 /* str is equal to current entry */
377 * found = kbmap [i].fk;
378 * mapped = kbmap [i].fp;
379 if (! * mapped) {
380 /* fix missing mapping in keyboard mapping table */
381 * mapped = "";
382 }
383 if (matchmode == 1) {
384 /* return index unless other prefix
385 was or will be found */
386 if (ret == -2) {
387 ret = i;
388 }
389 } else {
390 return i;
391 }
392 } else {
393 /* str is partial prefix of current entry */
394 if (matchmode == 1) {
395 /* return -1 but continue to search
396 for exact match */
397 ret = -1;
398 } else if (matchmode != 2) {
399 return -1;
400 } else {
401 }
402 }
403 }
404 ++ i;
405 if (kbmap [i].fk == NIL_PTR) {
406 i = 0;
407 return ret;
408 }
409 } while (i != lastmatch);
410
411 return ret;
412
413 #endif
414 }
415
416 int
map_key(str,matchmode,found,mapped)417 map_key (str, matchmode, found, mapped)
418 char * str;
419 int matchmode;
420 char * * found;
421 char * * mapped;
422 {
423 return mapkb (str, keyboard_map, matchmode, found, mapped);
424 }
425
426 int
keyboard_mapping_active()427 keyboard_mapping_active ()
428 {
429 return keyboard_map != (keymaptabletype) NIL_PTR;
430 }
431
432
433 /*======================================================================*\
434 |* End *|
435 \*======================================================================*/
436