2007-07-16 Holger Hans Peter Freyther <zecke@selfish.org>
authorzecke <zecke@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 16 Jul 2007 20:39:03 +0000 (20:39 +0000)
committerzecke <zecke@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 16 Jul 2007 20:39:03 +0000 (20:39 +0000)
        Reviewed by Niko.

        FrameView, PlatformScrollbar and changes to the way we draw

        Fix the lifetime of PlatformScrollbar, use a default width and
        height and fix drawing of the PlatformScrollbar and other widgets
        the following way: FrameGdk handles the expose events of the Frame
        and will make the frame redraw and now it will draw the childrent of
        the FrameView as well. This approach has the issue of honoring the
        z-order of elements inside the RenderTree. Honoring the z-order will
        be a bit more work

        Widget can now handle Widget::setGtkWidget call where the GtkWidget
        has not yet a GdkWindow allocated. We will lazily set the GdkDrawable.

        In preparation of honoring the z-order of the RenderTree for RenderWidgets
        it is started to store native objects inside the GraphicsContext. Doing this
        nicely eliminates the need of RenderThemeGdk to do any drawing to a temporary
        GdkPixmap. This should fix themes with rounded buttons.

        ScrollView implement add- and removeChild to get a working PlatformScrollbar

        * platform/Widget.h:
        * platform/gdk/FrameGdk.cpp:
        (frame_gdk_expose_child): Will send the expose to all children
        (WebCore::FrameGdk::handleGdkEvent): Painting changes, move to mouseMoved
        * platform/gdk/PlatformScreenGdk.cpp:
        (WebCore::screenDepth): gdkDrawable
        * platform/gdk/PlatformScrollBarGdk.cpp:
        (PlatformScrollbar::PlatformScrollbar): Fix ownership
        (PlatformScrollbar::~PlatformScrollbar): Fix ownership
        (PlatformScrollbar::paint): Widget::paint will do the right thing soon
        * platform/gdk/RenderThemeGdk.cpp: No need for using a GdkPixmap, draw directly
        (WebCore::RenderThemeGdk::paintCheckbox): No need for using a GdkPixmap, draw directly
        (WebCore::RenderThemeGdk::paintRadio): No need for using a GdkPixmap, draw directly
        (WebCore::RenderThemeGdk::paintButton): No need for using a GdkPixmap, draw directly
        * platform/gdk/RenderThemeGdk.h: remove the copyContext call
        * platform/gdk/ScrollViewGdk.cpp: gdkDrawable
        (WebCore::ScrollView::updateView): gdkDrawable
        (WebCore::ScrollView::update): clear the area to fix repainting issues
        (WebCore::ScrollView::setGtkWidget): gdkDrawable
        (WebCore::ScrollView::addChild): implement
        (WebCore::ScrollView::removeChild): implement
        * platform/gdk/TemporaryLinkStubs.cpp: Not needed header removed
        * platform/gdk/WidgetGdk.cpp:
        (WebCore::Widget::gdkDrawable): Renamed from drawable
        (WebCore::Widget::setGtkWidget): use gdkDrawable
        (WebCore::Widget::setCursor): gdkDrawable
        (WebCore::Widget::show): gdkDrawable
        (WebCore::Widget::hide): gdkDrawable
        * platform/graphics/GraphicsContext.h: Allow to set the GdkDrawable, e.g. used inside a expose event
        * platform/graphics/cairo/GraphicsContextCairo.cpp:
        (WebCore::GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate):
        (WebCore::GraphicsContext::setGdkDrawable):
        (WebCore::GraphicsContext::gdkDrawable):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@24322 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
WebCore/ChangeLog
WebCore/platform/Widget.h
WebCore/platform/gdk/FrameGdk.cpp
WebCore/platform/gdk/PlatformScreenGdk.cpp
WebCore/platform/gdk/PlatformScrollBarGdk.cpp
WebCore/platform/gdk/RenderThemeGdk.cpp
WebCore/platform/gdk/RenderThemeGdk.h
WebCore/platform/gdk/ScrollViewGdk.cpp
WebCore/platform/gdk/TemporaryLinkStubs.cpp
WebCore/platform/gdk/WidgetGdk.cpp
WebCore/platform/graphics/GraphicsContext.h
WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp

index d8d956b7a077995b1efde784aa2256a21f3d5441..e41961a501e53f63c6b8fe5889a5b79a745d7cd1 100644 (file)
@@ -1,3 +1,62 @@
+2007-07-16  Holger Hans Peter Freyther  <zecke@selfish.org>
+
+        Reviewed by Niko.
+
+        FrameView, PlatformScrollbar and changes to the way we draw
+
+        Fix the lifetime of PlatformScrollbar, use a default width and
+        height and fix drawing of the PlatformScrollbar and other widgets
+        the following way: FrameGdk handles the expose events of the Frame
+        and will make the frame redraw and now it will draw the childrent of
+        the FrameView as well. This approach has the issue of honoring the
+        z-order of elements inside the RenderTree. Honoring the z-order will
+        be a bit more work
+
+        Widget can now handle Widget::setGtkWidget call where the GtkWidget
+        has not yet a GdkWindow allocated. We will lazily set the GdkDrawable.
+
+        In preparation of honoring the z-order of the RenderTree for RenderWidgets
+        it is started to store native objects inside the GraphicsContext. Doing this
+        nicely eliminates the need of RenderThemeGdk to do any drawing to a temporary
+        GdkPixmap. This should fix themes with rounded buttons.
+
+        ScrollView implement add- and removeChild to get a working PlatformScrollbar
+
+
+        * platform/Widget.h:
+        * platform/gdk/FrameGdk.cpp:
+        (frame_gdk_expose_child): Will send the expose to all children
+        (WebCore::FrameGdk::handleGdkEvent): Painting changes, move to mouseMoved
+        * platform/gdk/PlatformScreenGdk.cpp:
+        (WebCore::screenDepth): gdkDrawable
+        * platform/gdk/PlatformScrollBarGdk.cpp:
+        (PlatformScrollbar::PlatformScrollbar): Fix ownership
+        (PlatformScrollbar::~PlatformScrollbar): Fix ownership
+        (PlatformScrollbar::paint): Widget::paint will do the right thing soon
+        * platform/gdk/RenderThemeGdk.cpp: No need for using a GdkPixmap, draw directly
+        (WebCore::RenderThemeGdk::paintCheckbox): No need for using a GdkPixmap, draw directly
+        (WebCore::RenderThemeGdk::paintRadio): No need for using a GdkPixmap, draw directly
+        (WebCore::RenderThemeGdk::paintButton): No need for using a GdkPixmap, draw directly
+        * platform/gdk/RenderThemeGdk.h: remove the copyContext call
+        * platform/gdk/ScrollViewGdk.cpp: gdkDrawable
+        (WebCore::ScrollView::updateView): gdkDrawable
+        (WebCore::ScrollView::update): clear the area to fix repainting issues
+        (WebCore::ScrollView::setGtkWidget): gdkDrawable
+        (WebCore::ScrollView::addChild): implement
+        (WebCore::ScrollView::removeChild): implement
+        * platform/gdk/TemporaryLinkStubs.cpp: Not needed header removed
+        * platform/gdk/WidgetGdk.cpp:
+        (WebCore::Widget::gdkDrawable): Renamed from drawable
+        (WebCore::Widget::setGtkWidget): use gdkDrawable
+        (WebCore::Widget::setCursor): gdkDrawable
+        (WebCore::Widget::show): gdkDrawable
+        (WebCore::Widget::hide): gdkDrawable
+        * platform/graphics/GraphicsContext.h: Allow to set the GdkDrawable, e.g. used inside a expose event
+        * platform/graphics/cairo/GraphicsContextCairo.cpp:
+        (WebCore::GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate):
+        (WebCore::GraphicsContext::setGdkDrawable):
+        (WebCore::GraphicsContext::gdkDrawable):
+
 2007-07-16  Holger Hans Peter Freyther  <zecke@selfish.org>
 
         Reviewed by Maciej.
index 7b71a217ceb9cb291ca84e044b7ecdcb35b9b4ed..8135c3a967062864c82d4f823deabb1294e4f1b1 100644 (file)
@@ -138,7 +138,7 @@ namespace WebCore {
 #if PLATFORM(GDK)
         Widget(GtkWidget*);
         virtual void setGtkWidget(GtkWidget*);
-        GdkDrawable* drawable() const;
+        GdkDrawable* gdkDrawable() const;
         GtkWidget* gtkWidget() const;
 #endif
 
index d29b5e6370777a09a09011981cc85168f586de41..9fa1be6ee334ffb21c113c712aba5b5279a529f5 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
  * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com 
+ * Copyright (C) 2007 Holger Hans Peter Freyther
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -70,6 +71,18 @@ Vector<char> loadResourceIntoArray(const char* resourceName)
     return resource;
 }
 
+struct FrameGdkExposeData {
+    GtkContainer *container;
+    GdkEventExpose *expose;
+};
+
+static void frame_gdk_expose_child(GtkWidget *widget, gpointer _data)
+{
+    FrameGdkExposeData* data = (FrameGdkExposeData*)_data;
+    int width, height;
+    gtk_container_propagate_expose(data->container, widget, data->expose);
+} 
+
 namespace WebCore {
 
 FrameGdk::FrameGdk(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClientGdk* frameLoader)
@@ -140,6 +153,7 @@ void FrameGdk::handleGdkEvent(GdkEvent* event)
             gdk_window_begin_paint_region(event->any.window, event->expose.region);
             cairo_t* cr = gdk_cairo_create(event->any.window);
             GraphicsContext ctx(cr);
+            ctx.setGdkDrawable(event->any.window);
             if (renderer()) {
                 if (view()->needsLayout())
                     view()->layout();
@@ -147,7 +161,14 @@ void FrameGdk::handleGdkEvent(GdkEvent* event)
                 paint(&ctx, rect);
             }
             cairo_destroy(cr);
+
+            /*
+             * Make sure children of the view get redrawn
+             */
+            FrameGdkExposeData data = { GTK_CONTAINER(view()->gtkWidget()), &event->expose };
+            gtk_container_forall(GTK_CONTAINER(view()->gtkWidget()), frame_gdk_expose_child, &data);
             gdk_window_end_paint(event->any.window);
+            
             break;
         }
 
@@ -190,7 +211,7 @@ void FrameGdk::handleGdkEvent(GdkEvent* event)
             break;
         }
         case GDK_MOTION_NOTIFY:
-            eventHandler()->handleMouseMoveEvent(PlatformMouseEvent(event));
+            eventHandler()->mouseMoved(PlatformMouseEvent(event));
             break;
         case GDK_BUTTON_PRESS:
         case GDK_2BUTTON_PRESS:
index 6604be7fabd35189de04cfb99c9bc4fa535a58f4..f378215786c246e356233729fd76c420318c9af4 100644 (file)
@@ -38,10 +38,10 @@ namespace WebCore {
 
 int screenDepth(Widget* widget) 
 {
-    ASSERT(widget->drawable());
+    ASSERT(widget->gdkDrawable());
 
     gint dummy, depth;
-    gdk_window_get_geometry(widget->drawable(), &dummy, &dummy, &dummy, &dummy, &depth);
+    gdk_window_get_geometry(widget->gdkDrawable(), &dummy, &dummy, &dummy, &dummy, &depth);
     return depth;
 }
 
index 7c25fe225596693f5dc11b7b06ce7e7922bda8ef..650b36e89519be0c2d5e2ac82904139e6dee9c94 100644 (file)
 
 #include "config.h"
 #include "PlatformScrollBar.h"
+#include "IntRect.h"
+#include "GraphicsContext.h"
 
 #include "NotImplemented.h"
 #include <gtk/gtk.h>
+#include <cairo/cairo.h>
 #include <stdio.h>
 
 using namespace WebCore;
@@ -41,14 +44,27 @@ PlatformScrollbar::PlatformScrollbar(ScrollbarClient* client, ScrollbarOrientati
     GtkScrollbar* scrollBar = orientation == HorizontalScrollbar ?
                               GTK_SCROLLBAR(::gtk_hscrollbar_new(NULL)) :
                               GTK_SCROLLBAR(::gtk_vscrollbar_new(NULL));
+    gtk_widget_show(GTK_WIDGET(scrollBar));
     setGtkWidget(GTK_WIDGET(scrollBar));
+
+    /*
+     * assign a sane default width and height to the ScrollBar, otherwise
+     * we will end up with a 0 width scrollbar.
+     */
+    resize(PlatformScrollbar::horizontalScrollbarHeight(),
+           PlatformScrollbar::verticalScrollbarWidth());    
+
+    g_object_ref(G_OBJECT(scrollBar));
+    gtk_object_sink(GTK_OBJECT(scrollBar));
 }
+
 PlatformScrollbar::~PlatformScrollbar()
 {
     /*
      * the Widget does not take over ownership.
      */
-    gtk_object_unref(GTK_OBJECT(gtkWidget()));
+    gtk_widget_destroy(gtkWidget());
+    g_object_unref(G_OBJECT(gtkWidget()));
 }
 
 int PlatformScrollbar::width() const
@@ -66,9 +82,9 @@ void PlatformScrollbar::setEnabled(bool enabled)
     Widget::setEnabled(enabled);
 }
 
-void PlatformScrollbar::paint(GraphicsContext*, const IntRect&)
+void PlatformScrollbar::paint(GraphicsContext* graphicsContext, const IntRect& damageRect)
 {
-    notImplemented();
+    Widget::paint(graphicsContext, damageRect);
 }
 
 void PlatformScrollbar::updateThumbPosition()
index c201d257ccc496e2722184efbcf57052420ff9e4..a72b49227f2336ffe40b68a31de6fad8dfda9fed 100644 (file)
@@ -187,12 +187,10 @@ bool RenderThemeGdk::paintCheckbox(RenderObject* o, const RenderObject::PaintInf
 {
     // FIXME: is it the right thing to do?
     GtkWidget *checkbox = gtkCheckbox();
-    GdkPixmap *pixmap = gdk_pixmap_new(GDK_DRAWABLE(checkbox->window), rect.width(), rect.height(), -1);
-    gtk_paint_box(checkbox->style, GDK_DRAWABLE(pixmap),
+    gtk_paint_box(checkbox->style, i.context->gdkDrawable(),
                   GTK_STATE_NORMAL, GTK_SHADOW_OUT,
                   NULL, checkbox, "checkbutton",
-                  0, 0, rect.width(), rect.height());
-    copyToContext(pixmap, i.context->platformContext(), rect);
+                  rect.x(), rect.y(), rect.width(), rect.height());
 
     return false;
 }
@@ -221,12 +219,10 @@ bool RenderThemeGdk::paintRadio(RenderObject* o, const RenderObject::PaintInfo&
 { 
     // FIXME: is it the right thing to do?
     GtkWidget *radio = gtkRadioButton();
-    GdkPixmap *pixmap = gdk_pixmap_new(GDK_DRAWABLE(radio->window), rect.width(), rect.height(), -1);
-    gtk_paint_box(radio->style, GDK_DRAWABLE(pixmap),
+    gtk_paint_box(radio->style, i.context->gdkDrawable(),
                   GTK_STATE_NORMAL, GTK_SHADOW_OUT,
                   NULL, radio, "radiobutton",
-                  0, 0, rect.width(), rect.height());
-    copyToContext(pixmap, i.context->platformContext(), rect);
+                  rect.x(), rect.y(), rect.width(), rect.height());
 
     return false;
 }
@@ -235,12 +231,10 @@ bool RenderThemeGdk::paintButton(RenderObject*, const RenderObject::PaintInfo& i
 { 
     // FIXME: should use theme-aware drawing. This should honor the state as well
     GtkWidget *button = gtkButton();
-    GdkPixmap *pixmap = gdk_pixmap_new(GDK_DRAWABLE(button->window), rect.width(), rect.height(), -1);
-    gtk_paint_box(button->style, GDK_DRAWABLE(pixmap),
+    gtk_paint_box(button->style, i.context->gdkDrawable(),
                   GTK_STATE_NORMAL, GTK_SHADOW_OUT,
                   NULL, button, "button",
-                  0, 0, rect.width(), rect.height());
-    copyToContext(pixmap, i.context->platformContext(), rect);
+                  rect.x(), rect.y(), rect.width(), rect.height());
     return false;
 }
 
@@ -269,18 +263,6 @@ void RenderThemeGdk::systemFont(int propId, FontDescription&) const
 {
 }
 
-/*
- * copy the src surface to the current context at position (rect.x,rect.y) and invalidate
- * GdkPixmap
- */
-void RenderThemeGdk::copyToContext(GdkPixmap *src, cairo_t* cr, const IntRect& rect)
-{
-    gdk_cairo_set_source_pixmap(cr, src, rect.x(), rect.y());
-    cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
-    cairo_paint(cr);
-    g_object_unref(src);
-}
-
 GtkWidget* RenderThemeGdk::gtkButton() const
 {
     if (!m_gtkButton) {
index e166f11921ed6c885e010eb3474bed04feb829de..6a933527200234374a89bdfc8970bc993ea24f84 100644 (file)
@@ -90,8 +90,6 @@ private:
      */
     GtkWidget* gtkWindowContainer() const;
 
-    void copyToContext(GdkPixmap *src, PlatformGraphicsContext*, const IntRect&);
-
 private:
     mutable GtkWidget *m_gtkButton;
     mutable GtkWidget *m_gtkCheckbox;
index d58f3a1c50b20cd2e2832ff1b9a95ae9903be8ad..09192b35497f502c01ec38f49d23d0871ab76934 100644 (file)
@@ -83,7 +83,7 @@ ScrollView::~ScrollView()
 void ScrollView::updateView(const IntRect& updateRect, bool now)
 {
     GdkRectangle rect = { updateRect.x(), updateRect.y(), updateRect.width(), updateRect.height() };
-    GdkDrawable* gdkdrawable = Widget::drawable();
+    GdkDrawable* gdkdrawable = Widget::gdkDrawable();
     if (GDK_IS_WINDOW(gdkdrawable)) {
         GdkWindow* window = GDK_WINDOW(gdkdrawable);
         gdk_window_invalidate_rect(window, &rect, true);
@@ -260,20 +260,26 @@ void ScrollView::setGtkWidget(GtkLayout* layout)
     m_data->verticalAdjustment = gtk_layout_get_vadjustment(layout);
 
     Widget::setGtkWidget(GTK_WIDGET(layout));
-    if (!GDK_IS_WINDOW(drawable())) {
+    if (!GDK_IS_WINDOW(gdkDrawable())) {
         LOG_ERROR("image scrollview not supported");
         return;
     }
 }
 
-void ScrollView::addChild(Widget*)
+void ScrollView::addChild(Widget* w)
 { 
-    notImplemented();
+    ASSERT(w->gtkWidget());
+    ASSERT(m_data->layout);
+
+    gtk_layout_put(m_data->layout, w->gtkWidget(), 0, 0);
 }
 
-void ScrollView::removeChild(Widget*)
+void ScrollView::removeChild(Widget* w)
 {
-    notImplemented();
+    ASSERT(w->gtkWidget());
+    ASSERT(m_data->layout);
+
+    gtk_container_remove(GTK_CONTAINER(m_data->layout), w->gtkWidget());
 }
 
 void ScrollView::scrollRectIntoViewRecursively(const IntRect&)
index 9383ed12c75f0071e29d006600eda02b7f4889c3..29fd6ab41b0e47dfca7f22c6a15e89f2fbd1a701 100644 (file)
@@ -64,7 +64,6 @@
 #include "NotImplemented.h"
 #include "Pasteboard.h"
 #include "PlatformMouseEvent.h"
-#include "PlatformScrollBar.h"
 #include "PlugInInfoStore.h"
 #include "ResourceError.h"
 #include "ResourceHandle.h"
index b42b7e192ed2860ea34b13e998cd58fea6369938..36ba02bd25874b885c9f87b01e2cbeadc8016eab 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
  * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com 
+ * Copyright (C) 2007 Holger Hans Peter Freyther
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -63,8 +64,10 @@ Widget::Widget(GtkWidget* widget)
     setGtkWidget(widget);
 }
 
-GdkDrawable* Widget::drawable() const
+GdkDrawable* Widget::gdkDrawable() const
 {
+    if (!data->drawable && data->widget)
+        data->drawable = GTK_IS_LAYOUT(data->widget) ? GTK_LAYOUT(data->widget)->bin_window : data->widget->window;
     return data->drawable;
 }
 
@@ -75,7 +78,7 @@ GtkWidget* Widget::gtkWidget() const
 
 void Widget::setGtkWidget(GtkWidget* widget)
 {
-    data->drawable = GTK_IS_LAYOUT(widget) ? GTK_LAYOUT(widget)->bin_window : widget->window;
+    data->drawable = 0;
     data->widget = widget;
 }
 
@@ -113,7 +116,7 @@ void Widget::setCursor(const Cursor& cursor)
     if (!pcur)
         return;
 
-    GdkDrawable* drawable = data->drawable;
+    GdkDrawable* drawable = gdkDrawable();
     if (!drawable || !GDK_IS_WINDOW(drawable))
         return;
     GdkWindow* window = GDK_WINDOW(drawable);
@@ -123,7 +126,7 @@ void Widget::setCursor(const Cursor& cursor)
 
 void Widget::show()
 {
-    GdkDrawable* drawable = data->drawable;
+    GdkDrawable* drawable = gdkDrawable();
     if (!drawable || !GDK_IS_WINDOW(drawable))
         return;
     GdkWindow* window = GDK_WINDOW(drawable);
@@ -132,7 +135,7 @@ void Widget::show()
 
 void Widget::hide()
 {
-    GdkDrawable* drawable = data->drawable;
+    GdkDrawable* drawable = gdkDrawable();
     if (!drawable || !GDK_IS_WINDOW(drawable))
         return;
     GdkWindow* window = GDK_WINDOW(drawable);
index 2bf3bf4d50ba312daa52302824e0a754b6a8a35b..430f25961bad3759f7610f194171226741716e45 100644 (file)
@@ -45,6 +45,10 @@ typedef QPainter PlatformGraphicsContext;
 typedef void PlatformGraphicsContext;
 #endif
 
+#if PLATFORM(GDK)
+typedef struct _GdkDrawable GdkDrawable;
+#endif
+
 #if PLATFORM(WIN)
 typedef struct HDC__* HDC;
 #endif
@@ -202,6 +206,11 @@ namespace WebCore {
         PlatformPath* currentPath();
 #endif
 
+#if PLATFORM(GDK)
+        void setGdkDrawable(GdkDrawable*);
+        GdkDrawable *gdkDrawable() const;
+#endif
+
     private:
         void savePlatformState();
         void restorePlatformState();
index be041c74989277b8f33639d006fe51c39ddacfb0..b092a3d209693a9f415002fa25a6aa9f7d1c10f8 100644 (file)
 #include <cairo-win32.h>
 #endif
 
+#if PLATFORM(GDK)
+#include <gdk/gdk.h>
+#endif
+
 
 #ifndef M_PI
 #define M_PI 3.14159265358979323846
@@ -59,6 +63,10 @@ public:
 
     cairo_t* cr;
     Vector<float> layers;
+
+#if PLATFORM(GDK)
+    GdkDrawable *drawable;
+#endif
 };
 
 static inline void setColor(cairo_t* cr, const Color& col)
@@ -79,6 +87,9 @@ static inline void fillRectSourceOver(cairo_t* cr, const FloatRect& rect, const
 
 GraphicsContextPlatformPrivate::GraphicsContextPlatformPrivate()
     :  cr(0)
+#if PLATFORM(GDK)
+    , drawable(0)
+#endif
 {
 }
 
@@ -786,6 +797,18 @@ void GraphicsContext::fillRoundedRect(const IntRect&, const IntSize& topLeft, co
     notImplemented();
 }
 
+#if PLATFORM(GDK)
+void GraphicsContext::setGdkDrawable(GdkDrawable* drawable)
+{
+    m_data->drawable = drawable;
+}
+
+GdkDrawable* GraphicsContext::gdkDrawable() const
+{
+    return m_data->drawable;
+}
+#endif
+
 } // namespace WebCore
 
 #endif // PLATFORM(CAIRO)