ncurses 6.1 - patch 20191123
[ncurses.git] / test / popup_msg.c
1 /****************************************************************************
2  * Copyright (c) 2017,2018 Free Software Foundation, Inc.                   *
3  *                                                                          *
4  * Permission is hereby granted, free of charge, to any person obtaining a  *
5  * copy of this software and associated documentation files (the            *
6  * "Software"), to deal in the Software without restriction, including      *
7  * without limitation the rights to use, copy, modify, merge, publish,      *
8  * distribute, distribute with modifications, sublicense, and/or sell       *
9  * copies of the Software, and to permit persons to whom the Software is    *
10  * furnished to do so, subject to the following conditions:                 *
11  *                                                                          *
12  * The above copyright notice and this permission notice shall be included  *
13  * in all copies or substantial portions of the Software.                   *
14  *                                                                          *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
16  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
18  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
19  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
20  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
21  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
22  *                                                                          *
23  * Except as contained in this notice, the name(s) of the above copyright   *
24  * holders shall not be used in advertising or otherwise to promote the     *
25  * sale, use or other dealings in this Software without prior written       *
26  * authorization.                                                           *
27  ****************************************************************************/
28 /*
29  * $Id: popup_msg.c,v 1.9 2018/05/12 15:08:45 tom Exp $
30  *
31  * Show a multi-line message in a window which may extend beyond the screen.
32  *
33  * Thomas Dickey - 2017/4/15.
34  */
35
36 #include <test.priv.h>
37
38 #include <popup_msg.h>
39
40 #if HAVE_NEWPAD
41
42 static WINDOW *old_window;
43
44 static void
45 begin_popup(void)
46 {
47     doupdate();
48     old_window = dupwin(curscr);
49 }
50
51 static void
52 end_popup(void)
53 {
54     touchwin(old_window);
55     wnoutrefresh(old_window);
56     doupdate();
57     delwin(old_window);
58 }
59
60 /*
61  * Display a temporary window, e.g., to display a help-message.
62  */
63 void
64 popup_msg(WINDOW *parent, const char *const *msg)
65 {
66     int x0 = 4;
67     int y0 = 2;
68     int y1 = 0;
69     int y2 = 0;
70     int wide = getmaxx(parent) - ((x0 + 1) * 2);
71     int high = getmaxy(parent) - ((y0 + 1) * 2);
72     WINDOW *help;
73     WINDOW *data;
74     int n;
75     int width = 0;
76     int length;
77     int last_y;
78     int ch = ERR;
79
80     for (n = 0; msg[n] != 0; ++n) {
81         int check = (int) strlen(msg[n]);
82         if (width < check)
83             width = check;
84     }
85     length = n;
86
87     if ((help = newwin(high, wide, y0, x0)) == 0)
88         return;
89     if ((data = newpad(length + 1, width)) == 0) {
90         delwin(help);
91         return;
92     }
93
94     begin_popup();
95
96     keypad(data, TRUE);
97
98     for (n = 0; n < length; ++n) {
99         waddstr(data, msg[n]);
100         if ((n + 1) < length) {
101             waddch(data, '\n');
102         }
103     }
104     y2 = getcury(data);
105     last_y = (y2 - (high - 3));
106
107     do {
108         switch (ch) {
109         case KEY_HOME:
110             y1 = 0;
111             break;
112         case KEY_END:
113             y1 = last_y;
114             break;
115         case KEY_PREVIOUS:
116         case KEY_PPAGE:
117             if (y1 > 0) {
118                 y1 -= high / 2;
119                 if (y1 < 0)
120                     y1 = 0;
121             } else {
122                 beep();
123             }
124             break;
125         case KEY_NEXT:
126         case KEY_NPAGE:
127             if (y1 < last_y) {
128                 y1 += high / 2;
129                 if (y1 > last_y)
130                     y1 = last_y;
131             } else {
132                 beep();
133             }
134             break;
135         case CTRL('P'):
136         case KEY_UP:
137             if (y1 > 0)
138                 --y1;
139             else
140                 beep();
141             break;
142         case CTRL('N'):
143         case KEY_DOWN:
144             if (y1 < last_y)
145                 ++y1;
146             else
147                 beep();
148             break;
149         default:
150             beep();
151             break;
152         case ERR:
153             break;
154         }
155         werase(help);
156         box(help, 0, 0);
157         wnoutrefresh(help);
158         pnoutrefresh(data, y1, 0, y0 + 1, x0 + 1, high, wide);
159         doupdate();
160     } while ((ch = wgetch(data)) != ERR && ch != QUIT && ch != ESCAPE);
161     werase(help);
162     wrefresh(help);
163     delwin(help);
164     delwin(data);
165
166     end_popup();
167 }
168
169 void
170 popup_msg2(WINDOW *parent, char **msg)
171 {
172     popup_msg(parent, (const char *const *) msg);
173 }
174
175 #else
176 void
177 popup_msg(WINDOW *parent, const char *const *msg)
178 {
179     (void) parent;
180     (void) msg;
181     beep();
182 }
183 #endif