X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=unix%2Fgtkfont.c;h=2f7e4a6172e96eb2b87cd6b92777befcd3732716;hb=984fe3dde809681f91d72152a4f96e91d79a2855;hp=e2a637828c9bef02e7679eaa6d109ac53182e5c2;hpb=f750a185873eba65f0fbb95dce204b0941f3cc25;p=PuTTY.git diff --git a/unix/gtkfont.c b/unix/gtkfont.c index e2a63782..2f7e4a61 100644 --- a/unix/gtkfont.c +++ b/unix/gtkfont.c @@ -12,10 +12,20 @@ #include #include #include + #include #if !GTK_CHECK_VERSION(3,0,0) #include #endif + +#define MAY_REFER_TO_GTK_IN_HEADERS + +#include "putty.h" +#include "gtkfont.h" +#include "gtkcompat.h" +#include "gtkmisc.h" +#include "tree234.h" + #ifndef NOT_X_WINDOWS #include #include @@ -23,26 +33,12 @@ #include #endif -#include "putty.h" -#include "gtkfont.h" -#include "tree234.h" - /* * Future work: * * - it would be nice to have a display of the current font name, * and in particular whether it's client- or server-side, * during the progress of the font selector. - * - * - it would be nice if we could move the processing of - * underline and VT100 double width into this module, so that - * instead of using the ghastly pixmap-stretching technique - * everywhere we could tell the Pango backend to scale its - * fonts to double size properly and at full resolution. - * However, this requires me to learn how to make Pango stretch - * text to an arbitrary aspect ratio (for double-width only - * text, which perversely is harder than DW+DH), and right now - * I haven't the energy. */ #if !GLIB_CHECK_VERSION(1,3,7) @@ -87,6 +83,9 @@ struct unifont_vtable { void (*draw_text)(unifont_drawctx *ctx, unifont *font, int x, int y, const wchar_t *string, int len, int wide, int bold, int cellwidth); + void (*draw_combining)(unifont_drawctx *ctx, unifont *font, + int x, int y, const wchar_t *string, int len, + int wide, int bold, int cellwidth); void (*enum_fonts)(GtkWidget *widget, fontsel_add_entry callback, void *callback_ctx); char *(*canonify_fontname)(GtkWidget *widget, const char *name, int *size, @@ -111,6 +110,9 @@ static int x11font_has_glyph(unifont *font, wchar_t glyph); static void x11font_draw_text(unifont_drawctx *ctx, unifont *font, int x, int y, const wchar_t *string, int len, int wide, int bold, int cellwidth); +static void x11font_draw_combining(unifont_drawctx *ctx, unifont *font, + int x, int y, const wchar_t *string, + int len, int wide, int bold, int cellwidth); static unifont *x11font_create(GtkWidget *widget, const char *name, int wide, int bold, int shadowoffset, int shadowalways); @@ -210,6 +212,7 @@ static const struct unifont_vtable x11font_vtable = { x11font_destroy, x11font_has_glyph, x11font_draw_text, + x11font_draw_combining, x11font_enum_fonts, x11font_canonify_fontname, x11font_scale_fontname, @@ -218,7 +221,7 @@ static const struct unifont_vtable x11font_vtable = { static char *x11_guess_derived_font_name(XFontStruct *xfs, int bold, int wide) { - Display *disp = GDK_DISPLAY(); + Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); Atom fontprop = XInternAtom(disp, "FONT", False); unsigned long ret; if (XGetFontProperty(xfs, fontprop, &ret)) { @@ -349,7 +352,7 @@ static unifont *x11font_create(GtkWidget *widget, const char *name, { struct x11font *xfont; XFontStruct *xfs; - Display *disp = GDK_DISPLAY(); + Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); Atom charset_registry, charset_encoding, spacing; unsigned long registry_ret, encoding_ret, spacing_ret; int pubcs, realcs, sixteen_bit, variable; @@ -455,7 +458,7 @@ static unifont *x11font_create(GtkWidget *widget, const char *name, static void x11font_destroy(unifont *font) { - Display *disp = GDK_DISPLAY(); + Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); struct x11font *xfont = (struct x11font *)font; int i; @@ -482,7 +485,7 @@ static void x11font_destroy(unifont *font) static void x11_alloc_subfont(struct x11font *xfont, int sfid) { - Display *disp = GDK_DISPLAY(); + Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); char *derived_name = x11_guess_derived_font_name (xfont->fonts[0].xfs, sfid & 1, !!(sfid & 2)); xfont->fonts[sfid].xfs = XLoadQueryFont(disp, derived_name); @@ -520,6 +523,8 @@ static int x11font_has_glyph(unifont *font, wchar_t glyph) #if !GTK_CHECK_VERSION(2,0,0) #define GDK_DRAWABLE_XID(d) GDK_WINDOW_XWINDOW(d) /* GTK1's name for this */ +#elif GTK_CHECK_VERSION(3,0,0) +#define GDK_DRAWABLE_XID(d) GDK_WINDOW_XID(d) /* GTK3's name for this */ #endif static int x11font_width_16(unifont_drawctx *ctx, x11font_individual *xfi, @@ -539,15 +544,17 @@ static int x11font_width_8(unifont_drawctx *ctx, x11font_individual *xfi, #ifdef DRAW_TEXT_GDK static void x11font_gdk_setup(unifont_drawctx *ctx, x11font_individual *xfi) { - XSetFont(GDK_DISPLAY(), GDK_GC_XGC(ctx->u.gdk.gc), xfi->xfs->fid); + Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); + XSetFont(disp, GDK_GC_XGC(ctx->u.gdk.gc), xfi->xfs->fid); } static void x11font_gdk_draw_16(unifont_drawctx *ctx, x11font_individual *xfi, int x, int y, const void *vstring, int start, int length) { + Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); const XChar2b *string = (const XChar2b *)vstring; - XDrawString16(GDK_DISPLAY(), GDK_DRAWABLE_XID(ctx->u.gdk.target), + XDrawString16(disp, GDK_DRAWABLE_XID(ctx->u.gdk.target), GDK_GC_XGC(ctx->u.gdk.gc), x, y, string+start, length); } @@ -555,8 +562,9 @@ static void x11font_gdk_draw_8(unifont_drawctx *ctx, x11font_individual *xfi, int x, int y, const void *vstring, int start, int length) { + Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); const char *string = (const char *)vstring; - XDrawString(GDK_DISPLAY(), GDK_DRAWABLE_XID(ctx->u.gdk.target), + XDrawString(disp, GDK_DRAWABLE_XID(ctx->u.gdk.target), GDK_GC_XGC(ctx->u.gdk.gc), x, y, string+start, length); } #endif @@ -565,6 +573,7 @@ static void x11font_gdk_draw_8(unifont_drawctx *ctx, static void x11font_cairo_setup(unifont_drawctx *ctx, x11font_individual *xfi) { if (xfi->pixmap == None) { + Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); XGCValues gcvals; GdkWindow *widgetwin = gtk_widget_get_window(ctx->u.cairo.widget); int widgetscr = GDK_SCREEN_XNUMBER(gdk_window_get_screen(widgetwin)); @@ -597,13 +606,13 @@ static void x11font_cairo_setup(unifont_drawctx *ctx, x11font_individual *xfi) } xfi->pixmap = XCreatePixmap - (GDK_DISPLAY(), + (disp, GDK_DRAWABLE_XID(gtk_widget_get_window(ctx->u.cairo.widget)), xfi->pixwidth, xfi->pixheight, 1); - gcvals.foreground = WhitePixel(GDK_DISPLAY(), widgetscr); - gcvals.background = BlackPixel(GDK_DISPLAY(), widgetscr); + gcvals.foreground = WhitePixel(disp, widgetscr); + gcvals.background = BlackPixel(disp, widgetscr); gcvals.font = xfi->xfs->fid; - xfi->gc = XCreateGC(GDK_DISPLAY(), xfi->pixmap, + xfi->gc = XCreateGC(disp, xfi->pixmap, GCForeground | GCBackground | GCFont, &gcvals); } } @@ -613,11 +622,12 @@ static void x11font_cairo_cache_glyph(x11font_individual *xfi, int glyphindex) XImage *image; int x, y; unsigned char *bitmap; + Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); bitmap = snewn(xfi->allsize, unsigned char); memset(bitmap, 0, xfi->allsize); - image = XGetImage(GDK_DISPLAY(), xfi->pixmap, 0, 0, + image = XGetImage(disp, xfi->pixmap, 0, 0, xfi->pixwidth, xfi->pixheight, AllPlanes, XYPixmap); for (y = 0; y < xfi->pixheight; y++) { for (x = 0; x < xfi->pixwidth; x++) { @@ -636,7 +646,7 @@ static void x11font_cairo_cache_glyph(x11font_individual *xfi, int glyphindex) * principle that Unicode characters come in contiguous blocks * often used together */ int old_nglyphs = xfi->nglyphs; - xfi->nglyphs = (glyphindex + 0xFF) & ~0xFF; + xfi->nglyphs = (glyphindex + 0x100) & ~0xFF; xfi->glyphcache = sresize(xfi->glyphcache, xfi->nglyphs, struct cairo_cached_glyph); @@ -666,6 +676,7 @@ static void x11font_cairo_draw_16(unifont_drawctx *ctx, x11font_individual *xfi, int x, int y, const void *vstring, int start, int length) { + Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); const XChar2b *string = (const XChar2b *)vstring + start; int i; for (i = 0; i < length; i++) { @@ -674,7 +685,7 @@ static void x11font_cairo_draw_16(unifont_drawctx *ctx, (unsigned char)string[i].byte2); if (glyphindex >= xfi->nglyphs || !xfi->glyphcache[glyphindex].surface) { - XDrawImageString16(GDK_DISPLAY(), xfi->pixmap, xfi->gc, + XDrawImageString16(disp, xfi->pixmap, xfi->gc, xfi->pixoriginx, xfi->pixoriginy, string+i, 1); x11font_cairo_cache_glyph(xfi, glyphindex); @@ -689,6 +700,7 @@ static void x11font_cairo_draw_8(unifont_drawctx *ctx, x11font_individual *xfi, int x, int y, const void *vstring, int start, int length) { + Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); const char *string = (const char *)vstring + start; int i; for (i = 0; i < length; i++) { @@ -696,7 +708,7 @@ static void x11font_cairo_draw_8(unifont_drawctx *ctx, int glyphindex = (unsigned char)string[i]; if (glyphindex >= xfi->nglyphs || !xfi->glyphcache[glyphindex].surface) { - XDrawImageString(GDK_DISPLAY(), xfi->pixmap, xfi->gc, + XDrawImageString(disp, xfi->pixmap, xfi->gc, xfi->pixoriginx, xfi->pixoriginy, string+i, 1); x11font_cairo_cache_glyph(xfi, glyphindex); @@ -863,16 +875,31 @@ static void x11font_draw_text(unifont_drawctx *ctx, unifont *font, } } +static void x11font_draw_combining(unifont_drawctx *ctx, unifont *font, + int x, int y, const wchar_t *string, + int len, int wide, int bold, int cellwidth) +{ + /* + * For server-side fonts, there's no sophisticated system for + * combining characters intelligently, so the best we can do is to + * overprint them on each other in the obvious way. + */ + int i; + for (i = 0; i < len; i++) + x11font_draw_text(ctx, font, x, y, string+i, 1, wide, bold, cellwidth); +} + static void x11font_enum_fonts(GtkWidget *widget, fontsel_add_entry callback, void *callback_ctx) { + Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); char **fontnames; char *tmp = NULL; int nnames, i, max, tmpsize; max = 32768; while (1) { - fontnames = XListFonts(GDK_DISPLAY(), "*", max, &nnames); + fontnames = XListFonts(disp, "*", max, &nnames); if (nnames >= max) { XFreeFontNames(fontnames); max *= 2; @@ -1047,7 +1074,7 @@ static char *x11font_canonify_fontname(GtkWidget *widget, const char *name, * selector treats them as worthwhile in their own right. */ XFontStruct *xfs; - Display *disp = GDK_DISPLAY(); + Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()); Atom fontprop, fontprop2; unsigned long ret; @@ -1106,6 +1133,10 @@ static int pangofont_has_glyph(unifont *font, wchar_t glyph); static void pangofont_draw_text(unifont_drawctx *ctx, unifont *font, int x, int y, const wchar_t *string, int len, int wide, int bold, int cellwidth); +static void pangofont_draw_combining(unifont_drawctx *ctx, unifont *font, + int x, int y, const wchar_t *string, + int len, int wide, int bold, + int cellwidth); static unifont *pangofont_create(GtkWidget *widget, const char *name, int wide, int bold, int shadowoffset, int shadowalways); @@ -1136,6 +1167,13 @@ struct pangofont { * Data passed in to unifont_create(). */ int bold, shadowoffset, shadowalways; + /* + * Cache of character widths, indexed by Unicode code point. In + * pixels; -1 means we haven't asked Pango about this character + * before. + */ + int *widthcache; + unsigned nwidthcache; }; static const struct unifont_vtable pangofont_vtable = { @@ -1144,6 +1182,7 @@ static const struct unifont_vtable pangofont_vtable = { pangofont_destroy, pangofont_has_glyph, pangofont_draw_text, + pangofont_draw_combining, pangofont_enum_fonts, pangofont_canonify_fontname, pangofont_scale_fontname, @@ -1259,6 +1298,8 @@ static unifont *pangofont_create_internal(GtkWidget *widget, pfont->bold = bold; pfont->shadowoffset = shadowoffset; pfont->shadowalways = shadowalways; + pfont->widthcache = NULL; + pfont->nwidthcache = 0; pango_font_metrics_unref(metrics); @@ -1312,10 +1353,40 @@ static void pangofont_destroy(unifont *font) { struct pangofont *pfont = (struct pangofont *)font; pango_font_description_free(pfont->desc); + sfree(pfont->widthcache); g_object_unref(pfont->fset); sfree(font); } +static int pangofont_char_width(PangoLayout *layout, struct pangofont *pfont, + wchar_t uchr, const char *utfchr, int utflen) +{ + /* + * Here we check whether a character has the same width as the + * character cell it'll be drawn in. Because profiling showed that + * asking Pango for text sizes was a huge bottleneck when we were + * calling it every time we needed to know this, we instead call + * it only on characters we don't already know about, and cache + * the results. + */ + + if ((unsigned)uchr >= pfont->nwidthcache) { + unsigned newsize = ((int)uchr + 0x100) & ~0xFF; + pfont->widthcache = sresize(pfont->widthcache, newsize, int); + while (pfont->nwidthcache < newsize) + pfont->widthcache[pfont->nwidthcache++] = -1; + } + + if (pfont->widthcache[uchr] < 0) { + PangoRectangle rect; + pango_layout_set_text(layout, utfchr, utflen); + pango_layout_get_extents(layout, NULL, &rect); + pfont->widthcache[uchr] = rect.width; + } + + return pfont->widthcache[uchr]; +} + static int pangofont_has_glyph(unifont *font, wchar_t glyph) { /* Pango implements font fallback, so assume it has everything */ @@ -1339,9 +1410,10 @@ static void pango_cairo_draw_layout(unifont_drawctx *ctx, } #endif -static void pangofont_draw_text(unifont_drawctx *ctx, unifont *font, - int x, int y, const wchar_t *string, int len, - int wide, int bold, int cellwidth) +static void pangofont_draw_internal(unifont_drawctx *ctx, unifont *font, + int x, int y, const wchar_t *string, + int len, int wide, int bold, int cellwidth, + int combining) { struct pangofont *pfont = (struct pangofont *)font; PangoLayout *layout; @@ -1392,6 +1464,7 @@ static void pangofont_draw_text(unifont_drawctx *ctx, unifont *font, utfptr = utfstring; while (utflen > 0) { int clen, n; + int desired = cellwidth * PANGO_SCALE; /* * We want to display every character from this string in @@ -1417,34 +1490,39 @@ static void pangofont_draw_text(unifont_drawctx *ctx, unifont *font, * them to do that. */ - /* - * Start by extracting a single UTF-8 character from the - * string. - */ - clen = 1; - while (clen < utflen && - (unsigned char)utfptr[clen] >= 0x80 && - (unsigned char)utfptr[clen] < 0xC0) - clen++; - n = 1; - - /* - * If it's a right-to-left character, we must display it on - * its own, to stop Pango helpfully re-reversing our already - * reversed text. - */ - if (!is_rtl(string[0])) { - + if (combining) { /* - * See if that character has the width we expect. + * For a character with combining stuff, we just dump the + * whole lot in one go, and expect it to take up just one + * character cell. */ - pango_layout_set_text(layout, utfptr, clen); - pango_layout_get_pixel_extents(layout, NULL, &rect); - - if (rect.width == cellwidth) { + clen = utflen; + n = 1; + } else { + /* + * Start by extracting a single UTF-8 character from the + * string. + */ + clen = 1; + while (clen < utflen && + (unsigned char)utfptr[clen] >= 0x80 && + (unsigned char)utfptr[clen] < 0xC0) + clen++; + n = 1; + + if (is_rtl(string[0]) || + pangofont_char_width(layout, pfont, string[n-1], + utfptr, clen) != desired) { + /* + * If this character is a right-to-left one, or has an + * unusual width, then we must display it on its own. + */ + } else { /* - * Try extracting more characters, for as long as they - * stay well-behaved. + * Try to amalgamate a contiguous string of characters + * with the expected sensible width, for the common case + * in which we're using a monospaced font and everything + * works as expected. */ while (clen < utflen) { int oldclen = clen; @@ -1454,9 +1532,9 @@ static void pangofont_draw_text(unifont_drawctx *ctx, unifont *font, (unsigned char)utfptr[clen] < 0xC0) clen++; n++; - pango_layout_set_text(layout, utfptr, clen); - pango_layout_get_pixel_extents(layout, NULL, &rect); - if (rect.width != n * cellwidth) { + if (pangofont_char_width(layout, pfont, + string[n-1], utfptr + oldclen, + clen - oldclen) != desired) { clen = oldclen; n--; break; @@ -1487,6 +1565,37 @@ static void pangofont_draw_text(unifont_drawctx *ctx, unifont *font, g_object_unref(layout); } +static void pangofont_draw_text(unifont_drawctx *ctx, unifont *font, + int x, int y, const wchar_t *string, int len, + int wide, int bold, int cellwidth) +{ + pangofont_draw_internal(ctx, font, x, y, string, len, wide, bold, + cellwidth, FALSE); +} + +static void pangofont_draw_combining(unifont_drawctx *ctx, unifont *font, + int x, int y, const wchar_t *string, + int len, int wide, int bold, + int cellwidth) +{ + wchar_t *tmpstring = NULL; + if (mk_wcwidth(string[0]) == 0) { + /* + * If we've been told to draw a sequence of _only_ combining + * characters, prefix a space so that they have something to + * combine with. + */ + tmpstring = snewn(len+1, wchar_t); + memcpy(tmpstring+1, string, len * sizeof(wchar_t)); + tmpstring[0] = L' '; + string = tmpstring; + len++; + } + pangofont_draw_internal(ctx, font, x, y, string, len, wide, bold, + cellwidth, TRUE); + sfree(tmpstring); +} + /* * Dummy size value to be used when converting a * PangoFontDescription of a scalable font to a string for @@ -1832,6 +1941,14 @@ void unifont_draw_text(unifont_drawctx *ctx, unifont *font, font->vt->draw_text(ctx, font, x, y, string, len, wide, bold, cellwidth); } +void unifont_draw_combining(unifont_drawctx *ctx, unifont *font, + int x, int y, const wchar_t *string, int len, + int wide, int bold, int cellwidth) +{ + font->vt->draw_combining(ctx, font, x, y, string, len, wide, bold, + cellwidth); +} + /* ---------------------------------------------------------------------- * Multiple-font wrapper. This is a type of unifont which encapsulates * up to two other unifonts, permitting missing glyphs in the main @@ -1848,6 +1965,10 @@ void unifont_draw_text(unifont_drawctx *ctx, unifont *font, static void multifont_draw_text(unifont_drawctx *ctx, unifont *font, int x, int y, const wchar_t *string, int len, int wide, int bold, int cellwidth); +static void multifont_draw_combining(unifont_drawctx *ctx, unifont *font, + int x, int y, const wchar_t *string, + int len, int wide, int bold, + int cellwidth); static void multifont_destroy(unifont *font); struct multifont { @@ -1862,6 +1983,7 @@ static const struct unifont_vtable multifont_vtable = { multifont_destroy, NULL, multifont_draw_text, + multifont_draw_combining, NULL, NULL, NULL, @@ -1922,9 +2044,15 @@ static void multifont_destroy(unifont *font) sfree(font); } -static void multifont_draw_text(unifont_drawctx *ctx, unifont *font, int x, +typedef void (*unifont_draw_func_t)(unifont_drawctx *ctx, unifont *font, + int x, int y, const wchar_t *string, + int len, int wide, int bold, + int cellwidth); + +static void multifont_draw_main(unifont_drawctx *ctx, unifont *font, int x, int y, const wchar_t *string, int len, - int wide, int bold, int cellwidth) + int wide, int bold, int cellwidth, + int cellinc, unifont_draw_func_t draw) { struct multifont *mfont = (struct multifont *)font; unifont *f; @@ -1946,13 +2074,30 @@ static void multifont_draw_text(unifont_drawctx *ctx, unifont *font, int x, */ f = ok ? mfont->main : mfont->fallback; if (f) - unifont_draw_text(ctx, f, x, y, string, i, wide, bold, cellwidth); + draw(ctx, f, x, y, string, i, wide, bold, cellwidth); string += i; len -= i; - x += i * cellwidth; + x += i * cellinc; } } +static void multifont_draw_text(unifont_drawctx *ctx, unifont *font, int x, + int y, const wchar_t *string, int len, + int wide, int bold, int cellwidth) +{ + multifont_draw_main(ctx, font, x, y, string, len, wide, bold, + cellwidth, cellwidth, unifont_draw_text); +} + +static void multifont_draw_combining(unifont_drawctx *ctx, unifont *font, + int x, int y, const wchar_t *string, + int len, int wide, int bold, + int cellwidth) +{ + multifont_draw_main(ctx, font, x, y, string, len, wide, bold, + cellwidth, 0, unifont_draw_combining); +} + #if GTK_CHECK_VERSION(2,0,0) /* ---------------------------------------------------------------------- @@ -1970,7 +2115,9 @@ typedef struct unifontsel_internal { GtkWidget *filter_buttons[4]; int n_filter_buttons; GtkWidget *preview_area; +#ifndef NO_BACKING_PIXMAPS GdkPixmap *preview_pixmap; +#endif int preview_width, preview_height; GdkColor preview_fg, preview_bg; int filter_flags; @@ -2089,6 +2236,8 @@ static int fontinfo_selorder_compare(void *av, void *bv) return 0; } +static void unifontsel_draw_preview_text(unifontsel_internal *fs); + static void unifontsel_deselect(unifontsel_internal *fs) { fs->selected = NULL; @@ -2096,6 +2245,7 @@ static void unifontsel_deselect(unifontsel_internal *fs) gtk_list_store_clear(fs->size_model); gtk_widget_set_sensitive(fs->u.ok_button, FALSE); gtk_widget_set_sensitive(fs->size_entry, FALSE); + unifontsel_draw_preview_text(fs); } static void unifontsel_setup_familylist(unifontsel_internal *fs) @@ -2106,6 +2256,8 @@ static void unifontsel_setup_familylist(unifontsel_internal *fs) int currflags = -1; fontinfo *info; + fs->inhibit_response = TRUE; + gtk_list_store_clear(fs->family_model); listindex = 0; @@ -2156,6 +2308,8 @@ static void unifontsel_setup_familylist(unifontsel_internal *fs) */ if (fs->selected && fs->selected->familyindex < 0) unifontsel_deselect(fs); + + fs->inhibit_response = FALSE; } static void unifontsel_setup_stylelist(unifontsel_internal *fs, @@ -2201,7 +2355,7 @@ static void unifontsel_setup_stylelist(unifontsel_internal *fs, gtk_list_store_append(fs->style_model, &iter); gtk_list_store_set(fs->style_model, &iter, 0, currstyle, 1, minpos, 2, maxpos+1, - 3, TRUE, -1); + 3, TRUE, 4, PANGO_WEIGHT_NORMAL, -1); listindex++; } if (info) { @@ -2210,7 +2364,7 @@ static void unifontsel_setup_stylelist(unifontsel_internal *fs, gtk_list_store_append(fs->style_model, &iter); gtk_list_store_set(fs->style_model, &iter, 0, info->charset, 1, -1, 2, -1, - 3, FALSE, -1); + 3, FALSE, 4, PANGO_WEIGHT_BOLD, -1); listindex++; } currcs = info->charset; @@ -2285,7 +2439,8 @@ static void unifontsel_set_filter_buttons(unifontsel_internal *fs) } } -static void unifontsel_draw_preview_text(unifontsel_internal *fs) +static void unifontsel_draw_preview_text_inner(unifont_drawctx *dctx, + unifontsel_internal *fs) { unifont *font; char *sizename = NULL; @@ -2300,100 +2455,123 @@ static void unifontsel_draw_preview_text(unifontsel_internal *fs) } else font = NULL; - if (fs->preview_pixmap) { - unifont_drawctx dctx; - dctx.type = DRAWTYPE_DEFAULT; #ifdef DRAW_TEXT_GDK - if (dctx.type == DRAWTYPE_GDK) { - dctx.u.gdk.target = fs->preview_pixmap; - dctx.u.gdk.gc = gdk_gc_new(fs->preview_pixmap); - gdk_gc_set_foreground(dctx.u.gdk.gc, &fs->preview_bg); - gdk_draw_rectangle(fs->preview_pixmap, dctx.u.gdk.gc, 1, 0, 0, - fs->preview_width, fs->preview_height); - gdk_gc_set_foreground(dctx.u.gdk.gc, &fs->preview_fg); - } + if (dctx->type == DRAWTYPE_GDK) { + gdk_gc_set_foreground(dctx->u.gdk.gc, &fs->preview_bg); + gdk_draw_rectangle(dctx->u.gdk.target, dctx->u.gdk.gc, 1, 0, 0, + fs->preview_width, fs->preview_height); + gdk_gc_set_foreground(dctx->u.gdk.gc, &fs->preview_fg); + } #endif #ifdef DRAW_TEXT_CAIRO - if (dctx.type == DRAWTYPE_CAIRO) { - dctx.u.cairo.widget = GTK_WIDGET(fs->preview_area); - dctx.u.cairo.cr = gdk_cairo_create(fs->preview_pixmap); - cairo_set_source_rgb(dctx.u.cairo.cr, - fs->preview_bg.red / 65535.0, - fs->preview_bg.green / 65535.0, - fs->preview_bg.blue / 65535.0); - cairo_paint(dctx.u.cairo.cr); - cairo_set_source_rgb(dctx.u.cairo.cr, - fs->preview_fg.red / 65535.0, - fs->preview_fg.green / 65535.0, - fs->preview_fg.blue / 65535.0); - } + if (dctx->type == DRAWTYPE_CAIRO) { + cairo_set_source_rgb(dctx->u.cairo.cr, + fs->preview_bg.red / 65535.0, + fs->preview_bg.green / 65535.0, + fs->preview_bg.blue / 65535.0); + cairo_paint(dctx->u.cairo.cr); + cairo_set_source_rgb(dctx->u.cairo.cr, + fs->preview_fg.red / 65535.0, + fs->preview_fg.green / 65535.0, + fs->preview_fg.blue / 65535.0); + } #endif - if (font) { - /* - * The pangram used here is rather carefully - * constructed: it contains a sequence of very narrow - * letters (`jil') and a pair of adjacent very wide - * letters (`wm'). - * - * If the user selects a proportional font, it will be - * coerced into fixed-width character cells when used - * in the actual terminal window. We therefore display - * it the same way in the preview pane, so as to show - * it the way it will actually be displayed - and we - * deliberately pick a pangram which will show the - * resulting miskerning at its worst. - * - * We aren't trying to sell people these fonts; we're - * trying to let them make an informed choice. Better - * that they find out the problems with using - * proportional fonts in terminal windows here than - * that they go to the effort of selecting their font - * and _then_ realise it was a mistake. - */ - info->fontclass->draw_text(&dctx, font, - 0, font->ascent, - L"bankrupt jilted showmen quiz convex fogey", - 41, FALSE, FALSE, font->width); - info->fontclass->draw_text(&dctx, font, - 0, font->ascent + font->height, - L"BANKRUPT JILTED SHOWMEN QUIZ CONVEX FOGEY", - 41, FALSE, FALSE, font->width); - /* - * The ordering of punctuation here is also selected - * with some specific aims in mind. I put ` and ' - * together because some software (and people) still - * use them as matched quotes no matter what Unicode - * might say on the matter, so people can quickly - * check whether they look silly in a candidate font. - * The sequence #_@ is there to let people judge the - * suitability of the underscore as an effectively - * alphabetic character (since that's how it's often - * used in practice, at least by programmers). - */ - info->fontclass->draw_text(&dctx, font, - 0, font->ascent + font->height * 2, - L"0123456789!?,.:;<>()[]{}\\/`'\"+*-=~#_@|%&^$", - 42, FALSE, FALSE, font->width); - } + if (font) { + /* + * The pangram used here is rather carefully + * constructed: it contains a sequence of very narrow + * letters (`jil') and a pair of adjacent very wide + * letters (`wm'). + * + * If the user selects a proportional font, it will be + * coerced into fixed-width character cells when used + * in the actual terminal window. We therefore display + * it the same way in the preview pane, so as to show + * it the way it will actually be displayed - and we + * deliberately pick a pangram which will show the + * resulting miskerning at its worst. + * + * We aren't trying to sell people these fonts; we're + * trying to let them make an informed choice. Better + * that they find out the problems with using + * proportional fonts in terminal windows here than + * that they go to the effort of selecting their font + * and _then_ realise it was a mistake. + */ + info->fontclass->draw_text(dctx, font, + 0, font->ascent, + L"bankrupt jilted showmen quiz convex fogey", + 41, FALSE, FALSE, font->width); + info->fontclass->draw_text(dctx, font, + 0, font->ascent + font->height, + L"BANKRUPT JILTED SHOWMEN QUIZ CONVEX FOGEY", + 41, FALSE, FALSE, font->width); + /* + * The ordering of punctuation here is also selected + * with some specific aims in mind. I put ` and ' + * together because some software (and people) still + * use them as matched quotes no matter what Unicode + * might say on the matter, so people can quickly + * check whether they look silly in a candidate font. + * The sequence #_@ is there to let people judge the + * suitability of the underscore as an effectively + * alphabetic character (since that's how it's often + * used in practice, at least by programmers). + */ + info->fontclass->draw_text(dctx, font, + 0, font->ascent + font->height * 2, + L"0123456789!?,.:;<>()[]{}\\/`'\"+*-=~#_@|%&^$", + 42, FALSE, FALSE, font->width); + + info->fontclass->destroy(font); + } + + sfree(sizename); +} + +static void unifontsel_draw_preview_text(unifontsel_internal *fs) +{ + unifont_drawctx dctx; + GdkWindow *target; + +#ifndef NO_BACKING_PIXMAPS + target = fs->preview_pixmap; +#else + target = gtk_widget_get_window(fs->preview_area); +#endif + if (!target) /* we may be called when we haven't created everything yet */ + return; + + dctx.type = DRAWTYPE_DEFAULT; #ifdef DRAW_TEXT_GDK - if (dctx.type == DRAWTYPE_GDK) { - gdk_gc_unref(dctx.u.gdk.gc); - } + if (dctx.type == DRAWTYPE_GDK) { + dctx.u.gdk.target = target; + dctx.u.gdk.gc = gdk_gc_new(target); + } #endif #ifdef DRAW_TEXT_CAIRO - if (dctx.type == DRAWTYPE_CAIRO) { - cairo_destroy(dctx.u.cairo.cr); - } + if (dctx.type == DRAWTYPE_CAIRO) { + dctx.u.cairo.widget = GTK_WIDGET(fs->preview_area); + dctx.u.cairo.cr = gdk_cairo_create(target); + } #endif - gdk_window_invalidate_rect(gtk_widget_get_window(fs->preview_area), - NULL, FALSE); + unifontsel_draw_preview_text_inner(&dctx, fs); + +#ifdef DRAW_TEXT_GDK + if (dctx.type == DRAWTYPE_GDK) { + gdk_gc_unref(dctx.u.gdk.gc); } - if (font) - info->fontclass->destroy(font); +#endif +#ifdef DRAW_TEXT_CAIRO + if (dctx.type == DRAWTYPE_CAIRO) { + cairo_destroy(dctx.u.cairo.cr); + } +#endif - sfree(sizename); + gdk_window_invalidate_rect(gtk_widget_get_window(fs->preview_area), + NULL, FALSE); } static void unifontsel_select_font(unifontsel_internal *fs, @@ -2402,6 +2580,7 @@ static void unifontsel_select_font(unifontsel_internal *fs, { int index; int minval, maxval; + gboolean success; GtkTreePath *treepath; GtkTreeIter iter; @@ -2442,7 +2621,9 @@ static void unifontsel_select_font(unifontsel_internal *fs, treepath); gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(fs->family_list), treepath, NULL, FALSE, 0.0, 0.0); - gtk_tree_model_get_iter(GTK_TREE_MODEL(fs->family_model), &iter, treepath); + success = gtk_tree_model_get_iter(GTK_TREE_MODEL(fs->family_model), + &iter, treepath); + assert(success); gtk_tree_path_free(treepath); /* @@ -2816,11 +2997,26 @@ static void alias_resolve(GtkTreeView *treeview, GtkTreePath *path, } } +#if GTK_CHECK_VERSION(3,0,0) +static gint unifontsel_draw_area(GtkWidget *widget, cairo_t *cr, gpointer data) +{ + unifontsel_internal *fs = (unifontsel_internal *)data; + unifont_drawctx dctx; + + dctx.type = DRAWTYPE_CAIRO; + dctx.u.cairo.widget = widget; + dctx.u.cairo.cr = cr; + unifontsel_draw_preview_text_inner(&dctx, fs); + + return TRUE; +} +#else static gint unifontsel_expose_area(GtkWidget *widget, GdkEventExpose *event, gpointer data) { unifontsel_internal *fs = (unifontsel_internal *)data; +#ifndef NO_BACKING_PIXMAPS if (fs->preview_pixmap) { gdk_draw_pixmap(gtk_widget_get_window(widget), (gtk_widget_get_style(widget)->fg_gc @@ -2830,12 +3026,18 @@ static gint unifontsel_expose_area(GtkWidget *widget, GdkEventExpose *event, event->area.x, event->area.y, event->area.width, event->area.height); } +#else + unifontsel_draw_preview_text(fs); +#endif + return TRUE; } +#endif static gint unifontsel_configure_area(GtkWidget *widget, GdkEventConfigure *event, gpointer data) { +#ifndef NO_BACKING_PIXMAPS unifontsel_internal *fs = (unifontsel_internal *)data; int ox, oy, nx, ny, x, y; @@ -2859,6 +3061,7 @@ static gint unifontsel_configure_area(GtkWidget *widget, unifontsel_draw_preview_text(fs); } +#endif gdk_window_invalidate_rect(gtk_widget_get_window(widget), NULL, FALSE); @@ -2878,25 +3081,22 @@ unifontsel *unifontsel_new(const char *wintitle) fs->selected = NULL; { + int width, height; + /* * Invent some magic size constants. */ - GtkRequisition req; - label = gtk_label_new("Quite Long Font Name (Foundry)"); - gtk_widget_size_request(label, &req); - font_width = req.width; - lists_height = 14 * req.height; - preview_height = 5 * req.height; - gtk_label_set_text(GTK_LABEL(label), "Italic Extra Condensed"); - gtk_widget_size_request(label, &req); - style_width = req.width; - gtk_label_set_text(GTK_LABEL(label), "48000"); - gtk_widget_size_request(label, &req); - size_width = req.width; - g_object_ref_sink(G_OBJECT(label)); -#if GTK_CHECK_VERSION(2,10,0) - g_object_unref(label); -#endif + get_label_text_dimensions("Quite Long Font Name (Foundry)", + &width, &height); + font_width = width; + lists_height = 14 * height; + preview_height = 5 * height; + + get_label_text_dimensions("Italic Extra Condensed", &width, &height); + style_width = width; + + get_label_text_dimensions("48000", &width, &height); + size_width = width; } /* @@ -2907,35 +3107,53 @@ unifontsel *unifontsel_new(const char *wintitle) fs->u.window = GTK_WINDOW(gtk_dialog_new()); gtk_window_set_title(fs->u.window, wintitle); fs->u.cancel_button = gtk_dialog_add_button - (GTK_DIALOG(fs->u.window), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); + (GTK_DIALOG(fs->u.window), STANDARD_CANCEL_LABEL, GTK_RESPONSE_CANCEL); fs->u.ok_button = gtk_dialog_add_button - (GTK_DIALOG(fs->u.window), GTK_STOCK_OK, GTK_RESPONSE_OK); + (GTK_DIALOG(fs->u.window), STANDARD_OK_LABEL, GTK_RESPONSE_OK); gtk_widget_grab_default(fs->u.ok_button); /* * Now set up the internal fields, including in particular all * the controls that actually allow the user to select fonts. */ +#if GTK_CHECK_VERSION(3,0,0) + table = gtk_grid_new(); + gtk_grid_set_column_spacing(GTK_GRID(table), 8); +#else table = gtk_table_new(8, 3, FALSE); - gtk_widget_show(table); gtk_table_set_col_spacings(GTK_TABLE(table), 8); -#if GTK_CHECK_VERSION(2,4,0) +#endif + gtk_widget_show(table); + +#if GTK_CHECK_VERSION(3,0,0) + /* GtkAlignment has become deprecated and we use the "margin" + * property */ + w = table; + g_object_set(G_OBJECT(w), "margin", 8, (const char *)NULL); +#elif GTK_CHECK_VERSION(2,4,0) /* GtkAlignment seems to be the simplest way to put padding round things */ w = gtk_alignment_new(0, 0, 1, 1); gtk_alignment_set_padding(GTK_ALIGNMENT(w), 8, 8, 8, 8); gtk_container_add(GTK_CONTAINER(w), table); gtk_widget_show(w); #else + /* In GTK < 2.4, even that isn't available */ w = table; #endif + gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area (GTK_DIALOG(fs->u.window))), w, TRUE, TRUE, 0); label = gtk_label_new_with_mnemonic("_Font:"); gtk_widget_show(label); - gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0); + align_label_left(GTK_LABEL(label)); +#if GTK_CHECK_VERSION(3,0,0) + gtk_grid_attach(GTK_GRID(table), label, 0, 0, 1, 1); + g_object_set(G_OBJECT(label), "hexpand", TRUE, (const char *)NULL); +#else gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, GTK_FILL, 0, 0, 0); +#endif /* * The Font list box displays only a string, but additionally @@ -2965,30 +3183,42 @@ unifontsel *unifontsel_new(const char *wintitle) gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); gtk_widget_set_size_request(scroll, font_width, lists_height); +#if GTK_CHECK_VERSION(3,0,0) + gtk_grid_attach(GTK_GRID(table), scroll, 0, 1, 1, 2); + g_object_set(G_OBJECT(scroll), "expand", TRUE, (const char *)NULL); +#else gtk_table_attach(GTK_TABLE(table), scroll, 0, 1, 1, 3, GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); +#endif fs->family_model = model; fs->family_list = w; label = gtk_label_new_with_mnemonic("_Style:"); gtk_widget_show(label); - gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0); + align_label_left(GTK_LABEL(label)); +#if GTK_CHECK_VERSION(3,0,0) + gtk_grid_attach(GTK_GRID(table), label, 1, 0, 1, 1); + g_object_set(G_OBJECT(label), "hexpand", TRUE, (const char *)NULL); +#else gtk_table_attach(GTK_TABLE(table), label, 1, 2, 0, 1, GTK_FILL, 0, 0, 0); +#endif /* - * The Style list box can contain insensitive elements - * (character set headings for server-side fonts), so we add - * an extra column to the list store to hold that information. + * The Style list box can contain insensitive elements (character + * set headings for server-side fonts), so we add an extra column + * to the list store to hold that information. Also, since GTK3 at + * least doesn't seem to display insensitive elements differently + * by default, we add a further column to change their style. */ - model = gtk_list_store_new(4, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT, - G_TYPE_BOOLEAN); + model = gtk_list_store_new(5, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT, + G_TYPE_BOOLEAN, G_TYPE_INT); w = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model)); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(w), FALSE); gtk_label_set_mnemonic_widget(GTK_LABEL(label), w); gtk_widget_show(w); column = gtk_tree_view_column_new_with_attributes ("Style", gtk_cell_renderer_text_new(), - "text", 0, "sensitive", 3, (char *)NULL); + "text", 0, "sensitive", 3, "weight", 4, (char *)NULL); gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); gtk_tree_view_append_column(GTK_TREE_VIEW(w), column); g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(w))), @@ -3002,15 +3232,25 @@ unifontsel *unifontsel_new(const char *wintitle) gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); gtk_widget_set_size_request(scroll, style_width, lists_height); +#if GTK_CHECK_VERSION(3,0,0) + gtk_grid_attach(GTK_GRID(table), scroll, 1, 1, 1, 2); + g_object_set(G_OBJECT(scroll), "expand", TRUE, (const char *)NULL); +#else gtk_table_attach(GTK_TABLE(table), scroll, 1, 2, 1, 3, GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); +#endif fs->style_model = model; fs->style_list = w; label = gtk_label_new_with_mnemonic("Si_ze:"); gtk_widget_show(label); - gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0); + align_label_left(GTK_LABEL(label)); +#if GTK_CHECK_VERSION(3,0,0) + gtk_grid_attach(GTK_GRID(table), label, 2, 0, 1, 1); + g_object_set(G_OBJECT(label), "hexpand", TRUE, (const char *)NULL); +#else gtk_table_attach(GTK_TABLE(table), label, 2, 3, 0, 1, GTK_FILL, 0, 0, 0); +#endif /* * The Size label attaches primarily to a text input box so @@ -3021,7 +3261,12 @@ unifontsel *unifontsel_new(const char *wintitle) gtk_label_set_mnemonic_widget(GTK_LABEL(label), w); gtk_widget_set_size_request(w, size_width, -1); gtk_widget_show(w); +#if GTK_CHECK_VERSION(3,0,0) + gtk_grid_attach(GTK_GRID(table), w, 2, 1, 1, 1); + g_object_set(G_OBJECT(w), "hexpand", TRUE, (const char *)NULL); +#else gtk_table_attach(GTK_TABLE(table), w, 2, 3, 1, 2, GTK_FILL, 0, 0, 0); +#endif g_signal_connect(G_OBJECT(w), "changed", G_CALLBACK(size_entry_changed), fs); @@ -3044,8 +3289,13 @@ unifontsel *unifontsel_new(const char *wintitle) gtk_widget_show(scroll); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); +#if GTK_CHECK_VERSION(3,0,0) + gtk_grid_attach(GTK_GRID(table), scroll, 2, 2, 1, 1); + g_object_set(G_OBJECT(scroll), "expand", TRUE, (const char *)NULL); +#else gtk_table_attach(GTK_TABLE(table), scroll, 2, 3, 2, 3, GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); +#endif fs->size_model = model; fs->size_list = w; @@ -3053,18 +3303,27 @@ unifontsel *unifontsel_new(const char *wintitle) * Preview widget. */ fs->preview_area = gtk_drawing_area_new(); +#ifndef NO_BACKING_PIXMAPS fs->preview_pixmap = NULL; +#endif fs->preview_width = 0; fs->preview_height = 0; fs->preview_fg.pixel = fs->preview_bg.pixel = 0; fs->preview_fg.red = fs->preview_fg.green = fs->preview_fg.blue = 0x0000; fs->preview_bg.red = fs->preview_bg.green = fs->preview_bg.blue = 0xFFFF; +#if !GTK_CHECK_VERSION(3,0,0) gdk_colormap_alloc_color(gdk_colormap_get_system(), &fs->preview_fg, FALSE, FALSE); gdk_colormap_alloc_color(gdk_colormap_get_system(), &fs->preview_bg, FALSE, FALSE); +#endif +#if GTK_CHECK_VERSION(3,0,0) + g_signal_connect(G_OBJECT(fs->preview_area), "draw", + G_CALLBACK(unifontsel_draw_area), fs); +#else g_signal_connect(G_OBJECT(fs->preview_area), "expose_event", G_CALLBACK(unifontsel_expose_area), fs); +#endif g_signal_connect(G_OBJECT(fs->preview_area), "configure_event", G_CALLBACK(unifontsel_configure_area), fs); gtk_widget_set_size_request(fs->preview_area, 1, preview_height); @@ -3073,7 +3332,12 @@ unifontsel *unifontsel_new(const char *wintitle) w = gtk_frame_new(NULL); gtk_container_add(GTK_CONTAINER(w), ww); gtk_widget_show(w); -#if GTK_CHECK_VERSION(2,4,0) + +#if GTK_CHECK_VERSION(3,0,0) + /* GtkAlignment has become deprecated and we use the "margin" + * property */ + g_object_set(G_OBJECT(w), "margin", 8, (const char *)NULL); +#elif GTK_CHECK_VERSION(2,4,0) ww = w; /* GtkAlignment seems to be the simplest way to put padding round things */ w = gtk_alignment_new(0, 0, 1, 1); @@ -3081,12 +3345,18 @@ unifontsel *unifontsel_new(const char *wintitle) gtk_container_add(GTK_CONTAINER(w), ww); gtk_widget_show(w); #endif + ww = w; w = gtk_frame_new("Preview of font"); gtk_container_add(GTK_CONTAINER(w), ww); gtk_widget_show(w); +#if GTK_CHECK_VERSION(3,0,0) + gtk_grid_attach(GTK_GRID(table), w, 0, 3, 3, 1); + g_object_set(G_OBJECT(w), "expand", TRUE, (const char *)NULL); +#else gtk_table_attach(GTK_TABLE(table), w, 0, 3, 3, 4, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 8); +#endif /* * We only provide the checkboxes for client- and server-side @@ -3103,7 +3373,12 @@ unifontsel *unifontsel_new(const char *wintitle) G_CALLBACK(unifontsel_button_toggled), fs); gtk_widget_show(w); fs->filter_buttons[fs->n_filter_buttons++] = w; +#if GTK_CHECK_VERSION(3,0,0) + gtk_grid_attach(GTK_GRID(table), w, 0, 4, 3, 1); + g_object_set(G_OBJECT(w), "hexpand", TRUE, (const char *)NULL); +#else gtk_table_attach(GTK_TABLE(table), w, 0, 3, 4, 5, GTK_FILL, 0, 0, 0); +#endif w = gtk_check_button_new_with_label("Show server-side fonts"); g_object_set_data(G_OBJECT(w), "user-data", GINT_TO_POINTER(FONTFLAG_SERVERSIDE)); @@ -3111,7 +3386,12 @@ unifontsel *unifontsel_new(const char *wintitle) G_CALLBACK(unifontsel_button_toggled), fs); gtk_widget_show(w); fs->filter_buttons[fs->n_filter_buttons++] = w; +#if GTK_CHECK_VERSION(3,0,0) + gtk_grid_attach(GTK_GRID(table), w, 0, 5, 3, 1); + g_object_set(G_OBJECT(w), "hexpand", TRUE, (const char *)NULL); +#else gtk_table_attach(GTK_TABLE(table), w, 0, 3, 5, 6, GTK_FILL, 0, 0, 0); +#endif w = gtk_check_button_new_with_label("Show server-side font aliases"); g_object_set_data(G_OBJECT(w), "user-data", GINT_TO_POINTER(FONTFLAG_SERVERALIAS)); @@ -3119,8 +3399,13 @@ unifontsel *unifontsel_new(const char *wintitle) G_CALLBACK(unifontsel_button_toggled), fs); gtk_widget_show(w); fs->filter_buttons[fs->n_filter_buttons++] = w; +#if GTK_CHECK_VERSION(3,0,0) + gtk_grid_attach(GTK_GRID(table), w, 0, 6, 3, 1); + g_object_set(G_OBJECT(w), "hexpand", TRUE, (const char *)NULL); +#else gtk_table_attach(GTK_TABLE(table), w, 0, 3, 6, 7, GTK_FILL, 0, 0, 0); #endif +#endif /* NOT_X_WINDOWS */ w = gtk_check_button_new_with_label("Show non-monospaced fonts"); g_object_set_data(G_OBJECT(w), "user-data", GINT_TO_POINTER(FONTFLAG_NONMONOSPACED)); @@ -3128,7 +3413,12 @@ unifontsel *unifontsel_new(const char *wintitle) G_CALLBACK(unifontsel_button_toggled), fs); gtk_widget_show(w); fs->filter_buttons[fs->n_filter_buttons++] = w; +#if GTK_CHECK_VERSION(3,0,0) + gtk_grid_attach(GTK_GRID(table), w, 0, 7, 3, 1); + g_object_set(G_OBJECT(w), "hexpand", TRUE, (const char *)NULL); +#else gtk_table_attach(GTK_TABLE(table), w, 0, 3, 7, 8, GTK_FILL, 0, 0, 0); +#endif assert(fs->n_filter_buttons <= lenof(fs->filter_buttons)); fs->filter_flags = FONTFLAG_CLIENTSIDE | FONTFLAG_SERVERSIDE | @@ -3161,8 +3451,10 @@ void unifontsel_destroy(unifontsel *fontsel) unifontsel_internal *fs = (unifontsel_internal *)fontsel; fontinfo *info; +#ifndef NO_BACKING_PIXMAPS if (fs->preview_pixmap) gdk_pixmap_unref(fs->preview_pixmap); +#endif freetree234(fs->fonts_by_selorder); while ((info = delpos234(fs->fonts_by_realname, 0)) != NULL) @@ -3184,7 +3476,7 @@ void unifontsel_set_name(unifontsel *fontsel, const char *fontname) * Provide a default if given an empty or null font name. */ if (!fontname || !*fontname) - fontname = "server:fixed"; + fontname = DEFAULT_GTK_FONT; /* * Call the canonify_fontname function.