1 #include <errno.h>
2 #include <stdarg.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 
7 #include "errno.h"
8 #include "newt.h"
9 
newtvwindow(char * title,char * button1,char * button2,char * button3,char * message,va_list args)10 static void * newtvwindow(char * title, char * button1, char * button2,
11 		       char * button3, char * message, va_list args) {
12     newtComponent b1, b2 = NULL, b3 = NULL, t, f, answer;
13     char * buf = NULL;
14     int size = 0;
15     int i = 0;
16     int scroll = 0;
17     int width, height;
18     char * flowedText;
19     newtGrid grid, buttonGrid;
20 
21     do {
22 	va_list argscopy;
23 
24 	va_copy(argscopy, args);
25 	size += 1000;
26 	if (buf) free(buf);
27 	buf = malloc(size);
28 	i = vsnprintf(buf, size, message, argscopy);
29 	va_end(argscopy);
30     } while (i >= size || i == -1);
31 
32     flowedText = newtReflowText(buf, 35, 5, 5, &width, &height);
33     if (height > 6) {
34 	free(flowedText);
35 	flowedText = newtReflowText(buf, 60, 5, 5, &width, &height);
36     }
37     free(buf);
38 
39     if (height > 12) {
40 	height = 12;
41 	scroll = NEWT_FLAG_SCROLL;
42     }
43     t = newtTextbox(-1, -1, width, height, NEWT_TEXTBOX_WRAP | scroll);
44     newtTextboxSetText(t, flowedText);
45     free(flowedText);
46 
47     if (button3) {
48 	buttonGrid = newtButtonBar(button1, &b1, button2, &b2,
49 				   button3, &b3, NULL);
50     } else if (button2) {
51 	buttonGrid = newtButtonBar(button1, &b1, button2, &b2, NULL);
52     } else {
53 	buttonGrid = newtButtonBar(button1, &b1, NULL);
54     }
55 
56     newtGridSetField(buttonGrid, 0, 0, NEWT_GRID_COMPONENT, b1,
57 		     0, 0, button2 ? 1 : 0, 0, 0, 0);
58 
59     grid = newtCreateGrid(1, 2);
60     newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, t, 0, 0, 0, 0, 0, 0);
61     newtGridSetField(grid, 0, 1, NEWT_GRID_SUBGRID, buttonGrid,
62 		     0, 1, 0, 0, 0, NEWT_GRID_FLAG_GROWX);
63     newtGridWrappedWindow(grid, title);
64 
65     f = newtForm(NULL, NULL, 0);
66     newtFormAddComponents(f, t, b1, NULL);
67 
68     if (button2)
69 	newtFormAddComponent(f, b2);
70     if (button3)
71 	newtFormAddComponent(f, b3);
72 
73     answer = newtRunForm(f);
74     newtGridFree(grid, 1);
75 
76     newtFormDestroy(f);
77     newtPopWindow();
78 
79     if (answer == f)
80 	return NULL;
81     else if (answer == b1)
82 	return button1;
83     else if (answer == b2)
84 	return button2;
85 
86     return button3;
87 }
88 
newtWinChoice(char * title,char * button1,char * button2,char * message,...)89 int newtWinChoice(char * title, char * button1, char * button2,
90 		   char * message, ...) {
91     va_list args;
92     void * rc;
93 
94     va_start(args, message);
95     rc = newtvwindow(title, button1, button2, NULL, message, args);
96     va_end(args);
97 
98     if (rc == button1)
99 	return 1;
100     else if (rc == button2)
101 	return 2;
102 
103     return 0;
104 }
105 
newtWinMessage(char * title,char * buttonText,char * text,...)106 void newtWinMessage(char * title, char * buttonText, char * text, ...) {
107     va_list args;
108 
109     va_start(args, text);
110     newtvwindow(title, buttonText, NULL, NULL, text, args);
111     va_end(args);
112 }
113 
newtWinMessagev(char * title,char * buttonText,char * text,va_list argv)114 void newtWinMessagev(char * title, char * buttonText, char * text,
115 		     va_list argv) {
116     newtvwindow(title, buttonText, NULL, NULL, text, argv);
117 }
118 
newtWinTernary(char * title,char * button1,char * button2,char * button3,char * message,...)119 int newtWinTernary(char * title, char * button1, char * button2,
120 		   char * button3, char * message, ...) {
121     va_list args;
122     void * rc;
123 
124     va_start(args, message);
125     rc = newtvwindow(title, button1, button2, button3, message, args);
126     va_end(args);
127 
128     if (rc == button1)
129 	return 1;
130     else if (rc == button2)
131 	return 2;
132     else if (rc == button3)
133 	return 3;
134 
135     return 0;
136 }
137 
newtWinMenu(char * title,char * text,int suggestedWidth,int flexDown,int flexUp,int maxListHeight,char ** items,int * listItem,char * button1,...)138 int newtWinMenu(char * title, char * text, int suggestedWidth, int flexDown,
139 		int flexUp, int maxListHeight, char ** items, int * listItem,
140 		char * button1, ...) {
141     newtComponent textbox, listbox, result, form;
142     va_list args;
143     newtComponent *buttons = NULL;
144     newtGrid grid, buttonBar;
145     size_t totalButtons = 0, numButtons = 0;
146     int i, rc;
147     int needScroll;
148     char * buttonName;
149 
150     textbox = newtTextboxReflowed(-1, -1, text, suggestedWidth, flexDown,
151 			          flexUp, 0);
152 
153     for (i = 0; items[i]; i++) ;
154     if (i < maxListHeight) maxListHeight = i;
155     needScroll = i > maxListHeight;
156 
157     listbox = newtListbox(-1, -1, maxListHeight,
158 		  (needScroll ? NEWT_FLAG_SCROLL : 0) | NEWT_FLAG_RETURNEXIT);
159     for (i = 0; items[i]; i++) {
160 	newtListboxAddEntry(listbox, items[i], (void *)(long) i);
161     }
162 
163     newtListboxSetCurrent(listbox, *listItem);
164 
165     va_start(args, button1);
166     for (buttonName = button1; buttonName; buttonName = va_arg(args, char *))
167        ++totalButtons;
168     va_end(args);
169 
170     buttons = (newtComponent *)alloca(sizeof(newtComponent)*(totalButtons));
171     va_start(args, button1);
172     for (buttonName = button1; buttonName; buttonName = va_arg(args, char *))
173        buttons[numButtons++] = newtButton(-1, -1, buttonName);
174     va_end(args);
175 
176     buttonBar = newtCreateGrid(numButtons ? numButtons : 1, 1);
177     for (i = 0; i < numButtons; i++) {
178 	newtGridSetField(buttonBar, i, 0, NEWT_GRID_COMPONENT,
179 			 buttons[i],
180 			 i ? 1 : 0, 0, 0, 0, 0, 0);
181     }
182 
183     grid = newtGridSimpleWindow(textbox, listbox, buttonBar);
184     newtGridWrappedWindow(grid, title);
185 
186     form = newtForm(NULL, 0, 0);
187     newtGridAddComponentsToForm(grid, form, 1);
188     newtGridFree(grid, 1);
189 
190     result = newtRunForm(form);
191 
192     *listItem = ((long) newtListboxGetCurrent(listbox));
193 
194     for (rc = 0; rc < numButtons && result != buttons[rc]; rc++)
195 	;
196     if (rc == numButtons)
197 	rc = 0; /* F12 or return-on-exit (which are the same for us) */
198     else
199 	rc++;
200 
201     newtFormDestroy(form);
202     newtPopWindow();
203 
204     return rc;
205 }
206 
newtWinEntries(char * title,char * text,int suggestedWidth,int flexDown,int flexUp,int dataWidth,struct newtWinEntry * items,char * button1,...)207 int newtWinEntries(char * title, char * text, int suggestedWidth, int flexDown,
208 		   int flexUp, int dataWidth,
209 		   struct newtWinEntry * items, char * button1, ...) {
210     newtComponent *buttons, result, form, textw;
211     newtGrid grid, buttonBar, subgrid;
212     int numItems;
213     int rc, i;
214     size_t numButtons = 0, totalButtons = 0;
215     char * buttonName;
216     va_list args;
217 
218     textw = newtTextboxReflowed(-1, -1, text, suggestedWidth, flexDown,
219 			        flexUp, 0);
220 
221     for (numItems = 0; items[numItems].text; numItems++);
222 
223     buttonName = button1;
224     va_start(args, button1);
225     for (buttonName = button1; buttonName; buttonName = va_arg(args, char *))
226        ++totalButtons;
227     va_end(args);
228 
229     buttons = (newtComponent *)alloca(sizeof(newtComponent)*(totalButtons));
230     va_start(args, button1);
231     for (buttonName = button1; buttonName; buttonName = va_arg(args, char *))
232        buttons[numButtons++] = newtButton(-1, -1, buttonName);
233     va_end(args);
234 
235     buttonBar = newtCreateGrid(numButtons ? numButtons : 1, 1);
236     for (i = 0; i < numButtons; i++) {
237 	newtGridSetField(buttonBar, i, 0, NEWT_GRID_COMPONENT,
238 			 buttons[i],
239 			 i ? 1 : 0, 0, 0, 0, 0, 0);
240     }
241 
242     subgrid = newtCreateGrid(2, numItems ? numItems : 1);
243     for (i = 0; i < numItems; i++) {
244 	newtGridSetField(subgrid, 0, i, NEWT_GRID_COMPONENT,
245 		         newtLabel(-1, -1, items[i].text),
246 		         0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
247 	newtGridSetField(subgrid, 1, i, NEWT_GRID_COMPONENT,
248 		         newtEntry(-1, -1, items[i].value ?
249 				    *items[i].value : NULL, dataWidth,
250 				    (const char **)items[i].value, items[i].flags),
251 		         1, 0, 0, 0, 0, 0);
252     }
253 
254     grid = newtCreateGrid(1, 3);
255     form = newtForm(NULL, 0, 0);
256     newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, textw,
257 		     0, 0, 0, 0, NEWT_ANCHOR_LEFT, 0);
258     newtGridSetField(grid, 0, 1, NEWT_GRID_SUBGRID, subgrid,
259 		     0, 1, 0, 0, 0, 0);
260     newtGridSetField(grid, 0, 2, NEWT_GRID_SUBGRID, buttonBar,
261 		     0, 1, 0, 0, 0, NEWT_GRID_FLAG_GROWX);
262     newtGridAddComponentsToForm(grid, form, 1);
263     newtGridWrappedWindow(grid, title);
264     newtGridFree(grid, 1);
265 
266     result = newtRunForm(form);
267 
268     for (rc = 0; rc < numItems; rc++)
269 	*items[rc].value = strdup(*items[rc].value);
270 
271     for (rc = 0; rc < numButtons && result != buttons[rc]; rc++)
272 	;
273     if (rc == numButtons)
274 	rc = 0; /* F12 */
275     else
276 	rc++;
277 
278     newtFormDestroy(form);
279     newtPopWindow();
280 
281     return rc;
282 }
283