1 /* $Id: keyboard.c,v 1.37 2018/07/26 00:22:47 tom Exp $ */
2
3 #include <vttest.h>
4 #include <ttymodes.h>
5 #include <esc.h>
6
7 /* Test of:
8 - DECLL (Load LEDs)
9 - Keyboard return messages
10 - SM RM (Set/Reset Mode) - Cursor Keys
11 - Auto repeat
12 - DECKPAM (Keypad Application Mode)
13 - DECKPNM (Keypad Numeric Mode)
14
15 The standard VT100 keyboard layout:
16
17 UP DN LE RI
18
19 ESC 1! 2@ 3# 4$ 5% 6^ 7& 8* 9( 0) -_ =+ `~ BS
20
21 TAB* qQ wW eE rR tT yY uU iI oO pP [{ ]} DEL
22
23 ** ** aA sS dD fF gG hH jJ kK lL ;: ," RETN \|
24
25 ** **** zZ xX cC vV bB nN mM ,< .> /? **** LF
26
27 ****************SPACE BAR****************
28
29 PF1 PF2 PF3 PF4
30
31 *7* *8* *9* *-*
32
33 *4* *5* *6* *,*
34
35 *1* *2* *3*
36
37 ***0*** *.* ENT
38
39 The standard LK401 (VT420) keyboard layout:
40
41 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 Help Do F17 F18 F19 F20
42
43 `~ 1! 2@ 3# 4$ 5% 6^ 7& 8* 9( 0) -_ =+ DEL
44
45 TAB* qQ wW eE rR tT yY uU iI oO pP [{ ]} Return
46
47 ** ** aA sS dD fF gG hH jJ kK lL ;: ," \|
48
49 ***** <> zZ xX cC vV bB nN mM ,< .> /? ******
50
51 ***** ***** ****************SPACE BAR**************** ****** ******
52
53 Find Insert Remove PF1 PF2 PF3 PF4
54
55 Select Prev Next *7* *8* *9* *-*
56
57 Up *4* *5* *6* *,*
58
59 Left Down Right *1* *2* *3*
60
61 ***0*** *.* ENT
62 */
63 /* *INDENT-OFF* */
64 static struct key {
65 char c;
66 int row;
67 int col;
68 const char *symbol;
69 } VT100_keytab [] = {
70 { ESC, 1, 0, "ESC" },
71 { '1', 1, 6, "1" }, { '!', 1, 7, "!" },
72 { '2', 1, 11, "2" }, { '@', 1, 12, "@" },
73 { '3', 1, 16, "3" }, { '#', 1, 17, "#" },
74 { '4', 1, 21, "4" }, { '$', 1, 22, "$" },
75 { '5', 1, 26, "5" }, { '%', 1, 27, "%" },
76 { '6', 1, 31, "6" }, { '^', 1, 32, "^" },
77 { '7', 1, 36, "7" }, { '&', 1, 37, "&" },
78 { '8', 1, 41, "8" }, { '*', 1, 42, "*" },
79 { '9', 1, 46, "9" }, { '(', 1, 47, "(" },
80 { '0', 1, 51, "0" }, { ')', 1, 52, ")" },
81 { '-', 1, 56, "-" }, { '_', 1, 57, "_" },
82 { '=', 1, 61, "=" }, { '+', 1, 62, "+" },
83 { '`', 1, 66, "`" }, { '~', 1, 67, "~" },
84 { 8, 1, 70, "BS" },
85 { 9, 2, 0, " TAB " },
86 { 'q', 2, 8, "q" }, { 'Q', 2, 9, "Q" },
87 { 'w', 2, 13, "w" }, { 'W', 2, 14, "W" },
88 { 'e', 2, 18, "e" }, { 'E', 2, 19, "E" },
89 { 'r', 2, 23, "r" }, { 'R', 2, 24, "R" },
90 { 't', 2, 28, "t" }, { 'T', 2, 29, "T" },
91 { 'y', 2, 33, "y" }, { 'Y', 2, 34, "Y" },
92 { 'u', 2, 38, "u" }, { 'U', 2, 39, "U" },
93 { 'i', 2, 43, "i" }, { 'I', 2, 44, "I" },
94 { 'o', 2, 48, "o" }, { 'O', 2, 49, "O" },
95 { 'p', 2, 53, "p" }, { 'P', 2, 54, "P" },
96 { '[', 2, 58, "[" }, { '{', 2, 59, "{" },
97 { ']', 2, 63, "]" }, { '}', 2, 64, "}" },
98 { 127, 2, 71, "DEL" },
99 { 'a', 3, 10, "a" }, { 'A', 3, 11, "A" },
100 { 's', 3, 15, "s" }, { 'S', 3, 16, "S" },
101 { 'd', 3, 20, "d" }, { 'D', 3, 21, "D" },
102 { 'f', 3, 25, "f" }, { 'F', 3, 26, "F" },
103 { 'g', 3, 30, "g" }, { 'G', 3, 31, "G" },
104 { 'h', 3, 35, "h" }, { 'H', 3, 36, "H" },
105 { 'j', 3, 40, "j" }, { 'J', 3, 41, "J" },
106 { 'k', 3, 45, "k" }, { 'K', 3, 46, "K" },
107 { 'l', 3, 50, "l" }, { 'L', 3, 51, "L" },
108 { ';', 3, 55, ";" }, { ':', 3, 56, ":" },
109 {'\'', 3, 60, "'" }, { '"', 3, 61,"\"" },
110 { 13, 3, 65, "RETN"},
111 {'\\', 3, 71,"\\" }, { '|', 3, 72, "|" },
112 { 'z', 4, 12, "z" }, { 'Z', 4, 13, "Z" },
113 { 'x', 4, 17, "x" }, { 'X', 4, 18, "X" },
114 { 'c', 4, 22, "c" }, { 'C', 4, 23, "C" },
115 { 'v', 4, 27, "v" }, { 'V', 4, 28, "V" },
116 { 'b', 4, 32, "b" }, { 'B', 4, 33, "B" },
117 { 'n', 4, 37, "n" }, { 'N', 4, 38, "N" },
118 { 'm', 4, 42, "m" }, { 'M', 4, 43, "M" },
119 { ',', 4, 47, "," }, { '<', 4, 48, "<" },
120 { '.', 4, 52, "." }, { '>', 4, 53, ">" },
121 { '/', 4, 57, "/" }, { '?', 4, 58, "?" },
122 { 10, 4, 69, "LF" },
123 { ' ', 5, 13, " SPACE BAR "},
124 {'\0', 0, 0, "" }
125 },
126 LK401_keytab [] = {
127 { '`', 1, 3, "`" }, { '~', 1, 4, "~" },
128 { '1', 1, 7, "1" }, { '!', 1, 8, "!" },
129 { '2', 1, 12, "2" }, { '@', 1, 13, "@" },
130 { '3', 1, 17, "3" }, { '#', 1, 18, "#" },
131 { '4', 1, 22, "4" }, { '$', 1, 23, "$" },
132 { '5', 1, 27, "5" }, { '%', 1, 28, "%" },
133 { '6', 1, 32, "6" }, { '^', 1, 33, "^" },
134 { '7', 1, 37, "7" }, { '&', 1, 38, "&" },
135 { '8', 1, 42, "8" }, { '*', 1, 43, "*" },
136 { '9', 1, 47, "9" }, { '(', 1, 48, "(" },
137 { '0', 1, 52, "0" }, { ')', 1, 53, ")" },
138 { '-', 1, 57, "-" }, { '_', 1, 58, "_" },
139 { '=', 1, 62, "=" }, { '+', 1, 63, "+" },
140 { 127, 1, 67, "DEL" },
141 { 9, 2, 0, "TAB " },
142 { 'q', 2, 9, "q" }, { 'Q', 2, 10, "Q" },
143 { 'w', 2, 14, "w" }, { 'W', 2, 15, "W" },
144 { 'e', 2, 19, "e" }, { 'E', 2, 20, "E" },
145 { 'r', 2, 24, "r" }, { 'R', 2, 25, "R" },
146 { 't', 2, 29, "t" }, { 'T', 2, 30, "T" },
147 { 'y', 2, 34, "y" }, { 'Y', 2, 35, "Y" },
148 { 'u', 2, 39, "u" }, { 'U', 2, 40, "U" },
149 { 'i', 2, 44, "i" }, { 'I', 2, 45, "I" },
150 { 'o', 2, 49, "o" }, { 'O', 2, 50, "O" },
151 { 'p', 2, 54, "p" }, { 'P', 2, 55, "P" },
152 { '[', 2, 59, "[" }, { '{', 2, 60, "{" },
153 { ']', 2, 64, "]" }, { '}', 2, 65, "}" },
154 { 13, 2, 69, "Return" },
155 { 'a', 3, 11, "a" }, { 'A', 3, 12, "A" },
156 { 's', 3, 16, "s" }, { 'S', 3, 17, "S" },
157 { 'd', 3, 21, "d" }, { 'D', 3, 22, "D" },
158 { 'f', 3, 26, "f" }, { 'F', 3, 27, "F" },
159 { 'g', 3, 31, "g" }, { 'G', 3, 32, "G" },
160 { 'h', 3, 36, "h" }, { 'H', 3, 37, "H" },
161 { 'j', 3, 41, "j" }, { 'J', 3, 42, "J" },
162 { 'k', 3, 46, "k" }, { 'K', 3, 47, "K" },
163 { 'l', 3, 51, "l" }, { 'L', 3, 52, "L" },
164 { ';', 3, 56, ";" }, { ':', 3, 57, ":" },
165 {'\'', 3, 61, "'" }, { '"', 3, 62,"\"" },
166 {'\\', 3, 66,"\\" }, { '|', 3, 67, "|" },
167 { '<', 4, 9, "<" }, { '>', 4, 10, ">" },
168 { 'z', 4, 13, "z" }, { 'Z', 4, 14, "Z" },
169 { 'x', 4, 18, "x" }, { 'X', 4, 19, "X" },
170 { 'c', 4, 23, "c" }, { 'C', 4, 24, "C" },
171 { 'v', 4, 28, "v" }, { 'V', 4, 29, "V" },
172 { 'b', 4, 33, "b" }, { 'B', 4, 34, "B" },
173 { 'n', 4, 38, "n" }, { 'N', 4, 39, "N" },
174 { 'm', 4, 43, "m" }, { 'M', 4, 44, "M" },
175 { ',', 4, 48, "," }, { '<', 4, 49, "<" },
176 { '.', 4, 53, "." }, { '>', 4, 54, ">" },
177 { '/', 4, 58, "/" }, { '?', 4, 59, "?" },
178 { ' ', 5, 14, " SPACE BAR "},
179 {'\0', 0, 0, "" }
180 },
181 *keytab;
182 /* *INDENT-ON* */
183
184 typedef struct {
185 unsigned char prefix;
186 const char *msg;
187 } CTLKEY;
188 /* *INDENT-OFF* */
189 static struct curkey {
190 CTLKEY curkeymsg[3];
191 int curkeyrow;
192 int curkeycol;
193 const char *curkeysymbol;
194 const char *curkeyname;
195 } VT100_curkeytab [] = {
196
197 /* A Reset, A Set, VT52 */
198
199 {{{CSI,"A"}, {SS3,"A"}, {ESC,"A"}}, 0, 56, "UP", "Up arrow" },
200 {{{CSI,"B"}, {SS3,"B"}, {ESC,"B"}}, 0, 61, "DN", "Down arrow" },
201 {{{CSI,"D"}, {SS3,"D"}, {ESC,"D"}}, 0, 66, "LT", "Left arrow" },
202 {{{CSI,"C"}, {SS3,"C"}, {ESC,"C"}}, 0, 71, "RT", "Right arrow"},
203 {{{0, ""}, {0, ""}, {0, "" }}, 0, 0, "", "" }
204 },
205 LK401_curkeytab [] = {
206
207 /* A Reset, A Set, VT52 */
208
209 {{{CSI,"A"}, {SS3,"A"}, {ESC,"A"}}, 8, 32, "Up", "Up arrow" },
210 {{{CSI,"B"}, {SS3,"B"}, {ESC,"B"}}, 9, 31, "Down", "Down arrow" },
211 {{{CSI,"D"}, {SS3,"D"}, {ESC,"D"}}, 9, 24, "Left", "Left arrow" },
212 {{{CSI,"C"}, {SS3,"C"}, {ESC,"C"}}, 9, 38, "Right", "Right arrow"},
213 {{{0, ""}, {0, ""}, {0, "" }}, 0, 0, "", "" }
214 },
215 *curkeytab;
216 static struct fnckey {
217 CTLKEY fnkeymsg[2];
218 int fnkeyrow;
219 int fnkeycol;
220 const char *fnkeysymbol;
221 const char *fnkeyname;
222 } fnkeytab [] = {
223
224 /* Normal, VT100/VT52 */
225 {{{CSI,"11~"}, {0,""}}, 0, 1, "F1", "F1 (xterm)" },
226 {{{CSI,"12~"}, {0,""}}, 0, 4, "F2", "F2 (xterm)" },
227 {{{CSI,"13~"}, {0,""}}, 0, 7, "F3", "F3 (xterm)" },
228 {{{CSI,"14~"}, {0,""}}, 0, 10, "F4", "F4 (xterm)" },
229 {{{CSI,"15~"}, {0,""}}, 0, 13, "F5", "F5 (xterm)" },
230
231 {{{CSI,"17~"}, {0,""}}, 0, 18, "F6", "F6" },
232 {{{CSI,"18~"}, {0,""}}, 0, 21, "F7", "F7" },
233 {{{CSI,"19~"}, {0,""}}, 0, 24, "F8", "F8" },
234 {{{CSI,"20~"}, {0,""}}, 0, 27, "F9", "F9" },
235 {{{CSI,"21~"}, {0,""}}, 0, 30, "F10", "F10" },
236 {{{CSI,"23~"}, {0,""}}, 0, 36, "F11", "F11" },
237 {{{CSI,"24~"}, {0,""}}, 0, 40, "F12", "F12" },
238 {{{CSI,"25~"}, {0,""}}, 0, 44, "F13", "F13" },
239 {{{CSI,"26~"}, {0,""}}, 0, 48, "F14", "F14" },
240 {{{CSI,"28~"}, {0,""}}, 0, 54, "Help", "Help (F15)" },
241 {{{CSI,"29~"}, {0,""}}, 0, 59, "Do", "Do (F16)" },
242 {{{CSI,"31~"}, {0,""}}, 0, 64, "F17", "F17" },
243 {{{CSI,"32~"}, {0,""}}, 0, 68, "F18", "F18" },
244 {{{CSI,"33~"}, {0,""}}, 0, 72, "F19", "F19" },
245 {{{CSI,"34~"}, {0,""}}, 0, 76, "F20", "F20" },
246 {{{0, ""}, {0,"" }}, 0, 0, "", "" }
247 },
248 edt_keypadtab[] = {
249 {{{CSI,"1~"}, {0,""}}, 6, 24, "Find" , "Find" },
250 {{{CSI,"2~"}, {0,""}}, 6, 30, "Insert", "Insert Here" },
251 {{{CSI,"3~"}, {0,""}}, 6, 37, "Remove", "Remove" },
252 {{{CSI,"4~"}, {0,""}}, 7, 23, "Select", "Select" },
253 {{{CSI,"5~"}, {0,""}}, 7, 31, "Prev", "Prev" },
254 {{{CSI,"6~"}, {0,""}}, 7, 38, "Next", "Next" },
255 {{{0, ""}, {0,""}}, 0, 0, "", "" }
256 };
257 static struct fnkey {
258 CTLKEY fnkeymsg[4];
259 int fnkeyrow;
260 int fnkeycol;
261 const char *fnkeysymbol;
262 const char *fnkeyname;
263 } num_keypadtab [] = {
264
265 /* ANSI-num, ANSI-app, VT52-nu, VT52-ap, r, c, symb name */
266
267 {{{SS3,"P"}, {SS3,"P"}, {ESC,"P"}, {ESC,"P" }}, 6, 59, "PF1", "PF1" },
268 {{{SS3,"Q"}, {SS3,"Q"}, {ESC,"Q"}, {ESC,"Q" }}, 6, 63, "PF2", "PF2" },
269 {{{SS3,"R"}, {SS3,"R"}, {ESC,"R"}, {ESC,"R" }}, 6, 67, "PF3", "PF3" },
270 {{{SS3,"S"}, {SS3,"S"}, {ESC,"S"}, {ESC,"S" }}, 6, 71, "PF4", "PF4" },
271 {{{0, "7"}, {SS3,"w"}, {0, "7"}, {ESC,"?w"}}, 7, 59, " 7 ", "Numeric 7" },
272 {{{0, "8"}, {SS3,"x"}, {0, "8"}, {ESC,"?x"}}, 7, 63, " 8 ", "Numeric 8" },
273 {{{0, "9"}, {SS3,"y"}, {0, "9"}, {ESC,"?y"}}, 7, 67, " 9 ", "Numeric 9" },
274 {{{0, "-"}, {SS3,"m"}, {0, "-"}, {ESC,"?m"}}, 7, 71, " - ", "Minus" },
275 {{{0, "4"}, {SS3,"t"}, {0, "4"}, {ESC,"?t"}}, 8, 59, " 4 ", "Numeric 4" },
276 {{{0, "5"}, {SS3,"u"}, {0, "5"}, {ESC,"?u"}}, 8, 63, " 5 ", "Numeric 5" },
277 {{{0, "6"}, {SS3,"v"}, {0, "6"}, {ESC,"?v"}}, 8, 67, " 6 ", "Numeric 6" },
278 {{{0, ","}, {SS3,"l"}, {0, ","}, {ESC,"?l"}}, 8, 71, " , ", "Comma" },
279 {{{0, "1"}, {SS3,"q"}, {0, "1"}, {ESC,"?q"}}, 9, 59, " 1 ", "Numeric 1" },
280 {{{0, "2"}, {SS3,"r"}, {0, "2"}, {ESC,"?r"}}, 9, 63, " 2 ", "Numeric 2" },
281 {{{0, "3"}, {SS3,"s"}, {0, "3"}, {ESC,"?s"}}, 9, 67, " 3 ", "Numeric 3" },
282 {{{0, "0"}, {SS3,"p"}, {0, "0"}, {ESC,"?p"}},10, 59, " 0 ","Numeric 0"},
283 {{{0, "."}, {SS3,"n"}, {0, "."}, {ESC,"?n"}},10, 67, " . ", "Point" },
284 {{{0,"\015"},{SS3,"M"}, {0,"\015"},{ESC,"?M"}},10, 71, "ENT", "ENTER" },
285 {{{0, ""}, {0, ""}, {0, ""}, {0, ""}}, 0, 0, "", "" }
286 };
287 /* *INDENT-ON* */
288
289 struct natkey {
290 char natc;
291 int natrow;
292 int natcol;
293 const char *natsymbol;
294 };
295
296 static int same_CTLKEY(const char *response, CTLKEY *code);
297
298 static int
find_cursor_key(char * curkeystr,int ckeymode)299 find_cursor_key(char *curkeystr, int ckeymode)
300 {
301 int i;
302
303 for (i = 0; curkeytab[i].curkeysymbol[0] != '\0'; i++) {
304 if (same_CTLKEY(curkeystr, &curkeytab[i].curkeymsg[ckeymode])) {
305 return i;
306 }
307 }
308 return -1;
309 }
310
311 static int
find_editing_key(char * keypadstr,int fkeymode)312 find_editing_key(char *keypadstr, int fkeymode)
313 {
314 int i;
315
316 for (i = 0; edt_keypadtab[i].fnkeysymbol[0] != '\0'; i++) {
317 if (same_CTLKEY(keypadstr, &edt_keypadtab[i].fnkeymsg[fkeymode])) {
318 return i;
319 }
320 }
321 return -1;
322 }
323
324 static int
find_function_key(char * keypadstr,int fkeymode)325 find_function_key(char *keypadstr, int fkeymode)
326 {
327 int i;
328
329 for (i = 0; fnkeytab[i].fnkeysymbol[0] != '\0'; i++) {
330 if (same_CTLKEY(keypadstr, &fnkeytab[i].fnkeymsg[fkeymode])) {
331 return i;
332 }
333 }
334 return -1;
335 }
336
337 static int
find_num_keypad_key(char * keypadstr,int fkeymode)338 find_num_keypad_key(char *keypadstr, int fkeymode)
339 {
340 int i;
341
342 for (i = 0; num_keypadtab[i].fnkeysymbol[0] != '\0'; i++) {
343 if (same_CTLKEY(keypadstr, &num_keypadtab[i].fnkeymsg[fkeymode])) {
344 return i;
345 }
346 }
347 return -1;
348 }
349
350 static void
set_keyboard_layout(struct natkey * table)351 set_keyboard_layout(struct natkey *table)
352 {
353 int i, j;
354
355 for (j = 0; table[j].natc != '\0'; j++) {
356 for (i = 0; keytab[i].c != '\0'; i++) {
357 if (keytab[i].row == table[j].natrow &&
358 keytab[i].col == table[j].natcol) {
359 keytab[i].c = table[j].natc;
360 keytab[i].symbol = table[j].natsymbol;
361 break;
362 }
363 }
364 }
365 }
366
367 static int
default_layout(MENU_ARGS)368 default_layout(MENU_ARGS)
369 {
370 /* FIXME: nothing resets the default keytab to original state */
371 return MENU_NOHOLD;
372 }
373
374 static int
same_CTLKEY(const char * response,CTLKEY * code)375 same_CTLKEY(const char *response, CTLKEY *code)
376 {
377 switch (code->prefix) {
378 case CSI:
379 if ((response = skip_csi_2(response)) == 0)
380 return FALSE;
381 break;
382 case SS3:
383 if ((response = skip_ss3_2(response)) == 0)
384 return FALSE;
385 break;
386 case ESC:
387 if (*response++ != ESC)
388 return FALSE;
389 /* FALLTHRU */
390 default:
391 break;
392 }
393 return !strcmp(response, code->msg);
394 }
395
396 static int
set_D47_layout(MENU_ARGS)397 set_D47_layout(MENU_ARGS)
398 {
399 /* *INDENT-OFF* */
400 static struct natkey table[] =
401 {
402 { '"', 1, 12, "\""},
403 { '&', 1, 32, "&" },
404 { '/', 1, 37, "/" },
405 { '(', 1, 42, "(" },
406 { ')', 1, 47, ")" },
407 { '=', 1, 52, "=" },
408 { '+', 1, 56, "+" },
409 { '?', 1, 57, "?" },
410 { '`', 1, 61, "`" },
411 { '@', 1, 62, "@" },
412 { '<', 1, 66, "<" },
413 { '>', 1, 67, ">" },
414 { '}', 2, 58, "}" },
415 { ']', 2, 59, "]" },
416 { '^', 2, 63, "^" },
417 { '~', 2, 64, "~" },
418 { '|', 3, 55, "|" },
419 {'\\', 3, 56,"\\" },
420 { '{', 3, 60, "{" },
421 { '[', 3, 61, "[" },
422 {'\'', 3, 71, "'" },
423 { '*', 3, 72, "*" },
424 { ',', 4, 47, "," },
425 { ';', 4, 48, ";" },
426 { '.', 4, 52, "." },
427 { ':', 4, 53, ":" },
428 { '-', 4, 57, "-" },
429 { '_', 4, 58, "_" },
430 {'\0', 0, 0, "" }
431 };
432 /* *INDENT-ON* */
433
434 set_keyboard_layout(table);
435 return MENU_NOHOLD;
436 }
437
438 static int
set_E47_layout(MENU_ARGS)439 set_E47_layout(MENU_ARGS)
440 {
441 /* *INDENT-OFF* */
442 static struct natkey table[] =
443 {
444 { '"', 1, 12, "\""},
445 { '&', 1, 32, "&" },
446 { '/', 1, 37, "/" },
447 { '(', 1, 42, "(" },
448 { ')', 1, 47, ")" },
449 { '=', 1, 52, "=" },
450 { '+', 1, 56, "+" },
451 { '?', 1, 57, "?" },
452 { '`', 1, 61, "`" },
453 { '@', 1, 62, "@" },
454 { '<', 1, 66, "<" },
455 { '>', 1, 67, ">" },
456 { '}', 2, 58, "}" },
457 { ']', 2, 59, "]" },
458 { '~', 2, 63, "~" },
459 { '^', 2, 64, "^" },
460 { '|', 3, 55, "|" },
461 {'\\', 3, 56,"\\" },
462 { '{', 3, 60, "{" },
463 { '[', 3, 61, "[" },
464 {'\'', 3, 71, "'" },
465 { '*', 3, 72, "*" },
466 { ',', 4, 47, "," },
467 { ';', 4, 48, ";" },
468 { '.', 4, 52, "." },
469 { ':', 4, 53, ":" },
470 { '-', 4, 57, "-" },
471 { '_', 4, 58, "_" },
472 {'\0', 0, 0, "" }
473 };
474 /* *INDENT-ON* */
475
476 set_keyboard_layout(table);
477 return MENU_NOHOLD;
478 }
479
480 static void
show_character(int i,char * scs_params,int hilite)481 show_character(int i, char *scs_params, int hilite)
482 {
483 int special = ((scs_params != 0) && (strlen(keytab[i].symbol) == 1));
484
485 vt_move(1 + 2 * keytab[i].row, 1 + keytab[i].col);
486 if (hilite)
487 vt_hilite(TRUE);
488 if (special)
489 esc(scs_params);
490 printf("%s", keytab[i].symbol);
491 if (special)
492 scs(0, 'B');
493 if (hilite)
494 vt_hilite(FALSE);
495 }
496
497 static void
show_cursor_keys(int flag)498 show_cursor_keys(int flag)
499 {
500 int i;
501
502 curkeytab = (terminal_id() < 200) ? VT100_curkeytab : LK401_curkeytab;
503
504 for (i = 0; curkeytab[i].curkeysymbol[0] != '\0'; i++) {
505 vt_move(1 + 2 * curkeytab[i].curkeyrow, 1 + curkeytab[i].curkeycol);
506 if (flag)
507 vt_hilite(TRUE);
508 printf("%s", curkeytab[i].curkeysymbol);
509 if (flag)
510 vt_hilite(FALSE);
511 }
512 }
513
514 static void
show_editing_keypad(int flag)515 show_editing_keypad(int flag)
516 {
517 if (terminal_id() >= 200) {
518 int i;
519
520 for (i = 0; edt_keypadtab[i].fnkeysymbol[0] != '\0'; i++) {
521 vt_move(1 + 2 * edt_keypadtab[i].fnkeyrow, 1 + edt_keypadtab[i].fnkeycol);
522 if (flag)
523 vt_hilite(TRUE);
524 printf("%s", edt_keypadtab[i].fnkeysymbol);
525 if (flag)
526 vt_hilite(FALSE);
527 }
528 }
529 }
530
531 static void
show_function_keys(int flag)532 show_function_keys(int flag)
533 {
534 if (terminal_id() >= 200) {
535 int i;
536
537 for (i = 0; fnkeytab[i].fnkeysymbol[0] != '\0'; i++) {
538 vt_move(1 + 2 * fnkeytab[i].fnkeyrow, 1 + fnkeytab[i].fnkeycol);
539 if (flag)
540 vt_hilite(TRUE);
541 printf("%s", fnkeytab[i].fnkeysymbol);
542 if (flag)
543 vt_hilite(FALSE);
544 }
545 }
546 }
547
548 static void
show_keyboard(int flag GCC_UNUSED,char * scs_params)549 show_keyboard(int flag GCC_UNUSED, char *scs_params)
550 {
551 int i;
552
553 if (terminal_id() >= 200) /* LK201 _looks_ the same as LK401 (to me) */
554 keytab = LK401_keytab;
555 else
556 keytab = VT100_keytab;
557
558 for (i = 0; keytab[i].c != '\0'; i++) {
559 show_character(i, scs_params, TRUE);
560 }
561 }
562
563 static void
show_numeric_keypad(int flag)564 show_numeric_keypad(int flag)
565 {
566 int i;
567
568 for (i = 0; num_keypadtab[i].fnkeysymbol[0] != '\0'; i++) {
569 vt_move(1 + 2 * num_keypadtab[i].fnkeyrow, 1 + num_keypadtab[i].fnkeycol);
570 if (flag)
571 vt_hilite(TRUE);
572 printf("%s", num_keypadtab[i].fnkeysymbol);
573 if (flag)
574 vt_hilite(FALSE);
575 }
576 }
577
578 /******************************************************************************/
579
580 static int
tst_AnswerBack(MENU_ARGS)581 tst_AnswerBack(MENU_ARGS)
582 {
583 char *abmstr;
584
585 set_tty_crmod(TRUE);
586 vt_clear(2);
587 vt_move(5, 1);
588 println("Finally, a check of the ANSWERBACK MESSAGE, which can be sent");
589 println("by pressing CTRL-BREAK. The answerback message can be loaded");
590 println("in SET-UP B by pressing SHIFT-A and typing e.g.");
591 println("");
592 println(" \" H e l l o , w o r l d Return \"");
593 println("");
594 println("(the double-quote characters included). Do that, and then try");
595 println("to send an answerback message with CTRL-BREAK. If it works,");
596 println("the answerback message should be displayed in reverse mode.");
597 println("Finish with a single RETURN.");
598
599 set_tty_crmod(FALSE);
600
601 do {
602 int row, col;
603
604 vt_move(row = 17, col = 1);
605 inflush();
606 abmstr = get_reply();
607 vt_move(row, col);
608 vt_el(0);
609 chrprint2(abmstr, row, col);
610 } while (strcmp(abmstr, "\r"));
611
612 restore_ttymodes();
613 return MENU_NOHOLD;
614 }
615
616 static int
tst_AutoRepeat(MENU_ARGS)617 tst_AutoRepeat(MENU_ARGS)
618 {
619 char arptstring[BUFSIZ];
620
621 vt_clear(2);
622 vt_move(10, 1);
623 println("Test of the AUTO REPEAT feature");
624
625 println("");
626 println("Hold down an alphanumeric key for a while, then push RETURN.");
627 printf("%s", "Auto Repeat OFF: ");
628 decarm(FALSE); /* DECARM */
629 inputline(arptstring);
630 if (LOG_ENABLED)
631 fprintf(log_fp, "Input: %s\n", arptstring);
632 if (strlen(arptstring) == 0)
633 println("No characters read!??");
634 else if (strlen(arptstring) == 1)
635 println("OK.");
636 else
637 println("Too many characters read.");
638 println("");
639
640 println("Hold down an alphanumeric key for a while, then push RETURN.");
641 printf("%s", "Auto Repeat ON: ");
642 decarm(TRUE);
643 inputline(arptstring);
644 if (LOG_ENABLED)
645 fprintf(log_fp, "Input: %s\n", arptstring);
646 if (strlen(arptstring) == 0)
647 println("No characters read!??");
648 else if (strlen(arptstring) == 1)
649 println("Not enough characters read.");
650 else
651 println("OK.");
652 println("");
653
654 return MENU_HOLD;
655 }
656
657 static int
tst_ControlKeys(MENU_ARGS)658 tst_ControlKeys(MENU_ARGS)
659 {
660 int i, okflag;
661 int kbdc;
662 char temp[80];
663 char *kbds = strcpy(temp, " ");
664 /* *INDENT-OFF* */
665 static struct {
666 int ccount;
667 const char *csymbol;
668 } ckeytab [] = {
669 { 0, "NUL (CTRL-@ or CTRL-Space)" },
670 { 0, "SOH (CTRL-A)" },
671 { 0, "STX (CTRL-B)" },
672 { 0, "ETX (CTRL-C)" },
673 { 0, "EOT (CTRL-D)" },
674 { 0, "ENQ (CTRL-E)" },
675 { 0, "ACK (CTRL-F)" },
676 { 0, "BEL (CTRL-G)" },
677 { 0, "BS (CTRL-H) (BACK SPACE)" },
678 { 0, "HT (CTRL-I) (TAB)" },
679 { 0, "LF (CTRL-J) (LINE FEED)" },
680 { 0, "VT (CTRL-K)" },
681 { 0, "FF (CTRL-L)" },
682 { 0, "CR (CTRL-M) (RETURN)" },
683 { 0, "SO (CTRL-N)" },
684 { 0, "SI (CTRL-O)" },
685 { 0, "DLE (CTRL-P)" },
686 { 0, "DC1 (CTRL-Q) (X-On)" },
687 { 0, "DC2 (CTRL-R)" },
688 { 0, "DC3 (CTRL-S) (X-Off)" },
689 { 0, "DC4 (CTRL-T)" },
690 { 0, "NAK (CTRL-U)" },
691 { 0, "SYN (CTRL-V)" },
692 { 0, "ETB (CTRL-W)" },
693 { 0, "CAN (CTRL-X)" },
694 { 0, "EM (CTRL-Y)" },
695 { 0, "SUB (CTRL-Z)" },
696 { 0, "ESC (CTRL-[) (ESCAPE)" },
697 { 0, "FS (CTRL-\\ or CTRL-? or CTRL-_)" },
698 { 0, "GS (CTRL-])" },
699 { 0, "RS (CTRL-^ or CTRL-~ or CTRL-`)" },
700 { 0, "US (CTRL-_ or CTRL-?)" }
701 };
702 /* *INDENT-ON* */
703
704 vt_clear(2);
705 for (i = 0; i < 32; i++) {
706 vt_move(1 + (i % 16), 1 + 40 * (i / 16));
707 vt_hilite(TRUE);
708 printf("%s", ckeytab[i].csymbol);
709 vt_hilite(FALSE);
710 }
711 vt_move(19, 1);
712 set_tty_crmod(TRUE);
713 println(
714 "Push each CTRL-key TWICE. Note that you should be able to send *all*");
715 println(
716 "CTRL-codes twice, including CTRL-S (X-Off) and CTRL-Q (X-Off)!");
717 println(
718 "Finish with DEL (also called DELETE or RUB OUT), or wait 1 minute.");
719 set_tty_raw(TRUE);
720 do {
721 int row, col;
722
723 vt_move(row = max_lines - 1, col = 1);
724 kbdc = inchar();
725 vt_move(row, col);
726 vt_el(0);
727 if (kbdc < 32) {
728 printf(" %s", ckeytab[kbdc].csymbol);
729 if (LOG_ENABLED)
730 fprintf(log_fp, "Key: %s\n", ckeytab[kbdc].csymbol);
731 } else {
732 sprintf(kbds, "%c", kbdc);
733 chrprint2(kbds, row, col);
734 printf("%s", " -- not a CTRL key");
735 }
736 if (kbdc < 32)
737 ckeytab[kbdc].ccount++;
738 if (ckeytab[kbdc].ccount == 2) {
739 vt_move(1 + (kbdc % 16), 1 + 40 * (kbdc / 16));
740 printf("%s", ckeytab[kbdc].csymbol);
741 }
742 } while (kbdc != '\177');
743
744 restore_ttymodes();
745 vt_move(max_lines, 1);
746 okflag = 1;
747 for (i = 0; i < 32; i++)
748 if (ckeytab[i].ccount < 2)
749 okflag = 0;
750 if (okflag)
751 printf("%s", "OK. ");
752 else
753 printf("%s", "You have not been able to send all CTRL keys! ");
754 return MENU_HOLD;
755 }
756
757 static int
tst_CursorKeys(MENU_ARGS)758 tst_CursorKeys(MENU_ARGS)
759 {
760 int i;
761 int ckeymode;
762 int row, col;
763 char *curkeystr;
764 VTLEVEL save;
765
766 static const char *curkeymodes[3] =
767 {
768 "ANSI / Cursor key mode RESET",
769 "ANSI / Cursor key mode SET",
770 "VT52 Mode"
771 };
772
773 vt_clear(2);
774 save_level(&save);
775 show_keyboard(0, (char *) 0);
776 show_function_keys(0);
777 show_editing_keypad(0);
778 show_numeric_keypad(0);
779 vt_move(max_lines - 2, 1);
780
781 set_tty_crmod(FALSE);
782 set_tty_echo(FALSE);
783
784 for (ckeymode = 0; ckeymode <= 2; ckeymode++) {
785 decckm(ckeymode); /* DECCKM */
786
787 show_cursor_keys(1);
788 vt_move(21, 1);
789 printf("<%s>%20s", curkeymodes[ckeymode], "");
790 vt_move(max_lines - 2, 1);
791 vt_el(0);
792 vt_move(max_lines - 2, 1);
793 printf("%s", "Press each cursor key. Finish with TAB.");
794 for (;;) {
795 vt_move(max_lines - 1, 1);
796 if (ckeymode == 2)
797 set_level(0); /* VT52 mode */
798 curkeystr = instr();
799 set_level(1); /* ANSI mode */
800
801 vt_move(row = max_lines - 1, col = 1);
802 vt_el(0);
803 vt_move(row, col);
804 chrprint2(curkeystr, row, col);
805
806 if (!strcmp(curkeystr, "\t"))
807 break;
808 if ((i = find_cursor_key(curkeystr, ckeymode)) >= 0) {
809 vt_hilite(TRUE);
810 show_result(" (%s key) ", curkeytab[i].curkeyname);
811 vt_hilite(FALSE);
812 vt_move(1 + 2 * curkeytab[i].curkeyrow, 1 + curkeytab[i].curkeycol);
813 printf("%s", curkeytab[i].curkeysymbol);
814 } else {
815 vt_hilite(TRUE);
816 show_result("%s", " (Unknown cursor key) ");
817 vt_hilite(FALSE);
818 }
819 }
820 }
821
822 decckm(FALSE);
823 restore_level(&save);
824 vt_move(max_lines - 1, 1);
825 vt_el(0);
826 restore_ttymodes();
827 return MENU_MERGE;
828 }
829
830 static int
tst_EditingKeypad(MENU_ARGS)831 tst_EditingKeypad(MENU_ARGS)
832 {
833 int i;
834 int fkeymode;
835 int row, col;
836 char *fnkeystr;
837 VTLEVEL save;
838
839 static const char *fnkeymodes[] =
840 {
841 "Normal mode",
842 "VT100/VT52 mode (none should be recognized)"
843 };
844
845 save_level(&save);
846 show_keyboard(0, (char *) 0);
847 show_cursor_keys(0);
848 show_function_keys(0);
849 show_numeric_keypad(0);
850 vt_move(max_lines - 2, 1);
851
852 if (terminal_id() < 200) {
853 printf("Sorry, a real VT%d terminal doesn't have an editing keypad\n",
854 terminal_id());
855 return MENU_HOLD;
856 }
857
858 set_tty_crmod(FALSE);
859 set_tty_echo(FALSE);
860
861 for (fkeymode = 0; fkeymode <= 1; fkeymode++) {
862 show_editing_keypad(1);
863 vt_move(21, 1);
864 printf("<%s>%20s", fnkeymodes[fkeymode], "");
865 vt_move(max_lines - 2, 1);
866 vt_el(0);
867 vt_move(max_lines - 2, 1);
868 printf("%s", "Press each function key. Finish with TAB.");
869
870 for (;;) {
871 vt_move(max_lines - 1, 1);
872 if (fkeymode == 0)
873 default_level();
874 if (fkeymode != 0)
875 set_level(1); /* VT100 mode */
876
877 fnkeystr = instr();
878
879 vt_move(row = max_lines - 1, col = 1);
880 vt_el(0);
881 vt_move(row, col);
882 chrprint2(fnkeystr, row, col);
883
884 if (!strcmp(fnkeystr, "\t"))
885 break;
886 if ((i = find_editing_key(fnkeystr, fkeymode)) >= 0) {
887 vt_hilite(TRUE);
888 show_result(" (%s key) ", edt_keypadtab[i].fnkeyname);
889 vt_hilite(FALSE);
890 vt_move(1 + 2 * edt_keypadtab[i].fnkeyrow, 1 + edt_keypadtab[i].fnkeycol);
891 printf("%s", edt_keypadtab[i].fnkeysymbol);
892 } else {
893 vt_hilite(TRUE);
894 show_result("%s", " (Unknown function key) ");
895 vt_hilite(FALSE);
896 }
897 }
898 }
899
900 vt_move(max_lines - 1, 1);
901 vt_el(0);
902 restore_level(&save);
903 restore_ttymodes();
904 return MENU_MERGE;
905 }
906
907 static int
tst_FunctionKeys(MENU_ARGS)908 tst_FunctionKeys(MENU_ARGS)
909 {
910 int i;
911 int fkeymode;
912 int row, col;
913 char *fnkeystr;
914 VTLEVEL save;
915
916 static const char *fnkeymodes[] =
917 {
918 "Normal mode (F6-F20, except xterm also F1-F5)",
919 "VT100/VT52 mode (F11-F13 only)"
920 };
921
922 save_level(&save);
923 show_keyboard(0, (char *) 0);
924 show_cursor_keys(0);
925 show_editing_keypad(0);
926 show_numeric_keypad(0);
927 vt_move(max_lines - 2, 1);
928
929 if (terminal_id() < 200) {
930 printf("Sorry, a real VT%d terminal doesn't have function keys\n",
931 terminal_id());
932 return MENU_HOLD;
933 }
934
935 set_tty_crmod(FALSE);
936 set_tty_echo(FALSE);
937
938 for (fkeymode = 0; fkeymode <= 1; fkeymode++) {
939 show_function_keys(1);
940 vt_move(21, 1);
941 printf("<%s>%20s", fnkeymodes[fkeymode], "");
942 vt_move(max_lines - 2, 1);
943 vt_el(0);
944 vt_move(max_lines - 2, 1);
945 printf("%s", "Press each function key. Finish with TAB.");
946
947 for (;;) {
948 vt_move(max_lines - 1, 1);
949 if (fkeymode == 0)
950 default_level();
951 if (fkeymode != 0)
952 set_level(1); /* VT100 mode */
953
954 fnkeystr = instr();
955
956 vt_move(row = max_lines - 1, col = 1);
957 vt_el(0);
958 vt_move(row, col);
959 chrprint2(fnkeystr, row, col);
960
961 if (!strcmp(fnkeystr, "\t"))
962 break;
963 if ((i = find_function_key(fnkeystr, fkeymode)) >= 0) {
964 vt_hilite(TRUE);
965 show_result(" (%s key) ", fnkeytab[i].fnkeyname);
966 vt_hilite(FALSE);
967 vt_move(1 + 2 * fnkeytab[i].fnkeyrow, 1 + fnkeytab[i].fnkeycol);
968 printf("%s", fnkeytab[i].fnkeysymbol);
969 } else {
970 vt_hilite(TRUE);
971 show_result("%s", " (Unknown function key) ");
972 vt_hilite(FALSE);
973 }
974 }
975 }
976
977 vt_move(max_lines - 1, 1);
978 vt_el(0);
979 restore_level(&save);
980 restore_ttymodes();
981 return MENU_MERGE;
982 }
983
984 static int
tst_NumericKeypad(MENU_ARGS)985 tst_NumericKeypad(MENU_ARGS)
986 {
987 int i;
988 int fkeymode;
989 int row, col;
990 char *fnkeystr;
991 VTLEVEL save;
992
993 static const char *fnkeymodes[4] =
994 {
995 "ANSI Numeric mode",
996 "ANSI Application mode",
997 "VT52 Numeric mode",
998 "VT52 Application mode"
999 };
1000
1001 vt_clear(2);
1002 save_level(&save);
1003 show_keyboard(0, (char *) 0);
1004 show_cursor_keys(0);
1005 show_function_keys(0);
1006 show_editing_keypad(0);
1007 vt_move(max_lines - 2, 1);
1008
1009 set_tty_crmod(FALSE);
1010 set_tty_echo(FALSE);
1011
1012 for (fkeymode = 0; fkeymode <= 3; fkeymode++) {
1013 show_numeric_keypad(1);
1014 vt_move(21, 1);
1015 printf("<%s>%20s", fnkeymodes[fkeymode], "");
1016 vt_move(max_lines - 2, 1);
1017 vt_el(0);
1018 vt_move(max_lines - 2, 1);
1019 printf("%s", "Press each function key. Finish with TAB.");
1020
1021 for (;;) {
1022 vt_move(max_lines - 1, 1);
1023 if (fkeymode >= 2)
1024 set_level(0); /* VT52 mode */
1025 if (fkeymode % 2)
1026 deckpam(); /* Application mode */
1027 else
1028 deckpnm(); /* Numeric mode */
1029 fnkeystr = instr();
1030 set_level(1); /* ANSI mode */
1031
1032 vt_move(row = max_lines - 1, col = 1);
1033 vt_el(0);
1034 vt_move(row, col);
1035 chrprint2(fnkeystr, row, col);
1036
1037 if (!strcmp(fnkeystr, "\t"))
1038 break;
1039 if ((i = find_num_keypad_key(fnkeystr, fkeymode)) >= 0) {
1040 vt_hilite(TRUE);
1041 show_result(" (%s key) ", num_keypadtab[i].fnkeyname);
1042 vt_hilite(FALSE);
1043 vt_move(1 + 2 * num_keypadtab[i].fnkeyrow, 1 + num_keypadtab[i].fnkeycol);
1044 printf("%s", num_keypadtab[i].fnkeysymbol);
1045 } else {
1046 vt_hilite(TRUE);
1047 show_result("%s", " (Unknown function key) ");
1048 vt_hilite(FALSE);
1049 }
1050 }
1051 }
1052
1053 deckpnm();
1054 vt_move(max_lines - 1, 1);
1055 vt_el(0);
1056 restore_level(&save);
1057 restore_ttymodes();
1058 return MENU_MERGE;
1059 }
1060
1061 static int
tst_KeyboardLayout(MENU_ARGS)1062 tst_KeyboardLayout(MENU_ARGS)
1063 {
1064 /* *INDENT-OFF* */
1065 static MENU keyboardmenu[] = {
1066 { "Standard American ASCII layout", default_layout },
1067 { "Swedish national layout D47", set_D47_layout },
1068 { "Swedish national layout E47", set_E47_layout },
1069 /* add new keyboard layouts here */
1070 { "", 0 }
1071 };
1072 /* *INDENT-ON* */
1073
1074 if (terminal_id() < 200) {
1075 vt_clear(2);
1076 keytab = VT100_keytab;
1077 title(0);
1078 println("Choose keyboard layout:");
1079 (void) menu(keyboardmenu);
1080 }
1081
1082 tst_keyboard_layout((char *) 0);
1083
1084 return MENU_MERGE;
1085 }
1086
1087 static int
tst_LED_Lights(MENU_ARGS)1088 tst_LED_Lights(MENU_ARGS)
1089 {
1090 int i;
1091 const char *ledmsg[6], *ledseq[6];
1092 /* *INDENT-OFF* */
1093 ledmsg[0] = "L1 L2 L3 L4"; ledseq[0] = "1;2;3;4";
1094 ledmsg[1] = " L2 L3 L4"; ledseq[1] = "1;0;4;3;2";
1095 ledmsg[2] = " L2 L3"; ledseq[2] = "1;4;;2;3";
1096 ledmsg[3] = "L1 L2"; ledseq[3] = ";;2;1";
1097 ledmsg[4] = "L1"; ledseq[4] = "1";
1098 ledmsg[5] = ""; ledseq[5] = "";
1099 /* *INDENT-ON* */
1100
1101 #ifdef UNIX
1102 fflush(stdout);
1103 #endif
1104 vt_clear(2);
1105 vt_move(10, 1);
1106 println("These LEDs (\"lamps\") on the keyboard should be on:");
1107 for (i = 0; i <= 5; i++) {
1108 vt_move(10, 52);
1109 vt_el(0);
1110 printf("%s", ledmsg[i]);
1111 decll("0");
1112 decll(ledseq[i]);
1113 vt_move(12, 1);
1114 holdit();
1115 }
1116 decll("0");
1117 return MENU_NOHOLD;
1118 }
1119
1120 /******************************************************************************/
1121 int
tst_keyboard_layout(char * scs_params)1122 tst_keyboard_layout(char *scs_params)
1123 {
1124 int i;
1125 int kbdc;
1126 char temp[80];
1127 char *kbds = strcpy(temp, " ");
1128
1129 vt_clear(2);
1130 show_keyboard(1, scs_params);
1131 show_cursor_keys(0);
1132 show_function_keys(0);
1133 show_editing_keypad(0);
1134 show_numeric_keypad(0);
1135 vt_move(max_lines - 2, 1);
1136
1137 set_tty_crmod(FALSE);
1138 set_tty_echo(FALSE);
1139
1140 inflush();
1141 printf("Press each key, both shifted and unshifted. Finish with RETURN:");
1142
1143 do { /* while (kbdc != 13) */
1144 int row, col;
1145 vt_move(row = max_lines - 1, col = 1);
1146 kbdc = inchar();
1147 vt_move(row, col);
1148 vt_el(0);
1149 if (scs_params != 0 && kbdc > ' ' && kbdc < '\177') {
1150 vt_hilite(TRUE);
1151 esc(scs_params);
1152 printf(" %c ", kbdc);
1153 scs(0, 'B');
1154 printf("= %d ", kbdc);
1155 scs(0, 'B');
1156 vt_hilite(FALSE);
1157 } else {
1158 sprintf(kbds, "%c", kbdc);
1159 chrprint2(kbds, row, col);
1160 }
1161 for (i = 0; keytab[i].c != '\0'; i++) {
1162 if (keytab[i].c == kbdc) {
1163 show_character(i, scs_params, FALSE);
1164 /* LK401 keyboard will have more than one hit for '<' and '>' */
1165 }
1166 }
1167 } while (kbdc != 13);
1168
1169 vt_move(max_lines - 1, 1);
1170 vt_el(0);
1171 restore_ttymodes();
1172 return MENU_MERGE;
1173 }
1174
1175 /******************************************************************************/
1176 int
tst_keyboard(MENU_ARGS)1177 tst_keyboard(MENU_ARGS)
1178 {
1179 /* *INDENT-OFF* */
1180 static MENU my_menu[] = {
1181 { "Exit", 0 },
1182 { "LED Lights", tst_LED_Lights },
1183 { "Auto Repeat", tst_AutoRepeat },
1184 { "KeyBoard Layout", tst_KeyboardLayout },
1185 { "Cursor Keys", tst_CursorKeys },
1186 { "Numeric Keypad", tst_NumericKeypad },
1187 { "Editing Keypad", tst_EditingKeypad },
1188 { "Function Keys", tst_FunctionKeys },
1189 { "AnswerBack", tst_AnswerBack },
1190 { "Control Keys", tst_ControlKeys },
1191 { "", 0 }
1192 };
1193 /* *INDENT-ON* */
1194
1195 do {
1196 vt_clear(2);
1197 __(title(0), printf("Keyboard Tests"));
1198 __(title(2), println("Choose test type:"));
1199 } while (menu(my_menu));
1200 return MENU_NOHOLD;
1201 }
1202