]> asedeno.scripts.mit.edu Git - PuTTY.git/commitdiff
In the new unified font handling, my strategy so far for combining
authorSimon Tatham <anakin@pobox.com>
Sat, 5 Apr 2008 13:37:20 +0000 (13:37 +0000)
committerSimon Tatham <anakin@pobox.com>
Sat, 5 Apr 2008 13:37:20 +0000 (13:37 +0000)
client- and server-side fonts into a single namespace was mainly to
hope there would naturally be no collisions, and to provide
disambiguating "client:" and "server:" prefixes for manual use in
emergencies.

Jacob points out, however, that his system not only has a namespace
clash but worse still the clash is at the name "fixed", which is our
default font! So, modify my namespace policy to use the
disambiguating prefixes everywhere by default, and use _unprefixed_
names only if the user types one in by hand.

In particular, I've changed the keys used to store font names in
Unix saved session files. Font names read from the new keys will be
passed straight to the new unifont framework; font names read from
the old keys will have "server:" prepended. So any existing
configuration file for GTK1 PuTTY should now work reliably in GTK2
PuTTY and select the same font, even if that font is one on which
your system (rather, your client+server combination) has a font
namespace clash.

[originally from svn r7973]

unix/gtkfont.c
unix/gtkwin.c
unix/uxstore.c

index 647f7aaed5ee8d3515e81051ef399b55e5da3f75..a909364c85a15724f43bd1e0307a7ba231790811 100644 (file)
 /*
  * 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
@@ -59,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,
@@ -78,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);
 
     /*
@@ -101,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);
 
@@ -144,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)
@@ -617,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
@@ -654,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);
            }
@@ -686,7 +700,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);
 
@@ -714,7 +729,7 @@ static const struct unifont_vtable pangofont_vtable = {
     pangofont_enum_fonts,
     pangofont_canonify_fontname,
     pangofont_scale_fontname,
-    "client"
+    "client",
 };
 
 /*
@@ -1062,7 +1077,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
@@ -1292,19 +1308,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)
 {
@@ -1329,6 +1336,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;
@@ -1336,6 +1371,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)
@@ -1354,6 +1396,7 @@ 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);
@@ -1376,7 +1419,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.
@@ -1390,6 +1434,7 @@ static void unifontsel_setup_familylist(unifontsel_internal *fs)
            if (info) {
                minpos = i;
                currfamily = info->family;
+               currflags = info->flags & FONTFLAG_SORT_MASK;
            }
        }
        if (!info)
@@ -1999,10 +2044,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 */
@@ -2359,7 +2410,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;
 
@@ -2367,7 +2418,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.
@@ -2375,7 +2426,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;
     }
@@ -2385,8 +2436,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
@@ -2395,8 +2450,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 */
     }
@@ -2420,11 +2478,16 @@ char *unifontsel_get_name(unifontsel *fontsel)
     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) */
index 51a867e1fa88359da3a4d7095681f0da2f59d638..dc8d6607e860b2ea1dcea999c08281f81ba50239 100644 (file)
@@ -134,7 +134,7 @@ FontSpec platform_default_fontspec(const char *name)
 {
     FontSpec ret;
     if (!strcmp(name, "Font"))
-       strcpy(ret.name, "fixed");
+       strcpy(ret.name, "server:fixed");
     else
        *ret.name = '\0';
     return ret;
index 80e216170075442e1353103d04d980098ee0c250..33b6d18d7b1ab9674dfe6ea81923426defe8b07f 100644 (file)
@@ -362,7 +362,35 @@ int read_setting_i(void *handle, const char *key, int defvalue)
 
 int read_setting_fontspec(void *handle, const char *name, FontSpec *result)
 {
-    return !!read_setting_s(handle, name, result->name, sizeof(result->name));
+    /*
+     * In GTK1-only PuTTY, we used to store font names simply as a
+     * valid X font description string (logical or alias), under a
+     * bare key such as "Font".
+     * 
+     * In GTK2 PuTTY, we have a prefix system where "client:"
+     * indicates a Pango font and "server:" an X one; existing
+     * configuration needs to be reinterpreted as having the
+     * "server:" prefix, so we change the storage key from the
+     * provided name string (e.g. "Font") to a suffixed one
+     * ("FontName").
+     */
+    char *suffname = dupcat(name, "Name", NULL);
+    if (read_setting_s(handle, suffname, result->name, sizeof(result->name))) {
+       sfree(suffname);
+       return TRUE;                   /* got new-style name */
+    }
+    sfree(suffname);
+
+    /* Fall back to old-style name. */
+    memcpy(result->name, "server:", 7);
+    if (!read_setting_s(handle, name,
+                       result->name + 7, sizeof(result->name) - 7) ||
+       !result->name[7]) {
+       result->name[0] = '\0';
+       return FALSE;
+    } else {
+       return TRUE;
+    }
 }
 int read_setting_filename(void *handle, const char *name, Filename *result)
 {
@@ -371,7 +399,14 @@ int read_setting_filename(void *handle, const char *name, Filename *result)
 
 void write_setting_fontspec(void *handle, const char *name, FontSpec result)
 {
-    write_setting_s(handle, name, result.name);
+    /*
+     * read_setting_fontspec had to handle two cases, but when
+     * writing our settings back out we simply always generate the
+     * new-style name.
+     */
+    char *suffname = dupcat(name, "Name", NULL);
+    write_setting_s(handle, suffname, result.name);
+    sfree(suffname);
 }
 void write_setting_filename(void *handle, const char *name, Filename result)
 {