X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/f7f9fb5cb0f779bc1a648b264805d7e12abc4260..db26b3afc1a5651b8a882128b141e2c4e4c42fa9:/unix/pterm.c diff --git a/unix/pterm.c b/unix/pterm.c index 92adcb13..8b6cd222 100644 --- a/unix/pterm.c +++ b/unix/pterm.c @@ -344,7 +344,7 @@ void get_window_pixels(void *frontend, int *x, int *y) char *get_window_title(void *frontend, int icon) { struct gui_data *inst = (struct gui_data *)frontend; - return icon ? inst->wintitle : inst->icontitle; + return icon ? inst->icontitle : inst->wintitle; } gint delete_window(GtkWidget *widget, GdkEvent *event, gpointer data) @@ -368,11 +368,20 @@ static void show_mouseptr(struct gui_data *inst, int show) inst->mouseptr_visible = show; } +void draw_backing_rect(struct gui_data *inst) +{ + GdkGC *gc = gdk_gc_new(inst->area->window); + gdk_gc_set_foreground(gc, &inst->cols[18]); /* default background */ + gdk_draw_rectangle(inst->pixmap, gc, 1, 0, 0, + inst->cfg.width * inst->font_width + 2*inst->cfg.window_border, + inst->cfg.height * inst->font_height + 2*inst->cfg.window_border); + gdk_gc_unref(gc); +} + gint configure_area(GtkWidget *widget, GdkEventConfigure *event, gpointer data) { struct gui_data *inst = (struct gui_data *)data; int w, h, need_size = 0; - GdkGC *gc; /* * See if the terminal size has changed, in which case we must @@ -397,12 +406,7 @@ gint configure_area(GtkWidget *widget, GdkEventConfigure *event, gpointer data) (inst->cfg.height * inst->font_height + 2*inst->cfg.window_border), -1); - gc = gdk_gc_new(inst->area->window); - gdk_gc_set_foreground(gc, &inst->cols[18]); /* default background */ - gdk_draw_rectangle(inst->pixmap, gc, 1, 0, 0, - inst->cfg.width * inst->font_width + 2*inst->cfg.window_border, - inst->cfg.height * inst->font_height + 2*inst->cfg.window_border); - gdk_gc_unref(gc); + draw_backing_rect(inst); if (need_size && inst->term) { term_size(inst->term, h, w, inst->cfg.savelines); @@ -2388,9 +2392,63 @@ void uxsel_input_remove(int id) { gdk_input_remove(id); } +char *guess_derived_font_name(GdkFont *font, int bold, int wide) +{ + XFontStruct *xfs = GDK_FONT_XFONT(font); + Display *disp = GDK_FONT_XDISPLAY(font); + Atom fontprop = XInternAtom(disp, "FONT", False); + unsigned long ret; + if (XGetFontProperty(xfs, fontprop, &ret)) { + char *name = XGetAtomName(disp, (Atom)ret); + if (name && name[0] == '-') { + char *strings[13]; + char *dupname, *extrafree = NULL, *ret; + char *p, *q; + int nstr; + + p = q = dupname = dupstr(name); /* skip initial minus */ + nstr = 0; + + while (*p && nstr < lenof(strings)) { + if (*p == '-') { + *p = '\0'; + strings[nstr++] = p+1; + } + p++; + } + + if (nstr < lenof(strings)) + return NULL; /* XLFD was malformed */ + + if (bold) + strings[2] = "bold"; + + if (wide) { + /* 4 is `wideness', which obviously may have changed. */ + /* 5 is additional style, which may be e.g. `ja' or `ko'. */ + strings[4] = strings[5] = "*"; + strings[11] = extrafree = dupprintf("%d", 2*atoi(strings[11])); + } + + ret = dupcat("-", strings[ 0], "-", strings[ 1], "-", strings[ 2], + "-", strings[ 3], "-", strings[ 4], "-", strings[ 5], + "-", strings[ 6], "-", strings[ 7], "-", strings[ 8], + "-", strings[ 9], "-", strings[10], "-", strings[11], + "-", strings[12], NULL); + sfree(extrafree); + sfree(dupname); + + return ret; + } + } + return NULL; +} + void setup_fonts_ucs(struct gui_data *inst) { int font_charset; + char *name; + int guessed; if (inst->fonts[0]) gdk_font_unref(inst->fonts[0]); @@ -2408,36 +2466,70 @@ void setup_fonts_ucs(struct gui_data *inst) 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); - } + name = inst->cfg.boldfont.name; + guessed = FALSE; + } else { + name = guess_derived_font_name(inst->fonts[0], TRUE, FALSE); + guessed = TRUE; + } + inst->fonts[1] = name ? gdk_font_load(name) : NULL; + if (inst->fonts[1]) { set_font_info(inst, 1); - } else - inst->fonts[1] = NULL; + } else if (!guessed) { + fprintf(stderr, "%s: unable to load bold font \"%s\"\n", appname, + inst->cfg.boldfont.name); + exit(1); + } + if (guessed) + sfree(name); + 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); - } + name = inst->cfg.widefont.name; + guessed = FALSE; + } else { + name = guess_derived_font_name(inst->fonts[0], FALSE, TRUE); + guessed = TRUE; + } + inst->fonts[2] = name ? gdk_font_load(name) : NULL; + if (inst->fonts[2]) { set_font_info(inst, 2); - } else - inst->fonts[2] = NULL; + } else if (!guessed) { + fprintf(stderr, "%s: unable to load wide font \"%s\"\n", appname, + inst->cfg.widefont.name); + exit(1); + } + if (guessed) + sfree(name); + 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); - } + name = inst->cfg.wideboldfont.name; + guessed = FALSE; + } else { + /* + * Here we have some choices. We can widen the bold font, + * bolden the wide font, or widen and bolden the standard + * font. Try them all, in that order! + */ + if (inst->cfg.widefont.name[0]) + name = guess_derived_font_name(inst->fonts[2], TRUE, FALSE); + else if (inst->cfg.boldfont.name[0]) + name = guess_derived_font_name(inst->fonts[1], FALSE, TRUE); + else + name = guess_derived_font_name(inst->fonts[0], TRUE, TRUE); + guessed = TRUE; + } + inst->fonts[3] = name ? gdk_font_load(name) : NULL; + if (inst->fonts[3]) { set_font_info(inst, 3); - } else - inst->fonts[3] = NULL; + } else if (!guessed) { + fprintf(stderr, "%s: unable to load wide/bold font \"%s\"\n", appname, + inst->cfg.wideboldfont.name); + exit(1); + } + if (guessed) + sfree(name); inst->font_width = gdk_char_width(inst->fonts[0], ' '); inst->font_height = inst->fonts[0]->ascent + inst->fonts[0]->descent; @@ -2546,10 +2638,21 @@ void change_settings_menuitem(GtkMenuItem *item, gpointer data) 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]) + 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 default background has changed, we must + * repaint the space in between the window border + * and the text area. + */ + if (i == 18) { + set_window_background(inst); + draw_backing_rect(inst); + } + } } /* @@ -2610,6 +2713,12 @@ void change_settings_menuitem(GtkMenuItem *item, gpointer data) } term_invalidate(inst->term); + + /* + * We do an explicit full redraw here to ensure the window + * border has been redrawn as well as the text area. + */ + gtk_widget_queue_draw(inst->area); } sfree(title); }