[gucharmap] Port drawing to cairo



commit e15a141c3458bba90bbd626f80620b261ab67105
Author: Christian Persch <chpe gnome org>
Date:   Sat Aug 14 16:04:54 2010 +0200

    Port drawing to cairo
    
    And cleanup drawing and scrolling code.
    
    Bug #626912.

 gucharmap/gucharmap-chartable.c     |  825 ++++++++++++-----------------------
 gucharmap/gucharmap-private.h       |    3 -
 gucharmap/gucharmap-search-dialog.c |    3 +-
 gucharmap/gucharmap-window.c        |   56 +---
 4 files changed, 278 insertions(+), 609 deletions(-)
---
diff --git a/gucharmap/gucharmap-chartable.c b/gucharmap/gucharmap-chartable.c
index 1e7c736..ce0de24 100644
--- a/gucharmap/gucharmap-chartable.c
+++ b/gucharmap/gucharmap-chartable.c
@@ -37,6 +37,14 @@
 #include "gucharmap-chartable-accessible.h"
 #endif
 
+#if !GTK_CHECK_VERSION (2, 18, 0)
+#define gtk_widget_has_focus(w) GTK_WIDGET_HAS_FOCUS(w)
+#endif
+
+#if !GTK_CHECK_VERSION (2, 20, 0)
+#define gtk_widget_get_realized(w) GTK_WIDGET_REALIZED (w)
+#endif
+
 enum
 {
   ACTIVATE,
@@ -60,6 +68,8 @@ enum
 
 static void gucharmap_chartable_class_init (GucharmapChartableClass *klass);
 static void gucharmap_chartable_finalize   (GObject *object);
+static void gucharmap_chartable_set_active_cell (GucharmapChartable *chartable,
+                                                 int cell);
 
 static guint signals[NUM_SIGNALS];
 
@@ -419,39 +429,6 @@ _gucharmap_chartable_y_offset (GucharmapChartable *chartable, gint row)
   return y;
 }
 
-static void
-set_top_row (GucharmapChartable *chartable, 
-             gint            row)
-{
-  GucharmapChartablePrivate *priv = chartable->priv;
-  gint r, c;
-
-  g_return_if_fail (row >= 0 && row <= priv->last_cell / priv->cols);
-
-  priv->old_page_first_cell = priv->page_first_cell;
-  priv->old_active_cell = priv->active_cell;
-
-  priv->page_first_cell = row * priv->cols;
-
-  /* character is still on the visible page */
-  if (priv->active_cell - priv->page_first_cell >= 0
-      && priv->active_cell - priv->page_first_cell < priv->page_size)
-    return;
-
-  c = priv->old_active_cell % priv->cols;
-
-  if (priv->page_first_cell < priv->old_page_first_cell)
-    r = priv->rows - 1;
-  else
-    r = 0;
-
-  priv->active_cell = priv->page_first_cell + r * priv->cols + c;
-  if (priv->active_cell > priv->last_cell)
-    priv->active_cell = priv->last_cell;
-
-  g_object_notify (G_OBJECT (chartable), "active-character");
-}
-
 /* returns the font family of the last glyph item in the first line of the
  * layout; should be freed by caller */
 static gchar *
@@ -539,6 +516,7 @@ create_glyph_pixmap (GucharmapChartable *chartable,
   GtkStyle *style;
   GdkPixmap *pixmap;
   char *family;
+  cairo_t *cr;
 
   /* Apply the scaling.  Unfortunately not all fonts seem to be scalable.
    * We could fall back to GdkPixbuf scaling, but that looks butt ugly :-/
@@ -571,34 +549,47 @@ create_glyph_pixmap (GucharmapChartable *chartable,
   pixmap = gdk_pixmap_new (gtk_widget_get_window (widget),
                            pixmap_width, pixmap_height, -1);
 
-  gdk_draw_rectangle (pixmap, style->base_gc[GTK_STATE_NORMAL],
-                      TRUE, 0, 0, pixmap_width, pixmap_height);
+  cr = gdk_cairo_create (pixmap);
+
+  gdk_cairo_set_source_color (cr, &style->base[GTK_STATE_NORMAL]);
+  cairo_rectangle (cr, 0, 0, pixmap_width, pixmap_height);
+  cairo_fill (cr);
 
-  /* Draw a rectangular border, taking char_rect offsets into account. */
-  gdk_draw_rectangle (pixmap, style->fg_gc[GTK_STATE_INSENSITIVE], 
-                      FALSE, 1, 1, pixmap_width - 3, pixmap_height - 3);
+  gdk_cairo_set_source_color (cr, &style->fg[GTK_STATE_INSENSITIVE]);
+  cairo_set_line_width (cr, 1);
+  cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
+  cairo_rectangle (cr, 1.5, 1.5, pixmap_width - 3, pixmap_height - 3);
+  cairo_stroke (cr);
 
   /* Now draw the glyph.  The coordinates are adapted
-   * in order to compensate negative char_rect offsets. */
-  gdk_draw_layout (pixmap, style->text_gc[GTK_STATE_NORMAL],
-                   -char_rect.x + PADDING, -char_rect.y + PADDING,
-                   pango_layout);
+   * in order to compensate negative char_rect offsets. 
+   */
+  gdk_cairo_set_source_color (cr, &style->text[GTK_STATE_NORMAL]);
+  cairo_move_to (cr, -char_rect.x + PADDING, -char_rect.y + PADDING);
+  pango_cairo_show_layout (cr, pango_layout);
   g_object_unref (pango_layout);
 
   if (draw_font_family)
     {
-      gdk_draw_line (pixmap, style->dark_gc[GTK_STATE_NORMAL],
-                     6 + 1, char_rect.height + 2 * PADDING,
-                     pixmap_width - 3 - 6, char_rect.height + 2 * PADDING);
-      gdk_draw_layout (pixmap, style->text_gc[GTK_STATE_NORMAL],
-                       PADDING, pixmap_height - PADDING - family_rect.height,
-                       pango_layout2);
+      cairo_set_line_width (cr, 1);
+      cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
+      gdk_cairo_set_source_color (cr, &style->dark[GTK_STATE_NORMAL]);
+      cairo_move_to (cr, 6 + 1 + .5, char_rect.height + 2 * PADDING + .5);
+      cairo_line_to (cr, pixmap_width - 3 - 6 - .5, char_rect.height + 2 * PADDING + .5);
+      cairo_stroke (cr);
+
+      gdk_cairo_set_source_color (cr, &style->text[GTK_STATE_NORMAL]);
+      cairo_move_to (cr, PADDING, pixmap_height - PADDING - family_rect.height);
+      /* FIXME: clip here? */
+      pango_cairo_show_layout (cr, pango_layout2);
 
       g_object_unref (pango_layout2);
     }
 
   g_free (family);
 
+  cairo_destroy (cr);
+
   return pixmap;
 }
 
@@ -684,6 +675,9 @@ update_zoom_window (GucharmapChartable *chartable)
   double scale;
   int font_size_px, screen_height;
 
+  if (priv->zoom_window == NULL)
+    return;
+
   font_size_px = get_font_size_px (chartable);
   screen_height = gdk_screen_get_height (gtk_widget_get_screen (widget));
 
@@ -764,136 +758,9 @@ gucharmap_chartable_hide_zoom (GucharmapChartable *chartable)
   g_object_notify (G_OBJECT (chartable), "zoom-showing");
 }
 
-static void
-gucharmap_chartable_set_active_cell (GucharmapChartable *chartable,
-                                     guint cell)
-{
-  GucharmapChartablePrivate *priv = chartable->priv;
-  int _cell = (int) cell;
-
-  priv->old_active_cell = priv->active_cell;
-  priv->old_page_first_cell = priv->page_first_cell;
-
-  priv->active_cell = _cell;
-
-  /* update page, if necessary */
-  if (_cell < priv->page_first_cell ||
-      _cell - priv->page_first_cell >= priv->page_size)
-    {
-      /* move the page_first_cell as far as active_cell has moved */
-      int offset = priv->active_cell - priv->old_active_cell;
-
-      if (priv->old_page_first_cell + offset < 0)
-        priv->page_first_cell = 0;
-      else if (priv->old_page_first_cell +
-               offset >
-               priv->last_cell -
-               (priv->last_cell % priv->cols) -
-               priv->cols * (priv->rows - 1))
-        priv->page_first_cell = priv->last_cell -
-                                     (priv->last_cell % priv->cols) -
-                                     priv->cols * (priv->rows - 1);
-      else
-        priv->page_first_cell = priv->old_page_first_cell + offset;
-    
-      /* FIXMEchpe: this should be fixed in the conditions above, but just do it for now: */
-      if (priv->page_first_cell < 0)
-        priv->page_first_cell = 0;
-
-      /* round down so that it's a multiple of priv->cols */
-      priv->page_first_cell -= (priv->page_first_cell % priv->cols);
-    
-      /* go back up if we should have rounded up */
-      if (priv->active_cell - priv->page_first_cell >= priv->page_size)
-        priv->page_first_cell += priv->cols;
-    }
-
-  g_object_notify (G_OBJECT (chartable), "active-character");
-
-  /* FIXMEchpe: update the scroll adjustment! */
-}
-
-static void
-set_active_char (GucharmapChartable *chartable,
-                 gunichar        wc)
-{
-  GucharmapChartablePrivate *priv = chartable->priv;
-
-  guint cell = gucharmap_codepoint_list_get_index (priv->codepoint_list, wc);
-  if (cell == -1) {
-    gtk_widget_error_bell (GTK_WIDGET (chartable));
-    return;
-  }
-
-  gucharmap_chartable_set_active_cell (chartable, cell);
-}
-
-static void
-draw_borders (GucharmapChartable *chartable)
-{
-  GucharmapChartablePrivate *priv = chartable->priv;
-  GtkWidget *widget = GTK_WIDGET (chartable);
-  GtkAllocation *allocation;
-  GtkStyle *style;
-  gint x, y, col, row;
-#if GTK_CHECK_VERSION (2, 18, 0)
-  GtkAllocation widget_allocation;
-
-  gtk_widget_get_allocation (widget, &widget_allocation);
-  allocation = &widget_allocation;
-#else
-  allocation = &widget->allocation;
-#endif
-
-  /* dark_gc[GTK_STATE_NORMAL] seems to be what is used to draw the borders
-   * around widgets, so we use it for the lines */
-
-  style = gtk_widget_get_style (widget);
-
-  /* vertical lines */
-  gdk_draw_line (priv->pixmap,
-                 style->dark_gc[GTK_STATE_NORMAL],
-                 0, 0, 0, allocation->height - 1);
-  for (col = 0, x = 0;  col < priv->cols;  col++)
-    {
-      x += _gucharmap_chartable_column_width (chartable, col);
-      gdk_draw_line (priv->pixmap,
-                     style->dark_gc[GTK_STATE_NORMAL],
-                     x, 0, x, allocation->height - 1);
-    }
-
-  /* horizontal lines */
-  gdk_draw_line (priv->pixmap,
-                 style->dark_gc[GTK_STATE_NORMAL],
-                 0, 0, allocation->width - 1, 0);
-  for (row = 0, y = 0;  row < priv->rows;  row++)
-    {
-      y += _gucharmap_chartable_row_height (chartable, row);
-      gdk_draw_line (priv->pixmap,
-                     style->dark_gc[GTK_STATE_NORMAL],
-                     0, y, allocation->width - 1, y);
-    }
-}
-
-static void
-set_scrollbar_adjustment (GucharmapChartable *chartable)
-{
-  GucharmapChartablePrivate *priv = chartable->priv;
-
-  /* block our "value_changed" handler */
-  g_signal_handler_block (G_OBJECT (priv->vadjustment),
-                          priv->vadjustment_changed_handler_id);
-
-  gtk_adjustment_set_value (priv->vadjustment, 1.0 * priv->page_first_cell / priv->cols);
-
-  g_signal_handler_unblock (G_OBJECT (priv->vadjustment),
-                            priv->vadjustment_changed_handler_id);
-}
-
-/* for mouse clicks */
 static gunichar
-get_cell_at_xy (GucharmapChartable *chartable, 
-                gint            x, 
+get_cell_at_xy (GucharmapChartable *chartable,
+                gint            x,
                 gint            y)
 {
   GucharmapChartablePrivate *priv = chartable->priv;
@@ -917,19 +784,20 @@ get_cell_at_xy (GucharmapChartable *chartable,
 }
 
 static void
-draw_character (GucharmapChartable *chartable, 
-                gint            row, 
+draw_character (GucharmapChartable *chartable,
+                cairo_t            *cr,
+                gint            row,
                 gint            col)
 {
   GucharmapChartablePrivate *priv = chartable->priv;
   GtkWidget *widget = GTK_WIDGET (chartable);
   gint padding_x, padding_y;
   gint char_width, char_height;
-  gint square_width, square_height; 
+  gint square_width, square_height;
   gunichar wc;
   guint cell;
-  GdkGC *gc;
   GtkStyle *style;
+  GdkColor *color;
   gchar buf[10];
   gint n;
 
@@ -939,23 +807,23 @@ draw_character (GucharmapChartable *chartable,
   if (wc > UNICHAR_MAX || !gucharmap_unichar_validate (wc) || !gucharmap_unichar_isdefined (wc))
     return;
 
+  cairo_save (cr);
+
   style = gtk_widget_get_style (widget);
 
-#if GTK_CHECK_VERSION (2, 18, 0)
   if (gtk_widget_has_focus (widget) && (gint)cell == priv->active_cell)
-#else
-  if (GTK_WIDGET_HAS_FOCUS (widget) && (gint)cell == priv->active_cell)
-#endif
-    gc = style->text_gc[GTK_STATE_SELECTED];
+    color = &style->text[GTK_STATE_SELECTED];
   else if ((gint)cell == priv->active_cell)
-    gc = style->text_gc[GTK_STATE_ACTIVE];
+    color = &style->text[GTK_STATE_ACTIVE];
   else
-    gc = style->text_gc[GTK_STATE_NORMAL];
+    color = &style->text[GTK_STATE_NORMAL];
+
+  gdk_cairo_set_source_color (cr, color);
 
   square_width = _gucharmap_chartable_column_width (chartable, col) - 1;
   square_height = _gucharmap_chartable_row_height (chartable, row) - 1;
 
-  n = gucharmap_unichar_to_printable_utf8 (wc, buf); 
+  n = gucharmap_unichar_to_printable_utf8 (wc, buf);
   pango_layout_set_text (priv->pango_layout, buf, n);
 
   pango_layout_get_pixel_size (priv->pango_layout, &char_width, &char_height);
@@ -964,59 +832,18 @@ draw_character (GucharmapChartable *chartable,
   padding_x = (square_width - char_width) - (square_width - char_width)/2;
   padding_y = (square_height - char_height) - (square_height - char_height)/2;
 
-  gdk_draw_layout (priv->pixmap, gc,
-                   _gucharmap_chartable_x_offset (chartable, col) + padding_x,
-                   _gucharmap_chartable_y_offset (chartable, row) + padding_y,
-                   priv->pango_layout);
-}
-
-static void
-draw_square_bg (GucharmapChartable *chartable, gint row, gint col)
-{
-  GucharmapChartablePrivate *priv = chartable->priv;
-  GtkWidget *widget = GTK_WIDGET (chartable);
-  gint square_width, square_height; 
-  GdkGC *gc;
-  GdkColor untinted;
-  GtkStyle *style;
-  guint cell;
-  gunichar wc;
-
-  cell = get_cell_at_rowcol (chartable, row, col);
-  wc = gucharmap_codepoint_list_get_char (priv->codepoint_list, cell);
+  cairo_rectangle (cr,
+                   _gucharmap_chartable_x_offset (chartable, col) + 1,
+                   _gucharmap_chartable_y_offset (chartable, row) + 1,
+                   _gucharmap_chartable_column_width (chartable, col) - 2,
+                   _gucharmap_chartable_row_height (chartable, row) - 2);
+  cairo_clip (cr);
+  cairo_move_to (cr,
+                 _gucharmap_chartable_x_offset (chartable, col) + padding_x,
+                 _gucharmap_chartable_y_offset (chartable, row) + padding_y);
+  pango_cairo_show_layout (cr, priv->pango_layout);
 
-  gc = gdk_gc_new (GDK_DRAWABLE (gtk_widget_get_window (widget)));
-
-  style = gtk_widget_get_style (widget);
-
-#if GTK_CHECK_VERSION (2, 18, 0)
-  if (gtk_widget_has_focus (widget) && (gint)cell == priv->active_cell)
-#else
-  if (GTK_WIDGET_HAS_FOCUS (widget) && (gint)cell == priv->active_cell)
-#endif
-    untinted = style->base[GTK_STATE_SELECTED];
-  else if ((gint)cell == priv->active_cell)
-    untinted = style->base[GTK_STATE_ACTIVE];
-  else if ((gint)cell > priv->last_cell)
-    untinted = style->dark[GTK_STATE_NORMAL];
-  else if (! gucharmap_unichar_validate (wc))
-    untinted = style->fg[GTK_STATE_INSENSITIVE];
-  else if (! gucharmap_unichar_isdefined (wc))
-    untinted = style->bg[GTK_STATE_INSENSITIVE];
-  else
-    untinted = style->base[GTK_STATE_NORMAL];
-
-  gdk_gc_set_rgb_fg_color (gc, &untinted);
-
-  square_width = _gucharmap_chartable_column_width (chartable, col) - 1;
-  square_height = _gucharmap_chartable_row_height (chartable, row) - 1;
-
-  gdk_draw_rectangle (priv->pixmap, gc, TRUE,
-                      _gucharmap_chartable_x_offset (chartable, col), 
-		      _gucharmap_chartable_y_offset (chartable, row),
-                      square_width, square_height);
-
-  g_object_unref (gc);
+  cairo_restore (cr);
 }
 
 static void
@@ -1032,15 +859,8 @@ expose_square (GucharmapChartable *chartable, gint row, gint col)
 }
 
 static void
-draw_square (GucharmapChartable *chartable, gint row, gint col)
-{
-  draw_square_bg (chartable, row, col);
-  draw_character (chartable, row, col);
-}
-
-static void
-draw_and_expose_cell (GucharmapChartable *chartable,
-                      guint cell)
+expose_cell (GucharmapChartable *chartable,
+             guint cell)
 {
   GucharmapChartablePrivate *priv = chartable->priv;
 
@@ -1048,64 +868,65 @@ draw_and_expose_cell (GucharmapChartable *chartable,
   gint col = _gucharmap_chartable_cell_column (chartable, cell);
 
   if (row >= 0 && row < priv->rows && col >= 0 && col < priv->cols)
-    {
-      draw_square (chartable, row, col);
-      expose_square (chartable, row, col);
-    }
+    expose_square (chartable, row, col);
 }
 
-/* draws the backing store pixmap */
 static void
-draw_chartable_from_scratch (GucharmapChartable *chartable)
+draw_square_bg (GucharmapChartable *chartable,
+                cairo_t *cr,
+                gint row,
+                gint col)
 {
   GucharmapChartablePrivate *priv = chartable->priv;
   GtkWidget *widget = GTK_WIDGET (chartable);
-  gint row, col;
-  GtkAllocation *allocation;
-#if GTK_CHECK_VERSION (2, 18, 0)
-  GtkAllocation widget_allocation;
+  GdkColor *untinted;
+  GtkStyle *style;
+  guint cell;
+  gunichar wc;
 
-  gtk_widget_get_allocation (widget, &widget_allocation);
-  allocation = &widget_allocation;
-#else
-  allocation = &widget->allocation;
-#endif
+  cairo_save (cr);
 
-  /* drawing area may not be exposed yet when restoring last char setting
-   */
-#if GTK_CHECK_VERSION (2, 20, 0)
-  if (!gtk_widget_get_realized (GTK_WIDGET (chartable)))
-#else
-  if (!GTK_WIDGET_REALIZED (chartable))
-#endif
-    return;
+  cell = get_cell_at_rowcol (chartable, row, col);
+  wc = gucharmap_codepoint_list_get_char (priv->codepoint_list, cell);
 
-  if (priv->pixmap == NULL)
-    priv->pixmap = gdk_pixmap_new (
-	    gtk_widget_get_window (widget),
-	    allocation->width,
-	    allocation->height, -1);
+  style = gtk_widget_get_style (widget);
+
+  if (gtk_widget_has_focus (widget) && (gint)cell == priv->active_cell)
+    untinted = &style->base[GTK_STATE_SELECTED];
+  else if ((gint)cell == priv->active_cell)
+    untinted = &style->base[GTK_STATE_ACTIVE];
+  else if ((gint)cell > priv->last_cell)
+    untinted = &style->dark[GTK_STATE_NORMAL];
+  else if (! gucharmap_unichar_validate (wc))
+    untinted = &style->fg[GTK_STATE_INSENSITIVE];
+  else if (! gucharmap_unichar_isdefined (wc))
+    untinted = &style->bg[GTK_STATE_INSENSITIVE];
+  else
+    untinted = &style->base[GTK_STATE_NORMAL];
 
-  draw_borders (chartable);
+  gdk_cairo_set_source_color (cr, untinted);
+  cairo_set_line_width (cr, 1);
+  cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
 
-  /* draw the characters */
-  for (row = 0;  row < priv->rows;  row++)
-    for (col = 0;  col < priv->cols;  col++)
-      {
-        draw_square_bg (chartable, row, col);
-        draw_character (chartable, row, col);
-      }
+  cairo_rectangle (cr,
+                   _gucharmap_chartable_x_offset (chartable, col),
+                   _gucharmap_chartable_y_offset (chartable, row),
+                   _gucharmap_chartable_column_width (chartable, col),
+                   _gucharmap_chartable_row_height (chartable, row));
+  cairo_fill (cr);
+
+  cairo_restore (cr);
 }
 
 static void
-copy_rows (GucharmapChartable *chartable, gint row_offset)
+draw_borders (GucharmapChartable *chartable,
+              cairo_t *cr)
 {
   GucharmapChartablePrivate *priv = chartable->priv;
   GtkWidget *widget = GTK_WIDGET (chartable);
-  gint num_padded_rows = priv->n_padded_rows;
-  gint from_row, to_row;
-  GtkStyle *style;
   GtkAllocation *allocation;
+  GtkStyle *style;
+  gint x, y, col, row;
 #if GTK_CHECK_VERSION (2, 18, 0)
   GtkAllocation widget_allocation;
 
@@ -1115,194 +936,184 @@ copy_rows (GucharmapChartable *chartable, gint row_offset)
   allocation = &widget->allocation;
 #endif
 
-  style = gtk_widget_get_style (widget);
+  cairo_save (cr);
 
-  if (ABS (row_offset) < priv->rows - num_padded_rows)
-    {
-      gint num_rows, height;
+  /* dark_gc[GTK_STATE_NORMAL] seems to be what is used to draw the borders
+   * around widgets, so we use it for the lines */
 
-      if (row_offset > 0)
-        {
-          from_row = row_offset;
-          to_row = 0;
-          num_rows = priv->rows - num_padded_rows - from_row;
-        }
-      else
-        {
-          from_row = 0;
-          to_row = -row_offset;
-          num_rows = priv->rows - num_padded_rows - to_row;
-        }
+  style = gtk_widget_get_style (widget);
+  gdk_cairo_set_source_color (cr, &style->dark[GTK_STATE_NORMAL]);
+
+  cairo_set_line_width (cr, 1); /* FIXME themeable? */
+  cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
 
-      height = _gucharmap_chartable_y_offset (chartable, num_rows) 
-               - _gucharmap_chartable_y_offset (chartable, 0) - 1;
+  /* vertical lines */
+  cairo_move_to (cr, .5, .5);
+  cairo_line_to (cr, .5, allocation->height - .5);
 
-      gdk_draw_drawable (
-              priv->pixmap,
-              style->base_gc[GTK_STATE_NORMAL],
-              priv->pixmap,
-              0, _gucharmap_chartable_y_offset (chartable, from_row), 
-              0, _gucharmap_chartable_y_offset (chartable, to_row),
-              allocation->width, height);
+  for (col = 0, x = 0;  col < priv->cols;  col++)
+    {
+      x += _gucharmap_chartable_column_width (chartable, col);
+      cairo_move_to (cr, x + .5, .5);
+      cairo_line_to (cr, x + .5, allocation->height - .5);
     }
 
-  if (ABS (row_offset) < num_padded_rows)
+  /* horizontal lines */
+  cairo_move_to (cr, .5, .5);
+  cairo_line_to (cr, allocation->width - .5, .5);
+
+  for (row = 0, y = 0;  row < priv->rows;  row++)
     {
-      /* don't need num_rows or height, cuz we can go off the end */
-      if (row_offset > 0)
-        {
-          from_row = priv->rows - num_padded_rows + row_offset;
-          to_row = priv->rows - num_padded_rows;
-        }
-      else
-        {
-          from_row = priv->rows - num_padded_rows;
-          to_row = priv->rows - num_padded_rows - row_offset;
-        }
+      y += _gucharmap_chartable_row_height (chartable, row);
 
-      /* it's ok to go off the end (so use allocation.height) */
-      gdk_draw_drawable (
-              priv->pixmap,
-              style->base_gc[GTK_STATE_NORMAL],
-              priv->pixmap,
-              0, _gucharmap_chartable_y_offset (chartable, from_row), 
-              0, _gucharmap_chartable_y_offset (chartable, to_row),
-              allocation->width,
-              allocation->height);
+      cairo_move_to (cr, .5, y + .5);
+      cairo_line_to (cr, allocation->width - .5, y + .5);
     }
+
+  cairo_stroke (cr);
+  cairo_restore (cr);
 }
 
 static void
-redraw_rows (GucharmapChartable *chartable, gint row_offset)
+gucharmap_chartable_draw (GucharmapChartable *chartable,
+                          cairo_t *cr,
+                          int start_row,
+                          int end_row,
+                          int start_col,
+                          int end_col)
 {
-  GucharmapChartablePrivate *priv = chartable->priv;
-  gint row, col, start_row, end_row;
-
-  if (row_offset > 0) 
-    {
-      start_row = priv->rows - row_offset;
-      end_row = priv->rows - 1;
-    }
-  else
-    {
-      start_row = 0;
-      end_row = -row_offset - 1;
-    }
+  int row, col;
 
-  for (row = 0;  row <= priv->rows;  row++)
+  for (row = start_row;  row < end_row; ++row)
     {
-      gboolean draw_row = FALSE;
-
-      draw_row = draw_row || (row >= start_row && row <= end_row);
-
-      if (row + row_offset >= 0 && row + row_offset <= priv->rows)
+      for (col = start_col;  col < end_col; ++col)
         {
-          draw_row = draw_row || (_gucharmap_chartable_row_height (chartable, row) 
-                                  != _gucharmap_chartable_row_height (chartable,  
-                                                         row + row_offset));
-        }
-
-      if (draw_row)
-        {
-          for (col = 0;  col < priv->cols;  col++)
-            draw_square (chartable, row, col);
+          draw_square_bg (chartable, cr, row, col);
+          draw_character (chartable, cr, row, col);
         }
     }
+
+  draw_borders (chartable, cr);
 }
 
-/* Redraws whatever needs to be redrawn, in the character table and
- * everything, and exposes what needs to be exposed. */
-void
-_gucharmap_chartable_redraw (GucharmapChartable *chartable, 
-                         gboolean        move_zoom)
+static void
+update_scrollbar_adjustment (GucharmapChartable *chartable)
 {
   GucharmapChartablePrivate *priv = chartable->priv;
-  GtkWidget *widget = GTK_WIDGET (chartable);
-  gint row_offset;
-  gboolean actives_done = FALSE;
-
-  row_offset = ((gint) priv->page_first_cell - (gint) priv->old_page_first_cell) / priv->cols;
+  GtkAdjustment *vadjustment = priv->vadjustment;
 
-#ifdef G_OS_WIN32
+  if (!vadjustment)
+    return;
 
-  if (row_offset != 0)
-    {
-      /* get around the bug in gdkdrawable-win32.c */
-      /* yup, this makes it really slow */
-      draw_chartable_from_scratch (chartable);
-      gtk_widget_queue_draw (widget);
-      actives_done = TRUE;
-    }
+  gtk_adjustment_configure (vadjustment,
+                            1.0 * priv->page_first_cell / priv->cols,
+                            0.0 /* lower */,
+                            1.0 * ((priv->last_cell + priv->cols - 1) / priv->cols) /* upper */,
+                            3.0 /* step increment */,
+                            1.0 * priv->rows /* page increment */,
+                            priv->rows);
+}
 
-#else /* #ifdef G_OS_WIN32 */
+static void
+gucharmap_chartable_set_active_cell (GucharmapChartable *chartable,
+                                     int cell)
+{
+  GtkWidget *widget = GTK_WIDGET (chartable);
+  GucharmapChartablePrivate *priv = chartable->priv;
+  int old_active_cell, old_page_first_cell;
 
-  if (priv->codepoint_list_changed
-          || row_offset >= priv->rows
-          || row_offset <= -priv->rows)
-    {
-      draw_chartable_from_scratch (chartable);
-      gtk_widget_queue_draw (widget);
-      actives_done = TRUE;
-      priv->codepoint_list_changed = FALSE;
-    }
-  else if (row_offset != 0)
-    {
-      copy_rows (chartable, row_offset);
-      redraw_rows (chartable, row_offset);
-      draw_borders (chartable);
-      gtk_widget_queue_draw (widget);
-    }
+  if (cell == priv->active_cell)
+    return;
 
-#endif
+  if (cell < 0)
+    cell = 0;
+  else if (cell > priv->last_cell)
+    cell = priv->last_cell;
 
-  if (priv->active_cell != priv->old_active_cell)
-    {
-      set_scrollbar_adjustment (chartable); /* XXX */
+  old_active_cell = priv->active_cell;
+  old_page_first_cell = priv->page_first_cell;
 
-      if (!actives_done)
-        {
-          draw_and_expose_cell (chartable, priv->old_active_cell);
-          draw_and_expose_cell (chartable, priv->active_cell);
-        }
+  priv->active_cell = cell;
 
-      if (priv->zoom_window)
-        update_zoom_window (chartable);
+  if (cell < priv->page_first_cell || cell >= priv->page_first_cell + priv->page_size)
+    {
+      int old_row = old_active_cell / priv->cols;
+      int new_row = cell / priv->cols;
+      int row_delta = new_row - old_row;
+      int delta = row_delta * priv->cols;
+      int first_cell_on_last_page = priv->last_cell - (priv->last_cell % priv->cols) - priv->cols * (priv->rows - 1);
+      int new_page_first_cell = old_page_first_cell + delta;
+
+      if (new_page_first_cell < 0)
+        priv->page_first_cell = 0;
+      else if (new_page_first_cell > first_cell_on_last_page)
+        priv->page_first_cell = first_cell_on_last_page;
+      else
+        priv->page_first_cell = new_page_first_cell;
 
-      if (move_zoom && priv->zoom_window)
-        {
-          place_zoom_window_on_active_cell (chartable);
-        }
+      if (priv->vadjustment)
+        gtk_adjustment_set_value (priv->vadjustment, 1.0 * priv->page_first_cell / priv->cols);
     }
+  else if (gtk_widget_get_realized (widget)) {
+    expose_cell (chartable, old_active_cell);
+    expose_cell (chartable, cell);
+  }
 
-  priv->old_page_first_cell = priv->page_first_cell;
-  priv->old_active_cell = priv->active_cell;
+  g_object_notify (G_OBJECT (chartable), "active-character");
+
+  update_zoom_window (chartable); 
+  place_zoom_window_on_active_cell (chartable);
 }
 
 static void
-update_scrollbar_adjustment (GucharmapChartable *chartable)
+set_active_char (GucharmapChartable *chartable,
+                 gunichar        wc)
 {
   GucharmapChartablePrivate *priv = chartable->priv;
-  GtkAdjustment *vadjustment = priv->vadjustment;
 
-  if (!vadjustment)
+  guint cell = gucharmap_codepoint_list_get_index (priv->codepoint_list, wc);
+  if (cell == -1) {
+    gtk_widget_error_bell (GTK_WIDGET (chartable));
     return;
+  }
 
-  gtk_adjustment_configure (vadjustment,
-                            1.0 * priv->page_first_cell / priv->cols,
-                            0.0,
-                            1.0 * ( priv->last_cell / priv->cols + 1 ),
-                            3.0,
-                            1.0 * priv->rows,
-                            /* FIXMEchpe: shouldn't set page size at all! */
-                            /* FIXMEchpe + 1 maybe? so scroll-wheel up/down scroll exactly half a page? */
-                            priv->rows);
+  gucharmap_chartable_set_active_cell (chartable, cell);
 }
 
 static void
-vadjustment_value_changed_cb (GtkAdjustment *adjustment, GucharmapChartable *chartable)
+vadjustment_value_changed_cb (GtkAdjustment *vadjustment, 
+                              GucharmapChartable *chartable)
 {
-  set_top_row (chartable, (gint) gtk_adjustment_get_value (adjustment));
-  _gucharmap_chartable_redraw (chartable, TRUE);
+  GucharmapChartablePrivate *priv = chartable->priv;
+  int row, r, c, old_page_first_cell, old_active_cell, first_cell;
+
+  row = (int) gtk_adjustment_get_value (vadjustment);
+
+  if (row < 0 || row > priv->last_cell / priv->cols)
+    row = 0;
+
+  first_cell = row * priv->cols;
+
+  gtk_widget_queue_draw (GTK_WIDGET (chartable));
+
+  old_page_first_cell = priv->page_first_cell;
+  old_active_cell = priv->active_cell;
+
+  priv->page_first_cell = first_cell;
+
+  /* character is still on the visible page */
+  if (priv->active_cell - priv->page_first_cell >= 0
+      && priv->active_cell - priv->page_first_cell < priv->page_size)
+    return;
+
+  c = old_active_cell % priv->cols;
+
+  if (priv->page_first_cell < old_page_first_cell)
+    r = priv->rows - 1;
+  else
+    r = 0;
+
+  gucharmap_chartable_set_active_cell (chartable, priv->page_first_cell + r * priv->cols + c);
 }
 
 /* GtkWidget class methods */
@@ -1336,25 +1147,11 @@ gucharmap_chartable_button_press (GtkWidget *widget,
   else if (event->button == 1 && event->type == GDK_BUTTON_PRESS) 
     {
       gucharmap_chartable_set_active_cell (chartable, get_cell_at_xy (chartable, event->x, event->y));
-      _gucharmap_chartable_redraw (chartable, TRUE);
     }
   else if (event->button == 3)
     {
       gucharmap_chartable_set_active_cell (chartable, get_cell_at_xy (chartable, event->x, event->y));
-      _gucharmap_chartable_redraw (chartable, FALSE); /* FIXMEchpe */
-
-      if (priv->zoom_mode_enabled)
-      {
-        make_zoom_window (chartable);
-
-        /* FIXME: shouldn't this be "!=" ? */
-        if (priv->active_cell == priv->old_active_cell)
-          update_zoom_window (chartable); 
-
-        place_zoom_window (chartable, event->x_root, event->y_root);
-        gtk_widget_show (priv->zoom_window);
-        g_object_notify (G_OBJECT (chartable), "zoom-showing");
-      }
+      gucharmap_chartable_show_zoom (chartable);
     }
 
   /* XXX: [need to return false so it gets drag events] */
@@ -1456,7 +1253,7 @@ gucharmap_chartable_drag_data_received (GtkWidget *widget,
     {
       gucharmap_chartable_emit_status_message (chartable, _("Character found."));
       set_active_char (chartable, wc);
-      _gucharmap_chartable_redraw (chartable, TRUE);
+      place_zoom_window_on_active_cell (chartable);
     }
 
   g_free (text);
@@ -1470,42 +1267,26 @@ gucharmap_chartable_expose_event (GtkWidget *widget,
 {
   GucharmapChartable *chartable = GUCHARMAP_CHARTABLE (widget);
   GucharmapChartablePrivate *priv = chartable->priv;
-#if GTK_CHECK_VERSION(2,90,5)
-  cairo_rectangle_int_t *rect;
-  cairo_rectangle_int_t r;
-#else
-  GdkRectangle *rects;
-  GdkRectangle *rect;
-#endif
-  int i, n_rects;
-  GdkGC *gc;
   GtkStyle *style;
-  GdkWindow *window;
+  cairo_t *cr;
 
-  /* Don't draw anything if we haven't set a codepoint list yet */
-  if (priv->codepoint_list == NULL)
+  if (event->window != gtk_widget_get_window (widget))
     return FALSE;
 
-  if (priv->pixmap == NULL)
-    {
-      draw_chartable_from_scratch (chartable);
-    }
-
 #if GTK_CHECK_VERSION(2,90,5)
   if (cairo_region_is_empty (event->region))
     return FALSE;
-  n_rects = cairo_region_num_rectangles (event->region);
 #else
   if (gdk_region_empty (event->region))
     return FALSE;
-  gdk_region_get_rectangles (event->region, &rects, &n_rects);
 #endif
 
-  if (n_rects == 0)
-    return FALSE;
-
 #if 0
   {
+    int i, n_rects;
+
+    n_rects = cairo_region_num_rectangles (event->region);
+
     g_print ("Exposing area %d:%d@(%d,%d) with %d rects ", event->area.width, event->area.height,
              event->area.x, event->area.y, n_rects);
     for (i = 0; i < n_rects; ++i) {
@@ -1515,29 +1296,25 @@ gucharmap_chartable_expose_event (GtkWidget *widget,
   }
 #endif
 
+  cr = gdk_cairo_create (event->window);
+  gdk_cairo_region (cr, event->region);
+  cairo_clip (cr);
+
   style = gtk_widget_get_style (widget);
-  window = gtk_widget_get_window (widget);
+  gdk_cairo_set_source_color (cr, &style->bg[GTK_STATE_NORMAL]);
+  gdk_cairo_region (cr, event->region);
+  cairo_fill (cr);
 
-  gc = style->fg_gc[GTK_STATE_NORMAL];
-  for (i = 0; i < n_rects; ++i) {
-#if GTK_CHECK_VERSION(2,90,5)
-    cairo_region_get_rectangle (event->region, i, &r);
-    rect = &r;
-#else
-    rect = rects + i;
-#endif
-    gdk_draw_drawable (window,
-                       gc,
-                       priv->pixmap,
-                       rect->x, rect->y,
-                       rect->x, rect->y,
-                       rect->width, rect->height);
+  if (priv->codepoint_list == NULL) {
+    cairo_destroy (cr);
+    return FALSE;
   }
 
-#if GTK_CHECK_VERSION(2,90,5)
-#else
-  g_free (rects);
-#endif
+  gucharmap_chartable_draw (chartable, cr,
+                            0, priv->rows,
+                            0, priv->cols);
+
+  cairo_destroy (cr);
 
   /* no need to chain up */
   return FALSE;
@@ -1550,8 +1327,7 @@ gucharmap_chartable_focus_in_event (GtkWidget *widget,
   GucharmapChartable *chartable = GUCHARMAP_CHARTABLE (widget);
   GucharmapChartablePrivate *priv = chartable->priv;
 
-  if (priv->pixmap != NULL)
-    draw_and_expose_cell (chartable, priv->active_cell);
+  expose_cell (chartable, priv->active_cell);
 
   return GTK_WIDGET_CLASS (gucharmap_chartable_parent_class)->focus_in_event (widget, event);
 }
@@ -1565,8 +1341,7 @@ gucharmap_chartable_focus_out_event (GtkWidget *widget,
 
   gucharmap_chartable_hide_zoom (chartable);
 
-  if (priv->pixmap != NULL)
-    draw_and_expose_cell (chartable, priv->active_cell);
+  expose_cell (chartable, priv->active_cell);
 
   /* FIXME: the parent's handler already does a draw... */
 
@@ -1648,7 +1423,6 @@ gucharmap_chartable_motion_notify (GtkWidget *widget,
         {
           gtk_widget_hide (priv->zoom_window);
           gucharmap_chartable_set_active_cell (chartable, cell);
-          _gucharmap_chartable_redraw (chartable, FALSE);
         }
 
       place_zoom_window (chartable, event->x_root, event->y_root);
@@ -1660,23 +1434,6 @@ gucharmap_chartable_motion_notify (GtkWidget *widget,
   return FALSE;
 }
 
-static void
-gucharmap_chartable_realize (GtkWidget *widget)
-{
-  GucharmapChartable *chartable = GUCHARMAP_CHARTABLE (widget);
-  GucharmapChartablePrivate *priv = chartable->priv;
-
-  GTK_WIDGET_CLASS (gucharmap_chartable_parent_class)->realize (widget);
-
-  gdk_window_set_back_pixmap (gtk_widget_get_window (widget), NULL, FALSE);
-    
-  if (priv->pixmap != NULL)
-    {
-      g_object_unref (priv->pixmap);
-      priv->pixmap = NULL;
-    }
-}
-
 #define FIRST_CELL_IN_SAME_ROW(x) ((x) - ((x) % priv->cols))
 
 static void
@@ -1735,11 +1492,6 @@ gucharmap_chartable_size_allocate (GtkWidget *widget,
   priv->minimal_row_height = bare_minimal_row_height + total_extra_pixels / priv->rows;
   priv->n_padded_rows = allocation->height - (priv->minimal_row_height * priv->rows + 1);
 
-  /* force pixmap to be redrawn on next expose event */
-  if (priv->pixmap != NULL)
-    g_object_unref (priv->pixmap);
-  priv->pixmap = NULL;
-
   if (priv->rows == old_rows && priv->cols == old_cols)
     return;
 
@@ -1780,10 +1532,6 @@ gucharmap_chartable_style_set (GtkWidget *widget,
 
   GTK_WIDGET_CLASS (gucharmap_chartable_parent_class)->style_set (widget, previous_style);
 
-  if (priv->pixmap != NULL)
-    g_object_unref (priv->pixmap);
-  priv->pixmap = NULL;
-
   if (priv->pango_layout)
     g_object_unref (priv->pango_layout);
   priv->pango_layout = NULL;
@@ -1926,15 +1674,11 @@ gucharmap_chartable_move_cursor_left_right (GucharmapChartable *chartable,
   GucharmapChartablePrivate *priv = chartable->priv;
   GtkWidget *widget = GTK_WIDGET (chartable);
   gboolean is_rtl;
-  int offset, new_cell;
+  int offset;
 
   is_rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
   offset = is_rtl ? -count : count;
-  new_cell = priv->active_cell + offset;
-
-  if (new_cell >= 0 &&
-      new_cell <= priv->last_cell)
-    gucharmap_chartable_set_active_cell (chartable, new_cell);
+  gucharmap_chartable_set_active_cell (chartable, priv->active_cell + offset);
 }
 
 static void
@@ -1942,12 +1686,9 @@ gucharmap_chartable_move_cursor_up_down (GucharmapChartable *chartable,
                                          int count)
 {
   GucharmapChartablePrivate *priv = chartable->priv;
-  int new_cell;
 
-  new_cell = priv->active_cell + priv->cols * count;
-  if (new_cell >= 0 &&
-      new_cell <= priv->last_cell)
-    gucharmap_chartable_set_active_cell (chartable, new_cell);
+  gucharmap_chartable_set_active_cell (chartable, 
+                                       priv->active_cell + priv->cols * count);
 }
 
 static void
@@ -1955,12 +1696,9 @@ gucharmap_chartable_move_cursor_page_up_down (GucharmapChartable *chartable,
                                               int count)
 {
   GucharmapChartablePrivate *priv = chartable->priv;
-  int page_size, new_cell;
 
-  page_size = priv->cols * priv->rows;
-  new_cell = priv->active_cell + page_size * count;
-  new_cell = CLAMP (new_cell, 0, priv->last_cell);
-  gucharmap_chartable_set_active_cell (chartable, new_cell);
+  gucharmap_chartable_set_active_cell (chartable, 
+                                       priv->active_cell + priv->page_size * count);
 }
 
 static void
@@ -2008,8 +1746,6 @@ gucharmap_chartable_move_cursor (GucharmapChartable *chartable,
       g_assert_not_reached ();
     }
 
-  _gucharmap_chartable_redraw (chartable, TRUE);
-
   return TRUE;
 }
 
@@ -2067,11 +1803,7 @@ gucharmap_chartable_paste_clipboard (GucharmapChartable *chartable)
   GtkClipboard *clipboard;
   gpointer *data;
 
-#if GTK_CHECK_VERSION (2, 20, 0)
   if (!gtk_widget_get_realized (GTK_WIDGET (chartable)))
-#else
-  if (!GTK_WIDGET_REALIZED (chartable))
-#endif
     return;
 
   data = g_slice_new (gpointer);
@@ -2244,7 +1976,6 @@ gucharmap_chartable_class_init (GucharmapChartableClass *klass)
   widget_class->key_press_event = gucharmap_chartable_key_press_event;
   widget_class->key_release_event = gucharmap_chartable_key_release_event;
   widget_class->motion_notify_event = gucharmap_chartable_motion_notify;
-  widget_class->realize = gucharmap_chartable_realize;
   widget_class->size_allocate = gucharmap_chartable_size_allocate;
   widget_class->size_request = gucharmap_chartable_size_request;
   widget_class->style_set = gucharmap_chartable_style_set;
@@ -2617,7 +2348,6 @@ gucharmap_chartable_set_active_character (GucharmapChartable *chartable,
                                           gunichar wc)
 {
   set_active_char (chartable, wc);
-  _gucharmap_chartable_redraw (chartable, TRUE);
 }
 
 /**
@@ -2692,11 +2422,6 @@ gucharmap_chartable_set_codepoint_list (GucharmapChartable     *chartable,
   else
     priv->last_cell = 0;
 
-  /* force pixmap to be redrawn */
-  if (priv->pixmap != NULL)
-    g_object_unref (priv->pixmap);
-  priv->pixmap = NULL;
-
   g_object_notify (object, "codepoint-list");
   g_object_notify (object, "active-character");
 
diff --git a/gucharmap/gucharmap-private.h b/gucharmap/gucharmap-private.h
index 7df7ed8..4f34e86 100644
--- a/gucharmap/gucharmap-private.h
+++ b/gucharmap/gucharmap-private.h
@@ -52,11 +52,8 @@ struct _GucharmapChartablePrivate {
 
   int page_first_cell; /* the cell index of the top left corner */
   int active_cell;     /* the active cell index */
-  int old_page_first_cell;
-  int old_active_cell;
 
   /* Drawing */
-  GdkPixmap *pixmap;
   PangoLayout *pango_layout;
 
   /* Zoom popup */
diff --git a/gucharmap/gucharmap-search-dialog.c b/gucharmap/gucharmap-search-dialog.c
index ddb9b87..b2ba675 100644
--- a/gucharmap/gucharmap-search-dialog.c
+++ b/gucharmap/gucharmap-search-dialog.c
@@ -615,11 +615,12 @@ _gucharmap_search_dialog_fire_search (GucharmapSearchDialog *search_dialog,
   GucharmapCodepointList *list;
   gunichar start_char;
   gint start_index;
+  GdkCursor *cursor;
 
   if (priv->search_state && priv->search_state->searching) /* Already searching */
     return;
 
-  GdkCursor *cursor = _gucharmap_window_progress_cursor ();
+  cursor = gdk_cursor_new_for_display (gtk_widget_get_display (GTK_WIDGET (search_dialog)), GDK_WATCH);
   gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (search_dialog)), cursor);
   gdk_cursor_unref (cursor);
 
diff --git a/gucharmap/gucharmap-window.c b/gucharmap/gucharmap-window.c
index f2c8894..84383ac 100644
--- a/gucharmap/gucharmap-window.c
+++ b/gucharmap/gucharmap-window.c
@@ -171,60 +171,6 @@ update_progress_bar (GucharmapWindow *guw)
     }
 }
 
-/* "progress" aka "busy-interactive" cursor (pointer + watch)
- * from mozilla 
- * caller should gdk_cursor_unref */
-GdkCursor *
-_gucharmap_window_progress_cursor (void)
-{
-  /* MOZ_CURSOR_SPINNING */
-  static const char moz_spinning_bits[] = 
-    {
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
-      0x00, 0x0c, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x3c, 0x00,
-      0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xfc,
-      0x01, 0x00, 0x00, 0xfc, 0x3b, 0x00, 0x00, 0x7c, 0x38, 0x00, 0x00,
-      0x6c, 0x54, 0x00, 0x00, 0xc4, 0xdc, 0x00, 0x00, 0xc0, 0x44, 0x00,
-      0x00, 0x80, 0x39, 0x00, 0x00, 0x80, 0x39, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 
-    };
-  static const char moz_spinning_mask_bits[] = 
-    {
-      0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00,
-      0x00, 0x1e, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x7e, 0x00,
-      0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x00, 0x00, 0xfe,
-      0x3b, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00,
-      0xfe, 0xfe, 0x00, 0x00, 0xee, 0xff, 0x01, 0x00, 0xe4, 0xff, 0x00,
-      0x00, 0xc0, 0x7f, 0x00, 0x00, 0xc0, 0x7f, 0x00, 0x00, 0x80, 0x39,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 
-    };
-
-  GdkPixmap *cursor, *mask;
-  GdkCursor *gdkcursor;
-  GdkColor fg = { 0, 0, 0, 0 };             /* black */
-  GdkColor bg = { 0, 65535, 65535, 65535 }; /* white */
-
-  cursor = gdk_bitmap_create_from_data (NULL, moz_spinning_bits, 32, 32);
-  mask = gdk_bitmap_create_from_data (NULL, moz_spinning_mask_bits, 32, 32);
-
-  gdkcursor = gdk_cursor_new_from_pixmap (cursor, mask, &fg, &bg, 2, 2);
-
-  g_object_unref (cursor);
-  g_object_unref (mask);
-
-  return gdkcursor;
-}
-
 static void
 search_start (GucharmapSearchDialog *search_dialog,
               GucharmapWindow       *guw)
@@ -232,7 +178,7 @@ search_start (GucharmapSearchDialog *search_dialog,
   GdkCursor *cursor;
   GtkAction *action;
 
-  cursor = _gucharmap_window_progress_cursor ();
+  cursor = gdk_cursor_new_for_display (gtk_widget_get_display (GTK_WIDGET (guw)), GDK_WATCH);
   gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (guw)), cursor);
   gdk_cursor_unref (cursor);
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]