ncurses 6.1 - patch 20180303
[ncurses.git] / test / popup_msg.c
1 /****************************************************************************
2  * Copyright (c) 2017 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.8 2017/09/03 21:05:01 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         return;
91
92     begin_popup();
93
94     keypad(data, TRUE);
95
96     for (n = 0; n < length; ++n) {
97         waddstr(data, msg[n]);
98         if ((n + 1) < length) {
99             waddch(data, '\n');
100         }
101     }
102     y2 = getcury(data);
103     last_y = (y2 - (high - 3));
104
105     do {
106         switch (ch) {
107         case KEY_HOME:
108             y1 = 0;
109             break;
110         case KEY_END:
111             y1 = last_y;
112             break;
113         case KEY_PREVIOUS:
114         case KEY_PPAGE:
115             if (y1 > 0) {
116                 y1 -= high / 2;
117                 if (y1 < 0)
118                     y1 = 0;
119             } else {
120                 beep();
121             }
122             break;
123         case KEY_NEXT:
124         case KEY_NPAGE:
125             if (y1 < last_y) {
126                 y1 += high / 2;
127                 if (y1 > last_y)
128                     y1 = last_y;
129             } else {
130                 beep();
131             }
132             break;
133         case CTRL('P'):
134         case KEY_UP:
135             if (y1 > 0)
136                 --y1;
137             else
138                 beep();
139             break;
140         case CTRL('N'):
141         case KEY_DOWN:
142             if (y1 < last_y)
143                 ++y1;
144             else
145                 beep();
146             break;
147         default:
148             beep();
149             break;
150         case ERR:
151             break;
152         }
153         werase(help);
154         box(help, 0, 0);
155         wnoutrefresh(help);
156         pnoutrefresh(data, y1, 0, y0 + 1, x0 + 1, high, wide);
157         doupdate();
158     } while ((ch = wgetch(data)) != ERR && ch != QUIT && ch != ESCAPE);
159     werase(help);
160     wrefresh(help);
161     delwin(help);
162     delwin(data);
163
164     end_popup();
165 }
166
167 void
168 popup_msg2(WINDOW *parent, char **msg)
169 {
170     popup_msg(parent, (const char *const *) msg);
171 }
172
173 #else
174 void
175 popup_msg(WINDOW *parent, const char *const *msg)
176 {
177     (void) parent;
178     (void) msg;
179     beep();
180 }
181 #endif