diff --git a/src/gfx.c b/src/gfx.c
index 021a6b7..8bc42cd 100644
--- a/src/gfx.c
+++ b/src/gfx.c
@@ -19,8 +19,6 @@
 #include "mainwin.h"
 #include "game.h"
 
-GdkPixmap *_pixmap = NULL;
-
 /* x and y of cell "under pointer" */
 gint _pointer_x = 0, _pointer_y = 0;
 
@@ -38,6 +36,7 @@ volatile gint _phase = 0;
 /* jumping animation timer tag */
 guint _timer_tag = 0;
 
+
 gboolean have_path(gint source_ball, gint target_ball);
 void move_ball(gint source_ball, gint target_ball);
 
@@ -64,27 +63,20 @@ gint get_destroy_phase(gint x, gint y) {
    return board_get_destroy_at_xy(x, y);
 }
 
-void update_rectangle(gint x, gint y, gint w, gint h) {
-   GtkWidget *widget = mw_get_da();
-
-   if (!widget || !_pixmap) {
-      return;
-   }
-   gdk_draw_drawable (gtk_widget_get_window (widget),
-   widget->style->fg_gc[gtk_widget_get_state(widget)],
-   _pixmap, x, y, x, y, w, h);
+static void update_rectangle (gint x, gint y, gint w, gint h)
+{
+   GtkWidget * board_w = mw_get_da();
+   gtk_widget_queue_draw_area (board_w, x, y, w, h);
 }
 
 void draw_ball_no_update(gint ballcolor, gint x, gint y, gint jumpnum, gint destroynum)
 {
-   GtkWidget *widget = mw_get_da();
-   GdkGC *gc = widget->style->fg_gc[gtk_widget_get_state(widget)];
    gint cxs = gtkbTheme->emptycell.xsize;
    gint cys = gtkbTheme->emptycell.ysize;
    GtkbPixmap *obj;
    gint xr, yr;
 
-   if (!widget || !_pixmap) {
+   if (!pixsurf) {
       return;
    }
 
@@ -93,13 +85,12 @@ void draw_ball_no_update(gint ballcolor, gint x, gint y, gint jumpnum, gint dest
    } else {
       obj = &gtkbTheme->emptycell;
    }
-   gdk_draw_pixbuf (_pixmap,
-                    gc,
-                    obj->pixbuf,
-                    0, 0,
-                    x * cxs, y * cys,
-                    cxs, cys,
-                    GDK_RGB_DITHER_NONE, 0, 0);
+
+   cairo_t * cr = cairo_create (pixsurf);
+   gdk_cairo_set_source_pixbuf (cr, obj->pixbuf, x * cxs, y * cys);
+   cairo_rectangle (cr, x * cxs, y * cys, cxs, cys);
+   cairo_fill (cr);
+
 
    if (ballcolor > 0) { /* ball */
       if (!jumpnum && !destroynum) { /* still ball */
@@ -117,13 +108,10 @@ void draw_ball_no_update(gint ballcolor, gint x, gint y, gint jumpnum, gint dest
 
    xr = x * cxs + (cxs - obj->xsize) / 2;
    yr = y * cys + (cys - obj->ysize) / 2;
-   gdk_draw_pixbuf (_pixmap,
-                    gc,
-                    obj->pixbuf,
-                    0, 0,
-                    xr, yr,
-                    obj->xsize, obj->ysize,
-                    GDK_RGB_DITHER_NONE, 0, 0);
+
+   gdk_cairo_set_source_pixbuf (cr, obj->pixbuf, xr, yr);
+   cairo_paint (cr);
+   cairo_destroy (cr);
 }
 
 void draw_ball(gint ballcolor, gint x, gint y, gint jumpnum, gint destroynum) {
@@ -147,8 +135,9 @@ void redraw_pointer(void) {
 
 void draw_board(void) {
    gint i, j;
+   GtkWidget * board_w = mw_get_da();
 
-   if (!mw_get_da()) {
+   if (!board_w) {
       return;
    }
    for (j = 0; j < rules_get_height(); j++) {
@@ -158,7 +147,8 @@ void draw_board(void) {
          }
       }
    }
-   update_rectangle(0, 0, -1, -1);
+
+   gtk_widget_queue_draw (board_w);
 }
 
 gint inc_with_limit(gint val, gint lim) {
@@ -342,10 +332,17 @@ void remake_board(gint numoldchilds, gboolean isnextvalid) {
    cxs = gtkbTheme->emptycell.xsize;
    cys = gtkbTheme->emptycell.ysize;
    gtk_widget_set_size_request(mw_get_da(), rules_get_width() * cxs, rules_get_height() * cys);
-   if (_pixmap) {
-      g_object_unref(_pixmap);
+   if (pixsurf) {
+      g_object_unref(pixsurf);
    }
-   _pixmap = gdk_pixmap_new(mw_get_da()->window, rules_get_width() * cxs, rules_get_height() * cys, -1);
+
+   if (pixsurf) {
+      cairo_surface_destroy (pixsurf);
+   }
+   pixsurf = gdk_window_create_similar_surface (gtk_widget_get_window (mw_get_da()),
+                                                CAIRO_CONTENT_COLOR_ALPHA,
+                                                rules_get_width() * cxs, rules_get_height() * cys);
+
    draw_board();
 }
 
@@ -358,22 +355,25 @@ void draw_next_balls(void) {
 }
 
 /* Refill the screen from the backing pixmap */
-gint expose_event(GtkWidget *widget, GdkEventExpose *event) {
-   GdkRectangle *rects;
-   int n_rects;
-   int i;
+gint expose_event (GtkWidget *widget, GdkEventExpose *event)
+{
+   cairo_t * cr = gdk_cairo_create (gtk_widget_get_window (widget));
+   GdkRectangle * area = &(event->area);
 
-   gdk_region_get_rectangles(event->region, &rects, &n_rects);
-
-   for (i = 0; i < n_rects; i++) {
-      gdk_draw_drawable (gtk_widget_get_window (widget),
-                         widget->style->fg_gc[gtk_widget_get_state(widget)],
-                         _pixmap, rects[i].x, rects[i].y, rects[i].x, rects[i].y,
-                         rects[i].width, rects[i].height);
+   GtkAllocation a;
+   gtk_widget_get_allocation (widget, &a);
+   if (area->width == a.width) {
+      cairo_set_source_surface (cr, pixsurf, 0, 0);
+      cairo_paint (cr);
+   } else {
+      //cairo_save (cr);
+      cairo_translate (cr, area->x, area->y);
+      cairo_set_source_surface (cr, pixsurf, -area->x, -area->y);
+      cairo_rectangle (cr, 0, 0, area->width, area->height);
+      cairo_fill (cr);
+      //cairo_restore (cr);
    }
-
-   g_free (rects);
-
+   cairo_destroy (cr);
    return FALSE;
 }
 
diff --git a/src/mainwin.c b/src/mainwin.c
index ae1979e..50d756e 100644
--- a/src/mainwin.c
+++ b/src/mainwin.c
@@ -25,13 +25,17 @@ GtkWidget *_user_score_label = NULL;
 /* box for next balls */
 GtkWidget *_small_balls_box;
 
-/* Backing pixmap for drawing area */
+/* board */
 GtkWidget *_drawing_area = NULL;
 
 GtkWidget *mw_get_da(void) {
    return _drawing_area;
 }
 
+/* Backing pixmap for drawing area */
+cairo_surface_t * pixsurf = NULL;
+
+
 /* add child widget to "next balls" display area */
 void mw_small_balls_add(GtkWidget *child) {
    gtk_box_pack_start(GTK_BOX(_small_balls_box), child, FALSE, FALSE, 0);
@@ -142,6 +146,10 @@ gint _user_action_event(GtkWidget *w, GdkEvent *ev)
 
 static void main_window_destroy_cb (GtkWidget * w, gpointer user_data)
 {
+   if (pixsurf) {
+      cairo_surface_destroy (pixsurf);
+      pixsurf = NULL;
+   }
    gtkb_theme_free_handler (NULL, NULL);
    gtk_main_quit ();
 }
diff --git a/src/mainwin.h b/src/mainwin.h
index d148865..ee32a7d 100644
--- a/src/mainwin.h
+++ b/src/mainwin.h
@@ -1,6 +1,8 @@
 #ifndef __MAINWIN_H__
 #define __MAINWIN_H__
 
+cairo_surface_t * pixsurf;
+
 void mw_create(gint da_width, gint da_height);
 void mw_small_balls_add(GtkWidget *child);
 void mw_show_hide_next_balls(gboolean show);