ncurses 6.0 - patch 20170909
[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.52 2017/09/04 11:49:55 tom Exp $
10  */
11
12 #include <test.priv.h>
13
14 #if defined(XCURSES)
15 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     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         exit_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, c, 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         wmove(win, 3, 5);
242         c = wgetch(win);
243         wclrtobot(win);
244         if (c >= KEY_MIN)
245             wprintw(win, "Key Pressed: %s", keyname(c));
246         else if (isprint(c))
247             wprintw(win, "Key Pressed: %c", c);
248         else
249             wprintw(win, "Key Pressed: %s", unctrl(UChar(c)));
250 #ifdef KEY_MOUSE
251         if (c == KEY_MOUSE) {
252 #if defined(NCURSES_MOUSE_VERSION)
253 #define ButtonChanged(n) ((event.bstate) & NCURSES_MOUSE_MASK(1, 037))
254 #define ButtonPressed(n) ((event.bstate) & NCURSES_MOUSE_MASK(1, NCURSES_BUTTON_PRESSED))
255 #define ButtonDouble(n)  ((event.bstate) & NCURSES_MOUSE_MASK(1, NCURSES_DOUBLE_CLICKED))
256 #define ButtonTriple(n)  ((event.bstate) & NCURSES_MOUSE_MASK(1, NCURSES_TRIPLE_CLICKED))
257 #define ButtonRelease(n) ((event.bstate) & NCURSES_MOUSE_MASK(1, NCURSES_BUTTON_RELEASED))
258             MEVENT event;
259             int button = 0;
260
261             getmouse(&event);
262             if (ButtonChanged(1))
263                 button = 1;
264             else if (ButtonChanged(2))
265                 button = 2;
266             else if (ButtonChanged(3))
267                 button = 3;
268             else
269                 button = 0;
270             wmove(win, 4, 18);
271             wprintw(win, "Button %d: ", button);
272             if (ButtonPressed(button))
273                 wprintw(win, "pressed: ");
274             else if (ButtonDouble(button))
275                 wprintw(win, "double: ");
276             else if (ButtonTriple(button))
277                 wprintw(win, "triple: ");
278             else
279                 wprintw(win, "released: ");
280             wprintw(win, " Position: Y: %d X: %d", event.y, event.x);
281 #elif defined(PDCURSES)
282             int button = 0;
283             request_mouse_pos();
284             if (BUTTON_CHANGED(1))
285                 button = 1;
286             else if (BUTTON_CHANGED(2))
287                 button = 2;
288             else if (BUTTON_CHANGED(3))
289                 button = 3;
290             else
291                 button = 0;
292             wmove(win, 4, 18);
293             wprintw(win, "Button %d: ", button);
294             if (MOUSE_MOVED)
295                 wprintw(win, "moved: ");
296             else if ((BUTTON_STATUS(button) & BUTTON_ACTION_MASK) == BUTTON_PRESSED)
297                 wprintw(win, "pressed: ");
298             else if ((BUTTON_STATUS(button) & BUTTON_ACTION_MASK) == BUTTON_DOUBLE_CLICKED)
299                 wprintw(win, "double: ");
300             else
301                 wprintw(win, "released: ");
302             wprintw(win, " Position: Y: %d X: %d", MOUSE_Y_POS, MOUSE_X_POS);
303 #endif /* NCURSES_VERSION vs PDCURSES */
304         }
305 #endif /* KEY_MOUSE */
306         wrefresh(win);
307         if (c == ' ')
308             break;
309     }
310 #if 0
311     nodelay(win, TRUE);
312     wgetch(win);
313     nodelay(win, FALSE);
314 #endif
315 #if defined(PDCURSES)
316     mouse_set(0L);
317 #endif
318     refresh();
319
320     repeat = 0;
321     do {
322         static const char *fmt[] =
323         {
324             "%d %10s",
325             "%d %[a-zA-Z]s",
326             "%d %[][a-zA-Z]s",
327             "%d %[^0-9]"
328         };
329         char *format = strdup(fmt[(unsigned) repeat % SIZEOF(fmt)]);
330
331         wclear(win);
332         MvWAddStr(win, 3, 2, "The window should have moved");
333         MvWAddStr(win, 4, 2,
334                   "This text should have appeared without you pressing a key");
335         MvWPrintw(win, 6, 2,
336                   "Scanning with format \"%s\"", format);
337         mvwin(win, 2 + 2 * (repeat % 4), 1 + 2 * (repeat % 4));
338         erase();
339         refresh();
340         wrefresh(win);
341         echo();
342         noraw();
343         num = 0;
344         *buffer = 0;
345         answered = mvwscanw(win, 7, 6, format, &num, buffer);
346         MvWPrintw(win, 8, 6,
347                   "String: %s Number: %d (%d values read)",
348                   buffer, num, answered);
349         Continue(win);
350         ++repeat;
351         free(format);
352     } while (answered > 0);
353 }
354
355 static void
356 outputTest(WINDOW *win)
357 {
358     WINDOW *win1;
359     char Buffer[80];
360     chtype ch;
361     int by, bx;
362
363 #if !HAVE_TIGETSTR
364 #if HAVE_TGETENT
365     char tc_buffer[4096];
366     char tc_parsed[4096];
367     char *area_pointer = tc_parsed;
368     tgetent(tc_buffer, getenv("TERM"));
369 #else
370 #define tgetstr(a,b) 0
371 #endif
372 #endif /* !HAVE_TIGETSTR */
373
374     nl();
375     wclear(win);
376     MvWAddStr(win, 1, 1,
377               "You should now have a screen in the upper left corner, and this text should have wrapped");
378     mvwin(win, 2, 1);
379     waddstr(win, "\nThis text should be down\n");
380     waddstr(win, "and broken into two here ^");
381     Continue(win);
382
383     wclear(win);
384     wattron(win, A_BOLD);
385     MvWAddStr(win, 1, 1, "A new window will appear with this text in it");
386     MvWAddStr(win, 8, 1, "Press any key to continue");
387     wrefresh(win);
388     wgetch(win);
389
390     getbegyx(win, by, bx);
391
392     if (LINES < 24 || COLS < 75) {
393         MvWAddStr(win, 5, 1,
394                   "Some tests have been skipped as they require a");
395         MvWAddStr(win, 6, 1, "display of at least 24 LINES by 75 COLUMNS");
396         Continue(win);
397     } else {
398         win1 = newwin(10, 50, 14, 25);
399         if (win1 == NULL) {
400             endwin();
401             return;
402         }
403 #ifdef A_COLOR
404         if (has_colors()) {
405             init_pair(3, COLOR_BLUE, COLOR_WHITE);
406             wbkgd(win1, (chtype) COLOR_PAIR(3));
407         } else
408             wbkgd(win1, A_NORMAL);
409 #else
410         wbkgd(win1, A_NORMAL);
411 #endif
412         wclear(win1);
413         MvWAddStr(win1, 5, 1,
414                   "This text should appear; using overlay option");
415         copywin(win, win1, 0, 0, 0, 0, 9, 49, TRUE);
416
417 #if defined(PDCURSES) && !defined(XCURSES)
418         box(win1, 0xb3, 0xc4);
419 #else
420         box(win1, ACS_VLINE, ACS_HLINE);
421 #endif
422         wmove(win1, 8, 26);
423         wrefresh(win1);
424         wgetch(win1);
425
426         wclear(win1);
427         wattron(win1, A_BLINK);
428         MvWAddStr(win1, 4, 1,
429                   "This blinking text should appear in only the second window");
430         wattroff(win1, A_BLINK);
431         mvwin(win1, by, bx);
432         overlay(win, win1);
433         mvwin(win1, 14, 25);
434         wmove(win1, 8, 26);
435         wrefresh(win1);
436         wgetch(win1);
437         delwin(win1);
438     }
439
440     clear();
441     wclear(win);
442     wrefresh(win);
443     MvWAddStr(win, 6, 2, "This line shouldn't appear");
444     MvWAddStr(win, 4, 2, "Only half of the next line is visible");
445     MvWAddStr(win, 5, 2, "Only half of the next line is visible");
446     wmove(win, 6, 1);
447     wclrtobot(win);
448     wmove(win, 5, 20);
449     wclrtoeol(win);
450     MvWAddStr(win, 8, 2, "This line also shouldn't appear");
451     wmove(win, 8, 1);
452     wdeleteln(win);
453     Continue(win);
454
455     wmove(win, 5, 9);
456     ch = winch(win);
457
458     wclear(win);
459     wmove(win, 6, 2);
460     waddstr(win, "The next char should be l:  ");
461     winsch(win, ch);
462     Continue(win);
463
464 #if HAVE_WINSSTR
465     (void) mvwinsstr(win, 6, 2, "A1B2C3D4E5");
466     Continue(win);
467 #endif
468
469     wmove(win, 5, 1);
470     winsertln(win);
471     MvWAddStr(win, 5, 2, "The lines below should have moved down");
472     Continue(win);
473
474     wclear(win);
475     wmove(win, 2, 2);
476     wprintw(win, "This is a formatted string in a window: %d %s\n", 42,
477             "is it");
478     MvWAddStr(win, 10, 1, "Enter a string: ");
479     wrefresh(win);
480     noraw();
481     echo();
482     *Buffer = 0;
483     wscanw(win, "%s", Buffer);
484
485     printw("This is a formatted string in stdscr: %d %s\n", 42, "is it");
486     MvAddStr(10, 1, "Enter a string: ");
487     *Buffer = 0;
488     scanw("%s", Buffer);
489
490     if (TIGETSTR("cvvis", "vs") != 0) {
491         wclear(win);
492         curs_set(2);
493         MvWAddStr(win, 1, 1, "The cursor should appear as a block (visible)");
494         Continue(win);
495     }
496
497     if (TIGETSTR("civis", "vi") != 0) {
498         wclear(win);
499         curs_set(0);
500         MvWAddStr(win, 1, 1,
501                   "The cursor should have disappeared (invisible)");
502         Continue(win);
503     }
504
505     if (TIGETSTR("cnorm", "ve") != 0) {
506         wclear(win);
507         curs_set(1);
508         MvWAddStr(win, 1, 1, "The cursor should be an underline (normal)");
509         Continue(win);
510     }
511 #ifdef A_COLOR
512     if (has_colors()) {
513         wclear(win);
514         MvWAddStr(win, 1, 1, "Colors should change after you press a key");
515         Continue(win);
516         init_pair(1, COLOR_RED, COLOR_WHITE);
517         wrefresh(win);
518     }
519 #endif
520
521     werase(win);
522
523 #if HAVE_TERMNAME
524     MvWAddStr(win, 1, 1, "Information About Your Terminal");
525     MvWAddStr(win, 3, 1, termname());
526     MvWAddStr(win, 4, 1, longname());
527     if (termattrs() & A_BLINK)
528         MvWAddStr(win, 5, 1, "This terminal supports blinking.");
529     else
530         MvWAddStr(win, 5, 1, "This terminal does NOT support blinking.");
531 #endif
532
533     (void) mvwaddnstr(win, 7, 5, "Have a nice day!ok", 16);
534     wrefresh(win);
535
536     (void) mvwinnstr(win, 7, 5, Buffer, 18);
537     MvAddStr(LINES - 2, 10, Buffer);
538     refresh();
539     Continue(win);
540 }
541
542 #if defined(PDCURSES) && !defined(XCURSES)
543 static void
544 resizeTest(WINDOW *dummy GCC_UNUSED)
545 {
546     WINDOW *win1;
547
548     savetty();
549
550     clear();
551     refresh();
552 #  if defined(OS2)
553     resize_term(50, 120);
554 #  else
555     resize_term(50, 80);
556 #  endif
557
558     win1 = newwin(10, 50, 14, 25);
559     if (win1 == NULL) {
560         exit_curses();
561         return;
562     }
563 #ifdef A_COLOR
564     if (has_colors()) {
565         init_pair(3, COLOR_BLUE, COLOR_WHITE);
566         wattrset(win1, COLOR_PAIR(3));
567     }
568 #endif
569     wclear(win1);
570
571     MvWAddStr(win1, 1, 1, "The screen may now have 50 lines");
572     Continue(win1);
573
574     wclear(win1);
575     resetty();
576
577     MvWAddStr(win1, 1, 1, "The screen should now be reset");
578     Continue(win1);
579
580     delwin(win1);
581
582     clear();
583     refresh();
584
585 }
586 #endif
587
588 #if HAVE_NEWPAD
589 static void
590 padTest(WINDOW *dummy GCC_UNUSED)
591 {
592     WINDOW *pad, *spad;
593
594     if ((pad = newpad(50, 100)) != 0) {
595         wattron(pad, A_REVERSE);
596         MvWAddStr(pad, 5, 2, "This is a new pad");
597         (void) wattrset(pad, A_NORMAL);
598         MvWAddStr(pad, 8, 0,
599                   "The end of this line should be truncated here:except  now");
600         MvWAddStr(pad, 11, 1, "This line should not appear.It will now");
601         wmove(pad, 10, 1);
602         wclrtoeol(pad);
603         MvWAddStr(pad, 10, 1, " Press any key to continue");
604         prefresh(pad, 0, 0, 0, 0, 10, 45);
605         keypad(pad, TRUE);
606         raw();
607         wgetch(pad);
608
609         if ((spad = subpad(pad, 12, 25, 6, 52)) != 0) {
610             MvWAddStr(spad, 2, 2, "This is a new subpad");
611             box(spad, 0, 0);
612             delwin(spad);
613         }
614         prefresh(pad, 0, 0, 0, 0, 15, 75);
615         keypad(pad, TRUE);
616         raw();
617         wgetch(pad);
618
619         MvWAddStr(pad, 35, 2, "This is displayed at line 35 in the pad");
620         MvWAddStr(pad, 40, 1, " Press any key to continue");
621         prefresh(pad, 30, 0, 0, 0, 10, 45);
622         keypad(pad, TRUE);
623         raw();
624         wgetch(pad);
625
626         delwin(pad);
627     }
628 }
629 #endif /* HAVE_NEWPAD */
630
631 struct commands {
632     NCURSES_CONST char *text;
633     void (*function) (WINDOW *);
634 };
635 typedef struct commands COMMAND;
636
637 static const COMMAND command[] =
638 {
639     {"General Test", introTest},
640 #if HAVE_NEWPAD
641     {"Pad Test", padTest},
642 #endif
643 #if defined(PDCURSES) && !defined(XCURSES)
644     {"Resize Test", resizeTest},
645 #endif
646     {"Scroll Test", scrollTest},
647     {"Input Test", inputTest},
648     {"Output Test", outputTest}
649 };
650 #define MAX_OPTIONS (int) SIZEOF(command)
651
652 static void
653 display_menu(int old_option, int new_option)
654 {
655     int i;
656
657     assert((new_option >= 0) && (new_option < MAX_OPTIONS));
658
659     (void) attrset(A_NORMAL);
660     MvAddStr(3, 20, "PDCurses Test Program");
661
662     for (i = 0; i < (int) MAX_OPTIONS; i++)
663         MvAddStr(5 + i, 25, command[i].text);
664
665     if ((old_option >= 0) && (old_option < MAX_OPTIONS))
666         MvAddStr(5 + old_option, 25, command[old_option].text);
667
668     (void) attrset(A_REVERSE);
669     MvAddStr(5 + new_option, 25, command[new_option].text);
670     (void) attrset(A_NORMAL);
671     MvAddStr(13, 3,
672              "Use Up and Down Arrows to select - Enter to run - Q to quit");
673     refresh();
674 }
675
676 int
677 main(
678         int argc GCC_UNUSED,
679         char *argv[]GCC_UNUSED)
680 {
681     WINDOW *win;
682     int key;
683     int old_option = (-1);
684     int new_option = 0;
685     bool quit = FALSE;
686     int n;
687
688     setlocale(LC_ALL, "");
689
690 #ifdef PDCDEBUG
691     PDC_debug("testcurs started\n");
692 #endif
693     if (!initTest(&win))
694         ExitProgram(EXIT_FAILURE);
695
696     erase();
697     display_menu(old_option, new_option);
698     for (;;) {
699 #ifdef A_COLOR
700         if (has_colors()) {
701             init_pair(1, COLOR_WHITE, COLOR_BLUE);
702             wbkgd(win, (chtype) COLOR_PAIR(1));
703         } else
704             wbkgd(win, A_REVERSE);
705 #else
706         wbkgd(win, A_REVERSE);
707 #endif
708         werase(win);
709
710         noecho();
711         keypad(stdscr, TRUE);
712         raw();
713         key = getch();
714         if (key < KEY_MIN && key > 0 && isalpha(key)) {
715             if (islower(key))
716                 key = toupper(key);
717             for (n = 0; n < MAX_OPTIONS; ++n) {
718                 if (key == command[n].text[0]) {
719                     display_menu(old_option, new_option = n);
720                     key = ' ';
721                     break;
722                 }
723             }
724         }
725         switch (key) {
726         case 10:
727         case 13:
728         case KEY_ENTER:
729             erase();
730             refresh();
731             (*command[new_option].function) (win);
732             erase();
733             display_menu(old_option, new_option);
734             break;
735         case KEY_UP:
736             new_option = ((new_option == 0)
737                           ? new_option
738                           : new_option - 1);
739             display_menu(old_option, new_option);
740             break;
741         case KEY_DOWN:
742             new_option = ((new_option == (MAX_OPTIONS - 1))
743                           ? new_option
744                           : new_option + 1);
745             display_menu(old_option, new_option);
746             break;
747         case 'Q':
748         case 'q':
749             quit = TRUE;
750             break;
751         default:
752             beep();
753             break;
754         case ' ':
755             break;
756         }
757         if (quit == TRUE)
758             break;
759     }
760
761     delwin(win);
762
763     exit_curses();
764 #ifdef XCURSES
765     XCursesExit();
766 #endif
767     ExitProgram(EXIT_SUCCESS);
768 }