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 "libdfui/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 "libaura/mem.h" 58 59 #include "libdfui/dfui.h" 60 #ifdef DEBUG 61 #include "libdfui/dump.h" 62 #endif 63 #include "libdfui/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 } 398