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