vendor/NCURSES: Import v5.7 sources
[dragonfly.git] / contrib / ncurses / tack / pad.c
1 /*
2 ** Copyright (C) 1991, 1997 Free Software Foundation, Inc.
3 ** 
4 ** This file is part of TACK.
5 ** 
6 ** TACK is free software; you can redistribute it and/or modify
7 ** it under the terms of the GNU General Public License as published by
8 ** the Free Software Foundation; either version 2, or (at your option)
9 ** any later version.
10 ** 
11 ** TACK is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 ** GNU General Public License for more details.
15 ** 
16 ** You should have received a copy of the GNU General Public License
17 ** along with TACK; see the file COPYING.  If not, write to
18 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 ** Boston, MA 02111-1307, USA.
20 */
21
22 #include <tack.h>
23
24 MODULE_ID("$Id: pad.c,v 1.3 2003/10/18 22:11:29 tom Exp $")
25
26 /* test the pad counts on the terminal */
27
28 static void pad_standard(struct test_list *, int *, int *);
29 static void init_xon_xoff(struct test_list *, int *, int *);
30 static void init_cup(struct test_list *, int *, int *);
31 static void pad_rmxon(struct test_list *, int *, int *);
32 static void pad_home1(struct test_list *, int *, int *);
33 static void pad_home2(struct test_list *, int *, int *);
34 static void pad_clear(struct test_list *, int *, int *);
35 static void pad_ech(struct test_list *, int *, int *);
36 static void pad_el1(struct test_list *, int *, int *);
37 static void pad_el(struct test_list *, int *, int *);
38 static void pad_smdc(struct test_list *, int *, int *);
39 static void pad_dch(struct test_list *, int *, int *);
40 static void pad_dch1(struct test_list *, int *, int *);
41 static void pad_smir(struct test_list *, int *, int *);
42 static void pad_ich(struct test_list *, int *, int *);
43 static void pad_ich1(struct test_list *, int *, int *);
44 static void pad_xch1(struct test_list *, int *, int *);
45 static void pad_rep(struct test_list *, int *, int *);
46 static void pad_cup(struct test_list *, int *, int *);
47 static void pad_hd(struct test_list *, int *, int *);
48 static void pad_hu(struct test_list *, int *, int *);
49 static void pad_rin(struct test_list *, int *, int *);
50 static void pad_il(struct test_list *, int *, int *);
51 static void pad_indn(struct test_list *, int *, int *);
52 static void pad_dl(struct test_list *, int *, int *);
53 static void pad_xl(struct test_list *, int *, int *);
54 static void pad_scrc(struct test_list *, int *, int *);
55 static void pad_csrind(struct test_list *, int *, int *);
56 static void pad_sccsrrc(struct test_list *, int *, int *);
57 static void pad_csr_nel(struct test_list *, int *, int *);
58 static void pad_csr_cup(struct test_list *, int *, int *);
59 static void pad_ht(struct test_list *, int *, int *);
60 static void pad_smso(struct test_list *, int *, int *);
61 static void pad_smacs(struct test_list *, int *, int *);
62 static void pad_crash(struct test_list *, int *, int *);
63
64 extern struct test_menu change_pad_menu;
65
66 /*
67    Any command found in this list, executed from a "Done" prompt
68    will force the default action to repeat rather than next.
69 */
70 const char *pad_repeat_test = {"ep-+<>"};
71
72 struct test_list pad_test_list[] = {
73         {0, 0, 0, 0, "e) edit terminfo", 0, &edit_menu},
74         {0, 0, 0, 0, "p) change padding", 0, &change_pad_menu},
75         {0, 0, 0, 0, "@) display statistics about the last test", dump_test_stats, 0},
76         {0, 0, 0, 0, "c) clear screen", menu_clear_screen, 0},
77         {0, 0, 0, 0, "i) send reset and init", menu_reset_init, 0},
78         {0, 0, 0, 0, txt_longer_test_time, longer_test_time, 0},
79         {0, 0, 0, 0, txt_shorter_test_time, shorter_test_time, 0},
80         {0, 0, 0, 0, txt_longer_augment, longer_augment, 0},
81         {0, 0, 0, 0, txt_shorter_augment, shorter_augment, 0},
82         /***
83            Phase 1: Test initialization and reset strings.
84         
85            (rs1) (rs2) (rs3) (is1) (is2) (is3) are very difficult to test.
86            They have no defined output.  To make matters worse, the cap
87            builder could partition (rs1) (rs2) (rs3) by length, leaving the
88            terminal in some unknown state between (rs1) and (rs2) or between
89            (r2) and (rs3).  Some reset strings clear the screen when done.
90         
91            We have no control over this.  The only thing we can do for
92            certain is to test the pad times by checking for overruns.
93         ***/
94         {MENU_NEXT, 3, "rs1", 0, 0, pad_standard, 0},
95         {MENU_NEXT, 3, "rs2", 0, 0, pad_standard, 0},
96         {MENU_NEXT, 3, "rs3", 0, 0, pad_standard, 0},
97         {MENU_NEXT | MENU_INIT, 0, 0, 0, 0, init_xon_xoff, 0},
98         {MENU_NEXT, 3, "is1", 0, 0, pad_standard, 0},
99         {MENU_NEXT, 3, "is2", 0, 0, pad_standard, 0},
100         {MENU_NEXT, 3, "is3", 0, 0, pad_standard, 0},
101         {MENU_NEXT, 3, "rmxon", "smxon", 0, pad_rmxon, 0},
102         {MENU_NEXT | MENU_INIT, 0, 0, 0, 0, init_cup, 0},
103         /*
104            Phase 2: Test home, screen clears and erases.
105         */
106         {MENU_NEXT, 0, "home", 0, 0, pad_home1, 0},
107         {MENU_NEXT, 0, "home) (nel", 0, 0, pad_home2, 0},
108         {MENU_NEXT | 1, 0, "clear", 0, 0, pad_clear, 0},
109         {MENU_NEXT | MENU_LM1, 0, "ed", 0, 0, pad_clear, 0},
110         {MENU_NEXT | MENU_80c, 0, "ech", 0, 0, pad_ech, 0},
111         {MENU_NEXT | MENU_80c, 0, "el1", "cub1 nel", 0, pad_el1, 0},
112         {MENU_NEXT | MENU_10c, 0, "el", "nel", 0, pad_el, 0},
113         /*
114            Phase 3: Character deletions and insertions
115         */
116         {MENU_NEXT, 0, "smdc) (rmdc", 0, 0, pad_smdc, 0},
117         {MENU_NEXT | MENU_80c, 0, "dch", "smdc rmdc", 0, pad_dch, 0},
118         {MENU_NEXT | MENU_80c, 0, "dch1", "smdc rmdc", 0, pad_dch1, 0},
119         {MENU_NEXT, 0, "smir) (rmir", 0, 0, pad_smir, 0},
120         {MENU_NEXT | MENU_90c, 0, "ich) (ip", "smir rmir", 0, pad_ich, 0},
121         {MENU_NEXT | MENU_90c, 0, "ich1) (ip", "smir rmir", 0, pad_ich1, 0},
122         {MENU_NEXT, 4, "ich1) (dch1", "smir rmir", 0, pad_xch1, 0},
123         {MENU_NEXT | MENU_90c, 0, "rep", 0, 0, pad_rep, 0},
124         /*
125            Phase 4: Test cursor addressing pads.
126         */
127         {MENU_NEXT, 0, "cup", 0, 0, pad_cup, 0},
128         /*
129            Phase 5: Test scrolling and cursor save/restore.
130         */
131         {MENU_NEXT, 0, "hd", 0, 0, pad_hd, 0},
132         {MENU_NEXT, 0, "hu", 0, 0, pad_hu, 0},
133         {MENU_NEXT | MENU_LM1 | 1, 0, "rin", 0, 0, pad_rin, 0},
134         {MENU_NEXT, 0, "ri", 0, 0, pad_rin, 0},
135         {MENU_NEXT | MENU_LM1 | 1, 0, "il", 0, 0, pad_il, 0},
136         {MENU_NEXT, 0, "il1", 0, 0, pad_il, 0},
137         {MENU_NEXT | MENU_LM1 | 1, 0, "indn", 0, 0, pad_indn, 0},
138         {MENU_NEXT, 0, "ind", 0, 0, pad_indn, 0},
139         {MENU_NEXT | MENU_LM1 | 1, 0, "dl", 0, 0, pad_dl, 0},
140         {MENU_NEXT, 0, "dl1", 0, 0, pad_dl, 0},
141         {MENU_NEXT, 0, "il1) (dl1", 0, 0, pad_xl, 0},
142         {MENU_NEXT, 0, "sc) (rc", 0, 0, pad_scrc, 0},
143         {MENU_NEXT | MENU_50l, 0, "csr) (ind", 0, 0, pad_csrind, 0},
144         {MENU_NEXT, 0, "sc) (csr) (rc", 0, 0, pad_sccsrrc, 0},
145         {MENU_NEXT, 0, "csr) (nel", "sc rc", 0, pad_csr_nel, 0},
146         {MENU_NEXT, 0, "csr) (cup", 0, 0, pad_csr_cup, 0},
147         /*
148            Phase 6: Test tabs.
149         */
150         {MENU_NEXT, 0, "ht", 0, 0, pad_ht, 0},
151         /*
152            Phase 7: Test character-set-switch pads.
153         */
154         {MENU_NEXT, 0, "smso) (rmso", 0, 0, pad_smso, 0},
155         {MENU_NEXT, 0, "smacs) (rmacs", 0, 0, pad_smacs, 0},
156         /*
157            Phase 8: Tests for miscellaneous mode-switch pads.
158         */
159         {MENU_NEXT, 3, "flash", 0, 0, pad_standard, 0},
160         {MENU_NEXT, 3, "smkx", 0, 0, pad_standard, 0},
161         {MENU_NEXT, 3, "rmkx", 0, 0, pad_standard, 0},
162         {MENU_NEXT, 3, "smm", 0, 0, pad_standard, 0},
163         {MENU_NEXT, 3, "rmm", 0, 0, pad_standard, 0},
164         /*
165            Phase 9: Test crash-and-burn properties of unpadded (clear).
166         */
167         {0, 0, "clear", "xon", "k) run clear test with no padding", pad_crash, 0},
168         {MENU_LAST, 0, 0, 0, 0, 0, 0}
169 };
170
171 extern int test_complete;       /* counts number of tests completed */
172
173 /* globals */
174 int hzcc;                       /* horizontal character count */
175 char letter;                    /* current character being displayed */
176 int letter_number;              /* points into letters[] */
177 int augment, repeats;           /* number of characters (or lines) effected */
178 char letters[] = "AbCdefghiJklmNopQrStuVwXyZ";
179
180 static char every_line[] = "This text should be on every line.";
181 static char all_lines[] = "Each char on any line should be the same.  ";
182 static char above_line[] = "The above lines should be all Xs.  ";
183 static char no_visual[] = "This loop test has no visual failure indicator.  ";
184
185 /*
186 **      pad_standard(test_list, status, ch)
187 **
188 **      Run a single cap pad test.
189 */
190 static void
191 pad_standard(
192         struct test_list *t,
193         int *state,
194         int *ch)
195 {
196         const char *long_name;
197         char *cap;
198         int l = 2, i;
199         char tbuf[128];
200
201         if ((cap = get_string_cap_byname(t->caps_done, &long_name))) {
202                 sprintf(tbuf, "(%s) %s, start testing", t->caps_done,
203                         long_name);
204                 if (skip_pad_test(t, state, ch, tbuf)) {
205                         return;
206                 }
207                 i = 1;
208                 pad_test_startup(1);
209                 do {
210                         if (i >= columns) {
211                                 page_loop();
212                                 l++;
213                                 i = 1;
214                         }
215                         tt_putp(cap);
216                         putchp(letter);
217                         i++;
218                 } while(still_testing());
219                 pad_test_shutdown(t, 0);
220                 if (l >= lines) {
221                         home_down();
222                 } else {
223                         put_crlf();
224                 }
225                 ptextln(no_visual);
226         } else {
227                 CAP_NOT_FOUND;
228                 /* Note: get_string_cap_byname() always sets long_name */
229                 sprintf(temp, "(%s) %s, not present.  ", t->caps_done,
230                         long_name);
231                 ptext(temp);
232         }
233         pad_done_message(t, state, ch);
234 }
235
236 /*
237 **      init_xon_xoff(test_list, status, ch)
238 **
239 **      Initialize the xon_xoff values
240 */
241 static void
242 init_xon_xoff(
243         struct test_list *t GCC_UNUSED,
244         int *state GCC_UNUSED,
245         int *ch GCC_UNUSED)
246 {
247         /* the reset strings may dink with the XON/XOFF modes */
248         if (select_xon_xoff == 0 && exit_xon_mode) {
249                 tc_putp(exit_xon_mode);
250         }
251         if (select_xon_xoff == 1 && enter_xon_mode) {
252                 tc_putp(enter_xon_mode);
253         }
254 }
255
256 /*
257 **      pad_rmxon(test_list, status, ch)
258 **
259 **      Test (rmxon) exit XON/XOFF mode
260 */
261 static void
262 pad_rmxon(
263         struct test_list *t,
264         int *state,
265         int *ch)
266 {
267         if (select_xon_xoff == 0 && exit_xon_mode) {
268                 pad_standard(t, state, ch);
269         }
270 }
271
272 /*
273 **      init_cup(test_list, status, ch)
274 **
275 **      Send the initialization strings for XON/XOFF and (smcup)
276 **      Stop pad testing if clear screen is missing.
277 */
278 static void
279 init_cup(
280         struct test_list *t,
281         int *state,
282         int *ch)
283 {
284         init_xon_xoff(t, state, ch);
285         if (enter_ca_mode) {
286                 tc_putp(enter_ca_mode);
287         }
288         if (!can_clear_screen) {
289                 ptext("(clear) clear screen not present,");
290                 ptext(" pad processing terminated.  ");
291                 pad_done_message(t, state, ch);
292                 if (*ch == 0 || *ch == 'n' || *ch == 's' || *ch == 'r') {
293                         *ch = '?';
294                 }
295                 return;
296         }
297 }
298
299 /*
300 **      pad_home1(test_list, status, ch)
301 **
302 **      Test (home) when (am) is set.
303 */
304 static void
305 pad_home1(
306         struct test_list *t,
307         int *state,
308         int *ch)
309 {
310         int j, k;
311
312         if (can_go_home && auto_right_margin) {
313                 /*
314                    truly brain damaged terminals will fail this test because
315                    they cannot accept data at full rate
316                 */
317                 if (skip_pad_test(t, state, ch, "(home) Home start testing")) {
318                         return;
319                 }
320                 pad_test_startup(1);
321                 do {
322                         go_home();
323                         for (j = 1; j < lines; j++) {
324                                 for (k = 0; k < columns; k++) {
325                                         if (k & 0xF) {
326                                                 put_this(letter);
327                                         } else {
328                                                 put_this('.');
329                                         }
330                                 }
331                                 SLOW_TERMINAL_EXIT;
332                         }
333                         NEXT_LETTER;
334                 } while(still_testing());
335                 pad_test_shutdown(t, 0);
336                 ptext("All the dots should line up.  ");
337                 pad_done_message(t, state, ch);
338                 put_clear();
339         }
340 }
341
342 /*
343 **      pad_home2(test_list, status, ch)
344 **
345 **      Test (home) and (nel).  (am) is reset.
346 */
347 static void
348 pad_home2(
349         struct test_list *t,
350         int *state,
351         int *ch)
352 {
353         int j, k;
354
355         if (can_go_home) {
356                 if (skip_pad_test(t, state, ch,
357                         "(home) Home, (nel) newline start testing")) {
358                         return;
359                 }
360                 pad_test_startup(1);
361                 do {
362                         go_home();
363                         for (j = 1; j < lines; j++) {
364                                 for (k = 2; k < columns; k++) {
365                                         if (k & 0xF) {
366                                                 put_this(letter);
367                                         } else {
368                                                 put_this('.');
369                                         }
370                                 }
371                                 put_crlf();     /* this does the (nel) */
372                                 SLOW_TERMINAL_EXIT;
373                         }
374                         NEXT_LETTER;
375                 } while(still_testing());
376                 pad_test_shutdown(t, 0);
377                 ptext("All the dots should line up.  ");
378                 pad_done_message(t, state, ch);
379                 put_clear();
380         }
381 }
382
383 /*
384 **      pad_clear(test_list, status, ch)
385 **
386 **      Test (clear) and (ed)
387 **      run the clear screen tests (also clear-to-end-of-screen)
388 **
389 **      0) full page
390 **      1) sparse page
391 **      2) short lines
392 **      3) one full line
393 **      4) one short line
394 */
395 static void
396 pad_clear(
397         struct test_list *t,
398         int *state,
399         int *ch)
400 {
401         const char *end_message = 0;
402         const char *txt;
403         int j, k, is_clear;
404         int clear_select;               /* select the test number */
405
406         is_clear = t->flags & 1;
407         clear_select = auto_right_margin ? 0 : 1;
408         if (is_clear) {
409                 txt = "(clear) clear-screen start testing";
410         } else {
411                 if (!clr_eos) {
412                         CAP_NOT_FOUND;
413                         ptext("(ed) erase-to-end-of-display, not present.  ");
414                         pad_done_message(t, state, ch);
415                         return;
416                 }
417                 txt = "(ed) erase-to-end-of-display start testing";
418         }
419         if (skip_pad_test(t, state, ch, txt)) {
420                 return;
421         }
422         if (enter_am_mode) {
423                 tc_putp(enter_am_mode);
424                 clear_select = 0;
425         }
426         for (; clear_select < 5; clear_select++) {
427                 if (augment > lines || is_clear || !cursor_address) {
428                         augment = lines;
429                 } else {
430                         if (augment <= 1) {
431                                 augment = 2;
432                         }
433                         if (augment < lines) {
434                                 put_clear();
435                                 tt_putparm(cursor_address, 1,
436                                         lines - augment - 1, 0);
437                                 ptextln("This line should not be erased (ed)");
438                         }
439                 }
440                 repeats = augment;
441                 switch (clear_select) {
442                 case 0:
443                         end_message = "Clear full screen.  ";
444                         break;
445                 case 1:
446                         end_message = "Clear sparse screen.  ";
447                         if (cursor_down) {
448                                 break;
449                         }
450                         clear_select++;
451                         /* FALLTHRU */
452                 case 2:
453                         end_message = "Clear one character per line.  ";
454                         if (newline) {
455                                 break;
456                         }
457                         clear_select++;
458                         /* FALLTHRU */
459                 case 3:
460                         end_message = "Clear one full line.  ";
461                         break;
462                 case 4:
463                         end_message = "Clear single short line.  ";
464                         break;
465                 }
466                 pad_test_startup(0);
467                 do {
468                         switch (clear_select) {
469                         case 0: /* full screen test */
470                                 for (j = 1; j < repeats; j++) {
471                                         for (k = 0; k < columns; k++) {
472                                                 if (k & 0xF) {
473                                                         put_this(letter);
474                                                 } else {
475                                                         put_this('.');
476                                                 }
477                                         }
478                                         SLOW_TERMINAL_EXIT;
479                                 }
480                                 break;
481                         case 1: /* sparse screen test */
482                                 for (j = columns - repeats; j > 2; j--) {
483                                         put_this(letter);
484                                 }
485                                 for (j = 2; j < repeats; j++) {
486                                         tt_putp(cursor_down);
487                                         put_this(letter);
488                                 }
489                                 break;
490                         case 2: /* short lines */
491                                 for (j = 2; j < repeats; j++) {
492                                         put_this(letter);
493                                         tt_putp(newline);
494                                 }
495                                 put_this(letter);
496                                 break;
497                         case 3: /* one full line */
498                                 for (j = columns - 5; j > 1; j--) {
499                                         put_this(letter);
500                                 }
501                                 break;
502                         case 4: /* one short line */
503                                 put_str("Erase this!");
504                                 break;
505                         }
506                         if (is_clear) {
507                                 put_clear();
508                         } else {
509                                 if (augment == lines) {
510                                         go_home();
511                                 } else {
512                                         tt_putparm(cursor_address, 1,
513                                                 lines - repeats, 0);
514                                 }
515                                 tt_tputs(clr_eos, repeats);
516                         }
517                         NEXT_LETTER;
518                 } while(still_testing());
519                 pad_test_shutdown(t, 1);
520                 ptext(end_message);
521
522                 pad_done_message(t, state, ch);
523
524                 if (*ch != 0 && *ch != 'n') {
525                         return;
526                 }
527         }
528 }
529
530 /*
531 **      pad_ech(test_list, status, ch)
532 **
533 **      Test (ech) erase characters
534 */
535 static void
536 pad_ech(
537         struct test_list *t,
538         int *state,
539         int *ch)
540 {
541         int i, j;
542
543         if (!erase_chars) {
544                 CAP_NOT_FOUND;
545                 ptext("(ech) Erase-characters, not present.  ");
546                 pad_done_message(t, state, ch);
547                 return;
548         }
549         if (skip_pad_test(t, state, ch,
550                 "(ech) Erase-characters start testing")) {
551                 return;
552         }
553         if (augment > columns - 2) {
554                 augment = columns - 2;
555         }
556         pad_test_startup(1);
557         do {
558                 go_home();
559                 for (i = 2; i < lines; i++) {
560                         for (j = 0; j <= repeats; j++) {
561                                 putchp(letter);
562                         }
563                         put_cr();
564                         tt_putparm(erase_chars, repeats, repeats, 0);
565                         put_crlf();
566                         SLOW_TERMINAL_EXIT;
567                 }
568                 for (i = 1; i <= repeats; i++) {
569                         putchp(' ');
570                 }
571                 putchp(letter);
572                 put_crlf();
573                 NEXT_LETTER;
574         } while(still_testing());
575         pad_test_shutdown(t, 0);
576         ptext(all_lines);
577         pad_done_message(t, state, ch);
578         put_clear();
579 }
580
581 /*
582 **      pad_el1(test_list, status, ch)
583 **
584 **      Test (el1) erase to start of line also (cub1) and (nel)
585 */
586 static void
587 pad_el1(
588         struct test_list *t,
589         int *state,
590         int *ch)
591 {
592         int i, j;
593
594         if (!clr_bol) {
595                 CAP_NOT_FOUND;
596                 ptext("(el1) Erase-to-beginning-of-line, not present.  ");
597                 pad_done_message(t, state, ch);
598                 return;
599         }
600         if (skip_pad_test(t, state, ch,
601                 "(el1) Erase-to-beginning-of-line start testing")) {
602                 return;
603         }
604         if (augment > columns - 2) {
605                 augment = columns - 2;
606         }
607         pad_test_startup(1);
608         do {
609                 go_home();
610                 for (i = 2; i < lines; i++) {
611                         for (j = 0; j <= repeats; j++) {
612                                 putchp(letter);
613                         }
614                         tt_putp(cursor_left);
615                         tt_putp(cursor_left);
616                         tt_tputs(clr_bol, repeats);
617                         put_crlf();
618                         SLOW_TERMINAL_EXIT;
619                 }
620                 for (i = 1; i <= repeats; i++) {
621                         putchp(' ');
622                 }
623                 putchp(letter);
624                 put_crlf();
625                 NEXT_LETTER;
626         } while(still_testing());
627         pad_test_shutdown(t, 0);
628         ptext(all_lines);
629         pad_done_message(t, state, ch);
630         put_clear();
631 }
632
633 /*
634 **      pad_el(test_list, status, ch)
635 **
636 **      Test (el) clear to end of line also (nel)
637 */
638 static void
639 pad_el(
640         struct test_list *t,
641         int *state,
642         int *ch)
643 {
644         int i, j;
645
646         if (!clr_eol) {
647                 CAP_NOT_FOUND;
648                 ptext("(el) Clear-to-end-of-line, not present.  ");
649                 pad_done_message(t, state, ch);
650                 return;
651         }
652         if (skip_pad_test(t, state, ch,
653                 "(el) Clear-to-end-of-line start testing")) {
654                 return;
655         }
656         hzcc = columns * 8 / 10;        /* horizontal character count */
657         if (augment > hzcc) {
658                 augment = hzcc;
659         }
660         pad_test_startup(1);
661         do {
662                 go_home();
663                 for (i = 2; i < lines; i++) {
664                         for (j = -1; j < augment; j++) {
665                                 putchp(letter);
666                         }
667                         put_cr();
668                         putchp(letter);
669                         tt_putp(clr_eol);
670                         put_crlf();
671                         SLOW_TERMINAL_EXIT;
672                 }
673                 putchp(letter);
674                 put_crlf();
675                 NEXT_LETTER;
676         } while(still_testing());
677         pad_test_shutdown(t, 0);
678         ptext(all_lines);
679         pad_done_message(t, state, ch);
680         put_clear();
681 }
682
683 /*
684 **      pad_smdc(test_list, status, ch)
685 **
686 **      Test (smdc) (rmdc) Delete mode
687 */
688 static void
689 pad_smdc(
690         struct test_list *t,
691         int *state,
692         int *ch)
693 {
694         int i;
695
696         if (!enter_delete_mode) {
697                 CAP_NOT_FOUND;
698                 ptext("(smdc) Enter-delete-mode");
699                 if (!exit_delete_mode) {
700                         ptext(", (rmdc) Exit-delete-mode");
701                 }
702                 ptext(", not present.  ");
703                 pad_done_message(t, state, ch);
704                 return;
705         }
706         if (skip_pad_test(t, state, ch,
707                 "(smdc) (rmdc) Enter/Exit-delete-mode start testing")) {
708                 return;
709         }
710         pad_test_startup(1);
711         do {
712                 page_loop();
713                 for (i = 1; i < columns; i++) {
714                         tt_putp(enter_delete_mode);
715                         tt_putp(exit_delete_mode);
716                         putchp(letter);
717                 }
718         } while(still_testing());
719         pad_test_shutdown(t, 0);
720         home_down();
721         ptext(no_visual);
722         pad_done_message(t, state, ch);
723         put_clear();
724 }
725
726 /*
727 **      pad_dch(test_list, status, ch)
728 **
729 **      Test (smdc) (rmdc) Delete mode and (dch)
730 */
731 static void
732 pad_dch(
733         struct test_list *t,
734         int *state,
735         int *ch)
736 {
737         int i, j;
738
739         if (!parm_dch) {
740                 CAP_NOT_FOUND;
741                 ptext("(dch) Delete-characters, not present.  ");
742                 pad_done_message(t, state, ch);
743                 return;
744         }
745         if (skip_pad_test(t, state, ch,
746                 "(dch) Delete-characters start testing")) {
747                 return;
748         }
749         hzcc = columns * 8 / 10;        /* horizontal character count */
750         if (augment > hzcc) {
751                 augment = hzcc;
752         }
753         pad_test_startup(1);
754         do {
755                 go_home();
756                 for (i = 2; i < lines; i++) {
757                         for (j = 0; j <= repeats; j++) {
758                                 putchp(letter);
759                         }
760                         put_cr();
761                         tt_putp(enter_delete_mode);
762                         tt_putparm(parm_dch, repeats, repeats, 0);
763                         tt_putp(exit_delete_mode);
764                         put_crlf();
765                         SLOW_TERMINAL_EXIT;
766                 }
767                 putchp(letter);
768                 put_crlf();
769                 NEXT_LETTER;
770         } while(still_testing());
771         pad_test_shutdown(t, 0);
772         home_down();
773         ptext(all_lines);
774         pad_done_message(t, state, ch);
775         put_clear();
776 }
777
778 /*
779 **      pad_dch1(test_list, status, ch)
780 **
781 **      Test (smdc) (rmdc) Delete mode and (dch1)
782 */
783 static void
784 pad_dch1(
785         struct test_list *t,
786         int *state,
787         int *ch)
788 {
789         int i, j;
790
791         if (!delete_character) {
792                 if (parm_dch) {
793                         /* if the other one is defined then its OK */
794                         return;
795                 }
796                 CAP_NOT_FOUND;
797                 ptext("(dch1) Delete-character, not present.  ");
798                 pad_done_message(t, state, ch);
799                 return;
800         }
801         if (skip_pad_test(t, state, ch,
802                 "(dch1) Delete-character start testing")) {
803                 return;
804         }
805         hzcc = columns * 8 / 10;        /* horizontal character count */
806         if (augment > hzcc) {
807                 augment = hzcc;
808         }
809         pad_test_startup(1);
810         do {
811                 go_home();
812                 for (i = 2; i < lines; i++) {
813                         for (j = -1; j < augment; j++) {
814                                 putchp(letter);
815                         }
816                         put_cr();
817                         tt_putp(enter_delete_mode);
818                         for (j = 0; j < augment; j++) {
819                                 tt_putp(delete_character);
820                         }
821                         tt_putp(exit_delete_mode);
822                         put_crlf();
823                         SLOW_TERMINAL_EXIT;
824                 }
825                 putchp(letter);
826                 put_crlf();
827                 NEXT_LETTER;
828         } while(still_testing());
829         pad_test_shutdown(t, 0);
830         ptext(all_lines);
831         pad_done_message(t, state, ch);
832         put_clear();
833 }
834
835 /*
836 **      pad_smir(test_list, status, ch)
837 **
838 **      Test (smir) (rmir) Insert mode
839 */
840 static void
841 pad_smir(
842         struct test_list *t,
843         int *state,
844         int *ch)
845 {
846         int i;
847
848         if (!enter_insert_mode) {
849                 CAP_NOT_FOUND;
850                 ptext("(smir) Enter-insert-mode");
851                 if (!exit_insert_mode) {
852                         ptext(", (rmir) Exit-insert-mode");
853                 }
854                 ptext(", not present.  ");
855                 pad_done_message(t, state, ch);
856                 return;
857         }
858         if (skip_pad_test(t, state, ch,
859                 "(smir) (rmir) Enter/Exit-insert-mode start testing")) {
860                 return;
861         }
862         pad_test_startup(1);
863         do {
864                 page_loop();
865                 for (i = 1; i < columns; i++) {
866                         tt_putp(enter_insert_mode);
867                         tt_putp(exit_insert_mode);
868                         putchp(letter);
869                 }
870         } while(still_testing());
871         pad_test_shutdown(t, 0);
872         home_down();
873         ptext(no_visual);
874         pad_done_message(t, state, ch);
875         put_clear();
876 }
877
878 /*
879 **      pad_ich(test_list, status, ch)
880 **
881 **      Test (smir) (rmir) Insert mode and (ich) and (ip)
882 */
883 static void
884 pad_ich(
885         struct test_list *t,
886         int *state,
887         int *ch)
888 {
889         int i, j;
890
891         if (!parm_ich) {
892                 CAP_NOT_FOUND;
893                 ptext("(ich) Insert-characters, not present.  ");
894                 pad_done_message(t, state, ch);
895                 return;
896         }
897         if (skip_pad_test(t, state, ch,
898                 "(ich) Insert-characters, (ip) Insert-padding start testing")) {
899                 return;
900         }
901         j = columns * 9 / 10;
902         if (augment > j) {
903                 augment = j;
904         }
905         pad_test_startup(1);
906         do {
907                 go_home();
908                 for (i = 2; i < lines; i++) {
909                         putchp(letter);
910                         put_cr();
911                         tt_putp(enter_insert_mode);
912                         replace_mode = 0;
913                         tt_putparm(parm_ich, repeats, repeats, 0);
914                         tt_putp(exit_insert_mode);
915                         replace_mode = 1;
916                         put_crlf();
917                         SLOW_TERMINAL_EXIT;
918                 }
919                 for (i = 0; i < repeats; i++) {
920                         putchp(' ');
921                 }
922                 putchp(letter);
923                 NEXT_LETTER;
924                 put_crlf();
925         } while(still_testing());
926         pad_test_shutdown(t, 0);
927         ptext(all_lines);
928         pad_done_message(t, state, ch);
929         tc_putp(exit_insert_mode);
930 }
931
932 /*
933 **      pad_ich1(test_list, status, ch)
934 **
935 **      Test (smir) (rmir) Insert mode and (ich1) and (ip)
936 */
937 static void
938 pad_ich1(
939         struct test_list *t,
940         int *state,
941         int *ch)
942 {
943         int i, j;
944
945         if (!insert_character) {
946                 CAP_NOT_FOUND;
947                 ptext("(ich1) Insert-character, not present.  ");
948                 pad_done_message(t, state, ch);
949                 return;
950         }
951         if (skip_pad_test(t, state, ch,
952                 "(ich1) Insert-character, (ip) Insert-padding start testing")) {
953                 return;
954         }
955         if (augment > columns - 2) {
956                 augment = columns - 2;
957         }
958         pad_test_startup(1);
959         do {
960                 put_clear();
961                 for (i = 2; i < lines; i++) {
962                         putchp(letter);
963                         put_cr();
964                         tt_putp(enter_insert_mode);
965                         replace_mode = 0;
966                         if (!insert_padding && !insert_character) {
967                                 /* only enter/exit is needed */
968                                 for (j = 0; j < augment; j++) {
969                                         putchp('.');
970                                 }
971                         } else {
972                                 for (j = 0; j < augment; j++) {
973                                         tt_putp(insert_character);
974                                         putchp('.');
975                                         tt_putp(insert_padding);
976                                 }
977                         }
978                         tt_putp(exit_insert_mode);
979                         replace_mode = 1;
980                         put_crlf();
981                         SLOW_TERMINAL_EXIT;
982                 }
983                 for (j = 0; j < augment; j++) {
984                         putchp('.');
985                 }
986                 putchp(letter);
987                 NEXT_LETTER;
988                 put_crlf();
989         } while(still_testing());
990         pad_test_shutdown(t, 0);
991         ptext(all_lines);
992         pad_done_message(t, state, ch);
993         tc_putp(exit_insert_mode);
994 }
995
996 /*
997 **      pad_xch1(test_list, status, ch)
998 **
999 **      Test (ich1) (ip) (dch1)
1000 */
1001 static void
1002 pad_xch1(
1003         struct test_list *t,
1004         int *state,
1005         int *ch)
1006 {
1007         static char xch1[] =
1008         "This line should not be garbled. It should be left justified.";
1009
1010         if (enter_insert_mode || exit_insert_mode ||
1011                 enter_delete_mode || exit_delete_mode ||
1012                 !insert_character || !delete_character) {
1013                 /* this test is quietly ignored */
1014                 return;
1015         }
1016         if (skip_pad_test(t, state, ch,
1017                 "(ich1) Insert-character, (dch1) Delete-character start testing")) {
1018                 return;
1019         }
1020         put_crlf();
1021         ptext(xch1);
1022         put_cr();
1023         pad_test_startup(0);
1024         do {
1025                 tt_putp(insert_character);
1026                 tt_putp(delete_character);
1027         } while(still_testing());
1028         pad_test_shutdown(t, 1);
1029         ptextln(xch1);
1030         ptext("The preceding two lines should be the same.  ");
1031         pad_done_message(t, state, ch);
1032 }
1033
1034 /*
1035 **      pad_rep(test_list, status, ch)
1036 **
1037 **      Test (rep) repeat character
1038 */
1039 static void
1040 pad_rep(
1041         struct test_list *t,
1042         int *state,
1043         int *ch)
1044 {
1045         int i, j;
1046
1047         if (!repeat_char) {
1048                 CAP_NOT_FOUND;
1049                 ptext("(rep) Repeat-character, not present.  ");
1050                 pad_done_message(t, state, ch);
1051                 return;
1052         }
1053         if (skip_pad_test(t, state, ch,
1054                 "(rep) Repeat-character start testing")) {
1055                 return;
1056         }
1057         if (augment > columns - 2) {
1058                 augment = columns - 2;
1059         }
1060         if (augment < 2) {
1061                 augment = 2;
1062         }
1063         pad_test_startup(1);
1064         do {
1065                 go_home();
1066                 for (i = 2; i < lines; i++) {
1067                         tt_putparm(repeat_char, repeats, letter, repeats);
1068                         put_crlf();
1069                 }
1070                 for (j = 0; j < repeats; j++) {
1071                         putchp(letter);
1072                 }
1073                 put_crlf();
1074                 NEXT_LETTER;
1075         } while(still_testing());
1076         pad_test_shutdown(t, 0);
1077         ptextln(all_lines);
1078         pad_done_message(t, state, ch);
1079 }
1080
1081 /*
1082 **      pad_cup(test_list, status, ch)
1083 **
1084 **      Test (cup) Cursor address
1085 */
1086 static void
1087 pad_cup(
1088         struct test_list *t,
1089         int *state,
1090         int *ch)
1091 {
1092         int i, j, l, r, c;
1093
1094         if (!cursor_address) {
1095                 CAP_NOT_FOUND;
1096                 ptext("(cup) Cursor-address not present.  ");
1097                 pad_done_message(t, state, ch);
1098                 return;
1099         }
1100         if (skip_pad_test(t, state, ch,
1101                 "(cup) Cursor-address start testing")) {
1102                 return;
1103         }
1104         put_clear();
1105         ptext("Each line should be filled with the same letter.  There should");
1106         ptext(" be no gaps, or single letters scattered over the screen.  ");
1107         if (char_count + 15 > columns) {
1108                 put_crlf();
1109         }
1110         if (((lines - line_count) & 1) == 0) {
1111                 /* this removes the gap in the middle of the test when the
1112                 number of lines is odd.  */
1113                 put_crlf();
1114         }
1115         r = line_count;
1116         c = char_count;
1117         l = (columns - 4) >> 1;
1118         pad_test_startup(0);
1119         do {
1120                 for (i = 1; i + i + r < lines; i++) {
1121                         for (j = 0; j <= l; j++) {
1122                                 tt_putparm(cursor_address, 1, r + i, j);
1123                                 putchp(letter);
1124                                 tt_putparm(cursor_address, 1, r + i, l + l + 1 - j);
1125                                 putchp(letter);
1126                                 tt_putparm(cursor_address, 1, lines - i, j);
1127                                 putchp(letter);
1128                                 tt_putparm(cursor_address, 1, lines - i, l + l + 1 - j);
1129                                 putchp(letter);
1130                         }
1131                         SLOW_TERMINAL_EXIT;
1132                 }
1133                 NEXT_LETTER;
1134         } while(still_testing());
1135         pad_test_shutdown(t, 0);
1136         tt_putparm(cursor_address, 1, line_count = r, char_count = c);
1137         pad_done_message(t, state, ch);
1138         put_clear();
1139 }
1140
1141 /*
1142 **      pad_hd(test_list, status, ch)
1143 **
1144 **      Test (hd) Half down
1145 */
1146 static void
1147 pad_hd(
1148         struct test_list *t,
1149         int *state,
1150         int *ch)
1151 {
1152         int i, j, k;
1153
1154         if (!down_half_line) {
1155                 CAP_NOT_FOUND;
1156                 ptext("(hd) Half-line-down not present.  ");
1157                 pad_done_message(t, state, ch);
1158                 return;
1159         }
1160         if (skip_pad_test(t, state, ch,
1161                 "(hd) Half-line-down start testing")) {
1162                 return;
1163         }
1164         pad_test_startup(1);
1165         do {
1166                 for (i = 1; i < columns; i += 2) {
1167                         for (j = 1; j < i; ++j) {
1168                                 putchp(' ');
1169                         }
1170                         tt_putp(down_half_line);
1171                         for (k = lines + lines; k > 4; k--) {
1172                                 if (j++ >= columns) {
1173                                         break;
1174                                 }
1175                                 tt_putp(down_half_line);
1176                                 putchp(letter);
1177                         }
1178                         go_home();
1179                         SLOW_TERMINAL_EXIT;
1180                 }
1181                 NEXT_LETTER;
1182         } while(still_testing());
1183         pad_test_shutdown(t, 0);
1184         pad_done_message(t, state, ch);
1185         put_clear();
1186 }
1187
1188 /*
1189 **      pad_hu(test_list, status, ch)
1190 **
1191 **      Test (hu) Half line up
1192 */
1193 static void
1194 pad_hu(
1195         struct test_list *t,
1196         int *state,
1197         int *ch)
1198 {
1199         int i, j, k;
1200
1201         if (!up_half_line) {
1202                 CAP_NOT_FOUND;
1203                 ptext("(hu) Half-line-up not present.  ");
1204                 pad_done_message(t, state, ch);
1205                 return;
1206         }
1207         if (skip_pad_test(t, state, ch,
1208                 "(hu) Half-line-up start testing")) {
1209                 return;
1210         }
1211         pad_test_startup(1);
1212         do {
1213                 for (i = 1; i < columns; i += 2) {
1214                         home_down();
1215                         for (j = 1; j < i; ++j) {
1216                                 putchp(' ');
1217                         }
1218                         tt_putp(up_half_line);
1219                         for (k = lines + lines; k > 4; k--) {
1220                                 if (j++ >= columns) {
1221                                         break;
1222                                 }
1223                                 tt_putp(up_half_line);
1224                                 putchp(letter);
1225                         }
1226                         SLOW_TERMINAL_EXIT;
1227                 }
1228                 go_home();
1229                 NEXT_LETTER;
1230         } while(still_testing());
1231         pad_test_shutdown(t, 0);
1232         pad_done_message(t, state, ch);
1233         put_clear();
1234 }
1235
1236 /*
1237 **      pad_rin(test_list, status, ch)
1238 **
1239 **      Test (rin) and (ri) Reverse index
1240 */
1241 static void
1242 pad_rin(
1243         struct test_list *t,
1244         int *state,
1245         int *ch)
1246 {
1247         int i;
1248         const char *start_message;
1249
1250         if (t->flags & 1) {
1251                 /* rin */
1252                 if (!parm_rindex) {
1253                         CAP_NOT_FOUND;
1254                         ptext("(rin) Scroll-reverse-n-lines not present.  ");
1255                         pad_done_message(t, state, ch);
1256                         return;
1257                 }
1258                 start_message = "(rin) Scroll-reverse-n-lines start testing";
1259         } else {
1260                 /* ri */
1261                 if (!scroll_reverse) {
1262                         CAP_NOT_FOUND;
1263                         ptext("(ri) Scroll-reverse not present.  ");
1264                         pad_done_message(t, state, ch);
1265                         return;
1266                 }
1267                 start_message = "(ri) Scroll-reverse start testing";
1268                 augment = 1;
1269         }
1270         if (skip_pad_test(t, state, ch, start_message)) {
1271                 return;
1272         }
1273         pad_test_startup(1);
1274         do {
1275                 sprintf(temp, "%d\r", test_complete);
1276                 put_str(temp);
1277                 if (scroll_reverse && repeats == 1) {
1278                         tt_putp(scroll_reverse);
1279                 } else {
1280                         tt_putparm(parm_rindex, repeats, repeats, 0);
1281                 }
1282         } while(still_testing());
1283         put_str("This line should be on the bottom.\r");
1284         if (scroll_reverse && augment == 1) {
1285                 for (i = 1; i < lines; i++) {
1286                         tt_putp(scroll_reverse);
1287                 }
1288         } else {
1289                 tt_putparm(parm_rindex, lines - 1, lines - 1, 0);
1290         }
1291         putln("The screen should have text on the bottom line.");
1292         sprintf(temp, "Scroll reverse %d line%s.  ", augment,
1293                 augment == 1 ? "" : "s");
1294         put_str(temp);
1295         pad_test_shutdown(t, 0);
1296         pad_done_message(t, state, ch);
1297         put_clear();
1298 }
1299
1300 /*
1301 **      pad_il(test_list, status, ch)
1302 **
1303 **      Test (il) and (il1) Insert line
1304 */
1305 static void
1306 pad_il(
1307         struct test_list *t,
1308         int *state,
1309         int *ch)
1310 {
1311         int i;
1312         const char *start_message;
1313
1314         if (t->flags & 1) {
1315                 /* il */
1316                 if (!parm_insert_line) {
1317                         CAP_NOT_FOUND;
1318                         ptext("(il) Insert-lines not present.  ");
1319                         pad_done_message(t, state, ch);
1320                         return;
1321                 }
1322                 start_message = "(il) Insert-lines start testing";
1323         } else {
1324                 /* il1 */
1325                 if (!insert_line) {
1326                         CAP_NOT_FOUND;
1327                         ptext("(il1) Insert-line not present.  ");
1328                         pad_done_message(t, state, ch);
1329                         return;
1330                 }
1331                 start_message = "(il1) Insert-line start testing";
1332                 augment = 1;
1333         }
1334         if (skip_pad_test(t, state, ch, start_message)) {
1335                 return;
1336         }
1337         pad_test_startup(1);
1338         do {
1339                 sprintf(temp, "%d\r", test_complete);
1340                 put_str(temp);
1341                 if (insert_line && repeats == 1) {
1342                         tt_putp(insert_line);
1343                 } else {
1344                         tt_putparm(parm_insert_line, repeats, repeats, 0);
1345                 }
1346         } while(still_testing());
1347         put_str("This line should be on the bottom.\r");
1348         if (insert_line && augment == 1) {
1349                 for (i = 1; i < lines; i++) {
1350                         tt_putp(insert_line);
1351                 }
1352         } else {
1353                 tt_putparm(parm_insert_line, lines - 1, lines - 1, 0);
1354         }
1355         putln("The screen should have text on the bottom line.");
1356         sprintf(temp, "Insert %d line%s.  ", augment,
1357                 augment == 1 ? "" : "s");
1358         put_str(temp);
1359         pad_test_shutdown(t, 0);
1360         pad_done_message(t, state, ch);
1361         put_clear();
1362 }
1363
1364 /*
1365 **      pad_indn(test_list, status, ch)
1366 **
1367 **      Test (indn) and (ind) Scroll forward
1368 */
1369 static void
1370 pad_indn(
1371         struct test_list *t,
1372         int *state,
1373         int *ch)
1374 {
1375         int i;
1376         const char *start_message;
1377
1378         if (t->flags & 1) {
1379                 /* indn */
1380                 if (!parm_index) {
1381                         CAP_NOT_FOUND;
1382                         ptext("(indn) Scroll-forward-n-lines not present.  ");
1383                         pad_done_message(t, state, ch);
1384                         return;
1385                 }
1386                 start_message = "(indn) Scroll-forward-n-lines start testing";
1387         } else {
1388                 /* ind */
1389                 if (!scroll_forward) {
1390                         CAP_NOT_FOUND;
1391                         ptext("(ind) Scroll-forward not present.  ");
1392                         pad_done_message(t, state, ch);
1393                         return;
1394                 }
1395                 if (over_strike) {
1396                         ptext("(ind) Scroll-forward not tested on overstrike terminals.  ");
1397                         pad_done_message(t, state, ch);
1398                         return;
1399                 }
1400                 start_message = "(ind) Scroll-forward start testing";
1401                 augment = 1;
1402         }
1403         if (skip_pad_test(t, state, ch, start_message)) {
1404                 return;
1405         }
1406         pad_test_startup(1);
1407         /* go to the bottom of the screen */
1408         home_down();
1409         do {
1410                 sprintf(temp, "%d\r", test_complete);
1411                 put_str(temp);
1412                 if (scroll_forward && repeats == 1) {
1413                         put_ind();
1414                 } else {
1415                         tt_putparm(parm_index, repeats, repeats, 0);
1416                 }
1417         } while(still_testing());
1418         put_str("This line should be on the top.\r");
1419         if (scroll_forward && augment == 1) {
1420                 for (i = 1; i < lines; i++) {
1421                         put_ind();
1422                 }
1423         } else {
1424                 tt_putparm(parm_index, lines - 1, lines - 1, 0);
1425         }
1426         go_home();
1427         sprintf(temp, "\nScroll forward %d line%s.  ", augment,
1428                 augment == 1 ? "" : "s");
1429         put_str(temp);
1430         pad_test_shutdown(t, 0);
1431         pad_done_message(t, state, ch);
1432 }
1433
1434 /*
1435 **      pad_dl(test_list, status, ch)
1436 **
1437 **      Test (dl) and (dl1) Delete lines
1438 */
1439 static void
1440 pad_dl(
1441         struct test_list *t,
1442         int *state,
1443         int *ch)
1444 {
1445         int i = 0;
1446         const char *start_message;
1447
1448         if (t->flags & 1) {
1449                 /* dl */
1450                 if (!parm_delete_line) {
1451                         CAP_NOT_FOUND;
1452                         ptext("(dl) Delete-lines not present.  ");
1453                         pad_done_message(t, state, ch);
1454                         return;
1455                 }
1456                 start_message = "(dl) Delete-lines start testing";
1457         } else {
1458                 /* dl1 */
1459                 if (!delete_line) {
1460                         CAP_NOT_FOUND;
1461                         ptext("(dl1) Delete-line not present.  ");
1462                         pad_done_message(t, state, ch);
1463                         return;
1464                 }
1465                 start_message = "(dl1) Delete-line start testing";
1466                 augment = 1;
1467         }
1468         if (skip_pad_test(t, state, ch, start_message)) {
1469                 return;
1470         }
1471         pad_test_startup(1);
1472         do {
1473                 sprintf(temp, "%d\r", test_complete);
1474                 if (augment < lines - 1) {
1475                         go_home();
1476                         putln(temp);
1477                 }
1478                 put_str(temp);
1479                 if (delete_line && repeats == 1) {
1480                         tt_putp(delete_line);
1481                 } else {
1482                         tt_putparm(parm_delete_line, repeats, repeats, 0);
1483                 }
1484         } while(still_testing());
1485         home_down();
1486         put_str("This line should be on the top.");
1487         go_home();
1488         if (delete_line && augment == 1) {
1489                 for (i = 1; i < lines; i++) {
1490                         tt_putp(delete_line);
1491                 }
1492         } else {
1493                 tt_putparm(parm_delete_line, lines - 1, lines - 1, 0);
1494         }
1495         sprintf(temp, "\nDelete %d line%s.  ", augment,
1496                 augment == 1 ? "" : "s");
1497         put_str(temp);
1498         pad_test_shutdown(t, 0);
1499         pad_done_message(t, state, ch);
1500 }
1501
1502 /*
1503 **      pad_xl(test_list, status, ch)
1504 **
1505 **      Test (il1) Insert and (dl1) Delete lines
1506 */
1507 static void
1508 pad_xl(
1509         struct test_list *t,
1510         int *state,
1511         int *ch)
1512 {
1513         if (!insert_line && !delete_line) {
1514                 /* quietly skip this test */
1515                 return;
1516         }
1517         if (skip_pad_test(t, state, ch,
1518                 "(il1) Insert-line, (dl1) Delete-line start testing")) {
1519                 return;
1520         }
1521         put_clear();
1522         putln("\rThis text is written on the first line.");
1523         ptext("This sentence begins on the second line.  As this");
1524         ptext(" test runs the bottom part of this paragraph will");
1525         ptext(" jump up and down.  Don't worry, that's normal.  When");
1526         ptext(" the jumping stops, the entire paragraph should");
1527         ptext(" still be on the screen and in the same place as when");
1528         ptext(" the test started.  If this paragraph has scrolled");
1529         ptext(" off the top or bottom of the screen then the test");
1530         ptext(" has failed.  Scrolling off the top of the screen");
1531         ptext(" usually means that the delete line capability is");
1532         ptext(" working better than the insert line capability.  If");
1533         ptext(" the text scrolls off the bottom then delete line may");
1534         ptext(" be broken.  If parts of the text are missing then");
1535         ptext(" you should get professional help.");
1536         put_crlf();
1537         go_home();
1538         put_newlines(2);
1539         pad_test_startup(0);
1540         do {
1541                 tt_putp(insert_line);
1542                 put_cr();
1543                 tt_putp(delete_line);
1544         } while(still_testing());
1545         pad_test_shutdown(t, 0);
1546         home_down();
1547         ptext("The top of the screen should have a paragraph of text.  ");
1548         pad_done_message(t, state, ch);
1549 }
1550
1551 /*
1552 **      pad_scrc(test_list, status, ch)
1553 **
1554 **      Test (sc) (rc) Save/restore cursor
1555 */
1556 static void
1557 pad_scrc(
1558         struct test_list *t,
1559         int *state,
1560         int *ch)
1561 {
1562         int i;
1563
1564         if (!save_cursor || !restore_cursor) {
1565                 CAP_NOT_FOUND;
1566                 if (save_cursor) {
1567                         ptext("(rc) Restore-cursor");
1568                 } else
1569                 if (restore_cursor) {
1570                         ptext("(sc) Save-cursor");
1571                 } else {
1572                         ptext("(sc) Save-cursor, (rc) Restore-cursor");
1573                 }
1574                 ptext(" not present.  ");
1575                 pad_done_message(t, state, ch);
1576                 return;
1577         }
1578         if (skip_pad_test(t, state, ch,
1579                 "(sc) (rc) Save/Restore-cursor start testing")) {
1580                 return;
1581         }
1582         pad_test_startup(1);
1583         do {
1584                 page_loop();
1585                 for (i = 1; i < columns; i++) {
1586                         tt_putp(save_cursor);
1587                         putchp(letter);
1588                         tt_putp(restore_cursor);
1589                         putchp('X');
1590                 }
1591         } while(still_testing());
1592         pad_test_shutdown(t, 0);
1593         home_down();
1594         ptext(above_line);
1595         pad_done_message(t, state, ch);
1596 }
1597
1598 /*
1599 **      pad_csrind(test_list, status, ch)
1600 **
1601 **      Test (csr) and (ind) Change scroll region and index.
1602 */
1603 static void
1604 pad_csrind(
1605         struct test_list *t,
1606         int *state,
1607         int *ch)
1608 {
1609         int i;
1610
1611         if (!change_scroll_region) {
1612                 CAP_NOT_FOUND;
1613                 ptext("(csr) Change-scroll-region not present.  ");
1614                 pad_done_message(t, state, ch);
1615                 return;
1616         }
1617         if (skip_pad_test(t, state, ch,
1618                 "(csr) Save/Restore-cursor, (ind) index start testing")) {
1619                 return;
1620         }
1621         if (augment < 2) {
1622                 augment = 2;
1623         }
1624         if (augment > lines - 1) {
1625                 augment = lines - 1;
1626         }
1627         put_clear();
1628         ptext("This text is on the top line.");
1629         tt_putparm(change_scroll_region, 1, lines - augment, lines - 1);
1630         /* go to the bottom of the screen */
1631         home_down();
1632         pad_test_startup(0);
1633         do {
1634                 sprintf(temp, "%d\r", test_complete);
1635                 put_str(temp);
1636                 put_ind();
1637         } while(still_testing());
1638         ptextln("(csr) is broken.");
1639         for (i = augment; i > 1; i--) {
1640                 put_ind();
1641         }
1642         pad_test_shutdown(t, 0);
1643         ptext("All but top and bottom lines should be blank.  ");
1644         pad_done_message(t, state, ch);
1645         tt_putparm(change_scroll_region, 1, 0, lines - 1);
1646         put_clear();
1647 }
1648
1649 /*
1650 **      pad_sccsrrc(test_list, status, ch)
1651 **
1652 **      Test (sc) (csr) and (rc) Save/Change/Restore scroll region
1653 */
1654 static void
1655 pad_sccsrrc(
1656         struct test_list *t,
1657         int *state,
1658         int *ch)
1659 {
1660         int i;
1661
1662         if (!save_cursor || !change_scroll_region || !restore_cursor) {
1663                 /* quietly ignore this test */
1664                 return;
1665         }
1666         if (skip_pad_test(t, state, ch,
1667                 "(sc) (csr) (rc) Save/Change/Restore-cursor, start testing")) {
1668                 return;
1669         }
1670         pad_test_startup(1);
1671         do {
1672                 page_loop();
1673                 for (i = 1; i < columns; i++) {
1674                         tt_putp(save_cursor);
1675                         putchp(letter);
1676                         tt_putparm(change_scroll_region, 1, 0, lines - 1);
1677                         tt_putp(restore_cursor);
1678                         putchp('X');
1679                 }
1680         } while(still_testing());
1681         pad_test_shutdown(t, 0);
1682         home_down();
1683         ptext(above_line);
1684         pad_done_message(t, state, ch);
1685         tt_putparm(change_scroll_region, 1, 0, lines - 1);
1686 }
1687
1688 /*
1689 **      pad_csr_nel(test_list, status, ch)
1690 **
1691 **      Test (sc) (csr) (nel) and (rc) Save/Change/Restore scroll region
1692 */
1693 static void
1694 pad_csr_nel(
1695         struct test_list *t,
1696         int *state,
1697         int *ch)
1698 {
1699         int i, j;
1700
1701         if (!save_cursor || !change_scroll_region || !restore_cursor) {
1702                 /* quietly ignore this test */
1703                 return;
1704         }
1705         if (skip_pad_test(t, state, ch,
1706                 "(csr) Change-scroll-region, (nel) newline start testing")) {
1707                 return;
1708         }
1709         pad_test_startup(1);
1710         do {
1711                 for (i = 0; i < lines; i++) {
1712                         for (j = lines - i; j > 0; j--) {
1713                                 put_crlf();
1714                         }
1715                         tt_putp(save_cursor);
1716                         tt_putparm(change_scroll_region, 1, i, lines - 1);
1717                         tt_putp(restore_cursor);
1718                         put_str(every_line);
1719                 }
1720                 tt_putp(save_cursor);
1721                 tt_putparm(change_scroll_region, 1, 0, lines - 1);
1722                 tt_putp(restore_cursor);
1723         } while(still_testing());
1724         pad_test_shutdown(t, 0);
1725         put_str("  ");
1726         pad_done_message(t, state, ch);
1727         tt_putparm(change_scroll_region, 1, 0, lines - 1);
1728 }
1729
1730 /*
1731 **      pad_csr_cup(test_list, status, ch)
1732 **
1733 **      Test (csr) (cup) Change scroll region and cursor address
1734 */
1735 static void
1736 pad_csr_cup(
1737         struct test_list *t,
1738         int *state,
1739         int *ch)
1740 {
1741         int i, j;
1742
1743         if (!change_scroll_region || !cursor_address) {
1744                 /* quietly ignore this test */
1745                 return;
1746         }
1747         if (skip_pad_test(t, state, ch,
1748                 "(csr) Change-scroll-region, (cup) cursor-address start testing")) {
1749                 return;
1750         }
1751         pad_test_startup(1);
1752         do {
1753                 for (i = 0; i < lines; i++) {
1754                         for (j = lines - i; j > 0; j--) {
1755                                 put_crlf();
1756                         }
1757                         tt_putparm(change_scroll_region, 1, i, lines - 1);
1758                         tt_putparm(cursor_address, 1, lines - 1, 0);
1759                         put_str(every_line);
1760                 }
1761                 tt_putparm(change_scroll_region, 1, 0, lines - 1);
1762                 tt_putparm(cursor_address, 1, lines - 1, strlen(every_line));
1763         } while(still_testing());
1764         pad_test_shutdown(t, 0);
1765         put_str("  ");
1766         pad_done_message(t, state, ch);
1767         tt_putparm(change_scroll_region, 1, 0, lines - 1);
1768 }
1769
1770 /*
1771 **      pad_ht(test_list, status, ch)
1772 **
1773 **      Test (ht) Tabs
1774 */
1775 static void
1776 pad_ht(
1777         struct test_list *t,
1778         int *state,
1779         int *ch)
1780 {
1781         int i, j;
1782
1783         if (!set_tab && init_tabs <= 0) {
1784                 CAP_NOT_FOUND;
1785                 ptext("(ht) Tab not tested.  (hts) Set-tabs and (it) initial-tabs not present.  ");
1786                 pad_done_message(t, state, ch);
1787                 return;
1788         }
1789         if (skip_pad_test(t, state, ch, "(ht) Tab start testing")) {
1790                 return;
1791         }
1792         pad_test_startup(1);
1793         do {
1794                 /*
1795                    it is not always possible to test tabs with caps
1796                    that do not already have padding. The following
1797                    test uses a mixed bag of tests in order to avoid
1798                    this problem. Note: I do not scroll
1799                 */
1800                 if (auto_right_margin && can_go_home)
1801                         for (i = 1, go_home(); i < lines - 2; i++) {
1802                                 for (j = 8; j < columns; j += 8) {
1803                                         putchp('\t');
1804                                 }
1805                                 put_str("A        ");
1806                         }
1807                 if (cursor_down && can_go_home)
1808                         for (i = 1, go_home(); i < lines - 2; i++) {
1809                                 for (j = 8; j < columns; j += 8) {
1810                                         putchp('\t');
1811                                 }
1812                                 put_str("D\r");
1813                                 tt_putp(cursor_down);
1814                         }
1815                 if (cursor_address)
1816                         for (i = 1; i < lines - 2; i++) {
1817                                 tt_putparm(cursor_address, 1, i - 1, 0);
1818                                 for (j = 8; j < columns; j += 8) {
1819                                         putchp('\t');
1820                                 }
1821                                 put_str("C");
1822                         }
1823                 go_home();
1824                 for (i = 1; i < lines - 2; i++) {
1825                         for (j = 8; j < columns; j += 8) {
1826                                 putchp('\t');
1827                         }
1828                         putln("N");
1829                 }
1830         } while(still_testing());
1831         pad_test_shutdown(t, 0);
1832         ptextln("Letters on the screen other than Ns at the right margin indicate failure.");
1833         ptext("A-(am) D-(cud1) C-(cup) N-(nel)  ");
1834         pad_done_message(t, state, ch);
1835 }
1836
1837 /*
1838 **      pad_smso(test_list, status, ch)
1839 **
1840 **      Test (smso) (rmso) Enter/exit mode
1841 */
1842 static void
1843 pad_smso(
1844         struct test_list *t,
1845         int *state,
1846         int *ch)
1847 {
1848         int i, j;
1849
1850         if (!enter_standout_mode || !exit_standout_mode) {
1851                 CAP_NOT_FOUND;
1852                 ptext("(smso) (rmso) Enter/Exit-standout-mode not present.  ");
1853                 pad_done_message(t, state, ch);
1854                 return;
1855         }
1856         if (skip_pad_test(t, state, ch,
1857                 "(smso) (rmso) Enter/Exit-standout-mode start testing")) {
1858                 return;
1859         }
1860         /*
1861            In terminals that emulate non-hidden attributes with hidden
1862            attributes, the amount of time that it takes to fill the screen
1863            with an attribute is nontrivial. The following test is designed to
1864            catch those delays
1865         */
1866         pad_test_startup(1);
1867         do {
1868                 page_loop();
1869                 j = magic_cookie_glitch > 0 ? magic_cookie_glitch : 0;
1870                 for (i = 2 + j + j; i < columns;) {
1871                         put_mode(enter_standout_mode);
1872                         i += j + j + 2;
1873                         putchp('X');
1874                         put_mode(exit_standout_mode);
1875                         putchp('X');
1876                 }
1877         } while(still_testing());
1878         pad_test_shutdown(t, 0);
1879         home_down();
1880         ptext(above_line);
1881         pad_done_message(t, state, ch);
1882         put_mode(exit_standout_mode);
1883 }
1884
1885 /*
1886 **      pad_smacs(test_list, status, ch)
1887 **
1888 **      Test (smacs) (rmacs) Enter/exit altcharset mode
1889 */
1890 static void
1891 pad_smacs(
1892         struct test_list *t,
1893         int *state,
1894         int *ch)
1895 {
1896         int i, j;
1897
1898         /* test enter even if exit is missing */
1899         if (!enter_alt_charset_mode) {
1900                 CAP_NOT_FOUND;
1901                 ptext("(smacs) Enter-altcharset-mode not present.  ");
1902                 pad_done_message(t, state, ch);
1903                 return;
1904         }
1905         if (skip_pad_test(t, state, ch,
1906                 "(smacs) (rmacs) Enter/Exit-altcharset-mode start testing")) {
1907                 return;
1908         }
1909         pad_test_startup(1);
1910         do {
1911                 page_loop();
1912                 j = magic_cookie_glitch > 0 ? magic_cookie_glitch : 0;
1913                 for (i = 2 + j + j; i < columns;) {
1914                         put_mode(enter_alt_charset_mode);
1915                         i += j + j + 2;
1916                         putchp(letter);
1917                         put_mode(exit_alt_charset_mode);
1918                         putchp(letter);
1919                 }
1920         } while(still_testing());
1921         pad_test_shutdown(t, 0);
1922         home_down();
1923         ptext("Every other character is from the alternate character set.  ");
1924         pad_done_message(t, state, ch);
1925         put_mode(exit_alt_charset_mode);
1926 }
1927
1928 /*
1929 **      pad_crash(test_list, status, ch)
1930 **
1931 **      Test (clear) without padding
1932 */
1933 static void
1934 pad_crash(
1935         struct test_list *t,
1936         int *state,
1937         int *ch)
1938 {
1939         int save_xon_xoff;
1940
1941         if (!clear_screen) {
1942                 ptext("(clear) Clear-screen not present.  ");
1943                 pad_done_message(t, state, ch);
1944                 return;
1945         }
1946         ptext("If you would like to see if the terminal will really lock up.");
1947         ptextln("  I will send the clear screen sequence without the pads.");
1948         if (skip_pad_test(t, state, ch,
1949                 "(clear) Clear-screen start crash testing")) {
1950                 return;
1951         }
1952         save_xon_xoff = xon_xoff;
1953         xon_xoff = 1;
1954         pad_test_startup(0);
1955         do {
1956                 put_str("Erase this!");
1957                 tt_putp(clear_screen);
1958         } while(still_testing());
1959         xon_xoff = save_xon_xoff;
1960         pad_test_shutdown(t, 1);
1961         pad_done_message(t, state, ch);
1962 }