ncurses 5.3
[mirror-ossqm-ncurses.git] / tack / charset.c
blob991401f37437479336fa9b93d1a230ddce979516
1 /*
2 ** Copyright (C) 1991, 1997-2000 Free Software Foundation, Inc.
3 **
4 ** This file is part of TACK.
5 **
6 ** TACK 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 2, or (at your option)
9 ** any later version.
10 **
11 ** TACK is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ** GNU General Public License for more details.
15 **
16 ** You should have received a copy of the GNU General Public License
17 ** along with TACK; see the file COPYING. If not, write to
18 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 ** Boston, MA 02111-1307, USA.
22 #include <tack.h>
24 MODULE_ID("$Id: charset.c,v 1.8 2001/06/18 18:44:26 tom Exp $")
27 Menu definitions for alternate character set and SGR tests.
30 static void charset_bel(struct test_list *t, int *state, int *ch);
31 static void charset_flash(struct test_list *t, int *state, int *ch);
32 static void charset_civis(struct test_list *t, int *state, int *ch);
33 static void charset_cvvis(struct test_list *t, int *state, int *ch);
34 static void charset_cnorm(struct test_list *t, int *state, int *ch);
35 static void charset_hs(struct test_list *t, int *state, int *ch);
36 static void charset_status(struct test_list *t, int *state, int *ch);
37 static void charset_dsl(struct test_list *t, int *state, int *ch);
38 static void charset_enacs(struct test_list *t, int *state, int *ch);
39 static void charset_smacs(struct test_list *t, int *state, int *ch);
40 static void charset_attributes(struct test_list *t, int *state, int *ch);
41 static void charset_sgr(struct test_list *t, int *state, int *ch);
43 struct test_list acs_test_list[] = {
44 {0, 0, 0, 0, "e) edit terminfo", 0, &edit_menu},
45 {MENU_NEXT, 3, "bel", 0, 0, charset_bel, 0},
46 {MENU_NEXT, 3, "flash", 0, 0, charset_flash, 0},
47 {MENU_NEXT, 3, "civis", 0, 0, charset_civis, 0},
48 {MENU_NEXT, 3, "cvvis", 0, 0, charset_cvvis, 0},
49 {MENU_NEXT, 3, "cnorm", 0, 0, charset_cnorm, 0},
50 {MENU_NEXT, 3, "hs", 0, 0, charset_hs, 0},
51 {MENU_NEXT, 3, "tsl) (fsl) (wsl", "hs", 0, charset_status, 0},
52 {MENU_NEXT, 3, "dsl", "hs", 0, charset_dsl, 0},
53 {MENU_NEXT, 0, "acsc) (enacs) (smacs) (rmacs", 0, 0, charset_enacs, 0},
54 {MENU_NEXT, 0, "smacs) (rmacs", 0, 0, charset_smacs, 0},
55 {MENU_NEXT, 11, 0, 0, 0, charset_attributes, 0},
56 {MENU_NEXT, 11, "sgr) (sgr0", "ma", 0, charset_sgr, 0},
57 {MENU_LAST, 0, 0, 0, 0, 0, 0}
60 const struct mode_list alt_modes[] = {
61 {"normal", "(sgr0)", "(sgr0)", 1},
62 {"standout", "(smso)", "(rmso)", 2},
63 {"underline", "(smul)", "(rmul)", 4},
64 {"reverse", "(rev)", "(sgr0)", 8},
65 {"blink", "(blink)", "(sgr0)", 16},
66 {"dim", "(dim)", "(sgr0)", 32},
67 {"bold", "(bold)", "(sgr0)", 64},
68 {"invis", "(invis)", "(sgr0)", 128},
69 {"protect", "(prot)", "(sgr0)", 256},
70 {"altcharset", "(smacs)", "(rmacs)", 512}
73 /* On many terminals the underline attribute is the last scan line.
74 This is OK unless the following line is reverse video.
75 Then the underline attribute does not show up. The following map
76 will reorder the display so that the underline attribute will
77 show up. */
78 const int mode_map[10] = {0, 1, 3, 4, 5, 6, 7, 8, 9, 2};
80 struct graphics_pair {
81 unsigned char c;
82 const char *name;
85 static struct graphics_pair glyph[] = {
86 {'+', "arrow pointing right"},
87 {',', "arrow pointing left"},
88 {'.', "arrow pointing down"},
89 {'0', "solid square block"},
90 {'i', "lantern symbol"},
91 {'-', "arrow pointing up"},
92 {'`', "diamond"},
93 {'a', "checker board (stipple)"},
94 {'f', "degree symbol"},
95 {'g', "plus/minus"},
96 {'h', "board of squares"},
97 {'j', "lower right corner"},
98 {'k', "upper right corner"},
99 {'l', "upper left corner"},
100 {'m', "lower left corner"},
101 {'n', "plus"},
102 {'o', "scan line 1"},
103 {'p', "scan line 3"},
104 {'q', "horizontal line"},
105 {'r', "scan line 7"},
106 {'s', "scan line 9"},
107 {'t', "left tee (|-)"},
108 {'u', "right tee (-|)"},
109 {'v', "bottom tee(_|_)"},
110 {'w', "top tee (T)"},
111 {'x', "vertical line"},
112 {'y', "less/equal"},
113 {'z', "greater/equal"},
114 {'{', "Pi"},
115 {'|', "not equal"},
116 {'}', "UK pound sign"},
117 {'~', "bullet"},
118 {'\0', "\0"}
122 ** charset_hs(test_list, status, ch)
124 ** (hs) test Has status line
126 static void
127 charset_hs(
128 struct test_list *t,
129 int *state,
130 int *ch)
132 if (has_status_line != 1) {
133 ptext("(hs) Has-status line is not defined. ");
134 generic_done_message(t, state, ch);
139 ** charset_status(test_list, status, ch)
141 ** (tsl) (fsl) (wsl) test Status line
143 static void
144 charset_status(
145 struct test_list *t,
146 int *state,
147 int *ch)
149 int i, max;
150 char *s;
151 static char m[] = "*** status line *** 123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.";
153 if (has_status_line != 1) {
154 return;
156 put_clear();
157 max = width_status_line == -1 ? columns : width_status_line;
158 sprintf(temp, "Terminal has status line of %d characters", max);
159 ptextln(temp);
161 put_str("This line s");
162 s = tparm(to_status_line, 0);
163 tc_putp(s);
164 for (i = 0; i < max; i++)
165 putchp(m[i]);
166 tc_putp(from_status_line);
167 putln("hould not be broken.");
168 ptextln("If the previous line is not a complete sentence then (tsl) to-status-line, (fsl) from-status-line, or (wsl) width-of-status-line is incorrect." );
169 generic_done_message(t, state, ch);
173 ** charset_dsl(test_list, status, ch)
175 ** (dsl) test Disable status line
177 static void
178 charset_dsl(
179 struct test_list *t,
180 int *state,
181 int *ch)
183 if (has_status_line != 1) {
184 return;
186 if (dis_status_line) {
187 ptextln("Disable status line (dsl)");
188 tc_putp(dis_status_line);
189 ptext("If you can still see the status line then (dsl) disable-status-line has failed. ");
190 } else {
191 ptext("(dsl) Disable-status-line is not defined. ");
193 generic_done_message(t, state, ch);
197 void
198 eat_cookie(void)
199 { /* put a blank if this is not a magic cookie
200 terminal */
201 if (magic_cookie_glitch < 1)
202 putchp(' ');
206 void
207 put_mode(char *s)
208 { /* send the attribute string (with or without
209 % execution) */
210 tc_putp(tparm(s)); /* allow % execution */
214 void
215 set_attr(int a)
216 { /* set the attribute from the bits in a */
217 int i, b[32];
219 if (magic_cookie_glitch > 0) {
220 char_count += magic_cookie_glitch;
222 if (a == 0 && exit_attribute_mode) {
223 put_mode(exit_attribute_mode);
224 return;
226 for (i = 0; i < 31; i++) {
227 b[i] = (a >> i) & 1;
229 tc_putp(tparm(set_attributes, b[1], b[2], b[3], b[4], b[5],
230 b[6], b[7], b[8], b[9]));
234 ** charset_sgr(test_list, status, ch)
236 ** (sgr) test Set Graphics Rendition
238 static void
239 charset_sgr(
240 struct test_list *t,
241 int *state,
242 int *ch)
244 int i, j;
246 if (!set_attributes) {
247 ptext("(sgr) Set-graphics-rendition is not defined. ");
248 generic_done_message(t, state, ch);
249 return;
251 if (!exit_attribute_mode) {
252 ptextln("(sgr0) Set-graphics-rendition-zero is not defined.");
253 /* go ahead and test anyway */
255 ptext("Test video attributes (sgr)");
257 for (i = 0; i < (int) (sizeof(alt_modes) / sizeof(struct mode_list));
258 i++) {
259 put_crlf();
260 sprintf(temp, "%d %-20s", i, alt_modes[i].name);
261 put_str(temp);
262 set_attr(alt_modes[i].number);
263 sprintf(temp, "%s", alt_modes[i].name);
264 put_str(temp);
265 set_attr(0);
268 putln("\n\nDouble mode test");
269 for (i = 0; i <= 9; i++) {
270 sprintf(temp, " %2d ", mode_map[i]);
271 put_str(temp);
273 for (i = 0; i <= 9; i++) {
274 put_crlf();
275 sprintf(temp, "%d", mode_map[i]);
276 put_str(temp);
277 for (j = 0; j <= 9; j++) {
278 eat_cookie();
279 set_attr((1 << mode_map[i]) | (1 << mode_map[j]));
280 put_str("Aa");
281 set_attr(0);
282 if (j < 9)
283 eat_cookie();
286 put_crlf();
288 #ifdef max_attributes
289 if (max_attributes >= 0) {
290 sprintf(temp, "(ma) Maximum attributes %d ", max_attributes);
291 ptext(temp);
293 #endif
294 generic_done_message(t, state, ch);
298 ** test_one_attr(mode-number, begin-string, end-string)
300 ** Display one attribute line.
302 static void
303 test_one_attr(
304 int n,
305 char *begin_mode,
306 char *end_mode)
308 int i;
310 sprintf(temp, "%-10s %s ", alt_modes[n].name, alt_modes[n].begin_mode);
311 ptext(temp);
312 for (; char_count < 19;) {
313 putchp(' ');
315 if (begin_mode) {
316 putchp('.');
317 put_mode(begin_mode);
318 put_str(alt_modes[n].name);
319 for (i = strlen(alt_modes[n].name); i < 13; i++) {
320 putchp(' ');
322 if (end_mode) {
323 put_mode(end_mode);
324 sprintf(temp, ". %s", alt_modes[n].end_mode);
325 } else {
326 set_attr(0);
327 strcpy(temp, ". (sgr)");
329 ptextln(temp);
330 } else {
331 for (i = 0; i < magic_cookie_glitch; i++)
332 putchp('*');
333 put_str("*** missing ***");
334 for (i = 0; i < magic_cookie_glitch; i++)
335 putchp('*');
336 put_crlf();
341 ** charset_attributes(test_list, status, ch)
343 ** Test SGR
345 static void
346 charset_attributes(
347 struct test_list *t,
348 int *state,
349 int *ch)
351 putln("Test video attributes");
352 test_one_attr(1, enter_standout_mode, exit_standout_mode);
353 test_one_attr(2, enter_underline_mode, exit_underline_mode);
354 test_one_attr(9, enter_alt_charset_mode, exit_alt_charset_mode);
355 if (!exit_attribute_mode && !set_attributes) {
356 ptextln("(sgr0) exit attribute mode is not defined.");
357 generic_done_message(t, state, ch);
358 return;
360 test_one_attr(3, enter_reverse_mode, exit_attribute_mode);
361 test_one_attr(4, enter_blink_mode, exit_attribute_mode);
362 test_one_attr(5, enter_dim_mode, exit_attribute_mode);
363 test_one_attr(6, enter_bold_mode, exit_attribute_mode);
364 test_one_attr(7, enter_secure_mode, exit_attribute_mode);
365 test_one_attr(8, enter_protected_mode, exit_attribute_mode);
366 generic_done_message(t, state, ch);
369 #define GLYPHS 256
372 ** charset_smacs(test_list, status, ch)
374 ** display all possible acs characters
375 ** (smacs) (rmacs)
377 static void
378 charset_smacs(
379 struct test_list *t,
380 int *state,
381 int *ch)
383 int i, c;
385 if (enter_alt_charset_mode) {
386 put_clear();
387 ptextln("The following characters are available. (smacs) (rmacs)");
388 for (i = ' '; i <= '`'; i += 32) {
389 put_crlf();
390 put_mode(exit_alt_charset_mode);
391 for (c = 0; c < 32; c++) {
392 putchp(c + i);
394 put_crlf();
395 put_mode(enter_alt_charset_mode);
396 for (c = 0; c < 32; c++) {
397 putchp(c + i);
399 put_mode(exit_alt_charset_mode);
400 put_crlf();
402 put_mode(exit_alt_charset_mode);
403 put_crlf();
404 generic_done_message(t, state, ch);
409 static void
410 test_acs(
411 int attr)
412 { /* alternate character set */
413 int i, j;
414 char valid_glyph[GLYPHS];
415 char acs_table[GLYPHS];
416 static unsigned char vt100[] = "`afgjklmnopqrstuvwxyz{|}~";
418 line_count = 0;
419 for (i = 0; i < GLYPHS; i++) {
420 valid_glyph[i] = FALSE;
421 acs_table[i] = i;
423 if (acs_chars) {
424 sprintf(temp, "Alternate character set map: %s",
425 expand(acs_chars));
426 putln(temp);
427 for (i = 0; acs_chars[i]; i += 2) {
428 if (acs_chars[i + 1] == 0) {
429 break;
431 for (j = 0;; j++) {
432 if (glyph[j].c == (unsigned char) acs_chars[i]) {
433 acs_table[glyph[j].c] = acs_chars[i + 1];
434 valid_glyph[glyph[j].c] = TRUE;
435 break;
437 if (glyph[j].name[0] == '\0') {
438 if (isgraph(UChar(acs_chars[i]))) {
439 sprintf(temp, " %c",
440 acs_chars[i]);
441 } else {
442 sprintf(temp, " 0x%02x",
443 UChar(acs_chars[i]));
445 strcpy(&temp[5], " *** has no mapping ***");
446 putln(temp);
447 break;
451 } else {
452 ptextln("acs_chars not defined (acsc)");
453 /* enable the VT-100 graphics characters (default) */
454 for (i = 0; vt100[i]; i++) {
455 valid_glyph[vt100[i]] = TRUE;
458 if (attr) {
459 set_attr(attr);
461 _nc_init_acs(); /* puts 'ena_acs' and incidentally links acs_map[] */
462 for (i = 0; glyph[i].name[0]; i++) {
463 if (valid_glyph[glyph[i].c]) {
464 put_mode(enter_alt_charset_mode);
465 put_this(acs_table[glyph[i].c]);
466 char_count++;
467 put_mode(exit_alt_charset_mode);
468 if (magic_cookie_glitch >= 1) {
469 sprintf(temp, " %-30.30s", glyph[i].name);
470 put_str(temp);
471 if (char_count + 33 >= columns)
472 put_crlf();
473 } else {
474 sprintf(temp, " %-24.24s", glyph[i].name);
475 put_str(temp);
476 if (char_count + 26 >= columns)
477 put_crlf();
479 if (line_count >= lines) {
480 (void) wait_here();
481 put_clear();
485 if (char_count > 1) {
486 put_crlf();
488 #ifdef ACS_ULCORNER
489 maybe_wait(5);
490 put_mode(enter_alt_charset_mode);
491 put_this(ACS_ULCORNER);
492 put_this(ACS_TTEE);
493 put_this(ACS_URCORNER);
494 put_this(ACS_ULCORNER);
495 put_this(ACS_HLINE);
496 put_this(ACS_URCORNER);
497 char_count += 6;
498 put_mode(exit_alt_charset_mode);
499 put_crlf();
500 put_mode(enter_alt_charset_mode);
501 put_this(ACS_LTEE);
502 put_this(ACS_PLUS);
503 put_this(ACS_RTEE);
504 put_this(ACS_VLINE);
505 if (magic_cookie_glitch >= 1)
506 put_this(' ');
507 else {
508 put_mode(exit_alt_charset_mode);
509 put_this(' ');
510 put_mode(enter_alt_charset_mode);
512 put_this(ACS_VLINE);
513 char_count += 6;
514 put_mode(exit_alt_charset_mode);
515 put_str(" Here are 2 boxes");
516 put_crlf();
517 put_mode(enter_alt_charset_mode);
518 put_this(ACS_LLCORNER);
519 put_this(ACS_BTEE);
520 put_this(ACS_LRCORNER);
521 put_this(ACS_LLCORNER);
522 put_this(ACS_HLINE);
523 put_this(ACS_LRCORNER);
524 char_count += 6;
525 put_mode(exit_alt_charset_mode);
526 put_crlf();
527 #endif
531 ** charset_bel(test_list, status, ch)
533 ** (bel) test Bell
535 static void
536 charset_bel(
537 struct test_list *t,
538 int *state,
539 int *ch)
541 if (bell) {
542 ptextln("Testing bell (bel)");
543 tc_putp(bell);
544 ptext("If you did not hear the Bell then (bel) has failed. ");
545 } else {
546 ptext("(bel) Bell is not defined. ");
548 generic_done_message(t, state, ch);
552 ** charset_flash(test_list, status, ch)
554 ** (flash) test Visual bell
556 static void
557 charset_flash(
558 struct test_list *t,
559 int *state,
560 int *ch)
562 if (flash_screen) {
563 ptextln("Testing visual bell (flash)");
564 tc_putp(flash_screen);
565 ptext("If you did not see the screen flash then (flash) has failed. ");
566 } else {
567 ptext("(flash) Flash is not defined. ");
569 generic_done_message(t, state, ch);
573 ** charset_civis(test_list, status, ch)
575 ** (civis) test Cursor invisible
577 static void
578 charset_civis(
579 struct test_list *t,
580 int *state,
581 int *ch)
583 if (cursor_normal) {
584 if (cursor_invisible) {
585 ptext("(civis) Turn off the cursor. ");
586 tc_putp(cursor_invisible);
587 ptext("If you can still see the cursor then (civis) has failed. ");
588 } else {
589 ptext("(civis) Cursor-invisible is not defined. ");
591 generic_done_message(t, state, ch);
592 tc_putp(cursor_normal);
597 ** charset_cvvis(test_list, status, ch)
599 ** (cvvis) test Cursor very visible
601 static void
602 charset_cvvis(
603 struct test_list *t,
604 int *state,
605 int *ch)
607 if (cursor_normal) {
608 if (cursor_visible) {
609 ptext("(cvvis) Make cursor very visible. ");
610 tc_putp(cursor_visible);
611 ptext("If the cursor is not very visible then (cvvis) has failed. ");
612 } else {
613 ptext("(cvvis) Cursor-very-visible is not defined. ");
615 generic_done_message(t, state, ch);
616 tc_putp(cursor_normal);
621 ** charset_cnorm(test_list, status, ch)
623 ** (cnorm) test Cursor normal
625 static void
626 charset_cnorm(
627 struct test_list *t,
628 int *state,
629 int *ch)
631 if (cursor_normal) {
632 ptext("(cnorm) Normal cursor. ");
633 tc_putp(cursor_normal);
634 ptext("If the cursor is not normal then (cnorm) has failed. ");
635 } else {
636 ptext("(cnorm) Cursor-normal is not defined. ");
638 generic_done_message(t, state, ch);
642 ** charset_enacs(test_list, status, ch)
644 ** test Alternate character set mode and alternate characters
645 ** (acsc) (enacs) (smacs) (rmacs)
647 static void
648 charset_enacs(
649 struct test_list *t,
650 int *state,
651 int *ch)
653 int c, i;
655 if (enter_alt_charset_mode || acs_chars) {
656 c = 0;
657 while (1) {
658 put_clear();
660 for terminals that use separate fonts for
661 attributes (such as X windows) the line
662 drawing characters must be checked for
663 each font.
665 if (c >= '0' && c <= '9') {
666 test_acs(alt_modes[c - '0'].number);
667 set_attr(0);
668 } else {
669 test_acs(0);
672 while (1) {
673 ptextln("[r] to repeat, [012345789] to test with attributes on, [?] for a list of attributes, anything else to go to next test. ");
674 generic_done_message(t, state, ch);
675 if (*ch != '?') {
676 break;
678 for (i = 0; i <= 9; i++) {
679 sprintf(temp, " %d %s %s", i, alt_modes[i].begin_mode,
680 alt_modes[i].name);
681 ptextln(temp);
684 if (*ch >= '0' && *ch <= '9') {
685 c = *ch;
686 } else
687 if (*ch != 'r') {
688 break;
691 } else {
692 ptext("(smacs) Enter-alt-char-set-mode and (acsc) Alternate-char-set are not defined. ");
693 generic_done_message(t, state, ch);
698 ** charset_can_test()
700 ** Initialize the can_test data base
702 void
703 charset_can_test(void)
705 int i;
707 for (i = 0; i < 9; i++) {
708 can_test(alt_modes[i].begin_mode, FLAG_CAN_TEST);
709 can_test(alt_modes[i].end_mode, FLAG_CAN_TEST);