]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - unix/gtkfont.c
Fixes for re-entrant calls in the serial configuration list boxes.
[PuTTY.git] / unix / gtkfont.c
index b5c31cfa5bbc68ab17b6dbbdbbf71ce79f9b89ee..0db5ba29f71add7f39b66bffdb21b22589d00cf8 100644 (file)
 #include "gtkfont.h"
 #include "tree234.h"
 
-/*
- * TODO on fontsel
- * ---------------
- * 
- *  - generalised style and padding polish
- *     + work out why the list boxes don't go all the way to the
- *      RHS of the dialog box
- * 
- *  - big testing and shakedown!
- */
-
 /*
  * 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.
+ * 
  *  - all the GDK font functions used in the x11font subclass are
  *    deprecated, so one day they may go away. When this happens -
  *    or before, if I'm feeling proactive - it oughtn't to be too
@@ -70,6 +63,8 @@
 #define FONTFLAG_SERVERALIAS   0x0004
 #define FONTFLAG_NONMONOSPACED 0x0008
 
+#define FONTFLAG_SORT_MASK     0x0007 /* used to disambiguate font families */
+
 typedef void (*fontsel_add_entry)(void *ctx, const char *realfontname,
                                  const char *family, const char *charset,
                                  const char *style, const char *stylekey,
@@ -89,7 +84,7 @@ struct unifont_vtable {
     void (*enum_fonts)(GtkWidget *widget,
                       fontsel_add_entry callback, void *callback_ctx);
     char *(*canonify_fontname)(GtkWidget *widget, const char *name, int *size,
-                              int resolve_aliases);
+                              int *flags, int resolve_aliases);
     char *(*scale_fontname)(GtkWidget *widget, const char *name, int size);
 
     /*
@@ -112,7 +107,8 @@ static void x11font_destroy(unifont *font);
 static void x11font_enum_fonts(GtkWidget *widget,
                               fontsel_add_entry callback, void *callback_ctx);
 static char *x11font_canonify_fontname(GtkWidget *widget, const char *name,
-                                      int *size, int resolve_aliases);
+                                      int *size, int *flags,
+                                      int resolve_aliases);
 static char *x11font_scale_fontname(GtkWidget *widget, const char *name,
                                    int size);
 
@@ -155,7 +151,7 @@ static const struct unifont_vtable x11font_vtable = {
     x11font_enum_fonts,
     x11font_canonify_fontname,
     x11font_scale_fontname,
-    "server"
+    "server",
 };
 
 char *x11_guess_derived_font_name(GdkFont *font, int bold, int wide)
@@ -577,13 +573,13 @@ static void x11font_enum_fonts(GtkWidget *widget,
 
            p += sprintf(p, "%04d%04d%s%04d%04d%s%04d%04d%s%04d%s%04d%s",
                         weightkey,
-                        strlen(components[2]), components[2],
+                        (int)strlen(components[2]), components[2],
                         slantkey,
-                        strlen(components[3]), components[3],
+                        (int)strlen(components[3]), components[3],
                         setwidthkey,
-                        strlen(components[4]), components[4],
-                        strlen(components[10]), components[10],
-                        strlen(components[5]), components[5]);
+                        (int)strlen(components[4]), components[4],
+                        (int)strlen(components[10]), components[10],
+                        (int)strlen(components[5]), components[5]);
 
            assert(p - tmp < thistmpsize);
 
@@ -628,7 +624,8 @@ static void x11font_enum_fonts(GtkWidget *widget,
 }
 
 static char *x11font_canonify_fontname(GtkWidget *widget, const char *name,
-                                      int *size, int resolve_aliases)
+                                      int *size, int *flags,
+                                      int resolve_aliases)
 {
     /*
      * When given an X11 font name to try to make sense of for a
@@ -665,6 +662,12 @@ static char *x11font_canonify_fontname(GtkWidget *widget, const char *name,
            if (XGetFontProperty(xfs, fontprop2, &fsize) && fsize > 0) {
                *size = fsize;
                gdk_font_unref(font);
+               if (flags) {
+                   if (name[0] == '-' || resolve_aliases)
+                       *flags = FONTFLAG_SERVERSIDE;
+                   else
+                       *flags = FONTFLAG_SERVERALIAS;
+               }
                return dupstr(name[0] == '-' || resolve_aliases ?
                              newname : name);
            }
@@ -681,10 +684,16 @@ static char *x11font_scale_fontname(GtkWidget *widget, const char *name,
     return NULL;                      /* shan't */
 }
 
+#if GTK_CHECK_VERSION(2,0,0)
+
 /* ----------------------------------------------------------------------
- * Pango font implementation.
+ * Pango font implementation (for GTK 2 only).
  */
 
+#if defined PANGO_PRE_1POINT4 && !defined PANGO_PRE_1POINT6
+#define PANGO_PRE_1POINT6             /* make life easier for pre-1.4 folk */
+#endif
+
 static void pangofont_draw_text(GdkDrawable *target, GdkGC *gc, unifont *font,
                                int x, int y, const char *string, int len,
                                int wide, int bold, int cellwidth);
@@ -695,7 +704,8 @@ static void pangofont_destroy(unifont *font);
 static void pangofont_enum_fonts(GtkWidget *widget, fontsel_add_entry callback,
                                 void *callback_ctx);
 static char *pangofont_canonify_fontname(GtkWidget *widget, const char *name,
-                                        int *size, int resolve_aliases);
+                                        int *size, int *flags,
+                                        int resolve_aliases);
 static char *pangofont_scale_fontname(GtkWidget *widget, const char *name,
                                      int size);
 
@@ -723,9 +733,58 @@ static const struct unifont_vtable pangofont_vtable = {
     pangofont_enum_fonts,
     pangofont_canonify_fontname,
     pangofont_scale_fontname,
-    "client"
+    "client",
 };
 
+/*
+ * This function is used to rigorously validate a
+ * PangoFontDescription. Later versions of Pango have a nasty
+ * habit of accepting _any_ old string as input to
+ * pango_font_description_from_string and returning a font
+ * description which can actually be used to display text, even if
+ * they have to do it by falling back to their most default font.
+ * This is doubtless helpful in some situations, but not here,
+ * because we need to know if a Pango font string actually _makes
+ * sense_ in order to fall back to treating it as an X font name
+ * if it doesn't. So we check that the font family is actually one
+ * supported by Pango.
+ */
+static int pangofont_check_desc_makes_sense(PangoContext *ctx,
+                                           PangoFontDescription *desc)
+{
+#ifndef PANGO_PRE_1POINT6
+    PangoFontMap *map;
+#endif
+    PangoFontFamily **families;
+    int i, nfamilies, matched;
+
+    /*
+     * Ask Pango for a list of font families, and iterate through
+     * them to see if one of them matches the family in the
+     * PangoFontDescription.
+     */
+#ifndef PANGO_PRE_1POINT6
+    map = pango_context_get_font_map(ctx);
+    if (!map)
+       return FALSE;
+    pango_font_map_list_families(map, &families, &nfamilies);
+#else
+    pango_context_list_families(ctx, &families, &nfamilies);
+#endif
+
+    matched = FALSE;
+    for (i = 0; i < nfamilies; i++) {
+       if (!g_strcasecmp(pango_font_family_get_name(families[i]),
+                         pango_font_description_get_family(desc))) {
+           matched = TRUE;
+           break;
+       }
+    }
+    g_free(families);
+
+    return matched;
+}
+
 static unifont *pangofont_create(GtkWidget *widget, const char *name,
                                 int wide, int bold,
                                 int shadowoffset, int shadowalways)
@@ -747,6 +806,10 @@ static unifont *pangofont_create(GtkWidget *widget, const char *name,
        pango_font_description_free(desc);
        return NULL;
     }
+    if (!pangofont_check_desc_makes_sense(ctx, desc)) {
+       pango_font_description_free(desc);
+       return NULL;
+    }
 #ifndef PANGO_PRE_1POINT6
     map = pango_context_get_font_map(ctx);
     if (!map) {
@@ -829,28 +892,83 @@ static void pangofont_draw_text(GdkDrawable *target, GdkGC *gc, unifont *font,
     }
 
     while (len > 0) {
-       int clen;
+       int clen, n;
 
        /*
-        * Extract a single UTF-8 character from the string.
+        * We want to display every character from this string in
+        * the centre of its own character cell. In the worst case,
+        * this requires a separate text-drawing call for each
+        * character; but in the common case where the font is
+        * properly fixed-width, we can draw many characters in one
+        * go which is much faster.
+        *
+        * This still isn't really ideal. If you look at what
+        * happens in the X protocol as a result of all of this, you
+        * find - naturally enough - that each call to
+        * gdk_draw_layout() generates a separate set of X RENDER
+        * operations involving creating a picture, setting a clip
+        * rectangle, doing some drawing and undoing the whole lot.
+        * In an ideal world, we should _always_ be able to turn the
+        * contents of this loop into a single RenderCompositeGlyphs
+        * operation which internally specifies inter-character
+        * deltas to get the spacing right, which would give us full
+        * speed _even_ in the worst case of a non-fixed-width font.
+        * However, Pango's architecture and documentation are so
+        * unhelpful that I have no idea how if at all to persuade
+        * them to do that.
+        */
+
+       /*
+        * Start by extracting a single UTF-8 character from the
+        * string.
         */
        clen = 1;
        while (clen < len &&
               (unsigned char)string[clen] >= 0x80 &&
               (unsigned char)string[clen] < 0xC0)
            clen++;
+       n = 1;
+
+       /*
+        * See if that character has the width we expect.
+        */
+       pango_layout_set_text(layout, string, clen);
+       pango_layout_get_pixel_extents(layout, NULL, &rect);
+
+       if (rect.width == cellwidth) {
+           /*
+            * Try extracting more characters, for as long as they
+            * stay well-behaved.
+            */
+           while (clen < len) {
+               int oldclen = clen;
+               clen++;                /* skip UTF-8 introducer byte */
+               while (clen < len &&
+                      (unsigned char)string[clen] >= 0x80 &&
+                      (unsigned char)string[clen] < 0xC0)
+                   clen++;
+               n++;
+               pango_layout_set_text(layout, string, clen);
+               pango_layout_get_pixel_extents(layout, NULL, &rect);
+               if (rect.width != n * cellwidth) {
+                   clen = oldclen;
+                   n--;
+                   break;
+               }
+           }
+       }
 
        pango_layout_set_text(layout, string, clen);
        pango_layout_get_pixel_extents(layout, NULL, &rect);
-       gdk_draw_layout(target, gc, x + (cellwidth - rect.width)/2,
+       gdk_draw_layout(target, gc, x + (n*cellwidth - rect.width)/2,
                        y + (pfont->u.height - rect.height)/2, layout);
        if (shadowbold)
-           gdk_draw_layout(target, gc, x + (cellwidth - rect.width)/2 + pfont->shadowoffset,
+           gdk_draw_layout(target, gc, x + (n*cellwidth - rect.width)/2 + pfont->shadowoffset,
                            y + (pfont->u.height - rect.height)/2, layout);
 
        len -= clen;
        string += clen;
-       x += cellwidth;
+       x += n * cellwidth;
     }
 
     g_object_unref(layout);
@@ -1018,7 +1136,8 @@ static void pangofont_enum_fonts(GtkWidget *widget, fontsel_add_entry callback,
 }
 
 static char *pangofont_canonify_fontname(GtkWidget *widget, const char *name,
-                                        int *size, int resolve_aliases)
+                                        int *size, int *flags,
+                                        int resolve_aliases)
 {
     /*
      * When given a Pango font name to try to make sense of for a
@@ -1042,6 +1161,10 @@ static char *pangofont_canonify_fontname(GtkWidget *widget, const char *name,
        pango_font_description_free(desc);
        return NULL;
     }
+    if (!pangofont_check_desc_makes_sense(ctx, desc)) {
+       pango_font_description_free(desc);
+       return NULL;
+    }
 #ifndef PANGO_PRE_1POINT6
     map = pango_context_get_font_map(ctx);
     if (!map) {
@@ -1067,6 +1190,7 @@ static char *pangofont_canonify_fontname(GtkWidget *widget, const char *name,
     }
 
     *size = PANGO_PIXELS(pango_font_description_get_size(desc));
+    *flags = FONTFLAG_CLIENTSIDE;
     pango_font_description_set_size(desc, PANGO_DUMMY_SIZE * PANGO_SCALE);
     newname = pango_font_description_to_string(desc);
     retname = dupstr(newname);
@@ -1097,6 +1221,8 @@ static char *pangofont_scale_fontname(GtkWidget *widget, const char *name,
     return retname;
 }
 
+#endif /* GTK_CHECK_VERSION(2,0,0) */
+
 /* ----------------------------------------------------------------------
  * Outermost functions which do the vtable dispatch.
  */
@@ -1109,7 +1235,9 @@ static char *pangofont_scale_fontname(GtkWidget *widget, const char *name,
  * of an explicit type-disambiguating prefix.)
  */
 static const struct unifont_vtable *unifont_types[] = {
+#if GTK_CHECK_VERSION(2,0,0)
     &pangofont_vtable,
+#endif
     &x11font_vtable,
 };
 
@@ -1188,8 +1316,11 @@ void unifont_draw_text(GdkDrawable *target, GdkGC *gc, unifont *font,
                        wide, bold, cellwidth);
 }
 
+#if GTK_CHECK_VERSION(2,0,0)
+
 /* ----------------------------------------------------------------------
- * Implementation of a unified font selector.
+ * Implementation of a unified font selector. Used on GTK 2 only;
+ * for GTK 1 we still use the standard font selector.
  */
 
 typedef struct fontinfo fontinfo;
@@ -1237,19 +1368,10 @@ struct fontinfo {
     const struct unifont_vtable *fontclass;
 };
 
-static int fontinfo_realname_compare(void *av, void *bv)
-{
-    fontinfo *a = (fontinfo *)av;
-    fontinfo *b = (fontinfo *)bv;
-    return g_strcasecmp(a->realname, b->realname);
-}
-
-static int fontinfo_realname_find(void *av, void *bv)
-{
-    const char *a = (const char *)av;
-    fontinfo *b = (fontinfo *)bv;
-    return g_strcasecmp(a, b->realname);
-}
+struct fontinfo_realname_find {
+    const char *realname;
+    int flags;
+};
 
 static int strnullcasecmp(const char *a, const char *b)
 {
@@ -1274,6 +1396,34 @@ static int strnullcasecmp(const char *a, const char *b)
     return g_strcasecmp(a, b);
 }
 
+static int fontinfo_realname_compare(void *av, void *bv)
+{
+    fontinfo *a = (fontinfo *)av;
+    fontinfo *b = (fontinfo *)bv;
+    int i;
+
+    if ((i = strnullcasecmp(a->realname, b->realname)) != 0)
+       return i;
+    if ((a->flags & FONTFLAG_SORT_MASK) != (b->flags & FONTFLAG_SORT_MASK))
+       return ((a->flags & FONTFLAG_SORT_MASK) <
+               (b->flags & FONTFLAG_SORT_MASK) ? -1 : +1);
+    return 0;
+}
+
+static int fontinfo_realname_find(void *av, void *bv)
+{
+    struct fontinfo_realname_find *a = (struct fontinfo_realname_find *)av;
+    fontinfo *b = (fontinfo *)bv;
+    int i;
+
+    if ((i = strnullcasecmp(a->realname, b->realname)) != 0)
+       return i;
+    if ((a->flags & FONTFLAG_SORT_MASK) != (b->flags & FONTFLAG_SORT_MASK))
+       return ((a->flags & FONTFLAG_SORT_MASK) <
+               (b->flags & FONTFLAG_SORT_MASK) ? -1 : +1);
+    return 0;
+}
+
 static int fontinfo_selorder_compare(void *av, void *bv)
 {
     fontinfo *a = (fontinfo *)av;
@@ -1281,6 +1431,13 @@ static int fontinfo_selorder_compare(void *av, void *bv)
     int i;
     if ((i = strnullcasecmp(a->family, b->family)) != 0)
        return i;
+    /*
+     * Font class comes immediately after family, so that fonts
+     * from different classes with the same family
+     */
+    if ((a->flags & FONTFLAG_SORT_MASK) != (b->flags & FONTFLAG_SORT_MASK))
+       return ((a->flags & FONTFLAG_SORT_MASK) <
+               (b->flags & FONTFLAG_SORT_MASK) ? -1 : +1);
     if ((i = strnullcasecmp(a->charset, b->charset)) != 0)
        return i;
     if ((i = strnullcasecmp(a->stylekey, b->stylekey)) != 0)
@@ -1294,11 +1451,21 @@ static int fontinfo_selorder_compare(void *av, void *bv)
     return 0;
 }
 
+static void unifontsel_deselect(unifontsel_internal *fs)
+{
+    fs->selected = NULL;
+    gtk_list_store_clear(fs->style_model);
+    gtk_list_store_clear(fs->size_model);
+    gtk_widget_set_sensitive(fs->u.ok_button, FALSE);
+    gtk_widget_set_sensitive(fs->size_entry, FALSE);
+}
+
 static void unifontsel_setup_familylist(unifontsel_internal *fs)
 {
     GtkTreeIter iter;
     int i, listindex, minpos = -1, maxpos = -1;
     char *currfamily = NULL;
+    int currflags = -1;
     fontinfo *info;
 
     gtk_list_store_clear(fs->family_model);
@@ -1321,7 +1488,8 @@ static void unifontsel_setup_familylist(unifontsel_internal *fs)
            info->familyindex = -1;
            continue;                  /* we're filtering out this font */
        }
-       if (!info || strnullcasecmp(currfamily, info->family)) {
+       if (!info || strnullcasecmp(currfamily, info->family) ||
+           currflags != (info->flags & FONTFLAG_SORT_MASK)) {
            /*
             * We've either finished a family, or started a new
             * one, or both.
@@ -1335,6 +1503,7 @@ static void unifontsel_setup_familylist(unifontsel_internal *fs)
            if (info) {
                minpos = i;
                currfamily = info->family;
+               currflags = info->flags & FONTFLAG_SORT_MASK;
            }
        }
        if (!info)
@@ -1342,6 +1511,13 @@ static void unifontsel_setup_familylist(unifontsel_internal *fs)
        info->familyindex = listindex;
        maxpos = i;
     }
+
+    /*
+     * If we've just filtered out the previously selected font,
+     * deselect it thoroughly.
+     */
+    if (fs->selected && fs->selected->familyindex < 0)
+       unifontsel_deselect(fs);
 }
 
 static void unifontsel_setup_stylelist(unifontsel_internal *fs,
@@ -1564,6 +1740,8 @@ static void unifontsel_select_font(unifontsel_internal *fs,
     if (size_is_explicit)
        fs->intendedsize = size;
 
+    gtk_widget_set_sensitive(fs->u.ok_button, TRUE);
+
     /*
      * Find the index of this fontinfo in the selorder list. 
      */
@@ -1942,10 +2120,16 @@ static void alias_resolve(GtkTreeView *treeview, GtkTreePath *path,
     gtk_tree_model_get(GTK_TREE_MODEL(fs->family_model), &iter, 1,&minval, -1);
     info = (fontinfo *)index234(fs->fonts_by_selorder, minval);
     if (info) {
+       int flags;
+       struct fontinfo_realname_find f;
+
        newname = info->fontclass->canonify_fontname
-           (GTK_WIDGET(fs->u.window), info->realname, &newsize, TRUE);
-       newinfo = find234(fs->fonts_by_realname, (char *)newname,
-                         fontinfo_realname_find);
+           (GTK_WIDGET(fs->u.window), info->realname, &newsize, &flags, TRUE);
+
+       f.realname = newname;
+       f.flags = flags;
+       newinfo = find234(fs->fonts_by_realname, &f, fontinfo_realname_find);
+
        sfree(newname);
        if (!newinfo)
            return;                    /* font name not in our index */
@@ -2014,6 +2198,7 @@ unifontsel *unifontsel_new(const char *wintitle)
     int i;
 
     fs->inhibit_response = FALSE;
+    fs->selected = NULL;
 
     {
        /*
@@ -2056,11 +2241,20 @@ unifontsel *unifontsel_new(const char *wintitle)
      * Now set up the internal fields, including in particular all
      * the controls that actually allow the user to select fonts.
      */
-    table = gtk_table_new(3, 8, FALSE);
+    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)
+    /* 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
+    w = table;
+#endif
     gtk_box_pack_start(GTK_BOX(GTK_DIALOG(fs->u.window)->vbox),
-                      table, TRUE, TRUE, 0);
+                      w, TRUE, TRUE, 0);
 
     label = gtk_label_new_with_mnemonic("_Font:");
     gtk_widget_show(label);
@@ -2179,6 +2373,9 @@ unifontsel *unifontsel_new(const char *wintitle)
     fs->size_model = model;
     fs->size_list = w;
 
+    /*
+     * Preview widget.
+     */
     fs->preview_area = gtk_drawing_area_new();
     fs->preview_pixmap = NULL;
     fs->preview_width = 0;
@@ -2200,12 +2397,14 @@ 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)
     ww = w;
     /* 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), ww);
     gtk_widget_show(w);
+#endif
     ww = w;
     w = gtk_frame_new("Preview of font");
     gtk_container_add(GTK_CONTAINER(w), ww);
@@ -2213,9 +2412,6 @@ unifontsel *unifontsel_new(const char *wintitle)
     gtk_table_attach(GTK_TABLE(table), w, 0, 3, 3, 4,
                     GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 8);
 
-    /*
-     * FIXME: preview widget
-     */
     i = 0;
     w = gtk_check_button_new_with_label("Show client-side fonts");
     gtk_object_set_data(GTK_OBJECT(w), "user-data",
@@ -2251,7 +2447,8 @@ unifontsel *unifontsel_new(const char *wintitle)
     gtk_table_attach(GTK_TABLE(table), w, 0, 3, 7, 8, GTK_FILL, 0, 0, 0);
 
     assert(i == lenof(fs->filter_buttons));
-    fs->filter_flags = FONTFLAG_CLIENTSIDE | FONTFLAG_SERVERSIDE;
+    fs->filter_flags = FONTFLAG_CLIENTSIDE | FONTFLAG_SERVERSIDE |
+       FONTFLAG_SERVERALIAS;
     unifontsel_set_filter_buttons(fs);
 
     /*
@@ -2269,7 +2466,8 @@ unifontsel *unifontsel_new(const char *wintitle)
      */
     unifontsel_setup_familylist(fs);
 
-    fs->selected = NULL;
+    fs->selsize = fs->intendedsize = 13;   /* random default */
+    gtk_widget_set_sensitive(fs->u.ok_button, FALSE);
 
     return (unifontsel *)fs;
 }
@@ -2294,7 +2492,7 @@ void unifontsel_destroy(unifontsel *fontsel)
 void unifontsel_set_name(unifontsel *fontsel, const char *fontname)
 {
     unifontsel_internal *fs = (unifontsel_internal *)fontsel;
-    int i, start, end, size;
+    int i, start, end, size, flags;
     const char *fontname2 = NULL;
     fontinfo *info;
 
@@ -2302,7 +2500,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 = "fixed";   /* Pango zealots might prefer "Monospace 12" */
+       fontname = "server:fixed";
 
     /*
      * Call the canonify_fontname function.
@@ -2310,7 +2508,7 @@ void unifontsel_set_name(unifontsel *fontsel, const char *fontname)
     fontname = unifont_do_prefix(fontname, &start, &end);
     for (i = start; i < end; i++) {
        fontname2 = unifont_types[i]->canonify_fontname
-           (GTK_WIDGET(fs->u.window), fontname, &size, FALSE);
+           (GTK_WIDGET(fs->u.window), fontname, &size, &flags, FALSE);
        if (fontname2)
            break;
     }
@@ -2320,8 +2518,12 @@ void unifontsel_set_name(unifontsel *fontsel, const char *fontname)
     /*
      * Now look up the canonified font name in our index.
      */
-    info = find234(fs->fonts_by_realname, (char *)fontname2,
-                  fontinfo_realname_find);
+    {
+       struct fontinfo_realname_find f;
+       f.realname = fontname2;
+       f.flags = flags;
+       info = find234(fs->fonts_by_realname, &f, fontinfo_realname_find);
+    }
 
     /*
      * If we've found the font, and its size field is either
@@ -2330,8 +2532,11 @@ void unifontsel_set_name(unifontsel *fontsel, const char *fontname)
      * font name instead.
      */
     if (!info || (info->size != size && info->size != 0)) {
-       info = find234(fs->fonts_by_realname, (char *)fontname,
-                      fontinfo_realname_find);
+       struct fontinfo_realname_find f;
+       f.realname = fontname;
+       f.flags = flags;
+
+       info = find234(fs->fonts_by_realname, &f, fontinfo_realname_find);
        if (!info || info->size != size)
            return;                    /* font name not in our index */
     }
@@ -2349,14 +2554,22 @@ char *unifontsel_get_name(unifontsel *fontsel)
     unifontsel_internal *fs = (unifontsel_internal *)fontsel;
     char *name;
 
-    assert(fs->selected);
+    if (!fs->selected)
+       return NULL;
 
     if (fs->selected->size == 0) {
        name = fs->selected->fontclass->scale_fontname
            (GTK_WIDGET(fs->u.window), fs->selected->realname, fs->selsize);
-       if (name)
-           return name;
+       if (name) {
+           char *ret = dupcat(fs->selected->fontclass->prefix, ":",
+                              name, NULL);
+           sfree(name);
+           return ret;
+       }
     }
 
-    return dupstr(fs->selected->realname);
+    return dupcat(fs->selected->fontclass->prefix, ":",
+                 fs->selected->realname, NULL);
 }
+
+#endif /* GTK_CHECK_VERSION(2,0,0) */