X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/8eed910da111b888ec363493ee55c6057eb61acf..6b0eeb4e4c9ecbff8eda72c5a1b49a448d6bbf3a:/unix/pterm.c diff --git a/unix/pterm.c b/unix/pterm.c index dad013cf..f2e8b120 100644 --- a/unix/pterm.c +++ b/unix/pterm.c @@ -34,6 +34,8 @@ #define NCOLOURS (lenof(((Config *)0)->colours)) +GdkAtom compound_text_atom, utf8_string_atom; + struct gui_data { GtkWidget *window, *area, *sbar; GtkBox *hbox; @@ -55,10 +57,10 @@ struct gui_data { char *pasteout_data, *pasteout_data_utf8; int pasteout_data_len, pasteout_data_utf8_len; int font_width, font_height; + int width, height; int ignore_sbar; int mouseptr_visible; guint term_paste_idle_id; - GdkAtom compound_text_atom, utf8_string_atom; int alt_keycode; int alt_digits; char wintitle[sizeof(((Config *)0)->wintitle)]; @@ -91,8 +93,7 @@ char *x_get_default(const char *key) void connection_fatal(void *frontend, char *p, ...) { - Terminal *term = (Terminal *)frontend; - struct gui_data *inst = (struct gui_data *)term->frontend; + struct gui_data *inst = (struct gui_data *)frontend; va_list ap; char *msg; @@ -151,21 +152,15 @@ void ldisc_update(void *frontend, int echo, int edit) */ } -int askappend(void *frontend, Filename filename) +int from_backend(void *frontend, int is_stderr, const char *data, int len) { - /* - * Logging in an xterm-alike is liable to be something you only - * do at serious diagnostic need. Hence, I'm going to take the - * easy option for now and assume we always want to overwrite - * log files. I can always make it properly configurable later. - */ - return 2; + struct gui_data *inst = (struct gui_data *)frontend; + return term_data(inst->term, is_stderr, data, len); } void logevent(void *frontend, char *string) { - Terminal *term = (Terminal *)frontend; - struct gui_data *inst = (struct gui_data *)term->frontend; + struct gui_data *inst = (struct gui_data *)frontend; log_eventlog(inst->logctx, string); @@ -210,8 +205,7 @@ static Mouse_Button translate_button(Mouse_Button button) */ void *get_window(void *frontend) { - Terminal *term = (Terminal *)frontend; - struct gui_data *inst = (struct gui_data *)term->frontend; + struct gui_data *inst = (struct gui_data *)frontend; return inst->window; } @@ -347,10 +341,11 @@ char *get_window_title(void *frontend, int icon) gint delete_window(GtkWidget *widget, GdkEvent *event, gpointer data) { - /* - * We could implement warn-on-close here if we really wanted - * to. - */ + struct gui_data *inst = (struct gui_data *)data; + if (!inst->exited && inst->cfg.warn_on_close) { + if (!reallyclose(inst)) + return TRUE; + } return FALSE; } @@ -373,13 +368,13 @@ gint configure_area(GtkWidget *widget, GdkEventConfigure *event, gpointer data) w = (event->width - 2*inst->cfg.window_border) / inst->font_width; h = (event->height - 2*inst->cfg.window_border) / inst->font_height; - if (w != inst->cfg.width || h != inst->cfg.height) { + if (w != inst->width || h != inst->height) { if (inst->pixmap) { gdk_pixmap_unref(inst->pixmap); inst->pixmap = NULL; } - inst->cfg.width = w; - inst->cfg.height = h; + inst->cfg.width = inst->width = w; + inst->cfg.height = inst->height = h; need_size = 1; } if (!inst->pixmap) { @@ -1160,8 +1155,11 @@ void request_resize(void *frontend, int w, int h) gtk_widget_set_size_request(inst->area, area_x, area_y); #else gtk_widget_set_usize(inst->area, area_x, area_y); + gtk_drawing_area_size(GTK_DRAWING_AREA(inst->area), area_x, area_y); #endif + gtk_container_dequeue_resize_handler(GTK_CONTAINER(inst->window)); + #if GTK_CHECK_VERSION(2,0,0) gtk_window_resize(GTK_WINDOW(inst->window), area_x + offset_x, area_y + offset_y); @@ -1179,10 +1177,11 @@ static void real_palette_set(struct gui_data *inst, int n, int r, int g, int b) inst->cols[n].green = g * 0x0101; inst->cols[n].blue = b * 0x0101; + gdk_colormap_free_colors(inst->colmap, inst->cols + n, 1); gdk_colormap_alloc_colors(inst->colmap, inst->cols + n, 1, FALSE, FALSE, success); if (!success[0]) - g_error("pterm: couldn't allocate colour %d (#%02x%02x%02x)\n", + g_error("%s: couldn't allocate colour %d (#%02x%02x%02x)\n", appname, n, r, g, b); } @@ -1239,8 +1238,9 @@ void palette_reset(void *frontend) FALSE, FALSE, success); for (i = 0; i < NCOLOURS; i++) { if (!success[i]) - g_error("pterm: couldn't allocate colour %d (#%02x%02x%02x)\n", - i, inst->cfg.colours[i][0], inst->cfg.colours[i][1], inst->cfg.colours[i][2]); + g_error("%s: couldn't allocate colour %d (#%02x%02x%02x)\n", + appname, i, inst->cfg.colours[i][0], + inst->cfg.colours[i][1], inst->cfg.colours[i][2]); } set_window_background(inst); @@ -1300,18 +1300,21 @@ void write_clip(void *frontend, wchar_t * data, int len, int must_deselect) gtk_selection_add_target(inst->area, GDK_SELECTION_PRIMARY, GDK_SELECTION_TYPE_STRING, 1); gtk_selection_add_target(inst->area, GDK_SELECTION_PRIMARY, - inst->compound_text_atom, 1); + compound_text_atom, 1); if (inst->pasteout_data_utf8) gtk_selection_add_target(inst->area, GDK_SELECTION_PRIMARY, - inst->utf8_string_atom, 1); + utf8_string_atom, 1); } + + if (must_deselect) + term_deselect(inst->term); } void selection_get(GtkWidget *widget, GtkSelectionData *seldata, guint info, guint time_stamp, gpointer data) { struct gui_data *inst = (struct gui_data *)data; - if (seldata->target == inst->utf8_string_atom) + if (seldata->target == utf8_string_atom) gtk_selection_data_set(seldata, seldata->target, 8, inst->pasteout_data_utf8, inst->pasteout_data_utf8_len); @@ -1354,7 +1357,7 @@ void request_paste(void *frontend) * fall back to an ordinary string. */ gtk_selection_convert(inst->area, GDK_SELECTION_PRIMARY, - inst->utf8_string_atom, GDK_CURRENT_TIME); + utf8_string_atom, GDK_CURRENT_TIME); } else { /* * If we're in direct-to-font mode, we disable UTF-8 @@ -1372,7 +1375,7 @@ void selection_received(GtkWidget *widget, GtkSelectionData *seldata, { struct gui_data *inst = (struct gui_data *)data; - if (seldata->target == inst->utf8_string_atom && seldata->length <= 0) { + if (seldata->target == utf8_string_atom && seldata->length <= 0) { /* * Failed to get a UTF-8 selection string. Try an ordinary * string. @@ -1387,7 +1390,7 @@ void selection_received(GtkWidget *widget, GtkSelectionData *seldata, */ if (seldata->length <= 0 || (seldata->type != GDK_SELECTION_TYPE_STRING && - seldata->type != inst->utf8_string_atom)) + seldata->type != utf8_string_atom)) return; /* Nothing happens. */ if (inst->pastein_data) @@ -1396,7 +1399,7 @@ void selection_received(GtkWidget *widget, GtkSelectionData *seldata, inst->pastein_data = snewn(seldata->length, wchar_t); inst->pastein_data_len = seldata->length; inst->pastein_data_len = - mb_to_wc((seldata->type == inst->utf8_string_atom ? + mb_to_wc((seldata->type == utf8_string_atom ? CS_UTF8 : inst->ucsdata.line_codepage), 0, seldata->data, seldata->length, inst->pastein_data, inst->pastein_data_len); @@ -1955,7 +1958,7 @@ void modalfatalbox(char *p, ...) void cmdline_error(char *p, ...) { va_list ap; - fprintf(stderr, "plink: "); + fprintf(stderr, "%s: ", appname); va_start(ap, p); vfprintf(stderr, p, ap); va_end(ap); @@ -1970,8 +1973,7 @@ char *get_x_display(void *frontend) long get_windowid(void *frontend) { - Terminal *term = (Terminal *)frontend; - struct gui_data *inst = (struct gui_data *)(term->frontend); + struct gui_data *inst = (struct gui_data *)frontend; return (long)GDK_WINDOW_XWINDOW(inst->area->window); } @@ -2020,7 +2022,7 @@ int do_cmdline(int argc, char **argv, int do_everything, #define EXPECTS_ARG { \ if (--argc <= 0) { \ err = 1; \ - fprintf(stderr, "pterm: %s expects an argument\n", p); \ + fprintf(stderr, "%s: %s expects an argument\n", appname, p); \ continue; \ } else \ val = *++argv; \ @@ -2107,7 +2109,8 @@ int do_cmdline(int argc, char **argv, int do_everything, SECOND_PASS_ONLY; if (!gdk_color_parse(val, &col)) { err = 1; - fprintf(stderr, "pterm: unable to parse colour \"%s\"\n", val); + fprintf(stderr, "%s: unable to parse colour \"%s\"\n", + appname, val); } else { int index; index = (!strcmp(p, "-fg") ? 0 : @@ -2136,7 +2139,8 @@ int do_cmdline(int argc, char **argv, int do_everything, pty_argv[argc] = NULL; break; /* finished command-line processing */ } else - err = 1, fprintf(stderr, "pterm: -e expects an argument\n"); + err = 1, fprintf(stderr, "%s: -e expects an argument\n", + appname); } else if (!strcmp(p, "-title")) { EXPECTS_ARG; @@ -2197,7 +2201,7 @@ int do_cmdline(int argc, char **argv, int do_everything, } else { err = 1; - fprintf(stderr, "pterm: unrecognized option '%s'\n", p); + fprintf(stderr, "%s: unrecognized option '%s'\n", appname, p); } } @@ -2291,6 +2295,80 @@ void uxsel_input_remove(int id) { gdk_input_remove(id); } +void setup_fonts_ucs(struct gui_data *inst) +{ + int font_charset; + + if (inst->fonts[0]) + gdk_font_unref(inst->fonts[0]); + if (inst->fonts[1]) + gdk_font_unref(inst->fonts[1]); + if (inst->fonts[2]) + gdk_font_unref(inst->fonts[2]); + if (inst->fonts[3]) + gdk_font_unref(inst->fonts[3]); + + inst->fonts[0] = gdk_font_load(inst->cfg.font.name); + if (!inst->fonts[0]) { + fprintf(stderr, "%s: unable to load font \"%s\"\n", appname, + inst->cfg.font.name); + exit(1); + } + font_charset = set_font_info(inst, 0); + if (inst->cfg.boldfont.name[0]) { + inst->fonts[1] = gdk_font_load(inst->cfg.boldfont.name); + if (!inst->fonts[1]) { + fprintf(stderr, "%s: unable to load bold font \"%s\"\n", appname, + inst->cfg.boldfont.name); + exit(1); + } + set_font_info(inst, 1); + } else + inst->fonts[1] = NULL; + if (inst->cfg.widefont.name[0]) { + inst->fonts[2] = gdk_font_load(inst->cfg.widefont.name); + if (!inst->fonts[2]) { + fprintf(stderr, "%s: unable to load wide font \"%s\"\n", appname, + inst->cfg.widefont.name); + exit(1); + } + set_font_info(inst, 2); + } else + inst->fonts[2] = NULL; + if (inst->cfg.wideboldfont.name[0]) { + inst->fonts[3] = gdk_font_load(inst->cfg.wideboldfont.name); + if (!inst->fonts[3]) { + fprintf(stderr, "%s: unable to load wide/bold font \"%s\"\n", + appname, inst->cfg.wideboldfont.name); + exit(1); + } + set_font_info(inst, 3); + } else + inst->fonts[3] = NULL; + + inst->font_width = gdk_char_width(inst->fonts[0], ' '); + inst->font_height = inst->fonts[0]->ascent + inst->fonts[0]->descent; + + inst->direct_to_font = init_ucs(&inst->ucsdata, + inst->cfg.line_codepage, font_charset); +} + +void set_geom_hints(struct gui_data *inst) +{ + GdkGeometry geom; + geom.min_width = inst->font_width + 2*inst->cfg.window_border; + geom.min_height = inst->font_height + 2*inst->cfg.window_border; + geom.max_width = geom.max_height = -1; + geom.base_width = 2*inst->cfg.window_border; + geom.base_height = 2*inst->cfg.window_border; + geom.width_inc = inst->font_width; + geom.height_inc = inst->font_height; + geom.min_aspect = geom.max_aspect = 0; + gtk_window_set_geometry_hints(GTK_WINDOW(inst->window), inst->area, &geom, + GDK_HINT_MIN_SIZE | GDK_HINT_BASE_SIZE | + GDK_HINT_RESIZE_INC); +} + void clear_scrollback_menuitem(GtkMenuItem *item, gpointer data) { struct gui_data *inst = (struct gui_data *)data; @@ -2304,6 +2382,12 @@ void reset_terminal_menuitem(GtkMenuItem *item, gpointer data) ldisc_send(inst->ldisc, NULL, 0, 0); } +void copy_all_menuitem(GtkMenuItem *item, gpointer data) +{ + struct gui_data *inst = (struct gui_data *)data; + term_copyall(inst->term); +} + void special_menuitem(GtkMenuItem *item, gpointer data) { struct gui_data *inst = (struct gui_data *)data; @@ -2314,8 +2398,8 @@ void special_menuitem(GtkMenuItem *item, gpointer data) void about_menuitem(GtkMenuItem *item, gpointer data) { - /* struct gui_data *inst = (struct gui_data *)data; */ - about_box(); + struct gui_data *inst = (struct gui_data *)data; + about_box(inst->window); } void event_log_menuitem(GtkMenuItem *item, gpointer data) @@ -2324,10 +2408,107 @@ void event_log_menuitem(GtkMenuItem *item, gpointer data) showeventlog(inst->eventlogstuff, inst->window); } +void change_settings_menuitem(GtkMenuItem *item, gpointer data) +{ + /* This maps colour indices in inst->cfg to those used in inst->cols. */ + static const int ww[] = { + 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, + 0, 1, 2, 3, 4, 5 + }; + struct gui_data *inst = (struct gui_data *)data; + char *title = dupcat(appname, " Reconfiguration", NULL); + Config cfg2, oldcfg; + int i, need_size; + + cfg2 = inst->cfg; /* structure copy */ + + if (do_config_box(title, &cfg2, 1)) { + + oldcfg = inst->cfg; /* structure copy */ + inst->cfg = cfg2; /* structure copy */ + + /* Pass new config data to the logging module */ + log_reconfig(inst->logctx, &cfg2); + /* + * Flush the line discipline's edit buffer in the case + * where local editing has just been disabled. + */ + ldisc_send(inst->ldisc, NULL, 0, 0); + /* Pass new config data to the terminal */ + term_reconfig(inst->term, &cfg2); + /* Pass new config data to the back end */ + inst->back->reconfig(inst->backhandle, &cfg2); + + /* + * Just setting inst->cfg is sufficient to cause colour + * setting changes to appear on the next ESC]R palette + * reset. But we should also check whether any colour + * settings have been changed, and revert the ones that + * have to the new default, on the assumption that the user + * is most likely to want an immediate update. + */ + for (i = 0; i < NCOLOURS; i++) { + if (oldcfg.colours[ww[i]][0] != cfg2.colours[ww[i]][0] || + oldcfg.colours[ww[i]][1] != cfg2.colours[ww[i]][1] || + oldcfg.colours[ww[i]][2] != cfg2.colours[ww[i]][2]) + real_palette_set(inst, i, cfg2.colours[ww[i]][0], + cfg2.colours[ww[i]][1], + cfg2.colours[ww[i]][2]); + } + + /* + * If the scrollbar needs to be shown, hidden, or moved + * from one end to the other of the window, do so now. + */ + if (oldcfg.scrollbar != cfg2.scrollbar) { + if (cfg2.scrollbar) + gtk_widget_show(inst->sbar); + else + gtk_widget_hide(inst->sbar); + } + if (oldcfg.scrollbar_on_left != cfg2.scrollbar_on_left) { + gtk_box_reorder_child(inst->hbox, inst->sbar, + cfg2.scrollbar_on_left ? 0 : 1); + } + + /* + * Change the window title, if required. + */ + if (strcmp(oldcfg.wintitle, cfg2.wintitle)) + set_title(inst, cfg2.wintitle); + + /* + * Redo the whole tangled fonts and Unicode mess if + * necessary. + */ + if (strcmp(oldcfg.font.name, cfg2.font.name) || + strcmp(oldcfg.boldfont.name, cfg2.boldfont.name) || + strcmp(oldcfg.widefont.name, cfg2.widefont.name) || + strcmp(oldcfg.wideboldfont.name, cfg2.wideboldfont.name) || + strcmp(oldcfg.line_codepage, cfg2.line_codepage)) { + setup_fonts_ucs(inst); + need_size = 1; + } else + need_size = 0; + + /* + * Resize the window. + */ + if (oldcfg.width != cfg2.width || oldcfg.height != cfg2.height || + oldcfg.window_border != cfg2.window_border || need_size) { + set_geom_hints(inst); + request_resize(inst, cfg2.width, cfg2.height); + } + + term_invalidate(inst->term); + } + sfree(title); +} + void update_specials_menu(void *frontend) { - Terminal *term = (Terminal *)frontend; - struct gui_data *inst = (struct gui_data *)term->frontend; + struct gui_data *inst = (struct gui_data *)frontend; const struct telnet_special *specials; @@ -2362,7 +2543,6 @@ int pt_main(int argc, char **argv) extern Backend *select_backend(Config *cfg); extern int cfgbox(Config *cfg); struct gui_data *inst; - int font_charset; /* defer any child exit handling until we're ready to deal with * it */ @@ -2388,52 +2568,12 @@ int pt_main(int argc, char **argv) if (!*inst->cfg.host && !cfgbox(&inst->cfg)) exit(0); /* config box hit Cancel */ - inst->fonts[0] = gdk_font_load(inst->cfg.font.name); - if (!inst->fonts[0]) { - fprintf(stderr, "pterm: unable to load font \"%s\"\n", - inst->cfg.font.name); - exit(1); - } - font_charset = set_font_info(inst, 0); - if (inst->cfg.boldfont.name[0]) { - inst->fonts[1] = gdk_font_load(inst->cfg.boldfont.name); - if (!inst->fonts[1]) { - fprintf(stderr, "pterm: unable to load bold font \"%s\"\n", - inst->cfg.boldfont.name); - exit(1); - } - set_font_info(inst, 1); - } else - inst->fonts[1] = NULL; - if (inst->cfg.widefont.name[0]) { - inst->fonts[2] = gdk_font_load(inst->cfg.widefont.name); - if (!inst->fonts[2]) { - fprintf(stderr, "pterm: unable to load wide font \"%s\"\n", - inst->cfg.widefont.name); - exit(1); - } - set_font_info(inst, 2); - } else - inst->fonts[2] = NULL; - if (inst->cfg.wideboldfont.name[0]) { - inst->fonts[3] = gdk_font_load(inst->cfg.wideboldfont.name); - if (!inst->fonts[3]) { - fprintf(stderr, "pterm: unable to load wide/bold font \"%s\"\n", - inst->cfg.wideboldfont.name); - exit(1); - } - set_font_info(inst, 3); - } else - inst->fonts[3] = NULL; - - inst->font_width = gdk_char_width(inst->fonts[0], ' '); - inst->font_height = inst->fonts[0]->ascent + inst->fonts[0]->descent; - - inst->compound_text_atom = gdk_atom_intern("COMPOUND_TEXT", FALSE); - inst->utf8_string_atom = gdk_atom_intern("UTF8_STRING", FALSE); + if (!compound_text_atom) + compound_text_atom = gdk_atom_intern("COMPOUND_TEXT", FALSE); + if (!utf8_string_atom) + utf8_string_atom = gdk_atom_intern("UTF8_STRING", FALSE); - inst->direct_to_font = init_ucs(&inst->ucsdata, - inst->cfg.line_codepage, font_charset); + setup_fonts_ucs(inst); inst->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); @@ -2442,43 +2582,36 @@ int pt_main(int argc, char **argv) */ palette_reset(inst); + inst->width = inst->cfg.width; + inst->height = inst->cfg.height; + inst->area = gtk_drawing_area_new(); gtk_drawing_area_size(GTK_DRAWING_AREA(inst->area), inst->font_width * inst->cfg.width + 2*inst->cfg.window_border, inst->font_height * inst->cfg.height + 2*inst->cfg.window_border); - if (inst->cfg.scrollbar) { - inst->sbar_adjust = GTK_ADJUSTMENT(gtk_adjustment_new(0,0,0,0,0,0)); - inst->sbar = gtk_vscrollbar_new(inst->sbar_adjust); - } + inst->sbar_adjust = GTK_ADJUSTMENT(gtk_adjustment_new(0,0,0,0,0,0)); + inst->sbar = gtk_vscrollbar_new(inst->sbar_adjust); inst->hbox = GTK_BOX(gtk_hbox_new(FALSE, 0)); - if (inst->cfg.scrollbar) { - if (inst->cfg.scrollbar_on_left) - gtk_box_pack_start(inst->hbox, inst->sbar, FALSE, FALSE, 0); - else - gtk_box_pack_end(inst->hbox, inst->sbar, FALSE, FALSE, 0); - } + /* + * We always create the scrollbar; it remains invisible if + * unwanted, so we can pop it up quickly if it suddenly becomes + * desirable. + */ + if (inst->cfg.scrollbar_on_left) + gtk_box_pack_start(inst->hbox, inst->sbar, FALSE, FALSE, 0); gtk_box_pack_start(inst->hbox, inst->area, TRUE, TRUE, 0); + if (!inst->cfg.scrollbar_on_left) + gtk_box_pack_start(inst->hbox, inst->sbar, FALSE, FALSE, 0); gtk_container_add(GTK_CONTAINER(inst->window), GTK_WIDGET(inst->hbox)); - { - GdkGeometry geom; - geom.min_width = inst->font_width + 2*inst->cfg.window_border; - geom.min_height = inst->font_height + 2*inst->cfg.window_border; - geom.max_width = geom.max_height = -1; - geom.base_width = 2*inst->cfg.window_border; - geom.base_height = 2*inst->cfg.window_border; - geom.width_inc = inst->font_width; - geom.height_inc = inst->font_height; - geom.min_aspect = geom.max_aspect = 0; - gtk_window_set_geometry_hints(GTK_WINDOW(inst->window), inst->area, &geom, - GDK_HINT_MIN_SIZE | GDK_HINT_BASE_SIZE | - GDK_HINT_RESIZE_INC); - } + set_geom_hints(inst); gtk_widget_show(inst->area); if (inst->cfg.scrollbar) gtk_widget_show(inst->sbar); + else + gtk_widget_hide(inst->sbar); gtk_widget_show(GTK_WIDGET(inst->hbox)); if (inst->gotpos) { @@ -2551,6 +2684,8 @@ int pt_main(int argc, char **argv) gtk_signal_connect(GTK_OBJECT(menuitem), "activate", \ GTK_SIGNAL_FUNC(func), inst); \ } while (0) + MKMENUITEM("Change Settings", change_settings_menuitem); + MKMENUITEM(NULL, NULL); if (use_event_log) MKMENUITEM("Event Log", event_log_menuitem); MKMENUITEM("Special Commands", NULL); @@ -2561,6 +2696,7 @@ int pt_main(int argc, char **argv) inst->specialsitem2 = menuitem; MKMENUITEM("Clear Scrollback", clear_scrollback_menuitem); MKMENUITEM("Reset Terminal", reset_terminal_menuitem); + MKMENUITEM("Copy All", copy_all_menuitem); MKMENUITEM(NULL, NULL); s = dupcat("About ", appname, NULL); MKMENUITEM(s, about_menuitem); @@ -2589,7 +2725,7 @@ int pt_main(int argc, char **argv) { char *realhost, *error; - error = inst->back->init((void *)inst->term, &inst->backhandle, + error = inst->back->init((void *)inst, &inst->backhandle, &inst->cfg, inst->cfg.host, inst->cfg.port, &realhost, inst->cfg.tcp_nodelay); @@ -2611,7 +2747,7 @@ int pt_main(int argc, char **argv) } } inst->back->provide_logctx(inst->backhandle, inst->logctx); - update_specials_menu(inst->term); + update_specials_menu(inst); term_provide_resize_fn(inst->term, inst->back->size, inst->backhandle);