]> ncurses.scripts.mit.edu Git - ncurses.git/blob - tack/pad.c
ncurses 5.0
[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.1 1998/01/10 00:30:27 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                 case 2:
452                         end_message = "Clear one character per line.  ";
453                         if (newline) {
454                                 break;
455                         }
456                         clear_select++;
457                 case 3:
458                         end_message = "Clear one full line.  ";
459                         break;
460                 case 4:
461                         end_message = "Clear single short line.  ";
462                         break;
463                 }
464                 pad_test_startup(0);
465                 do {
466                         switch (clear_select) {
467                         case 0: /* full screen test */
468                                 for (j = 1; j < repeats; j++) {
469                                         for (k = 0; k < columns; k++) {
470                                                 if (k & 0xF) {
471                                                         put_this(letter);
472                                                 } else {
473                                                         put_this('.');
474                                                 }
475                                         }
476                                         SLOW_TERMINAL_EXIT;
477                                 }
478                                 break;
479                         case 1: /* sparse screen test */
480                                 for (j = columns - repeats; j > 2; j--) {
481                                         put_this(letter);
482                                 }
483                                 for (j = 2; j < repeats; j++) {
484                                         tt_putp(cursor_down);
485                                         put_this(letter);
486                                 }
487                                 break;
488                         case 2: /* short lines */
489                                 for (j = 2; j < repeats; j++) {
490                                         put_this(letter);
491                                         tt_putp(newline);
492                                 }
493                                 put_this(letter);
494                                 break;
495                         case 3: /* one full line */
496                                 for (j = columns - 5; j > 1; j--) {
497                                         put_this(letter);
498                                 }
499                                 break;
500                         case 4: /* one short line */
501                                 put_str("Erase this!");
502                                 break;
503                         }
504                         if (is_clear) {
505                                 put_clear();
506                         } else {
507                                 if (augment == lines) {
508                                         go_home();
509                                 } else {
510                                         tt_putparm(cursor_address, 1,
511                                                 lines - repeats, 0);
512                                 }
513                                 tt_tputs(clr_eos, repeats);
514                         }
515                         NEXT_LETTER;
516                 } while(still_testing());
517                 pad_test_shutdown(t, 1);
518                 ptext(end_message);
519
520                 pad_done_message(t, state, ch);
521
522                 if (*ch != 0 && *ch != 'n') {
523                         return;
524                 }
525         }
526 }
527
528 /*
529 **      pad_ech(test_list, status, ch)
530 **
531 **      Test (ech) erase characters
532 */
533 static void
534 pad_ech(
535         struct test_list *t,
536         int *state,
537         int *ch)
538 {
539         int i, j;
540
541         if (!erase_chars) {
542                 CAP_NOT_FOUND;
543                 ptext("(ech) Erase-characters, not present.  ");
544                 pad_done_message(t, state, ch);
545                 return;
546         }
547         if (skip_pad_test(t, state, ch,
548                 "(ech) Erase-characters start testing")) {
549                 return;
550         }
551         if (augment > columns - 2) {
552                 augment = columns - 2;
553         }
554         pad_test_startup(1);
555         do {
556                 go_home();
557                 for (i = 2; i < lines; i++) {
558                         for (j = 0; j <= repeats; j++) {
559                                 putchp(letter);
560                         }
561                         put_cr();
562                         tt_putparm(erase_chars, repeats, repeats, 0);
563                         put_crlf();
564                         SLOW_TERMINAL_EXIT;
565                 }
566                 for (i = 1; i <= repeats; i++) {
567                         putchp(' ');
568                 }
569                 putchp(letter);
570                 put_crlf();
571                 NEXT_LETTER;
572         } while(still_testing());
573         pad_test_shutdown(t, 0);
574         ptext(all_lines);
575         pad_done_message(t, state, ch);
576         put_clear();
577 }
578
579 /*
580 **      pad_el1(test_list, status, ch)
581 **
582 **      Test (el1) erase to start of line also (cub1) and (nel)
583 */
584 static void
585 pad_el1(
586         struct test_list *t,
587         int *state,
588         int *ch)
589 {
590         int i, j;
591
592         if (!clr_bol) {
593                 CAP_NOT_FOUND;
594                 ptext("(el1) Erase-to-beginning-of-line, not present.  ");
595                 pad_done_message(t, state, ch);
596                 return;
597         }
598         if (skip_pad_test(t, state, ch,
599                 "(el1) Erase-to-beginning-of-line start testing")) {
600                 return;
601         }
602         if (augment > columns - 2) {
603                 augment = columns - 2;
604         }
605         pad_test_startup(1);
606         do {
607                 go_home();
608                 for (i = 2; i < lines; i++) {
609                         for (j = 0; j <= repeats; j++) {
610                                 putchp(letter);
611                         }
612                         tt_putp(cursor_left);
613                         tt_putp(cursor_left);
614                         tt_tputs(clr_bol, repeats);
615                         put_crlf();
616                         SLOW_TERMINAL_EXIT;
617                 }
618                 for (i = 1; i <= repeats; i++) {
619                         putchp(' ');
620                 }
621                 putchp(letter);
622                 put_crlf();
623                 NEXT_LETTER;
624         } while(still_testing());
625         pad_test_shutdown(t, 0);
626         ptext(all_lines);
627         pad_done_message(t, state, ch);
628         put_clear();
629 }
630
631 /*
632 **      pad_el(test_list, status, ch)
633 **
634 **      Test (el) clear to end of line also (nel)
635 */
636 static void
637 pad_el(
638         struct test_list *t,
639         int *state,
640         int *ch)
641 {
642         int i, j;
643
644         if (!clr_eol) {
645                 CAP_NOT_FOUND;
646                 ptext("(el) Clear-to-end-of-line, not present.  ");
647                 pad_done_message(t, state, ch);
648                 return;
649         }
650         if (skip_pad_test(t, state, ch,
651                 "(el) Clear-to-end-of-line start testing")) {
652                 return;
653         }
654         hzcc = columns * 8 / 10;        /* horizontal character count */
655         if (augment > hzcc) {
656                 augment = hzcc;
657         }
658         pad_test_startup(1);
659         do {
660                 go_home();
661                 for (i = 2; i < lines; i++) {
662                         for (j = -1; j < augment; j++) {
663                                 putchp(letter);
664                         }
665                         put_cr();
666                         putchp(letter);
667                         tt_putp(clr_eol);
668                         put_crlf();
669                         SLOW_TERMINAL_EXIT;
670                 }
671                 putchp(letter);
672                 put_crlf();
673                 NEXT_LETTER;
674         } while(still_testing());
675         pad_test_shutdown(t, 0);
676         ptext(all_lines);
677         pad_done_message(t, state, ch);
678         put_clear();
679 }
680
681 /*
682 **      pad_smdc(test_list, status, ch)
683 **
684 **      Test (smdc) (rmdc) Delete mode
685 */
686 static void
687 pad_smdc(
688         struct test_list *t,
689         int *state,
690         int *ch)
691 {
692         int i;
693
694         if (!enter_delete_mode) {
695                 CAP_NOT_FOUND;
696                 ptext("(smdc) Enter-delete-mode");
697                 if (!exit_delete_mode) {
698                         ptext(", (rmdc) Exit-delete-mode");
699                 }
700                 ptext(", not present.  ");
701                 pad_done_message(t, state, ch);
702                 return;
703         }
704         if (skip_pad_test(t, state, ch,
705                 "(smdc) (rmdc) Enter/Exit-delete-mode start testing")) {
706                 return;
707         }
708         pad_test_startup(1);
709         do {
710                 page_loop();
711                 for (i = 1; i < columns; i++) {
712                         tt_putp(enter_delete_mode);
713                         tt_putp(exit_delete_mode);
714                         putchp(letter);
715                 }
716         } while(still_testing());
717         pad_test_shutdown(t, 0);
718         home_down();
719         ptext(no_visual);
720         pad_done_message(t, state, ch);
721         put_clear();
722 }
723
724 /*
725 **      pad_dch(test_list, status, ch)
726 **
727 **      Test (smdc) (rmdc) Delete mode and (dch)
728 */
729 static void
730 pad_dch(
731         struct test_list *t,
732         int *state,
733         int *ch)
734 {
735         int i, j;
736
737         if (!parm_dch) {
738                 CAP_NOT_FOUND;
739                 ptext("(dch) Delete-characters, not present.  ");
740                 pad_done_message(t, state, ch);
741                 return;
742         }
743         if (skip_pad_test(t, state, ch,
744                 "(dch) Delete-characters start testing")) {
745                 return;
746         }
747         hzcc = columns * 8 / 10;        /* horizontal character count */
748         if (augment > hzcc) {
749                 augment = hzcc;
750         }
751         pad_test_startup(1);
752         do {
753                 go_home();
754                 for (i = 2; i < lines; i++) {
755                         for (j = 0; j <= repeats; j++) {
756                                 putchp(letter);
757                         }
758                         put_cr();
759                         tt_putp(enter_delete_mode);
760                         tt_putparm(parm_dch, repeats, repeats, 0);
761                         tt_putp(exit_delete_mode);
762                         put_crlf();
763                         SLOW_TERMINAL_EXIT;
764                 }
765                 putchp(letter);
766                 put_crlf();
767                 NEXT_LETTER;
768         } while(still_testing());
769         pad_test_shutdown(t, 0);
770         home_down();
771         ptext(all_lines);
772         pad_done_message(t, state, ch);
773         put_clear();
774 }
775
776 /*
777 **      pad_dch1(test_list, status, ch)
778 **
779 **      Test (smdc) (rmdc) Delete mode and (dch1)
780 */
781 static void
782 pad_dch1(
783         struct test_list *t,
784         int *state,
785         int *ch)
786 {
787         int i, j;
788
789         if (!delete_character) {
790                 if (parm_dch) {
791                         /* if the other one is defined then its OK */
792                         return;
793                 }
794                 CAP_NOT_FOUND;
795                 ptext("(dch1) Delete-character, not present.  ");
796                 pad_done_message(t, state, ch);
797                 return;
798         }
799         if (skip_pad_test(t, state, ch,
800                 "(dch1) Delete-character start testing")) {
801                 return;
802         }
803         hzcc = columns * 8 / 10;        /* horizontal character count */
804         if (augment > hzcc) {
805                 augment = hzcc;
806         }
807         pad_test_startup(1);
808         do {
809                 go_home();
810                 for (i = 2; i < lines; i++) {
811                         for (j = -1; j < augment; j++) {
812                                 putchp(letter);
813                         }
814                         put_cr();
815                         tt_putp(enter_delete_mode);
816                         for (j = 0; j < augment; j++) {
817                                 tt_putp(delete_character);
818                         }
819                         tt_putp(exit_delete_mode);
820                         put_crlf();
821                         SLOW_TERMINAL_EXIT;
822                 }
823                 putchp(letter);
824                 put_crlf();
825                 NEXT_LETTER;
826         } while(still_testing());
827         pad_test_shutdown(t, 0);
828         ptext(all_lines);
829         pad_done_message(t, state, ch);
830         put_clear();
831 }
832
833 /*
834 **      pad_smir(test_list, status, ch)
835 **
836 **      Test (smir) (rmir) Insert mode
837 */
838 static void
839 pad_smir(
840         struct test_list *t,
841         int *state,
842         int *ch)
843 {
844         int i;
845
846         if (!enter_insert_mode) {
847                 CAP_NOT_FOUND;
848                 ptext("(smir) Enter-insert-mode");
849                 if (!exit_insert_mode) {
850                         ptext(", (rmir) Exit-insert-mode");
851                 }
852                 ptext(", not present.  ");
853                 pad_done_message(t, state, ch);
854                 return;
855         }
856         if (skip_pad_test(t, state, ch,
857                 "(smir) (rmir) Enter/Exit-insert-mode start testing")) {
858                 return;
859         }
860         pad_test_startup(1);
861         do {
862                 page_loop();
863                 for (i = 1; i < columns; i++) {
864                         tt_putp(enter_insert_mode);
865                         tt_putp(exit_insert_mode);
866                         putchp(letter);
867                 }
868         } while(still_testing());
869         pad_test_shutdown(t, 0);
870         home_down();
871         ptext(no_visual);
872         pad_done_message(t, state, ch);
873         put_clear();
874 }
875
876 /*
877 **      pad_ich(test_list, status, ch)
878 **
879 **      Test (smir) (rmir) Insert mode and (ich) and (ip)
880 */
881 static void
882 pad_ich(
883         struct test_list *t,
884         int *state,
885         int *ch)
886 {
887         int i, j;
888
889         if (!parm_ich) {
890                 CAP_NOT_FOUND;
891                 ptext("(ich) Insert-characters, not present.  ");
892                 pad_done_message(t, state, ch);
893                 return;
894         }
895         if (skip_pad_test(t, state, ch,
896                 "(ich) Insert-characters, (ip) Insert-padding start testing")) {
897                 return;
898         }
899         j = columns * 9 / 10;
900         if (augment > j) {
901                 augment = j;
902         }
903         pad_test_startup(1);
904         do {
905                 go_home();
906                 for (i = 2; i < lines; i++) {
907                         putchp(letter);
908                         put_cr();
909                         tt_putp(enter_insert_mode);
910                         replace_mode = 0;
911                         tt_putparm(parm_ich, repeats, repeats, 0);
912                         tt_putp(exit_insert_mode);
913                         replace_mode = 1;
914                         put_crlf();
915                         SLOW_TERMINAL_EXIT;
916                 }
917                 for (i = 0; i < repeats; i++) {
918                         putchp(' ');
919                 }
920                 putchp(letter);
921                 NEXT_LETTER;
922                 put_crlf();
923         } while(still_testing());
924         pad_test_shutdown(t, 0);
925         ptext(all_lines);
926         pad_done_message(t, state, ch);
927         tc_putp(exit_insert_mode);
928 }
929
930 /*
931 **      pad_ich1(test_list, status, ch)
932 **
933 **      Test (smir) (rmir) Insert mode and (ich1) and (ip)
934 */
935 static void
936 pad_ich1(
937         struct test_list *t,
938         int *state,
939         int *ch)
940 {
941         int i, j;
942
943         if (!insert_character) {
944                 CAP_NOT_FOUND;
945                 ptext("(ich1) Insert-character, not present.  ");
946                 pad_done_message(t, state, ch);
947                 return;
948         }
949         if (skip_pad_test(t, state, ch,
950                 "(ich1) Insert-character, (ip) Insert-padding start testing")) {
951                 return;
952         }
953         if (augment > columns - 2) {
954                 augment = columns - 2;
955         }
956         pad_test_startup(1);
957         do {
958                 put_clear();
959                 for (i = 2; i < lines; i++) {
960                         putchp(letter);
961                         put_cr();
962                         tt_putp(enter_insert_mode);
963                         replace_mode = 0;
964                         if (!insert_padding && !insert_character) {
965                                 /* only enter/exit is needed */
966                                 for (j = 0; j < augment; j++) {
967                                         putchp('.');
968                                 }
969                         } else {
970                                 for (j = 0; j < augment; j++) {
971                                         tt_putp(insert_character);
972                                         putchp('.');
973                                         tt_putp(insert_padding);
974                                 }
975                         }
976                         tt_putp(exit_insert_mode);
977                         replace_mode = 1;
978                         put_crlf();
979                         SLOW_TERMINAL_EXIT;
980                 }
981                 for (j = 0; j < augment; j++) {
982                         putchp('.');
983                 }
984                 putchp(letter);
985                 NEXT_LETTER;
986                 put_crlf();
987         } while(still_testing());
988         pad_test_shutdown(t, 0);
989         ptext(all_lines);
990         pad_done_message(t, state, ch);
991         tc_putp(exit_insert_mode);
992 }
993
994 /*
995 **      pad_xch1(test_list, status, ch)
996 **
997 **      Test (ich1) (ip) (dch1)
998 */
999 static void
1000 pad_xch1(
1001         struct test_list *t,
1002         int *state,
1003         int *ch)
1004 {
1005         static char xch1[] =
1006         "This line should not be garbled. It should be left justified.";
1007
1008         if (enter_insert_mode || exit_insert_mode ||
1009                 enter_delete_mode || exit_delete_mode ||
1010                 !insert_character || !delete_character) {
1011                 /* this test is quitely ignored */
1012                 return;
1013         }
1014         if (skip_pad_test(t, state, ch,
1015                 "(ich1) Insert-character, (dch1) Delete-character start testing")) {
1016                 return;
1017         }
1018         put_crlf();
1019         ptext(xch1);
1020         put_cr();
1021         pad_test_startup(0);
1022         do {
1023                 tt_putp(insert_character);
1024                 tt_putp(delete_character);
1025         } while(still_testing());
1026         pad_test_shutdown(t, 1);
1027         ptextln(xch1);
1028         ptext("The preceeding two lines should be the same.  ");
1029         pad_done_message(t, state, ch);
1030 }
1031
1032 /*
1033 **      pad_rep(test_list, status, ch)
1034 **
1035 **      Test (rep) repeat character
1036 */
1037 static void
1038 pad_rep(
1039         struct test_list *t,
1040         int *state,
1041         int *ch)
1042 {
1043         int i, j;
1044
1045         if (!repeat_char) {
1046                 CAP_NOT_FOUND;
1047                 ptext("(rep) Repeat-character, not present.  ");
1048                 pad_done_message(t, state, ch);
1049                 return;
1050         }
1051         if (skip_pad_test(t, state, ch,
1052                 "(rep) Repeat-character start testing")) {
1053                 return;
1054         }
1055         if (augment > columns - 2) {
1056                 augment = columns - 2;
1057         }
1058         if (augment < 2) {
1059                 augment = 2;
1060         }
1061         pad_test_startup(1);
1062         do {
1063                 go_home();
1064                 for (i = 2; i < lines; i++) {
1065                         tt_putparm(repeat_char, repeats, letter, repeats);
1066                         put_crlf();
1067                 }
1068                 for (j = 0; j < repeats; j++) {
1069                         putchp(letter);
1070                 }
1071                 put_crlf();
1072                 NEXT_LETTER;
1073         } while(still_testing());
1074         pad_test_shutdown(t, 0);
1075         ptextln(all_lines);
1076         pad_done_message(t, state, ch);
1077 }
1078
1079 /*
1080 **      pad_cup(test_list, status, ch)
1081 **
1082 **      Test (cup) Cursor address
1083 */
1084 static void
1085 pad_cup(
1086         struct test_list *t,
1087         int *state,
1088         int *ch)
1089 {
1090         int i, j, l, r, c;
1091
1092         if (!cursor_address) {
1093                 CAP_NOT_FOUND;
1094                 ptext("(cup) Cursor-address not present.  ");
1095                 pad_done_message(t, state, ch);
1096                 return;
1097         }
1098         if (skip_pad_test(t, state, ch,
1099                 "(cup) Cursor-address start testing")) {
1100                 return;
1101         }
1102         put_clear();
1103         ptext("Each line should be filled with the same letter.  There should");
1104         ptext(" be no gaps, or single letters scattered over the screen.  ");
1105         if (char_count + 15 > columns) {
1106                 put_crlf();
1107         }
1108         if (((lines - line_count) & 1) == 0) {
1109                 /* this removes the gap in the middle of the test when the
1110                 number of lines is odd.  */
1111                 put_crlf();
1112         }
1113         r = line_count;
1114         c = char_count;
1115         l = (columns - 4) >> 1;
1116         pad_test_startup(0);
1117         do {
1118                 for (i = 1; i + i + r < lines; i++) {
1119                         for (j = 0; j <= l; j++) {
1120                                 tt_putparm(cursor_address, 1, r + i, j);
1121                                 putchp(letter);
1122                                 tt_putparm(cursor_address, 1, r + i, l + l + 1 - j);
1123                                 putchp(letter);
1124                                 tt_putparm(cursor_address, 1, lines - i, j);
1125                                 putchp(letter);
1126                                 tt_putparm(cursor_address, 1, lines - i, l + l + 1 - j);
1127                                 putchp(letter);
1128                         }
1129                         SLOW_TERMINAL_EXIT;
1130                 }
1131                 NEXT_LETTER;
1132         } while(still_testing());
1133         pad_test_shutdown(t, 0);
1134         tt_putparm(cursor_address, 1, line_count = r, char_count = c);
1135         pad_done_message(t, state, ch);
1136         put_clear();
1137 }
1138
1139 /*
1140 **      pad_hd(test_list, status, ch)
1141 **
1142 **      Test (hd) Half down
1143 */
1144 static void
1145 pad_hd(
1146         struct test_list *t,
1147         int *state,
1148         int *ch)
1149 {
1150         int i, j, k;
1151
1152         if (!down_half_line) {
1153                 CAP_NOT_FOUND;
1154                 ptext("(hd) Half-line-down not present.  ");
1155                 pad_done_message(t, state, ch);
1156                 return;
1157         }
1158         if (skip_pad_test(t, state, ch,
1159                 "(hd) Half-line-down start testing")) {
1160                 return;
1161         }
1162         pad_test_startup(1);
1163         do {
1164                 for (i = 1; i < columns; i += 2) {
1165                         for (j = 1; j < i; ++j) {
1166                                 putchp(' ');
1167                         }
1168                         tt_putp(down_half_line);
1169                         for (k = lines + lines; k > 4; k--) {
1170                                 if (j++ >= columns) {
1171                                         break;
1172                                 }
1173                                 tt_putp(down_half_line);
1174                                 putchp(letter);
1175                         }
1176                         go_home();
1177                         SLOW_TERMINAL_EXIT;
1178                 }
1179                 NEXT_LETTER;
1180         } while(still_testing());
1181         pad_test_shutdown(t, 0);
1182         pad_done_message(t, state, ch);
1183         put_clear();
1184 }
1185
1186 /*
1187 **      pad_hu(test_list, status, ch)
1188 **
1189 **      Test (hu) Half line up
1190 */
1191 static void
1192 pad_hu(
1193         struct test_list *t,
1194         int *state,
1195         int *ch)
1196 {
1197         int i, j, k;
1198
1199         if (!up_half_line) {
1200                 CAP_NOT_FOUND;
1201                 ptext("(hu) Half-line-up not present.  ");
1202                 pad_done_message(t, state, ch);
1203                 return;
1204         }
1205         if (skip_pad_test(t, state, ch,
1206                 "(hu) Half-line-up start testing")) {
1207                 return;
1208         }
1209         pad_test_startup(1);
1210         do {
1211                 for (i = 1; i < columns; i += 2) {
1212                         home_down();
1213                         for (j = 1; j < i; ++j) {
1214                                 putchp(' ');
1215                         }
1216                         tt_putp(up_half_line);
1217                         for (k = lines + lines; k > 4; k--) {
1218                                 if (j++ >= columns) {
1219                                         break;
1220                                 }
1221                                 tt_putp(up_half_line);
1222                                 putchp(letter);
1223                         }
1224                         SLOW_TERMINAL_EXIT;
1225                 }
1226                 go_home();
1227                 NEXT_LETTER;
1228         } while(still_testing());
1229         pad_test_shutdown(t, 0);
1230         pad_done_message(t, state, ch);
1231         put_clear();
1232 }
1233
1234 /*
1235 **      pad_rin(test_list, status, ch)
1236 **
1237 **      Test (rin) and (ri) Reverse index
1238 */
1239 static void
1240 pad_rin(
1241         struct test_list *t,
1242         int *state,
1243         int *ch)
1244 {
1245         int i;
1246         const char *start_message;
1247
1248         if (t->flags & 1) {
1249                 /* rin */
1250                 if (!parm_rindex) {
1251                         CAP_NOT_FOUND;
1252                         ptext("(rin) Scroll-reverse-n-lines not present.  ");
1253                         pad_done_message(t, state, ch);
1254                         return;
1255                 }
1256                 start_message = "(rin) Scroll-reverse-n-lines start testing";
1257         } else {
1258                 /* ri */
1259                 if (!scroll_reverse) {
1260                         CAP_NOT_FOUND;
1261                         ptext("(ri) Scroll-reverse not present.  ");
1262                         pad_done_message(t, state, ch);
1263                         return;
1264                 }
1265                 start_message = "(ri) Scroll-reverse start testing";
1266                 augment = 1;
1267         }
1268         if (skip_pad_test(t, state, ch, start_message)) {
1269                 return;
1270         }
1271         pad_test_startup(1);
1272         do {
1273                 sprintf(temp, "%d\r", test_complete);
1274                 put_str(temp);
1275                 if (scroll_reverse && augment == 1) {
1276                         tt_putp(scroll_reverse);
1277                 } else {
1278                         tt_putparm(parm_rindex, repeats, repeats, 0);
1279                 }
1280         } while(still_testing());
1281         put_str("This line should be on the bottom.\r");
1282         if (scroll_reverse && augment == 1) {
1283                 for (i = 1; i < lines; i++) {
1284                         tt_putp(scroll_reverse);
1285                 }
1286         } else {
1287                 tt_putparm(parm_rindex, lines - 1, lines - 1, 0);
1288         }
1289         putln("The screen should have text on the bottom line.");
1290         sprintf(temp, "Scroll reverse %d line%s.  ", augment,
1291                 augment == 1 ? "" : "s");
1292         put_str(temp);
1293         pad_test_shutdown(t, 0);
1294         pad_done_message(t, state, ch);
1295         put_clear();
1296 }
1297
1298 /*
1299 **      pad_il(test_list, status, ch)
1300 **
1301 **      Test (il) and (il1) Insert line
1302 */
1303 static void
1304 pad_il(
1305         struct test_list *t,
1306         int *state,
1307         int *ch)
1308 {
1309         int i;
1310         const char *start_message;
1311
1312         if (t->flags & 1) {
1313                 /* il */
1314                 if (!parm_insert_line) {
1315                         CAP_NOT_FOUND;
1316                         ptext("(il) Insert-lines not present.  ");
1317                         pad_done_message(t, state, ch);
1318                         return;
1319                 }
1320                 start_message = "(il) Insert-lines start testing";
1321         } else {
1322                 /* il1 */
1323                 if (!insert_line) {
1324                         CAP_NOT_FOUND;
1325                         ptext("(il1) Insert-line not present.  ");
1326                         pad_done_message(t, state, ch);
1327                         return;
1328                 }
1329                 start_message = "(il1) Insert-line start testing";
1330                 augment = 1;
1331         }
1332         if (skip_pad_test(t, state, ch, start_message)) {
1333                 return;
1334         }
1335         pad_test_startup(1);
1336         do {
1337                 sprintf(temp, "%d\r", test_complete);
1338                 put_str(temp);
1339                 if (insert_line && repeats == 1) {
1340                         tt_putp(insert_line);
1341                 } else {
1342                         tt_putparm(parm_insert_line, repeats, repeats, 0);
1343                 }
1344         } while(still_testing());
1345         put_str("This line should be on the bottom.\r");
1346         if (scroll_reverse && augment == 1) {
1347                 for (i = 1; i < lines; i++) {
1348                         tt_putp(insert_line);
1349                 }
1350         } else {
1351                 tt_putparm(parm_insert_line, lines - 1, lines - 1, 0);
1352         }
1353         putln("The screen should have text on the bottom line.");
1354         sprintf(temp, "Insert %d line%s.  ", augment,
1355                 augment == 1 ? "" : "s");
1356         put_str(temp);
1357         pad_test_shutdown(t, 0);
1358         pad_done_message(t, state, ch);
1359         put_clear();
1360 }
1361
1362 /*
1363 **      pad_indn(test_list, status, ch)
1364 **
1365 **      Test (indn) and (ind) Scroll forward
1366 */
1367 static void
1368 pad_indn(
1369         struct test_list *t,
1370         int *state,
1371         int *ch)
1372 {
1373         int i;
1374         const char *start_message;
1375
1376         if (t->flags & 1) {
1377                 /* indn */
1378                 if (!parm_index) {
1379                         CAP_NOT_FOUND;
1380                         ptext("(indn) Scroll-forward-n-lines not present.  ");
1381                         pad_done_message(t, state, ch);
1382                         return;
1383                 }
1384                 start_message = "(indn) Scroll-forward-n-lines start testing";
1385         } else {
1386                 /* ind */
1387                 if (!scroll_forward && over_strike) {
1388                         CAP_NOT_FOUND;
1389                         ptext("(ind) Scroll-forward not tested on overstrike terminals.  ");
1390                         pad_done_message(t, state, ch);
1391                         return;
1392                 }
1393                 start_message = "(ind) Scroll-forward start testing";
1394                 augment = 1;
1395         }
1396         if (skip_pad_test(t, state, ch, start_message)) {
1397                 return;
1398         }
1399         pad_test_startup(1);
1400         /* go to the bottom of the screen */
1401         home_down();
1402         do {
1403                 sprintf(temp, "%d\r", test_complete);
1404                 put_str(temp);
1405                 if (augment > 1) {
1406                         tt_putparm(parm_index, repeats, repeats, 0);
1407                 } else {
1408                         put_ind();
1409                 }
1410         } while(still_testing());
1411         put_str("This line should be on the top.\r");
1412         if (augment == 1) {
1413                 for (i = 1; i < lines; i++) {
1414                         put_ind();
1415                 }
1416         } else {
1417                 tt_putparm(parm_index, lines - 1, lines - 1, 0);
1418         }
1419         go_home();
1420         sprintf(temp, "\nScroll forward %d line%s.  ", augment,
1421                 augment == 1 ? "" : "s");
1422         put_str(temp);
1423         pad_test_shutdown(t, 0);
1424         pad_done_message(t, state, ch);
1425 }
1426
1427 /*
1428 **      pad_dl(test_list, status, ch)
1429 **
1430 **      Test (dl) and (dl1) Delete lines
1431 */
1432 static void
1433 pad_dl(
1434         struct test_list *t,
1435         int *state,
1436         int *ch)
1437 {
1438         int i = 0;
1439         const char *start_message;
1440
1441         if (t->flags & 1) {
1442                 /* dl */
1443                 if (!parm_delete_line) {
1444                         CAP_NOT_FOUND;
1445                         ptext("(dl) Delete-lines not present.  ");
1446                         pad_done_message(t, state, ch);
1447                         return;
1448                 }
1449                 start_message = "(dl) Delete-lines start testing";
1450         } else {
1451                 /* dl1 */
1452                 if (!delete_line) {
1453                         CAP_NOT_FOUND;
1454                         ptext("(dl1) Delete-line not present.  ");
1455                         pad_done_message(t, state, ch);
1456                         return;
1457                 }
1458                 start_message = "(dl1) Delete-line start testing";
1459                 augment = 1;
1460         }
1461         if (skip_pad_test(t, state, ch, start_message)) {
1462                 return;
1463         }
1464         pad_test_startup(1);
1465         do {
1466                 sprintf(temp, "%d\r", test_complete);
1467                 if ((i & 0x7f) == 0 && augment < lines - 1) {
1468                         go_home();
1469                         putln(temp);
1470                 }
1471                 put_str(temp);
1472                 if (repeats || !delete_line) {
1473                         tt_putparm(parm_delete_line, repeats, repeats, 0);
1474                 } else {
1475                         tt_putp(delete_line);
1476                 }
1477         } while(still_testing());
1478         home_down();
1479         put_str("This line should be on the top.");
1480         go_home();
1481         if (repeats || !delete_line) {
1482                 tt_putparm(parm_delete_line, lines - 1, lines - 1, 0);
1483         } else {
1484                 for (i = 1; i < lines; i++) {
1485                         tt_putp(delete_line);
1486                 }
1487         }
1488         sprintf(temp, "\nDelete %d line%s.  ", augment,
1489                 augment == 1 ? "" : "s");
1490         put_str(temp);
1491         pad_test_shutdown(t, 0);
1492         pad_done_message(t, state, ch);
1493 }
1494
1495 /*
1496 **      pad_xl(test_list, status, ch)
1497 **
1498 **      Test (il1) Insert and (dl1) Delete lines
1499 */
1500 static void
1501 pad_xl(
1502         struct test_list *t,
1503         int *state,
1504         int *ch)
1505 {
1506         if (!insert_line && !delete_line) {
1507                 /* quietly skip this test */
1508                 return;
1509         }
1510         if (skip_pad_test(t, state, ch,
1511                 "(il1) Insert-line, (dl1) Delete-line start testing")) {
1512                 return;
1513         }
1514         put_clear();
1515         putln("\rThis text is written on the first line.");
1516         ptext("This sentence begins on the second line.  As this");
1517         ptext(" test runs the bottom part of this paragraph will");
1518         ptext(" jump up and down.  Don't worry, that's normal.  When");
1519         ptext(" the jumping stops, the entire paragraph should");
1520         ptext(" still be on the screen and in the same place as when");
1521         ptext(" the test started.  If this paragraph has scrolled");
1522         ptext(" off the top or bottom of the screen then the test");
1523         ptext(" has failed.  Scrolling off the top of the screen");
1524         ptext(" usually means that the delete line capability is");
1525         ptext(" working better than the insert line capability.  If");
1526         ptext(" the text scrolls off the bottom then delete line may");
1527         ptext(" be broken.  If parts of the text are missing then");
1528         ptext(" you should get professional help.");
1529         put_crlf();
1530         go_home();
1531         put_newlines(2);
1532         pad_test_startup(0);
1533         do {
1534                 tt_putp(insert_line);
1535                 put_cr();
1536                 tt_putp(delete_line);
1537         } while(still_testing());
1538         pad_test_shutdown(t, 0);
1539         home_down();
1540         ptext("The top of the screen should have a paragraph of text.  ");
1541         pad_done_message(t, state, ch);
1542 }
1543
1544 /*
1545 **      pad_scrc(test_list, status, ch)
1546 **
1547 **      Test (sc) (rc) Save/restore cursor
1548 */
1549 static void
1550 pad_scrc(
1551         struct test_list *t,
1552         int *state,
1553         int *ch)
1554 {
1555         int i;
1556
1557         if (!save_cursor || !restore_cursor) {
1558                 CAP_NOT_FOUND;
1559                 if (save_cursor) {
1560                         ptext("(rc) Restore-cursor");
1561                 } else
1562                 if (restore_cursor) {
1563                         ptext("(sc) Save-cursor");
1564                 } else {
1565                         ptext("(sc) Save-cursor, (rc) Restore-cursor");
1566                 }
1567                 ptext(" not present.  ");
1568                 pad_done_message(t, state, ch);
1569                 return;
1570         }
1571         if (skip_pad_test(t, state, ch,
1572                 "(sc) (rc) Save/Restore-cursor start testing")) {
1573                 return;
1574         }
1575         pad_test_startup(1);
1576         do {
1577                 page_loop();
1578                 for (i = 1; i < columns; i++) {
1579                         tt_putp(save_cursor);
1580                         putchp(letter);
1581                         tt_putp(restore_cursor);
1582                         putchp('X');
1583                 }
1584         } while(still_testing());
1585         pad_test_shutdown(t, 0);
1586         home_down();
1587         ptext(above_line);
1588         pad_done_message(t, state, ch);
1589 }
1590
1591 /*
1592 **      pad_csrind(test_list, status, ch)
1593 **
1594 **      Test (csr) and (ind) Change scroll region and index.
1595 */
1596 static void
1597 pad_csrind(
1598         struct test_list *t,
1599         int *state,
1600         int *ch)
1601 {
1602         int i;
1603
1604         if (!change_scroll_region) {
1605                 CAP_NOT_FOUND;
1606                 ptext("(csr) Change-scroll-region not present.  ");
1607                 pad_done_message(t, state, ch);
1608                 return;
1609         }
1610         if (skip_pad_test(t, state, ch,
1611                 "(csr) Save/Restore-cursor, (ind) index start testing")) {
1612                 return;
1613         }
1614         if (augment < 2) {
1615                 augment = 2;
1616         }
1617         if (augment > lines - 1) {
1618                 augment = lines - 1;
1619         }
1620         put_clear();
1621         ptext("This text is on the top line.");
1622         tt_putparm(change_scroll_region, 1, lines - augment, lines - 1);
1623         /* go to the bottom of the screen */
1624         home_down();
1625         pad_test_startup(0);
1626         do {
1627                 sprintf(temp, "%d\r", test_complete);
1628                 put_str(temp);
1629                 put_ind();
1630         } while(still_testing());
1631         ptextln("(csr) is broken.");
1632         for (i = augment; i > 1; i--) {
1633                 put_ind();
1634         }
1635         pad_test_shutdown(t, 0);
1636         ptext("All but top and bottom lines should be blank.  ");
1637         pad_done_message(t, state, ch);
1638         tt_putparm(change_scroll_region, 1, 0, lines - 1);
1639         put_clear();
1640 }
1641
1642 /*
1643 **      pad_sccsrrc(test_list, status, ch)
1644 **
1645 **      Test (sc) (csr) and (rc) Save/Change/Restore scroll region
1646 */
1647 static void
1648 pad_sccsrrc(
1649         struct test_list *t,
1650         int *state,
1651         int *ch)
1652 {
1653         int i;
1654
1655         if (!save_cursor || !change_scroll_region || !restore_cursor) {
1656                 /* quietly ignore this test */
1657                 return;
1658         }
1659         if (skip_pad_test(t, state, ch,
1660                 "(sc) (csr) (rc) Save/Change/Restore-cursor, start testing")) {
1661                 return;
1662         }
1663         pad_test_startup(1);
1664         do {
1665                 page_loop();
1666                 for (i = 1; i < columns; i++) {
1667                         tt_putp(save_cursor);
1668                         putchp(letter);
1669                         tt_putparm(change_scroll_region, 1, 0, lines - 1);
1670                         tt_putp(restore_cursor);
1671                         putchp('X');
1672                 }
1673         } while(still_testing());
1674         pad_test_shutdown(t, 0);
1675         home_down();
1676         ptext(above_line);
1677         pad_done_message(t, state, ch);
1678         tt_putparm(change_scroll_region, 1, 0, lines - 1);
1679 }
1680
1681 /*
1682 **      pad_csr_nel(test_list, status, ch)
1683 **
1684 **      Test (sc) (csr) (nel) and (rc) Save/Change/Restore scroll region
1685 */
1686 static void
1687 pad_csr_nel(
1688         struct test_list *t,
1689         int *state,
1690         int *ch)
1691 {
1692         int i, j;
1693
1694         if (!save_cursor || !change_scroll_region || !restore_cursor) {
1695                 /* quietly ignore this test */
1696                 return;
1697         }
1698         if (skip_pad_test(t, state, ch,
1699                 "(csr) Change-scroll-region, (nel) newline start testing")) {
1700                 return;
1701         }
1702         pad_test_startup(1);
1703         do {
1704                 for (i = 0; i < lines; i++) {
1705                         for (j = lines - i; j > 0; j--) {
1706                                 put_crlf();
1707                         }
1708                         tt_putp(save_cursor);
1709                         tt_putparm(change_scroll_region, 1, i, lines - 1);
1710                         tt_putp(restore_cursor);
1711                         put_str(every_line);
1712                 }
1713                 tt_putp(save_cursor);
1714                 tt_putparm(change_scroll_region, 1, 0, lines - 1);
1715                 tt_putp(restore_cursor);
1716         } while(still_testing());
1717         pad_test_shutdown(t, 0);
1718         put_str("  ");
1719         pad_done_message(t, state, ch);
1720         tt_putparm(change_scroll_region, 1, 0, lines - 1);
1721 }
1722
1723 /*
1724 **      pad_csr_cup(test_list, status, ch)
1725 **
1726 **      Test (csr) (cup) Change scroll region and cursor address
1727 */
1728 static void
1729 pad_csr_cup(
1730         struct test_list *t,
1731         int *state,
1732         int *ch)
1733 {
1734         int i, j;
1735
1736         if (!change_scroll_region || !cursor_address) {
1737                 /* quietly ignore this test */
1738                 return;
1739         }
1740         if (skip_pad_test(t, state, ch,
1741                 "(csr) Change-scroll-region, (cup) cursor-address start testing")) {
1742                 return;
1743         }
1744         pad_test_startup(1);
1745         do {
1746                 for (i = 0; i < lines; i++) {
1747                         for (j = lines - i; j > 0; j--) {
1748                                 put_crlf();
1749                         }
1750                         tt_putparm(change_scroll_region, 1, i, lines - 1);
1751                         tt_putparm(cursor_address, 1, lines - 1, 0);
1752                         put_str(every_line);
1753                 }
1754                 tt_putparm(change_scroll_region, 1, 0, lines - 1);
1755                 tt_putparm(cursor_address, 1, lines - 1, strlen(every_line));
1756         } while(still_testing());
1757         pad_test_shutdown(t, 0);
1758         put_str("  ");
1759         pad_done_message(t, state, ch);
1760         tt_putparm(change_scroll_region, 1, 0, lines - 1);
1761 }
1762
1763 /*
1764 **      pad_ht(test_list, status, ch)
1765 **
1766 **      Test (ht) Tabs
1767 */
1768 static void
1769 pad_ht(
1770         struct test_list *t,
1771         int *state,
1772         int *ch)
1773 {
1774         int i, j;
1775
1776         if (!set_tab && init_tabs <= 0) {
1777                 CAP_NOT_FOUND;
1778                 ptext("(ht) Tab not tested.  (hts) Set-tabs and (it) initial-tabs not present.  ");
1779                 pad_done_message(t, state, ch);
1780                 return;
1781         }
1782         if (skip_pad_test(t, state, ch, "(ht) Tab start testing")) {
1783                 return;
1784         }
1785         pad_test_startup(1);
1786         do {
1787                 /*
1788                    it is not always possible to test tabs with caps
1789                    that do not already have padding. The following
1790                    test uses a mixed bag of tests in order to avoid
1791                    this problem. Note: I do not scroll
1792                 */
1793                 if (auto_right_margin && can_go_home)
1794                         for (i = 1, go_home(); i < lines - 2; i++) {
1795                                 for (j = 8; j < columns; j += 8) {
1796                                         putchp('\t');
1797                                 }
1798                                 put_str("A        ");
1799                         }
1800                 if (cursor_down && can_go_home)
1801                         for (i = 1, go_home(); i < lines - 2; i++) {
1802                                 for (j = 8; j < columns; j += 8) {
1803                                         putchp('\t');
1804                                 }
1805                                 put_str("D\r");
1806                                 tt_putp(cursor_down);
1807                         }
1808                 if (cursor_address)
1809                         for (i = 1; i < lines - 2; i++) {
1810                                 tt_putparm(cursor_address, 1, i - 1, 0);
1811                                 for (j = 8; j < columns; j += 8) {
1812                                         putchp('\t');
1813                                 }
1814                                 put_str("C");
1815                         }
1816                 go_home();
1817                 for (i = 1; i < lines - 2; i++) {
1818                         for (j = 8; j < columns; j += 8) {
1819                                 putchp('\t');
1820                         }
1821                         putln("N");
1822                 }
1823         } while(still_testing());
1824         pad_test_shutdown(t, 0);
1825         ptextln("Letters on the screen other than Ns at the right margin indicate failure.");
1826         ptext("A-(am) D-(cud1) C-(cup) N-(nel)  ");
1827         pad_done_message(t, state, ch);
1828 }
1829
1830 /*
1831 **      pad_smso(test_list, status, ch)
1832 **
1833 **      Test (smso) (rmso) Enter/exit mode
1834 */
1835 static void
1836 pad_smso(
1837         struct test_list *t,
1838         int *state,
1839         int *ch)
1840 {
1841         int i, j;
1842
1843         if (!enter_standout_mode || !exit_standout_mode) {
1844                 CAP_NOT_FOUND;
1845                 ptext("(smso) (rmso) Enter/Exit-standout-mode not present.  ");
1846                 pad_done_message(t, state, ch);
1847                 return;
1848         }
1849         if (skip_pad_test(t, state, ch,
1850                 "(smso) (rmso) Enter/Exit-standout-mode start testing")) {
1851                 return;
1852         }
1853         /*
1854            In terminals that emulate non-hidden attributes with hidden
1855            attributes, the amount of time that it takes to fill the screen
1856            with an attribute is nontrivial. The following test is designed to
1857            catch those delays
1858         */
1859         pad_test_startup(1);
1860         do {
1861                 page_loop();
1862                 j = magic_cookie_glitch > 0 ? magic_cookie_glitch : 0;
1863                 for (i = 2 + j + j; i < columns;) {
1864                         put_mode(enter_standout_mode);
1865                         i += j + j + 2;
1866                         putchp('X');
1867                         put_mode(exit_standout_mode);
1868                         putchp('X');
1869                 }
1870         } while(still_testing());
1871         pad_test_shutdown(t, 0);
1872         home_down();
1873         ptext(above_line);
1874         pad_done_message(t, state, ch);
1875         put_mode(exit_standout_mode);
1876 }
1877
1878 /*
1879 **      pad_smacs(test_list, status, ch)
1880 **
1881 **      Test (smacs) (rmacs) Enter/exit altcharset mode
1882 */
1883 static void
1884 pad_smacs(
1885         struct test_list *t,
1886         int *state,
1887         int *ch)
1888 {
1889         int i, j;
1890
1891         /* test enter even if exit is missing */
1892         if (!enter_alt_charset_mode) {
1893                 CAP_NOT_FOUND;
1894                 ptext("(smacs) Enter-altcharset-mode not present.  ");
1895                 pad_done_message(t, state, ch);
1896                 return;
1897         }
1898         if (skip_pad_test(t, state, ch,
1899                 "(smacs) (rmacs) Enter/Exit-altcharset-mode start testing")) {
1900                 return;
1901         }
1902         pad_test_startup(1);
1903         do {
1904                 page_loop();
1905                 j = magic_cookie_glitch > 0 ? magic_cookie_glitch : 0;
1906                 for (i = 2 + j + j; i < columns;) {
1907                         put_mode(enter_alt_charset_mode);
1908                         i += j + j + 2;
1909                         putchp(letter);
1910                         put_mode(exit_alt_charset_mode);
1911                         putchp(letter);
1912                 }
1913         } while(still_testing());
1914         pad_test_shutdown(t, 0);
1915         home_down();
1916         ptext("Every other character is from the alternate character set.  ");
1917         pad_done_message(t, state, ch);
1918         put_mode(exit_alt_charset_mode);
1919 }
1920
1921 /*
1922 **      pad_crash(test_list, status, ch)
1923 **
1924 **      Test (clear) without padding
1925 */
1926 static void
1927 pad_crash(
1928         struct test_list *t,
1929         int *state,
1930         int *ch)
1931 {
1932         int save_xon_xoff;
1933
1934         if (!clear_screen) {
1935                 ptext("(clear) Clear-screen not present.  ");
1936                 pad_done_message(t, state, ch);
1937                 return;
1938         }
1939         ptext("If you would like to see if the terminal will really lock up.");
1940         ptextln("  I will send the clear screen sequence without the pads.");
1941         if (skip_pad_test(t, state, ch,
1942                 "(clear) Clear-screen start crash testing")) {
1943                 return;
1944         }
1945         save_xon_xoff = xon_xoff;
1946         xon_xoff = 1;
1947         pad_test_startup(0);
1948         do {
1949                 put_str("Erase this!");
1950                 tt_putp(clear_screen);
1951         } while(still_testing());
1952         xon_xoff = save_xon_xoff;
1953         pad_test_shutdown(t, 1);
1954         pad_done_message(t, state, ch);
1955 }