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