1 /*
2  * This is a test program for PDCurses. Originally by
3  * John Burnell <johnb@kea.am.dsir.govt.nz>
4  *
5  *  wrs(5/28/93) -- modified to be consistent (perform identically)
6  *                  with either PDCurses or under Unix System V, R4
7  */
8 
9 #ifndef _XOPEN_SOURCE_EXTENDED
10 # define _XOPEN_SOURCE_EXTENDED 1
11 #endif
12 
13 #include <stdio.h>
14 #include <ctype.h>
15 #include <string.h>
16 #include <curses.h>
17 
18 #ifdef WACS_S1
19 # define HAVE_WIDE 1
20 #else
21 # define HAVE_WIDE 0
22 #endif
23 
24 #include <locale.h>
25 
26 #if HAVE_WIDE
27 # include <wchar.h>
28 #endif
29 
30 #if defined(PDCURSES) && !defined(XCURSES)
31 # define HAVE_RESIZE 1
32 #else
33 # define HAVE_RESIZE 0
34 #endif
35 
36 #ifdef A_COLOR
37 # define HAVE_COLOR 1
38 #else
39 # define HAVE_COLOR 0
40 #endif
41 
42 /* Set to non-zero if you want to test the PDCurses clipboard */
43 
44 #define HAVE_CLIPBOARD 0
45 
46 void inputTest(WINDOW *);
47 void scrollTest(WINDOW *);
48 void introTest(WINDOW *);
49 int initTest(WINDOW **, int, char **);
50 void outputTest(WINDOW *);
51 void padTest(WINDOW *);
52 void acsTest(WINDOW *);
53 void attrTest(WINDOW *);
54 
55 #if HAVE_COLOR
56 void colorTest(WINDOW *);
57 #endif
58 
59 #if HAVE_RESIZE
60 void resizeTest(WINDOW *);
61 #endif
62 
63 #if HAVE_CLIPBOARD
64 void clipboardTest(WINDOW *);
65 #endif
66 
67 #if HAVE_WIDE
68 void wideTest(WINDOW *);
69 #endif
70 
71 void display_menu(int, int);
72 
73 struct commands
74 {
75     const char *text;
76     void (*function)(WINDOW *);
77 };
78 
79 typedef struct commands COMMAND;
80 
81 #define MAX_OPTIONS (7 + HAVE_COLOR + HAVE_RESIZE + HAVE_CLIPBOARD + HAVE_WIDE)
82 
83 COMMAND command[MAX_OPTIONS] =
84 {
85     {"Intro Test", introTest},
86     {"Pad Test", padTest},
87 #if HAVE_RESIZE
88     {"Resize Test", resizeTest},
89 #endif
90     {"Scroll Test", scrollTest},
91     {"Input Test", inputTest},
92     {"Output Test", outputTest},
93     {"ACS Test", acsTest},
94     {"Attrib Test", attrTest},
95 #if HAVE_COLOR
96     {"Color Test", colorTest},
97 #endif
98 #if HAVE_CLIPBOARD
99     {"Clipboard Test", clipboardTest},
100 #endif
101 #if HAVE_WIDE
102     {"Wide Input", wideTest}
103 #endif
104 };
105 
106 int width, height;
107 
main(int argc,char * argv[])108 int main(int argc, char *argv[])
109 {
110     WINDOW *win;
111     int key, old_option = -1, new_option = 0;
112     bool quit = FALSE;
113 
114     setlocale(LC_ALL, "");
115 
116     if (initTest(&win, argc, argv))
117         return 1;
118 
119 #ifdef A_COLOR
120     if (has_colors())
121     {
122         init_pair(1, COLOR_WHITE, COLOR_BLUE);
123         wbkgd(win, COLOR_PAIR(1));
124     }
125     else
126 #endif
127         wbkgd(win, A_REVERSE);
128 
129     erase();
130     display_menu(old_option, new_option);
131 
132     while (1)
133     {
134         noecho();
135         keypad(stdscr, TRUE);
136         raw();
137 
138         key = getch();
139 
140         switch(key)
141         {
142         case 10:
143         case 13:
144         case KEY_ENTER:
145             old_option = -1;
146             erase();
147             refresh();
148             (*command[new_option].function)(win);
149             erase();
150             display_menu(old_option, new_option);
151             break;
152 
153         case KEY_PPAGE:
154         case KEY_HOME:
155             old_option = new_option;
156             new_option = 0;
157             display_menu(old_option, new_option);
158             break;
159 
160         case KEY_NPAGE:
161         case KEY_END:
162             old_option = new_option;
163             new_option = MAX_OPTIONS - 1;
164             display_menu(old_option, new_option);
165             break;
166 
167         case KEY_UP:
168             old_option = new_option;
169             new_option = (new_option == 0) ?
170                 new_option : new_option - 1;
171             display_menu(old_option, new_option);
172             break;
173 
174         case KEY_DOWN:
175             old_option = new_option;
176             new_option = (new_option == MAX_OPTIONS - 1) ?
177                 new_option : new_option + 1;
178             display_menu(old_option, new_option);
179             break;
180 #ifdef KEY_RESIZE
181         case KEY_RESIZE:
182 # ifdef PDCURSES
183             resize_term(0, 0);
184 # endif
185             old_option = -1;
186             erase();
187             display_menu(old_option, new_option);
188             break;
189 #endif
190         case 'Q':
191         case 'q':
192             quit = TRUE;
193         }
194 
195         if (quit == TRUE)
196             break;
197     }
198 
199     delwin(win);
200     endwin();
201 
202     return 0;
203 }
204 
Continue(WINDOW * win)205 void Continue(WINDOW *win)
206 {
207     mvwaddstr(win, 10, 1, " Press any key to continue");
208     wrefresh(win);
209     raw();
210     wgetch(win);
211 }
212 
Continue2(void)213 void Continue2(void)
214 {
215     move(LINES - 1, 1);
216     clrtoeol();
217     mvaddstr(LINES - 2, 1, " Press any key to continue");
218     refresh();
219     raw();
220     getch();
221 }
222 
initTest(WINDOW ** win,int argc,char * argv[])223 int initTest(WINDOW **win, int argc, char *argv[])
224 {
225 #ifdef XCURSES
226     Xinitscr(argc, argv);
227 #else
228     initscr();
229 #endif
230 #ifdef A_COLOR
231     if (has_colors())
232         start_color();
233 #endif
234     /* Create a drawing window */
235 
236     width  = 60;
237     height = 13;
238 
239     *win = newwin(height, width, (LINES - height) / 2, (COLS - width) / 2);
240 
241     if (*win == NULL)
242     {
243         endwin();
244         return 1;
245     }
246 
247     return 0;
248 }
249 
introTest(WINDOW * win)250 void introTest(WINDOW *win)
251 {
252     werase(win);
253     wmove(win, height / 2 - 5, width / 2);
254     wvline(win, ACS_VLINE, 10);
255     wmove(win, height / 2, width / 2 - 10);
256     whline(win, ACS_HLINE, 20);
257     Continue(win);
258 
259     beep();
260     werase(win);
261 
262     box(win, ACS_VLINE, ACS_HLINE);
263     wrefresh(win);
264 
265     cbreak();
266     mvwaddstr(win, 1, 1,
267         "You should have a rectangle in the middle of the screen");
268     mvwaddstr(win, 2, 1, "You should have heard a beep");
269     Continue(win);
270 
271     flash();
272     mvwaddstr(win, 3, 1, "You should have seen a flash");
273     Continue(win);
274 }
275 
scrollTest(WINDOW * win)276 void scrollTest(WINDOW *win)
277 {
278     int i, OldY;
279 #ifndef PDCURSES
280     int OldX;
281 #endif
282     werase(win);
283     mvwaddstr(win, height - 2, 1, "The window will now scroll slowly");
284     box(win, ACS_VLINE, ACS_HLINE);
285     wrefresh(win);
286     scrollok(win, TRUE);
287     napms(500);
288 
289     for (i = 1; i <= height; i++)
290     {
291         napms(150);
292         scroll(win);
293         wrefresh(win);
294     };
295 
296 #ifdef PDCURSES
297     OldY = getmaxy(win);
298 #else
299     getmaxyx(win, OldY, OldX);
300 #endif
301     mvwaddstr(win, 6, 1, "The top of the window will scroll");
302     wmove(win, 1, 1);
303     wsetscrreg(win, 0, 4);
304     box(win, ACS_VLINE, ACS_HLINE);
305     wrefresh(win);
306 
307     for (i = 1; i <= 5; i++)
308     {
309         napms(500);
310         scroll(win);
311         wrefresh(win);
312     }
313 
314     mvwaddstr(win, 3, 1, "The bottom of the window will scroll");
315     wmove(win, 8, 1);
316     wsetscrreg(win, 5, --OldY);
317     box(win, ACS_VLINE, ACS_HLINE);
318     wrefresh(win);
319 
320     for (i = 5; i <= OldY; i++)
321     {
322         napms(300);
323         wscrl(win, -1);
324         wrefresh(win);
325     }
326 
327     wsetscrreg(win, 0, OldY);
328 }
329 
inputTest(WINDOW * win)330 void inputTest(WINDOW *win)
331 {
332     int w, h, bx, by, sw, sh, i, c, num = 0;
333     char buffer[80];
334     WINDOW *subWin;
335     static const char spinner[4] = "/-\\|";
336     int spinner_count = 0;
337 
338     wclear(win);
339 
340     getmaxyx(win, h, w);
341     getbegyx(win, by, bx);
342 
343     sw = w / 3;
344     sh = h / 3;
345 
346     if ((subWin = subwin(win, sh, sw, by + h - sh - 2, bx + w - sw - 2))
347         == NULL)
348         return;
349 
350 #ifdef A_COLOR
351     if (has_colors())
352     {
353         init_pair(2, COLOR_WHITE, COLOR_RED);
354         wbkgd(subWin, COLOR_PAIR(2) | A_BOLD);
355     }
356     else
357 #endif
358         wbkgd(subWin, A_BOLD);
359 
360     box(subWin, ACS_VLINE, ACS_HLINE);
361     wrefresh(win);
362 
363     nocbreak();
364 
365     wclear (win);
366     mvwaddstr(win, 1, 1,
367         "Press keys (or mouse buttons) to show their names");
368     mvwaddstr(win, 2, 1, "Press spacebar to finish");
369     wrefresh(win);
370 
371     keypad(win, TRUE);
372     raw();
373     noecho();
374 
375     wtimeout(win, 200);
376 
377 #ifdef PDCURSES
378     mouse_set(ALL_MOUSE_EVENTS);
379     PDC_save_key_modifiers(TRUE);
380     PDC_return_key_modifiers(TRUE);
381 #endif
382     curs_set(0);        /* turn cursor off */
383 
384     while (1)
385     {
386         while (1)
387         {
388             c = wgetch(win);
389 
390             if (c == ERR)
391             {
392                 spinner_count++;
393                 if (spinner_count == 4)
394                     spinner_count = 0;
395                 mvwaddch(win, 3, 3, spinner[spinner_count]);
396                 wrefresh(win);
397             }
398             else
399                 break;
400         }
401 #ifdef PDCURSES
402         wmove(win, 4, 18);
403         wclrtoeol(win);
404 #endif
405         mvwaddstr(win, 3, 5, "Key Pressed: ");
406         wclrtoeol(win);
407 
408         if (c >= KEY_MIN)
409             wprintw(win, "%s", keyname(c));
410         else if (isprint(c))
411             wprintw(win, "%c", c);
412         else
413             wprintw(win, "%s", unctrl(c));
414 #ifdef PDCURSES
415         if (c == KEY_MOUSE)
416         {
417             int button = 0;
418             request_mouse_pos();
419 
420             if (BUTTON_CHANGED(1))
421                 button = 1;
422             else if (BUTTON_CHANGED(2))
423                 button = 2;
424             else if (BUTTON_CHANGED(3))
425                 button = 3;
426 
427             if (button && (BUTTON_STATUS(button) &
428                 BUTTON_MODIFIER_MASK))
429             {
430                 waddstr(win, " Modifier(s):");
431 
432                 if (BUTTON_STATUS(button) & BUTTON_SHIFT)
433                     waddstr(win, " SHIFT");
434 
435                 if (BUTTON_STATUS(button) & BUTTON_CONTROL)
436                     waddstr(win, " CONTROL");
437 
438                 if (BUTTON_STATUS(button) & BUTTON_ALT)
439                     waddstr(win, " ALT");
440             }
441 
442             wmove(win, 4, 18);
443             wclrtoeol(win);
444             wprintw(win, "Button %d: ", button);
445 
446             if (MOUSE_MOVED)
447                 waddstr(win, "moved: ");
448             else if (MOUSE_WHEEL_UP)
449                 waddstr(win, "wheel up: ");
450             else if (MOUSE_WHEEL_DOWN)
451                 waddstr(win, "wheel dn: ");
452             else if (MOUSE_WHEEL_LEFT)
453                 waddstr(win, "wheel lt: ");
454             else if (MOUSE_WHEEL_RIGHT)
455                 waddstr(win, "wheel rt: ");
456             else if ((BUTTON_STATUS(button) &
457                 BUTTON_ACTION_MASK) == BUTTON_PRESSED)
458                 waddstr(win, "pressed: ");
459             else if ((BUTTON_STATUS(button) &
460                 BUTTON_ACTION_MASK) == BUTTON_CLICKED)
461                 waddstr(win, "clicked: ");
462             else if ((BUTTON_STATUS(button) &
463                 BUTTON_ACTION_MASK) == BUTTON_DOUBLE_CLICKED)
464                 waddstr(win, "double: ");
465             else
466                 waddstr(win, "released: ");
467 
468             wprintw(win, "Position: Y: %d X: %d", MOUSE_Y_POS, MOUSE_X_POS);
469         }
470         else if (PDC_get_key_modifiers())
471         {
472             waddstr(win, " Modifier(s):");
473             if (PDC_get_key_modifiers() & PDC_KEY_MODIFIER_SHIFT)
474                 waddstr(win, " SHIFT");
475 
476             if (PDC_get_key_modifiers() & PDC_KEY_MODIFIER_CONTROL)
477                 waddstr(win, " CONTROL");
478 
479             if (PDC_get_key_modifiers() & PDC_KEY_MODIFIER_ALT)
480                 waddstr(win, " ALT");
481 
482             if (PDC_get_key_modifiers() & PDC_KEY_MODIFIER_NUMLOCK)
483                 waddstr(win, " NUMLOCK");
484         }
485 #endif
486         wrefresh(win);
487 
488         if (c == ' ')
489             break;
490     }
491 
492     wtimeout(win, -1);  /* turn off timeout() */
493     curs_set(1);        /* turn cursor back on */
494 
495 #ifdef PDCURSES
496     mouse_set(0L);
497     PDC_save_key_modifiers(FALSE);
498     PDC_return_key_modifiers(FALSE);
499 #endif
500     wclear(win);
501     mvwaddstr(win, 2, 1, "Press some keys for 5 seconds");
502     mvwaddstr(win, 1, 1, "Pressing ^C should do nothing");
503     wrefresh(win);
504 
505     werase(subWin);
506     box(subWin, ACS_VLINE, ACS_HLINE);
507 
508     for (i = 0; i < 5; i++)
509     {
510         mvwprintw(subWin, 1, 1, "Time = %d", i);
511         wrefresh(subWin);
512         napms(1000);
513         flushinp();
514     }
515 
516     delwin(subWin);
517     werase(win);
518     flash();
519     wrefresh(win);
520     napms(500);
521     flushinp();
522 
523     mvwaddstr(win, 2, 1, "Press a key, followed by ENTER");
524     wmove(win, 9, 10);
525     wrefresh(win);
526     echo();
527 
528     keypad(win, TRUE);
529     raw();
530     wgetnstr(win, buffer, 3);
531     flushinp();
532 
533     wmove(win, 9, 10);
534     wdelch(win);
535     mvwaddstr(win, 4, 1, "The character should now have been deleted");
536     Continue(win);
537 
538     refresh();
539     wclear(win);
540     echo();
541     buffer[0] = '\0';
542     mvwaddstr(win, 3, 2, "The window should have moved");
543     mvwaddstr(win, 4, 2,
544               "This text should have appeared without you pressing a key");
545     mvwaddstr(win, 6, 2, "Enter a number then a string seperated by space");
546     mvwin(win, 2, 1);
547     wrefresh(win);
548     mvwscanw(win, 7, 6, "%d %s", &num, buffer);
549     mvwprintw(win, 8, 6, "String: %s Number: %d", buffer, num);
550     Continue(win);
551 
552     refresh();
553     wclear(win);
554     echo();
555     mvwaddstr(win, 3, 2, "Enter a 5 character string: ");
556     wgetnstr(win, buffer, 5);
557     mvwprintw(win, 4, 2, "String: %s", buffer);
558     Continue(win);
559 }
560 
outputTest(WINDOW * win)561 void outputTest(WINDOW *win)
562 {
563     WINDOW *win1;
564     char Buffer[80];
565     chtype ch;
566     int by, bx;
567 
568 #ifdef PDCURSES
569     PDC_set_blink(TRUE);
570 #endif
571     nl();
572     wclear(win);
573     mvwaddstr(win, 1, 1, "You should now have a screen in the upper "
574                          "left corner, and this text should have wrapped");
575     waddstr(win,"\nThis text should be down\n");
576     waddstr(win,  "and broken into two here ^");
577     Continue(win);
578 
579     wclear(win);
580     wattron(win, A_BOLD);
581     mvwaddstr(win, 1, 1, "A new window will appear with this text in it");
582     mvwaddstr(win, 8, 1, "Press any key to continue");
583     wrefresh(win);
584     wgetch(win);
585 
586     getbegyx(win, by, bx);
587 
588     if (LINES < 24 || COLS < 75)
589     {
590         mvwaddstr(win, 5, 1, "Some tests have been skipped as they require a");
591         mvwaddstr(win, 6, 1, "display of at least 24 LINES by 75 COLUMNS");
592         Continue(win);
593     }
594     else
595     {
596         win1 = newwin(10, 50, 14, 25);
597 
598         if (win1 == NULL)
599         {
600             endwin();
601             return;
602         }
603 
604 #ifdef A_COLOR
605         if (has_colors())
606         {
607             init_pair(3, COLOR_BLUE, COLOR_WHITE);
608             wbkgd(win1, COLOR_PAIR(3));
609         }
610         else
611 #endif
612             wbkgd(win1, A_NORMAL);
613 
614         wclear(win1);
615         mvwaddstr(win1, 5, 1, "This text should appear; using overlay option");
616         copywin(win, win1, 0, 0, 0, 0, 9, 49, TRUE);
617         box(win1, ACS_VLINE, ACS_HLINE);
618         wmove(win1, 8, 26);
619         wrefresh(win1);
620         wgetch(win1);
621 
622         wclear(win1);
623 
624         wattron(win1, A_BLINK);
625         mvwaddstr(win1, 4, 1,
626                   "This blinking text should appear in only the second window");
627         wattroff(win1, A_BLINK);
628 
629         mvwin(win1, by, bx);
630         overlay(win, win1);
631         mvwin(win1, 14, 25);
632         wmove(win1, 8, 26);
633         wrefresh(win1);
634         wgetch(win1);
635 
636         delwin(win1);
637     }
638 
639     clear();
640     wclear(win);
641     wrefresh(win);
642     mvwaddstr(win, 6, 2, "This line shouldn't appear");
643     mvwaddstr(win, 4, 2, "Only half of the next line is visible");
644     mvwaddstr(win, 5, 2, "Only half of the next line is visible");
645     wmove(win, 6, 1);
646     wclrtobot(win);
647     wmove(win, 5, 20);
648     wclrtoeol(win);
649     mvwaddstr(win, 8, 2, "This line also shouldn't appear");
650     wmove(win, 8, 1);
651     winsdelln(win, -1);
652     Continue(win);
653 
654     wmove(win, 5, 9);
655     ch = winch(win);
656 
657     wclear(win);
658     wmove(win, 6, 2);
659     waddstr(win, "The next char should be l:  ");
660     winsch(win, ch);
661     Continue(win);
662 
663     mvwinsstr(win, 6, 2, "A1B2C3D4E5");
664     Continue(win);
665 
666     wmove(win, 5, 1);
667     winsdelln(win, 1);
668     mvwaddstr(win, 5, 2, "The lines below should have moved down");
669     Continue(win);
670 
671     wclear(win);
672     wmove(win, 2, 2);
673     wprintw(win, "This is a formatted string in a window: %d %s\n",
674             42, "is it");
675     mvwaddstr(win, 10, 1, "Enter a string: ");
676     wrefresh(win);
677     echo();
678     wscanw(win, "%s", Buffer);
679 
680     printw("This is a formatted string in stdscr: %d %s\n", 42, "is it");
681     mvaddstr(10, 1, "Enter a string: ");
682     scanw("%s", Buffer);
683 
684     wclear(win);
685     curs_set(2);
686     mvwaddstr(win, 1, 1, "The cursor should be in high-visibility mode");
687     Continue(win);
688 
689     wclear(win);
690     curs_set(0);
691     mvwaddstr(win, 1, 1, "The cursor should have disappeared");
692     Continue(win);
693 
694     wclear(win);
695     curs_set(1);
696     mvwaddstr(win, 1, 1, "The cursor should be normal");
697     Continue(win);
698 
699 #ifdef A_COLOR
700     if (has_colors())
701     {
702         wclear(win);
703         mvwaddstr(win, 1, 1, "Colors should change after you press a key");
704         Continue(win);
705 
706         init_pair(1, COLOR_RED, COLOR_WHITE);
707         wrefresh(win);
708     }
709 #endif
710     werase(win);
711     mvwaddstr(win, 1, 1, "Information About Your Terminal");
712     mvwaddstr(win, 3, 1, termname());
713     mvwaddstr(win, 4, 1, longname());
714 
715     if (termattrs() & A_BLINK)
716         mvwaddstr(win, 5, 1, "This terminal claims to support blinking.");
717     else
718         mvwaddstr(win, 5, 1, "This terminal does NOT support blinking.");
719 
720     mvwaddnstr(win, 7, 5, "Have a nice day!ok", 16);
721     wrefresh(win);
722 
723     mvwinnstr(win, 7, 5, Buffer, 18);
724     mvaddstr(LINES - 2, 10, Buffer);
725     refresh();
726     Continue(win);
727 #ifdef PDCURSES
728     PDC_set_blink(FALSE);
729 #endif
730 }
731 
732 #if HAVE_RESIZE
resizeTest(WINDOW * dummy)733 void resizeTest(WINDOW *dummy)
734 {
735     WINDOW *win1;
736     int nwidth = 135, nheight = 52;
737     int owidth = COLS, oheight = LINES;
738 
739     savetty();
740 
741     resize_term(nheight, nwidth);
742 
743     clear();
744     refresh();
745 
746     win1 = newwin(10, 50, 14, 25);
747 
748     if (win1 == NULL)
749     {
750         endwin();
751         return;
752     }
753 
754 #ifdef A_COLOR
755     if (has_colors())
756     {
757         init_pair(3, COLOR_BLUE, COLOR_WHITE);
758         wattrset(win1, COLOR_PAIR(3));
759     }
760 
761     wclear(win1);
762 #endif
763     mvwaddstr(win1, 0, 0, "The screen may now be resized");
764     mvwprintw(win1, 1, 4, "Given size: %d by %d", nwidth, nheight);
765     mvwprintw(win1, 2, 4, "Actual size: %d by %d", COLS, LINES);
766     Continue(win1);
767 
768     wclear(win1);
769     resetty();
770 
771     mvwaddstr(win1, 0, 0, "The screen should now be reset");
772     mvwprintw(win1, 1, 6, "Old size: %d by %d", owidth, oheight);
773     mvwprintw(win1, 2, 6, "Size now: %d by %d", COLS, LINES);
774     Continue(win1);
775 
776     delwin(win1);
777 
778     clear();
779     refresh();
780 }
781 #endif /* HAVE_RESIZE */
782 
padTest(WINDOW * dummy)783 void padTest(WINDOW *dummy)
784 {
785     WINDOW *pad, *spad;
786 
787     pad = newpad(50, 100);
788     wattron(pad, A_REVERSE);
789     mvwaddstr(pad, 5, 2, "This is a new pad");
790     wattrset(pad, 0);
791     mvwaddstr(pad, 8, 0,
792         "The end of this line should be truncated here:except  now");
793     mvwaddstr(pad, 11, 1, "This line should not appear.It will now");
794     wmove(pad, 10, 1);
795     wclrtoeol(pad);
796     mvwaddstr(pad, 10, 1, " Press any key to continue");
797     prefresh(pad, 0, 0, 0, 0, 10, 45);
798     keypad(pad, TRUE);
799     raw();
800     wgetch(pad);
801 
802     spad = subpad(pad, 12, 25, 7, 52);
803     mvwaddstr(spad, 2, 2, "This is a new subpad");
804     box(spad, 0, 0);
805     prefresh(pad, 0, 0, 0, 0, 15, 75);
806     keypad(pad, TRUE);
807     raw();
808     wgetch(pad);
809 
810     mvwaddstr(pad, 35, 2, "This is displayed at line 35 in the pad");
811     mvwaddstr(pad, 40, 1, " Press any key to continue");
812     prefresh(pad, 30, 0, 0, 0, 10, 45);
813     keypad(pad, TRUE);
814     raw();
815     wgetch(pad);
816 
817     delwin(pad);
818 }
819 
820 #if HAVE_CLIPBOARD
clipboardTest(WINDOW * win)821 void clipboardTest(WINDOW *win)
822 {
823     static const char *text =
824         "This string placed in clipboard by PDCurses test program, testcurs.";
825     char *ptr = NULL;
826     long i, length = 0;
827 
828     mvaddstr(1, 1,
829              "This test will display the contents of the system clipboard");
830 
831     Continue2();
832 
833     scrollok(stdscr, TRUE);
834     i = PDC_getclipboard(&ptr, &length);
835 
836     switch(i)
837     {
838     case PDC_CLIP_ACCESS_ERROR:
839         mvaddstr(3, 1, "There was an error accessing the clipboard");
840         refresh();
841         break;
842 
843     case PDC_CLIP_MEMORY_ERROR:
844         mvaddstr(3, 1,
845             "Unable to allocate memory for clipboard contents");
846         break;
847 
848     case PDC_CLIP_EMPTY:
849         mvaddstr(3, 1, "There was no text in the clipboard");
850         break;
851 
852     default:
853         wsetscrreg(stdscr, 0, LINES - 1);
854         clear();
855         mvaddstr(1, 1, "Clipboard contents...");
856         mvprintw(2, 1, "%s\n", ptr);
857     }
858 
859     Continue2();
860 
861     clear();
862     mvaddstr(1, 1,
863         "This test will place the following string in the system clipboard:");
864     mvaddstr(2, 1, text);
865 
866     i = PDC_setclipboard(text, strlen(text));
867 
868     switch(i)
869     {
870     case PDC_CLIP_ACCESS_ERROR:
871         mvaddstr(3, 1, "There was an error accessing the clipboard");
872         break;
873 
874     case PDC_CLIP_MEMORY_ERROR:
875         mvaddstr(3, 1, "Unable to allocate memory for clipboard contents");
876         break;
877 
878     default:
879         mvaddstr(3, 1, "The string was placed in the clipboard successfully");
880     }
881 
882     Continue2();
883 }
884 #endif /* HAVE_CLIPBOARD */
885 
acsTest(WINDOW * win)886 void acsTest(WINDOW *win)
887 {
888 #ifdef ACS_S3
889 # define ACSNUM 32
890 #else
891 # define ACSNUM 25
892 #endif
893     static const char *acs_names[] =
894     {
895         "ACS_ULCORNER", "ACS_URCORNER", "ACS_LLCORNER", "ACS_LRCORNER",
896         "ACS_LTEE", "ACS_RTEE", "ACS_TTEE", "ACS_BTEE", "ACS_HLINE",
897         "ACS_VLINE", "ACS_PLUS",
898 
899         "ACS_S1", "ACS_S9", "ACS_DIAMOND", "ACS_CKBOARD", "ACS_DEGREE",
900         "ACS_PLMINUS", "ACS_BULLET",
901 
902         "ACS_LARROW", "ACS_RARROW", "ACS_UARROW", "ACS_DARROW",
903         "ACS_BOARD", "ACS_LANTERN", "ACS_BLOCK"
904 #ifdef ACS_S3
905         , "ACS_S3", "ACS_S7", "ACS_LEQUAL", "ACS_GEQUAL",
906         "ACS_PI", "ACS_NEQUAL", "ACS_STERLING"
907 #endif
908     };
909 
910     chtype acs_values[ACSNUM];
911 
912 #if HAVE_WIDE
913     cchar_t *wacs_values[] =
914     {
915         WACS_ULCORNER, WACS_URCORNER, WACS_LLCORNER, WACS_LRCORNER,
916         WACS_LTEE, WACS_RTEE, WACS_TTEE, WACS_BTEE, WACS_HLINE,
917         WACS_VLINE, WACS_PLUS,
918 
919         WACS_S1, WACS_S9, WACS_DIAMOND, WACS_CKBOARD, WACS_DEGREE,
920         WACS_PLMINUS, WACS_BULLET,
921 
922         WACS_LARROW, WACS_RARROW, WACS_UARROW, WACS_DARROW, WACS_BOARD,
923         WACS_LANTERN, WACS_BLOCK
924 # ifdef WACS_S3
925         , WACS_S3, WACS_S7, WACS_LEQUAL, WACS_GEQUAL, WACS_PI,
926         WACS_NEQUAL, WACS_STERLING
927 # endif
928     };
929 
930     static const wchar_t russian[] = {0x0420, 0x0443, 0x0441, 0x0441,
931         0x043a, 0x0438, 0x0439, L' ', 0x044f, 0x0437, 0x044b, 0x043a, 0};
932 
933     static const wchar_t greek[] = {0x0395, 0x03bb, 0x03bb, 0x03b7,
934         0x03bd, 0x03b9, 0x03ba, 0x03ac, 0};
935 
936     static const wchar_t georgian[] = {0x10e5, 0x10d0, 0x10e0, 0x10d7,
937         0x10e3, 0x10da, 0x10d8, L' ', 0x10d4, 0x10dc, 0x10d0, 0};
938 #endif
939 
940     int i, tmarg = (LINES - 22) / 2;
941 
942     attrset(A_BOLD);
943     mvaddstr(tmarg, (COLS - 23) / 2, "Alternate Character Set");
944     attrset(A_NORMAL);
945 
946     tmarg += 3;
947 
948 #define A(b,c) acs_values[b] = ACS_##c
949 
950     A(0,ULCORNER); A(1,URCORNER); A(2,LLCORNER); A(3,LRCORNER);
951     A(4,LTEE);     A(5,RTEE);     A(6,TTEE);     A(7,BTEE);
952     A(8,HLINE);    A(9,VLINE);    A(10,PLUS);    A(11,S1);
953     A(12,S9);      A(13,DIAMOND); A(14,CKBOARD); A(15,DEGREE);
954 
955     A(16,PLMINUS); A(17,BULLET);  A(18,LARROW);  A(19,RARROW);
956     A(20,UARROW);  A(21,DARROW);  A(22,BOARD);   A(23,LANTERN);
957     A(24,BLOCK);
958 #ifdef ACS_S3
959     A(25,S3);      A(26,S7);      A(27,LEQUAL);  A(28,GEQUAL);
960     A(29,PI);      A(30,NEQUAL);  A(31,STERLING);
961 #endif
962 
963 #undef A
964 
965     for (i = 0; i < ACSNUM; i++)
966     {
967         move((i % 8) * 2 + tmarg, (i / 8) * (COLS / 4) + (COLS / 8 - 7));
968         addch(acs_values[i]);
969         printw(" %s", acs_names[i]);
970     }
971 
972     mvaddstr(tmarg + 18, 3, "Press any key to continue");
973     getch();
974 
975 #if HAVE_WIDE
976     clear();
977 
978     attrset(A_BOLD);
979     mvaddstr(tmarg - 3, (COLS - 28) / 2, "Wide Alternate Character Set");
980     attrset(A_NORMAL);
981 
982     for (i = 0; i < ACSNUM; i++)
983     {
984         move((i % 8) * 2 + tmarg, (i / 8) * (COLS / 4) + (COLS / 8 - 7));
985         add_wch(wacs_values[i]);
986         printw(" W%s", acs_names[i]);
987     }
988 
989     /* Spanish, Russian, Greek, Georgian */
990 
991     mvaddwstr(tmarg + 16, COLS / 8 - 5, L"Espa\xf1ol");
992     mvaddwstr(tmarg + 16, 3 * (COLS / 8) - 5, russian);
993     mvaddwstr(tmarg + 16, 5 * (COLS / 8) - 5, greek);
994     mvaddwstr(tmarg + 16, 7 * (COLS / 8) - 5, georgian);
995 
996     mvaddstr(tmarg + 18, 3, "Press any key to continue");
997     getch();
998 #endif
999 }
1000 
attrTest(WINDOW * win)1001 void attrTest(WINDOW *win)
1002 {
1003     int tmarg = (LINES - 16) / 2;
1004     int col1 = (COLS - 36) / 2, col2 = col1 + 20;
1005 
1006     attrset(A_BOLD);
1007     mvaddstr(tmarg, (COLS - 20) / 2, "Character Attributes");
1008     attrset(A_NORMAL);
1009 
1010     refresh();
1011 
1012 #ifdef PDCURSES
1013     PDC_set_blink(TRUE);
1014     PDC_set_bold(TRUE);
1015 #endif
1016 
1017 #ifdef A_ITALIC
1018     attrset(A_ITALIC);
1019     mvaddstr(tmarg + 3, col1, "A_ITALIC");
1020     attrset(A_NORMAL);
1021 #endif
1022 
1023     attrset(A_BOLD);
1024     mvaddstr(tmarg + 5, col1, "A_BOLD");
1025     attrset(A_NORMAL);
1026 
1027     attrset(A_BLINK);
1028     mvaddstr(tmarg + 7, col1, "A_BLINK");
1029     attrset(A_NORMAL);
1030 
1031     attrset(A_REVERSE);
1032     mvaddstr(tmarg + 9, col1, "A_REVERSE");
1033     attrset(A_NORMAL);
1034 
1035     attrset(A_STANDOUT);
1036     mvaddstr(tmarg + 11, col1, "A_STANDOUT");
1037     attrset(A_NORMAL);
1038 
1039     attrset(A_UNDERLINE);
1040     mvaddstr(tmarg + 13, col1, "A_UNDERLINE");
1041     attrset(A_NORMAL);
1042 
1043 #ifdef A_ITALIC
1044     attrset(A_ITALIC|A_UNDERLINE);
1045     mvaddstr(tmarg + 3, col2, "Underlined Italic");
1046     attrset(A_NORMAL);
1047 #endif
1048 
1049     attrset(A_BOLD|A_UNDERLINE);
1050     mvaddstr(tmarg + 5, col2, "Underlined Bold");
1051     attrset(A_NORMAL);
1052 
1053     attrset(A_BLINK|A_UNDERLINE);
1054     mvaddstr(tmarg + 7, col2, "Underlined Blink");
1055     attrset(A_NORMAL);
1056 
1057 #ifdef A_LEFTLINE
1058     attrset(A_LEFTLINE);
1059     mvaddstr(tmarg + 9, col2, "A_LEFTLINE");
1060     attrset(A_NORMAL);
1061 #endif
1062 
1063 #ifdef A_RIGHTLINE
1064     attrset(A_RIGHTLINE);
1065     mvaddstr(tmarg + 11, col2, "A_RIGHTLINE");
1066     attrset(A_NORMAL);
1067 #endif
1068 
1069     attrset(A_PROTECT);
1070     mvaddstr(tmarg + 13, col2, "A_PROTECT");
1071     attrset(A_NORMAL);
1072 
1073     mvaddstr(tmarg + 16, 3, "Press any key to continue");
1074     getch();
1075 
1076 #ifdef PDCURSES
1077     PDC_set_bold(FALSE);
1078     PDC_set_blink(FALSE);
1079 #endif
1080 }
1081 
1082 #if HAVE_COLOR
colorTest(WINDOW * win)1083 void colorTest(WINDOW *win)
1084 {
1085     static const short colors[] =
1086     {
1087         COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_BLUE,
1088         COLOR_CYAN, COLOR_MAGENTA, COLOR_YELLOW, COLOR_WHITE
1089     };
1090 
1091     static const char *colornames[] =
1092     {
1093         "COLOR_BLACK", "COLOR_RED", "COLOR_GREEN", "COLOR_BLUE",
1094         "COLOR_CYAN", "COLOR_MAGENTA", "COLOR_YELLOW", "COLOR_WHITE"
1095     };
1096 
1097     chtype fill = ACS_BLOCK;
1098     int maxcol = (COLORS >= 16) ? 16 : 8;
1099     bool widecol = (maxcol == 16);
1100 
1101     int i, j, tmarg, col1, col2, col3;
1102 
1103     if (!has_colors())
1104         return;
1105 
1106     tmarg = (LINES - 19) / 2;
1107     col1 = (COLS - 60) / 2;
1108     col2 = col1 + 20;
1109     col3 = col2 + 20;
1110 
1111     attrset(A_BOLD);
1112     mvaddstr(tmarg, (COLS - 22) / 2, "Color Attribute Macros");
1113     attrset(A_NORMAL);
1114 
1115     if (widecol)
1116     {
1117         mvaddstr(tmarg + 3, col2 + 3, "Colors 0-7");
1118         mvaddstr(tmarg + 3, col3 + 2, "Colors 8-15");
1119     }
1120     else
1121     {
1122         mvaddstr(tmarg + 3, col2 + 4, "A_NORMAL");
1123         mvaddstr(tmarg + 3, col3 + 5, "A_BOLD");
1124     }
1125 
1126     for (i = 0; i < 8; i++)
1127     {
1128         init_pair(i + 4, colors[i], COLOR_BLACK);
1129         if (widecol)
1130             init_pair(i + 12, colors[i] + 8, COLOR_BLACK);
1131 
1132         mvaddstr(tmarg + i + 5, col1, colornames[i]);
1133 
1134         for (j = 0; j < 16; j++)
1135         {
1136             mvaddch(tmarg + i + 5, col2 + j, fill | COLOR_PAIR(i + 4));
1137             mvaddch(tmarg + i + 5, col3 + j, fill | (widecol ?
1138                     COLOR_PAIR(i + 12) : (COLOR_PAIR(i + 4) | A_BOLD) ));
1139         }
1140     }
1141 
1142     mvprintw(tmarg + 15, col1, "COLORS = %d", COLORS);
1143     mvprintw(tmarg + 16, col1, "COLOR_PAIRS = %d", COLOR_PAIRS);
1144 
1145     mvaddstr(tmarg + 19, 3, "Press any key to continue");
1146     getch();
1147 
1148     if (can_change_color())
1149     {
1150         struct
1151         {
1152             short red, green, blue;
1153         } orgcolors[16];
1154 
1155         for (i = 0; i < maxcol; i++)
1156             color_content(i, &(orgcolors[i].red),
1157                              &(orgcolors[i].green),
1158                              &(orgcolors[i].blue));
1159 
1160         attrset(A_BOLD);
1161         mvaddstr(tmarg, (COLS - 22) / 2, " init_color() Example ");
1162         attrset(A_NORMAL);
1163 
1164         refresh();
1165 
1166         for (i = 0; i < 8; i++)
1167         {
1168             init_color(colors[i], i * 125, 0, i * 125);
1169 
1170             if (widecol)
1171                 init_color(colors[i] + 8, 0, i * 125, 0);
1172         }
1173 
1174         mvaddstr(tmarg + 19, 3, "Press any key to continue");
1175         getch();
1176 
1177         for (i = 0; i < maxcol; i++)
1178             init_color(i, orgcolors[i].red,
1179                           orgcolors[i].green,
1180                           orgcolors[i].blue);
1181     }
1182 
1183     if (COLORS >= 256)
1184     {
1185         int x, y, z, lmarg = (COLS - 77) / 2;
1186 
1187         erase();
1188 
1189         attrset(A_BOLD);
1190         mvaddstr(tmarg, (COLS - 15) / 2, "Extended Colors");
1191         attrset(A_NORMAL);
1192 
1193         mvaddstr(tmarg + 3, lmarg, "6x6x6 Color Cube (16-231):");
1194 
1195         for (i = 16; i < 256; i++)
1196             init_pair(i, COLOR_BLACK, i);
1197 
1198         for (i = 16, z = 0; z < 6; z++)
1199             for (y = 0; y < 6; y++)
1200                 for (x = 0; x < 6; x++)
1201                 {
1202                     chtype ch = ' ' | COLOR_PAIR(i++);
1203 
1204                     mvaddch(tmarg + 5 + y, z * 13 + x * 2 + lmarg, ch);
1205                     addch(ch);
1206                 }
1207 
1208         mvaddstr(tmarg + 13, lmarg, "Greyscale (232-255):");
1209 
1210         for (x = 0; x < 24; x++)
1211         {
1212             chtype ch = ' ' | COLOR_PAIR(232 + x);
1213 
1214             mvaddch(tmarg + 15, x * 2 + lmarg, ch);
1215             addch(ch);
1216         }
1217 
1218         mvaddstr(tmarg + 19, 3, "Press any key to continue");
1219         getch();
1220     }
1221 }
1222 #endif
1223 
1224 #if HAVE_WIDE
wideTest(WINDOW * win)1225 void wideTest(WINDOW *win)
1226 {
1227     wchar_t tmp[513];
1228     size_t i;
1229 
1230     attrset(A_BOLD);
1231     mvaddstr(1, (COLS - 25) / 2, "Wide Character Input Test");
1232     attrset(A_NORMAL);
1233 
1234     mvaddstr(4, 1, "Enter a string: ");
1235 
1236     echo();
1237 
1238     get_wstr((wint_t *)tmp);
1239     addstr("\n\n String:\n\n ");
1240     addwstr(tmp);
1241     addstr("\n\n\n Hex:\n\n ");
1242 
1243     for (i = 0; i < wcslen(tmp); i++)
1244     {
1245         printw("%04x ", tmp[i]);
1246         addnwstr(tmp + i, 1);
1247         addstr("  ");
1248     }
1249 
1250     noecho();
1251 
1252     Continue2();
1253 }
1254 #endif
1255 
display_menu(int old_option,int new_option)1256 void display_menu(int old_option, int new_option)
1257 {
1258     int lmarg = (COLS - 14) / 2,
1259         tmarg = (LINES - (MAX_OPTIONS + 2)) / 2;
1260 
1261     if (old_option == -1)
1262     {
1263         int i;
1264 
1265         attrset(A_BOLD);
1266         mvaddstr(tmarg - 3, lmarg - 5, "PDCurses Test Program");
1267         attrset(A_NORMAL);
1268 
1269         for (i = 0; i < MAX_OPTIONS; i++)
1270             mvaddstr(tmarg + i, lmarg, command[i].text);
1271     }
1272     else
1273         mvaddstr(tmarg + old_option, lmarg, command[old_option].text);
1274 
1275     attrset(A_REVERSE);
1276     mvaddstr(tmarg + new_option, lmarg, command[new_option].text);
1277     attrset(A_NORMAL);
1278 
1279     mvaddstr(tmarg + MAX_OPTIONS + 2, lmarg - 23,
1280              "Use Up and Down Arrows to select - Enter to run - Q to quit");
1281     refresh();
1282 }
1283