#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "font-info.h" #include "file-dialogs.h" #include "get-string.h" #include "embedded-view.h" #include "identity.h" FILE *logger = NULL; window_t *lkb_top; popup_menu_t *grammar_menu, *parse_menu; embedded_view_t *console_view; char *current_user(); int gDone = 0; int passive_mode = 0; char *status_bar = "No grammar is loaded."; int status_bar_x = 0; struct window_manager *wms; int nwm = 0, awm = 0; void poll_for_window_events(int msec); void update_status_bar(); char *remote_server = 0; main(int argc, char *argv[]) { parse_options(argc, argv); setup_redirects(); read_preferences(); if(fcntl(0, F_SETFL, O_NONBLOCK)) perror("fcntl stdin"); setlocale(LC_ALL, ""); if(passive_mode) run_passive_yzlui(); assert(!setup_console()); lkb_send_version(); while(!gDone) { poll_for_window_events(50); check_lkb_stream(); update_status_bar(); } lkb_send_quit(); close_window_managers(); return 0; } parse_options(int argc, char **argv) { int ch; while( -1 != (ch=getopt(argc, argv, "vhpc:s:")))switch(ch) { case 'v': printf(LUI_ID " version " YZLUI_VERSION_STRING "\n"); exit(0); case 'h': printf("usage: " LUI_ID " [-v | -h] | [-p] [-c host:port]\n"); exit(0); case 'p': passive_mode = 1; break; case 'c': remote_server = optarg; break; case '?': fprintf(stderr, "usage: " LUI_ID " [-v | -h] | [-p] [-c host:port]\n"); exit(-1); case 's': passive_mode = 0; fprintf(stderr, LUI_ID " -s %s\n", optarg); break; } if(optind!=argc) fprintf(stderr, "warning: ignoring trailing arguments\n"); return 0; } //void XFlush(void *foo) {} //void XSync(void *foo, int goo) {} run_passive_yzlui() { passive_mode = 1; lkb_send_version(); while(!gDone) { poll_for_window_events(50); if(check_lkb_stream()) break; } close_window_managers(); exit(0); } setup_redirects() { int i; // set up a log file char *user = current_user(); char *file = (char *)malloc(strlen(user) + strlen("/tmp/" LUI_ID ".debug.") + 1); if(remote_server) { for(i=0;i<5;i++) if(redirect_stdio_to_socket(remote_server)) { if(i!=4)sleep(i+1); } else break; if(i==5) { fprintf(stderr, "unable to connect to remote host, giving up.\n"); exit(-1); } } sprintf(file, "/tmp/" LUI_ID ".debug.%s", user); logger = fopen(file, "w"); // redirect stderr to it close(2); dup2(fileno(logger), 2); } register_window_manager(window_t *w, void (*event)(event_t ev), int (*drag)(char *type, int x, int y), int type) { int i; awm++; for(i=0;iw; //fprintf(stderr, "closing %s\n", w->name); // notify the window's handling code that it is being closed yzSelectWindow(w); event_t ev; bzero(&ev,sizeof(ev)); ev.type = YZ_WINDOW_CLOSE; wm->event(ev); // this is expected to have the effect of closing the window and deregistering the WM yzSelectWindow(NULL); } close_window_managers() { int i; //fprintf(stderr, "closing window managers\n"); for(i=0;iname); yzSelectWindow(wms[i].w); ev = yzGetEvent(ts); wms[i].event(ev); // even if it's an IDLE }*/ fd_set fds; FD_ZERO(&fds); extern int stdin_still_open; if(stdin_still_open) FD_SET(0, &fds); ev = yzGetGlobalEventAndSelect(&w, 1, fds, msec); if(ev.type==YZ_KEY_DOWN && ev.key=='Q') // global kill-typed-window command { for(i=0;i=nwm)return; // send a lowercase 'q' to all windows of this type ev.key = 'q'; type = wms[i].type; //printf("Q for type %d\n", type); for(i=0;iwidth-1, 19); yzPenColor(0,0,0); yzOutlineRect(0, 0, lkb_top->width-1, 19); grammar_menu = yzAddPopupMenu("Grammar", x, 0, 100, 20, 1, "Load Grammar...", "Reload", NULL); x += 100; parse_menu = yzAddPopupMenu("Parse", x, 0, 100, 20, 2, "Parse Sentence...", NULL); x += 100; status_bar_x = x; } setup_console() { extern embedded_view_t the_console_view; setup_window(); console_view = &the_console_view; console_view->vis_width = lkb_top->width - 15; console_view->private = 0; if(console_view->init(console_view))return -1; init_view(console_view, 0, 20, lkb_top->width, lkb_top->height); yzSelectWindow(lkb_top); yzPutWindowData("embedded_view", console_view); console_add("YZLUI Console Ready.\n"); setup_menus(); return 0; } handle_menu_event(popup_menu_t *popup) { switch(popup->id) { case 1: handle_grammar_menu_choice(popup->lastSelID); break; case 2: handle_parse_menu_choice(popup->lastSelID); break; } } extern int grammar_loaded; handle_grammar_menu_choice(int id) { char *path; char cwd[1024]; void grammar_load_cb(char *path); void reload_grammar(); switch(id) { case 1: getcwd(cwd, 1023); #ifndef USE_EXTERNAL_GET_FILE path = get_file_path("Load what grammar?", cwd);//"/root/lisp"); if(path)grammar_load_cb(path); #else async_open_dialog( "\"Load what grammar?\"", "~/lisp", grammar_load_cb); #endif break; case 2: reload_grammar(); break; } } handle_parse_menu_choice(int id) { char *string; void parse_string_cb(char *string); switch(id) { case 1: if(!grammar_loaded) { console_add("No grammar loaded.\n"); break; } /*async_get_string_dialog( "Parse what string?", "Kim adores snow.", parse_string_cb);*/ string = get_string_dialog("Parse what string?", "Kim adores snow."); if(string)parse_string_cb(string); break; } } void update_status_bar() { static char *old_status = "no initial string"; extern int finish_grammar_time; if(finish_grammar_time > 0 && time(0) >= finish_grammar_time) status_bar = "Grammar is ready."; if(!strcmp(old_status, status_bar))return; old_status = status_bar; redraw_status_bar(); } redraw_status_bar() { yzSelectWindow(lkb_top); yzPenColor(50000, 50000, 55000); yzRect(status_bar_x, 0, lkb_top->width-1, 19); yzPenColor(0,0,0); yzOutlineRect(status_bar_x, 0, lkb_top->width-1, 19); yzSelectFont("system"); yzText(status_bar_x + 15, 16, status_bar); } char *current_user() { struct passwd *user; if((user = getpwuid(getuid())) != NULL) { return(user->pw_name); } /* if */ else { return("unknown"); } /* else */ } /* current_user() */