Bug 627699 - Port GTK2 to GTK3: Partial patch for nsWindow.cpp and associated files; r=karlt
authorMartin Stransky <stransky@redhat.com>
Thu, 22 Sep 2011 21:58:07 +0100
changeset 78393 875cb4f20eac2544dc1d3249ed7cffe4e3962f63
parent 78392 0c47234a402129649f1012e38a67eb70a05ad332
child 78394 9561bb68864bfb367bb28dcc263d2f1701d731a3
push id340
push userclegnitto@mozilla.com
push dateTue, 08 Nov 2011 22:56:33 +0000
treeherdermozilla-beta@f745dc151615 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskarlt
bugs627699
milestone9.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 627699 - Port GTK2 to GTK3: Partial patch for nsWindow.cpp and associated files; r=karlt
widget/src/gtk2/gtk2compat.h
widget/src/gtk2/nsWindow.cpp
widget/src/gtk2/nsWindow.h
widget/src/shared/nsShmImage.cpp
widget/src/shared/nsShmImage.h
new file mode 100644
--- /dev/null
+++ b/widget/src/gtk2/gtk2compat.h
@@ -0,0 +1,157 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim:expandtab:shiftwidth=4:tabstop=4:
+ */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is Martin Stransky
+ * <stransky@redhat.com>.  Portions created by the Initial Developer
+ * are Copyright (C) 2001 the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * gtk2compat.h: GTK2 compatibility routines
+ *
+ * gtk2compat provides an API which is not defined in GTK2.
+ */
+
+#ifndef _GTK2_COMPAT_H_
+#define _GTK2_COMPAT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#if !GTK_CHECK_VERSION(2, 14, 0)
+static inline GdkWindow*
+gtk_widget_get_window(GtkWidget *widget)
+{
+  return widget->window;
+}
+
+static inline const guchar *
+gtk_selection_data_get_data(GtkSelectionData *selection_data)
+{
+  return selection_data->data;
+}
+
+static inline gint
+gtk_selection_data_get_length(GtkSelectionData *selection_data)
+{
+  return selection_data->length;
+}
+
+static inline GdkAtom
+gtk_selection_data_get_target(GtkSelectionData *selection_data)
+{
+  return selection_data->target;
+}
+
+static inline GtkWidget *
+gtk_dialog_get_content_area(GtkDialog *dialog)
+{
+  return dialog->vbox;
+}
+#endif
+
+
+#if !GTK_CHECK_VERSION(2, 16, 0)
+static inline GdkAtom
+gtk_selection_data_get_selection(GtkSelectionData *selection_data)
+{
+  return selection_data->selection;
+}
+#endif
+
+#if !GTK_CHECK_VERSION(2, 18, 0)
+static inline gboolean
+gtk_widget_get_visible(GtkWidget *widget)
+{
+  return GTK_WIDGET_VISIBLE(widget);
+}
+
+static inline gboolean
+gtk_widget_has_focus(GtkWidget *widget)
+{
+  return GTK_WIDGET_HAS_FOCUS(widget);
+}
+
+static inline void
+gtk_widget_get_allocation(GtkWidget *widget, GtkAllocation *allocation)
+{
+  *allocation = widget->allocation;
+}
+
+static inline gboolean
+gdk_window_is_destroyed(GdkWindow *window)
+{
+  return GDK_WINDOW_OBJECT(window)->destroyed;
+}
+#endif
+
+#if !GTK_CHECK_VERSION(2, 22, 0)
+static inline gint
+gdk_visual_get_depth(GdkVisual *visual)
+{
+  return visual->depth;
+}
+
+static inline GdkDragAction
+gdk_drag_context_get_actions(GdkDragContext *context)
+{
+  return context->actions;
+}
+#endif
+
+#if !GTK_CHECK_VERSION(2, 24, 0)
+static inline GdkWindow *
+gdk_x11_window_lookup_for_display(GdkDisplay *display, Window window)
+{
+  return gdk_window_lookup_for_display(display, window);
+}
+
+static inline GdkDisplay *
+gdk_window_get_display(GdkWindow *window)
+{
+  return gdk_drawable_get_display(GDK_DRAWABLE(window));
+}
+#endif
+
+static inline Window 
+gdk_x11_window_get_xid(GdkWindow *window)
+{
+  return(GDK_WINDOW_XWINDOW(window));
+}
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif // _GTK2_COMPAT_H_
--- a/widget/src/gtk2/nsWindow.cpp
+++ b/widget/src/gtk2/nsWindow.cpp
@@ -18,16 +18,18 @@
  *
  * The Initial Developer of the Original Code is Christopher Blizzard
  * <blizzard@mozilla.org>.  Portions created by the Initial Developer
  * are Copyright (C) 2001 the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   Mats Palmgren <matspal@gmail.com>
  *   Masayuki Nakano <masayuki@d-toybox.com>
+ *   Martin Stransky <stransky@redhat.com>
+ *   Jan Horak <jhorak@redhat.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -53,32 +55,44 @@
 #include "nsWidgetsCID.h"
 #include "nsDragService.h"
 #include "nsIDragSessionGTK.h"
 
 #include "nsGtkKeyUtils.h"
 #include "nsGtkCursors.h"
 
 #include <gtk/gtk.h>
+#if defined(MOZ_WIDGET_GTK3)
+#include <gtk/gtkx.h>
+#endif
 #ifdef MOZ_X11
 #include <gdk/gdkx.h>
 #include <X11/Xatom.h>
 #include <X11/extensions/XShm.h>
 #include <X11/extensions/shape.h>
+#if defined(MOZ_WIDGET_GTK3)
+#include <gdk/gdkkeysyms-compat.h>
+#endif
 
 #ifdef AIX
 #include <X11/keysym.h>
 #else
 #include <X11/XF86keysym.h>
 #endif
 
 #include "gtk2xtbin.h"
 #endif /* MOZ_X11 */
 #include <gdk/gdkkeysyms.h>
+#if defined(MOZ_WIDGET_GTK2)
 #include <gtk/gtkprivate.h>
+#endif
+
+#if defined(MOZ_WIDGET_GTK2)
+#include "gtk2compat.h"
+#endif
 
 #include "nsWidgetAtoms.h"
 
 #ifdef MOZ_ENABLE_STARTUP_NOTIFICATION
 #define SN_API_NOT_YET_FROZEN
 #include <startup-notification-1.0/libsn/sn.h>
 #endif
 
@@ -132,16 +146,17 @@ extern "C" {
 #include "gfxImageSurface.h"
 #include "gfxUtils.h"
 #include "Layers.h"
 #include "LayerManagerOGL.h"
 #include "GLContextProvider.h"
 
 #ifdef MOZ_X11
 #include "gfxXlibSurface.h"
+#include "cairo-xlib.h"
 #endif
 
 #include "nsShmImage.h"
 
 #ifdef MOZ_DFB
 extern "C" {
 #ifdef MOZ_DIRECT_DEBUG
 #define DIRECT_ENABLE_DEBUG
@@ -181,18 +196,23 @@ static GdkWindow *get_inner_gdk_window (
 static inline PRBool is_context_menu_key(const nsKeyEvent& inKeyEvent);
 static void   key_event_to_context_menu_event(nsMouseEvent &aEvent,
                                               GdkEventKey *aGdkEvent);
 
 static int    is_parent_ungrab_enter(GdkEventCrossing *aEvent);
 static int    is_parent_grab_leave(GdkEventCrossing *aEvent);
 
 /* callbacks from widgets */
+#if defined(MOZ_WIDGET_GTK2)
 static gboolean expose_event_cb           (GtkWidget *widget,
                                            GdkEventExpose *event);
+#else
+static gboolean expose_event_cb           (GtkWidget *widget,
+                                           cairo_t *rect);
+#endif
 static gboolean configure_event_cb        (GtkWidget *widget,
                                            GdkEventConfigure *event);
 static void     container_unrealize_cb    (GtkWidget *widget);
 static void     size_allocate_cb          (GtkWidget *widget,
                                            GtkAllocation *allocation);
 static gboolean delete_event_cb           (GtkWidget *widget,
                                            GdkEventAny *event);
 static gboolean enter_notify_event_cb     (GtkWidget *widget,
@@ -318,30 +338,16 @@ static PRBool                      gCons
 #define NS_WINDOW_TITLE_MAX_LENGTH 4095
 
 // If after selecting profile window, the startup fail, please refer to
 // http://bugzilla.gnome.org/show_bug.cgi?id=88940
 
 // needed for imgIContainer cursors
 // GdkDisplay* was added in 2.2
 typedef struct _GdkDisplay GdkDisplay;
-typedef GdkDisplay* (*_gdk_display_get_default_fn)(void);
-
-typedef GdkCursor*  (*_gdk_cursor_new_from_pixbuf_fn)(GdkDisplay *display,
-                                                      GdkPixbuf *pixbuf,
-                                                      gint x,
-                                                      gint y);
-static _gdk_display_get_default_fn    _gdk_display_get_default;
-static _gdk_cursor_new_from_pixbuf_fn _gdk_cursor_new_from_pixbuf;
-static PRBool sPixbufCursorChecked;
-
-// needed for GetAttention calls
-// gdk_window_set_urgency_hint was added in 2.8
-typedef void (*_gdk_window_set_urgency_hint_fn)(GdkWindow *window,
-                                                gboolean urgency);
 
 #define kWindowPositionSlop 20
 
 // cursor cache
 static GdkCursor *gCursorCache[eCursorCount];
 
 // imported in nsWidgetFactory.cpp
 PRBool gDisableNativeTheme = PR_FALSE;
@@ -377,16 +383,26 @@ protected:
         pixman_region32_fini(&region);
     }
     // Whether this needs to be released:
     PRBool HaveResource() const { return data != nsnull; }
 
     pixman_region32& get() { return *this; }
 };
 
+static inline PRInt32
+GetBitmapStride(PRInt32 width)
+{
+#if defined(MOZ_X11) || defined(MOZ_WIDGET_GTK2)
+  return (width+7)/8;
+#else
+  return cairo_format_stride_for_width(CAIRO_FORMAT_A1, width);
+#endif
+}
+
 nsWindow::nsWindow()
 {
     mIsTopLevel       = PR_FALSE;
     mIsDestroyed      = PR_FALSE;
     mNeedsResize      = PR_FALSE;
     mNeedsMove        = PR_FALSE;
     mListenForResizes = PR_FALSE;
     mIsShown          = PR_FALSE;
@@ -646,20 +662,20 @@ EnsureInvisibleContainer()
     return gInvisibleContainer;
 }
 
 static void
 CheckDestroyInvisibleContainer()
 {
     NS_PRECONDITION(gInvisibleContainer, "oh, no");
 
-    if (!gdk_window_peek_children(gInvisibleContainer->window)) {
+    if (!gdk_window_peek_children(gtk_widget_get_window(gInvisibleContainer))) {
         // No children, so not in use.
         // Make sure to destroy the GtkWindow also.
-        gtk_widget_destroy(gInvisibleContainer->parent);
+        gtk_widget_destroy(gtk_widget_get_parent(gInvisibleContainer));
         gInvisibleContainer = NULL;
     }
 }
 
 // Change the containing GtkWidget on a sub-hierarchy of GdkWindows belonging
 // to aOldWidget and rooted at aWindow, and reparent any child GtkWidgets of
 // the GdkWindow hierarchy to aNewWidget.
 static void
@@ -670,17 +686,17 @@ SetWidgetForHierarchy(GdkWindow *aWindow
     gpointer data;
     gdk_window_get_user_data(aWindow, &data);
 
     if (data != aOldWidget) {
         if (!GTK_IS_WIDGET(data))
             return;
 
         GtkWidget* widget = static_cast<GtkWidget*>(data);
-        if (widget->parent != aOldWidget)
+        if (gtk_widget_get_parent(widget) != aOldWidget)
             return;
 
         // This window belongs to a child widget, which will no longer be a
         // child of aOldWidget.
         gtk_widget_reparent(widget, aNewWidget);
 
         return;
     }
@@ -767,23 +783,23 @@ nsWindow::Destroy(void)
     }
 
     // make sure that we remove ourself as the focus window
     if (gFocusWindow == this) {
         LOGFOCUS(("automatically losing focus...\n"));
         gFocusWindow = nsnull;
     }
 
-#ifdef MOZ_X11
+#if defined(MOZ_WIDGET_GTK2) && defined(MOZ_X11)
     // make sure that we remove ourself as the plugin focus window
     if (gPluginFocusWindow == this) {
         gPluginFocusWindow->LoseNonXEmbedPluginFocus();
     }
-#endif /* MOZ_X11 */
-
+#endif /* MOZ_X11 && MOZ_WIDGET_GTK2 */
+  
     if (mWindowGroup) {
         g_object_unref(mWindowGroup);
         mWindowGroup = nsnull;
     }
 
     // Destroy thebes surface now. Badness can happen if we destroy
     // the surface after its X Window.
     mThebesSurface = nsnull;
@@ -863,17 +879,17 @@ nsWindow::GetDPI()
         } else {
             // Fall back to something sane.
             NS_WARNING("Unknown device - using default DPI");
             sDPI = 96.0f;
         }
     }
     return sDPI;
 #else
-    Display *dpy = GDK_DISPLAY();
+    Display *dpy = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
     int defaultScreen = DefaultScreen(dpy);
     double heightInches = DisplayHeightMM(dpy, defaultScreen)/MM_PER_INCH_FLOAT;
     if (heightInches < 0.25) {
         // Something's broken, but we'd better not crash.
         return 96.0f;
     }
     return float(DisplayHeight(dpy, defaultScreen)/heightInches);
 #endif
@@ -893,31 +909,31 @@ nsWindow::SetParent(nsIWidget *aNewParen
     mParent->RemoveChild(this);
 
     mParent = aNewParent;
 
     GtkWidget* oldContainer = GetMozContainerWidget();
     if (!oldContainer) {
         // The GdkWindows have been destroyed so there is nothing else to
         // reparent.
-        NS_ABORT_IF_FALSE(GDK_WINDOW_OBJECT(mGdkWindow)->destroyed,
+        NS_ABORT_IF_FALSE(gdk_window_is_destroyed(mGdkWindow),
                           "live GdkWindow with no widget");
         return NS_OK;
     }
 
     if (aNewParent) {
         aNewParent->AddChild(this);
         ReparentNativeWidget(aNewParent);
     } else {
         // aNewParent is NULL, but reparent to a hidden window to avoid
         // destroying the GdkWindow and its descendants.
         // An invisible container widget is needed to hold descendant
         // GtkWidgets.
         GtkWidget* newContainer = EnsureInvisibleContainer();
-        GdkWindow* newParentWindow = newContainer->window;
+        GdkWindow* newParentWindow = gtk_widget_get_window(newContainer);
         ReparentNativeWidgetInternal(aNewParent, newContainer, newParentWindow,
                                      oldContainer);
     }
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsWindow::ReparentNativeWidget(nsIWidget* aNewParent)
@@ -925,21 +941,21 @@ nsWindow::ReparentNativeWidget(nsIWidget
     NS_PRECONDITION(aNewParent, "");
     NS_ASSERTION(!mIsDestroyed, "");
     NS_ASSERTION(!static_cast<nsWindow*>(aNewParent)->mIsDestroyed, "");
 
     GtkWidget* oldContainer = GetMozContainerWidget();
     if (!oldContainer) {
         // The GdkWindows have been destroyed so there is nothing else to
         // reparent.
-        NS_ABORT_IF_FALSE(GDK_WINDOW_OBJECT(mGdkWindow)->destroyed,
+        NS_ABORT_IF_FALSE(gdk_window_is_destroyed(mGdkWindow),
                           "live GdkWindow with no widget");
         return NS_OK;
     }
-    NS_ABORT_IF_FALSE(!GDK_WINDOW_OBJECT(mGdkWindow)->destroyed,
+    NS_ABORT_IF_FALSE(!gdk_window_is_destroyed(mGdkWindow),
                       "destroyed GdkWindow with widget");
     
     nsWindow* newParent = static_cast<nsWindow*>(aNewParent);
     GdkWindow* newParentWindow = newParent->mGdkWindow;
     GtkWidget* newContainer = NULL;
     if (newParentWindow) {
         newContainer = get_gtk_widget_for_gdk_window(newParentWindow);
     }
@@ -948,24 +964,24 @@ nsWindow::ReparentNativeWidget(nsIWidget
       GtkWindow* topLevelParent =
           GTK_WINDOW(gtk_widget_get_toplevel(newContainer));
       gtk_window_set_transient_for(GTK_WINDOW(mShell), topLevelParent);
       mTransientParent = topLevelParent;
       if (mWindowGroup) {
           g_object_unref(mWindowGroup);
           mWindowGroup = NULL;
       }
-      if (mTransientParent->group) {
-          gtk_window_group_add_window(mTransientParent->group,
+      if (gtk_window_get_group(mTransientParent)) {
+          gtk_window_group_add_window(gtk_window_get_group(mTransientParent),
                                       GTK_WINDOW(mShell));
-          mWindowGroup = mTransientParent->group;
+          mWindowGroup = gtk_window_get_group(mTransientParent);
           g_object_ref(mWindowGroup);
       }
-      else if (GTK_WINDOW(mShell)->group) {
-          gtk_window_group_remove_window(GTK_WINDOW(mShell)->group,
+      else if (gtk_window_get_group(GTK_WINDOW(mShell))) {
+          gtk_window_group_remove_window(gtk_window_get_group(GTK_WINDOW(mShell)),
                                          GTK_WINDOW(mShell));
       }
     }
 
     ReparentNativeWidgetInternal(aNewParent, newContainer, newParentWindow,
                                  oldContainer);
     return NS_OK;
 }
@@ -974,22 +990,22 @@ void
 nsWindow::ReparentNativeWidgetInternal(nsIWidget* aNewParent,
                                        GtkWidget* aNewContainer,
                                        GdkWindow* aNewParentWindow,
                                        GtkWidget* aOldContainer)
 {
     if (!aNewContainer) {
         // The new parent GdkWindow has been destroyed.
         NS_ABORT_IF_FALSE(!aNewParentWindow ||
-                          GDK_WINDOW_OBJECT(aNewParentWindow)->destroyed,
+                          gdk_window_is_destroyed(aNewParentWindow),
                           "live GdkWindow with no widget");
         Destroy();
     } else {
         if (aNewContainer != aOldContainer) {
-            NS_ABORT_IF_FALSE(!GDK_WINDOW_OBJECT(aNewParentWindow)->destroyed,
+            NS_ABORT_IF_FALSE(!gdk_window_is_destroyed(aNewParentWindow),
                               "destroyed GdkWindow with widget");
             SetWidgetForHierarchy(mGdkWindow, aOldContainer, aNewContainer);
         }
 
         if (!mIsTopLevel) {
             gdk_window_reparent(mGdkWindow, aNewParentWindow, mBounds.x,
                                 mBounds.y);
         }
@@ -1400,53 +1416,50 @@ SetUserTimeAndStartupIDForActivatedWindo
     GTKToolkit->GetDesktopStartupID(&desktopStartupID);
     if (desktopStartupID.IsEmpty()) {
         // We don't have the data we need. Fall back to an
         // approximation ... using the timestamp of the remote command
         // being received as a guess for the timestamp of the user event
         // that triggered it.
         PRUint32 timestamp = GTKToolkit->GetFocusTimestamp();
         if (timestamp) {
-            gdk_window_focus(aWindow->window, timestamp);
+            gdk_window_focus(gtk_widget_get_window(aWindow), timestamp);
             GTKToolkit->SetFocusTimestamp(0);
         }
         return;
     }
 
-#ifdef MOZ_ENABLE_STARTUP_NOTIFICATION
-    GdkDrawable* drawable = GDK_DRAWABLE(aWindow->window);
-    GtkWindow* win = GTK_WINDOW(aWindow);
-    if (!win) {
-        NS_WARNING("Passed in widget was not a GdkWindow!");
-        return;
-    }
-    GdkScreen* screen = gtk_window_get_screen(win);
+#if defined(MOZ_ENABLE_STARTUP_NOTIFICATION)
+    GdkWindow* gdkWindow = gtk_widget_get_window(aWindow);
+  
+    GdkScreen* screen = gdk_window_get_screen(gdkWindow);
     SnDisplay* snd =
-        sn_display_new(gdk_x11_drawable_get_xdisplay(drawable), nsnull, nsnull);
+        sn_display_new(gdk_x11_display_get_xdisplay(gdk_window_get_display(gdkWindow)), 
+                       nsnull, nsnull);
     if (!snd)
         return;
     SnLauncheeContext* ctx =
         sn_launchee_context_new(snd, gdk_screen_get_number(screen),
                                 desktopStartupID.get());
     if (!ctx) {
         sn_display_unref(snd);
         return;
     }
 
     if (sn_launchee_context_get_id_has_timestamp(ctx)) {
         PRLibrary* gtkLibrary;
         SetUserTimeFunc setUserTimeFunc = (SetUserTimeFunc)
             PR_FindFunctionSymbolAndLibrary("gdk_x11_window_set_user_time", &gtkLibrary);
         if (setUserTimeFunc) {
-            setUserTimeFunc(aWindow->window, sn_launchee_context_get_timestamp(ctx));
+            setUserTimeFunc(gdkWindow, sn_launchee_context_get_timestamp(ctx));
             PR_UnloadLibrary(gtkLibrary);
         }
     }
 
-    sn_launchee_context_setup_window(ctx, gdk_x11_drawable_get_xid(drawable));
+    sn_launchee_context_setup_window(ctx, gdk_x11_window_get_xid(gdkWindow));
     sn_launchee_context_complete(ctx);
 
     sn_launchee_context_unref(ctx);
     sn_display_unref(snd);
 #endif
 
     GTKToolkit->SetDesktopStartupID(EmptyCString());
 }
@@ -1463,23 +1476,23 @@ nsWindow::SetFocus(PRBool aRaise)
     if (!owningWidget)
         return NS_ERROR_FAILURE;
 
     // Raise the window if someone passed in PR_TRUE and the prefs are
     // set properly.
     GtkWidget *toplevelWidget = gtk_widget_get_toplevel(owningWidget);
 
     if (gRaiseWindows && aRaise && toplevelWidget &&
-        !GTK_WIDGET_HAS_FOCUS(owningWidget) &&
-        !GTK_WIDGET_HAS_FOCUS(toplevelWidget)) {
+        !gtk_widget_has_focus(owningWidget) &&
+        !gtk_widget_has_focus(toplevelWidget)) {
         GtkWidget* top_window = nsnull;
         GetToplevelWidget(&top_window);
-        if (top_window && (GTK_WIDGET_VISIBLE(top_window)))
+        if (top_window && (gtk_widget_get_visible(top_window)))
         {
-            gdk_window_show_unraised(top_window->window);
+            gdk_window_show_unraised(gtk_widget_get_window(top_window));
             // Unset the urgency hint if possible.
             SetUrgencyHint(top_window, PR_FALSE);
         }
     }
 
     nsRefPtr<nsWindow> owningWindow = get_window_for_gtk_widget(owningWidget);
     if (!owningWindow)
         return NS_ERROR_FAILURE;
@@ -1540,17 +1553,17 @@ nsWindow::SetFocus(PRBool aRaise)
 }
 
 NS_IMETHODIMP
 nsWindow::GetScreenBounds(nsIntRect &aRect)
 {
     if (mIsTopLevel && mContainer) {
         // use the point including window decorations
         gint x, y;
-        gdk_window_get_root_origin(GTK_WIDGET(mContainer)->window, &x, &y);
+        gdk_window_get_root_origin(gtk_widget_get_window(GTK_WIDGET(mContainer)), &x, &y);
         aRect.MoveTo(x, y);
     }
     else {
         aRect.MoveTo(WidgetToScreenOffset());
     }
     // mBounds.Size() is the window bounds, not the window-manager frame
     // bounds (bug 581863).  gdk_window_get_frame_extents would give the
     // frame bounds, but mBounds.Size() is returned here for consistency
@@ -1593,105 +1606,37 @@ nsWindow::SetCursor(nsCursor aCursor)
         newCursor = get_gtk_cursor(aCursor);
 
         if (nsnull != newCursor) {
             mCursor = aCursor;
 
             if (!mContainer)
                 return NS_OK;
 
-            gdk_window_set_cursor(GTK_WIDGET(mContainer)->window, newCursor);
+            gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(mContainer)), newCursor);
         }
     }
 
     return NS_OK;
 }
 
-
-static
-PRUint8* Data32BitTo1Bit(PRUint8* aImageData,
-                         PRUint32 aImageBytesPerRow,
-                         PRUint32 aWidth, PRUint32 aHeight)
-{
-  PRUint32 outBpr = (aWidth + 7) / 8;
-
-  PRUint8* outData = new PRUint8[outBpr * aHeight];
-  if (!outData)
-      return NULL;
-
-  PRUint8 *outRow = outData,
-          *imageRow = aImageData;
-
-  for (PRUint32 curRow = 0; curRow < aHeight; curRow++) {
-      PRUint8 *irow = imageRow;
-      PRUint8 *orow = outRow;
-      PRUint8 imagePixels = 0;
-      PRUint8 offset = 0;
-
-      for (PRUint32 curCol = 0; curCol < aWidth; curCol++) {
-          PRUint8 r = *imageRow++,
-                  g = *imageRow++,
-                  b = *imageRow++;
-               /* a = * */imageRow++;
-
-          if ((r + b + g) < 3 * 128)
-              imagePixels |= (1 << offset);
-
-          if (offset == 7) {
-              *outRow++ = imagePixels;
-              offset = 0;
-              imagePixels = 0;
-          } else {
-              offset++;
-          }
-      }
-      if (offset != 0)
-          *outRow++ = imagePixels;
-
-      imageRow = irow + aImageBytesPerRow;
-      outRow = orow + outBpr;
-  }
-
-  return outData;
-}
-
-
-
 NS_IMETHODIMP
 nsWindow::SetCursor(imgIContainer* aCursor,
                     PRUint32 aHotspotX, PRUint32 aHotspotY)
 {
     // if we're not the toplevel window pass up the cursor request to
     // the toplevel window to handle it.
     if (!mContainer && mGdkWindow) {
         nsWindow *window = GetContainerWindow();
         if (!window)
             return NS_ERROR_FAILURE;
 
         return window->SetCursor(aCursor, aHotspotX, aHotspotY);
     }
 
-    if (!sPixbufCursorChecked) {
-        PRLibrary* lib;
-        _gdk_cursor_new_from_pixbuf = (_gdk_cursor_new_from_pixbuf_fn)
-            PR_FindFunctionSymbolAndLibrary("gdk_cursor_new_from_pixbuf", &lib);
-        if (lib) {
-            // We already link against GDK, so we can unload it.
-            PR_UnloadLibrary(lib);
-            lib = nsnull;
-        }
-        _gdk_display_get_default = (_gdk_display_get_default_fn)
-            PR_FindFunctionSymbolAndLibrary("gdk_display_get_default", &lib);
-        if (lib) {
-            // We already link against GDK, so we can unload it.
-            PR_UnloadLibrary(lib);
-            lib = nsnull;
-        }
-        sPixbufCursorChecked = PR_TRUE;
-    }
     mCursor = nsCursor(-1);
 
     // Get the image's current frame
     GdkPixbuf* pixbuf = nsImageToPixbuf::ImageToPixbuf(aCursor);
     if (!pixbuf)
         return NS_ERROR_NOT_AVAILABLE;
 
     int width = gdk_pixbuf_get_width(pixbuf);
@@ -1712,64 +1657,24 @@ nsWindow::SetCursor(imgIContainer* aCurs
         GdkPixbuf* alphaBuf = gdk_pixbuf_add_alpha(pixbuf, FALSE, 0, 0, 0);
         g_object_unref(pixbuf);
         if (!alphaBuf) {
             return NS_ERROR_OUT_OF_MEMORY;
         }
         pixbuf = alphaBuf;
     }
 
-    GdkCursor* cursor;
-    if (!_gdk_cursor_new_from_pixbuf || !_gdk_display_get_default) {
-        // Fallback to a monochrome cursor
-        GdkPixmap* mask = gdk_pixmap_new(NULL, width, height, 1);
-        if (!mask) {
-            g_object_unref(pixbuf);
-            return NS_ERROR_OUT_OF_MEMORY;
-        }
-
-        PRUint8* data = Data32BitTo1Bit(gdk_pixbuf_get_pixels(pixbuf),
-                                        gdk_pixbuf_get_rowstride(pixbuf),
-                                        width, height);
-        if (!data) {
-            g_object_unref(mask);
-            g_object_unref(pixbuf);
-            return NS_ERROR_OUT_OF_MEMORY;
-        }
-
-        GdkPixmap* image = gdk_bitmap_create_from_data(NULL, (const gchar*)data, width,
-                                                       height);
-        delete[] data;
-        if (!image) {
-            g_object_unref(mask);
-            g_object_unref(pixbuf);
-            return NS_ERROR_OUT_OF_MEMORY;
-        }
-
-        gdk_pixbuf_render_threshold_alpha(pixbuf, mask, 0, 0, 0, 0, width,
-                                          height, 1);
-
-        GdkColor fg = { 0, 0, 0, 0 }; // Black
-        GdkColor bg = { 0, 0xFFFF, 0xFFFF, 0xFFFF }; // White
-
-        cursor = gdk_cursor_new_from_pixmap(image, mask, &fg, &bg, aHotspotX,
-                                            aHotspotY);
-        g_object_unref(image);
-        g_object_unref(mask);
-    } else {
-        // Now create the cursor
-        cursor = _gdk_cursor_new_from_pixbuf(_gdk_display_get_default(),
-                                             pixbuf,
-                                             aHotspotX, aHotspotY);
-    }
+    GdkCursor* cursor = gdk_cursor_new_from_pixbuf(gdk_display_get_default(),
+                                                   pixbuf,
+                                                   aHotspotX, aHotspotY);
     g_object_unref(pixbuf);
     nsresult rv = NS_ERROR_OUT_OF_MEMORY;
     if (cursor) {
         if (mContainer) {
-            gdk_window_set_cursor(GTK_WIDGET(mContainer)->window, cursor);
+            gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(mContainer)), cursor);
             rv = NS_OK;
         }
         gdk_cursor_unref(cursor);
     }
 
     return rv;
 }
 
@@ -1801,17 +1706,17 @@ nsWindow::Update()
 {
     if (!mGdkWindow)
         return NS_OK;
 
     LOGDRAW(("Update [%p] %p\n", this, mGdkWindow));
 
     gdk_window_process_updates(mGdkWindow, FALSE);
     // Send the updates to the server.
-    gdk_display_flush(gdk_drawable_get_display(GDK_DRAWABLE(mGdkWindow)));
+    gdk_display_flush(gdk_window_get_display(mGdkWindow));
     return NS_OK;
 }
 
 void*
 nsWindow::GetNativeData(PRUint32 aDataType)
 {
     switch (aDataType) {
     case NS_NATIVE_WINDOW:
@@ -1824,25 +1729,29 @@ nsWindow::GetNativeData(PRUint32 aDataTy
     }
 
     case NS_NATIVE_PLUGIN_PORT:
         return SetupPluginPort();
         break;
 
     case NS_NATIVE_DISPLAY:
 #ifdef MOZ_X11
-        return GDK_DISPLAY();
+        return GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
 #else
         return nsnull;
 #endif /* MOZ_X11 */
         break;
 
     case NS_NATIVE_GRAPHIC: {
-        NS_ASSERTION(nsnull != mToolkit, "NULL toolkit, unable to get a GC");
+#if defined(MOZ_WIDGET_GTK2)
+        NS_ASSERTION(nsnull != mToolkit, "NULL toolkit, unable to get a GC");    
         return (void *)static_cast<nsGTKToolkit *>(mToolkit)->GetSharedGC();
+#else
+        return nsnull;
+#endif
         break;
     }
 
     case NS_NATIVE_SHELLWIDGET:
         return (void *) mShell;
 
     case NS_NATIVE_SHAREABLE_WINDOW:
         return (void *) GDK_WINDOW_XID(gdk_window_get_toplevel(mGdkWindow));
@@ -2008,17 +1917,17 @@ nsWindow::GetAttention(PRInt32 aCycleCou
 
     GtkWidget* top_window = nsnull;
     GtkWidget* top_focused_window = nsnull;
     GetToplevelWidget(&top_window);
     if (gFocusWindow)
         gFocusWindow->GetToplevelWidget(&top_focused_window);
 
     // Don't get attention if the window is focused anyway.
-    if (top_window && (GTK_WIDGET_VISIBLE(top_window)) &&
+    if (top_window && (gtk_widget_get_visible(top_window)) &&
         top_window != top_focused_window) {
         SetUrgencyHint(top_window, PR_TRUE);
     }
 
     return NS_OK;
 }
 
 PRBool
@@ -2027,31 +1936,32 @@ nsWindow::HasPendingInputEvent()
     // This sucks, but gtk/gdk has no way to answer the question we want while
     // excluding paint events, and there's no X API that will let us peek
     // without blocking or removing.  To prevent event reordering, peek
     // anything except expose events.  Reordering expose and others should be
     // ok, hopefully.
     PRBool haveEvent;
 #ifdef MOZ_X11
     XEvent ev;
+    Display *display = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
     haveEvent =
-        XCheckMaskEvent(GDK_DISPLAY(),
+        XCheckMaskEvent(display,
                         KeyPressMask | KeyReleaseMask | ButtonPressMask |
                         ButtonReleaseMask | EnterWindowMask | LeaveWindowMask |
                         PointerMotionMask | PointerMotionHintMask |
                         Button1MotionMask | Button2MotionMask |
                         Button3MotionMask | Button4MotionMask |
                         Button5MotionMask | ButtonMotionMask | KeymapStateMask |
                         VisibilityChangeMask | StructureNotifyMask |
                         ResizeRedirectMask | SubstructureNotifyMask |
                         SubstructureRedirectMask | FocusChangeMask |
                         PropertyChangeMask | ColormapChangeMask |
                         OwnerGrabButtonMask, &ev);
     if (haveEvent) {
-        XPutBackEvent(GDK_DISPLAY(), &ev);
+        XPutBackEvent(display, &ev);
     }
 #else
     haveEvent = PR_FALSE;
 #endif
     return haveEvent;
 }
 
 #if 0
@@ -2074,22 +1984,21 @@ gdk_window_flash(GdkWindow *    aGdkWind
   gint         x;
   gint         y;
   gint         width;
   gint         height;
   guint        i;
   GdkGC *      gc = 0;
   GdkColor     white;
 
-  gdk_window_get_geometry(aGdkWindow,
-                          NULL,
-                          NULL,
-                          &width,
-                          &height,
-                          NULL);
+#if defined(MOZ_WIDGET_GTK2)
+  gdk_window_get_geometry(aGdkWindow,NULL,NULL,&width,&height,NULL);
+#else
+  gdk_window_get_geometry(aGdkWindow,NULL,NULL,&width,&height);
+#endif
 
   gdk_window_get_origin (aGdkWindow,
                          &x,
                          &y);
 
   gc = gdk_gc_new(GDK_ROOT_PARENT());
 
   white.pixel = WhitePixel(gdk_display,DefaultScreen(gdk_display));
@@ -2131,22 +2040,25 @@ gdk_window_flash(GdkWindow *    aGdkWind
 static void
 DispatchDidPaint(nsIWidget* aWidget)
 {
     nsEventStatus status;
     nsPaintEvent didPaintEvent(PR_TRUE, NS_DID_PAINT, aWidget);
     aWidget->DispatchEvent(&didPaintEvent, status);
 }
 
+#if defined(MOZ_WIDGET_GTK2)
 gboolean
-nsWindow::OnExposeEvent(GtkWidget *aWidget, GdkEventExpose *aEvent)
+nsWindow::OnExposeEvent(GdkEventExpose *aEvent)
+#else
+gboolean
+nsWindow::OnExposeEvent(cairo_t *cr)
+#endif
 {
     if (mIsDestroyed) {
-        LOG(("Expose event on destroyed window [%p] window %p\n",
-             (void *)this, (void *)aEvent->window));
         return FALSE;
     }
 
     // Windows that are not visible will be painted after they become visible.
     if (!mGdkWindow || mIsFullyObscured || !mHasMappedToplevel)
         return FALSE;
 
     // Dispatch WILL_PAINT to allow scripts etc. to run before we
@@ -2159,39 +2071,58 @@ nsWindow::OnExposeEvent(GtkWidget *aWidg
 
         // If the window has been destroyed during WILL_PAINT, there is
         // nothing left to do.
         if (!mGdkWindow)
             return TRUE;
     }
 
     nsPaintEvent event(PR_TRUE, NS_PAINT, this);
-    event.refPoint.x = aEvent->area.x;
-    event.refPoint.y = aEvent->area.y;
     event.willSendDidPaint = PR_TRUE;
 
+#if defined(MOZ_WIDGET_GTK2)
     GdkRectangle *rects;
     gint nrects;
     gdk_region_get_rectangles(aEvent->region, &rects, &nrects);
     if (NS_UNLIKELY(!rects)) // OOM
         return FALSE;
-
+#else
+#ifdef cairo_copy_clip_rectangle_list
+#error "Looks like we're including Mozilla's cairo instead of system cairo"
+#else
+    cairo_rectangle_list_t *rects;
+    rects = cairo_copy_clip_rectangle_list(cr);  
+    if (NS_UNLIKELY(rects->status != CAIRO_STATUS_SUCCESS)) {
+       NS_WARNING("Failed to obtain cairo rectangle list.");
+       return FALSE;
+    }
+#endif
+#endif
+
+// GTK3 TODO?
+#if defined(MOZ_WIDGET_GTK2)
     if (nrects > MAX_RECTS_IN_REGION) {
         // Just use the bounding box
         rects[0] = aEvent->area;
         nrects = 1;
     }
+#endif
 
     LOGDRAW(("sending expose event [%p] %p 0x%lx (rects follow):\n",
-             (void *)this, (void *)aEvent->window,
-             GDK_WINDOW_XWINDOW(aEvent->window)));
-
-    GdkRectangle *r;
+             (void *)this, (void *)mGdkWindow,
+             gdk_x11_window_get_xid(mGdkWindow)));
+  
+#if defined(MOZ_WIDGET_GTK2)
+    GdkRectangle *r = rects;
     GdkRectangle *r_end = rects + nrects;
-    for (r = rects; r < r_end; ++r) {
+#else
+    cairo_rectangle_t *r = rects->rectangles;
+    cairo_rectangle_t *r_end = r + rects->num_rectangles;
+#endif
+    for (; r < r_end; ++r) {
         event.region.Or(event.region, nsIntRect(r->x, r->y, r->width, r->height));
         LOGDRAW(("\t%d %d %d %d\n", r->x, r->y, r->width, r->height));
     }
 
     // Our bounds may have changed after dispatching WILL_PAINT.  Clip
     // to the new bounds here.  The event region is relative to this
     // window.
     event.region.And(event.region,
@@ -2214,17 +2145,21 @@ nsWindow::OnExposeEvent(GtkWidget *aWidg
                     event.region.Sub(event.region, r);
                 }
             }
             children = children->next;
         }
     }
 
     if (event.region.IsEmpty()) {
+#if defined(MOZ_WIDGET_GTK2)
         g_free(rects);
+#else
+        cairo_rectangle_list_destroy(rects);
+#endif
         return TRUE;
     }
 
     if (GetLayerManager()->GetBackendType() == LayerManager::LAYERS_OPENGL)
     {
         LayerManagerOGL *manager = static_cast<LayerManagerOGL*>(GetLayerManager());
         manager->SetClippingRegion(event.region);
 
@@ -2233,17 +2168,21 @@ nsWindow::OnExposeEvent(GtkWidget *aWidg
 
         g_free(rects);
 
         DispatchDidPaint(this);
 
         return TRUE;
     }
             
+#if defined(MOZ_WIDGET_GTK2)
     nsRefPtr<gfxContext> ctx = new gfxContext(GetThebesSurface());
+#else
+    nsRefPtr<gfxContext> ctx = new gfxContext(GetThebesSurface(cr));
+#endif
 
 #ifdef MOZ_DFB
     gfxPlatformGtk::SetGdkDrawable(ctx->OriginalSurface(),
                                    GDK_DRAWABLE(mGdkWindow));
 
     // clip to the update region
     gfxUtils::ClipToRegion(ctx, event.region);
 
@@ -2286,18 +2225,18 @@ nsWindow::OnExposeEvent(GtkWidget *aWidg
     }
 
 #if 0
     // NOTE: Paint flashing region would be wrong for cairo, since
     // cairo inflates the update region, etc.  So don't paint flash
     // for cairo.
 #ifdef DEBUG
     // XXX aEvent->region may refer to a newly-invalid area.  FIXME
-    if (0 && WANT_PAINT_FLASHING && aEvent->window)
-        gdk_window_flash(aEvent->window, 1, 100, aEvent->region);
+    if (0 && WANT_PAINT_FLASHING && gtk_widget_get_window(aEvent))
+        gdk_window_flash(mGdkWindow, 1, 100, aEvent->region);
 #endif
 #endif
 
 #endif // MOZ_X11
 
     nsEventStatus status;
     {
       AutoLayerManagerSetup setupLayerManager(this, ctx, layerBuffering);
@@ -2333,30 +2272,47 @@ nsWindow::OnExposeEvent(GtkWidget *aWidg
                 ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
                 ctx->SetPattern(pattern);
                 ctx->Paint();
             }
         }
     }
 #  ifdef MOZ_HAVE_SHMIMAGE
     if (nsShmImage::UseShm() && NS_LIKELY(!mIsDestroyed)) {
+#if defined(MOZ_WIDGET_GTK2)
         mShmImage->Put(mGdkWindow, rects, r_end);
+#else
+        mShmImage->Put(mGdkWindow, rects);
+#endif
     }
 #  endif  // MOZ_HAVE_SHMIMAGE
 #endif // MOZ_X11
 
+#if defined(MOZ_WIDGET_GTK2)
     g_free(rects);
+#else
+    cairo_rectangle_list_destroy(rects);
+#endif
 
     DispatchDidPaint(this);
 
     // Synchronously flush any new dirty areas
+#if defined(MOZ_WIDGET_GTK2)
     GdkRegion* dirtyArea = gdk_window_get_update_area(mGdkWindow);
+#else
+    cairo_region_t* dirtyArea = gdk_window_get_update_area(mGdkWindow);
+#endif
+
     if (dirtyArea) {
         gdk_window_invalidate_region(mGdkWindow, dirtyArea, PR_FALSE);
+#if defined(MOZ_WIDGET_GTK2)
         gdk_region_destroy(dirtyArea);
+#else
+        cairo_region_destroy(dirtyArea);
+#endif
         gdk_window_process_updates(mGdkWindow, PR_FALSE);
     }
 
     // check the return value!
     return TRUE;
 }
 
 gboolean
@@ -2526,17 +2482,17 @@ nsWindow::OnEnterNotifyEvent(GtkWidget *
 }
 
 // XXX Is this the right test for embedding cases?
 static PRBool
 is_top_level_mouse_exit(GdkWindow* aWindow, GdkEventCrossing *aEvent)
 {
     gint x = gint(aEvent->x_root);
     gint y = gint(aEvent->y_root);
-    GdkDisplay* display = gdk_drawable_get_display(aWindow);
+    GdkDisplay* display = gdk_window_get_display(aWindow);
     GdkWindow* winAtPt = gdk_display_get_window_at_pointer(display, &x, &y);
     if (!winAtPt)
         return PR_TRUE;
     GdkWindow* topLevelAtPt = gdk_window_get_toplevel(winAtPt);
     GdkWindow* topLevelWidget = gdk_window_get_toplevel(aWindow);
     return topLevelAtPt != topLevelWidget;
 }
 
@@ -2644,29 +2600,30 @@ nsWindow::OnMotionNotifyEvent(GtkWidget 
     // but not more than that?
     PRPackedBool synthEvent = PR_FALSE;
 #ifdef MOZ_X11
     XEvent xevent;
 
     while (XPending (GDK_WINDOW_XDISPLAY(aEvent->window))) {
         XEvent peeked;
         XPeekEvent (GDK_WINDOW_XDISPLAY(aEvent->window), &peeked);
-        if (peeked.xany.window != GDK_WINDOW_XWINDOW(aEvent->window)
+        if (peeked.xany.window != gdk_x11_window_get_xid(aEvent->window)
             || peeked.type != MotionNotify)
             break;
 
         synthEvent = PR_TRUE;
         XNextEvent (GDK_WINDOW_XDISPLAY(aEvent->window), &xevent);
     }
-
+#if defined(MOZ_WIDGET_GTK2)
     // if plugins still keeps the focus, get it back
     if (gPluginFocusWindow && gPluginFocusWindow != this) {
         nsRefPtr<nsWindow> kungFuDeathGrip = gPluginFocusWindow;
         gPluginFocusWindow->LoseNonXEmbedPluginFocus();
     }
+#endif /* MOZ_WIDGET_GTK2 */
 #endif /* MOZ_X11 */
 
     nsMouseEvent event(PR_TRUE, NS_MOUSE_MOVE, this, nsMouseEvent::eReal);
 
     gdouble pressure = 0;
     gdk_event_get_axis ((GdkEvent*)aEvent, GDK_AXIS_PRESSURE, &pressure);
     // Sometime gdk generate 0 pressure value between normal values
     // We have to ignore that and use last valid value
@@ -2966,17 +2923,17 @@ nsWindow::OnContainerFocusInEvent(GtkWid
     NS_ASSERTION(mWindowType != eWindowType_popup,
                  "Unexpected focus on a popup window");
 
     LOGFOCUS(("OnContainerFocusInEvent [%p]\n", (void *)this));
 
     // Unset the urgency hint, if possible
     GtkWidget* top_window = nsnull;
     GetToplevelWidget(&top_window);
-    if (top_window && (GTK_WIDGET_VISIBLE(top_window)))
+    if (top_window && (gtk_widget_get_visible(top_window)))
         SetUrgencyHint(top_window, PR_FALSE);
 
     // Return if being called within SetFocus because the focus manager
     // already knows that the window is active.
     if (gBlockActivateEvent) {
         LOGFOCUS(("NS_ACTIVATE event is blocked [%p]\n", (void *)this));
         return;
     }
@@ -3014,23 +2971,23 @@ nsWindow::OnContainerFocusOutEvent(GtkWi
             shouldRollup = (sourceNode == nsnull);
         }
 
         if (shouldRollup) {
             check_for_rollup(aEvent->window, 0, 0, PR_FALSE, PR_TRUE);
         }
     }
 
-#ifdef MOZ_X11
+#if defined(MOZ_WIDGET_GTK2) && defined(MOZ_X11)
     // plugin lose focus
     if (gPluginFocusWindow) {
         nsRefPtr<nsWindow> kungFuDeathGrip = gPluginFocusWindow;
         gPluginFocusWindow->LoseNonXEmbedPluginFocus();
     }
-#endif /* MOZ_X11 */
+#endif /* MOZ_X11 && MOZ_WIDGET_GTK2 */
 
     if (gFocusWindow) {
         nsRefPtr<nsWindow> kungFuDeathGrip = gFocusWindow;
         if (gFocusWindow->mIMModule) {
             gFocusWindow->mIMModule->OnBlurWindow(gFocusWindow);
         }
         gFocusWindow = nsnull;
     }
@@ -3058,34 +3015,38 @@ nsWindow::DispatchContentCommandEvent(PR
   return TRUE;
 }
 
 static PRUint32
 GetCharCodeFor(const GdkEventKey *aEvent, guint aShiftState,
                gint aGroup)
 {
     guint keyval;
-    if (gdk_keymap_translate_keyboard_state(NULL, aEvent->hardware_keycode,
+    GdkKeymap *keymap = gdk_keymap_get_default();
+
+    if (gdk_keymap_translate_keyboard_state(keymap, aEvent->hardware_keycode,
                                             GdkModifierType(aShiftState),
                                             aGroup,
                                             &keyval, NULL, NULL, NULL)) {
         GdkEventKey tmpEvent = *aEvent;
         tmpEvent.state = guint(aShiftState);
         tmpEvent.keyval = keyval;
         tmpEvent.group = aGroup;
         return nsConvertCharCodeToUnicode(&tmpEvent);
     }
     return 0;
 }
 
 static gint
 GetKeyLevel(GdkEventKey *aEvent)
 {
     gint level;
-    if (!gdk_keymap_translate_keyboard_state(NULL,
+    GdkKeymap *keymap = gdk_keymap_get_default();
+
+    if (!gdk_keymap_translate_keyboard_state(keymap,
                                              aEvent->hardware_keycode,
                                              GdkModifierType(aEvent->state),
                                              aEvent->group,
                                              NULL, NULL, &level, NULL))
         return -1;
     return level;
 }
 
@@ -3617,17 +3578,17 @@ nsWindow::OnDragMotionEvent(GtkWidget *a
     nsCOMPtr<nsIDragService> dragService = do_GetService(kCDragServiceCID);
     nsCOMPtr<nsIDragSessionGTK> dragSessionGTK = do_QueryInterface(dragService);
 
     // first, figure out which internal widget this drag motion actually
     // happened on
     nscoord retx = 0;
     nscoord rety = 0;
 
-    GdkWindow *innerWindow = get_inner_gdk_window(aWidget->window, aX, aY,
+    GdkWindow *innerWindow = get_inner_gdk_window(gtk_widget_get_window(aWidget), aX, aY,
                                                   &retx, &rety);
     nsRefPtr<nsWindow> innerMostWidget = get_window_for_gdk_window(innerWindow);
 
     if (!innerMostWidget)
         innerMostWidget = this;
 
     // update the drag context
     dragSessionGTK->TargetSetLastContext(aWidget, aDragContext, aTime);
@@ -3706,17 +3667,17 @@ nsWindow::OnDragDropEvent(GtkWidget *aWi
 
     // get our drag context
     nsCOMPtr<nsIDragService> dragService = do_GetService(kCDragServiceCID);
     nsCOMPtr<nsIDragSessionGTK> dragSessionGTK = do_QueryInterface(dragService);
 
     nscoord retx = 0;
     nscoord rety = 0;
 
-    GdkWindow *innerWindow = get_inner_gdk_window(aWidget->window, aX, aY,
+    GdkWindow *innerWindow = get_inner_gdk_window(gtk_widget_get_window(aWidget), aX, aY,
                                                   &retx, &rety);
     nsRefPtr<nsWindow> innerMostWidget = get_window_for_gdk_window(innerWindow);
 
     if (!innerMostWidget)
         innerMostWidget = this;
 
     // set this now before any of the drag enter or leave events happen
     dragSessionGTK->TargetSetLastContext(aWidget, aDragContext, aTime);
@@ -3871,40 +3832,47 @@ GetBrandName(nsXPIDLString& brandName)
     if (brandName.IsEmpty())
         brandName.Assign(NS_LITERAL_STRING("Mozilla"));
 }
 
 static GdkWindow *
 CreateGdkWindow(GdkWindow *parent, GtkWidget *widget)
 {
     GdkWindowAttr attributes;
-    gint          attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
+    gint          attributes_mask = GDK_WA_VISUAL;
 
     attributes.event_mask = (GDK_EXPOSURE_MASK | GDK_STRUCTURE_MASK |
                              GDK_VISIBILITY_NOTIFY_MASK |
                              GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK |
                              GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
 #ifdef HAVE_GTK_MOTION_HINTS
                              GDK_POINTER_MOTION_HINT_MASK |
 #endif
                              GDK_POINTER_MOTION_MASK);
 
     attributes.width = 1;
     attributes.height = 1;
     attributes.wclass = GDK_INPUT_OUTPUT;
     attributes.visual = gtk_widget_get_visual(widget);
+    attributes.window_type = GDK_WINDOW_CHILD;
+
+#if defined(MOZ_WIDGET_GTK2)
+    attributes_mask |= GDK_WA_COLORMAP;
     attributes.colormap = gtk_widget_get_colormap(widget);
-    attributes.window_type = GDK_WINDOW_CHILD;
+#endif
 
     GdkWindow *window = gdk_window_new(parent, &attributes, attributes_mask);
     gdk_window_set_user_data(window, widget);
 
+// GTK3 TODO?
+#if defined(MOZ_WIDGET_GTK2)
     /* set the default pixmap to None so that you don't end up with the
        gtk default which is BlackPixel. */
     gdk_window_set_back_pixmap(window, NULL, FALSE);
+#endif
 
     return window;
 }
 
 nsresult
 nsWindow::Create(nsIWidget        *aParent,
                  nsNativeWidget    aNativeParent,
                  const nsIntRect  &aRect,
@@ -3992,17 +3960,17 @@ nsWindow::Create(nsIWidget        *aPare
             gtk_window_set_type_hint(GTK_WINDOW(mShell),
                                      GDK_WINDOW_TYPE_HINT_DIALOG);
             gtk_window_set_transient_for(GTK_WINDOW(mShell),
                                          topLevelParent);
             mTransientParent = topLevelParent;
             // add ourselves to the parent window's window group
             if (!topLevelParent) {
                 gtk_widget_realize(mShell);
-                GdkWindow* dialoglead = mShell->window;
+                GdkWindow* dialoglead = gtk_widget_get_window(mShell);
                 gdk_window_set_group(dialoglead, dialoglead);
             }
             if (parentGdkWindow) {
                 nsWindow *parentnsWindow =
                     get_window_for_gdk_window(parentGdkWindow);
                 NS_ASSERTION(parentnsWindow,
                              "no nsWindow for parentGdkWindow!");
                 if (parentnsWindow && parentnsWindow->mWindowGroup) {
@@ -4051,17 +4019,17 @@ nsWindow::Create(nsIWidget        *aPare
                 // Element focus is managed by the parent window so the
                 // WM_HINTS input field is set to False to tell the window
                 // manager not to set input focus to this window ...
                 gtk_window_set_accept_focus(GTK_WINDOW(mShell), FALSE);
 #ifdef MOZ_X11
                 // ... but when the window manager offers focus through
                 // WM_TAKE_FOCUS, focus is requested on the parent window.
                 gtk_widget_realize(mShell);
-                gdk_window_add_filter(mShell->window,
+                gdk_window_add_filter(gtk_widget_get_window(mShell),
                                       popup_take_focus_filter, NULL); 
 #endif
             }
 
             GdkWindowTypeHint gtkTypeHint;
             if (aInitData->mIsDragPopup) {
                 gtkTypeHint = GDK_WINDOW_TYPE_HINT_DND;
             }
@@ -4080,20 +4048,20 @@ nsWindow::Create(nsIWidget        *aPare
             }
             gtk_window_set_type_hint(GTK_WINDOW(mShell), gtkTypeHint);
 
             if (topLevelParent) {
                 gtk_window_set_transient_for(GTK_WINDOW(mShell),
                                             topLevelParent);
                 mTransientParent = topLevelParent;
 
-                if (topLevelParent->group) {
-                    gtk_window_group_add_window(topLevelParent->group,
-                                            GTK_WINDOW(mShell));
-                    mWindowGroup = topLevelParent->group;
+                GtkWindowGroup *groupParent = gtk_window_get_group(topLevelParent);
+                if (groupParent) {
+                    gtk_window_group_add_window(groupParent, GTK_WINDOW(mShell));
+                    mWindowGroup = groupParent;
                     g_object_ref(mWindowGroup);
                 }
             }
         }
         else { // must be eWindowType_toplevel
             mShell = gtk_window_new(GTK_WINDOW_TOPLEVEL);
             SetDefaultIcon();
             gtk_window_set_wmclass(GTK_WINDOW(mShell), "Toplevel", cBrand.get());
@@ -4108,39 +4076,41 @@ nsWindow::Create(nsIWidget        *aPare
         }
 
         // create our container
         GtkWidget *container = moz_container_new();
         mContainer = MOZ_CONTAINER(container);
         gtk_container_add(GTK_CONTAINER(mShell), container);
         gtk_widget_realize(container);
 
+#if defined(MOZ_WIDGET_GTK2)
         // Don't let GTK mess with the shapes of our GdkWindows
         GTK_PRIVATE_SET_FLAG(container, GTK_HAS_SHAPE_MASK);
+#endif
 
         // make sure this is the focus widget in the container
         gtk_window_set_focus(GTK_WINDOW(mShell), container);
 
         // the drawing window
-        mGdkWindow = container->window;
+        mGdkWindow = gtk_widget_get_window(container);
 
         if (mWindowType == eWindowType_popup) {
             // gdk does not automatically set the cursor for "temporary"
             // windows, which are what gtk uses for popups.
 
             mCursor = eCursor_wait; // force SetCursor to actually set the
                                     // cursor, even though our internal state
                                     // indicates that we already have the
                                     // standard cursor.
             SetCursor(eCursor_standard);
 
             if (aInitData->mNoAutoHide) {
                 gint wmd = ConvertBorderStyles(mBorderStyle);
                 if (wmd != -1)
-                  gdk_window_set_decorations(mShell->window, (GdkWMDecoration) wmd);
+                  gdk_window_set_decorations(gtk_widget_get_window(mShell), (GdkWMDecoration) wmd);
             }
         }
     }
         break;
     case eWindowType_plugin:
     case eWindowType_child: {
         if (parentMozContainer) {
             mGdkWindow = CreateGdkWindow(parentGdkWindow, parentMozContainer);
@@ -4150,20 +4120,22 @@ nsWindow::Create(nsIWidget        *aPare
                 mHasMappedToplevel = parentnsWindow->mHasMappedToplevel;
         }
         else if (parentGtkContainer) {
             GtkWidget *container = moz_container_new();
             mContainer = MOZ_CONTAINER(container);
             gtk_container_add(parentGtkContainer, container);
             gtk_widget_realize(container);
 
+#if defined(MOZ_WIDGET_GTK2)
             // Don't let GTK mess with the shapes of our GdkWindows
             GTK_PRIVATE_SET_FLAG(container, GTK_HAS_SHAPE_MASK);
-
-            mGdkWindow = container->window;
+#endif
+
+            mGdkWindow = gtk_widget_get_window(container);
         }
         else {
             NS_WARNING("Warning: tried to create a new child widget with no parent!");
             return NS_ERROR_FAILURE;
         }
     }
         break;
     default:
@@ -4202,17 +4174,17 @@ nsWindow::Create(nsIWidget        *aPare
                                "notify::gtk-theme-name",
                                G_CALLBACK(theme_changed_cb), this);
         g_signal_connect_after(default_settings,
                                "notify::gtk-font-name",
                                G_CALLBACK(theme_changed_cb), this);
 
 #ifdef MOZ_PLATFORM_MAEMO
         if (mWindowType == eWindowType_toplevel) {
-            GdkWindow *gdkwin = mShell->window;
+            GdkWindow *gdkwin = gtk_widget_get_window(mShell);
 
             // Tell the Hildon desktop that we support being rotated
             gulong portrait_set = 1;
             GdkAtom support = gdk_atom_intern("_HILDON_PORTRAIT_MODE_SUPPORT", FALSE);
             gdk_property_change(gdkwin, support, gdk_x11_xatom_to_atom(XA_CARDINAL),
                                 32, GDK_PROP_MODE_REPLACE,
                                 (const guchar *) &portrait_set, 1);
 
@@ -4225,18 +4197,23 @@ nsWindow::Create(nsIWidget        *aPare
 #endif
     }
 
     if (mContainer) {
         g_signal_connect(mContainer, "unrealize",
                          G_CALLBACK(container_unrealize_cb), NULL);
         g_signal_connect_after(mContainer, "size_allocate",
                                G_CALLBACK(size_allocate_cb), NULL);
+#if defined(MOZ_WIDGET_GTK2)
         g_signal_connect(mContainer, "expose_event",
                          G_CALLBACK(expose_event_cb), NULL);
+#else
+        g_signal_connect(G_OBJECT(mContainer), "draw",
+                         G_CALLBACK(expose_event_cb), NULL);
+#endif
         g_signal_connect(mContainer, "enter_notify_event",
                          G_CALLBACK(enter_notify_event_cb), NULL);
         g_signal_connect(mContainer, "leave_notify_event",
                          G_CALLBACK(leave_notify_event_cb), NULL);
         g_signal_connect(mContainer, "motion_notify_event",
                          G_CALLBACK(motion_notify_event_cb), NULL);
         g_signal_connect(mContainer, "button_press_event",
                          G_CALLBACK(button_press_event_cb), NULL);
@@ -4283,28 +4260,28 @@ nsWindow::Create(nsIWidget        *aPare
         nsWindow *container = GetContainerWindow();
         if (container) {
             mIMModule = container->mIMModule;
         }
     }
 
     LOG(("nsWindow [%p]\n", (void *)this));
     if (mShell) {
-        LOG(("\tmShell %p %p %lx\n", (void *)mShell, (void *)mShell->window,
-             GDK_WINDOW_XWINDOW(mShell->window)));
+        LOG(("\tmShell %p %p %lx\n", (void *)mShell, (void *)gtk_widget_get_window(mShell),
+             gdk_x11_window_get_xid(gtk_widget_get_window(mShell))));
     }
 
     if (mContainer) {
         LOG(("\tmContainer %p %p %lx\n", (void *)mContainer,
-             (void *)GTK_WIDGET(mContainer)->window,
-             GDK_WINDOW_XWINDOW(GTK_WIDGET(mContainer)->window)));
+             (void *)gtk_widget_get_window(GTK_WIDGET(mContainer)),
+             gdk_x11_window_get_xid(gtk_widget_get_window(GTK_WIDGET(mContainer)))));
     }
     else if (mGdkWindow) {
         LOG(("\tmGdkWindow %p %lx\n", (void *)mGdkWindow,
-             GDK_WINDOW_XWINDOW(mGdkWindow)));
+             gdk_x11_window_get_xid(mGdkWindow)));
     }
 
     // resize so that everything is set to the right dimensions
     if (!mIsTopLevel)
         Resize(mBounds.x, mBounds.y, mBounds.width, mBounds.height, PR_FALSE);
 
 #ifdef ACCESSIBILITY
     nsresult rv;
@@ -4388,21 +4365,22 @@ nsWindow::SetWindowClass(const nsAString
       role = c + 1;
     }
     else if (!isascii(*c) || (!isalnum(*c) && ('_' != *c) && ('-' != *c)))
       *c = '_';
   }
   class_hint->res_name[0] = toupper(class_hint->res_name[0]);
   if (!role) role = class_hint->res_name;
 
-  gdk_window_set_role(GTK_WIDGET(mShell)->window, role);
+  GdkWindow *shellWindow = gtk_widget_get_window(GTK_WIDGET(mShell));
+  gdk_window_set_role(shellWindow, role);
   // Can't use gtk_window_set_wmclass() for this; it prints
   // a warning & refuses to make the change.
-  XSetClassHint(GDK_DISPLAY(),
-                GDK_WINDOW_XWINDOW(GTK_WIDGET(mShell)->window),
+  XSetClassHint(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()),
+                gdk_x11_window_get_xid(shellWindow),
                 class_hint);
   nsMemory::Free(class_hint->res_class);
   nsMemory::Free(class_hint->res_name);
   XFree(class_hint);
 #else /* MOZ_X11 */
 
   char *res_name;
 
@@ -4425,17 +4403,17 @@ nsWindow::SetWindowClass(const nsAString
       role = c + 1;
     }
     else if (!isascii(*c) || (!isalnum(*c) && ('_' != *c) && ('-' != *c)))
       *c = '_';
   }
   res_name[0] = toupper(res_name[0]);
   if (!role) role = res_name;
 
-  gdk_window_set_role(GTK_WIDGET(mShell)->window, role);
+  gdk_window_set_role(gtk_widget_get_window(GTK_WIDGET(mShell)), role);
 
   nsMemory::Free(res_name);
 
 #endif /* MOZ_X11 */
   return NS_OK;
 }
 
 void
@@ -4449,19 +4427,20 @@ nsWindow::NativeResize(PRInt32 aWidth, P
     // clear our resize flag
     mNeedsResize = PR_FALSE;
 
     if (mIsTopLevel) {
         gtk_window_resize(GTK_WINDOW(mShell), aWidth, aHeight);
     }
     else if (mContainer) {
         GtkWidget *widget = GTK_WIDGET(mContainer);
-        GtkAllocation allocation;
-        allocation.x = widget->allocation.x;
-        allocation.y = widget->allocation.y;
+        GtkAllocation allocation, prev_allocation;
+        gtk_widget_get_allocation(widget, &prev_allocation);
+        allocation.x = prev_allocation.x;
+        allocation.y = prev_allocation.y;
         allocation.width = aWidth;
         allocation.height = aHeight;
         gtk_widget_size_allocate(widget, &allocation);
     }
     else if (mGdkWindow) {
         gdk_window_resize(mGdkWindow, aWidth, aHeight);
     }
 }
@@ -4635,17 +4614,21 @@ nsWindow::SetTransparencyMode(nsTranspar
         return;
 
     if (!isTransparent) {
         if (mTransparencyBitmap) {
             delete[] mTransparencyBitmap;
             mTransparencyBitmap = nsnull;
             mTransparencyBitmapWidth = 0;
             mTransparencyBitmapHeight = 0;
+#if defined(MOZ_WIDGET_GTK2)
             gtk_widget_reset_shapes(mShell);
+#else
+            // GTK3 TODO
+#endif
         }
     } // else the new default alpha values are "all 1", so we don't
     // need to change anything yet
 
     mIsTransparent = isTransparent;
 }
 
 nsTransparencyMode
@@ -4774,57 +4757,69 @@ nsWindow::SetWindowClipRegion(const nsTA
     }
 
     if (!StoreWindowClipRegion(*newRects))
         return;
 
     if (!mGdkWindow)
         return;
 
+#if defined(MOZ_WIDGET_GTK2)
     GdkRegion *region = gdk_region_new(); // aborts on OOM
     for (PRUint32 i = 0; i < newRects->Length(); ++i) {
         const nsIntRect& r = newRects->ElementAt(i);
         GdkRectangle rect = { r.x, r.y, r.width, r.height };
         gdk_region_union_with_rect(region, &rect);
     }
 
     gdk_window_shape_combine_region(mGdkWindow, region, 0, 0);
     gdk_region_destroy(region);
-
+#else
+    cairo_region_t *region = cairo_region_create();
+    for (PRUint32 i = 0; i < newRects->Length(); ++i) {
+        const nsIntRect& r = newRects->ElementAt(i);
+        cairo_rectangle_int_t rect = { r.x, r.y, r.width, r.height };
+        cairo_region_union_rectangle(region, &rect);
+    }
+
+    gdk_window_shape_combine_region(mGdkWindow, region, 0, 0);
+    cairo_region_destroy(region);
+#endif
+  
     return;
 }
 
 void
 nsWindow::ResizeTransparencyBitmap(PRInt32 aNewWidth, PRInt32 aNewHeight)
 {
     if (!mTransparencyBitmap)
         return;
 
     if (aNewWidth == mTransparencyBitmapWidth &&
         aNewHeight == mTransparencyBitmapHeight)
         return;
 
-    PRInt32 newSize = ((aNewWidth+7)/8)*aNewHeight;
+    PRInt32 newSize = GetBitmapStride(aNewWidth)*aNewHeight;
     gchar* newBits = new gchar[newSize];
     if (!newBits) {
         delete[] mTransparencyBitmap;
         mTransparencyBitmap = nsnull;
         mTransparencyBitmapWidth = 0;
         mTransparencyBitmapHeight = 0;
         return;
     }
     // fill new mask with "opaque", first
     memset(newBits, 255, newSize);
 
     // Now copy the intersection of the old and new areas into the new mask
     PRInt32 copyWidth = NS_MIN(aNewWidth, mTransparencyBitmapWidth);
     PRInt32 copyHeight = NS_MIN(aNewHeight, mTransparencyBitmapHeight);
-    PRInt32 oldRowBytes = (mTransparencyBitmapWidth+7)/8;
-    PRInt32 newRowBytes = (aNewWidth+7)/8;
-    PRInt32 copyBytes = (copyWidth+7)/8;
+    PRInt32 oldRowBytes = GetBitmapStride(mTransparencyBitmapWidth);
+    PRInt32 newRowBytes = GetBitmapStride(aNewWidth);
+    PRInt32 copyBytes = GetBitmapStride(copyWidth);
 
     PRInt32 i;
     gchar* fromPtr = mTransparencyBitmap;
     gchar* toPtr = newBits;
     for (i = 0; i < copyHeight; i++) {
         memcpy(toPtr, fromPtr, copyBytes);
         fromPtr += oldRowBytes;
         toPtr += newRowBytes;
@@ -4836,17 +4831,17 @@ nsWindow::ResizeTransparencyBitmap(PRInt
     mTransparencyBitmapHeight = aNewHeight;
 }
 
 static PRBool
 ChangedMaskBits(gchar* aMaskBits, PRInt32 aMaskWidth, PRInt32 aMaskHeight,
         const nsIntRect& aRect, PRUint8* aAlphas, PRInt32 aStride)
 {
     PRInt32 x, y, xMax = aRect.XMost(), yMax = aRect.YMost();
-    PRInt32 maskBytesPerRow = (aMaskWidth + 7)/8;
+    PRInt32 maskBytesPerRow = GetBitmapStride(aMaskWidth);
     for (y = aRect.y; y < yMax; y++) {
         gchar* maskBytes = aMaskBits + y*maskBytesPerRow;
         PRUint8* alphas = aAlphas;
         for (x = aRect.x; x < xMax; x++) {
             PRBool newBit = *alphas > 0;
             alphas++;
 
             gchar maskByte = maskBytes[x >> 3];
@@ -4862,17 +4857,17 @@ ChangedMaskBits(gchar* aMaskBits, PRInt3
     return PR_FALSE;
 }
 
 static
 void UpdateMaskBits(gchar* aMaskBits, PRInt32 aMaskWidth, PRInt32 aMaskHeight,
         const nsIntRect& aRect, PRUint8* aAlphas, PRInt32 aStride)
 {
     PRInt32 x, y, xMax = aRect.XMost(), yMax = aRect.YMost();
-    PRInt32 maskBytesPerRow = (aMaskWidth + 7)/8;
+    PRInt32 maskBytesPerRow = GetBitmapStride(aMaskWidth);
     for (y = aRect.y; y < yMax; y++) {
         gchar* maskBytes = aMaskBits + y*maskBytesPerRow;
         PRUint8* alphas = aAlphas;
         for (x = aRect.x; x < xMax; x++) {
             PRBool newBit = *alphas > 0;
             alphas++;
 
             gchar mask = 1 << (x & 7);
@@ -4886,38 +4881,55 @@ void UpdateMaskBits(gchar* aMaskBits, PR
 
 void
 nsWindow::ApplyTransparencyBitmap()
 {
 #ifdef MOZ_X11
     // We use X11 calls where possible, because GDK handles expose events
     // for shaped windows in a way that's incompatible with us (Bug 635903).
     // It doesn't occur when the shapes are set through X.
-    Display* xDisplay = GDK_WINDOW_XDISPLAY(mShell->window);
-    Window xDrawable = GDK_WINDOW_XID(mShell->window);
+    GdkWindow *shellWindow = gtk_widget_get_window(mShell);
+    Display* xDisplay = GDK_WINDOW_XDISPLAY(shellWindow);
+    Window xDrawable = GDK_WINDOW_XID(shellWindow);
     Pixmap maskPixmap = XCreateBitmapFromData(xDisplay,
                                               xDrawable,
                                               mTransparencyBitmap,
                                               mTransparencyBitmapWidth,
                                               mTransparencyBitmapHeight);
     XShapeCombineMask(xDisplay, xDrawable,
                       ShapeBounding, 0, 0,
                       maskPixmap, ShapeSet);
     XFreePixmap(xDisplay, maskPixmap);
 #else
+#if defined(MOZ_WIDGET_GTK2)
     gtk_widget_reset_shapes(mShell);
-    GdkBitmap* maskBitmap = gdk_bitmap_create_from_data(mShell->window,
+    GdkBitmap* maskBitmap = gdk_bitmap_create_from_data(gtk_widget_get_window(mShell),
             mTransparencyBitmap,
             mTransparencyBitmapWidth, mTransparencyBitmapHeight);
     if (!maskBitmap)
         return;
 
     gtk_widget_shape_combine_mask(mShell, maskBitmap, 0, 0);
     g_object_unref(maskBitmap);
-#endif
+#else
+    cairo_surface_t *maskBitmap;
+    maskBitmap = cairo_image_surface_create_for_data((unsigned char*)mTransparencyBitmap, 
+                                                     CAIRO_FORMAT_A1, 
+                                                     mTransparencyBitmapWidth, 
+                                                     mTransparencyBitmapHeight,
+                                                     GetBitmapStride(mTransparencyBitmapWidth));
+    if (!maskBitmap)
+        return;
+
+    cairo_region_t * maskRegion = gdk_cairo_region_create_from_surface(maskBitmap);
+    gtk_widget_shape_combine_region(mShell, maskRegion);
+    cairo_region_destroy(maskRegion);
+    cairo_surface_destroy(maskBitmap);
+#endif // MOZ_WIDGET_GTK2
+#endif // MOZ_X11
 }
 
 nsresult
 nsWindow::UpdateTranslucentWindowAlphaInternal(const nsIntRect& aRect,
                                                PRUint8* aAlphas, PRInt32 aStride)
 {
     if (!mShell) {
         // Pass the request to the toplevel window
@@ -4931,17 +4943,17 @@ nsWindow::UpdateTranslucentWindowAlphaIn
             return NS_ERROR_FAILURE;
 
         return topWindow->UpdateTranslucentWindowAlphaInternal(aRect, aAlphas, aStride);
     }
 
     NS_ASSERTION(mIsTransparent, "Window is not transparent");
 
     if (mTransparencyBitmap == nsnull) {
-        PRInt32 size = ((mBounds.width+7)/8)*mBounds.height;
+        PRInt32 size = GetBitmapStride(mBounds.width)*mBounds.height;
         mTransparencyBitmap = new gchar[size];
         if (mTransparencyBitmap == nsnull)
             return NS_ERROR_FAILURE;
         memset(mTransparencyBitmap, 255, size);
         mTransparencyBitmapWidth = mBounds.width;
         mTransparencyBitmapHeight = mBounds.height;
     }
 
@@ -5050,59 +5062,48 @@ nsWindow::GetContainerWindow()
     return window;
 }
 
 void
 nsWindow::SetUrgencyHint(GtkWidget *top_window, PRBool state)
 {
     if (!top_window)
         return;
-
-    // Try to get a pointer to gdk_window_set_urgency_hint
-    PRLibrary* lib;
-    _gdk_window_set_urgency_hint_fn _gdk_window_set_urgency_hint = nsnull;
-    _gdk_window_set_urgency_hint = (_gdk_window_set_urgency_hint_fn)
-           PR_FindFunctionSymbolAndLibrary("gdk_window_set_urgency_hint", &lib);
-
-    if (_gdk_window_set_urgency_hint) {
-        _gdk_window_set_urgency_hint(top_window->window, state);
-        PR_UnloadLibrary(lib);
-    }
-    else if (state) {
-        gdk_window_show_unraised(top_window->window);
-    }
+        
+    gdk_window_set_urgency_hint(gtk_widget_get_window(top_window), state);
 }
 
 void *
 nsWindow::SetupPluginPort(void)
 {
     if (!mGdkWindow)
         return nsnull;
 
-    if (GDK_WINDOW_OBJECT(mGdkWindow)->destroyed == TRUE)
+    if (gdk_window_is_destroyed(mGdkWindow) == TRUE)
         return nsnull;
 
+    Window window = gdk_x11_window_get_xid(mGdkWindow);
+    
     // we have to flush the X queue here so that any plugins that
     // might be running on separate X connections will be able to use
     // this window in case it was just created
 #ifdef MOZ_X11
-    XWindowAttributes xattrs;
-    XGetWindowAttributes(GDK_DISPLAY(), GDK_WINDOW_XWINDOW(mGdkWindow),
-                         &xattrs);
-    XSelectInput (GDK_DISPLAY (),
-                  GDK_WINDOW_XWINDOW(mGdkWindow),
+    XWindowAttributes xattrs;    
+    Display *display = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
+    XGetWindowAttributes(display, window, &xattrs);
+    XSelectInput (display, window,
                   xattrs.your_event_mask |
                   SubstructureNotifyMask);
 
     gdk_window_add_filter(mGdkWindow, plugin_window_filter_func, this);
 
-    XSync(GDK_DISPLAY(), False);
+    XSync(display, False);
 #endif /* MOZ_X11 */
-
-    return (void *)GDK_WINDOW_XWINDOW(mGdkWindow);
+    
+    return (void *)window;
 }
 
 nsresult
 nsWindow::SetWindowIconList(const nsTArray<nsCString> &aIconList)
 {
     GList *list = NULL;
 
     for (PRUint32 i = 0; i < aIconList.Length(); ++i) {
@@ -5151,49 +5152,55 @@ nsWindow::SetNonXEmbedPluginFocus()
         nsRefPtr<nsWindow> kungFuDeathGrip = gPluginFocusWindow;
         gPluginFocusWindow->LoseNonXEmbedPluginFocus();
     }
 
     LOGFOCUS(("nsWindow::SetNonXEmbedPluginFocus\n"));
 
     Window curFocusWindow;
     int focusState;
-
-    XGetInputFocus(GDK_WINDOW_XDISPLAY(mGdkWindow),
+    
+    GdkDisplay *gdkDisplay = gdk_window_get_display(mGdkWindow);
+    XGetInputFocus(gdk_x11_display_get_xdisplay(gdkDisplay),
                    &curFocusWindow,
                    &focusState);
 
     LOGFOCUS(("\t curFocusWindow=%p\n", curFocusWindow));
 
     GdkWindow* toplevel = gdk_window_get_toplevel(mGdkWindow);
+#if defined(MOZ_WIDGET_GTK2)
     GdkWindow *gdkfocuswin = gdk_window_lookup(curFocusWindow);
+#else
+    GdkWindow *gdkfocuswin = gdk_x11_window_lookup_for_display(gdkDisplay,
+                                                               curFocusWindow);
+#endif
 
     // lookup with the focus proxy window is supposed to get the
     // same GdkWindow as toplevel. If the current focused window
     // is not the focus proxy, we return without any change.
     if (gdkfocuswin != toplevel) {
         return;
     }
 
     // switch the focus from the focus proxy to the plugin window
     mOldFocusWindow = curFocusWindow;
     XRaiseWindow(GDK_WINDOW_XDISPLAY(mGdkWindow),
-                 GDK_WINDOW_XWINDOW(mGdkWindow));
+                 gdk_x11_window_get_xid(mGdkWindow));
     gdk_error_trap_push();
     XSetInputFocus(GDK_WINDOW_XDISPLAY(mGdkWindow),
-                   GDK_WINDOW_XWINDOW(mGdkWindow),
+                   gdk_x11_window_get_xid(mGdkWindow),
                    RevertToNone,
                    CurrentTime);
     gdk_flush();
     gdk_error_trap_pop();
     gPluginFocusWindow = this;
     gdk_window_add_filter(NULL, plugin_client_message_filter, this);
 
     LOGFOCUS(("nsWindow::SetNonXEmbedPluginFocus oldfocus=%p new=%p\n",
-              mOldFocusWindow, GDK_WINDOW_XWINDOW(mGdkWindow)));
+              mOldFocusWindow, gdk_x11_window_get_xid(mGdkWindow)));
 }
 
 void
 nsWindow::LoseNonXEmbedPluginFocus()
 {
     LOGFOCUS(("nsWindow::LoseNonXEmbedPluginFocus\n"));
 
     // This method is only for the nsWindow which contains a
@@ -5209,17 +5216,17 @@ nsWindow::LoseNonXEmbedPluginFocus()
                    &curFocusWindow,
                    &focusState);
 
     // we only switch focus between plugin window and focus proxy. If the
     // current focused window is not the plugin window, just removing the
     // event filter that blocks the WM_TAKE_FOCUS is enough. WM and gtk2
     // will take care of the focus later.
     if (!curFocusWindow ||
-        curFocusWindow == GDK_WINDOW_XWINDOW(mGdkWindow)) {
+        curFocusWindow == gdk_x11_window_get_xid(mGdkWindow)) {
 
         gdk_error_trap_push();
         XRaiseWindow(GDK_WINDOW_XDISPLAY(mGdkWindow),
                      mOldFocusWindow);
         XSetInputFocus(GDK_WINDOW_XDISPLAY(mGdkWindow),
                        mOldFocusWindow,
                        RevertToParent,
                        CurrentTime);
@@ -5229,17 +5236,16 @@ nsWindow::LoseNonXEmbedPluginFocus()
     gPluginFocusWindow = NULL;
     mOldFocusWindow = 0;
     gdk_window_remove_filter(NULL, plugin_client_message_filter, this);
 
     LOGFOCUS(("nsWindow::LoseNonXEmbedPluginFocus end\n"));
 }
 #endif /* MOZ_X11 */
 
-
 gint
 nsWindow::ConvertBorderStyles(nsBorderStyle aStyle)
 {
     gint w = 0;
 
     if (aStyle == eBorderStyle_default)
         return -1;
 
@@ -5301,40 +5307,41 @@ nsWindow::HideWindowChrome(PRBool aShoul
 
         return topWindow->HideWindowChrome(aShouldHide);
     }
 
     // Sawfish, metacity, and presumably other window managers get
     // confused if we change the window decorations while the window
     // is visible.
     PRBool wasVisible = PR_FALSE;
-    if (gdk_window_is_visible(mShell->window)) {
-        gdk_window_hide(mShell->window);
+    GdkWindow *shellWindow = gtk_widget_get_window(mShell);
+    if (gdk_window_is_visible(shellWindow)) {
+        gdk_window_hide(shellWindow);
         wasVisible = PR_TRUE;
     }
 
     gint wmd;
     if (aShouldHide)
         wmd = 0;
     else
         wmd = ConvertBorderStyles(mBorderStyle);
 
     if (wmd != -1)
-      gdk_window_set_decorations(mShell->window, (GdkWMDecoration) wmd);
+      gdk_window_set_decorations(shellWindow, (GdkWMDecoration) wmd);
 
     if (wasVisible)
-        gdk_window_show(mShell->window);
+        gdk_window_show(shellWindow);
 
     // For some window managers, adding or removing window decorations
     // requires unmapping and remapping our toplevel window.  Go ahead
     // and flush the queue here so that we don't end up with a BadWindow
     // error later when this happens (when the persistence timer fires
     // and GetWindowPos is called)
 #ifdef MOZ_X11
-    XSync(GDK_DISPLAY(), False);
+    XSync(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()) , False);
 #else
     gdk_flush ();
 #endif /* MOZ_X11 */
 
     return NS_OK;
 }
 
 static PRBool
@@ -5435,17 +5442,22 @@ is_mouse_in_window (GdkWindow* aWindow, 
             break;
         }
 
         offsetX += tmpX;
         offsetY += tmpY;
         window = gdk_window_get_parent(window);
     }
 
+#if defined(MOZ_WIDGET_GTK2)
     gdk_drawable_get_size(aWindow, &w, &h);
+#else
+    w = gdk_window_get_width(aWindow);
+    h = gdk_window_get_height(aWindow);
+#endif
 
     if (aMouseX > x && aMouseX < x + w &&
         aMouseY > y && aMouseY < y + h)
         return PR_TRUE;
 
     return PR_FALSE;
 }
 
@@ -5472,19 +5484,16 @@ get_gtk_widget_for_gdk_window(GdkWindow 
     gdk_window_get_user_data(window, &user_data);
 
     return GTK_WIDGET(user_data);
 }
 
 static GdkCursor *
 get_gtk_cursor(nsCursor aCursor)
 {
-    GdkPixmap *cursor;
-    GdkPixmap *mask;
-    GdkColor fg, bg;
     GdkCursor *gdkcursor = nsnull;
     PRUint8 newType = 0xff;
 
     if ((gdkcursor = gCursorCache[aCursor])) {
         return gdkcursor;
     }
 
     switch (aCursor) {
@@ -5591,67 +5600,117 @@ get_gtk_cursor(nsCursor aCursor)
         NS_ASSERTION(aCursor, "Invalid cursor type");
         gdkcursor = gdk_cursor_new(GDK_LEFT_PTR);
         break;
     }
 
     // if by now we don't have a xcursor, this means we have to make a
     // custom one
     if (newType != 0xff) {
-        gdk_color_parse("#000000", &fg);
-        gdk_color_parse("#ffffff", &bg);
-
-        cursor = gdk_bitmap_create_from_data(NULL,
-                                             (char *)GtkCursors[newType].bits,
-                                             32, 32);
-        if (!cursor)
+        GdkPixbuf * cursor_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, 32, 32);
+        if (!cursor_pixbuf)
             return NULL;
-
-        mask =
-            gdk_bitmap_create_from_data(NULL,
-                                        (char *)GtkCursors[newType].mask_bits,
-                                        32, 32);
-        if (!mask) {
-            g_object_unref(cursor);
-            return NULL;
+      
+        guchar *data = gdk_pixbuf_get_pixels(cursor_pixbuf);
+        
+        // Read data from GtkCursors and compose RGBA surface from 1bit bitmap and mask
+        // GtkCursors bits and mask are 32x32 monochrome bitmaps (1 bit for each pixel)
+        // so it's 128 byte array (4 bytes for are one bitmap row and there are 32 rows here).
+        const unsigned char *bits = GtkCursors[newType].bits;
+        const unsigned char *mask_bits = GtkCursors[newType].mask_bits;
+        
+        for (int i = 0; i < 128; i++) {
+            char bit = *bits++;
+            char mask = *mask_bits++;
+            for (int j = 0; j < 8; j++) {
+                unsigned char pix = ~(((bit >> j) & 0x01) * 0xff);
+                *data++ = pix;
+                *data++ = pix;
+                *data++ = pix;
+                *data++ = (((mask >> j) & 0x01) * 0xff);
+            }
         }
-
-        gdkcursor = gdk_cursor_new_from_pixmap(cursor, mask, &fg, &bg,
+      
+        gdkcursor = gdk_cursor_new_from_pixbuf(gdk_display_get_default(), cursor_pixbuf,
                                                GtkCursors[newType].hot_x,
                                                GtkCursors[newType].hot_y);
-
-        g_object_unref(mask);
-        g_object_unref(cursor);
+        
+        g_object_unref(cursor_pixbuf);
     }
 
     gCursorCache[aCursor] = gdkcursor;
 
     return gdkcursor;
 }
 
 // gtk callbacks
 
+#if defined(MOZ_WIDGET_GTK2)
 static gboolean
 expose_event_cb(GtkWidget *widget, GdkEventExpose *event)
 {
     nsRefPtr<nsWindow> window = get_window_for_gdk_window(event->window);
     if (!window)
         return FALSE;
 
     // XXX We are so getting lucky here.  We are doing all of
     // mozilla's painting and then allowing default processing to occur.
     // This means that Mozilla paints in all of it's stuff and then
     // NO_WINDOW widgets (like scrollbars, for example) are painted by
     // Gtk on top of what we painted.
 
     // This return window->OnExposeEvent(widget, event); */
 
-    window->OnExposeEvent(widget, event);
+    window->OnExposeEvent(event);
     return FALSE;
 }
+#else
+void
+draw_window_of_widget(GtkWidget *widget, GdkWindow *aWindow, cairo_t *cr)
+{
+    gpointer windowWidget;
+    gdk_window_get_user_data(aWindow, &windowWidget);
+
+    // aWindow is in another widget
+    if (windowWidget != widget)
+        return;
+    
+    if (gtk_cairo_should_draw_window(cr, aWindow)) {
+        nsRefPtr<nsWindow> window = get_window_for_gdk_window(aWindow);
+        if (!window) {
+            NS_WARNING("Cannot get nsWindow from GtkWidget");
+        }
+        else {      
+            cairo_save(cr);      
+            gtk_cairo_transform_to_window(cr, widget, aWindow);  
+            // TODO - window->OnExposeEvent() can destroy this or other windows,
+            // do we need to handle it somehow?
+            window->OnExposeEvent(cr);
+            cairo_restore(cr);
+        }
+    }
+    
+    GList *children = gdk_window_get_children(aWindow);
+    GList *child = children;
+    while (child) {
+        draw_window_of_widget(widget, GDK_WINDOW(child->data), cr);
+        child = g_list_next(child);
+    }  
+    g_list_free(children);
+
+}
+
+/* static */
+gboolean
+expose_event_cb(GtkWidget *widget, cairo_t *cr)
+{
+    draw_window_of_widget(widget, gtk_widget_get_window(widget), cr);
+    return FALSE;
+}
+#endif //MOZ_WIDGET_GTK2
 
 static gboolean
 configure_event_cb(GtkWidget *widget,
                    GdkEventConfigure *event)
 {
     nsRefPtr<nsWindow> window = get_window_for_gtk_widget(widget);
     if (!window)
         return FALSE;
@@ -5861,63 +5920,74 @@ popup_take_focus_filter(GdkXEvent *gdk_x
 
     GtkWindow* parent = gtk_window_get_transient_for(GTK_WINDOW(widget));
     if (!parent)
         return GDK_FILTER_CONTINUE;
 
     if (gtk_window_is_active(parent))
         return GDK_FILTER_REMOVE; // leave input focus on the parent
 
-    GdkWindow* parent_window = GTK_WIDGET(parent)->window;
+    GdkWindow* parent_window = gtk_widget_get_window(GTK_WIDGET(parent));
     if (!parent_window)
         return GDK_FILTER_CONTINUE;
 
     // In case the parent has not been deconified.
     gdk_window_show_unraised(parent_window);
 
     // Request focus on the parent window.
     // Use gdk_window_focus rather than gtk_window_present to avoid
     // raising the parent window.
     gdk_window_focus(parent_window, timestamp);
     return GDK_FILTER_REMOVE;
 }
 
 static GdkFilterReturn
 plugin_window_filter_func(GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
 {
-    GdkWindow *plugin_window;
-    XEvent    *xevent;
+    GdkWindow  *plugin_window;
+    XEvent     *xevent;
+    Window      xeventWindow;
 
     nsRefPtr<nsWindow> nswindow = (nsWindow*)data;
     GdkFilterReturn return_val;
 
     xevent = (XEvent *)gdk_xevent;
     return_val = GDK_FILTER_CONTINUE;
 
     switch (xevent->type)
     {
         case CreateNotify:
         case ReparentNotify:
             if (xevent->type==CreateNotify) {
-                plugin_window = gdk_window_lookup(xevent->xcreatewindow.window);
+                xeventWindow = xevent->xcreatewindow.window;
             }
             else {
                 if (xevent->xreparent.event != xevent->xreparent.parent)
                     break;
-                plugin_window = gdk_window_lookup (xevent->xreparent.window);
+                xeventWindow = xevent->xreparent.window;
             }
+#if defined(MOZ_WIDGET_GTK2)
+            plugin_window = gdk_window_lookup(xeventWindow);
+#else
+            plugin_window = gdk_x11_window_lookup_for_display(
+                                  gdk_x11_lookup_xdisplay(xevent->xcreatewindow.display), xeventWindow);
+#endif        
             if (plugin_window) {
                 GtkWidget *widget =
                     get_gtk_widget_for_gdk_window(plugin_window);
 
+// TODO GTK3
+#if defined(MOZ_WIDGET_GTK2)
                 if (GTK_IS_XTBIN(widget)) {
                     nswindow->SetPluginType(nsWindow::PluginType_NONXEMBED);
                     break;
                 }
-                else if(GTK_IS_SOCKET(widget)) {
+                else 
+#endif
+                if(GTK_IS_SOCKET(widget)) {
                     nswindow->SetPluginType(nsWindow::PluginType_XEMBED);
                     break;
                 }
             }
             nswindow->SetPluginType(nsWindow::PluginType_NONXEMBED);
             return_val = GDK_FILTER_REMOVE;
             break;
         case EnterNotify:
@@ -5995,17 +6065,17 @@ key_press_event_cb(GtkWidget *widget, Gd
     // are generated only when the key is physically released.
 #define NS_GDKEVENT_MATCH_MASK 0x1FFF /* GDK_SHIFT_MASK .. GDK_BUTTON5_MASK */
     GdkDisplay* gdkDisplay = gtk_widget_get_display(widget);
     Display* dpy = GDK_DISPLAY_XDISPLAY(gdkDisplay);
     while (XPending(dpy)) {
         XEvent next_event;
         XPeekEvent(dpy, &next_event);
         GdkWindow* nextGdkWindow =
-            gdk_window_lookup_for_display(gdkDisplay, next_event.xany.window);
+            gdk_x11_window_lookup_for_display(gdkDisplay, next_event.xany.window);
         if (nextGdkWindow != event->window ||
             next_event.type != KeyPress ||
             next_event.xkey.keycode != event->hardware_keycode ||
             next_event.xkey.state != (event->state & NS_GDKEVENT_MATCH_MASK)) {
             break;
         }
         XNextEvent(dpy, &next_event);
         event->time = next_event.xkey.time;
@@ -6065,26 +6135,28 @@ hierarchy_changed_cb (GtkWidget *widget,
     GdkEventWindowState event;
 
     event.new_window_state = GDK_WINDOW_STATE_WITHDRAWN;
 
     if (GTK_IS_WINDOW(previous_toplevel)) {
         g_signal_handlers_disconnect_by_func(previous_toplevel,
                                              FuncToGpointer(window_state_event_cb),
                                              widget);
-        if (previous_toplevel->window) {
-            old_window_state = gdk_window_get_state(previous_toplevel->window);
+        GdkWindow *win = gtk_widget_get_window(previous_toplevel);
+        if (win) {
+            old_window_state = gdk_window_get_state(win);
         }
     }
 
     if (GTK_IS_WINDOW(toplevel)) {
         g_signal_connect_swapped(toplevel, "window-state-event",
                                  G_CALLBACK(window_state_event_cb), widget);
-        if (toplevel->window) {
-            event.new_window_state = gdk_window_get_state(toplevel->window);
+        GdkWindow *win = gtk_widget_get_window(toplevel);
+        if (win) {
+            event.new_window_state = gdk_window_get_state(win);
         }
     }
 
     event.changed_mask = static_cast<GdkWindowState>
         (old_window_state ^ event.new_window_state);
 
     if (event.changed_mask) {
         event.type = GDK_WINDOW_STATE;
@@ -6115,50 +6187,50 @@ theme_changed_cb (GtkSettings *settings,
 
 //////////////////////////////////////////////////////////////////////
 // These are all of our drag and drop operations
 
 void
 nsWindow::InitDragEvent(nsDragEvent &aEvent)
 {
     // set the keyboard modifiers
-    gint x, y;
     GdkModifierType state = (GdkModifierType)0;
-    gdk_window_get_pointer(NULL, &x, &y, &state);
+    gdk_display_get_pointer(gdk_display_get_default(), NULL, NULL, NULL, &state);
     aEvent.isShift = (state & GDK_SHIFT_MASK) ? PR_TRUE : PR_FALSE;
     aEvent.isControl = (state & GDK_CONTROL_MASK) ? PR_TRUE : PR_FALSE;
     aEvent.isAlt = (state & GDK_MOD1_MASK) ? PR_TRUE : PR_FALSE;
     aEvent.isMeta = PR_FALSE; // GTK+ doesn't support the meta key
 }
 
 // This will update the drag action based on the information in the
 // drag context.  Gtk gets this from a combination of the key settings
 // and what the source is offering.
 
 void
 nsWindow::UpdateDragStatus(GdkDragContext *aDragContext,
                            nsIDragService *aDragService)
 {
     // default is to do nothing
     int action = nsIDragService::DRAGDROP_ACTION_NONE;
+    GdkDragAction gdkAction = gdk_drag_context_get_actions(aDragContext);
 
     // set the default just in case nothing matches below
-    if (aDragContext->actions & GDK_ACTION_DEFAULT)
+    if (gdkAction & GDK_ACTION_DEFAULT)
         action = nsIDragService::DRAGDROP_ACTION_MOVE;
 
     // first check to see if move is set
-    if (aDragContext->actions & GDK_ACTION_MOVE)
+    if (gdkAction & GDK_ACTION_MOVE)
         action = nsIDragService::DRAGDROP_ACTION_MOVE;
 
     // then fall to the others
-    else if (aDragContext->actions & GDK_ACTION_LINK)
+    else if (gdkAction & GDK_ACTION_LINK)
         action = nsIDragService::DRAGDROP_ACTION_LINK;
 
     // copy is ctrl
-    else if (aDragContext->actions & GDK_ACTION_COPY)
+    else if (gdkAction & GDK_ACTION_COPY)
         action = nsIDragService::DRAGDROP_ACTION_COPY;
 
     // update the drag information
     nsCOMPtr<nsIDragSession> session;
     aDragService->GetCurrentSession(getter_AddRefs(session));
 
     if (session)
         session->SetDragAction(action);
@@ -6269,24 +6341,28 @@ nsWindow::DragLeaveTimerCallback(nsITime
     window->FireDragLeaveTimer();
 }
 
 static GdkWindow *
 get_inner_gdk_window (GdkWindow *aWindow,
                       gint x, gint y,
                       gint *retx, gint *rety)
 {
-    gint cx, cy, cw, ch, cd;
+    gint cx, cy, cw, ch;
     GList *children = gdk_window_peek_children(aWindow);
     for (GList *child = g_list_last(children);
          child;
          child = g_list_previous(child)) {
         GdkWindow *childWindow = (GdkWindow *) child->data;
         if (get_window_for_gdk_window(childWindow)) {
-            gdk_window_get_geometry(childWindow, &cx, &cy, &cw, &ch, &cd);
+#if defined(MOZ_WIDGET_GTK2)
+            gdk_window_get_geometry(childWindow, &cx, &cy, &cw, &ch, NULL);
+#else
+            gdk_window_get_geometry(childWindow, &cx, &cy, &cw, &ch);
+#endif
             if ((cx < x) && (x < (cx + cw)) &&
                 (cy < y) && (y < (cy + ch)) &&
                 gdk_window_is_visible(childWindow)) {
                 return get_inner_gdk_window(childWindow,
                                             x - cx, y - cy,
                                             retx, rety);
             }
         }
@@ -6556,17 +6632,17 @@ nsWindow::GetToggledKeyState(PRUint32 aK
 
     *aLEDState = (modifiers & mask) != 0;
     return NS_OK;
 #else
     return NS_ERROR_NOT_IMPLEMENTED;
 #endif /* MOZ_X11 */
 }
 
-#ifdef MOZ_X11
+#if defined(MOZ_X11) && defined(MOZ_WIDGET_GTK2)
 /* static */ already_AddRefed<gfxASurface>
 nsWindow::GetSurfaceForGdkDrawable(GdkDrawable* aDrawable,
                                    const nsIntSize& aSize)
 {
     GdkVisual* visual = gdk_drawable_get_visual(aDrawable);
     Screen* xScreen =
         gdk_x11_screen_get_xscreen(gdk_drawable_get_screen(aDrawable));
     Display* xDisplay = DisplayOfScreen(xScreen);
@@ -6601,65 +6677,90 @@ nsWindow::GetSurfaceForGdkDrawable(GdkDr
 
     NS_IF_ADDREF(result);
     return result;
 }
 #endif
 
 // return the gfxASurface for rendering to this widget
 gfxASurface*
+#if defined(MOZ_WIDGET_GTK2)
 nsWindow::GetThebesSurface()
+#else
+nsWindow::GetThebesSurface(cairo_t *cr)
+#endif
 {
     if (!mGdkWindow)
         return nsnull;
 
-    GdkDrawable* d;
-    gint x_offset, y_offset;
-    gdk_window_get_internal_paint_info(mGdkWindow, &d, &x_offset, &y_offset);
+#if !defined(MOZ_WIDGET_GTK2)
+    cairo_surface_t *surf = cairo_get_target(cr);
+    if (cairo_surface_status(surf) != CAIRO_STATUS_SUCCESS) {
+      NS_NOTREACHED("Missing cairo target?");
+      return NULL;
+    }
+#endif // MOZ_WIDGET_GTK2
 
 #ifdef MOZ_X11
     gint width, height;
-    gdk_drawable_get_size(d, &width, &height);
+
+#if defined(MOZ_WIDGET_GTK2)
+    gdk_drawable_get_size(GDK_DRAWABLE(mGdkWindow), &width, &height);
+#else
+    width = gdk_window_get_width(mGdkWindow);
+    height = gdk_window_get_height(mGdkWindow);
+#endif
+
     // Owen Taylor says this is the right thing to do!
     width = NS_MIN(32767, width);
     height = NS_MIN(32767, height);
     gfxIntSize size(width, height);
-    Visual* visual = GDK_VISUAL_XVISUAL(gdk_drawable_get_visual(d));
+
+    GdkVisual *gdkVisual = gdk_window_get_visual(mGdkWindow);
+    Visual* visual = gdk_x11_visual_get_xvisual(gdkVisual);
 
 #  ifdef MOZ_HAVE_SHMIMAGE
     PRBool usingShm = PR_FALSE;
     if (nsShmImage::UseShm()) {
         // EnsureShmImage() is a dangerous interface, but we guarantee
         // that the thebes surface and the shmimage have the same
         // lifetime
         mThebesSurface =
             nsShmImage::EnsureShmImage(size,
-                                       visual, gdk_drawable_get_depth(d),
+                                       visual, gdk_visual_get_depth(gdkVisual),
                                        mShmImage);
         usingShm = mThebesSurface != nsnull;
     }
     if (!usingShm)
 #  endif  // MOZ_HAVE_SHMIMAGE
 
+#if defined(MOZ_WIDGET_GTK2)
     mThebesSurface = new gfxXlibSurface
-        (GDK_WINDOW_XDISPLAY(d),
-         GDK_WINDOW_XWINDOW(d),
+        (GDK_WINDOW_XDISPLAY(mGdkWindow),
+         gdk_x11_window_get_xid(mGdkWindow),
          visual,
          size);
+#else
+#if MOZ_TREE_CAIRO
+#error "cairo-gtk3 target must be built with --enable-system-cairo"
+#else
+    mThebesSurface = gfxASurface::Wrap(surf);
+#endif
+#endif
+
 #endif
 #ifdef MOZ_DFB
-    mThebesSurface = new gfxDirectFBSurface(gdk_directfb_surface_lookup(d));
+    // not supported
+    mThebesSurface = nsnull;
 #endif
 
     // if the surface creation is reporting an error, then
     // we don't have a surface to give back
     if (mThebesSurface && mThebesSurface->CairoStatus() != 0) {
         mThebesSurface = nsnull;
-    } else {
-        mThebesSurface->SetDeviceOffset(gfxPoint(-x_offset, -y_offset));
     }
 
     return mThebesSurface;
 }
 
 // Code shared begin BeginMoveDrag and BeginResizeDrag
 PRBool
 nsWindow::GetDragInfo(nsMouseEvent* aMouseEvent,
--- a/widget/src/gtk2/nsWindow.h
+++ b/widget/src/gtk2/nsWindow.h
@@ -198,18 +198,21 @@ public:
     NS_IMETHOD         MakeFullScreen(PRBool aFullScreen);
     NS_IMETHOD         HideWindowChrome(PRBool aShouldHide);
 
     // utility method, -1 if no change should be made, otherwise returns a
     // value that can be passed to gdk_window_set_decorations
     gint               ConvertBorderStyles(nsBorderStyle aStyle);
 
     // event callbacks
-    gboolean           OnExposeEvent(GtkWidget *aWidget,
-                                     GdkEventExpose *aEvent);
+#if defined(MOZ_WIDGET_GTK2)
+    gboolean           OnExposeEvent(GdkEventExpose *aEvent);
+#else
+    gboolean           OnExposeEvent(cairo_t *cr);
+#endif
     gboolean           OnConfigureEvent(GtkWidget *aWidget,
                                         GdkEventConfigure *aEvent);
     void               OnContainerUnrealize(GtkWidget *aWidget);
     void               OnSizeAllocate(GtkWidget *aWidget,
                                       GtkAllocation *aAllocation);
     void               OnDeleteEvent(GtkWidget *aWidget,
                                      GdkEventAny *aEvent);
     void               OnEnterNotifyEvent(GtkWidget *aWidget,
@@ -329,20 +332,24 @@ public:
    void                ResizeTransparencyBitmap(PRInt32 aNewWidth, PRInt32 aNewHeight);
    void                ApplyTransparencyBitmap();
    virtual void        SetTransparencyMode(nsTransparencyMode aMode);
    virtual nsTransparencyMode GetTransparencyMode();
    virtual nsresult    ConfigureChildren(const nsTArray<Configuration>& aConfigurations);
    nsresult            UpdateTranslucentWindowAlphaInternal(const nsIntRect& aRect,
                                                             PRUint8* aAlphas, PRInt32 aStride);
 
+#if defined(MOZ_WIDGET_GTK2)
     gfxASurface       *GetThebesSurface();
 
     static already_AddRefed<gfxASurface> GetSurfaceForGdkDrawable(GdkDrawable* aDrawable,
                                                                   const nsIntSize& aSize);
+#else
+    gfxASurface       *GetThebesSurface(cairo_t *cr);
+#endif
     NS_IMETHOD         ReparentNativeWidget(nsIWidget* aNewParent);
 
 #ifdef ACCESSIBILITY
     static PRBool      sAccessibilityEnabled;
 #endif
 protected:
     // Helper for SetParent and ReparentNativeWidget.
     void ReparentNativeWidgetInternal(nsIWidget* aNewParent,
@@ -523,9 +530,8 @@ private:
 
 class nsChildWindow : public nsWindow {
 public:
     nsChildWindow();
     ~nsChildWindow();
 };
 
 #endif /* __nsWindow_h__ */
-
--- a/widget/src/shared/nsShmImage.cpp
+++ b/widget/src/shared/nsShmImage.cpp
@@ -33,17 +33,17 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-#if defined(MOZ_WIDGET_GTK2)
+#if defined(MOZ_WIDGET_GTK2) || defined(MOZ_WIDGET_GTK3)
 #include <gtk/gtk.h>
 #include <gdk/gdkx.h>
 #elif defined(MOZ_WIDGET_QT)
 #include <QWidget>
 #endif
 
 #include "nsShmImage.h"
 #include "gfxPlatform.h"
@@ -86,17 +86,17 @@ nsShmImage::Create(const gfxIntSize& aSi
     }
 
     shm->mInfo.shmid = shm->mSegment->GetHandle();
     shm->mInfo.shmaddr =
         shm->mImage->data = static_cast<char*>(shm->mSegment->memory());
     shm->mInfo.readOnly = False;
 
     int xerror = 0;
-#if defined(MOZ_WIDGET_GTK2)
+#if defined(MOZ_WIDGET_GTK2) || defined(MOZ_WIDGET_GTK3)
     gdk_error_trap_push();
     Status attachOk = XShmAttach(dpy, &shm->mInfo);
     XSync(dpy, False);
     xerror = gdk_error_trap_pop();
 #elif defined(MOZ_WIDGET_QT)
     Status attachOk = XShmAttach(dpy, &shm->mInfo);
 #endif
 
@@ -157,26 +157,55 @@ nsShmImage::Put(GdkWindow* aWindow, GdkR
         XShmPutImage(dpy, d, gc, mImage,
                      r->x, r->y,
                      r->x - dx, r->y - dy,
                      r->width, r->height,
                      False);
     }
     XFreeGC(dpy, gc);
 
-#ifdef MOZ_WIDGET_GTK2
     // FIXME/bug 597336: we need to ensure that the shm image isn't
     // scribbled over before all its pending XShmPutImage()s complete.
     // However, XSync() is an unnecessarily heavyweight
     // synchronization mechanism; other options are possible.  If this
     // XSync is shown to hurt responsiveness, we need to explore the
     // other options.
     XSync(dpy, False);
-#endif
 }
+
+#elif defined(MOZ_WIDGET_GTK3)
+void
+nsShmImage::Put(GdkWindow* aWindow, cairo_rectangle_list_t* aRects)
+{
+    Display* dpy = gdk_x11_get_default_xdisplay();
+    Drawable d = GDK_WINDOW_XID(aWindow);
+    int dx = 0, dy = 0;
+
+    GC gc = XCreateGC(dpy, d, 0, nsnull);
+    cairo_rectangle_t r;
+    for (int i = 0; i < aRects->num_rectangles; i++) {
+        r = aRects->rectangles[i];
+        XShmPutImage(dpy, d, gc, mImage,
+                     r.x, r.y,
+                     r.x - dx, r.y - dy,
+                     r.width, r.height,
+                     False);
+    }
+
+    XFreeGC(dpy, gc);
+
+    // FIXME/bug 597336: we need to ensure that the shm image isn't
+    // scribbled over before all its pending XShmPutImage()s complete.
+    // However, XSync() is an unnecessarily heavyweight
+    // synchronization mechanism; other options are possible.  If this
+    // XSync is shown to hurt responsiveness, we need to explore the
+    // other options.
+    XSync(dpy, False);
+}
+
 #elif defined(MOZ_WIDGET_QT)
 void
 nsShmImage::Put(QWidget* aWindow, QRect& aRect)
 {
     Display* dpy = aWindow->x11Info().display();
     Drawable d = aWindow->handle();
 
     GC gc = XCreateGC(dpy, d, 0, nsnull);
--- a/widget/src/shared/nsShmImage.h
+++ b/widget/src/shared/nsShmImage.h
@@ -51,17 +51,17 @@
 
 #include "nsIWidget.h"
 #include "gfxASurface.h"
 
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 #include <X11/extensions/XShm.h>
 
-#if defined(MOZ_WIDGET_GTK2)
+#if defined(MOZ_WIDGET_GTK2) || defined(MOZ_WIDGET_GTK3)
 #define DISPLAY gdk_x11_get_default_xdisplay
 #elif defined(MOZ_WIDGET_QT)
 #include "QX11Info"
 #define DISPLAY QX11Info().display
 #endif
 
 class QRect;
 class QWidget;
@@ -90,16 +90,18 @@ public:
             XDestroyImage(mImage);
         }
     }
 
     already_AddRefed<gfxASurface> AsSurface();
 
 #if defined(MOZ_WIDGET_GTK2)
     void Put(GdkWindow* aWindow, GdkRectangle* aRects, GdkRectangle* aEnd);
+#elif defined(MOZ_WIDGET_GTK3)
+    void Put(GdkWindow* aWindow, cairo_rectangle_list_t* aRects);
 #elif defined(MOZ_WIDGET_QT)
     void Put(QWidget* aWindow, QRect& aRect);
 #endif
 
     gfxIntSize Size() const { return mSize; }
 
 private:
     nsShmImage()