ncurses 5.1
[ncurses.git] / 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.2 2000/03/04 21:04:58 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 && augment == 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 (scroll_reverse && 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 && over_strike) {
1390                         CAP_NOT_FOUND;
1391                         ptext("(ind) Scroll-forward not tested on overstrike terminals.  ");
1392                         pad_done_message(t, state, ch);
1393                         return;
1394                 }
1395                 start_message = "(ind) Scroll-forward start testing";
1396                 augment = 1;
1397         }
1398         if (skip_pad_test(t, state, ch, start_message)) {
1399                 return;
1400         }
1401         pad_test_startup(1);
1402         /* go to the bottom of the screen */
1403         home_down();
1404         do {
1405                 sprintf(temp, "%d\r", test_complete);
1406                 put_str(temp);
1407                 if (augment > 1) {
1408                         tt_putparm(parm_index, repeats, repeats, 0);
1409                 } else {
1410                         put_ind();
1411                 }
1412         } while(still_testing());
1413         put_str("This line should be on the top.\r");
1414         if (augment == 1) {
1415                 for (i = 1; i < lines; i++) {
1416                         put_ind();
1417                 }
1418         } else {
1419                 tt_putparm(parm_index, lines - 1, lines - 1, 0);
1420         }
1421         go_home();
1422         sprintf(temp, "\nScroll forward %d line%s.  ", augment,
1423                 augment == 1 ? "" : "s");
1424         put_str(temp);
1425         pad_test_shutdown(t, 0);
1426         pad_done_message(t, state, ch);
1427 }
1428
1429 /*
1430 **      pad_dl(test_list, status, ch)
1431 **
1432 **      Test (dl) and (dl1) Delete lines
1433 */
1434 static void
1435 pad_dl(
1436         struct test_list *t,
1437         int *state,
1438         int *ch)
1439 {
1440         int i = 0;
1441         const char *start_message;
1442
1443         if (t->flags & 1) {
1444                 /* dl */
1445                 if (!parm_delete_line) {
1446                         CAP_NOT_FOUND;
1447                         ptext("(dl) Delete-lines not present.  ");
1448                         pad_done_message(t, state, ch);
1449                         return;
1450                 }
1451                 start_message = "(dl) Delete-lines start testing";
1452         } else {
1453                 /* dl1 */
1454                 if (!delete_line) {
1455                         CAP_NOT_FOUND;
1456                         ptext("(dl1) Delete-line not present.  ");
1457                         pad_done_message(t, state, ch);
1458                         return;
1459                 }
1460                 start_message = "(dl1) Delete-line start testing";
1461                 augment = 1;
1462         }
1463         if (skip_pad_test(t, state, ch, start_message)) {
1464                 return;
1465         }
1466         pad_test_startup(1);
1467         do {
1468                 sprintf(temp, "%d\r", test_complete);
1469                 if ((i & 0x7f) == 0 && augment < lines - 1) {
1470                         go_home();
1471                         putln(temp);
1472                 }
1473                 put_str(temp);
1474                 if (repeats || !delete_line) {
1475                         tt_putparm(parm_delete_line, repeats, repeats, 0);
1476                 } else {
1477                         tt_putp(delete_line);
1478                 }
1479         } while(still_testing());
1480         home_down();
1481         put_str("This line should be on the top.");
1482         go_home();
1483         if (repeats || !delete_line) {
1484                 tt_putparm(parm_delete_line, lines - 1, lines - 1, 0);
1485         } else {
1486                 for (i = 1; i < lines; i++) {
1487                         tt_putp(delete_line);
1488                 }
1489         }
1490         sprintf(temp, "\nDelete %d line%s.  ", augment,
1491                 augment == 1 ? "" : "s");
1492         put_str(temp);
1493         pad_test_shutdown(t, 0);
1494         pad_done_message(t, state, ch);
1495 }
1496
1497 /*
1498 **      pad_xl(test_list, status, ch)
1499 **
1500 **      Test (il1) Insert and (dl1) Delete lines
1501 */
1502 static void
1503 pad_xl(
1504         struct test_list *t,
1505         int *state,
1506         int *ch)
1507 {
1508         if (!insert_line && !delete_line) {
1509                 /* quietly skip this test */
1510                 return;
1511         }
1512         if (skip_pad_test(t, state, ch,
1513                 "(il1) Insert-line, (dl1) Delete-line start testing")) {
1514                 return;
1515         }
1516         put_clear();
1517         putln("\rThis text is written on the first line.");
1518         ptext("This sentence begins on the second line.  As this");
1519         ptext(" test runs the bottom part of this paragraph will");
1520         ptext(" jump up and down.  Don't worry, that's normal.  When");
1521         ptext(" the jumping stops, the entire paragraph should");
1522         ptext(" still be on the screen and in the same place as when");
1523         ptext(" the test started.  If this paragraph has scrolled");
1524         ptext(" off the top or bottom of the screen then the test");
1525         ptext(" has failed.  Scrolling off the top of the screen");
1526         ptext(" usually means that the delete line capability is");
1527         ptext(" working better than the insert line capability.  If");
1528         ptext(" the text scrolls off the bottom then delete line may");
1529         ptext(" be broken.  If parts of the text are missing then");
1530         ptext(" you should get professional help.");
1531         put_crlf();
1532         go_home();
1533         put_newlines(2);
1534         pad_test_startup(0);
1535         do {
1536                 tt_putp(insert_line);
1537                 put_cr();
1538                 tt_putp(delete_line);
1539         } while(still_testing());
1540         pad_test_shutdown(t, 0);
1541         home_down();
1542         ptext("The top of the screen should have a paragraph of text.  ");
1543         pad_done_message(t, state, ch);
1544 }
1545
1546 /*
1547 **      pad_scrc(test_list, status, ch)
1548 **
1549 **      Test (sc) (rc) Save/restore cursor
1550 */
1551 static void
1552 pad_scrc(
1553         struct test_list *t,
1554         int *state,
1555         int *ch)
1556 {
1557         int i;
1558
1559         if (!save_cursor || !restore_cursor) {
1560                 CAP_NOT_FOUND;
1561                 if (save_cursor) {
1562                         ptext("(rc) Restore-cursor");
1563                 } else
1564                 if (restore_cursor) {
1565                         ptext("(sc) Save-cursor");
1566                 } else {
1567                         ptext("(sc) Save-cursor, (rc) Restore-cursor");
1568                 }
1569                 ptext(" not present.  ");
1570                 pad_done_message(t, state, ch);
1571                 return;
1572         }
1573         if (skip_pad_test(t, state, ch,
1574                 "(sc) (rc) Save/Restore-cursor start testing")) {
1575                 return;
1576         }
1577         pad_test_startup(1);
1578         do {
1579                 page_loop();
1580                 for (i = 1; i < columns; i++) {
1581                         tt_putp(save_cursor);
1582                         putchp(letter);
1583                         tt_putp(restore_cursor);
1584                         putchp('X');
1585                 }
1586         } while(still_testing());
1587         pad_test_shutdown(t, 0);
1588         home_down();
1589         ptext(above_line);
1590         pad_done_message(t, state, ch);
1591 }
1592
1593 /*
1594 **      pad_csrind(test_list, status, ch)
1595 **
1596 **      Test (csr) and (ind) Change scroll region and index.
1597 */
1598 static void
1599 pad_csrind(
1600         struct test_list *t,
1601         int *state,
1602         int *ch)
1603 {
1604         int i;
1605
1606         if (!change_scroll_region) {
1607                 CAP_NOT_FOUND;
1608                 ptext("(csr) Change-scroll-region not present.  ");
1609                 pad_done_message(t, state, ch);
1610                 return;
1611         }
1612         if (skip_pad_test(t, state, ch,
1613                 "(csr) Save/Restore-cursor, (ind) index start testing")) {
1614                 return;
1615         }
1616         if (augment < 2) {
1617                 augment = 2;
1618         }
1619         if (augment > lines - 1) {
1620                 augment = lines - 1;
1621         }
1622         put_clear();
1623         ptext("This text is on the top line.");
1624         tt_putparm(change_scroll_region, 1, lines - augment, lines - 1);
1625         /* go to the bottom of the screen */
1626         home_down();
1627         pad_test_startup(0);
1628         do {
1629                 sprintf(temp, "%d\r", test_complete);
1630                 put_str(temp);
1631                 put_ind();
1632         } while(still_testing());
1633         ptextln("(csr) is broken.");
1634         for (i = augment; i > 1; i--) {
1635                 put_ind();
1636         }
1637         pad_test_shutdown(t, 0);
1638         ptext("All but top and bottom lines should be blank.  ");
1639         pad_done_message(t, state, ch);
1640         tt_putparm(change_scroll_region, 1, 0, lines - 1);
1641         put_clear();
1642 }
1643
1644 /*
1645 **      pad_sccsrrc(test_list, status, ch)
1646 **
1647 **      Test (sc) (csr) and (rc) Save/Change/Restore scroll region
1648 */
1649 static void
1650 pad_sccsrrc(
1651         struct test_list *t,
1652         int *state,
1653         int *ch)
1654 {
1655         int i;
1656
1657         if (!save_cursor || !change_scroll_region || !restore_cursor) {
1658                 /* quietly ignore this test */
1659                 return;
1660         }
1661         if (skip_pad_test(t, state, ch,
1662                 "(sc) (csr) (rc) Save/Change/Restore-cursor, start testing")) {
1663                 return;
1664         }
1665         pad_test_startup(1);
1666         do {
1667                 page_loop();
1668                 for (i = 1; i < columns; i++) {
1669                         tt_putp(save_cursor);
1670                         putchp(letter);
1671                         tt_putparm(change_scroll_region, 1, 0, lines - 1);
1672                         tt_putp(restore_cursor);
1673                         putchp('X');
1674                 }
1675         } while(still_testing());
1676         pad_test_shutdown(t, 0);
1677         home_down();
1678         ptext(above_line);
1679         pad_done_message(t, state, ch);
1680         tt_putparm(change_scroll_region, 1, 0, lines - 1);
1681 }
1682
1683 /*
1684 **      pad_csr_nel(test_list, status, ch)
1685 **
1686 **      Test (sc) (csr) (nel) and (rc) Save/Change/Restore scroll region
1687 */
1688 static void
1689 pad_csr_nel(
1690         struct test_list *t,
1691         int *state,
1692         int *ch)
1693 {
1694         int i, j;
1695
1696         if (!save_cursor || !change_scroll_region || !restore_cursor) {
1697                 /* quietly ignore this test */
1698                 return;
1699         }
1700         if (skip_pad_test(t, state, ch,
1701                 "(csr) Change-scroll-region, (nel) newline start testing")) {
1702                 return;
1703         }
1704         pad_test_startup(1);
1705         do {
1706                 for (i = 0; i < lines; i++) {
1707                         for (j = lines - i; j > 0; j--) {
1708                                 put_crlf();
1709                         }
1710                         tt_putp(save_cursor);
1711                         tt_putparm(change_scroll_region, 1, i, lines - 1);
1712                         tt_putp(restore_cursor);
1713                         put_str(every_line);
1714                 }
1715                 tt_putp(save_cursor);
1716                 tt_putparm(change_scroll_region, 1, 0, lines - 1);
1717                 tt_putp(restore_cursor);
1718         } while(still_testing());
1719         pad_test_shutdown(t, 0);
1720         put_str("  ");
1721         pad_done_message(t, state, ch);
1722         tt_putparm(change_scroll_region, 1, 0, lines - 1);
1723 }
1724
1725 /*
1726 **      pad_csr_cup(test_list, status, ch)
1727 **
1728 **      Test (csr) (cup) Change scroll region and cursor address
1729 */
1730 static void
1731 pad_csr_cup(
1732         struct test_list *t,
1733         int *state,
1734         int *ch)
1735 {
1736         int i, j;
1737
1738         if (!change_scroll_region || !cursor_address) {
1739                 /* quietly ignore this test */
1740                 return;
1741         }
1742         if (skip_pad_test(t, state, ch,
1743                 "(csr) Change-scroll-region, (cup) cursor-address start testing")) {
1744                 return;
1745         }
1746         pad_test_startup(1);
1747         do {
1748                 for (i = 0; i < lines; i++) {
1749                         for (j = lines - i; j > 0; j--) {
1750                                 put_crlf();
1751                         }
1752                         tt_putparm(change_scroll_region, 1, i, lines - 1);
1753                         tt_putparm(cursor_address, 1, lines - 1, 0);
1754                         put_str(every_line);
1755                 }
1756                 tt_putparm(change_scroll_region, 1, 0, lines - 1);
1757                 tt_putparm(cursor_address, 1, lines - 1, strlen(every_line));
1758         } while(still_testing());
1759         pad_test_shutdown(t, 0);
1760         put_str("  ");
1761         pad_done_message(t, state, ch);
1762         tt_putparm(change_scroll_region, 1, 0, lines - 1);
1763 }
1764
1765 /*
1766 **      pad_ht(test_list, status, ch)
1767 **
1768 **      Test (ht) Tabs
1769 */
1770 static void
1771 pad_ht(
1772         struct test_list *t,
1773         int *state,
1774         int *ch)
1775 {
1776         int i, j;
1777
1778         if (!set_tab && init_tabs <= 0) {
1779                 CAP_NOT_FOUND;
1780                 ptext("(ht) Tab not tested.  (hts) Set-tabs and (it) initial-tabs not present.  ");
1781                 pad_done_message(t, state, ch);
1782                 return;
1783         }
1784         if (skip_pad_test(t, state, ch, "(ht) Tab start testing")) {
1785                 return;
1786         }
1787         pad_test_startup(1);
1788         do {
1789                 /*
1790                    it is not always possible to test tabs with caps
1791                    that do not already have padding. The following
1792                    test uses a mixed bag of tests in order to avoid
1793                    this problem. Note: I do not scroll
1794                 */
1795                 if (auto_right_margin && can_go_home)
1796                         for (i = 1, go_home(); i < lines - 2; i++) {
1797                                 for (j = 8; j < columns; j += 8) {
1798                                         putchp('\t');
1799                                 }
1800                                 put_str("A        ");
1801                         }
1802                 if (cursor_down && can_go_home)
1803                         for (i = 1, go_home(); i < lines - 2; i++) {
1804                                 for (j = 8; j < columns; j += 8) {
1805                                         putchp('\t');
1806                                 }
1807                                 put_str("D\r");
1808                                 tt_putp(cursor_down);
1809                         }
1810                 if (cursor_address)
1811                         for (i = 1; i < lines - 2; i++) {
1812                                 tt_putparm(cursor_address, 1, i - 1, 0);
1813                                 for (j = 8; j < columns; j += 8) {
1814                                         putchp('\t');
1815                                 }
1816                                 put_str("C");
1817                         }
1818                 go_home();
1819                 for (i = 1; i < lines - 2; i++) {
1820                         for (j = 8; j < columns; j += 8) {
1821                                 putchp('\t');
1822                         }
1823                         putln("N");
1824                 }
1825         } while(still_testing());
1826         pad_test_shutdown(t, 0);
1827         ptextln("Letters on the screen other than Ns at the right margin indicate failure.");
1828         ptext("A-(am) D-(cud1) C-(cup) N-(nel)  ");
1829         pad_done_message(t, state, ch);
1830 }
1831
1832 /*
1833 **      pad_smso(test_list, status, ch)
1834 **
1835 **      Test (smso) (rmso) Enter/exit mode
1836 */
1837 static void
1838 pad_smso(
1839         struct test_list *t,
1840         int *state,
1841         int *ch)
1842 {
1843         int i, j;
1844
1845         if (!enter_standout_mode || !exit_standout_mode) {
1846                 CAP_NOT_FOUND;
1847                 ptext("(smso) (rmso) Enter/Exit-standout-mode not present.  ");
1848                 pad_done_message(t, state, ch);
1849                 return;
1850         }
1851         if (skip_pad_test(t, state, ch,
1852                 "(smso) (rmso) Enter/Exit-standout-mode start testing")) {
1853                 return;
1854         }
1855         /*
1856            In terminals that emulate non-hidden attributes with hidden
1857            attributes, the amount of time that it takes to fill the screen
1858            with an attribute is nontrivial. The following test is designed to
1859            catch those delays
1860         */
1861         pad_test_startup(1);
1862         do {
1863                 page_loop();
1864                 j = magic_cookie_glitch > 0 ? magic_cookie_glitch : 0;
1865                 for (i = 2 + j + j; i < columns;) {
1866                         put_mode(enter_standout_mode);
1867                         i += j + j + 2;
1868                         putchp('X');
1869                         put_mode(exit_standout_mode);
1870                         putchp('X');
1871                 }
1872         } while(still_testing());
1873         pad_test_shutdown(t, 0);
1874         home_down();
1875         ptext(above_line);
1876         pad_done_message(t, state, ch);
1877         put_mode(exit_standout_mode);
1878 }
1879
1880 /*
1881 **      pad_smacs(test_list, status, ch)
1882 **
1883 **      Test (smacs) (rmacs) Enter/exit altcharset mode
1884 */
1885 static void
1886 pad_smacs(
1887         struct test_list *t,
1888         int *state,
1889         int *ch)
1890 {
1891         int i, j;
1892
1893         /* test enter even if exit is missing */
1894         if (!enter_alt_charset_mode) {
1895                 CAP_NOT_FOUND;
1896                 ptext("(smacs) Enter-altcharset-mode not present.  ");
1897                 pad_done_message(t, state, ch);
1898                 return;
1899         }
1900         if (skip_pad_test(t, state, ch,
1901                 "(smacs) (rmacs) Enter/Exit-altcharset-mode start testing")) {
1902                 return;
1903         }
1904         pad_test_startup(1);
1905         do {
1906                 page_loop();
1907                 j = magic_cookie_glitch > 0 ? magic_cookie_glitch : 0;
1908                 for (i = 2 + j + j; i < columns;) {
1909                         put_mode(enter_alt_charset_mode);
1910                         i += j + j + 2;
1911                         putchp(letter);
1912                         put_mode(exit_alt_charset_mode);
1913                         putchp(letter);
1914                 }
1915         } while(still_testing());
1916         pad_test_shutdown(t, 0);
1917         home_down();
1918         ptext("Every other character is from the alternate character set.  ");
1919         pad_done_message(t, state, ch);
1920         put_mode(exit_alt_charset_mode);
1921 }
1922
1923 /*
1924 **      pad_crash(test_list, status, ch)
1925 **
1926 **      Test (clear) without padding
1927 */
1928 static void
1929 pad_crash(
1930         struct test_list *t,
1931         int *state,
1932         int *ch)
1933 {
1934         int save_xon_xoff;
1935
1936         if (!clear_screen) {
1937                 ptext("(clear) Clear-screen not present.  ");
1938                 pad_done_message(t, state, ch);
1939                 return;
1940         }
1941         ptext("If you would like to see if the terminal will really lock up.");
1942         ptextln("  I will send the clear screen sequence without the pads.");
1943         if (skip_pad_test(t, state, ch,
1944                 "(clear) Clear-screen start crash testing")) {
1945                 return;
1946         }
1947         save_xon_xoff = xon_xoff;
1948         xon_xoff = 1;
1949         pad_test_startup(0);
1950         do {
1951                 put_str("Erase this!");
1952                 tt_putp(clear_screen);
1953         } while(still_testing());
1954         xon_xoff = save_xon_xoff;
1955         pad_test_shutdown(t, 1);
1956         pad_done_message(t, state, ch);
1957 }