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