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 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 = NULL; 148 int done = 0; 149 char msgtype; 150 int opt; 151 char last_message[80]; 152 int is_streaming = 0; 153 int ch; 154 char *bdropfn = NULL; 155 char *rendezvous = NULL; 156 int transport = 0; 157 int force_monochrome = 0; 158 159 /* 160 * Get command-line arguments. 161 */ 162 while ((opt = getopt(argc, argv, "b:mr:t:")) != -1) { 163 switch(opt) { 164 case 'b': 165 bdropfn = aura_strdup(optarg); 166 break; 167 case 'm': 168 force_monochrome = 1; 169 break; 170 case 'r': 171 rendezvous = aura_strdup(optarg); 172 break; 173 case 't': 174 transport = user_get_transport(optarg); 175 break; 176 case '?': 177 default: 178 usage(argv); 179 } 180 } 181 argc -= optind; 182 argv += optind; 183 184 if (!transport) 185 transport = user_get_transport("tcp"); 186 187 if (rendezvous == NULL) { 188 if (transport == DFUI_TRANSPORT_TCP) { 189 rendezvous = aura_strdup("9999"); 190 } else { 191 rendezvous = aura_strdup("test"); 192 } 193 } 194 195 #ifdef ENABLE_NLS 196 setlocale (LC_ALL, ""); 197 bindtextdomain (PACKAGE, LOCALEDIR); 198 textdomain (PACKAGE); 199 #endif 200 201 /* 202 * Set up screen. 203 */ 204 205 initscr(); 206 207 #ifdef SIGNAL_HANDLING 208 signal(SIGINT, signal_handler); 209 signal(SIGTERM, signal_handler); 210 #endif 211 212 curses_colors_init(force_monochrome); 213 cbreak(); 214 noecho(); 215 nonl(); 216 keypad(stdscr, TRUE); 217 curs_set(0); 218 219 getmaxyx(stdscr, ymax, xmax); 220 221 if (bdropfn == NULL) { 222 curses_colors_set(stdscr, CURSES_COLORS_BACKDROP); 223 curses_window_blank(stdscr); 224 } else { 225 curses_load_backdrop(stdscr, bdropfn); 226 } 227 228 menubar = curses_bar_new(0, 0, 0, 1, CURSES_COLORS_MENUBAR, 229 CURSES_BAR_WIDEN); 230 statusbar = curses_bar_new(0, 0, 0, 1, CURSES_COLORS_STATUSBAR, 231 CURSES_BAR_WIDEN | CURSES_BAR_BOTTOM); 232 233 curses_bar_set_text(menubar, _("F10=Refresh Display")); 234 curses_bar_set_text(statusbar, _("Waiting for backend...")); 235 236 update_panels(); 237 doupdate(); 238 239 #ifdef DEBUG 240 dfui_debug_file = fopen("/tmp/dfuife_curses_debug.log", "w"); 241 #endif 242 243 c = dfui_connection_new(transport, rendezvous); 244 dfui_fe_connect(c); 245 246 curses_bar_set_text(statusbar, _("Connected")); 247 248 while (!done) { 249 dfui_fe_receive(c, &msgtype, &payload); 250 switch (msgtype) { 251 case DFUI_BE_MSG_PRESENT: 252 f = (struct dfui_form *)payload; 253 r = present_form(c, f); 254 #ifdef SIGNAL_HANDLING 255 if (caught_signal) abort_frontend(c); 256 #endif 257 dfui_fe_submit(c, r); 258 dfui_form_free(f); 259 dfui_response_free(r); 260 break; 261 case DFUI_BE_MSG_PROG_BEGIN: 262 pr = (struct dfui_progress *)payload; 263 if (pf != NULL) 264 curses_form_free(pf); 265 is_streaming = dfui_progress_get_streaming(pr); 266 strncpy(last_message, dfui_info_get_short_desc( 267 dfui_progress_get_info(pr)), 79); 268 pf = curses_form_construct_from_dfui_progress(pr, 269 &pbar, &plab, &pcan); 270 curses_form_draw(pf); 271 curses_form_refresh(pf); 272 dfui_progress_free(pr); 273 nodelay(stdscr, TRUE); 274 dfui_fe_progress_continue(c); 275 break; 276 case DFUI_BE_MSG_PROG_UPDATE: 277 pr = (struct dfui_progress *)payload; 278 if (pf != NULL) { 279 curses_widgets_update_from_dfui_progress(pr, 280 pbar, plab, pcan); 281 } 282 dfui_progress_free(pr); 283 ch = getch(); 284 if (ch == ' ' || ch == '\n' || ch == '\r') { 285 dfui_fe_progress_cancel(c); 286 } else if (ch == KEY_F(10)) { 287 redrawwin(stdscr); 288 curses_form_refresh(NULL); 289 dfui_fe_progress_continue(c); 290 } else { 291 dfui_fe_progress_continue(c); 292 } 293 break; 294 case DFUI_BE_MSG_PROG_END: 295 if (pf != NULL) { 296 if (is_streaming) { 297 w = curses_form_widget_add(pf, 0, pf->int_height, 0, 298 CURSES_BUTTON, "OK", -1, 299 CURSES_WIDGET_CENTER | CURSES_WIDGET_WIDEN); 300 pf->int_height++; 301 curses_widget_set_click_cb(w, cb_click_close_form); 302 pf->widget_focus = w; 303 curses_form_widget_ensure_visible(w); 304 curses_widget_draw(w); 305 curses_form_refresh(pf); 306 curses_form_frob(pf); 307 } 308 curses_form_free(pf); 309 curses_form_refresh(NULL); 310 } 311 pf = NULL; 312 plab = pbar = pcan = NULL; 313 nodelay(stdscr, FALSE); 314 dfui_fe_progress_continue(c); 315 break; 316 case DFUI_BE_MSG_SET_GLOBAL: 317 gp = (struct dfui_property *)payload; 318 319 #ifdef ENABLE_NLS 320 /* 321 * Check for a change to the "lang" setting... 322 */ 323 if (strcmp(dfui_property_get_name(gp), "lang") == 0) { 324 set_lang_envars(dfui_property_get_value(gp)); 325 326 /* let gettext know about changes */ 327 ++_nl_msg_cat_cntr; 328 329 /* BEGIN: reinit curses to use new TERM */ 330 curses_bar_free(menubar); 331 curses_bar_free(statusbar); 332 333 endwin(); 334 newterm(getenv("TERM"), stdout, stdin); 335 336 curses_colors_init(force_monochrome); 337 cbreak(); 338 noecho(); 339 nonl(); 340 keypad(stdscr, TRUE); 341 curs_set(0); 342 343 update_panels(); 344 doupdate(); 345 346 if (bdropfn == NULL) { 347 curses_colors_set(stdscr, 348 CURSES_COLORS_BACKDROP); 349 curses_window_blank(stdscr); 350 } else { 351 curses_load_backdrop(stdscr, bdropfn); 352 } 353 354 menubar = curses_bar_new(0, 0, 0, 1, 355 CURSES_COLORS_MENUBAR, CURSES_BAR_WIDEN); 356 statusbar = curses_bar_new(0, 0, 0, 1, 357 CURSES_COLORS_STATUSBAR, 358 CURSES_BAR_WIDEN | CURSES_BAR_BOTTOM); 359 /* END: reinit curses to use new TERM */ 360 361 curses_bar_set_text(menubar, 362 _("F1=Help F10=Refresh Display")); 363 } 364 #endif 365 366 dfui_fe_confirm_set_global(c); 367 dfui_property_free(gp); 368 break; 369 case DFUI_BE_MSG_STOP: 370 dfui_fe_confirm_stop(c); 371 done = 1; 372 break; 373 } 374 } 375 376 dfui_fe_disconnect(c); 377 378 #ifdef DEBUG 379 fclose(dfui_debug_file); 380 #endif 381 382 curses_bar_free(menubar); 383 curses_bar_free(statusbar); 384 385 clear(); 386 refresh(); 387 endwin(); 388 389 if (rendezvous != NULL) 390 free(rendezvous); 391 if (bdropfn != NULL) 392 free(bdropfn); 393 394 exit(0); 395 } 396