]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - unix/gtkfont.c
GTK 3 prep: use the glib names for base object types.
[PuTTY.git] / unix / gtkfont.c
index 0f2dc58151380856af7219e69b65f309bdc66255..2c828e3f57cd7d14b63e074763a42833d1976499 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 #include <gtk/gtk.h>
+#if !GTK_CHECK_VERSION(3,0,0)
 #include <gdk/gdkkeysyms.h>
+#endif
+#ifndef NOT_X_WINDOWS
 #include <gdk/gdkx.h>
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 #include <X11/Xatom.h>
+#endif
 
 #include "putty.h"
 #include "gtkfont.h"
  *    I haven't the energy.
  */
 
+#if !GLIB_CHECK_VERSION(1,3,7)
+#define g_ascii_strcasecmp g_strcasecmp
+#define g_ascii_strncasecmp g_strncasecmp
+#endif
+
 /*
  * Ad-hoc vtable mechanism to allow font structures to be
  * polymorphic.
@@ -90,8 +99,12 @@ struct unifont_vtable {
     const char *prefix;
 };
 
+#ifndef NOT_X_WINDOWS
+
 /* ----------------------------------------------------------------------
- * X11 font implementation, directly using Xlib calls.
+ * X11 font implementation, directly using Xlib calls. Conditioned out
+ * if X11 fonts aren't available at all (e.g. building with GTK3 for a
+ * back end other than X).
  */
 
 static int x11font_has_glyph(unifont *font, wchar_t glyph);
@@ -170,7 +183,7 @@ static char *x11_guess_derived_font_name(XFontStruct *xfs, int bold, int wide)
     if (XGetFontProperty(xfs, fontprop, &ret)) {
        char *name = XGetAtomName(disp, (Atom)ret);
        if (name && name[0] == '-') {
-           char *strings[13];
+           const char *strings[13];
            char *dupname, *extrafree = NULL, *ret;
            char *p, *q;
            int nstr;
@@ -186,8 +199,10 @@ static char *x11_guess_derived_font_name(XFontStruct *xfs, int bold, int wide)
                p++;
            }
 
-           if (nstr < lenof(strings))
+           if (nstr < lenof(strings)) {
+                sfree(dupname);
                return NULL;           /* XLFD was malformed */
+            }
 
            if (bold)
                strings[2] = "bold";
@@ -425,7 +440,7 @@ static int x11font_has_glyph(unifont *font, wchar_t glyph)
         char sbstring[2];
         int sblen = wc_to_mb(xfont->real_charset, 0, &glyph, 1,
                              sbstring, 2, "", NULL, NULL);
-        if (!sbstring[0])
+        if (sblen == 0 || !sbstring[0])
             return FALSE;              /* not even in the charset */
 
         return x11_font_has_glyph(xfont->fonts[0], 0,
@@ -661,21 +676,21 @@ static void x11font_enum_fonts(GtkWidget *widget,
            style = p;
            p += sprintf(p, "%s", components[2][0] ? components[2] :
                         "regular");
-           if (!g_strcasecmp(components[3], "i"))
+           if (!g_ascii_strcasecmp(components[3], "i"))
                p += sprintf(p, " italic");
-           else if (!g_strcasecmp(components[3], "o"))
+           else if (!g_ascii_strcasecmp(components[3], "o"))
                p += sprintf(p, " oblique");
-           else if (!g_strcasecmp(components[3], "ri"))
+           else if (!g_ascii_strcasecmp(components[3], "ri"))
                p += sprintf(p, " reverse italic");
-           else if (!g_strcasecmp(components[3], "ro"))
+           else if (!g_ascii_strcasecmp(components[3], "ro"))
                p += sprintf(p, " reverse oblique");
-           else if (!g_strcasecmp(components[3], "ot"))
+           else if (!g_ascii_strcasecmp(components[3], "ot"))
                p += sprintf(p, " other-slant");
-           if (components[4][0] && g_strcasecmp(components[4], "normal"))
+           if (components[4][0] && g_ascii_strcasecmp(components[4], "normal"))
                p += sprintf(p, " %s", components[4]);
-           if (!g_strcasecmp(components[10], "m"))
+           if (!g_ascii_strcasecmp(components[10], "m"))
                p += sprintf(p, " [M]");
-           if (!g_strcasecmp(components[10], "c"))
+           if (!g_ascii_strcasecmp(components[10], "c"))
                p += sprintf(p, " [C]");
            if (components[5][0])
                p += sprintf(p, " %s", components[5]);
@@ -687,23 +702,23 @@ static void x11font_enum_fonts(GtkWidget *widget,
             */
            p++;
            stylekey = p;
-           if (!g_strcasecmp(components[2], "medium") ||
-               !g_strcasecmp(components[2], "regular") ||
-               !g_strcasecmp(components[2], "normal") ||
-               !g_strcasecmp(components[2], "book"))
+           if (!g_ascii_strcasecmp(components[2], "medium") ||
+               !g_ascii_strcasecmp(components[2], "regular") ||
+               !g_ascii_strcasecmp(components[2], "normal") ||
+               !g_ascii_strcasecmp(components[2], "book"))
                weightkey = 0;
-           else if (!g_strncasecmp(components[2], "demi", 4) ||
-                    !g_strncasecmp(components[2], "semi", 4))
+           else if (!g_ascii_strncasecmp(components[2], "demi", 4) ||
+                    !g_ascii_strncasecmp(components[2], "semi", 4))
                weightkey = 1;
            else
                weightkey = 2;
-           if (!g_strcasecmp(components[3], "r"))
+           if (!g_ascii_strcasecmp(components[3], "r"))
                slantkey = 0;
-           else if (!g_strncasecmp(components[3], "r", 1))
+           else if (!g_ascii_strncasecmp(components[3], "r", 1))
                slantkey = 2;
            else
                slantkey = 1;
-           if (!g_strcasecmp(components[4], "normal"))
+           if (!g_ascii_strcasecmp(components[4], "normal"))
                setwidthkey = 0;
            else
                setwidthkey = 1;
@@ -819,6 +834,8 @@ static char *x11font_scale_fontname(GtkWidget *widget, const char *name,
     return NULL;                      /* shan't */
 }
 
+#endif /* NOT_X_WINDOWS */
+
 #if GTK_CHECK_VERSION(2,0,0)
 
 /* ----------------------------------------------------------------------
@@ -915,8 +932,8 @@ static int pangofont_check_desc_makes_sense(PangoContext *ctx,
 
     matched = FALSE;
     for (i = 0; i < nfamilies; i++) {
-       if (!g_strcasecmp(pango_font_family_get_name(families[i]),
-                         pango_font_description_get_family(desc))) {
+       if (!g_ascii_strcasecmp(pango_font_family_get_name(families[i]),
+                               pango_font_description_get_family(desc))) {
            matched = TRUE;
            break;
        }
@@ -1440,7 +1457,9 @@ static const struct unifont_vtable *unifont_types[] = {
 #if GTK_CHECK_VERSION(2,0,0)
     &pangofont_vtable,
 #endif
+#ifndef NOT_X_WINDOWS
     &x11font_vtable,
+#endif
 };
 
 /*
@@ -1567,6 +1586,7 @@ unifont *multifont_create(GtkWidget *widget, const char *name,
     if (!font)
         return NULL;
 
+    fallback = NULL;
     if (font->want_fallback) {
        for (i = 0; i < lenof(unifont_types); i++) {
             if (unifont_types[i]->create_fallback) {
@@ -1650,6 +1670,7 @@ typedef struct unifontsel_internal {
     GtkListStore *family_model, *style_model, *size_model;
     GtkWidget *family_list, *style_list, *size_entry, *size_list;
     GtkWidget *filter_buttons[4];
+    int n_filter_buttons;
     GtkWidget *preview_area;
     GdkPixmap *preview_pixmap;
     int preview_width, preview_height;
@@ -1712,7 +1733,7 @@ static int strnullcasecmp(const char *a, const char *b)
     /*
      * Otherwise, ordinary strcasecmp.
      */
-    return g_strcasecmp(a, b);
+    return g_ascii_strcasecmp(a, b);
 }
 
 static int fontinfo_realname_compare(void *av, void *bv)
@@ -1957,9 +1978,9 @@ static void unifontsel_set_filter_buttons(unifontsel_internal *fs)
 {
     int i;
 
-    for (i = 0; i < lenof(fs->filter_buttons); i++) {
-       int flagbit = GPOINTER_TO_INT(gtk_object_get_data
-                                     (GTK_OBJECT(fs->filter_buttons[i]),
+    for (i = 0; i < fs->n_filter_buttons; i++) {
+        int flagbit = GPOINTER_TO_INT(g_object_get_data
+                                      (G_OBJECT(fs->filter_buttons[i]),
                                       "user-data"));
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fs->filter_buttons[i]),
                                     !!(fs->filter_flags & flagbit));
@@ -2035,7 +2056,8 @@ static void unifontsel_draw_preview_text(unifontsel_internal *fs)
                                       42, FALSE, FALSE, font->width);
        }
        gdk_gc_unref(gc);
-       gdk_window_invalidate_rect(fs->preview_area->window, NULL, FALSE);
+        gdk_window_invalidate_rect(gtk_widget_get_window(fs->preview_area),
+                                   NULL, FALSE);
     }
     if (font)
        info->fontclass->destroy(font);
@@ -2181,8 +2203,8 @@ static void unifontsel_button_toggled(GtkToggleButton *tb, gpointer data)
     unifontsel_internal *fs = (unifontsel_internal *)data;
     int newstate = gtk_toggle_button_get_active(tb);
     int newflags;
-    int flagbit = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(tb),
-                                                     "user-data"));
+    int flagbit = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(tb),
+                                                    "user-data"));
 
     if (newstate)
        newflags = fs->filter_flags | flagbit;
@@ -2282,6 +2304,8 @@ static fontinfo *update_for_intended_size(unifontsel_internal *fs,
      */
     below = findrelpos234(fs->fonts_by_selorder, &info2, NULL,
                          REL234_LE, &pos);
+    if (!below)
+        pos = -1;
     above = index234(fs->fonts_by_selorder, pos+1);
 
     /*
@@ -2289,7 +2313,7 @@ static fontinfo *update_for_intended_size(unifontsel_internal *fs,
      * case. If we have, it'll be in `below' and not `above',
      * because we did a REL234_LE rather than REL234_LT search.
      */
-    if (!fontinfo_selorder_compare(&info2, below))
+    if (below && !fontinfo_selorder_compare(&info2, below))
        return below;
 
     /*
@@ -2466,8 +2490,9 @@ static gint unifontsel_expose_area(GtkWidget *widget, GdkEventExpose *event,
     unifontsel_internal *fs = (unifontsel_internal *)data;
 
     if (fs->preview_pixmap) {
-       gdk_draw_pixmap(widget->window,
-                       widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
+        gdk_draw_pixmap(gtk_widget_get_window(widget),
+                       (gtk_widget_get_style(widget)->fg_gc
+                         [gtk_widget_get_state(widget)]),
                        fs->preview_pixmap,
                        event->area.x, event->area.y,
                        event->area.x, event->area.y,
@@ -2495,14 +2520,15 @@ static gint unifontsel_configure_area(GtkWidget *widget,
        
        nx = (x > ox ? x : ox);
        ny = (y > oy ? y : oy);
-       fs->preview_pixmap = gdk_pixmap_new(widget->window, nx, ny, -1);
+       fs->preview_pixmap = gdk_pixmap_new(gtk_widget_get_window(widget),
+                                            nx, ny, -1);
        fs->preview_width = nx;
        fs->preview_height = ny;
 
        unifontsel_draw_preview_text(fs);
     }
 
-    gdk_window_invalidate_rect(widget->window, NULL, FALSE);
+    gdk_window_invalidate_rect(gtk_widget_get_window(widget), NULL, FALSE);
 
     return TRUE;
 }
@@ -2539,7 +2565,7 @@ unifontsel *unifontsel_new(const char *wintitle)
        g_object_ref_sink(label);
        g_object_unref(label);
 #else
-        gtk_object_sink(GTK_OBJECT(label));
+        g_object_ref_sink(G_OBJECT(label));
 #endif
     }
 
@@ -2572,7 +2598,8 @@ unifontsel *unifontsel_new(const char *wintitle)
 #else
     w = table;
 #endif
-    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(fs->u.window)->vbox),
+    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:");
@@ -2706,10 +2733,10 @@ unifontsel *unifontsel_new(const char *wintitle)
                             FALSE, FALSE);
     gdk_colormap_alloc_color(gdk_colormap_get_system(), &fs->preview_bg,
                             FALSE, FALSE);
-    gtk_signal_connect(GTK_OBJECT(fs->preview_area), "expose_event",
-                      GTK_SIGNAL_FUNC(unifontsel_expose_area), fs);
-    gtk_signal_connect(GTK_OBJECT(fs->preview_area), "configure_event",
-                      GTK_SIGNAL_FUNC(unifontsel_configure_area), fs);
+    g_signal_connect(G_OBJECT(fs->preview_area), "expose_event",
+                     G_CALLBACK(unifontsel_expose_area), fs);
+    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);
     gtk_widget_show(fs->preview_area);
     ww = fs->preview_area;
@@ -2731,41 +2758,49 @@ 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);
 
-    i = 0;
+    /*
+     * We only provide the checkboxes for client- and server-side
+     * fonts if we have the X11 back end available, because that's the
+     * only situation in which more than one class of font is
+     * available anyway.
+     */
+    fs->n_filter_buttons = 0;
+#ifndef NOT_X_WINDOWS
     w = gtk_check_button_new_with_label("Show client-side fonts");
-    gtk_object_set_data(GTK_OBJECT(w), "user-data",
-                       GINT_TO_POINTER(FONTFLAG_CLIENTSIDE));
-    gtk_signal_connect(GTK_OBJECT(w), "toggled",
-                      GTK_SIGNAL_FUNC(unifontsel_button_toggled), fs);
+    g_object_set_data(G_OBJECT(w), "user-data",
+                      GINT_TO_POINTER(FONTFLAG_CLIENTSIDE));
+    g_signal_connect(G_OBJECT(w), "toggled",
+                     G_CALLBACK(unifontsel_button_toggled), fs);
     gtk_widget_show(w);
-    fs->filter_buttons[i++] = w;
+    fs->filter_buttons[fs->n_filter_buttons++] = w;
     gtk_table_attach(GTK_TABLE(table), w, 0, 3, 4, 5, GTK_FILL, 0, 0, 0);
     w = gtk_check_button_new_with_label("Show server-side fonts");
-    gtk_object_set_data(GTK_OBJECT(w), "user-data",
-                       GINT_TO_POINTER(FONTFLAG_SERVERSIDE));
-    gtk_signal_connect(GTK_OBJECT(w), "toggled",
-                      GTK_SIGNAL_FUNC(unifontsel_button_toggled), fs);
+    g_object_set_data(G_OBJECT(w), "user-data",
+                      GINT_TO_POINTER(FONTFLAG_SERVERSIDE));
+    g_signal_connect(G_OBJECT(w), "toggled",
+                     G_CALLBACK(unifontsel_button_toggled), fs);
     gtk_widget_show(w);
-    fs->filter_buttons[i++] = w;
+    fs->filter_buttons[fs->n_filter_buttons++] = w;
     gtk_table_attach(GTK_TABLE(table), w, 0, 3, 5, 6, GTK_FILL, 0, 0, 0);
     w = gtk_check_button_new_with_label("Show server-side font aliases");
-    gtk_object_set_data(GTK_OBJECT(w), "user-data",
-                       GINT_TO_POINTER(FONTFLAG_SERVERALIAS));
-    gtk_signal_connect(GTK_OBJECT(w), "toggled",
-                      GTK_SIGNAL_FUNC(unifontsel_button_toggled), fs);
+    g_object_set_data(G_OBJECT(w), "user-data",
+                      GINT_TO_POINTER(FONTFLAG_SERVERALIAS));
+    g_signal_connect(G_OBJECT(w), "toggled",
+                     G_CALLBACK(unifontsel_button_toggled), fs);
     gtk_widget_show(w);
-    fs->filter_buttons[i++] = w;
+    fs->filter_buttons[fs->n_filter_buttons++] = w;
     gtk_table_attach(GTK_TABLE(table), w, 0, 3, 6, 7, GTK_FILL, 0, 0, 0);
+#endif
     w = gtk_check_button_new_with_label("Show non-monospaced fonts");
-    gtk_object_set_data(GTK_OBJECT(w), "user-data",
-                       GINT_TO_POINTER(FONTFLAG_NONMONOSPACED));
-    gtk_signal_connect(GTK_OBJECT(w), "toggled",
-                      GTK_SIGNAL_FUNC(unifontsel_button_toggled), fs);
+    g_object_set_data(G_OBJECT(w), "user-data",
+                      GINT_TO_POINTER(FONTFLAG_NONMONOSPACED));
+    g_signal_connect(G_OBJECT(w), "toggled",
+                     G_CALLBACK(unifontsel_button_toggled), fs);
     gtk_widget_show(w);
-    fs->filter_buttons[i++] = w;
+    fs->filter_buttons[fs->n_filter_buttons++] = w;
     gtk_table_attach(GTK_TABLE(table), w, 0, 3, 7, 8, GTK_FILL, 0, 0, 0);
 
-    assert(i == lenof(fs->filter_buttons));
+    assert(fs->n_filter_buttons <= lenof(fs->filter_buttons));
     fs->filter_flags = FONTFLAG_CLIENTSIDE | FONTFLAG_SERVERSIDE |
        FONTFLAG_SERVERALIAS;
     unifontsel_set_filter_buttons(fs);