Control: tags -1 + patch Please find attached a patch which I tested as much as I can. I considered switching from Xft to Pango and doing the drawing with PangoCairo but its API does not allow access to some features (autohinting, subpixel smoothing, etc.) so that would reduce the program's functionality.
The patch also fixes some other issues: * Missing sentinels in some fontconfig variadic functions * Some memory leaks * Duplicate font families in the fonts combobox * Garbage value as first item in the styles combobox
Description: Port to GTK 3. Bug-Debian: https://bugs.debian.org/967509 Author: Yavor Doganov <[email protected]> Forwarded: no Last-Update: 2026-01-14 --- --- gwaterfall.orig/configure.ac +++ gwaterfall/configure.ac @@ -21,8 +21,7 @@ AC_PROG_CC AC_PROG_LIBTOOL -# no need to check for fontconfig, xft brings it in -PKG_CHECK_MODULES(WATERFALL, gtk+-2.0 >= 2.2.0 xft >= 2.0.0) +PKG_CHECK_MODULES(WATERFALL, gtk+-3.0 cairo-xlib fontconfig xft >= 2.0.0) AC_SUBST(WATERFALL_CFLAGS) AC_SUBST(WATERFALL_LIBS) --- gwaterfall.orig/src/main.c +++ gwaterfall/src/main.c @@ -33,16 +33,16 @@ FcObjectSet *set; FcPattern *pattern; FcFontSet *list; - GList *styles = NULL; - FcChar8 *style; + GList *l, *styles = NULL; + FcChar8 *style = NULL; gint i; if (style_combo == NULL) return; - set = FcObjectSetBuild (FC_STYLE, 0); + set = FcObjectSetBuild (FC_STYLE, NULL); pattern = FcPatternBuild (0, FC_FAMILY, FcTypeString, - waterfall_get_font_family (waterfall), 0); + waterfall_get_font_family (waterfall), NULL); g_assert (pattern != NULL); list = FcFontList (0, pattern, set); @@ -51,41 +51,51 @@ for (i = 0; i < list->nfont; i++) { FcPatternGetString (list->fonts[i], FC_STYLE, 0, &style); - styles = g_list_append (styles, style); + if (style) + styles = g_list_append (styles, style); } if (styles) - gtk_combo_set_popdown_strings (GTK_COMBO (style_combo), styles); + for (l = styles; l; l = l->next) + gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (style_combo), + l->data); + + gtk_combo_box_set_active (GTK_COMBO_BOX (style_combo), 0); + g_list_free (styles); FcFontSetDestroy (list); } static void -family_changed (GtkEntry *entry, +family_changed (GtkComboBox *combo, Waterfall *waterfall) { - const gchar *new_family = gtk_entry_get_text (entry); + gchar *new_family + = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (combo)); /* ignore empty string (it sends these a lot) */ if (new_family[0] == '\0') return; waterfall_set_font_family (waterfall, new_family); + g_free (new_family); set_style_choices (waterfall); } static void -style_changed (GtkEntry *entry, +style_changed (GtkComboBox *combo, Waterfall *waterfall) { - const gchar *new_style = gtk_entry_get_text (entry); + gchar *new_style + = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (combo)); /* ignore empty string (it sends these a lot) */ if (new_style[0] == '\0') return; waterfall_set_font_style (waterfall, new_style); + g_free (new_style); } @@ -94,17 +104,16 @@ { GtkWidget *combo; FcFontSet *list; - FcObjectSet *set = FcObjectSetBuild (FC_FAMILY, 0); + FcObjectSet *set = FcObjectSetBuild (FC_FAMILY, NULL); FcPattern *pattern = FcPatternCreate (); - GList *family_names = NULL; + GList *l, *family_names = NULL; FcChar8 *family_name; int i; - combo = gtk_combo_new (); + combo = gtk_combo_box_text_new (); gtk_widget_show (combo); - gtk_editable_set_editable (GTK_EDITABLE (GTK_COMBO (combo)->entry), FALSE); - g_signal_connect (GTK_COMBO (combo)->entry, "changed", + g_signal_connect (combo, "changed", G_CALLBACK (family_changed), waterfall); list = FcFontList (0, pattern, set); @@ -115,7 +124,9 @@ for (i = 0; i < list->nfont; i++) { FcPatternGetString (list->fonts[i], FC_FAMILY, 0, &family_name); - family_names = g_list_append (family_names, family_name); + if (!g_list_find_custom (family_names, family_name, + (GCompareFunc) FcStrCmpIgnoreCase)) + family_names = g_list_append (family_names, family_name); } /* family_names = g_list_append (family_names, "Serif"); @@ -124,8 +135,11 @@ */ family_names = g_list_sort (family_names, (GCompareFunc) FcStrCmpIgnoreCase); - gtk_combo_set_popdown_strings (GTK_COMBO (combo), family_names); + for (l = family_names; l; l = l->next) + gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), + l->data); + gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0); g_list_free (family_names); FcFontSetDestroy (list); @@ -136,12 +150,10 @@ static GtkWidget * construct_font_style_chooser (Waterfall *waterfall) { - style_combo = gtk_combo_new (); + style_combo = gtk_combo_box_text_new (); gtk_widget_show (style_combo); - gtk_editable_set_editable (GTK_EDITABLE (GTK_COMBO (style_combo)->entry), - FALSE); - g_signal_connect (GTK_COMBO (style_combo)->entry, "changed", + g_signal_connect (style_combo, "changed", G_CALLBACK (style_changed), waterfall); set_style_choices (waterfall); @@ -219,11 +231,11 @@ construct_size_bar (Waterfall *waterfall) { GtkWidget *hbox; - GtkObject *adjustment; + GtkAdjustment *adjustment; GtkWidget *spin_button; GtkWidget *label; - hbox = gtk_hbox_new (FALSE, 12); + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); gtk_widget_show (hbox); label = gtk_label_new ("Smallest:"); @@ -270,11 +282,11 @@ construct_aspect_bar (Waterfall *waterfall) { GtkWidget *hbox; - GtkObject *adjustment; + GtkAdjustment *adjustment; GtkWidget *spin_button; GtkWidget *label; - hbox = gtk_hbox_new (FALSE, 6); + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); gtk_widget_show (hbox); label = gtk_label_new ("Aspect:"); @@ -388,7 +400,7 @@ GtkWidget *hbox; GtkWidget *button; - hbox = gtk_hbox_new (FALSE, 3); + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3); gtk_widget_show (hbox); button = gtk_button_new_with_label (" <<< "); @@ -444,42 +456,30 @@ static void -set_rgba_none (GtkMenuItem *menu_item, - Waterfall *waterfall) -{ - waterfall_set_rgba (waterfall, FC_RGBA_NONE); -} - - -static void -set_rgba_rgb (GtkMenuItem *menu_item, - Waterfall *waterfall) +set_rgba (GtkComboBox *combo, + Waterfall *waterfall) { - waterfall_set_rgba (waterfall, FC_RGBA_RGB); -} - - -static void -set_rgba_bgr (GtkMenuItem *menu_item, - Waterfall *waterfall) -{ - waterfall_set_rgba (waterfall, FC_RGBA_BGR); -} - - -static void -set_rgba_vrgb (GtkMenuItem *menu_item, - Waterfall *waterfall) -{ - waterfall_set_rgba (waterfall, FC_RGBA_VRGB); -} - + switch (gtk_combo_box_get_active (combo)) + { + case 0: + waterfall_set_rgba (waterfall, FC_RGBA_NONE); + break; + case 1: + waterfall_set_rgba (waterfall, FC_RGBA_RGB); + break; + case 2: + waterfall_set_rgba (waterfall, FC_RGBA_BGR); + break; + case 3: + waterfall_set_rgba (waterfall, FC_RGBA_VRGB); + break; + case 4: + waterfall_set_rgba (waterfall, FC_RGBA_VBGR); + break; -static void -set_rgba_vbgr (GtkMenuItem *menu_item, - Waterfall *waterfall) -{ - waterfall_set_rgba (waterfall, FC_RGBA_VBGR); + default: + break; + } } @@ -487,54 +487,27 @@ construct_rgba_menu (Waterfall *waterfall) { GtkWidget *option_menu; - GtkWidget *menu; - GtkWidget *menu_item; GtkWidget *label; - rgba_hbox = gtk_hbox_new (FALSE, 6); + rgba_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); gtk_widget_show (rgba_hbox); label = gtk_label_new ("Subpixel smoothing:"); gtk_widget_show (label); gtk_box_pack_start (GTK_BOX (rgba_hbox), label, FALSE, FALSE, 0); - menu = gtk_menu_new (); - gtk_widget_show (menu); + option_menu = gtk_combo_box_text_new (); + + gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (option_menu), "None"); + gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (option_menu), "RGB"); + gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (option_menu), "BGR"); + gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (option_menu), "VRGB"); + gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (option_menu), "VBGR"); + gtk_combo_box_set_active (GTK_COMBO_BOX (option_menu), 0); + g_signal_connect (option_menu, "changed", G_CALLBACK (set_rgba), waterfall); - menu_item = gtk_menu_item_new_with_label ("None"); - gtk_widget_show (menu_item); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); - g_signal_connect (menu_item, "activate", - G_CALLBACK (set_rgba_none), waterfall); - - menu_item = gtk_menu_item_new_with_label ("RGB"); - gtk_widget_show (menu_item); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); - g_signal_connect (menu_item, "activate", - G_CALLBACK (set_rgba_rgb), waterfall); - - menu_item = gtk_menu_item_new_with_label ("BGR"); - gtk_widget_show (menu_item); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); - g_signal_connect (menu_item, "activate", - G_CALLBACK (set_rgba_bgr), waterfall); - - menu_item = gtk_menu_item_new_with_label ("VRGB"); - gtk_widget_show (menu_item); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); - g_signal_connect (menu_item, "activate", - G_CALLBACK (set_rgba_vrgb), waterfall); - - menu_item = gtk_menu_item_new_with_label ("VBGR"); - gtk_widget_show (menu_item); - gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); - g_signal_connect (menu_item, "activate", - G_CALLBACK (set_rgba_vbgr), waterfall); - - option_menu = gtk_option_menu_new (); gtk_widget_show (option_menu); gtk_box_pack_start (GTK_BOX (rgba_hbox), option_menu, FALSE, FALSE, 0); - gtk_option_menu_set_menu (GTK_OPTION_MENU (option_menu), menu); gtk_widget_set_sensitive (rgba_hbox, waterfall_get_antialias (waterfall)); @@ -551,10 +524,10 @@ GtkWidget *check_button; GtkWidget *separator; - vbox = gtk_vbox_new (FALSE, 6); + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); gtk_widget_show (vbox); - hbox = gtk_hbox_new (FALSE, 12); + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); gtk_widget_show (hbox); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); @@ -567,7 +540,7 @@ construct_font_style_chooser (waterfall), FALSE, FALSE, 0); - separator = gtk_vseparator_new (); + separator = gtk_separator_new (GTK_ORIENTATION_VERTICAL); gtk_widget_show (separator); gtk_box_pack_start (GTK_BOX (hbox), separator, FALSE, FALSE, 0); @@ -589,7 +562,7 @@ g_signal_connect (G_OBJECT (autohint_check_button), "toggled", G_CALLBACK (autohint_toggled), waterfall); - separator = gtk_vseparator_new (); + separator = gtk_separator_new (GTK_ORIENTATION_VERTICAL); gtk_widget_show (separator); gtk_box_pack_start (GTK_BOX (hbox), separator, FALSE, FALSE, 0); @@ -604,21 +577,21 @@ gtk_box_pack_start (GTK_BOX (hbox), construct_rgba_menu (waterfall), FALSE, FALSE, 0); - separator = gtk_vseparator_new (); + separator = gtk_separator_new (GTK_ORIENTATION_VERTICAL); gtk_widget_show (separator); gtk_box_pack_start (GTK_BOX (hbox), separator, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), construct_aspect_bar (waterfall), FALSE, FALSE, 0); - hbox = gtk_hbox_new (FALSE, 12); + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); gtk_widget_show (hbox); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), construct_size_bar (waterfall), FALSE, FALSE, 0); - separator = gtk_vseparator_new (); + separator = gtk_separator_new (GTK_ORIENTATION_VERTICAL); gtk_widget_show (separator); gtk_box_pack_start (GTK_BOX (hbox), separator, FALSE, FALSE, 0); @@ -636,7 +609,11 @@ GtkWidget *vbox; GtkWidget *waterfall; GtkWidget *scrolled_window; + GtkCssProvider *css; + GdkMonitor *monitor; GdkScreen *screen; + GdkRectangle geom; + const char *css_data = "viewport * { background-color: @theme_bg_color }"; gtk_init (&argc, &argv); @@ -645,22 +622,31 @@ g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (gtk_main_quit), NULL); + gtk_widget_realize (window); screen = gtk_window_get_screen (GTK_WINDOW (window)); + monitor = gdk_display_get_monitor_at_window(gdk_screen_get_display (screen), + gtk_widget_get_window (window)); + gdk_monitor_get_geometry (monitor, &geom); gtk_window_set_default_size (GTK_WINDOW (window), - gdk_screen_get_width (screen) * 3/4, - gdk_screen_get_height (screen) * 3/4); + geom.width * 3/4, geom.height * 3/4); - vbox = gtk_vbox_new (FALSE, 6); + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6); gtk_widget_show (vbox); gtk_container_add (GTK_CONTAINER (window), vbox); waterfall = waterfall_new (); gtk_widget_show (waterfall); + css = gtk_css_provider_new (); + gtk_css_provider_load_from_data (css, css_data, -1, NULL); + gtk_style_context_add_provider_for_screen (screen, GTK_STYLE_PROVIDER (css), + GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + scrolled_window = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_overlay_scrolling (GTK_SCROLLED_WINDOW + (scrolled_window), FALSE); gtk_widget_show (scrolled_window); - gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), - waterfall); + gtk_container_add (GTK_CONTAINER (scrolled_window), waterfall); gtk_box_pack_start (GTK_BOX (vbox), construct_options_bar (WATERFALL (waterfall)), --- gwaterfall.orig/src/waterfall.c +++ gwaterfall/src/waterfall.c @@ -18,6 +18,7 @@ #include <gtk/gtk.h> #include <gdk/gdkx.h> +#include <cairo-xlib.h> #include <X11/Xft/Xft.h> #include <string.h> #include "waterfall.h" @@ -29,6 +30,7 @@ enum { BUFFER = 12 }; +static void queue_redraw (Waterfall *waterfall); /* buf should have at least WATERFALL_PAGE_SIZE slots */ static void @@ -82,15 +84,16 @@ FcPatternAddInteger (pattern, FC_RGBA, waterfall->rgba); FcPatternAddDouble (pattern, FC_ASPECT, waterfall->aspect); - match = XftFontMatch (GDK_DISPLAY (), gdk_x11_get_default_screen (), - pattern, &result); + match = XftFontMatch (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), + gdk_x11_get_default_screen (), pattern, &result); FcPatternDestroy (pattern); if (!match) return NULL; - font = XftFontOpenPattern (GDK_DISPLAY (), match); + font = XftFontOpenPattern (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), + match); if (!font) FcPatternDestroy (match); @@ -103,25 +106,33 @@ gint *width, gint *height) { + Display *dpy; XGlyphInfo extents; gdouble lines; XftFont *big_font, *small_font, *theme_font; - gchar *buf; + GtkStyleContext *ctxt; + PangoFontDescription *desc = NULL; + gchar *buf, *font; gunichar ucs[128]; gint ucs_len; + ctxt = gtk_widget_get_style_context (GTK_WIDGET (waterfall)); + gtk_style_context_get (ctxt, gtk_style_context_get_state (ctxt), + GTK_STYLE_PROPERTY_FONT, &desc, NULL); + font = pango_font_description_to_string (desc); + pango_font_description_free (desc); small_font = open_font (waterfall, waterfall->min_size); big_font = open_font (waterfall, waterfall->max_size); - theme_font = XftFontOpenName (GDK_DISPLAY (), gdk_x11_get_default_screen (), - pango_font_description_to_string ( - GTK_WIDGET (waterfall)->style->font_desc)); + dpy = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); + theme_font = XftFontOpenName (dpy, gdk_x11_get_default_screen (), font); + g_free (font); get_string_for_page (waterfall, ucs, &ucs_len); - XftTextExtents32 (GDK_DISPLAY (), big_font, ucs, ucs_len, &extents); + XftTextExtents32 (dpy, big_font, ucs, ucs_len, &extents); *width = extents.width + BUFFER; buf = g_strdup_printf ("%5.1f", waterfall->max_size); - XftTextExtentsUtf8 (GDK_DISPLAY (), theme_font, buf, strlen (buf), &extents); + XftTextExtentsUtf8 (dpy, theme_font, buf, strlen (buf), &extents); *width += extents.width + BUFFER; g_free (buf); @@ -141,9 +152,9 @@ *height = 3000; } - XftFontClose (GDK_DISPLAY (), big_font); - XftFontClose (GDK_DISPLAY (), small_font); - XftFontClose (GDK_DISPLAY (), theme_font); + XftFontClose (dpy, big_font); + XftFontClose (dpy, small_font); + XftFontClose (dpy, theme_font); } @@ -151,50 +162,65 @@ draw_pixmap (Waterfall *waterfall) { Colormap colormap; + Display *dpy; Drawable drawable; Visual *visual; + Window w; gint width, height; XGlyphInfo extents; XftFont *theme_font; - XftColor fg; + XftColor fg, bg; XftFont *font; XftDraw *xftdraw; + GtkStyleContext *ctxt; + GdkRGBA *fg_rgba = NULL, *bg_rgba = NULL; + PangoFontDescription *desc = NULL; gdouble size; gint y; gint size_width; /* width allotted to "12.0", etc */ - gchar *buf; + gchar *buf, *font_str; gunichar ucs[128]; gint ucs_len; + int screen_nr; - width = GTK_WIDGET (waterfall)->allocation.width; - height = GTK_WIDGET (waterfall)->allocation.height; + ctxt = gtk_widget_get_style_context (GTK_WIDGET (waterfall)); + width = gtk_widget_get_allocated_width (GTK_WIDGET (waterfall)); + height = gtk_widget_get_allocated_height (GTK_WIDGET (waterfall)); + + gtk_style_context_get (ctxt, gtk_style_context_get_state (ctxt), + GTK_STYLE_PROPERTY_FONT, &desc, + GTK_STYLE_PROPERTY_COLOR, &fg_rgba, + GTK_STYLE_PROPERTY_BACKGROUND_COLOR, &bg_rgba, + NULL); + font_str = pango_font_description_to_string (desc); + pango_font_description_free (desc); + dpy = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); + screen_nr = gdk_x11_get_default_screen (); + theme_font = XftFontOpenName (dpy, screen_nr, font_str); + g_free (font_str); - theme_font = XftFontOpenName (GDK_DISPLAY (), gdk_x11_get_default_screen (), - pango_font_description_to_string ( - GTK_WIDGET (waterfall)->style->font_desc)); - - waterfall->pixmap = gdk_pixmap_new (GTK_WIDGET (waterfall)->window, - width, height, -1); - - gdk_draw_rectangle (GDK_DRAWABLE (waterfall->pixmap), - GTK_WIDGET (waterfall)->style->base_gc[GTK_STATE_NORMAL], - TRUE, 0, 0, width, height); - - colormap = gdk_x11_colormap_get_xcolormap ( - gdk_drawable_get_colormap (GTK_WIDGET (waterfall)->window)); - drawable = gdk_x11_drawable_get_xid (GDK_DRAWABLE (waterfall->pixmap)); + colormap = DefaultColormap (dpy, screen_nr); visual = gdk_x11_visual_get_xvisual ( gtk_widget_get_visual (GTK_WIDGET (waterfall))); + w = gdk_x11_window_get_xid (gtk_widget_get_window (GTK_WIDGET (waterfall))); + drawable = XCreatePixmap (dpy, w, width, height, + DefaultDepth (dpy, screen_nr)); + xftdraw = XftDrawCreate (dpy, drawable, visual, colormap); + + fg.color.red = (int) (0.5 + CLAMP (fg_rgba->red, 0., 1.) * 65535.); + fg.color.green = (int) (0.5 + CLAMP (fg_rgba->green, 0., 1.) * 65535.); + fg.color.blue = (int) (0.5 + CLAMP (fg_rgba->blue, 0., 1.) * 65535.); + fg.color.alpha = (int) (0.5 + CLAMP (fg_rgba->alpha, 0., 1.) * 65535.); + + bg.color.red = (int) (0.5 + CLAMP (bg_rgba->red, 0., 1.) * 65535.); + bg.color.green = (int) (0.5 + CLAMP (bg_rgba->green, 0., 1.) * 65535.); + bg.color.blue = (int) (0.5 + CLAMP (bg_rgba->blue, 0., 1.) * 65535.); + bg.color.alpha = (int) (0.5 + CLAMP (bg_rgba->alpha, 0., 1.) * 65535.); - xftdraw = XftDrawCreate (GDK_DISPLAY (), drawable, visual, colormap); - - fg.color.red = GTK_WIDGET (waterfall)->style->fg[GTK_STATE_NORMAL].red; - fg.color.green = GTK_WIDGET (waterfall)->style->fg[GTK_STATE_NORMAL].green; - fg.color.blue = GTK_WIDGET (waterfall)->style->fg[GTK_STATE_NORMAL].blue; - fg.color.alpha = 0xffff; + XftDrawRect (xftdraw, &bg, 0, 0, width, height); buf = g_strdup_printf ("%5.1f", waterfall->max_size); - XftTextExtentsUtf8 (GDK_DISPLAY (), theme_font, buf, strlen (buf), &extents); + XftTextExtentsUtf8 (dpy, theme_font, buf, strlen (buf), &extents); size_width = extents.width + BUFFER; g_free (buf); @@ -211,29 +237,27 @@ get_string_for_page (waterfall, ucs, &ucs_len); XftDrawString32(xftdraw, &fg, font, size_width, y, ucs, ucs_len); - XftFontClose (GDK_DISPLAY (), font); + XftFontClose (dpy, font); } - XftFontClose (GDK_DISPLAY (), theme_font); + waterfall->pixmap = cairo_xlib_surface_create (dpy, drawable, visual, + width, height); + + XftFontClose (dpy, theme_font); XftDrawDestroy (xftdraw); + XFreeColormap (dpy, colormap); } static gint -expose_event (Waterfall *waterfall, - GdkEventExpose *event) +draw (Waterfall *waterfall, + cairo_t *cr) { - gdk_window_set_back_pixmap (GTK_WIDGET (waterfall)->window, NULL, FALSE); - if (waterfall->pixmap == NULL) draw_pixmap (waterfall); - gdk_draw_drawable (GTK_WIDGET (waterfall)->window, - GTK_WIDGET (waterfall)->style->fg_gc[GTK_STATE_NORMAL], - waterfall->pixmap, - event->area.x, event->area.y, - event->area.x, event->area.y, - event->area.width, event->area.height); + cairo_set_source_surface (cr, waterfall->pixmap, 0, 0); + cairo_paint (cr); return FALSE; } @@ -243,6 +267,8 @@ size_allocate (GtkWidget *widget, GtkAllocation *allocation) { + /* Trigger a full redraw if the window is resized. */ + queue_redraw (WATERFALL (widget)); } @@ -262,8 +288,8 @@ waterfall->page = -1; gtk_widget_set_events (GTK_WIDGET (waterfall), GDK_EXPOSURE_MASK); - g_signal_connect (G_OBJECT (waterfall), "expose-event", - G_CALLBACK (expose_event), NULL); + g_signal_connect (G_OBJECT (waterfall), "draw", + G_CALLBACK (draw), NULL); g_signal_connect (G_OBJECT (waterfall), "size-allocate", G_CALLBACK (size_allocate), NULL); } @@ -311,7 +337,7 @@ if (waterfall->pixmap) { - g_object_unref (waterfall->pixmap); + cairo_surface_destroy (waterfall->pixmap); waterfall->pixmap = NULL; } @@ -330,7 +356,8 @@ g_free (waterfall->font_family); if (waterfall->font) - XftFontClose (GDK_DISPLAY (), waterfall->font); + XftFontClose (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), + waterfall->font); waterfall->font_family = g_strdup (new_family); waterfall->font = open_font (waterfall, waterfall->min_size); @@ -354,7 +381,8 @@ g_free (waterfall->font_style); if (waterfall->font) - XftFontClose (GDK_DISPLAY (), waterfall->font); + XftFontClose (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), + waterfall->font); waterfall->font_style = g_strdup (new_style); waterfall->font = open_font (waterfall, waterfall->min_size); --- gwaterfall.orig/src/waterfall.h +++ gwaterfall/src/waterfall.h @@ -42,7 +42,7 @@ { GtkDrawingArea parent; - GdkPixmap *pixmap; + cairo_surface_t *pixmap; XftDraw *xftdraw; gchar *font_family;

