1 /* $Id: vt420.c,v 1.170 2018/07/26 00:41:17 tom Exp $ */
2
3 /*
4 * Reference: Installing and Using the VT420 Video Terminal (North American
5 * Model (EK-VT420-UG.002)
6 */
7 #include <vttest.h>
8 #include <draw.h>
9 #include <esc.h>
10 #include <ttymodes.h>
11
12 typedef enum {
13 marNone = -1,
14 marReset = 0,
15 marFirst = 1,
16 marLast = 2,
17 marMiddle = 3,
18 marEnd
19 } MARS;
20
21 int origin_mode = FALSE;
22 char txt_override_color[80];
23
24 static int do_lines = FALSE;
25 static int use_colors = FALSE;
26
27 /******************************************************************************/
28
29 static void
reset_colors(void)30 reset_colors(void)
31 {
32 if (use_colors) {
33 sgr("0");
34 use_colors = FALSE;
35 if (LOG_ENABLED) {
36 fprintf(log_fp, "Note: turned off colors\n");
37 }
38 }
39 }
40
41 void
set_colors(const char * value)42 set_colors(const char *value)
43 {
44 if (do_colors) {
45 if (value == 0)
46 value = "0";
47 sgr(value);
48 use_colors = strcmp(value, "0");
49 if (LOG_ENABLED) {
50 fprintf(log_fp, "Note: turned %s colors\n", use_colors ? "on" : "off");
51 }
52 }
53 }
54
55 /******************************************************************************/
56
57 int lrmm_flag;
58
59 static MARS lr_marg_flag;
60 static int lr_marg1, lr_marg2;
61 static MARS tb_marg_flag;
62 static int tb_marg1, tb_marg2;
63
64 char origin_mode_mesg[80];
65 char lrmm_mesg[80];
66 char lr_marg_mesg[80];
67 char tb_marg_mesg[80];
68
69 int
toggle_LRMM(MENU_ARGS)70 toggle_LRMM(MENU_ARGS)
71 {
72 lrmm_flag = !lrmm_flag;
73 if (lrmm_flag)
74 sm("?69");
75 else
76 rm("?69");
77 return MENU_NOHOLD;
78 }
79
80 /*
81 * The message tells what margins will be used in the test, not what their
82 * value is while drawing the menu (since actually setting margins would
83 * interfere with the menu).
84 */
85 int
toggle_STBM(MENU_ARGS)86 toggle_STBM(MENU_ARGS)
87 {
88 switch (++tb_marg_flag) {
89 default:
90 tb_marg_flag = marReset;
91 tb_marg1 = 0;
92 tb_marg2 = 0;
93 strcpy(tb_marg_mesg, "Top/Bottom margins are reset");
94 break;
95 case marFirst:
96 tb_marg1 = 1;
97 tb_marg2 = max_lines / 2;
98 strcpy(tb_marg_mesg, "Top/Bottom margins are set to top half of screen");
99 break;
100 case marLast:
101 tb_marg1 = max_lines / 2;
102 tb_marg2 = max_lines;
103 strcpy(tb_marg_mesg,
104 "Top/Bottom margins are set to bottom half of screen");
105 break;
106 case marMiddle:
107 tb_marg1 = max_lines / 4;
108 tb_marg2 = (3 * max_lines) / 4;
109 strcpy(tb_marg_mesg,
110 "Top/Bottom margins are set to middle half of screen");
111 break;
112 }
113 return MENU_NOHOLD;
114 }
115
116 int
toggle_SLRM(MENU_ARGS)117 toggle_SLRM(MENU_ARGS)
118 {
119 switch (++lr_marg_flag) {
120 default:
121 lr_marg_flag = marReset;
122 lr_marg1 = 0;
123 lr_marg2 = 0;
124 strcpy(lr_marg_mesg, "Left/right margins are reset");
125 break;
126 case marFirst:
127 lr_marg1 = 1;
128 lr_marg2 = min_cols / 2;
129 strcpy(lr_marg_mesg, "Left/right margins are set to left half of screen");
130 break;
131 case marLast:
132 lr_marg1 = (min_cols / 2) + 1;
133 lr_marg2 = min_cols;
134 strcpy(lr_marg_mesg,
135 "Left/right margins are set to right half of screen");
136 break;
137 case marMiddle:
138 lr_marg1 = (min_cols / 4) + 1;
139 lr_marg2 = (3 * min_cols) / 4;
140 strcpy(lr_marg_mesg,
141 "Left/right margins are set to middle half of screen");
142 break;
143 }
144 return MENU_NOHOLD;
145 }
146
147 int
get_top_margin(void)148 get_top_margin(void)
149 {
150 int result = (tb_marg1 ? tb_marg1 : 1);
151 if (origin_mode)
152 result = 1;
153 return result;
154 }
155
156 int
get_left_margin(void)157 get_left_margin(void)
158 {
159 int result = ((lrmm_flag && lr_marg1) ? lr_marg1 : 1);
160 if (origin_mode)
161 result = 1;
162 return result;
163 }
164
165 int
get_right_margin(void)166 get_right_margin(void)
167 {
168 int result = ((lrmm_flag && lr_marg2) ? lr_marg2 : min_cols);
169 if (origin_mode) {
170 result = (((lrmm_flag && lr_marg2) ? lr_marg2 : min_cols) -
171 ((lrmm_flag && lr_marg1) ? lr_marg1 : 1) +
172 1);
173 }
174 return result;
175 }
176
177 int
get_bottom_margin(int n)178 get_bottom_margin(int n)
179 {
180 int result = (tb_marg2 ? tb_marg2 : (n));
181 if (origin_mode) {
182 result = ((tb_marg2 ? tb_marg2 : max_lines) -
183 (tb_marg1 ? tb_marg1 : 1) +
184 1);
185 }
186 return result;
187 }
188
189 static int
get_hold_col(void)190 get_hold_col(void)
191 {
192 int hold_col = 1;
193
194 if (lrmm_flag) {
195 switch (lr_marg_flag) {
196 default:
197 break;
198 case marFirst:
199 hold_col = get_right_margin() + 1;
200 break;
201 case marMiddle:
202 hold_col = get_left_margin();
203 break;
204 }
205 }
206 return hold_col;
207 }
208
209 /*
210 * Return a good row value at which to print a prompt, avoiding most overwrite
211 * of test-results.
212 */
213 static int
get_hold_row(void)214 get_hold_row(void)
215 {
216 int hold_row;
217
218 switch (tb_marg_flag) {
219 default:
220 hold_row = max_lines / 2;
221 break;
222 case marFirst:
223 hold_row = (origin_mode
224 ? (max_lines - 4)
225 : (get_bottom_margin(max_lines) + 1));
226 break;
227 case marMiddle:
228 hold_row = (max_lines > 16) ? (max_lines - 4) : (max_lines / 2);
229 break;
230 case marLast:
231 hold_row = 1;
232 break;
233 }
234 return hold_row;
235 }
236
237 static int
hold_clear(void)238 hold_clear(void)
239 {
240 int result;
241
242 switch (tb_marg_flag) {
243 default:
244 result = 0;
245 break;
246 case marFirst:
247 result = 1;
248 break;
249 case marReset:
250 case marLast:
251 result = 0;
252 break;
253 }
254
255 return result;
256 }
257
258 /*
259 * Prompt as part of a multi-step test, temporarily resetting DECOM so we can
260 * put the prompt anywhere.
261 */
262 static void
special_prompt(int row,int col,const char * msg)263 special_prompt(int row, int col, const char *msg)
264 {
265 if (origin_mode)
266 decom(FALSE);
267
268 vt_move(row, col);
269 if (msg != 0) {
270 printf("%s", msg);
271 vt_move(row + 1, col);
272 }
273 holdit();
274
275 if (origin_mode)
276 decom(TRUE);
277 }
278
279 /*
280 * Fill area outside margins with given character, to help show that changes
281 * are limited to the area within margins.
282 */
283 static void
fill_outside(int ch)284 fill_outside(int ch)
285 {
286 int row, col;
287
288 if (LOG_ENABLED) {
289 fprintf(log_fp, "Note: filling outside margins with '%c'\n", ch);
290 }
291
292 if (!do_colors)
293 set_colors("0");
294
295 if (origin_mode)
296 decom(FALSE);
297
298 for (row = 1; row <= max_lines; ++row) {
299 if (row < tb_marg1 ||
300 row > tb_marg2 ||
301 lr_marg1 > 1 ||
302 lr_marg2 < min_cols) {
303 int first = 1;
304 int next = 0;
305
306 for (col = 1; col <= min_cols; ++col) {
307 if ((lrmm_flag && lr_marg1 && col < lr_marg1) ||
308 (lrmm_flag && lr_marg2 && col > lr_marg2) ||
309 (tb_marg1 != 0 && row < tb_marg1) ||
310 (tb_marg2 != 0 && row > tb_marg2)) {
311 if (first || (next != col)) {
312 vt_move(row, col);
313 first = 0;
314 next = col + 1;
315 }
316 putchar(ch);
317 ++next;
318 }
319 }
320 }
321 }
322
323 if (origin_mode)
324 decom(TRUE);
325 }
326
327 void
test_with_margins(int enable)328 test_with_margins(int enable)
329 {
330 switch (enable) {
331 case 1:
332 fill_outside('.');
333 /* FALLTHRU */
334 case 2:
335 decstbm(tb_marg1, tb_marg2);
336 decslrm(lr_marg1, lr_marg2);
337 if (origin_mode)
338 decom(TRUE);
339 break;
340 default:
341 decstbm(0, 0);
342 decslrm(0, 0);
343 if (origin_mode)
344 decom(FALSE);
345 break;
346 }
347 }
348
349 /*
350 * Fill the area within margins with a test pattern. The top line is numbers,
351 * the bottom line is alphas. In between, use asterisks.
352 */
353 static void
fill_margins(void)354 fill_margins(void)
355 {
356 int top = get_top_margin();
357 int bot = get_bottom_margin(max_lines);
358 int lft = get_left_margin();
359 int rgt = get_right_margin();
360 int row, col;
361
362 set_colors(WHITE_ON_BLUE);
363
364 decawm(FALSE); /* do this to allow writing in lower-right */
365 for (row = top; row <= bot; ++row) {
366 cup(row, lft);
367 for (col = lft; col <= rgt; ++col) {
368 if (row == top) {
369 putchar((col - lft) % 10 + '0');
370 } else if (row == bot) {
371 putchar((col - lft) % 26 + 'a');
372 } else {
373 putchar('*');
374 }
375 }
376 }
377 decawm(TRUE);
378 }
379
380 static void
setup_rectangle(BOX * box,int last)381 setup_rectangle(BOX *box, int last)
382 {
383 box->top = 5;
384 box->left = 5;
385 box->right = min_cols - 5;
386 box->bottom = max_lines - 10;
387
388 if (origin_mode) {
389 int top = get_top_margin();
390 int lft = get_left_margin();
391 int rgt = get_right_margin();
392 int bot = get_bottom_margin(last - 1);
393 int wide = (rgt - lft + 1);
394 int high = (bot - top + 1);
395
396 if (high > 20) {
397 box->top = 5;
398 box->bottom = high - 10;
399 } else {
400 box->top = 2;
401 box->bottom = high - 2;
402 }
403
404 if (wide > 20) {
405 box->left = 5;
406 box->right = wide - 5;
407 } else {
408 box->left = 2;
409 box->right = wide - 2;
410 }
411 }
412 }
413
414 #define DATA(name,level) { name, #name, level }
415
416 static int
show_DECLRMM(MENU_ARGS)417 show_DECLRMM(MENU_ARGS)
418 {
419 /* *INDENT-OFF* */
420 RQM_DATA dec_modes[] = { /* this list is sorted by code, not name */
421 DATA( DECLRMM, 4 /* left/right margin mode */),
422 };
423 /* *INDENT-ON* */
424
425 int code;
426 int old_DECRPM = set_DECRPM(4);
427
428 code = any_RQM(PASS_ARGS, dec_modes, TABLESIZE(dec_modes), 1);
429 set_DECRPM(old_DECRPM);
430 return code;
431 }
432
433 #undef DATA
434
435 /*
436 * Allow user to test the same screens with/without lines.
437 */
438 static int
toggle_lines_mode(MENU_ARGS)439 toggle_lines_mode(MENU_ARGS)
440 {
441 do_lines = !do_lines;
442 return MENU_NOHOLD;
443 }
444
445 /*
446 * Allow user to test the same screens with/without origin-mode.
447 */
448 int
toggle_DECOM(MENU_ARGS)449 toggle_DECOM(MENU_ARGS)
450 {
451 origin_mode = !origin_mode;
452 return MENU_NOHOLD;
453 }
454
455 /*
456 * DECALN does not set attributes; we want a colored screen for some tests.
457 */
458 static void
fill_screen(void)459 fill_screen(void)
460 {
461 if (do_colors) {
462 int y, x;
463
464 set_colors(WHITE_ON_BLUE);
465 for (y = 0; y < max_lines - 4; ++y) {
466 cup(y + 1, 1);
467 for (x = 0; x < min_cols; ++x)
468 putchar('E');
469 }
470 /* make this a different color to show fill versus erase diffs */
471 set_colors(WHITE_ON_GREEN);
472 } else {
473 decaln(); /* fill the screen */
474 }
475 }
476
477 /******************************************************************************/
478
479 static int
rpt_DECSACE(MENU_ARGS)480 rpt_DECSACE(MENU_ARGS)
481 {
482 return any_decrqss(the_title, "*x");
483 }
484
485 static int
rpt_DECSNLS(MENU_ARGS)486 rpt_DECSNLS(MENU_ARGS)
487 {
488 return any_decrqss(the_title, "*|");
489 }
490
491 static int
rpt_DECSLRM(MENU_ARGS)492 rpt_DECSLRM(MENU_ARGS)
493 {
494 return any_decrqss(the_title, "s");
495 }
496
497 static int
rpt_DECELF(MENU_ARGS)498 rpt_DECELF(MENU_ARGS)
499 {
500 return any_decrqss(the_title, "+q");
501 }
502
503 /*
504 * VT420 manual shows "=}", but the terminal returns an error. VT510 sequences
505 * show "*}".
506 */
507 static int
rpt_DECLFKC(MENU_ARGS)508 rpt_DECLFKC(MENU_ARGS)
509 {
510 return any_decrqss(the_title, "*}");
511 }
512
513 static int
rpt_DECSMKR(MENU_ARGS)514 rpt_DECSMKR(MENU_ARGS)
515 {
516 return any_decrqss(the_title, "+r");
517 }
518
519 /******************************************************************************/
520
521 static void
show_DataIntegrity(char * report)522 show_DataIntegrity(char *report)
523 {
524 int pos = 0;
525 int code = scanto(report, &pos, 'n');
526 const char *show;
527
528 switch (code) {
529 case 70:
530 show = "No communication errors";
531 break;
532 case 71:
533 show = "Communication errors";
534 break;
535 case 73:
536 show = "Not reported since last power-up or RIS";
537 break;
538 default:
539 show = SHOW_FAILURE;
540 }
541 show_result("%s", show);
542 }
543
544 static void
show_keypress(int row,int col)545 show_keypress(int row, int col)
546 {
547 char *report;
548 char last[BUFSIZ];
549
550 last[0] = '\0';
551 vt_move(row++, 1);
552 println("When you are done, press any key twice to quit.");
553 vt_move(row, col);
554 fflush(stdout);
555 while (strcmp(report = instr(), last)) {
556 vt_move(row, col);
557 vt_clear(0);
558 chrprint2(report, row, col);
559 strcpy(last, report);
560 }
561 }
562
563 static void
show_MultisessionStatus(char * report)564 show_MultisessionStatus(char *report)
565 {
566 int pos = 0;
567 int Ps1 = scan_any(report, &pos, 'n');
568 int Ps2 = scanto(report, &pos, 'n');
569 const char *show;
570
571 switch (Ps1) {
572 case 80:
573 show = "SSU sessions enabled (%d max)";
574 break;
575 case 81:
576 show = "SSU sessions available but pending (%d max)";
577 break;
578 case 83:
579 show = "SSU sessions not ready";
580 break;
581 case 87:
582 show = "Sessions on separate lines";
583 break;
584 default:
585 show = SHOW_FAILURE;
586 }
587 show_result(show, Ps2);
588 }
589
590 /******************************************************************************/
591
592 /*
593 * VT400 & up.
594 * DECBI - Back Index
595 * This control function moves the cursor backward one column. If the cursor
596 * is at the left margin, then all screen data within the margin moves one
597 * column to the right. The column that shifted past the right margin is lost.
598 *
599 * Format: ESC 6
600 * Description:
601 * DECBI adds a new column at the left margin with no visual attributes. DECBI
602 * is not affected by the margins. If the cursor is at the left border of the
603 * page when the terminal received DECBI, then the terminal ignores DECBI.
604 */
605 static int
tst_DECBI(MENU_ARGS)606 tst_DECBI(MENU_ARGS)
607 {
608 int n, m;
609 int last = max_lines - 4;
610 int final;
611 int top;
612 int lft;
613 int rgt;
614
615 test_with_margins(1);
616
617 top = get_top_margin();
618 lft = get_left_margin();
619 rgt = get_right_margin();
620
621 final = (rgt - lft + 1) / 4;
622
623 set_colors(WHITE_ON_BLUE);
624
625 for (n = final; n > 0; n--) {
626 slowly();
627 cup(top, lft);
628 if (n != final) {
629 for (m = 0; m < 4; m++)
630 decbi();
631 }
632 printf("%3d", n);
633 }
634
635 reset_colors();
636
637 test_with_margins(0);
638
639 vt_move(last, 1);
640 vt_clear(0);
641
642 println(the_title);
643 println("If your terminal supports DECBI (backward index), then the top row");
644 printf("should be numbered 1 through %d.\n", final);
645 return MENU_HOLD;
646 }
647
648 static int
tst_DECBKM(MENU_ARGS)649 tst_DECBKM(MENU_ARGS)
650 {
651 int row, col;
652 char *report;
653
654 vt_move(1, 1);
655 println(the_title);
656
657 set_tty_raw(TRUE);
658 set_tty_echo(FALSE);
659
660 reset_inchar();
661 decbkm(TRUE);
662 println("Press the backspace key");
663 vt_move(row = 3, col = 10);
664 report = instr();
665 chrprint2(report, row, col);
666 show_result(!strcmp(report, "\010") ? SHOW_SUCCESS : SHOW_FAILURE);
667
668 reset_inchar();
669 vt_move(5, 1);
670 decbkm(FALSE);
671 println("Press the backspace key again");
672 vt_move(row = 6, col = 10);
673 report = instr();
674 chrprint2(report, row, col);
675 show_result(!strcmp(report, "\177") ? SHOW_SUCCESS : SHOW_FAILURE);
676
677 vt_move(max_lines - 1, 1);
678 restore_ttymodes();
679 return MENU_HOLD;
680 }
681
682 /*
683 * VT400 & up
684 * Change Attributes in Rectangular Area
685 */
686 static int
tst_DECCARA(MENU_ARGS)687 tst_DECCARA(MENU_ARGS)
688 {
689 int last = max_lines - 4;
690 BOX box;
691
692 setup_rectangle(&box, last);
693
694 test_with_margins(1);
695
696 set_colors(WHITE_ON_BLUE);
697
698 decsace(TRUE);
699 fill_screen();
700 deccara(box.top, box.left, box.bottom, box.right, 7); /* invert a rectangle) */
701 deccara(box.top + 1, box.left + 1, box.bottom - 1, box.right - 1, 0); /* invert a rectangle) */
702
703 test_with_margins(0);
704 sgr("0");
705 vt_move(last, 1);
706 vt_clear(0);
707
708 println(the_title);
709 println("There should be an open rectangle formed by reverse-video E's");
710 holdit();
711
712 test_with_margins(2);
713 decsace(FALSE);
714 fill_screen();
715 deccara(box.top, box.left, box.bottom, box.right, 7); /* invert a rectangle) */
716 deccara(box.top + 1, box.left + 1, box.bottom - 1, box.right - 1, 0); /* invert a rectangle) */
717
718 sgr("0");
719
720 test_with_margins(0);
721
722 vt_move(last, 1);
723 vt_clear(0);
724
725 println(the_title);
726 println("There should be an open rectangle formed by reverse-video E's");
727 println("combined with wrapping at the margins.");
728 return MENU_HOLD;
729 }
730
731 #define fmt_DECCKSR "Testing DECCKSR: %s\n"
732
733 static int
tst_DECCKSR(MENU_ARGS,int Pid,const char * the_csi,int expected)734 tst_DECCKSR(MENU_ARGS, int Pid, const char *the_csi, int expected)
735 {
736 char *report;
737 char *before;
738 char *after;
739 int pos = 0;
740 int actual;
741 int row, col;
742
743 vt_move(1, 1);
744 printf(fmt_DECCKSR, the_title);
745
746 set_tty_raw(TRUE);
747 set_tty_echo(FALSE);
748
749 do_csi("%s", the_csi);
750 report = get_reply();
751 vt_move(row = 3, col = 10);
752 chrprint2(report, row, col);
753 if ((report = skip_dcs(report)) != 0
754 && strip_terminator(report)
755 && strlen(report) > 1
756 && scanto(report, &pos, '!') == Pid
757 && report[pos++] == '~'
758 && (after = skip_xdigits((before = report + pos), &actual)) != 0
759 && *after == '\0') {
760 if ((after - before) != 4) {
761 show_result("%s: expected 4 digits", SHOW_FAILURE);
762 } else if (expected >= 0) {
763 if (actual == expected) {
764 show_result(SHOW_SUCCESS);
765 } else {
766 char msg[80];
767 sprintf(msg, "%04X", (expected & 0xffff));
768 show_result("expected %s", msg);
769 }
770 } else {
771 show_result(SHOW_SUCCESS);
772 }
773 } else {
774 show_result(SHOW_FAILURE);
775 }
776
777 restore_ttymodes();
778 vt_move(max_lines - 1, 1);
779 return MENU_HOLD;
780 }
781
782 /*
783 * VT400 & up.
784 * Copy Rectangular area
785 */
786 static int
tst_DECCRA(MENU_ARGS)787 tst_DECCRA(MENU_ARGS)
788 {
789 #define adj_y 3
790 #define adj_x 4
791 #define adj_DECCRA " (down %d, right %d)\r\n", box.bottom + 1 - box.top, box.right + 1 - box.left, adj_y, adj_x
792 #define msg_DECCRA(msg) "The %dx%d box " msg adj_DECCRA
793 BOX box;
794 int hmargin = origin_mode ? ((get_right_margin() * 3) / 8) : 30;
795 int vmargin = origin_mode ? ((get_bottom_margin(max_lines) * 2) / 5) : 10;
796 int last = max_lines - 3;
797
798 if (make_box_params(&box, vmargin, hmargin) == 0) {
799 box.top = 5;
800 box.left = 5;
801
802 test_with_margins(1);
803
804 if (do_colors) {
805 set_colors(WHITE_ON_BLUE);
806 } else {
807 sgr(BLINK_REVERSE);
808 }
809 draw_box_outline(&box, do_lines ? -1 : '*');
810 sgr("0");
811
812 test_with_margins(0);
813
814 vt_move(last, 1);
815 println(the_title);
816 tprintf(msg_DECCRA("will be copied"));
817 holdit();
818
819 test_with_margins(2);
820
821 deccra(box.top, box.left, box.bottom, box.right, 1,
822 box.top + adj_y, box.left + adj_x, 1);
823
824 test_with_margins(0);
825
826 vt_move(last, 1);
827 vt_clear(0);
828
829 tprintf(msg_DECCRA("should be copied, overlapping"));
830 holdit();
831
832 test_with_margins(2);
833
834 make_box_params(&box, vmargin, hmargin);
835 box.top = 5;
836 box.left = 5;
837
838 if (do_colors) {
839 set_colors(YELLOW_ON_BLACK);
840 } else {
841 sgr("0;7"); /* fill the box in reverse */
842 }
843 draw_box_filled(&box, -1);
844
845 if (do_colors) {
846 set_colors(WHITE_ON_BLUE);
847 } else {
848 sgr(BLINK_REVERSE);
849 }
850 draw_box_outline(&box, do_lines ? -1 : '*');
851 sgr("0");
852
853 test_with_margins(0);
854
855 vt_move(last, 1);
856 println(the_title);
857 tprintf(msg_DECCRA("will be copied"));
858 holdit();
859
860 test_with_margins(2);
861
862 sgr("0;4"); /* set underline, to check if that leaks through */
863 deccra(box.top, box.left, box.bottom, box.right, 1,
864 box.top + adj_y, box.left + adj_x, 1);
865 sgr("0");
866
867 test_with_margins(0);
868
869 vt_move(last, 1);
870 vt_clear(0);
871
872 tprintf(msg_DECCRA("should be copied, overlapping"));
873 }
874 return MENU_HOLD;
875 }
876
877 static int
marker_of(int n)878 marker_of(int n)
879 {
880 return (n - 1) % 26 + 'a';
881 }
882
883 /*
884 * VT400 & up.
885 * Delete column.
886 */
887 static int
tst_DECDC(MENU_ARGS)888 tst_DECDC(MENU_ARGS)
889 {
890 int n;
891 int last = max_lines - 3;
892 int base_row;
893 int base_col;
894 int left_col;
895 int last_row;
896 int real_col;
897 int top;
898 int bot;
899 int lft;
900 int rgt;
901 int final_dc;
902 char mark_1st = 0;
903 char mark_2nd = 0;
904
905 test_with_margins(1);
906
907 set_colors(WHITE_ON_BLUE);
908
909 top = get_top_margin();
910 lft = get_left_margin();
911 rgt = get_right_margin();
912 bot = get_bottom_margin(last - 1);
913
914 /*
915 * Adjustments so that most of the initial line (before shifting) passes
916 * through the area within margins.
917 */
918 if (origin_mode) {
919 base_row = 0;
920 if (lrmm_flag) {
921 left_col = 1;
922 switch (tb_marg_flag) {
923 default:
924 last_row = bot;
925 break;
926 case marReset:
927 case marLast:
928 last_row = bot - 3;
929 break;
930 }
931 base_col = rgt - (bot - top) + last_row;
932 if (base_col < 0)
933 base_col = 0;
934 if (base_col > rgt)
935 base_col = rgt;
936 real_col = lr_marg1 + lft - (lr_marg1 != 0);
937 } else {
938 last_row = last;
939 base_col = (2 * last);
940 left_col = 1;
941 real_col = lft;
942 }
943 } else {
944 switch (lr_marg_flag) {
945 default:
946 base_col = (2 * last);
947 left_col = 1;
948 break;
949 case marFirst:
950 base_col = (min_cols / 2);
951 left_col = 1;
952 break;
953 case marMiddle:
954 base_col = (3 * min_cols) / 4;
955 left_col = (min_cols / 4) + 1;
956 break;
957 case marLast:
958 base_col = min_cols + 0;
959 left_col = (min_cols / 2) + 1;
960 break;
961 }
962 if (tb_marg_flag == marLast) {
963 base_row = max_lines / 2;
964 } else {
965 base_row = 0;
966 }
967 last_row = last;
968 real_col = lft;
969 }
970
971 final_dc = base_col - 1;
972
973 for (n = 1; n < last_row; n++) {
974 int row = base_row + n;
975 int col = base_col - n;
976
977 if (row <= last_row) {
978 int mark = marker_of(n);
979
980 if (row >= top && row <= bot && row < last_row) {
981 mark_2nd = (char) mark;
982 if (mark_1st == 0) {
983 mark_1st = (char) mark;
984 }
985 }
986
987 slowly();
988 __(cup(row, col), print_chr(mark));
989 if (top > 1 || (lrmm_flag && lft > 1)) {
990 __(cup(1, 1), decdc(1)); /* outside margins, should be ignored */
991 __(cup(row, col), print_chr(mark));
992 }
993 if (final_dc-- > left_col)
994 __(cup(top, lft), decdc(1));
995 }
996 }
997 if (final_dc > left_col) {
998 slowly();
999 __(cup(top, lft), decdc(final_dc - left_col));
1000 }
1001
1002 reset_colors();
1003
1004 test_with_margins(0);
1005
1006 ruler(last, min_cols);
1007 vt_move(last + 1, 1);
1008 vt_clear(0);
1009
1010 tprintf("If your terminal supports DECDC, letters %c-%c are on column %d\n",
1011 mark_1st, mark_2nd, real_col);
1012 return MENU_HOLD;
1013 }
1014
1015 /*
1016 * VT400 & up
1017 * Erase Rectangular area
1018 */
1019 static int
tst_DECERA(MENU_ARGS)1020 tst_DECERA(MENU_ARGS)
1021 {
1022 int last = max_lines - 3;
1023 BOX box;
1024
1025 setup_rectangle(&box, last);
1026
1027 fill_screen();
1028
1029 test_with_margins(1);
1030
1031 set_colors(WHITE_ON_GREEN);
1032
1033 decera(box.top, box.left, box.bottom, box.right);
1034
1035 sgr("0");
1036
1037 test_with_margins(0);
1038
1039 vt_move(last, 1);
1040 vt_clear(0);
1041
1042 println(the_title);
1043 if (origin_mode)
1044 println("There should be a rectangle cleared in the middle of the margins.");
1045 else
1046 println("There should be a rectangle cleared in the middle of the screen.");
1047 return MENU_HOLD;
1048 }
1049
1050 /*
1051 * This is two tests: IND (index) and RI (reverse index). For each test, we
1052 * start by filling the area inside (including) the margins with a test
1053 * pattern, and then after the user presses "return", update the screen so that
1054 * only one line of the test-pattern should remain visible.
1055 */
1056 static int
tst_IND_RI(MENU_ARGS)1057 tst_IND_RI(MENU_ARGS)
1058 {
1059 int hold_row = get_hold_row();
1060 int hold_col = get_hold_col(); /* where to put "Push RETURN" */
1061 int row;
1062 int top = get_top_margin();
1063 int bot = get_bottom_margin(max_lines);
1064 int lft = get_left_margin();
1065 int rgt = get_right_margin();
1066
1067 test_with_margins(1);
1068
1069 fill_margins();
1070
1071 set_colors(0);
1072 special_prompt(hold_row, hold_col, 0);
1073
1074 set_colors(WHITE_ON_GREEN);
1075 cup(bot, (lft + rgt) / 2);
1076 for (row = top; row < bot; ++row) {
1077 slowly();
1078 ind();
1079 }
1080
1081 set_colors(0);
1082 special_prompt(hold_row, hold_col, "\"abcd...\" should be at top. ");
1083
1084 fill_margins();
1085 fill_outside('.');
1086
1087 set_colors(0);
1088 special_prompt(hold_row, hold_col, 0);
1089
1090 set_colors(WHITE_ON_GREEN);
1091 cup(top, (lft + rgt) / 2);
1092 for (row = top; row < bot; ++row) {
1093 slowly();
1094 ri();
1095 }
1096
1097 set_colors(0);
1098 special_prompt(hold_row, hold_col, "\"0123...\" should be at bottom. ");
1099
1100 test_with_margins(0);
1101
1102 return MENU_NOHOLD;
1103 }
1104
1105 static int
tst_IL_DL(MENU_ARGS)1106 tst_IL_DL(MENU_ARGS)
1107 {
1108 int hold_row = get_hold_row();
1109 int hold_col = get_hold_col(); /* where to put "Push RETURN" */
1110 int row;
1111 int top = get_top_margin();
1112 int bot = get_bottom_margin(max_lines);
1113 int lft = get_left_margin();
1114 int rgt = get_right_margin();
1115
1116 test_with_margins(1);
1117
1118 fill_margins();
1119
1120 set_colors(0);
1121 special_prompt(hold_row, hold_col, 0);
1122
1123 /*
1124 * This should be ignored because it is outside margins.
1125 */
1126 set_colors(WHITE_ON_GREEN);
1127 if (!origin_mode) {
1128 if (top > 1) {
1129 cup(top - 1, lft);
1130 il(1);
1131 } else if (bot < max_lines) {
1132 cup(bot + 1, lft);
1133 il(1);
1134 } else if (lft > 1) {
1135 cup(top, lft - 1);
1136 il(1);
1137 } else if (rgt < min_cols) {
1138 cup(top, rgt + 1);
1139 il(1);
1140 }
1141 }
1142
1143 cup(top, (lft + rgt) / 2);
1144 for (row = top; row < bot;) {
1145 int skip = (row % 2) + 1;
1146 row += skip;
1147 if (row >= bot)
1148 skip = 1;
1149 slowly();
1150 il(skip);
1151 }
1152
1153 set_colors(0);
1154 special_prompt(hold_row, hold_col, "\"0123...\" should be at bottom. ");
1155
1156 fill_margins();
1157 fill_outside('.');
1158
1159 set_colors(0);
1160 special_prompt(hold_row, hold_col, 0);
1161
1162 set_colors(WHITE_ON_GREEN);
1163 cup(top, (lft + rgt) / 2);
1164 for (row = top; row < bot;) {
1165 int skip = (row % 2) + 1;
1166 row += skip;
1167 if (row >= bot)
1168 skip = 1;
1169 slowly();
1170 dl(skip);
1171 }
1172
1173 set_colors(0);
1174 special_prompt(hold_row, hold_col, "\"abcd...\" should be at top. ");
1175
1176 test_with_margins(0);
1177
1178 return MENU_NOHOLD;
1179 }
1180
1181 static int
tst_ICH_DCH(MENU_ARGS)1182 tst_ICH_DCH(MENU_ARGS)
1183 {
1184 int n;
1185 int last = max_lines - 3;
1186 int base_row;
1187 int base_col;
1188 int last_row;
1189 int real_col;
1190 int top;
1191 int bot;
1192 int lft;
1193 int rgt;
1194 char mark_1st = 0;
1195 char mark_2nd = 0;
1196
1197 test_with_margins(1);
1198
1199 set_colors(WHITE_ON_BLUE);
1200
1201 top = get_top_margin();
1202 bot = get_bottom_margin(last - 1);
1203 lft = get_left_margin();
1204 rgt = get_right_margin();
1205
1206 /*
1207 * Adjustments so that most of the initial line (before shifting) passes
1208 * through the area within margins.
1209 */
1210 if (origin_mode) {
1211 base_row = 0;
1212 if (lrmm_flag) {
1213 base_col = rgt - (bot - top) - 2;
1214 if (base_col < 0)
1215 base_col = 0;
1216 switch (tb_marg_flag) {
1217 default:
1218 last_row = bot;
1219 break;
1220 case marReset:
1221 case marLast:
1222 last_row = bot - 3;
1223 break;
1224 }
1225 real_col = rgt + lr_marg1 - (lr_marg1 != 0);
1226 } else {
1227 last_row = last;
1228 base_col = (2 * last);
1229 real_col = rgt;
1230 }
1231 } else {
1232 switch (lr_marg_flag) {
1233 default:
1234 base_col = (2 * last);
1235 break;
1236 case marFirst:
1237 base_col = 0;
1238 break;
1239 case marMiddle:
1240 base_col = min_cols / 4;
1241 break;
1242 case marLast:
1243 base_col = (min_cols / 2);
1244 break;
1245 }
1246 if (tb_marg_flag == marLast) {
1247 base_row = max_lines / 2;
1248 } else {
1249 base_row = 0;
1250 }
1251 last_row = last;
1252 real_col = rgt;
1253 }
1254
1255 for (n = 1; n < last_row; n++) {
1256 int row = base_row + n;
1257 int col = base_col + n;
1258
1259 if (row < last_row) {
1260 int mark = marker_of(n);
1261
1262 if (row >= top && row <= bot && row < last_row) {
1263 mark_2nd = (char) mark;
1264 if (mark_1st == 0) {
1265 mark_1st = (char) mark;
1266 }
1267 }
1268
1269 slowly();
1270 __(cup(row, col), print_chr(mark));
1271 if (col < rgt) {
1272 cup(row, lft);
1273 print_chr('?');
1274 cup(row, lft);
1275 ich(rgt - col);
1276 }
1277 }
1278 }
1279
1280 reset_colors();
1281
1282 test_with_margins(0);
1283
1284 ruler(last, min_cols);
1285 vt_move(last + 1, 1);
1286 vt_clear(0);
1287
1288 tprintf("If your terminal supports ICH, letters %c-%c are on column %d\n",
1289 mark_1st, mark_2nd, real_col);
1290 holdit();
1291
1292 vt_clear(0);
1293 test_with_margins(1);
1294
1295 set_colors(WHITE_ON_BLUE);
1296
1297 /*
1298 * Adjustments so that most of the initial line (before shifting) passes
1299 * through the area within margins.
1300 */
1301 if (origin_mode) {
1302 base_row = 0;
1303 if (lrmm_flag) {
1304 switch (tb_marg_flag) {
1305 default:
1306 last_row = bot;
1307 break;
1308 case marReset:
1309 case marLast:
1310 last_row = bot - 3;
1311 break;
1312 }
1313 base_col = rgt - (bot - top) + last_row;
1314 if (base_col < 0)
1315 base_col = 0;
1316 if (base_col > rgt)
1317 base_col = rgt;
1318 real_col = lr_marg1 + lft - (lr_marg1 != 0);
1319 } else {
1320 last_row = last;
1321 base_col = (2 * last);
1322 real_col = lft;
1323 }
1324 } else {
1325 switch (lr_marg_flag) {
1326 default:
1327 base_col = (2 * last);
1328 break;
1329 case marFirst:
1330 base_col = (min_cols / 2);
1331 break;
1332 case marMiddle:
1333 base_col = (3 * min_cols) / 4;
1334 break;
1335 case marLast:
1336 base_col = min_cols + 0;
1337 break;
1338 }
1339 if (tb_marg_flag == marLast) {
1340 base_row = max_lines / 2;
1341 } else {
1342 base_row = 0;
1343 }
1344 last_row = last;
1345 real_col = lft;
1346 }
1347
1348 for (n = 1; n < last_row; n++) {
1349 int row = base_row + n;
1350 int col = base_col - n;
1351
1352 if (row <= last_row) {
1353 int mark = marker_of(n);
1354
1355 if (row >= top && row <= bot && row < last_row) {
1356 mark_2nd = (char) mark;
1357 if (mark_1st == 0) {
1358 mark_1st = (char) mark;
1359 }
1360 }
1361
1362 __(cup(row, col), print_chr(mark));
1363 slowly();
1364 if (col < rgt)
1365 ech(rgt - col);
1366 if (col > lft) {
1367 cup(row, lft);
1368 dch(col - lft);
1369 } else {
1370 cup(row, 1);
1371 dch(col - 1);
1372 }
1373 }
1374 }
1375
1376 reset_colors();
1377
1378 test_with_margins(0);
1379
1380 ruler(last, min_cols);
1381 vt_move(last + 1, 1);
1382 vt_clear(0);
1383
1384 tprintf("If your terminal supports DCH, letters %c-%c are on column %d\n",
1385 mark_1st, mark_2nd, real_col);
1386 return MENU_HOLD;
1387 }
1388
1389 /*
1390 * Check to see if ASCII formatting controls (BS, HT, CR) are affected by
1391 * left/right margins. Do this by starting after the left-margin, and
1392 * backspacing "before" the left margin. Then fill the margins with a usable
1393 * test pattern. After that, use tabs to go to the right margin, adding
1394 * another usable test (+), and use carriage returns to go to the left margin,
1395 * adding another usable test (-).
1396 */
1397 static int
tst_ASCII_format(MENU_ARGS)1398 tst_ASCII_format(MENU_ARGS)
1399 {
1400 int last = max_lines - 4;
1401 int top;
1402 int bot;
1403 int lft;
1404 int rgt;
1405 int n;
1406 int tab;
1407 int size;
1408
1409 test_with_margins(1);
1410
1411 top = get_top_margin();
1412 bot = get_bottom_margin(last - 1);
1413 lft = get_left_margin();
1414 rgt = get_right_margin();
1415
1416 /*
1417 * This should stop at the left margin, and the result overwritten by a
1418 * fill-pattern.
1419 */
1420 set_colors(WHITE_ON_BLUE);
1421 cup(top, rgt);
1422 for (n = 0; n < rgt; ++n) {
1423 printf("*%c%c", BS, BS);
1424 }
1425
1426 /*
1427 * Fill the margins with a repeating pattern. Do it twice, to force it to
1428 * scroll up.
1429 */
1430 set_colors(WHITE_ON_GREEN);
1431 size = 2 * (rgt - lft + 1) * (bot - top + 1);
1432 for (n = 0; n < size; ++n) {
1433 int ch = ((n % 10) ? ((n % 10) + '0') : '_');
1434 putchar(ch);
1435 }
1436
1437 /*
1438 * Mark the margins with '-' (left) and '+' (right).
1439 */
1440 set_colors(YELLOW_ON_BLACK);
1441 cup(top, lft);
1442 for (n = top; n <= bot; ++n) {
1443 for (tab = 0; tab < (rgt - lft + 16) / TABWIDTH; ++tab) {
1444 putchar(TAB);
1445 }
1446 putchar('+');
1447 putchar(CR);
1448 putchar('-');
1449 putchar(TAB);
1450 putchar('*');
1451 if (n < bot) {
1452 putchar(LF);
1453 }
1454 }
1455
1456 test_with_margins(0);
1457
1458 set_colors("0");
1459
1460 vt_move(last, 1);
1461 vt_clear(0);
1462
1463 ruler(last, min_cols);
1464 println(the_title);
1465 println("A repeating \"0123456789_\" pattern should fall within the -/+ margins");
1466 return MENU_HOLD;
1467 }
1468
1469 /*
1470 * VT400 & up.
1471 *
1472 * DECFI - Forward Index
1473 * This control function moves the column forward one column. If the cursor is
1474 * at the right margin, then all screen data within the margins moves one
1475 * column to the left. The column shifted past the left margin is lost.
1476 *
1477 * Format: ESC 9
1478 * Description:
1479 * DECFI adds a new column at the right margin with no visual attributes.
1480 * DECFI is not affected by the margins. If the cursor is at the right border
1481 * of the page when the terminal receives DECFI, then the terminal ignores
1482 * DECFI.
1483 */
1484 static int
tst_DECFI(MENU_ARGS)1485 tst_DECFI(MENU_ARGS)
1486 {
1487 int n, m;
1488 int last = max_lines - 4;
1489 int final;
1490 int top;
1491 int lft;
1492 int rgt;
1493
1494 test_with_margins(1);
1495
1496 set_colors(WHITE_ON_BLUE);
1497
1498 top = get_top_margin();
1499 lft = get_left_margin();
1500 rgt = get_right_margin();
1501
1502 final = (rgt - lft + 1) / 4;
1503
1504 for (n = 1; n <= final; n++) {
1505 slowly();
1506 cup(top, rgt - 3);
1507 printf("%3d", n); /* leaves cursor in rightmost column */
1508 if (n != final) {
1509 for (m = 0; m < 4; m++)
1510 decfi();
1511 }
1512 }
1513
1514 reset_colors();
1515
1516 test_with_margins(0);
1517
1518 vt_move(last, 1);
1519 vt_clear(0);
1520
1521 println(the_title);
1522 println("If your terminal supports DECFI (forward index), then the top row");
1523 printf("should be numbered 1 through %d.\n", final);
1524 return MENU_HOLD;
1525 }
1526
1527 /*
1528 * Demonstrate whether cursor movement is limited by margins. VT420 manual
1529 * says that CUU/CUD will stop on the margins, but if outside the margins
1530 * will proceed to the page border. So we can test this by
1531 *
1532 * a) moving to the margin, and cursor up/down toward the border, placing a
1533 * marker at the end of the cursor movement (to overwrite a prior marker placed
1534 * explicitly on the border).
1535 *
1536 * b) repeat the process, going from the border into the area within margins.
1537 *
1538 * c) Even for the no-margins case, this is useful, since it demonstrates
1539 * whether the cursor forces scrolling.
1540 */
1541 static int
tst_cursor_margins(MENU_ARGS)1542 tst_cursor_margins(MENU_ARGS)
1543 {
1544 BOX box;
1545 int last = get_hold_row();
1546 int row;
1547 int col;
1548
1549 test_with_margins(1);
1550
1551 box.top = get_top_margin();
1552 box.left = get_left_margin();
1553 box.right = get_right_margin();
1554 box.bottom = get_bottom_margin(max_lines);
1555
1556 set_colors(WHITE_ON_BLUE);
1557 draw_box_filled(&box, ' ');
1558 draw_box_outline(&box, '*');
1559 set_colors(WHITE_ON_GREEN);
1560
1561 for (row = box.top; row <= box.bottom; ++row) {
1562 cup(row, box.left);
1563 for (col = min_cols; col > 0; col--) {
1564 cub(1);
1565 }
1566 putchar('l');
1567 }
1568
1569 for (row = box.top; row <= box.bottom; ++row) {
1570 cup(row, box.right);
1571 for (col = 1; col <= min_cols; col++) {
1572 cuf(1);
1573 }
1574 putchar('r');
1575 }
1576
1577 for (col = box.left; col <= box.right; ++col) {
1578 cup(box.top, col);
1579 for (row = box.top; row > 0; row--) {
1580 cuu(1);
1581 }
1582 putchar('u');
1583 }
1584
1585 for (col = box.left; col <= box.right; ++col) {
1586 cup(box.bottom, col);
1587 for (row = box.bottom; row <= max_lines; row++) {
1588 cud(1);
1589 }
1590 putchar('d');
1591 }
1592
1593 set_colors("0");
1594 test_with_margins(0);
1595
1596 vt_move(last, 1);
1597 if (last > box.bottom)
1598 vt_clear(0);
1599
1600 println(the_title);
1601 println("A box of *'s was written on screen border, overwritten using margins (u/d/l/r)");
1602 return MENU_HOLD;
1603 }
1604
1605 /*
1606 * Test movement with other things than cursor controls, i.e., BS, HT, CR, LF,
1607 * to see how margins affect them.
1608 */
1609 static int
tst_other_margins(MENU_ARGS)1610 tst_other_margins(MENU_ARGS)
1611 {
1612 BOX box;
1613 int last = get_hold_row();
1614 int row;
1615 int col;
1616
1617 test_with_margins(1);
1618
1619 box.top = get_top_margin();
1620 box.left = get_left_margin();
1621 box.right = get_right_margin();
1622 box.bottom = get_bottom_margin(max_lines);
1623
1624 set_colors(WHITE_ON_BLUE);
1625 draw_box_filled(&box, ' ');
1626 draw_box_outline(&box, '*');
1627 set_colors(WHITE_ON_GREEN);
1628
1629 for (row = box.top; row <= box.bottom; ++row) {
1630 cup(row, box.left);
1631 for (col = box.left; col > 0; col--) {
1632 putchar('\b');
1633 }
1634 putchar('l');
1635 }
1636
1637 for (row = box.top; row <= box.bottom; ++row) {
1638 cup(row, box.right);
1639 for (col = 1; col <= min_cols; col++) {
1640 putchar('\t');
1641 }
1642 putchar('r');
1643 }
1644
1645 for (col = box.left; col <= box.right; ++col) {
1646 cup(box.top, col);
1647 putchar('u');
1648 for (row = box.bottom; row > box.top; row--) {
1649 ind();
1650 }
1651 }
1652
1653 for (col = box.left; col <= box.right; ++col) {
1654 switch (col % 4) {
1655 case 0:
1656 cup(box.bottom, col);
1657 putchar('d');
1658 break;
1659 case 1:
1660 cup(box.top, col);
1661 for (row = box.top; row < box.bottom; row++) {
1662 putchar('\f');
1663 }
1664 putchar('d');
1665 break;
1666 case 2:
1667 cup(box.top, col);
1668 for (row = box.top; row < box.bottom; row++) {
1669 nel();
1670 cuf(col - 1);
1671 }
1672 putchar('d');
1673 break;
1674 case 3:
1675 cup(box.bottom, col);
1676 putchar('d');
1677 for (row = box.top; row < box.bottom; row++) {
1678 ri();
1679 }
1680 putchar('u');
1681 break;
1682 }
1683 }
1684
1685 set_colors("0");
1686 test_with_margins(0);
1687
1688 vt_move(last, 1);
1689 if (hold_clear())
1690 vt_clear(0);
1691
1692 println(the_title);
1693 println("A box of *'s was written on screen border, overwritten using margins (u/d/l/r)");
1694 return MENU_HOLD;
1695 }
1696
1697 /*
1698 * VT400 & up
1699 * Fill Rectangular area
1700 */
1701 static int
tst_DECFRA(MENU_ARGS)1702 tst_DECFRA(MENU_ARGS)
1703 {
1704 int last = max_lines - 3;
1705 BOX box;
1706
1707 setup_rectangle(&box, last);
1708
1709 test_with_margins(1);
1710
1711 if (do_colors) {
1712 set_colors(WHITE_ON_BLUE);
1713 vt_clear(2); /* xterm fills the whole screen's background */
1714 set_colors(WHITE_ON_GREEN);
1715 }
1716 decfra('*', box.top, box.left, box.bottom, box.right);
1717
1718 set_colors("0");
1719
1720 test_with_margins(0);
1721
1722 vt_move(last, 1);
1723 vt_clear(0);
1724
1725 println(the_title);
1726 if (origin_mode)
1727 println("There should be a rectangle of *'s in the middle of the margins.");
1728 else
1729 println("There should be a rectangle of *'s in the middle of the screen.");
1730 holdit();
1731
1732 test_with_margins(2);
1733
1734 set_colors(WHITE_ON_BLUE);
1735
1736 decfra(' ', box.top, box.left, box.bottom, box.right);
1737 sgr("0");
1738
1739 test_with_margins(0);
1740
1741 vt_move(last, 1);
1742 vt_clear(0);
1743
1744 println(the_title);
1745 println("The rectangle of *'s should be gone.");
1746 return MENU_HOLD;
1747 }
1748
1749 /*
1750 * VT400 & up.
1751 * Insert column.
1752 */
1753 static int
tst_DECIC(MENU_ARGS)1754 tst_DECIC(MENU_ARGS)
1755 {
1756 int n;
1757 int last = max_lines - 3;
1758 int base_row;
1759 int base_col;
1760 int last_row;
1761 int last_col;
1762 int real_col;
1763 int top;
1764 int bot;
1765 int lft;
1766 int rgt;
1767 int final_ic;
1768 char mark_1st = 0;
1769 char mark_2nd = 0;
1770
1771 test_with_margins(1);
1772
1773 set_colors(WHITE_ON_BLUE);
1774
1775 top = get_top_margin();
1776 bot = get_bottom_margin(last - 1);
1777 lft = get_left_margin();
1778 rgt = get_right_margin();
1779
1780 /*
1781 * Adjustments so that most of the initial line (before shifting) passes
1782 * through the area within margins.
1783 */
1784 if (origin_mode) {
1785 base_row = 0;
1786 if (lrmm_flag) {
1787 base_col = rgt - (bot - top) - 2;
1788 if (base_col < 0)
1789 base_col = 0;
1790 last_col = rgt - 1;
1791 switch (tb_marg_flag) {
1792 default:
1793 last_row = bot;
1794 break;
1795 case marReset:
1796 case marLast:
1797 last_row = bot - 3;
1798 break;
1799 }
1800 real_col = rgt + lr_marg1 - (lr_marg1 != 0);
1801 } else {
1802 last_row = last;
1803 base_col = (2 * last);
1804 last_col = min_cols - 1;
1805 real_col = rgt;
1806 }
1807 } else {
1808 if (lrmm_flag) {
1809 switch (lr_marg_flag) {
1810 default:
1811 base_col = (2 * last);
1812 last_col = min_cols - 1;
1813 break;
1814 case marFirst:
1815 base_col = 0;
1816 last_col = min_cols / 2 - 1;
1817 break;
1818 case marMiddle:
1819 base_col = min_cols / 4;
1820 last_col = (3 * min_cols) / 4 - 1;
1821 break;
1822 case marLast:
1823 base_col = (min_cols / 2);
1824 last_col = min_cols - 1;
1825 break;
1826 }
1827 } else {
1828 base_col = (2 * last);
1829 last_col = min_cols - 1;
1830 }
1831 if (tb_marg_flag == marLast) {
1832 base_row = max_lines / 2;
1833 } else {
1834 base_row = 0;
1835 }
1836 last_row = last;
1837 real_col = rgt;
1838 }
1839
1840 final_ic = base_col;
1841
1842 for (n = 1; n < last_row; n++) {
1843 int row = base_row + n;
1844 int col = base_col + n;
1845
1846 if (row < last_row) {
1847 int mark = marker_of(n);
1848
1849 if (row >= top && row <= bot && row < last_row) {
1850 mark_2nd = (char) mark;
1851 if (mark_1st == 0) {
1852 mark_1st = (char) mark;
1853 }
1854 }
1855
1856 slowly();
1857 __(cup(row, col), print_chr(mark));
1858 if (!origin_mode && (top > 1 || (lrmm_flag && lft > 1))) {
1859 __(cup(1, 1), decic(1)); /* outside margins, should be ignored */
1860 __(cup(row, col), print_chr(mark));
1861 }
1862 if (final_ic++ <= last_col)
1863 __(cup(top, lft), decic(1));
1864 }
1865 }
1866 if (final_ic <= last_col) {
1867 slowly();
1868 decic(last_col - final_ic);
1869 }
1870
1871 reset_colors();
1872
1873 test_with_margins(0);
1874
1875 ruler(last, min_cols);
1876 vt_move(last + 1, 1);
1877 vt_clear(0);
1878
1879 tprintf("If your terminal supports DECIC, letters %c-%c are on column %d\n",
1880 mark_1st, mark_2nd, real_col);
1881 return MENU_HOLD;
1882 }
1883
1884 static int
tst_DECIC_DECDC(MENU_ARGS)1885 tst_DECIC_DECDC(MENU_ARGS)
1886 {
1887 tst_DECIC(PASS_ARGS);
1888 holdit();
1889 vt_clear(2);
1890 tst_DECDC(PASS_ARGS);
1891 return MENU_HOLD;
1892 }
1893
1894 static int
tst_DECKBUM(MENU_ARGS)1895 tst_DECKBUM(MENU_ARGS)
1896 {
1897 vt_move(1, 1);
1898 println(the_title);
1899
1900 set_tty_raw(TRUE);
1901 set_tty_echo(FALSE);
1902
1903 deckbum(TRUE);
1904 println("The keyboard is set for data processing.");
1905 show_keypress(3, 10);
1906
1907 vt_move(10, 1);
1908 deckbum(FALSE);
1909 println("The keyboard is set for normal (typewriter) processing.");
1910 show_keypress(11, 10);
1911
1912 restore_ttymodes();
1913 vt_move(max_lines - 1, 1);
1914 return MENU_HOLD;
1915 }
1916
1917 static int
tst_DECKPM(MENU_ARGS)1918 tst_DECKPM(MENU_ARGS)
1919 {
1920 vt_move(1, 1);
1921 println(the_title);
1922
1923 set_tty_raw(TRUE);
1924 set_tty_echo(FALSE);
1925
1926 deckpm(TRUE);
1927 println("The keyboard is set for position reports.");
1928 show_keypress(3, 10);
1929
1930 vt_move(10, 1);
1931 deckpm(FALSE);
1932 println("The keyboard is set for character codes.");
1933 show_keypress(11, 10);
1934
1935 restore_ttymodes();
1936 vt_move(max_lines - 1, 1);
1937 return MENU_HOLD;
1938 }
1939
1940 static int
tst_DECNKM(MENU_ARGS)1941 tst_DECNKM(MENU_ARGS)
1942 {
1943 vt_move(1, 1);
1944 println(the_title);
1945
1946 set_tty_raw(TRUE);
1947 set_tty_echo(FALSE);
1948
1949 decnkm(FALSE);
1950 println("Press one or more keys on the keypad. They should generate numeric codes.");
1951 show_keypress(3, 10);
1952
1953 vt_move(10, 1);
1954 decnkm(TRUE);
1955 println("Press one or more keys on the keypad. They should generate control codes.");
1956 show_keypress(11, 10);
1957
1958 decnkm(FALSE);
1959 vt_move(max_lines - 1, 1);
1960 restore_ttymodes();
1961 return MENU_HOLD;
1962 }
1963
1964 /*
1965 * VT400 & up
1966 * Reverse Attributes in Rectangular Area
1967 */
1968 static int
tst_DECRARA(MENU_ARGS)1969 tst_DECRARA(MENU_ARGS)
1970 {
1971 int last = max_lines - 4;
1972 BOX box;
1973
1974 setup_rectangle(&box, last);
1975
1976 decsace(TRUE);
1977 fill_screen();
1978
1979 test_with_margins(1);
1980
1981 decrara(box.top, box.left, box.bottom, box.right, 7); /* invert a rectangle) */
1982 decrara(box.top + 1, box.left + 1, box.bottom - 1, box.right - 1, 7); /* invert a rectangle) */
1983
1984 sgr("0");
1985
1986 test_with_margins(0);
1987
1988 vt_move(last, 1);
1989 vt_clear(0);
1990
1991 println(the_title);
1992 println("There should be an open rectangle formed by reverse-video E's");
1993 holdit();
1994
1995 decsace(FALSE);
1996 fill_screen();
1997
1998 test_with_margins(1);
1999
2000 decrara(box.top, box.left, box.bottom, box.right, 7); /* invert a rectangle) */
2001 decrara(box.top + 1, box.left + 1, box.bottom - 1, box.right - 1, 7); /* invert a rectangle) */
2002
2003 sgr("0");
2004
2005 test_with_margins(0);
2006
2007 vt_move(last, 1);
2008 vt_clear(0);
2009
2010 println(the_title);
2011 println("There should be an open rectangle formed by reverse-video E's");
2012 println("combined with wrapping at the margins.");
2013 return MENU_HOLD;
2014 }
2015
2016 int
tst_vt420_DECRQSS(MENU_ARGS)2017 tst_vt420_DECRQSS(MENU_ARGS)
2018 {
2019 /* *INDENT-OFF* */
2020 static MENU my_menu[] = {
2021 { "Exit", 0 },
2022 { "Test VT320 features (DECRQSS)", tst_vt320_DECRQSS },
2023 { "Select attribute change extent (DECSACE)", rpt_DECSACE },
2024 { "Set number of lines per screen (DECSNLS)", rpt_DECSNLS },
2025 { "Set left and right margins (DECSLRM)", rpt_DECSLRM },
2026 { "Enable local functions (DECELF)", rpt_DECELF },
2027 { "Local function key control (DECLFKC)", rpt_DECLFKC },
2028 { "Select modifier key reporting (DECSMKR)", rpt_DECSMKR },
2029 { "", 0 }
2030 };
2031 /* *INDENT-ON* */
2032
2033 do {
2034 vt_clear(2);
2035 __(title(0), printf("VT420 Status-Strings Reports"));
2036 __(title(2), println("Choose test type:"));
2037 } while (menu(my_menu));
2038 return MENU_NOHOLD;
2039 }
2040
2041 /*
2042 * Selective-Erase Rectangular area
2043 */
2044 static int
tst_DECSERA(MENU_ARGS)2045 tst_DECSERA(MENU_ARGS)
2046 {
2047 int last = max_lines - 3;
2048 BOX box;
2049
2050 setup_rectangle(&box, last);
2051
2052 /*
2053 * Part 1: clear the borders of a rectangle, leaving protect inner rectangle.
2054 */
2055 fill_screen();
2056
2057 test_with_margins(1);
2058
2059 set_colors(WHITE_ON_GREEN);
2060
2061 /*
2062 * Protect an area slightly smaller than we will erase.
2063 *
2064 * That way (since the SGR color at this point differs from the color used to
2065 * fill the screen), we can see whether the colors are modified by the erase,
2066 * and if so, whether they come from the SGR color.
2067 */
2068 decfra('*', box.top, box.left, box.bottom, box.right);
2069 decsca(1);
2070 decfra('*', box.top + 1, box.left + 1, box.bottom - 1, box.right - 1);
2071 decsca(0);
2072
2073 sgr("0");
2074
2075 test_with_margins(0);
2076
2077 vt_move(last, 1);
2078 vt_clear(0);
2079
2080 println(the_title);
2081 tprintf("Rectangle %d,%d - %d,%d was filled using DECFRA\n",
2082 box.top,
2083 box.left,
2084 box.bottom,
2085 box.right);
2086 holdit();
2087
2088 test_with_margins(2); /* reenable but do not paint margins */
2089
2090 set_colors(WHITE_ON_BLUE);
2091
2092 decsera(box.top, box.left, box.bottom, box.right); /* erase the border */
2093
2094 sgr("0");
2095
2096 test_with_margins(0);
2097
2098 vt_move(last, 1);
2099 vt_clear(0);
2100
2101 println(the_title);
2102 tprintf("Border %d,%d - %d,%d is cleared using DECSERA\n",
2103 box.top,
2104 box.left,
2105 box.bottom,
2106 box.right);
2107 holdit();
2108
2109 /*
2110 * Part 2: clear within the borders instead of clearing the borders.
2111 */
2112 fill_screen();
2113
2114 test_with_margins(1);
2115
2116 set_colors(WHITE_ON_GREEN);
2117
2118 /*
2119 * Protect a rectangle and overwrite an inner rectangle which is not
2120 * protected.
2121 *
2122 * That way (since the SGR color at this point differs from the color used to
2123 * fill the screen), we can see whether the colors are modified by the erase,
2124 * and if so, whether they come from the SGR color.
2125 */
2126 decsca(1);
2127 decfra('*', box.top, box.left, box.bottom, box.right);
2128 decsca(0);
2129 decfra('*', box.top + 1, box.left + 1, box.bottom - 1, box.right - 1);
2130
2131 sgr("0");
2132
2133 test_with_margins(0);
2134
2135 vt_move(last, 1);
2136 vt_clear(0);
2137
2138 println(the_title);
2139 tprintf("Rectangle %d,%d - %d,%d was filled using DECFRA\n",
2140 box.top,
2141 box.left,
2142 box.bottom,
2143 box.right);
2144 holdit();
2145
2146 test_with_margins(2); /* reenable but do not paint margins */
2147
2148 set_colors(WHITE_ON_BLUE);
2149
2150 decsera(box.top, box.left, box.bottom, box.right); /* erase inside border */
2151
2152 sgr("0");
2153
2154 test_with_margins(0);
2155
2156 vt_move(last, 1);
2157 vt_clear(0);
2158
2159 println(the_title);
2160 tprintf("Inside %d,%d - %d,%d is cleared using DECSERA\n",
2161 box.top + 1,
2162 box.left + 1,
2163 box.bottom - 1,
2164 box.right - 1);
2165
2166 return MENU_HOLD;
2167 }
2168
2169 static int
tst_DECSNLS(MENU_ARGS)2170 tst_DECSNLS(MENU_ARGS)
2171 {
2172 int rows;
2173 int row, col;
2174 char temp[80];
2175
2176 vt_move(row = 1, col = 1);
2177 println("Testing Select Number of Lines per Screen (DECSNLS)");
2178 println("");
2179
2180 for (rows = 48; rows >= 24; rows -= 12) {
2181 set_tty_raw(TRUE);
2182 set_tty_echo(FALSE);
2183
2184 row += 2;
2185 sprintf(temp, "%d Lines/Screen:", rows);
2186 fputs(temp, stdout);
2187 decsnls(rows);
2188 decrqss("*|");
2189 chrprint2(instr(), row, (int) strlen(temp));
2190 println("");
2191
2192 restore_ttymodes();
2193 holdit();
2194 }
2195
2196 return MENU_NOHOLD;
2197 }
2198
2199 static int
tst_DSR_area_sum(MENU_ARGS)2200 tst_DSR_area_sum(MENU_ARGS)
2201 {
2202 char buffer[1024];
2203 int expected = 0;
2204 int pid = 1;
2205 int page = 1;
2206 int r, c;
2207 int rows = 2; /* first two rows have known content */
2208 size_t len;
2209
2210 sprintf(buffer, fmt_DECCKSR, the_title);
2211 len = strlen(buffer) - 1;
2212 memset(buffer + len, ' ', sizeof(buffer) - len);
2213 for (r = 0; r < rows; ++r) {
2214 for (c = 0; c < min_cols; ++c) {
2215 expected += (unsigned char) buffer[(min_cols * r) + c];
2216 expected &= 0xffff;
2217 }
2218 }
2219
2220 /* compute a checksum on the title line, which contains some text */
2221 sprintf(buffer, "%d;%d;1;1;%d;%d*y", pid, page, rows, min_cols);
2222 return tst_DECCKSR(PASS_ARGS, 1, buffer, expected);
2223 }
2224
2225 static int
tst_DSR_data_ok(MENU_ARGS)2226 tst_DSR_data_ok(MENU_ARGS)
2227 {
2228 return any_DSR(PASS_ARGS, "?75n", show_DataIntegrity);
2229 }
2230
2231 static int
tst_DSR_macrospace(MENU_ARGS)2232 tst_DSR_macrospace(MENU_ARGS)
2233 {
2234 int row, col;
2235 char *report;
2236 const char *show;
2237
2238 vt_move(1, 1);
2239 printf("Testing DECMSR: %s\n", the_title);
2240
2241 set_tty_raw(TRUE);
2242 set_tty_echo(FALSE);
2243
2244 do_csi("?62n");
2245 report = instr();
2246 vt_move(row = 3, col = 10);
2247 chrprint2(report, row, col);
2248 if ((report = skip_csi(report)) != 0
2249 && (report = skip_digits(report)) != 0
2250 && !strcmp(report, "*{")) {
2251 show = SHOW_SUCCESS;
2252 } else {
2253 show = SHOW_FAILURE;
2254 }
2255 show_result("%s", show);
2256
2257 restore_ttymodes();
2258 vt_move(max_lines - 1, 1);
2259 return MENU_HOLD;
2260 }
2261
2262 static int
tst_DSR_memory_sum(MENU_ARGS)2263 tst_DSR_memory_sum(MENU_ARGS)
2264 {
2265 return tst_DECCKSR(PASS_ARGS, 1, "?63;1n", -1);
2266 }
2267
2268 static int
tst_DSR_multisession(MENU_ARGS)2269 tst_DSR_multisession(MENU_ARGS)
2270 {
2271 return any_DSR(PASS_ARGS, "?85n", show_MultisessionStatus);
2272 }
2273
2274 int
tst_SRM(MENU_ARGS)2275 tst_SRM(MENU_ARGS)
2276 {
2277 int oldc, newc;
2278
2279 vt_move(1, 1);
2280 println(the_title);
2281
2282 set_tty_raw(TRUE);
2283
2284 set_tty_echo(FALSE);
2285 srm(FALSE);
2286
2287 println("Local echo is enabled, remote echo disabled. Press any keys, repeat to quit.");
2288 vt_move(3, 10);
2289
2290 oldc = -1;
2291 while ((newc = inchar()) != oldc)
2292 oldc = newc;
2293
2294 set_tty_echo(TRUE);
2295 srm(TRUE);
2296
2297 vt_move(10, 1);
2298 println("Local echo is disabled, remote echo enabled. Press any keys, repeat to quit.");
2299 vt_move(11, 10);
2300
2301 oldc = -1;
2302 while ((newc = inchar()) != oldc)
2303 oldc = newc;
2304
2305 vt_move(max_lines - 1, 1);
2306 restore_ttymodes();
2307 return MENU_HOLD;
2308 }
2309
2310 /******************************************************************************/
2311
2312 void
setup_vt420_cursor(MENU_ARGS)2313 setup_vt420_cursor(MENU_ARGS)
2314 {
2315 tb_marg_flag = marNone;
2316 toggle_STBM(PASS_ARGS);
2317
2318 lr_marg_flag = marNone;
2319 toggle_SLRM(PASS_ARGS);
2320 }
2321
2322 void
menus_vt420_cursor(void)2323 menus_vt420_cursor(void)
2324 {
2325 sprintf(origin_mode_mesg, "%s DECOM (origin mode)", STR_ENABLE(origin_mode));
2326 sprintf(lrmm_mesg, "%s DECLRMM (left/right mode)", STR_ENABLE(lrmm_flag));
2327 sprintf(txt_override_color, "%s test-regions (xterm)",
2328 do_colors ? "Color" : "Do not color");
2329 }
2330
2331 void
finish_vt420_cursor(MENU_ARGS)2332 finish_vt420_cursor(MENU_ARGS)
2333 {
2334 reset_colors();
2335 do_colors = FALSE;
2336
2337 if (tb_marg_flag > marReset)
2338 decstbm(0, 0);
2339
2340 if (lr_marg_flag > marReset) {
2341 if (!lrmm_flag)
2342 toggle_LRMM(PASS_ARGS);
2343 decslrm(0, 0);
2344 }
2345
2346 if (lrmm_flag)
2347 toggle_LRMM(PASS_ARGS);
2348
2349 if (origin_mode) {
2350 decom(FALSE);
2351 origin_mode = FALSE;
2352 }
2353 }
2354
2355 /*
2356 * The main vt100 module tests CUP, HVP, CUF, CUB, CUU, CUD
2357 */
2358 int
tst_vt420_cursor(MENU_ARGS)2359 tst_vt420_cursor(MENU_ARGS)
2360 {
2361 /* *INDENT-OFF* */
2362 static MENU my_menu[] = {
2363 { "Exit", 0 },
2364 { "Test VT320 features", tst_vt320_cursor },
2365 { origin_mode_mesg, toggle_DECOM },
2366 { lrmm_mesg, toggle_LRMM },
2367 { tb_marg_mesg, toggle_STBM },
2368 { lr_marg_mesg, toggle_SLRM },
2369 { txt_override_color, toggle_color_mode, },
2370 { "Test Back Index (DECBI)", tst_DECBI },
2371 { "Test Forward Index (DECFI)", tst_DECFI },
2372 { "Test cursor movement within margins", tst_cursor_margins },
2373 { "Test other movement (CR/HT/LF/FF) within margins", tst_other_margins },
2374 { "", 0 }
2375 };
2376 /* *INDENT-ON* */
2377
2378 setup_vt420_cursor(PASS_ARGS);
2379
2380 do {
2381 vt_clear(2);
2382 __(title(0), printf("VT420 Cursor-Movement Tests"));
2383 __(title(2), println("Choose test type:"));
2384 menus_vt420_cursor();
2385 } while (menu(my_menu));
2386
2387 finish_vt420_cursor(PASS_ARGS);
2388
2389 return MENU_NOHOLD;
2390 }
2391
2392 /******************************************************************************/
2393
2394 static int
show_DECSTBM(MENU_ARGS)2395 show_DECSTBM(MENU_ARGS)
2396 {
2397 int code;
2398 decstbm(tb_marg1, tb_marg2);
2399 code = rpt_DECSTBM(PASS_ARGS);
2400 return code;
2401 }
2402
2403 static int
show_DECSLRM(MENU_ARGS)2404 show_DECSLRM(MENU_ARGS)
2405 {
2406 int code;
2407 decslrm(lr_marg1, lr_marg2);
2408 code = rpt_DECSLRM(PASS_ARGS);
2409 return code;
2410 }
2411
2412 /*
2413 * The main vt100 module tests IRM, DL, IL, DCH, ICH, ED, EL
2414 * The vt220 module tests ECH and DECSCA
2415 */
2416 static int
tst_VT420_editing(MENU_ARGS)2417 tst_VT420_editing(MENU_ARGS)
2418 {
2419 /* *INDENT-OFF* */
2420 static MENU my_menu[] = {
2421 { "Exit", 0 },
2422 { origin_mode_mesg, toggle_DECOM },
2423 { lrmm_mesg, toggle_LRMM },
2424 { tb_marg_mesg, toggle_STBM },
2425 { lr_marg_mesg, toggle_SLRM },
2426 { txt_override_color, toggle_color_mode, },
2427 { "Show DECRQM response for DECLRMM", show_DECLRMM },
2428 { "Show DECRQSS response for DECSTBM", show_DECSTBM },
2429 { "Show DECRQSS response for DECSLRM", show_DECSLRM },
2430 { "Test insert/delete column (DECIC, DECDC)", tst_DECIC_DECDC },
2431 { "Test vertical scrolling (IND, RI)", tst_IND_RI },
2432 { "Test insert/delete line (IL, DL)", tst_IL_DL },
2433 { "Test insert/delete char (ICH, DCH)", tst_ICH_DCH },
2434 { "Test ASCII formatting (BS, CR, TAB)", tst_ASCII_format },
2435 { "", 0 }
2436 };
2437 /* *INDENT-ON* */
2438
2439 setup_vt420_cursor(PASS_ARGS);
2440
2441 do {
2442 vt_clear(2);
2443 __(title(0), printf("VT420 Editing Sequence Tests"));
2444 __(title(2), println("Choose test type:"));
2445 menus_vt420_cursor();
2446 } while (menu(my_menu));
2447
2448 finish_vt420_cursor(PASS_ARGS);
2449
2450 return MENU_NOHOLD;
2451 }
2452
2453 /******************************************************************************/
2454
2455 /*
2456 * The main vt100 module tests LNM, DECKPAM, DECARM, DECAWM
2457 */
2458 static int
tst_VT420_keyboard_ctl(MENU_ARGS)2459 tst_VT420_keyboard_ctl(MENU_ARGS)
2460 {
2461 /* *INDENT-OFF* */
2462 static MENU my_menu[] = {
2463 { "Exit", 0 },
2464 { "Test Backarrow key (DECBKM)", tst_DECBKM },
2465 { "Test Numeric keypad (DECNKM)", tst_DECNKM },
2466 { "Test Keyboard usage (DECKBUM)", tst_DECKBUM },
2467 { "Test Key position (DECKPM)", tst_DECKPM },
2468 { "Test Enable Local Functions (DECELF)", not_impl },
2469 { "Test Local Function-Key Control (DECLFKC)", not_impl },
2470 { "Test Select Modifier-Key Reporting (DECSMKR)", not_impl }, /* DECEKBD */
2471 { "", 0 }
2472 };
2473 /* *INDENT-ON* */
2474
2475 do {
2476 vt_clear(2);
2477 __(title(0), printf("VT420 Keyboard-Control Tests"));
2478 __(title(2), println("Choose test type:"));
2479 } while (menu(my_menu));
2480 return MENU_NOHOLD;
2481 }
2482
2483 /******************************************************************************/
2484
2485 static int
tst_VT420_rectangle(MENU_ARGS)2486 tst_VT420_rectangle(MENU_ARGS)
2487 {
2488 static char txt_override_lines[80];
2489 /* *INDENT-OFF* */
2490 static MENU my_menu[] = {
2491 { "Exit", 0 },
2492 { origin_mode_mesg, toggle_DECOM },
2493 { lrmm_mesg, toggle_LRMM },
2494 { tb_marg_mesg, toggle_STBM },
2495 { lr_marg_mesg, toggle_SLRM },
2496 { txt_override_color, toggle_color_mode, },
2497 { txt_override_lines, toggle_lines_mode, },
2498 { "Test Change-Attributes in Rectangular Area (DECCARA)", tst_DECCARA },
2499 { "Test Copy Rectangular area (DECCRA)", tst_DECCRA },
2500 { "Test Erase Rectangular area (DECERA)", tst_DECERA },
2501 { "Test Fill Rectangular area (DECFRA)", tst_DECFRA },
2502 { "Test Reverse-Attributes in Rectangular Area (DECRARA)", tst_DECRARA },
2503 { "Test Selective-Erase Rectangular area (DECSERA)", tst_DECSERA },
2504 { "", 0 }
2505 };
2506 /* *INDENT-ON* */
2507
2508 setup_vt420_cursor(PASS_ARGS);
2509
2510 do {
2511 vt_clear(2);
2512 __(title(0), printf("VT420 Rectangular Area Tests%s",
2513 ((terminal_id() < 400)
2514 ? " (should not work)"
2515 : "")));
2516 __(title(2), println("Choose test type:"));
2517 menus_vt420_cursor();
2518 sprintf(txt_override_lines, "%s line-drawing characters",
2519 do_lines ? "Use" : "Do not use");
2520 } while (menu(my_menu));
2521
2522 finish_vt420_cursor(PASS_ARGS);
2523
2524 return MENU_NOHOLD;
2525 }
2526
2527 /******************************************************************************/
2528
2529 /* UDK and rectangle-checksum status are available only on VT400 */
2530
2531 int
tst_vt420_device_status(MENU_ARGS)2532 tst_vt420_device_status(MENU_ARGS)
2533 {
2534 /* *INDENT-OFF* */
2535 static MENU my_menu[] = {
2536 { "Exit", 0 },
2537 { "Test VT320 features", tst_vt320_device_status },
2538 { "Test Printer Status", tst_DSR_printer },
2539 { "Test UDK Status", tst_DSR_userkeys },
2540 { "Test Keyboard Status", tst_DSR_keyboard },
2541 { "Test Locator Status", tst_DSR_locator },
2542 { "Test Macro Space", tst_DSR_macrospace },
2543 { "Test Memory Checksum", tst_DSR_memory_sum },
2544 { "Test Data Integrity", tst_DSR_data_ok },
2545 { "Test Multiple Session Status", tst_DSR_multisession },
2546 { "Test Checksum of Rectangular Area (DECRQCRA)", tst_DSR_area_sum },
2547 { "Test Extended Cursor-Position (DECXCPR)", tst_DSR_cursor },
2548 { "", 0 }
2549 };
2550 /* *INDENT-ON* */
2551
2552 do {
2553 vt_clear(2);
2554 __(title(0), printf("VT420 Device Status Reports (DSR)"));
2555 __(title(2), println("Choose test type:"));
2556 } while (menu(my_menu));
2557 return MENU_NOHOLD;
2558 }
2559
2560 /******************************************************************************/
2561
2562 int
tst_vt420_report_presentation(MENU_ARGS)2563 tst_vt420_report_presentation(MENU_ARGS)
2564 {
2565 /* *INDENT-OFF* */
2566 static MENU my_menu[] = {
2567 { "Exit", 0 },
2568 { "Test VT320 features", tst_vt320_report_presentation },
2569 { "Request Mode (DECRQM)/Report Mode (DECRPM)", tst_DECRPM },
2570 { "Status-String Report (DECRQSS)", tst_vt420_DECRQSS },
2571 { "", 0 }
2572 };
2573 /* *INDENT-ON* */
2574
2575 int old_DECRPM = set_DECRPM(4);
2576
2577 do {
2578 vt_clear(2);
2579 __(title(0), printf("VT420 Presentation State Reports"));
2580 __(title(2), println("Choose test type:"));
2581 } while (menu(my_menu));
2582 set_DECRPM(old_DECRPM);
2583 return MENU_NOHOLD;
2584 }
2585
2586 int
tst_vt420_reports(MENU_ARGS)2587 tst_vt420_reports(MENU_ARGS)
2588 {
2589 /* *INDENT-OFF* */
2590 static MENU my_menu[] = {
2591 { "Exit", 0 },
2592 { "Test VT320 features", tst_vt320_reports },
2593 { "Test Presentation State Reports", tst_vt420_report_presentation },
2594 { "Test Device Status Reports (DSR)", tst_vt420_device_status },
2595 { "", 0 }
2596 };
2597 /* *INDENT-ON* */
2598
2599 do {
2600 vt_clear(2);
2601 __(title(0), printf("VT420 Reports"));
2602 __(title(2), println("Choose test type:"));
2603 } while (menu(my_menu));
2604 return MENU_NOHOLD;
2605 }
2606
2607 /******************************************************************************/
2608
2609 static int
tst_VT420_screen(MENU_ARGS)2610 tst_VT420_screen(MENU_ARGS)
2611 {
2612 /* *INDENT-OFF* */
2613 static MENU my_menu[] = {
2614 { "Exit", 0 },
2615 { "Test VT320 features", tst_vt320_screen },
2616 { "Test Select Number of Lines per Screen (DECSNLS)", tst_DECSNLS },
2617 { "", 0 }
2618 };
2619 /* *INDENT-ON* */
2620
2621 do {
2622 vt_clear(2);
2623 __(title(0), printf("VT420 Screen-Display Tests"));
2624 __(title(2), println("Choose test type:"));
2625 } while (menu(my_menu));
2626 return MENU_NOHOLD;
2627 }
2628
2629 /******************************************************************************/
2630
2631 /*
2632 * These apply only to VT400's & above.
2633 */
2634 int
tst_vt420(MENU_ARGS)2635 tst_vt420(MENU_ARGS)
2636 {
2637 /* *INDENT-OFF* */
2638 static MENU my_menu[] = {
2639 { "Exit", 0 },
2640 { "Test VT320 features", tst_vt320 },
2641 { "Test cursor-movement", tst_vt420_cursor },
2642 { "Test editing sequences", tst_VT420_editing },
2643 { "Test keyboard-control", tst_VT420_keyboard_ctl },
2644 { "Test macro-definition (DECDMAC)", not_impl },
2645 { "Test rectangular area functions", tst_VT420_rectangle },
2646 { "Test reporting functions", tst_vt420_reports },
2647 { "Test screen-display functions", tst_VT420_screen },
2648 { "", 0 }
2649 };
2650 /* *INDENT-ON* */
2651
2652 do {
2653 vt_clear(2);
2654 __(title(0), printf("VT420 Tests"));
2655 __(title(2), println("Choose test type:"));
2656 } while (menu(my_menu));
2657 return MENU_NOHOLD;
2658 }
2659