home *** CD-ROM | disk | FTP | other *** search
- /*
- ** This software is Copyright (c) 1991 by Daniel Weaver.
- **
- ** Permission is hereby granted to copy, distribute or otherwise
- ** use any part of this package as long as you do not try to make
- ** money from it or pretend that you wrote it. This copyright
- ** notice must be maintained in any copy made.
- **
- ** Use of this software constitutes acceptance for use in an AS IS
- ** condition. There are NO warranties with regard to this software.
- ** In no event shall the author be liable for any damages whatsoever
- ** arising out of or in connection with the use or performance of this
- ** software. Any use of this software is at the user's own risk.
- **
- ** If you make modifications to this software that you feel
- ** increases it usefulness for the rest of the community, please
- ** email the changes, enhancements, bug fixes as well as any and
- ** all ideas to me. This software is going to be maintained and
- ** enhanced as deemed necessary by the community.
- */
- /* test the function keys on the terminal */
-
- #include "curses.h"
- #include "ted.h"
-
- #define MAX_MODES 256
-
- extern char *malloc();
-
- /* scan code externals */
- extern int scan_max; /* length of longest scan code */
- extern char **scan_up, **scan_down, **scan_name;
- extern int *scan_tested, *scan_length;
-
- /* local definitions */
- static char *fk_name[MAX_STRINGS];
- static char *fkval[MAX_STRINGS];
- static char *fk_label[MAX_STRINGS]; /* function key labels (if any) */
- static int fk_tested[MAX_STRINGS];
- static int fkmax = 1; /* length of longest key */
- static int got_labels = 0; /* true if we have some labels */
- static int key_count = 0;
- static int end_state;
-
- /* unknown function keys */
- #define MAX_FK_UNK 50
- static char *fk_unknown[MAX_FK_UNK];
- static int fk_length[MAX_FK_UNK];
- static int funk;
-
- static char default_bank[] = "\033(B\017";
- static char *puc[] = {"", "<", "=", ">", "?", 0};
- static int private_use, ape, terminal_class, got_escape;
- static short ansi_value[256];
- static char ansi_buf[512], pack_buf[512];
- static char *ach, *pch;
-
- struct ansi_reports {
- int lvl, final;
- char *text;
- char *request;
- };
-
- static struct ansi_reports report_list[] = {
- 0, 'c', "(DA) Primary device attributes", "\033[0c",
- 1, 0, "(DSR) Terminal status", "\033[5n",
- 1, 'R', "(DSR) Cursor position", "\033[6n",
- 62, 0, "(DA) Secondary device attributes", "\033[>0c",
- 62, 0, "(DSR) Printer status", "\033[?15n",
- 62, 0, "(DSR) Function key definition", "\033[?25n",
- 62, 0, "(DSR) Keyboard language", "\033[?26n",
- 63, 0, "(DECRQSS) Data destination", "\033P$q$}\033\\",
- 63, 0, "(DECRQSS) Status line type", "\033P$q$~\033\\",
- 63, 0, "(DECRQSS) Erase attribute", "\033P$q\"q\033\\",
- 63, 0, "(DECRQSS) Personality", "\033P$q\"p\033\\",
- 63, 0, "(DECRQSS) Top and bottom margins", "\033P$qr\033\\",
- 63, 0, "(DECRQSS) Character attributes", "\033P$qm\033\\",
- 63, 0, "(DECRQSS) Illegal request", "\033P$q@\033\\",
- 63, 0, "(DECRQUPSS) User pref suplemental set", "\033[&u",
- 63, 0, "(DECRQPSR) Cursor information", "\033[1$w",
- 63, 0, "(DECRQPSR) Tab stop information", "\033[2$w",
- 64, 0, "(DA) Tertiary device attributes", "\033[=0c",
- 64, 0, "(DSR) Extended cursor position", "\033[?6n",
- 64, 0, "(DSR) Macro space", "\033[?62n",
- 64, 0, "(DSR) Memory checksum", "\033[?63n",
- 64, 0, "(DSR) Data integrity", "\033[?75n",
- 64, 0, "(DSR) Multiple session status", "\033[?85n",
- 64, 0, "(DECRQSS) Attribute change extent", "\033P$q*x\033\\",
- 64, 0, "(DECRQSS) Columns per page", "\033P$q$|\033\\",
- 64, 0, "(DECRQSS) Lines per page", "\033P$qt\033\\",
- 64, 0, "(DECRQSS) Lines per screen", "\033P$q*|\033\\",
- 64, 0, "(DECRQSS) Left and right margins", "\033P$qs\033\\",
- 64, 0, "(DECRQSS) Local functions", "\033P$q+q\033\\",
- 64, 0, "(DECRQSS) Local function key control", "\033P$q=}\033\\",
- 64, 0, "(DECRQSS) Select modifier key reporting", "\033P$q+r\033\\",
- 64, 0, "(DECRQDE) Window report", "\033[\"v",
- 0, 0, 0, 0};
-
- struct request_control {
- char *text;
- char *expect;
- char *request;
- char *set_mode;
- char *reset_mode;
- };
-
- /* Request control function selection or setting */
- struct request_control rqss[] = {
- "Data sent to screen", "0", "$}", "\033[0$}", 0,
- "Data sent to disabled status line", "0", "$}",
- "\033[0$~\033[1$}", "\033[0$}",
- "Data sent to enabled status line", "1", "$}",
- "\033[2$~\033[1$}", "\033[0$}",
- "Disbale status line", "0", "$~", "\033[0$~", 0,
- "Top status line", "1", "$~", "\033[1$~", 0,
- "Bottom status line", "2", "$~", "\033[2$~", 0,
- "Eraseable character", "0", "\"q", "\033[0\"q", 0,
- "Noneraseable character", "1", "\"q", "\033[1\"q", "\033[0\"q",
- "Top and bottom margins", "3;10", "r", "\0337\033[3;10r",
- "\033[r\0338",
- "Top and bottom margins", "default", "r", "\0337\033[r", "\0338",
- "Character attributes, dim, bold", "1", "m", "\033[2;1m", "\033[m",
- "Character attributes, bold, dim", "2", "m", "\033[1;2m", "\033[m",
- "Character attributes, under, rev", "4;7", "m", "\033[4;7m", "\033[m",
- "Character attributes, color", "35;42", "m", "\033[35;42m", "\033[m",
- "All character attributes", "", "m", "\033[1;2;3;4;5;6;7;8;9m",
- "\033[m",
- 0, 0, 0, 0, 0
- };
-
- static void
- keys_tested(first_time, hex_output)
- int first_time, hex_output;
- { /* display a list of the keys not tested */
- int i, l;
- char outbuf[256];
-
- put_clear();
- tty_set();
- if (tty_can_sync) (void) tty_sync_error();
- if (got_labels)
- {
- putln("Function key labels:");
- for (i = 0; i < key_count; ++i) {
- if (fk_label[i])
- {
- sprintf(outbuf, "%s %s",
- fk_name[i] ? fk_name[i] : "??", fk_label[i]);
- put_columns(outbuf, strlen(outbuf), 16);
- }
- }
- put_newlines(2);
- }
- if (funk)
- {
- putln("The following keys are not defined:");
- for (i = 0; i < funk; ++i) {
- put_columns(fk_unknown[i], fk_length[i], 16);
- }
- put_mode(exit_attribute_mode);
- put_newlines(2);
- }
- if (first_time) putln("The following keys are defined:");
- else putln("The following keys have not been tested:");
- if (scan_mode)
- for (i = 0; scan_down[i]; i++) {
- if (!scan_tested[i])
- {
- if (hex_output)
- strcpy(outbuf, hex_expand_to(scan_down[i], 3));
- else strcpy(outbuf, expand(scan_down[i]));
- l = expand_chars;
- if (hex_output)
- strcat(outbuf, hex_expand_to(scan_up[i], 3));
- else strcat(outbuf, expand(scan_up[i]));
- expand_chars += l;
- l = strlen(scan_name[i]);
- if (((char_count + 16) & ~15) +
- ((expand_chars + 7) & ~7) + l >= columns)
- put_crlf();
- else
- if (char_count) putchp(' ');
- put_columns(outbuf, expand_chars, 16);
- put_columns(scan_name[i], l, 8);
- }
- }
- else
- for (i = 0; i < key_count; i++) {
- if (!fk_tested[i])
- {
- if (hex_output)
- strcpy(outbuf, hex_expand_to(fkval[i], 3));
- else strcpy(outbuf, expand(fkval[i]));
- l = strlen(fk_name[i]);
- if (((char_count + 16) & ~15) +
- ((expand_chars + 7) & ~7) + l >= columns)
- put_crlf();
- else
- if (char_count) putchp(' ');
- put_columns(outbuf, expand_chars, 16);
- put_columns(fk_name[i], l, 8);
- }
- }
- put_newlines(2);
- }
-
-
- #ifdef TESTCAP
- void
- enter_lab(key_name, key_value, lab_name, lab_value)
- char *key_name, *key_value, *lab_name, *lab_value;
- { /* enter a label. Called by getcap() */
- int j;
-
- cap_test(key_name);
- cap_test(lab_name);
- /* ignore labels without function key values */
- if (key_value)
- {
- j = strlen(key_value);
- fkmax = fkmax > j ? fkmax : j;
- fkval[key_count] = key_value;
- fk_tested[key_count] = 0;
- fk_name[key_count] = key_name;
- fk_label[key_count++] = lab_value;
- if (lab_value) got_labels = TRUE;
- }
- }
- #endif
-
-
- void
- enter_key(name, value)
- char *name, *value;
- { /* enter a function key. Also called by getcap() */
- int j;
-
- #ifdef TESTCAP
- cap_test(name);
- #else
- can_test(name);
- #endif
- if (value)
- {
- j = strlen(value);
- fkmax = fkmax > j ? fkmax : j;
- /* do not permit duplicates */
- for (j = 0; j < key_count; j++) {
- if (!strcmp(fk_name[j], name)) return;
- }
- fkval[key_count] = value;
- fk_tested[key_count] = 0;
- fk_label[key_count] = NULL;
- fk_name[key_count++] = name;
- }
- }
-
-
- static void
- find_keys()
- { /* find out which function keys are defined */
- #ifndef TESTCAP
- char **string_base;
- char *fkey_number[MAX_STRINGS]; /* function key number */
- char *fkey_label[MAX_STRINGS]; /* function key labels */
- int i, j, k;
-
- string_base = &back_tab;
- for (i = j = 0; strnames[i]; i++) {
- if (*string_base)
- if (strncmp(strnames[i], "lf", 2) == 0)
- {
- fkey_number[j] = strnames[i];
- fkey_label[j++] = *string_base;
- }
- else
- if (strnames[i][0] == 'k')
- enter_key(strnames[i], *string_base);
- if (string_base == &prtr_non)
- #ifdef SVR3
- string_base = &char_padding;
- #else
- break;
- #endif
- else string_base++;
- }
- /* match the labels to the function keys */
- for (i = 0; i < j; i++) {
- for (k = 0; k < key_count; k++)
- if (!strcmp(&fkey_number[i][1], &fk_name[k][1])) {
- fk_label[k] = fkey_label[i];
- got_labels = TRUE;
- break;
- }
- }
- #endif
- }
-
-
- static void
- fresh_line()
- { /* clear the line for a new fumction key line */
- if (over_strike) put_crlf();
- else
- {
- put_cr();
- if (clr_eol) putp(clr_eol);
- else put_str(" \r");
- }
- }
-
-
- static int
- end_funky(ch)
- { /* return true if this is the end */
- switch (ch) {
- case 'e':
- case 'E':
- end_state = 'e';
- break;
- case 'n':
- case 'N':
- if (end_state == 'e') end_state = 'n';
- else end_state = 0;
- break;
- case 'd':
- case 'D':
- if (end_state == 'n') end_state = 'd';
- else end_state = 0;
- break;
- case 'l':
- case 'L':
- if (end_state == 'l') end_state = '?';
- else end_state = 'l';
- break;
- default:
- end_state = 0;
- break;
- }
- return end_state == 'd';
- }
-
-
- static int
- found_match(s, hx, cc)
- char *s;
- int hx, cc;
- { /* return true if this string is a match */
- int j, f;
- char outbuf[256];
-
- if (!*s) return 0;
- if (scan_mode)
- for (j = f = 0; scan_down[j]; j++) {
- if (scan_length[j] == 0) continue;
- if (!strncmp(s, scan_down[j], scan_length[j]))
- {
- if (!f)
- { /* first match */
- put_cr();
- if (hx) put_str(hex_expand_to(s, 10));
- else put_str(expand_to(s, 10));
- f = 1;
- }
- (void) end_funky(scan_name[j][0]);
- put_str(" ");
- put_str(scan_name[j]);
- scan_tested[j] = 1;
- s += scan_length[j];
- if (strncmp(s, scan_up[j], scan_length[j]))
- {
- put_str(" scan down");
- }
- else s += scan_length[j];
- if (!*s) break;
- j = -1;
- }
- if (!strncmp(s, scan_up[j], scan_length[j]))
- {
- if (!f)
- { /* first match */
- put_cr();
- if (hx) put_str(hex_expand_to(s, 10));
- else put_str(expand_to(s, 10));
- f = 1;
- }
- put_str(" ");
- put_str(scan_name[j]);
- put_str(" scan up");
- s += scan_length[j];
- if (!*s) break;
- j = -1;
- }
- }
- else
- for (j = f = 0; j < key_count; j++) {
- if (!strcmp(s, fkval[j]))
- {
- if (!f)
- { /* first match */
- put_cr();
- if (hx) put_str(hex_expand_to(s, 10));
- else put_str(expand_to(s, 10));
- f = 1;
- }
- sprintf(outbuf, " (%s)", fk_name[j]);
- put_str(outbuf);
- if (fk_label[j])
- {
- sprintf(outbuf, " <%s>", fk_label[j]);
- put_str(outbuf);
- }
- fk_tested[j] = 1;
- }
- }
- if (end_state == '?')
- {
- keys_tested(0, hx);
- tty_raw(cc, char_mask);
- end_state = 0;
- }
- return f;
- }
-
-
- static int
- found_exit(keybuf, hx, cc)
- char *keybuf;
- int hx, cc;
- { /* return true if the user wants to exit */
- int j, k;
- char *s;
-
-
- if (scan_mode)
- {
- if (*keybuf == '\0') return TRUE;
- }
- else
- {
- /* break is a special case */
- if (*keybuf == '\0')
- {
- fresh_line();
- tty_set();
- ptext("Hit X to exit");
- if (wait_here() == 'X') return TRUE;
- keys_tested(0, hx);
- tty_raw(cc, char_mask);
- return FALSE;
- }
- /* is this the end? */
- for (k = 0; j = (keybuf[k] & STRIP_PARITY); k++) {
- if (end_funky(j)) return TRUE;
- }
-
- j = TRUE; /* does he need an updated list? */
- for (k = 0; keybuf[k]; k++)
- j &= (keybuf[k] & STRIP_PARITY) == '?';
- if (j || end_state == '?')
- {
- keys_tested(0, hx);
- tty_raw(cc, char_mask);
- end_state = 0;
- return FALSE;
- }
- }
-
- put_cr();
- if (hx) s = hex_expand_to(keybuf, 10);
- else s = expand_to(keybuf, 10);
- sprintf(temp, "%s Unknown", s);
- put_str(temp);
- for (j = 0; j < MAX_FK_UNK; j++) {
- if (j == funk)
- {
- fk_length[funk] = expand_chars;
- if (fk_unknown[funk] = malloc(strlen(s) + 1))
- strcpy(fk_unknown[funk++], s);
- break;
- }
- if (fk_length[j] == expand_chars)
- if (!strcmp(fk_unknown[j], s)) break;
- }
- return FALSE;
- }
-
-
- test_funky(hex_output)
- int hex_output;
- {
- int i, j, k, len, fk;
- char outbuf[256];
- char keybuf[256];
-
- find_keys();
- if (stop_testing)
- {
- can_test("(km)(smm)(rmm)");
- #ifdef SVR3
- can_test("(nlab)(lw)(lh)(smln)(plm)(rmln)");
- #endif
- #ifndef TESTCAP
- can_test("(pfx)(pfloc)");
- #endif
- return;
- }
- if (tty_can_sync == 1) verify_time();
- if (keypad_xmit) putp(keypad_xmit);
- keys_tested(1, hex_output); /* also clears screen */
- ptextln("Hit any function key. Type 'end' to quit. Type ? to update the display.");
- put_crlf();
- keybuf[0] = '\0';
- end_state = 0;
- if (scan_mode) fkmax = scan_max;
- #ifdef WAIT_MODE
- sprintf(temp, "All function keys are assumed to be %d characters long. You must pad shorter keys with blanks.", fkmax);
- ptextln(temp);
- /* use this code if your OS can not tell if a character is ready.
- Reads will be done in wait mode. Use blanks to pad short
- strings. */
- tty_raw(1, char_mask);
- while(end_state != 'd') {
- fflush(stdout);
- if (!read(fileno(stdin), keybuf, 1)) break;
- keybuf[0] &= char_mask;
- fresh_line();
- for (len = 1; len < fkmax; len++) {
- keybuf[len] = '\0';
- if (hex_output)
- put_str(hex_expand_to(&keybuf[len - 1], 3));
- else put_str(expand(&keybuf[len - 1]));
- fflush(stdout);
- if (!read(fileno(stdin), &keybuf[len], 1)) break;
- keybuf[len] &= char_mask;
- }
- /* come here when typing stops */
- keybuf[len] = '\0';
- if (found_match(keybuf, hex_output, 1)) continue;
- /* backup over the blanks */
- for ( ; len; keybuf[--len] = '\0')
- if (keybuf[len - 1] != ' ') break;
- if (len == 0) continue;
- if (found_match(keybuf, hex_output, 1)) continue;
- if (found_exit(keybuf, hex_output, 1)) break;
- }
- #else
- /* use this code if your OS can tell if a character is ready.
- Reads will be done by read_key() defined in sysdep.c */
- tty_raw(0, char_mask);
- while(end_state != 'd') {
- read_key(keybuf, fkmax);
- fresh_line();
- if (found_match(keybuf, hex_output, 0)) continue;
- if (found_exit(keybuf, hex_output, 0)) break;
- }
- #endif
- if (keypad_local) putp(keypad_local);
- keys_tested(0, hex_output);
- if (has_meta_key)
- {
- if (char_mask != ALLOW_PARITY)
- {
- if (tty_meta_prep()) (void) wait_here();
- }
- ptext("Begin meta key test. (km) (smm) (rmm) Hit any key");
- ptext(" with the meta key. The character will be");
- ptext(" displayed in hex. If the meta key is working");
- ptext(" then the most significant bit will be set. Type");
- ptextln(" 'end' to exit.");
- tty_raw(1, ALLOW_PARITY);
- putp(meta_on);
-
- for (i = j = k = len = 0; i != 'e' | j != 'n' | k != 'd'; ) {
- i = j; j = k;
- k = getchp(ALLOW_PARITY);
- if (k == EOF) break;
- if ((len += 3) >= columns)
- {
- put_crlf(); len = 3;
- }
- sprintf(outbuf, "%02X ", k);
- put_str(outbuf);
- k &= STRIP_PARITY;
- }
- putp(meta_off);
- put_crlf();
- }
- else
- {
- ptextln("This terminal has no meta key. (km)");
- (void) wait_here();
- }
- tty_set();
-
- #ifdef SVR3
- new_test(8);
- sprintf(temp, "Your terminal has %d labels (nlab) that are %d characters wide (lw) and %d lines high (lh)",
- num_labels, label_width, label_height);
- ptext(temp);
- ptextln(" Testing (smln) (pln) (rmln)");
- if (label_on) putp(label_on);
- if (label_width <= 0) label_width = sizeof(outbuf) - 1;
- for (i = 1; i <= num_labels; i++) {
- sprintf(outbuf, "L%d..............................", i);
- outbuf[label_width] = '\0';
- putp(tparm(plab_norm, i, outbuf));
- }
- (void) wait_here();
- if (label_off) putp(label_off);
- #endif
-
- #ifndef TESTCAP
- new_test(8);
- fk = 1; /* use function key 1 for now */
- if (pkey_xmit)
- {
- char mm[256];
-
- /* test program function key */
- sprintf(temp,
- "(pfx) Set function key %d to transmit abc\\n", fk);
- ptextln(temp);
- putp(tparm(pkey_xmit, fk, "abc\n"));
- sprintf(temp, "Hit function key %d\n", fk);
- ptextln(temp);
- for (i = 0; i < 4; ++i) mm[i] = getchp(STRIP_PARITY);
- mm[i] = '\0';
- put_crlf();
- if (mm[0] != 'a' | mm[1] != 'b' | mm[2] != 'c')
- {
- sprintf(temp, "Error string recieved was: %s", expand(mm));
- ptextln(temp);
- }
- else putln("Thank you\n");
- /* if the terminal sent too much, flush it */
- if (tty_can_sync) (void) tty_sync_error();
- }
- else ptextln("Function key transmit (pfx), not present.");
-
- if (pkey_local)
- {
- /* test local function key */
- sprintf(temp,
- "(pfloc) Set function key %d to execute a clear and print \"Done!\"", fk);
- ptextln(temp);
- sprintf(temp, "%sDone!", liberated(clear_screen));
- putp(tparm(pkey_local, fk, temp));
- sprintf(temp, "Hit function key %d. Then hit return.", fk);
- ptextln(temp);
- }
- else ptextln("Function key execute local (pfloc), not present.");
-
- (void) wait_here();
- /* if the terminal sent anything else, flush it */
- if (tty_can_sync) (void) tty_sync_error();
- if (key_f1 && pkey_xmit) putp(tparm(pkey_xmit, fk, key_f1));
- #endif
- }
-
-
- test_printer()
- { /* test the printer commands */
-
- if (stop_testing)
- {
- can_test("(mc4)(mc5)(mc0)(mc5i)");
- return;
- }
- put_clear();
- putln("Begin printer test.");
- if (!prtr_on || !prtr_off)
- {
- ptextln("Printer on/off missing. (mc5) (mc4)");
- }
- else
- #if defined(SVR3) || defined(XENIX)
- if (prtr_silent)
- {
- ptextln("Your printer is silent. (mc5i) is set.");
- putp(prtr_on);
- ptextln("This line should be on the printer but not your screen. (mc5)");
- putp(prtr_off);
- ptextln("This line should be only on the screen. (mc4)");
- }
- else
- {
- ptextln("Your printer is not silent. (mc5i) is reset.");
- putp(prtr_on);
- ptextln("This line should be on the printer and the screen. (mc5)");
- putp(prtr_off);
- ptextln("This line should only be on the screen. (mc4)");
- }
- #else
- {
- putp(prtr_on);
- ptextln("This line should be on the printer. (mc5)");
- putp(prtr_off);
- ptextln("This line should only be on the screen. (mc4)");
- }
- #endif
- (void) wait_here();
- if (print_screen)
- {
- ptext("I am going to send the contents of the screen to");
- ptext(" the printer, then wait for a keystroke from you.");
- ptext(" All of the text that appears on the screen");
- ptextln(" should be printed. (mc0)");
- putp(print_screen);
- (void) wait_here();
- }
- putln("End of printer test.");
- }
-
-
- static void
- line_pattern()
- { /* put up a pattern that will help count the number of lines */
- int i, j;
-
- put_clear();
- if (over_strike)
- for (i = 0; i < 100; i++) {
- if (i) put_crlf();
- for (j = i / 10; j; j--) put_this(' ');
- put_this('0' + ((i + 1) % 10));
- }
- else /* I assume it will scroll */
- for (i = 100; i; i--) {
- sprintf(temp, "\r\n%d", i);
- put_str(temp);
- }
- }
-
-
- static void
- column_pattern()
- { /* put up at pattern that will help count the number of columns */
- int i, j;
-
- put_clear();
- for (i = 0; i < 20; i++) {
- for (j = 1; j < 10; j++) {
- put_this('0' + j);
- }
- put_this('.');
- }
- }
-
-
- test_report(crx, hex_display)
- int crx, hex_display;
- { /* status report and echo test */
- int i, j, ch, crp, high_bit, save_scan_mode;
- char buf[1024];
- char txt[8];
-
- put_clear();
- if (crx == 1)
- {
- ptext("Characters after a CR or LF will be echoed as");
- ptext(" is. All other characters will be expanded. Type");
- ptext(" 'end' to exit. Type");
- ptext(" 'echo' to redisplay last report. Type");
- ptext(" 'hex' to redisplay last report in hex. Type");
- ptextln(" 'clear' to clear screen.");
- }
- else /* echo test */
- {
- ptext("Begin echo test. Type");
- ptext(" 'end' to exit. Type");
- ptext(" 'hex' to display characters in hex. Type");
- ptext(" 'high' to toggle high order bit on output. Type");
- ptextln(" 'clear' to clear screen.");
- }
- txt[sizeof(txt) - 1] = '\0';
- save_scan_mode = scan_mode;
- tty_raw(1, char_mask);
- for (i = crp = high_bit = 0; ; ) {
- ch = getchp(char_mask);
- if (ch == EOF) break;
- if (i >= sizeof(buf) - 1) i = 0;
- buf[i++] = ch;
- buf[i] = '\0';
- for (j = 0; j < sizeof(txt) - 1; j++) {
- txt[j] = txt[j + 1];
- }
- txt[sizeof(txt) - 1] = ch & STRIP_PARITY;
- if (crx == 0) /* echo test */
- {
- if (hex_display) ptext(hex_expand_to(&buf[i - 1], 3));
- else putch(ch | high_bit);
- }
- else /* status report test */
- if (ch == '\n' | ch == '\r')
- {
- put_crlf();
- crp = 0;
- }
- else
- if (crp++ < crx) putch(ch | high_bit);
- else put_str(expand(&buf[i - 1]));
- if (!strncmp(&txt[sizeof(txt) - 7], "columns", 7))
- {
- column_pattern();
- buf[i = 0] = '\0';
- crp = 0;
- }
- if (!strncmp(&txt[sizeof(txt) - 5], "lines", 5))
- {
- line_pattern();
- buf[i = 0] = '\0';
- crp = 0;
- }
- if (!strncmp(&txt[sizeof(txt) - 5], "clear", 5))
- {
- put_clear();
- buf[i = 0] = '\0';
- crp = 0;
- }
- if (!strncmp(&txt[sizeof(txt) - 4], "high", 4))
- {
- high_bit ^= 0x80;
- if (high_bit) ptextln("\nParity bit set");
- else ptextln("\nParity bit reset");
- }
- if (!strncmp(&txt[sizeof(txt) - 4], "echo", 4))
- {
- /* display the last status report */
- /* clear bypass condition on Tek terminals */
- put_crlf();
- buf[i -= 4] = '\0';
- put_str(expand(buf));
- }
- if (save_scan_mode &&
- !strncmp(&txt[sizeof(txt) - 4], "scan", 4))
- {
- /* toggle scan mode */
- scan_mode = !scan_mode;
- }
- if (!strncmp(&txt[sizeof(txt) - 3], "end", 3)) break;
- if (!strncmp(&txt[sizeof(txt) - 3], "hex", 3))
- if (crx)
- {
- /* display the last status report */
- /* clear bypass condition on Tek terminals */
- put_crlf();
- buf[i -= 3] = '\0';
- put_str(hex_expand_to(buf, 3));
- }
- else hex_display = !hex_display;
- if (!strncmp(&txt[sizeof(txt) - 3], "two", 3)) crx = 2;
- if (!strncmp(&txt[sizeof(txt) - 3], "one", 3)) crx = 1;
- if (!strncmp(&txt[sizeof(txt) - 3], "all", 3)) crx = 0;
- }
- scan_mode = save_scan_mode;
- put_crlf();
- tty_set();
- if (crx) ptextln("End of status report test.");
- else ptextln("End of echo test.");
- }
-
-
- static int
- pack_ansi()
- { /* read and pack an ANSI character */
- int ch;
-
- if (*pch) return *pch++;
-
- while (1) {
- ch = getchp(char_mask);
- if (ch == EOF) return EOF;
- if (ch == A_DC1 || ch == A_DC3) continue;
- *ach++ = ch; *ach = '\0';
- if (got_escape && ch >= ' ')
- {
- got_escape = 0;
- if (ch < '@' || ch > '_')
- {
- *pch++ = A_ESC;
- *pch = ch;
- pch[1] = '\0';
- return A_ESC;
- }
- ch += 0x40;
- break;
- }
- else
- if (ch == A_ESC) got_escape = 1;
- else break;
- }
- *pch++ = ch; *pch = '\0';
- return ch;
- }
-
-
- static void
- read_ansi()
- { /* read an ANSI status report */
- int ch;
-
- fflush(stdout);
- ach = ansi_buf; pch = pack_buf;
- ansi_buf[0] = pack_buf[0] = '\0';
- got_escape = 0;
- ch = pack_ansi();
- if (ch == A_ESC)
- do {
- ch = pack_ansi();
- if (ch == EOF) return;
- } while (ch < '0' || ch > '~');
- else
- if (ch == A_CSI)
- do {
- ch = pack_ansi();
- if (ch == EOF) return;
- } while (ch < '@' || ch > '~');
- else
- if (ch == A_DCS)
- do {
- ch = pack_ansi();
- if (ch == EOF) return;
- } while (ch != A_ST);
- return;
- }
-
-
- static int
- valid_mode(expected)
- int expected;
- { /* read a terminal mode status report and parse the result */
- char *s;
- int ch, terminator;
-
- read_ansi();
-
- ape = 0;
- ch = pack_buf[0] & 0xff;
- if (ch != A_CSI && ch != A_DCS) return FALSE;
-
- s = pack_buf + 1;
- private_use = 0;
- if (*s >= '<' & *s <= '?') private_use = *s++;
- ansi_value[0] = 0;
- terminator = 0;
- for ( ; ch = *s; s++) {
- if (ch >= '0' && ch <= '9')
- ansi_value[ape] = ansi_value[ape] * 10 + ch - '0';
- else
- if (ch == ';' || ch == ':')
- ansi_value[++ape] = 0;
- else
- if (ch >= '<' && ch <= '?')
- private_use = ch;
- else
- if (ch >= ' ')
- terminator = (terminator << 8) | ch;
- else break;
- }
- return terminator == expected;
- }
-
-
- static int
- read_reports()
- { /* read all the reports in the ANSI report structure */
- int i, j, k, tc, vcr, lc;
- char *s;
-
- lc = 5;
- terminal_class = tc = 0;
- for (i = 0; report_list[i].text; i++, lc++) {
- if (terminal_class < report_list[i].lvl &&
- tc < report_list[i].lvl)
- {
- j = wait_here();
- if (j != 'c' && j != 'C') return j;
- tc = report_list[i].lvl;
- }
- else
- if (lc >= lines)
- {
- (void) wait_here();
- lc = 1;
- }
- sprintf(temp, "%s (%s) ", report_list[i].text,
- expand_command(report_list[i].request));
- ptext(temp);
- for (j = strlen(temp); j < 49; j++) putchp(' ');
- putp(report_list[i].request);
- vcr = 0;
- if (report_list[i].final == 0) read_ansi();
- else
- if (valid_mode(report_list[i].final))
- switch(report_list[i].final) {
- case 'c':
- terminal_class = ansi_value[0];
- break;
- case 'R':
- vcr = TRUE;
- break;
- }
- j = pack_buf[0] & 0xff;
- if (j == A_CSI || j == A_DCS)
- {
- s = expand(ansi_buf);
- if (char_count + expand_chars >= columns)
- {
- put_str("\r\n ");
- lc++;
- }
- put_str(s);
- }
- put_crlf();
- if (vcr)
- { /* find out how big the screen is */
- putp(report_list[i].request);
- if (!valid_mode('R')) continue;
- j = ansi_value[0];
- k = ansi_value[1];
- putp("\033[255B\033[255C\033[6n");
- if (!valid_mode('R')) continue;
- sprintf(temp, "\033[%d;%dH", j, k);
- putp(temp);
- ptext("(DSR) Screen size (CSI 6 n)");
- for (j = char_count; j < 50; j++) putchp(' ');
- sprintf(temp, "%d x %d", ansi_value[1], ansi_value[0]);
- ptextln(temp);
-
- }
- }
- return wait_here();
- }
-
-
- static int
- request_cfss()
- { /* Request Control function selection or settings */
- int i, j, k, l, ch;
- char *s;
-
- put_clear();
- ptextln("Request Expected Received");
- put_crlf();
- for (i = 0; rqss[i].text; i++) {
- ptext(rqss[i].text);
- j = strlen(rqss[i].text) + strlen(rqss[i].expect);
- putchp(' ');
- for (j++; j < 40; j++) putchp(' ');
- ptext(rqss[i].expect);
- putchp(' ');
- putp(rqss[i].set_mode);
- sprintf(temp, "\033P$q%s\033\\", rqss[i].request);
- putp(temp);
- read_ansi();
- putp(rqss[i].reset_mode);
- putchp(' ');
- for (j = 0; ansi_buf[j]; j++) {
- if (ansi_buf[j] == 'r')
- {
- for (k = j++; ch = (ansi_buf[k] & 0xff); k++)
- if (ch == A_ESC) break;
- else
- if (ch == A_ST) break;
- ansi_buf[k] = '\0';
- s = expand(&ansi_buf[j]);
- if (char_count + expand_chars >= columns)
- put_str("\r\n ");
- put_str(s);
- }
- }
- put_crlf();
- }
- /* calculate the valid attributes */
- ptext("Valid attributes: 0");
- j = 0;
- for (i = 1; i < 20; i++) {
- sprintf(temp, "\033[0;%dm\033P$qm\033\\", i);
- putp(temp);
- (void) valid_mode('m');
- if (ape > 0)
- {
- j = i;
- sprintf(temp, "\033[0m; %d", i);
- putp(temp);
- }
- }
- put_crlf();
- /* calculate how many parameters can be sent */
- ptext("Max number of parameters: ");
- sprintf(temp, "%dm\033P$qm\033\\", j);
- l = -1;
- if (j > 0)
- for (l = 1; l < 33; l++ ) {
- putp("\033[0");
- for (ch = 1; ch <= l; ch++) put_this(';');
- putp(temp);
- (void) valid_mode('m');
- if (ape == 0) break;
- }
- putp("\033[m");
- if (l >= 0)
- {
- sprintf(temp, "%d", l);
- ptext(temp);
- }
- else ptext("unknown");
- put_crlf();
- return wait_here();
- }
-
-
- static
- mode_display(p, n, c, s, r)
- char *p;
- char n, c, s, r;
- { /* print the mode display entry */
- int k;
-
- sprintf(temp, "%s%d (%c, %c, %c)", p, n, c, s, r);
- k = strlen(temp);
- if (char_count + k >= columns) put_crlf();
- for ( ; k < 14; k++) putchp(' ');
- put_str(temp);
- }
-
-
- static void
- terminal_state()
- { /* test DECRQM status reports */
- int i, j, k, l, modes_found;
- char *s;
- char buf[256], tms[256];
- char mode_puc[MAX_MODES], mode_number[MAX_MODES];
- char set_value[MAX_MODES], reset_value[MAX_MODES];
- char current_value[MAX_MODES];
-
- ptext("Testing terminal mode status. (CSI 0 $ p)");
- putp("\033[0$p");
- modes_found = 0;
- tms[0] = '\0';
- if (valid_mode(('$' << 8) | 'y'))
- for (i = 0; puc[i]; i++) {
- put_crlf();
- if (i)
- {
- sprintf(temp, "Private use: %c", puc[i][0]);
- }
- else strcpy(temp, "Standard modes:");
- k = strlen(temp);
- ptext(temp);
- for (j = 0; j < sizeof(buf); buf[j++] = ' ');
- for (j = l = 0; j < 255 && j - l < 50; j++) {
- sprintf(temp, "\033[%s%d$p", puc[i], j);
- putp(temp);
- if (!valid_mode(('$' << 8) | 'y'))
- { /* not valid, save terminating value */
- s = expand(ansi_buf);
- sprintf(tms, "%s%s%d %s ", tms, puc[i], j, s);
- break;
- }
- if (private_use != puc[i][0]) break;
- if (ansi_value[0] != j) break;
- if (ansi_value[1])
- {
- l = j;
- if (k > 70)
- {
- buf[k] = '\0';
- put_crlf();
- ptextln(buf);
- for (k = 0; k < sizeof(buf); )
- buf[k++] = ' ';
- k = 0;
- }
- sprintf(temp, " %d", j);
- ptext(temp);
- k += strlen(temp);
- buf[k - 1] = ansi_value[1] + '0';
- if (modes_found >= MAX_MODES) continue;
- current_value[modes_found] =
- ansi_value[1] + '0';
- /* some modes never return */
- if ((i == 0 && j == 13) /* control execution */
- || (puc[i][0] == '?' && j == 2)) /* VT52 */
- set_value[modes_found] =
- reset_value[modes_found] = '-';
- else set_value[modes_found] =
- reset_value[modes_found] = ' ';
- mode_puc[modes_found] = i;
- mode_number[modes_found++] = j;
- }
- }
- buf[k] = '\0';
- if (buf[k - 1] != ' ')
- {
- put_crlf();
- ptext(buf);
- }
- }
-
- if (i = modes_found)
- {
- put_crlf();
- put_crlf();
- if (tms[0]) ptextln(tms);
- ptext("Hit 'Y' to test mode set/reset states.");
- i = wait_here();
- }
- if (i == 'y' || i == 'Y')
- while (1) {
- #ifdef STATUSFIX
- FILE *fp;
-
- #ifdef TEDANSI
- fp = fopen("ted.ansi", "w");
- #else
- fp = fopen("/dev/console", "w");
- #endif
- #endif
- for (i = j = 0; j < modes_found; j = ++i >> 1) {
- if (set_value[j] == '-') continue;
- k = (current_value[j] ^ i) & 1;
- sprintf(temp, "\033[%s%d%c\033[%s%d$p",
- puc[mode_puc[j]], mode_number[j],
- k ? 'l' : 'h',
- puc[mode_puc[j]], mode_number[j]);
- #ifdef STATUSFIX
- if (fp)
- {
- fprintf(fp, "%s\n", expand(temp));
- fflush(fp);
- }
- #endif
- putp(temp);
- if (!valid_mode(('$' << 8) | 'y')) continue;
- if (k) reset_value[j] = ansi_value[1] + '0';
- else set_value[j] = ansi_value[1] + '0';
- }
- put_str("\033[30l"); /* added for GORT bug (WY-185) */
- #ifdef STATUSFIX
- if (fp) fclose(fp);
- #endif
- tty_set();
- /* print the results */
- put_clear();
- putln("mode (initial, set, reset)");
- for (j = 0; j < modes_found; j++) {
- mode_display(puc[mode_puc[j]], mode_number[j],
- current_value[j], set_value[j], reset_value[j]);
- }
- ptext("\n\nHit 'R' to repeat test. 'S' to sort results.");
- i = wait_here();
- if (i == 's' || i == 'S')
- { /* print the same stuff, sorted by current_value */
- put_crlf();
- for (i = '1'; i <= '4'; i++) {
- for (j = 0; j < modes_found; j++) {
- if (current_value[j] == i)
- mode_display(puc[mode_puc[j]],
- mode_number[j], current_value[j],
- set_value[j], reset_value[j]);
- }
- }
- ptext("\n\nHit 'R' to repeat test.");
- i = wait_here();
- }
- if (i != 'r' && i != 'R') break;
- tty_raw(1, char_mask);
- }
- else tty_set();
- }
-
-
- test_ansi_reports()
- { /* test ansi status reports */
- int i;
-
- put_clear();
- ptext("Begin ANSI status report testing. ");
- ptext(" Parity bit set will be displayed in reverse video. ");
- ptextln(" If the terminal hangs, hit any alphabetic key.");
- put_crlf();
- tty_raw(1, char_mask);
-
- do {
- i = read_reports();
- } while(i == 'r' || i == 'R');
-
- if (terminal_class >= 63)
- {
- do {
- i = request_cfss();
- } while(i == 'r' || i == 'R');
- terminal_state();
- }
- else tty_set();
-
- putln("\nEnd of ANSI status report test.");
- (void) wait_here();
- }
-
-
- static void
- select_bank(bank)
- char *bank;
- { /* select a graphics character set for ANSI terminals */
- putp(bank);
- switch (bank[1] & 3) {
- case 0:
- putchp('O' & 0x1f); /* control O */
- break;
- case 1:
- putchp('N' & 0x1f); /* control N */
- putp("\033~");
- break;
- case 2:
- putp("\033n\033}");
- break;
- case 3:
- putp("\033o\033|");
- break;
- }
- }
-
-
- static void
- show_characters(bank, bias)
- char *bank;
- int bias;
- { /* print the ANSI graphics characters */
- int i;
-
- sprintf(temp, "G%d GL ", bank[1] & 3);
- ptext(temp);
- select_bank(bank);
- for (i = ' '; i < 0x80; i++) {
- if (char_count >= columns ||
- (i != ' ' && (i & 31) == 0)) put_str("\n ");
- putchp(i + bias);
- }
- select_bank(default_bank);
- put_str(" DEL <");
- select_bank(bank);
- putchp(0x7f + bias);
- select_bank(default_bank);
- putchp('>');
- put_crlf();
- put_crlf();
- }
-
-
- /* ANSI graphics test
- 94 96 character sets
- G0 ( ,
- G1 ) -
- G2 * .
- G3 + /
-
- Standard Definitions
- A UK
- B US ASCII
-
- Dec extended definitions
- 0 Special graphics
-
- */
-
- ansi_graphics()
- { /* test ANSI character sets */
- int j, ch;
- char bank[32];
-
- put_clear();
- ptext("Enter the bank ()*+,-./ followed by the character set");
- ptext(" 0123456789:;<=>? for private use, and");
- ptextln(" @A...Z[\\]^_`a...z{|}~ for standard sets.");
- strcpy(bank, "\033)0");
- for ( ; bank[0]; ) {
- put_crlf();
- show_characters(bank, 0);
- /* G0 will not print in GR */
- if (bank[1] & 3) show_characters(bank, 0x80);
- for (j = 1; ch = getchp(char_mask); j++) {
- if (ch == EOF) break;
- putchp(ch);
- if (j == 1 && ch > '/') j++;
- bank[j] = ch;
- if (ch < ' ' | ch > '/') break;
- if (j + 1 >= sizeof(bank)) break;
- }
- if (j == 1) break;
- if (bank[j] < '0' || bank[j] > '~') break;
- bank[j + 1] = '\0';
- }
- }
-