Installer import into contrib (real import this time)
[dragonfly.git] / contrib / bsdinstaller-1.1.6 / src / frontends / ncurses / main.c
1 /*
2  * Copyright (c)2004 Cat's Eye Technologies.  All rights reserved.
3  * 
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 
8  *   Redistributions of source code must retain the above copyright
9  *   notice, this list of conditions and the following disclaimer.
10  * 
11  *   Redistributions in binary form must reproduce the above copyright
12  *   notice, this list of conditions and the following disclaimer in
13  *   the documentation and/or other materials provided with the
14  *   distribution.
15  * 
16  *   Neither the name of Cat's Eye Technologies nor the names of its
17  *   contributors may be used to endorse or promote products derived
18  *   from this software without specific prior written permission. 
19  * 
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31  * OF THE POSSIBILITY OF SUCH DAMAGE. 
32  */
33
34 /*
35  * main.c
36  * Main program for dfuife_curses.
37  * $Id: main.c,v 1.21 2005/03/25 04:51:10 cpressey Exp $
38  */
39
40 #include <ctype.h>
41 #include <ncurses.h>
42 #include <signal.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <term.h>
46 #include <unistd.h>
47
48 #ifdef ENABLE_NLS
49 #include <libintl.h>
50 #include "dfui/lang.h"
51 #define _(String) gettext (String)
52 extern int _nl_msg_cat_cntr;
53 #else
54 #define _(String) (String)
55 #endif
56
57 #include "aura/mem.h"
58
59 #include "dfui/dfui.h"
60 #ifdef DEBUG
61 #include "dfui/dump.h"
62 #endif
63 #include "dfui/system.h"
64
65 #include "curses_form.h"
66 #include "curses_widget.h"
67 #include "curses_bar.h"
68 #include "curses_util.h"
69 #include "curses_xlat.h"
70
71 /*** GLOBALS ***/
72
73 struct curses_bar *menubar, *statusbar;
74
75 /*** SIGNAL HANDLING ***/
76
77 #ifdef SIGNAL_HANDLING
78 volatile sig_atomic_t caught_signal;
79
80 void signal_handler(int signo)
81 {
82         caught_signal = signo;
83 }
84
85 void
86 abort_frontend(struct dfui_connection *c)
87 {
88         dfui_fe_abort(c);
89
90         clear();
91         refresh();
92         endwin();
93         exit(1);
94 }
95 #endif
96
97 static struct dfui_response *
98 #ifdef SIGNAL_HANDLING
99 present_form(struct dfui_connection *c, struct dfui_form *f)
100 #else
101 present_form(struct dfui_connection *c __unused, struct dfui_form *f)
102 #endif
103 {
104         struct dfui_response *r = NULL;
105         struct curses_form *cf;
106         struct curses_widget *cw;
107
108         cf = curses_form_construct_from_dfui_form(f);
109         curses_form_draw(cf);
110         curses_form_refresh(cf);
111         cw = curses_form_frob(cf);
112 #ifdef SIGNAL_HANDLING
113         if (caught_signal) abort_frontend(c);
114 #endif
115         r = response_construct_from_curses_form(f, cf, cw);
116         curses_form_free(cf);
117         curses_form_refresh(NULL);
118         return(r);
119 }
120
121 static void
122 usage(char **argv)
123 {
124         fprintf(stderr, _("Usage: %s "
125             "[-b backdrop] [-r rendezvous] [-t caps|npipe|tcp]\n"),
126             argv[0]);
127         exit(1);
128 }
129
130 /*
131  * dfuife_curses
132  * DFUI Curses frontend.
133  */
134 int
135 main(int argc, char **argv)
136 {
137         struct dfui_connection *c;
138         struct dfui_form *f;
139         struct dfui_response *r;
140         struct dfui_progress *pr;
141         struct dfui_property *gp;
142
143         struct curses_form *pf = NULL;
144         struct curses_widget *pbar = NULL, *plab = NULL, *pcan = NULL;
145         struct curses_widget *w;
146
147         void *payload;
148         int done = 0;
149         char msgtype;
150         int opt;
151         int last_amount = 0;
152         char last_message[80];
153         int is_streaming = 0;
154         int ch;
155         char *bdropfn = NULL;
156         char *rendezvous = NULL;
157         int transport = 0;
158         int force_monochrome = 0;
159
160         /*
161          * Get command-line arguments.
162          */
163         while ((opt = getopt(argc, argv, "b:mr:t:")) != -1) {
164                 switch(opt) {
165                 case 'b':
166                         bdropfn = aura_strdup(optarg);
167                         break;
168                 case 'm':
169                         force_monochrome = 1;
170                         break;
171                 case 'r':
172                         rendezvous = aura_strdup(optarg);
173                         break;
174                 case 't':
175                         transport = user_get_transport(optarg);
176                         break;
177                 case '?':
178                 default:
179                         usage(argv);
180                 }
181         }
182         argc -= optind;
183         argv += optind;
184
185         if (!transport)
186                 transport = user_get_transport("tcp");
187
188         if (rendezvous == NULL) {
189                 if (transport == DFUI_TRANSPORT_TCP) {
190                         rendezvous = aura_strdup("9999");
191                 } else {
192                         rendezvous = aura_strdup("test");
193                 }
194         }
195
196 #ifdef ENABLE_NLS
197         setlocale (LC_ALL, "");
198         bindtextdomain (PACKAGE, LOCALEDIR);
199         textdomain (PACKAGE);
200 #endif
201
202         /*
203          * Set up screen.
204          */
205
206         initscr();
207
208 #ifdef SIGNAL_HANDLING
209         signal(SIGINT, signal_handler);
210         signal(SIGTERM, signal_handler);
211 #endif
212
213         curses_colors_init(force_monochrome);
214         cbreak();
215         noecho();
216         nonl();
217         keypad(stdscr, TRUE);
218         curs_set(0);
219
220         getmaxyx(stdscr, ymax, xmax);
221
222         if (bdropfn == NULL) {
223                 curses_colors_set(stdscr, CURSES_COLORS_BACKDROP);
224                 curses_window_blank(stdscr);
225         } else {
226                 curses_load_backdrop(stdscr, bdropfn);
227         }
228
229         menubar = curses_bar_new(0, 0, 0, 1, CURSES_COLORS_MENUBAR,
230                                  CURSES_BAR_WIDEN);
231         statusbar = curses_bar_new(0, 0, 0, 1, CURSES_COLORS_STATUSBAR,
232                                    CURSES_BAR_WIDEN | CURSES_BAR_BOTTOM);
233
234         curses_bar_set_text(menubar, _("F10=Refresh Display"));
235         curses_bar_set_text(statusbar, _("Waiting for backend..."));
236
237         update_panels();
238         doupdate();
239
240 #ifdef DEBUG
241         dfui_debug_file = fopen("/tmp/dfuife_curses_debug.log", "w");
242 #endif
243
244         c = dfui_connection_new(transport, rendezvous);
245         dfui_fe_connect(c);
246
247         curses_bar_set_text(statusbar, _("Connected"));
248
249         while (!done) {
250                 dfui_fe_receive(c, &msgtype, &payload);
251                 switch (msgtype) {
252                 case DFUI_BE_MSG_PRESENT:
253                         f = (struct dfui_form *)payload;
254                         r = present_form(c, f);
255 #ifdef SIGNAL_HANDLING
256                         if (caught_signal) abort_frontend(c);
257 #endif
258                         dfui_fe_submit(c, r);
259                         dfui_form_free(f);
260                         dfui_response_free(r);
261                         break;
262                 case DFUI_BE_MSG_PROG_BEGIN:
263                         pr = (struct dfui_progress *)payload;
264                         if (pf != NULL)
265                                 curses_form_free(pf);
266                         is_streaming = dfui_progress_get_streaming(pr);
267                         last_amount = dfui_progress_get_amount(pr);
268                         strncpy(last_message, dfui_info_get_short_desc(
269                             dfui_progress_get_info(pr)), 79);
270                         pf = curses_form_construct_from_dfui_progress(pr,
271                             &pbar, &plab, &pcan);
272                         curses_form_draw(pf);
273                         curses_form_refresh(pf);
274                         dfui_progress_free(pr);
275                         nodelay(stdscr, TRUE);
276                         dfui_fe_progress_continue(c);
277                         break;
278                 case DFUI_BE_MSG_PROG_UPDATE:
279                         pr = (struct dfui_progress *)payload;
280                         if (pf != NULL) {
281                                 curses_widgets_update_from_dfui_progress(pr,
282                                     pbar, plab, pcan);
283                         }
284                         dfui_progress_free(pr);
285                         ch = getch();
286                         if (ch == ' ' || ch == '\n' || ch == '\r') {
287                                 dfui_fe_progress_cancel(c);
288                         } else if (ch == KEY_F(10)) {
289                                 redrawwin(stdscr);
290                                 curses_form_refresh(NULL);
291                                 dfui_fe_progress_continue(c);
292                         } else {
293                                 dfui_fe_progress_continue(c);
294                         }
295                         break;
296                 case DFUI_BE_MSG_PROG_END:
297                         if (pf != NULL) {
298                                 if (is_streaming) {
299                                         w = curses_form_widget_add(pf, 0, pf->int_height, 0,
300                                             CURSES_BUTTON, "OK", -1,
301                                             CURSES_WIDGET_CENTER | CURSES_WIDGET_WIDEN);
302                                         pf->int_height++;
303                                         curses_widget_set_click_cb(w, cb_click_close_form);
304                                         pf->widget_focus = w;
305                                         curses_form_widget_ensure_visible(w);
306                                         curses_widget_draw(w);
307                                         curses_form_refresh(pf);
308                                         curses_form_frob(pf);
309                                 }
310                                 curses_form_free(pf);
311                                 curses_form_refresh(NULL);
312                         }
313                         pf = NULL;
314                         plab = pbar = pcan = NULL;
315                         nodelay(stdscr, FALSE);
316                         dfui_fe_progress_continue(c);
317                         break;
318                 case DFUI_BE_MSG_SET_GLOBAL:
319                         gp = (struct dfui_property *)payload;
320
321 #ifdef ENABLE_NLS
322                         /*
323                          * Check for a change to the "lang" setting...
324                          */
325                         if (strcmp(dfui_property_get_name(gp), "lang") == 0) {
326                                 set_lang_envars(dfui_property_get_value(gp));
327
328                                 /* let gettext know about changes */
329                                 ++_nl_msg_cat_cntr;
330
331                                 /* BEGIN: reinit curses to use new TERM */
332                                 curses_bar_free(menubar);
333                                 curses_bar_free(statusbar);
334
335                                 endwin();
336                                 newterm(getenv("TERM"), stdout, stdin);
337
338                                 curses_colors_init(force_monochrome);
339                                 cbreak();
340                                 noecho();
341                                 nonl();
342                                 keypad(stdscr, TRUE);
343                                 curs_set(0);
344
345                                 update_panels();
346                                 doupdate();
347
348                                 if (bdropfn == NULL) {
349                                         curses_colors_set(stdscr,
350                                             CURSES_COLORS_BACKDROP);
351                                         curses_window_blank(stdscr);
352                                 } else {
353                                         curses_load_backdrop(stdscr, bdropfn);
354                                 }
355
356                                 menubar = curses_bar_new(0, 0, 0, 1,
357                                     CURSES_COLORS_MENUBAR, CURSES_BAR_WIDEN);
358                                 statusbar = curses_bar_new(0, 0, 0, 1,
359                                     CURSES_COLORS_STATUSBAR,
360                                     CURSES_BAR_WIDEN | CURSES_BAR_BOTTOM);
361                                 /* END: reinit curses to use new TERM */
362
363                                 curses_bar_set_text(menubar,
364                                         _("F1=Help F10=Refresh Display"));
365                         }
366 #endif
367
368                         dfui_fe_confirm_set_global(c);
369                         dfui_property_free(gp);
370                         break;
371                 case DFUI_BE_MSG_STOP:
372                         dfui_fe_confirm_stop(c);
373                         done = 1;
374                         break;
375                 }
376         }
377
378         dfui_fe_disconnect(c);
379
380 #ifdef DEBUG
381         fclose(dfui_debug_file);
382 #endif
383
384         curses_bar_free(menubar);
385         curses_bar_free(statusbar);
386
387         clear();
388         refresh();
389         endwin();
390
391         if (rendezvous != NULL)
392                 free(rendezvous);
393         if (bdropfn != NULL)
394                 free(bdropfn);
395
396         exit(0);
397 }