ncurses 5.1
[ncurses.git] / test / testcurs.c
1 /*
2  *
3  * This is a test program for the PDCurses screen package for IBM PC type
4  * machines.
5  *
6  * This program was written by John Burnell (johnb@kea.am.dsir.govt.nz)
7  *  wrs(5/28/93) -- modified to be consistent (perform identically) with either
8  *                  PDCurses or under Unix System V, R4
9  *
10  * $Id: testcurs.c,v 1.22 2000/06/17 23:23:34 tom Exp $
11  */
12
13 #include <test.priv.h>
14 #include <ctype.h>
15
16 #if defined(XCURSES)
17 char *XCursesProgramName = "testcurs";
18 #endif
19
20 static int initTest(WINDOW **);
21 static void display_menu(int, int);
22 static void inputTest(WINDOW *);
23 static void introTest(WINDOW *);
24 static void outputTest(WINDOW *);
25 static void padTest(WINDOW *);
26 static void scrollTest(WINDOW *);
27 #if defined(PDCURSES) && !defined(XCURSES)
28 static void resizeTest(WINDOW *);
29 #endif
30
31 struct commands {
32     NCURSES_CONST char *text;
33     void (*function) (WINDOW *);
34 };
35 typedef struct commands COMMAND;
36
37 const COMMAND command[] =
38 {
39     {"Intro Test", introTest},
40     {"Pad Test", padTest},
41 #if defined(PDCURSES) && !defined(XCURSES)
42     {"Resize Test", resizeTest},
43 #endif
44     {"Scroll Test", scrollTest},
45     {"Input Test", inputTest},
46     {"Output Test", outputTest}
47 };
48 #define MAX_OPTIONS ((sizeof(command)/sizeof(command[0])))
49
50 int width, height;
51
52 int
53 main(
54     int argc GCC_UNUSED,
55     char *argv[]GCC_UNUSED)
56 {
57     WINDOW *win;
58     int key, old_option = (-1), new_option = 0;
59     bool quit = FALSE;
60
61 #ifdef PDCDEBUG
62     PDC_debug("testcurs started\n");
63 #endif
64     if (!initTest(&win))
65         return EXIT_FAILURE;
66
67     erase();
68     display_menu(old_option, new_option);
69     while (1) {
70 #ifdef A_COLOR
71         if (has_colors()) {
72             init_pair(1, COLOR_WHITE, COLOR_BLUE);
73             wbkgd(win, COLOR_PAIR(1));
74         } else
75             wbkgd(win, A_REVERSE);
76 #else
77         wbkgd(win, A_REVERSE);
78 #endif
79         werase(win);
80
81         noecho();
82         keypad(stdscr, TRUE);
83         raw();
84         key = getch();
85         switch (key) {
86         case 10:
87         case 13:
88         case KEY_ENTER:
89             erase();
90             refresh();
91             (*command[new_option].function) (win);
92             erase();
93             display_menu(old_option, new_option);
94             break;
95         case KEY_UP:
96             new_option = (new_option == 0) ? new_option : new_option - 1;
97             display_menu(old_option, new_option);
98             break;
99         case KEY_DOWN:
100             new_option = (new_option == MAX_OPTIONS - 1) ? new_option :
101                 new_option + 1;
102             display_menu(old_option, new_option);
103             break;
104         case 'Q':
105         case 'q':
106             quit = TRUE;
107             break;
108         default:
109             break;
110         }
111         if (quit == TRUE)
112             break;
113     }
114
115     delwin(win);
116
117     endwin();
118 #ifdef XCURSES
119     XCursesExit();
120 #endif
121     return EXIT_SUCCESS;
122 }
123
124 static void
125 Continue(WINDOW *win)
126 {
127     int y1 = getmaxy(win);
128     int x1 = getmaxx(win);
129     int y0 = y1 < 10 ? y1 : 10;
130     int x0 = 1;
131     long save;
132
133     save = mvwinch(win, y0, x1 - 1);
134
135     mvwaddstr(win, y0, x0, " Press any key to continue");
136     wclrtoeol(win);
137     getyx(win, y0, x0);
138
139     mvwaddch(win, y0, x1 - 1, save);
140
141     wmove(win, y0, x0);
142     raw();
143     wgetch(win);
144 }
145
146 static int
147 initTest(WINDOW **win)
148 {
149 #ifdef PDCDEBUG
150     PDC_debug("initTest called\n");
151 #endif
152 #ifdef TRACE
153     trace(TRACE_MAXIMUM);
154 #endif
155     initscr();
156 #ifdef PDCDEBUG
157     PDC_debug("after initscr()\n");
158 #endif
159 #ifdef A_COLOR
160     if (has_colors())
161         start_color();
162 #endif
163     width = 60;
164     height = 13;                /* Create a drawing window */
165     *win = newwin(height, width, (LINES - height) / 2, (COLS - width) / 2);
166     if (*win == NULL) {
167         endwin();
168         return 0;
169     }
170     return 1;
171 }
172
173 static void
174 introTest(WINDOW *win)
175 {
176     wmove(win, height / 2 - 5, width / 2);
177     wvline(win, ACS_VLINE, 10);
178     wmove(win, height / 2, width / 2 - 10);
179     whline(win, ACS_HLINE, 20);
180     Continue(win);
181
182     beep();
183     werase(win);
184
185     box(win, ACS_VLINE, ACS_HLINE);
186     wrefresh(win);
187     cbreak();
188     mvwaddstr(win, 1, 1,
189         "You should have rectangle in the middle of the screen");
190     mvwaddstr(win, 2, 1, "You should have heard a beep");
191     Continue(win);
192     return;
193 }
194
195 static void
196 scrollTest(WINDOW *win)
197 {
198     int i;
199     int half;
200     int OldX, OldY;
201     NCURSES_CONST char *Message = "The window will now scroll slowly";
202
203     wclear(win);
204     getmaxyx(win, OldY, OldX);
205     half = OldY / 2;
206     mvwprintw(win, OldY - 2, 1, Message);
207     wrefresh(win);
208     scrollok(win, TRUE);
209     for (i = 1; i <= OldY; i++) {
210         napms(600);
211         scroll(win);
212         wrefresh(win);
213     }
214
215     werase(win);
216     for (i = 1; i < OldY; i++) {
217         mvwprintw(win, i, 1, "Line %d", i);
218     }
219     mvwprintw(win, OldY - 2, 1, "The top of the window will scroll");
220     wmove(win, 1, 1);
221     wsetscrreg(win, 0, half - 1);
222     box(win, ACS_VLINE, ACS_HLINE);
223     wrefresh(win);
224     for (i = 1; i <= half; i++) {
225         napms(600);
226         scroll(win);
227         box(win, ACS_VLINE, ACS_HLINE);
228         wrefresh(win);
229     }
230
231     werase(win);
232     for (i = 1; i < OldY; i++) {
233         mvwprintw(win, i, 1, "Line %d", i);
234     }
235     mvwprintw(win, 1, 1, "The bottom of the window will scroll");
236     wmove(win, OldY - 2, 1);
237     wsetscrreg(win, half, --OldY);
238     box(win, ACS_VLINE, ACS_HLINE);
239     wrefresh(win);
240     for (i = half; i <= OldY; i++) {
241         napms(600);
242         wscrl(win, -1);
243         box(win, ACS_VLINE, ACS_HLINE);
244         wrefresh(win);
245     }
246     wsetscrreg(win, 0, OldY);
247 }
248
249 static void
250 inputTest(WINDOW *win)
251 {
252     int w, h, bx, by, sw, sh, i, c, num;
253     char buffer[80];
254     WINDOW *subWin;
255     wclear(win);
256
257     getmaxyx(win, h, w);
258     getbegyx(win, by, bx);
259     sw = w / 3;
260     sh = h / 3;
261     if ((subWin = subwin(win, sh, sw, by + h - sh - 2, bx + w - sw - 2)) == NULL)
262         return;
263
264 #ifdef A_COLOR
265     if (has_colors()) {
266         init_pair(2, COLOR_WHITE, COLOR_RED);
267         wbkgd(subWin, COLOR_PAIR(2) | A_BOLD);
268     } else
269         wbkgd(subWin, A_BOLD);
270 #else
271     wbkgd(subWin, A_BOLD);
272 #endif
273     box(subWin, ACS_VLINE, ACS_HLINE);
274     wrefresh(win);
275
276     nocbreak();
277     mvwaddstr(win, 2, 1, "Press some keys for 5 seconds");
278     mvwaddstr(win, 1, 1, "Pressing ^C should do nothing");
279     wrefresh(win);
280
281     werase(subWin);
282     box(subWin, ACS_VLINE, ACS_HLINE);
283     for (i = 0; i < 5; i++) {
284         mvwprintw(subWin, 1, 1, "Time = %d", i);
285         wrefresh(subWin);
286         napms(1000);
287         flushinp();
288     }
289
290     delwin(subWin);
291     werase(win);
292     flash();
293     wrefresh(win);
294     napms(500);
295
296     mvwaddstr(win, 2, 1, "Press a key, followed by ENTER");
297     wmove(win, 9, 10);
298     wrefresh(win);
299     echo();
300     noraw();
301     wgetch(win);
302     flushinp();
303
304     wmove(win, 9, 10);
305     wdelch(win);
306     mvwaddstr(win, 4, 1, "The character should now have been deleted");
307     Continue(win);
308
309     wclear(win);
310     mvwaddstr(win, 1, 1, "Press keys (or mouse buttons) to show their names");
311     mvwaddstr(win, 2, 1, "Press spacebar to finish");
312     wrefresh(win);
313     keypad(win, TRUE);
314     raw();
315     noecho();
316     typeahead(-1);
317 #if defined(PDCURSES)
318     mouse_set(ALL_MOUSE_EVENTS);
319 #endif
320     while (1) {
321         wmove(win, 3, 5);
322         c = wgetch(win);
323         wclrtobot(win);
324         if (c >= KEY_MIN)
325             wprintw(win, "Key Pressed: %s", keyname(c));
326         else if (isprint(c))
327             wprintw(win, "Key Pressed: %c", c);
328         else
329             wprintw(win, "Key Pressed: %s", unctrl(c));
330 #if defined(PDCURSES)
331         if (c == KEY_MOUSE) {
332             int button = 0;
333             request_mouse_pos();
334             if (BUTTON_CHANGED(1))
335                 button = 1;
336             else if (BUTTON_CHANGED(2))
337                 button = 2;
338             else if (BUTTON_CHANGED(3))
339                 button = 3;
340             else
341                 button = 0;
342             wmove(win, 4, 18);
343             wprintw(win, "Button %d: ", button);
344             if (MOUSE_MOVED)
345                 wprintw(win, "moved: ");
346             else if ((BUTTON_STATUS(button) & BUTTON_ACTION_MASK) == BUTTON_PRESSED)
347                 wprintw(win, "pressed: ");
348             else if ((BUTTON_STATUS(button) & BUTTON_ACTION_MASK) == BUTTON_DOUBLE_CLICKED)
349                 wprintw(win, "double: ");
350             else
351                 wprintw(win, "released: ");
352             wprintw(win, " Position: Y: %d X: %d", MOUSE_Y_POS, MOUSE_X_POS);
353         }
354 #endif
355         wrefresh(win);
356         if (c == ' ')
357             break;
358     }
359 #if 0
360     nodelay(win, TRUE);
361     wgetch(win);
362     nodelay(win, FALSE);
363 #endif
364 #if defined(PDCURSES)
365     mouse_set(0L);
366 #endif
367     refresh();
368     wclear(win);
369     mvwaddstr(win, 3, 2, "The window should have moved");
370     mvwaddstr(win, 4, 2,
371         "This text should have appeared without you pressing a key");
372     mvwaddstr(win, 6, 2, "Enter a number then a string separated by space");
373     mvwin(win, 2, 1);
374     wrefresh(win);
375     echo();
376     noraw();
377     num = 0;
378     *buffer = 0;
379     mvwscanw(win, 7, 6, "%d %s", &num, buffer);
380     mvwprintw(win, 8, 6, "String: %s Number: %d", buffer, num);
381     Continue(win);
382 }
383
384 static void
385 outputTest(WINDOW *win)
386 {
387     WINDOW *win1;
388     char Buffer[80];
389     chtype ch;
390     int by, bx;
391
392     nl();
393     wclear(win);
394     mvwaddstr(win, 1, 1,
395         "You should now have a screen in the upper left corner, and this text should have wrapped");
396     mvwin(win, 2, 1);
397     waddstr(win, "\nThis text should be down\n");
398     waddstr(win, "and broken into two here ^");
399     Continue(win);
400
401     wclear(win);
402     wattron(win, A_BOLD);
403     mvwaddstr(win, 1, 1, "A new window will appear with this text in it");
404     mvwaddstr(win, 8, 1, "Press any key to continue");
405     wrefresh(win);
406     wgetch(win);
407
408     getbegyx(win, by, bx);
409
410     if (LINES < 24 || COLS < 75) {
411         mvwaddstr(win, 5, 1,
412             "Some tests have been skipped as they require a");
413         mvwaddstr(win, 6, 1, "display of at least 24 LINES by 75 COLUMNS");
414         Continue(win);
415     } else {
416         win1 = newwin(10, 50, 14, 25);
417         if (win1 == NULL) {
418             endwin();
419             return;
420         }
421 #ifdef A_COLOR
422         if (has_colors()) {
423             init_pair(3, COLOR_BLUE, COLOR_WHITE);
424             wbkgd(win1, COLOR_PAIR(3));
425         } else
426             wbkgd(win1, A_NORMAL);
427 #else
428         wbkgd(win1, A_NORMAL);
429 #endif
430         wclear(win1);
431         mvwaddstr(win1, 5, 1,
432             "This text should appear; using overlay option");
433         copywin(win, win1, 0, 0, 0, 0, 9, 49, TRUE);
434
435 #if defined(PDCURSES) && !defined(XCURSES)
436         box(win1, 0xb3, 0xc4);
437 #else
438         box(win1, ACS_VLINE, ACS_HLINE);
439 #endif
440         wmove(win1, 8, 26);
441         wrefresh(win1);
442         wgetch(win1);
443
444         wclear(win1);
445         wattron(win1, A_BLINK);
446         mvwaddstr(win1, 4, 1,
447             "This blinking text should appear in only the second window");
448         wattroff(win1, A_BLINK);
449         mvwin(win1, by, bx);
450         overlay(win, win1);
451         mvwin(win1, 14, 25);
452         wmove(win1, 8, 26);
453         wrefresh(win1);
454         wgetch(win1);
455         delwin(win1);
456     }
457
458     clear();
459     wclear(win);
460     wrefresh(win);
461     mvwaddstr(win, 6, 2, "This line shouldn't appear");
462     mvwaddstr(win, 4, 2, "Only half of the next line is visible");
463     mvwaddstr(win, 5, 2, "Only half of the next line is visible");
464     wmove(win, 6, 1);
465     wclrtobot(win);
466     wmove(win, 5, 20);
467     wclrtoeol(win);
468     mvwaddstr(win, 8, 2, "This line also shouldn't appear");
469     wmove(win, 8, 1);
470     wdeleteln(win);
471     Continue(win);
472
473     wmove(win, 5, 9);
474     ch = winch(win);
475
476     wclear(win);
477     wmove(win, 6, 2);
478     waddstr(win, "The next char should be l:  ");
479     winsch(win, ch);
480     Continue(win);
481
482     mvwinsstr(win, 6, 2, "A1B2C3D4E5");
483     Continue(win);
484
485     wmove(win, 5, 1);
486     winsertln(win);
487     mvwaddstr(win, 5, 2, "The lines below should have moved down");
488     Continue(win);
489
490     wclear(win);
491     wmove(win, 2, 2);
492     wprintw(win, "This is a formatted string in a window: %d %s\n", 42,
493         "is it");
494     mvwaddstr(win, 10, 1, "Enter a string: ");
495     wrefresh(win);
496     noraw();
497     echo();
498     *Buffer = 0;
499     wscanw(win, "%s", Buffer);
500
501     printw("This is a formatted string in stdscr: %d %s\n", 42, "is it");
502     mvaddstr(10, 1, "Enter a string: ");
503     *Buffer = 0;
504     scanw("%s", Buffer);
505
506     if (tigetstr("cvvis") != 0) {
507         wclear(win);
508         curs_set(2);
509         mvwaddstr(win, 1, 1, "The cursor should appear as a block (visible)");
510         Continue(win);
511     }
512
513     if (tigetstr("civis") != 0) {
514         wclear(win);
515         curs_set(0);
516         mvwaddstr(win, 1, 1,
517             "The cursor should have disappeared (invisible)");
518         Continue(win);
519     }
520
521     if (tigetstr("cnorm") != 0) {
522         wclear(win);
523         curs_set(1);
524         mvwaddstr(win, 1, 1, "The cursor should be an underline (normal)");
525         Continue(win);
526     }
527 #ifdef A_COLOR
528     if (has_colors()) {
529         wclear(win);
530         mvwaddstr(win, 1, 1, "Colors should change after you press a key");
531         Continue(win);
532         init_pair(1, COLOR_RED, COLOR_WHITE);
533         wrefresh(win);
534     }
535 #endif
536
537     werase(win);
538     mvwaddstr(win, 1, 1, "Information About Your Terminal");
539     mvwaddstr(win, 3, 1, termname());
540     mvwaddstr(win, 4, 1, longname());
541     if (termattrs() & A_BLINK)
542         mvwaddstr(win, 5, 1, "This terminal supports blinking.");
543     else
544         mvwaddstr(win, 5, 1, "This terminal does NOT support blinking.");
545
546     mvwaddnstr(win, 7, 5, "Have a nice day!ok", 16);
547     wrefresh(win);
548
549     mvwinnstr(win, 7, 5, Buffer, 18);
550     mvaddstr(LINES - 2, 10, Buffer);
551     refresh();
552     Continue(win);
553 }
554
555 #if defined(PDCURSES) && !defined(XCURSES)
556 static void
557 resizeTest(WINDOW *dummy GCC_UNUSED)
558 {
559     WINDOW *win1;
560
561     savetty();
562
563     clear();
564     refresh();
565 #  if defined(OS2)
566     resize_term(50, 120);
567 #  else
568     resize_term(50, 80);
569 #  endif
570
571     win1 = newwin(10, 50, 14, 25);
572     if (win1 == NULL) {
573         endwin();
574         return;
575     }
576 #ifdef A_COLOR
577     if (has_colors()) {
578         init_pair(3, COLOR_BLUE, COLOR_WHITE);
579         wattrset(win1, COLOR_PAIR(3));
580     }
581 #endif
582     wclear(win1);
583
584     mvwaddstr(win1, 1, 1, "The screen may now have 50 lines");
585     Continue(win1);
586
587     wclear(win1);
588     resetty();
589
590     mvwaddstr(win1, 1, 1, "The screen should now be reset");
591     Continue(win1);
592
593     delwin(win1);
594
595     clear();
596     refresh();
597
598 }
599 #endif
600
601 static void
602 padTest(WINDOW *dummy GCC_UNUSED)
603 {
604     WINDOW *pad, *spad;
605
606     pad = newpad(50, 100);
607     wattron(pad, A_REVERSE);
608     mvwaddstr(pad, 5, 2, "This is a new pad");
609     wattrset(pad, A_NORMAL);
610     mvwaddstr(pad, 8, 0,
611         "The end of this line should be truncated here:except  now");
612     mvwaddstr(pad, 11, 1, "This line should not appear.It will now");
613     wmove(pad, 10, 1);
614     wclrtoeol(pad);
615     mvwaddstr(pad, 10, 1, " Press any key to continue");
616     prefresh(pad, 0, 0, 0, 0, 10, 45);
617     keypad(pad, TRUE);
618     raw();
619     wgetch(pad);
620
621     spad = subpad(pad, 12, 25, 6, 52);
622     mvwaddstr(spad, 2, 2, "This is a new subpad");
623     box(spad, 0, 0);
624     prefresh(pad, 0, 0, 0, 0, 15, 75);
625     keypad(pad, TRUE);
626     raw();
627     wgetch(pad);
628
629     mvwaddstr(pad, 35, 2, "This is displayed at line 35 in the pad");
630     mvwaddstr(pad, 40, 1, " Press any key to continue");
631     prefresh(pad, 30, 0, 0, 0, 10, 45);
632     keypad(pad, TRUE);
633     raw();
634     wgetch(pad);
635
636     delwin(pad);
637 }
638
639 static void
640 display_menu(int old_option, int new_option)
641 {
642     register size_t i;
643
644     attrset(A_NORMAL);
645     mvaddstr(3, 20, "PDCurses Test Program");
646
647     for (i = 0; i < MAX_OPTIONS; i++)
648         mvaddstr(5 + i, 25, command[i].text);
649     if (old_option != (-1))
650         mvaddstr(5 + old_option, 25, command[old_option].text);
651     attrset(A_REVERSE);
652     mvaddstr(5 + new_option, 25, command[new_option].text);
653     attrset(A_NORMAL);
654     mvaddstr(13, 3,
655         "Use Up and Down Arrows to select - Enter to run - Q to quit");
656     refresh();
657 }