X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/4397c7255220defe2b3841cbf4e32a4cf3b7bfbb..985b644054f5e0d777184c48bfd8a97e824705fd:/unix/gtkwin.c diff --git a/unix/gtkwin.c b/unix/gtkwin.c index 1b0ba4a1..f969b046 100644 --- a/unix/gtkwin.c +++ b/unix/gtkwin.c @@ -64,7 +64,7 @@ struct gui_data { int is_wide; } fontinfo[4]; int xpos, ypos, gotpos, gravity; - GdkCursor *rawcursor, *textcursor, *blankcursor, *currcursor; + GdkCursor *rawcursor, *textcursor, *blankcursor, *waitcursor, *currcursor; GdkColor cols[NALLCOLOURS]; GdkColormap *colmap; wchar_t *pastein_data; @@ -76,6 +76,7 @@ struct gui_data { int width, height; int ignore_sbar; int mouseptr_visible; + int busy_status; guint term_paste_idle_id; int alt_keycode; int alt_digits; @@ -94,6 +95,7 @@ struct gui_data { char *progname, **gtkargvstart; int ngtkargs; guint32 input_event_time; /* Timestamp of the most recent input event. */ + int reconfiguring; }; struct draw_ctx { @@ -175,6 +177,12 @@ void ldisc_update(void *frontend, int echo, int edit) */ } +char *get_ttymode(void *frontend, const char *mode) +{ + struct gui_data *inst = (struct gui_data *)frontend; + return term_get_ttymode(inst->term, mode); +} + int from_backend(void *frontend, int is_stderr, const char *data, int len) { struct gui_data *inst = (struct gui_data *)frontend; @@ -372,15 +380,34 @@ gint delete_window(GtkWidget *widget, GdkEvent *event, gpointer data) return FALSE; } +static void update_mouseptr(struct gui_data *inst) +{ + switch (inst->busy_status) { + case BUSY_NOT: + if (!inst->mouseptr_visible) { + gdk_window_set_cursor(inst->area->window, inst->blankcursor); + } else if (send_raw_mouse) { + gdk_window_set_cursor(inst->area->window, inst->rawcursor); + } else { + gdk_window_set_cursor(inst->area->window, inst->textcursor); + } + break; + case BUSY_WAITING: /* XXX can we do better? */ + case BUSY_CPU: + /* We always display these cursors. */ + gdk_window_set_cursor(inst->area->window, inst->waitcursor); + break; + default: + assert(0); + } +} + static void show_mouseptr(struct gui_data *inst, int show) { if (!inst->cfg.hide_mouseptr) show = 1; - if (show) - gdk_window_set_cursor(inst->area->window, inst->currcursor); - else - gdk_window_set_cursor(inst->area->window, inst->blankcursor); inst->mouseptr_visible = show; + update_mouseptr(inst); } void draw_backing_rect(struct gui_data *inst) @@ -1149,7 +1176,7 @@ void notify_remote_exit(void *frontend) inst->exited = TRUE; if (inst->cfg.close_on_exit == FORCE_ON || (inst->cfg.close_on_exit == AUTO && exitcode == 0)) - exit(0); /* just go. */ + gtk_main_quit(); /* just go */ if (inst->ldisc) { ldisc_free(inst->ldisc); inst->ldisc = NULL; @@ -1227,6 +1254,13 @@ gint focus_event(GtkWidget *widget, GdkEventFocus *event, gpointer data) return FALSE; } +void set_busy_status(void *frontend, int status) +{ + struct gui_data *inst = (struct gui_data *)frontend; + inst->busy_status = status; + update_mouseptr(inst); +} + /* * set or clear the "raw mouse message" mode */ @@ -1235,11 +1269,7 @@ void set_raw_mouse_mode(void *frontend, int activate) struct gui_data *inst = (struct gui_data *)frontend; activate = activate && !inst->cfg.no_mouse_rep; send_raw_mouse = activate; - if (send_raw_mouse) - inst->currcursor = inst->rawcursor; - else - inst->currcursor = inst->textcursor; - show_mouseptr(inst, inst->mouseptr_visible); + update_mouseptr(inst); } void request_resize(void *frontend, int w, int h) @@ -1322,7 +1352,7 @@ static void real_palette_set(struct gui_data *inst, int n, int r, int g, int b) gdk_colormap_free_colors(inst->colmap, inst->cols + n, 1); gdk_colormap_alloc_colors(inst->colmap, inst->cols + n, 1, - FALSE, FALSE, success); + FALSE, TRUE, success); if (!success[0]) g_error("%s: couldn't allocate colour %d (#%02x%02x%02x)\n", appname, n, r, g, b); @@ -1389,7 +1419,7 @@ void palette_reset(void *frontend) } gdk_colormap_alloc_colors(inst->colmap, inst->cols, NALLCOLOURS, - FALSE, FALSE, success); + FALSE, TRUE, success); for (i = 0; i < NALLCOLOURS; i++) { if (!success[i]) g_error("%s: couldn't allocate colour %d (#%02x%02x%02x)\n", @@ -1855,6 +1885,7 @@ void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len, GdkGC *gc = dctx->gc; int ncombining, combining; int nfg, nbg, t, fontid, shadow, rlen, widefactor; + int monochrome = gtk_widget_get_visual(inst->area)->depth == 1; if (attr & TATTR_COMBINING) { ncombining = len; @@ -1862,9 +1893,9 @@ void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len, } else ncombining = 1; - nfg = ((attr & ATTR_FGMASK) >> ATTR_FGSHIFT); - nbg = ((attr & ATTR_BGMASK) >> ATTR_BGSHIFT); - if (attr & ATTR_REVERSE) { + nfg = ((monochrome ? ATTR_DEFFG : (attr & ATTR_FGMASK)) >> ATTR_FGSHIFT); + nbg = ((monochrome ? ATTR_DEFBG : (attr & ATTR_BGMASK)) >> ATTR_BGSHIFT); + if (!!(attr & ATTR_REVERSE) ^ (monochrome && (attr & TATTR_ACTCURS))) { t = nfg; nfg = nbg; nbg = t; @@ -1877,7 +1908,7 @@ void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len, if (nbg < 16) nbg |= 8; else if (nbg >= 256) nbg |= 1; } - if (attr & TATTR_ACTCURS) { + if ((attr & TATTR_ACTCURS) && !monochrome) { nfg = 260; nbg = 261; } @@ -2537,7 +2568,11 @@ int do_cmdline(int argc, char **argv, int do_everything, } else if(!strcmp(p, "-help") || !strcmp(p, "--help")) { help(stdout); exit(0); - + + } else if (!strcmp(p, "-pgpfp")) { + pgp_fingerprints(); + exit(1); + } else if(p[0] != '-' && (!do_everything || process_nonoption_arg(p, cfg))) { /* do nothing */ @@ -2855,6 +2890,11 @@ void change_settings_menuitem(GtkMenuItem *item, gpointer data) assert(lenof(ww) == NCFGCOLOURS); + if (inst->reconfiguring) + return; + else + inst->reconfiguring = TRUE; + cfg2 = inst->cfg; /* structure copy */ if (do_config_box(title, &cfg2, 1, @@ -2972,6 +3012,7 @@ void change_settings_menuitem(GtkMenuItem *item, gpointer data) gtk_widget_queue_draw(inst->area); } sfree(title); + inst->reconfiguring = FALSE; } void fork_and_exec_self(struct gui_data *inst, int fd_to_close, ...) @@ -3192,6 +3233,33 @@ void saved_session_freedata(GtkMenuItem *item, gpointer data) sfree(str); } +static void update_savedsess_menu(GtkMenuItem *menuitem, gpointer data) +{ + struct gui_data *inst = (struct gui_data *)data; + struct sesslist sesslist; + int i; + + gtk_container_foreach(GTK_CONTAINER(inst->sessionsmenu), + (GtkCallback)gtk_widget_destroy, NULL); + + get_sesslist(&sesslist, TRUE); + for (i = 1; i < sesslist.nsessions; i++) { + GtkWidget *menuitem = + gtk_menu_item_new_with_label(sesslist.sessions[i]); + gtk_container_add(GTK_CONTAINER(inst->sessionsmenu), menuitem); + gtk_widget_show(menuitem); + gtk_object_set_data(GTK_OBJECT(menuitem), "user-data", + dupstr(sesslist.sessions[i])); + gtk_signal_connect(GTK_OBJECT(menuitem), "activate", + GTK_SIGNAL_FUNC(saved_session_menuitem), + inst); + gtk_signal_connect(GTK_OBJECT(menuitem), "destroy", + GTK_SIGNAL_FUNC(saved_session_freedata), + inst); + } + get_sesslist(&sesslist, FALSE); /* free up */ +} + void update_specials_menu(void *frontend) { struct gui_data *inst = (struct gui_data *)frontend; @@ -3310,6 +3378,7 @@ int pt_main(int argc, char **argv) inst = snew(struct gui_data); memset(inst, 0, sizeof(*inst)); inst->alt_keycode = -1; /* this one needs _not_ to be zero */ + inst->busy_status = BUSY_NOT; /* defer any child exit handling until we're ready to deal with * it */ @@ -3470,28 +3539,10 @@ int pt_main(int argc, char **argv) gtk_widget_hide(inst->restartitem); MKMENUITEM("Duplicate Session", dup_session_menuitem); if (saved_sessions) { - struct sesslist sesslist; - int i; - inst->sessionsmenu = gtk_menu_new(); - - get_sesslist(&sesslist, TRUE); - for (i = 1; i < sesslist.nsessions; i++) { - menuitem = gtk_menu_item_new_with_label(sesslist.sessions[i]); - gtk_container_add(GTK_CONTAINER(inst->sessionsmenu), menuitem); - gtk_widget_show(menuitem); - gtk_object_set_data(GTK_OBJECT(menuitem), "user-data", - dupstr(sesslist.sessions[i])); - gtk_signal_connect(GTK_OBJECT(menuitem), "activate", - GTK_SIGNAL_FUNC(saved_session_menuitem), - inst); - gtk_signal_connect(GTK_OBJECT(menuitem), "destroy", - GTK_SIGNAL_FUNC(saved_session_freedata), - inst); - } - get_sesslist(&sesslist, FALSE); - - MKMENUITEM("Saved Sessions", NULL); + /* sessionsmenu will be updated when it's invoked */ + /* XXX is this the right way to do dynamic menus in Gtk? */ + MKMENUITEM("Saved Sessions", update_savedsess_menu); gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), inst->sessionsmenu); } @@ -3520,6 +3571,7 @@ int pt_main(int argc, char **argv) inst->textcursor = make_mouse_ptr(inst, GDK_XTERM); inst->rawcursor = make_mouse_ptr(inst, GDK_LEFT_PTR); + inst->waitcursor = make_mouse_ptr(inst, GDK_WATCH); inst->blankcursor = make_mouse_ptr(inst, -1); make_mouse_ptr(inst, -2); /* clean up cursor font */ inst->currcursor = inst->textcursor;