changeset 9760:8c6d0386d3f5

8087516: Conditional support for GTK 3 on Linux Reviewed-by: kcr
author ddhill
date Fri, 06 May 2016 19:50:10 -0400
parents 1d3101c5796b
children 378a29c3fe40
files buildSrc/linux.gradle modules/graphics/src/main/java/com/sun/glass/ui/gtk/GtkApplication.java modules/graphics/src/main/native-glass/gtk/GlassApplication.cpp modules/graphics/src/main/native-glass/gtk/GlassCommonDialogs.cpp modules/graphics/src/main/native-glass/gtk/GlassRobot.cpp modules/graphics/src/main/native-glass/gtk/GlassSystemClipboard.cpp modules/graphics/src/main/native-glass/gtk/GlassView.cpp modules/graphics/src/main/native-glass/gtk/GlassWindow.cpp modules/graphics/src/main/native-glass/gtk/glass_dnd.cpp modules/graphics/src/main/native-glass/gtk/glass_general.cpp modules/graphics/src/main/native-glass/gtk/glass_general.h modules/graphics/src/main/native-glass/gtk/glass_gtkcompat.cpp modules/graphics/src/main/native-glass/gtk/glass_gtkcompat.h modules/graphics/src/main/native-glass/gtk/glass_key.cpp modules/graphics/src/main/native-glass/gtk/glass_screen.cpp modules/graphics/src/main/native-glass/gtk/glass_window.cpp modules/graphics/src/main/native-glass/gtk/glass_window.h modules/graphics/src/main/native-glass/gtk/glass_window_ime.cpp modules/graphics/src/main/native-glass/gtk/glass_wrapper.h modules/graphics/src/main/native-glass/gtk/wrapper_gdk.c modules/graphics/src/main/native-glass/gtk/wrapper_gtk.c modules/graphics/src/main/native-glass/gtk/wrapper_main.c modules/graphics/src/main/native-glass/gtk/wrapper_pix.c
diffstat 23 files changed, 3436 insertions(+), 667 deletions(-) [+]
line wrap: on
line diff
--- a/buildSrc/linux.gradle	Fri May 06 13:48:32 2016 -0700
+++ b/buildSrc/linux.gradle	Fri May 06 19:50:10 2016 -0400
@@ -72,7 +72,7 @@
 
         results = new ByteArrayOutputStream();
         exec {
-            commandLine "pkg-config", "--libs", "gtk+-2.0", "gthread-2.0", "xtst"
+            commandLine "pkg-config", "--libs", "pangocairo", "gio-2.0", "gthread-2.0", "xtst"
             standardOutput = results
         }
         propFile << "libs=" << results.toString().trim();
@@ -144,7 +144,7 @@
 LINUX.glass.compiler = compiler
 LINUX.glass.ccFlags = [ccFlags, "-Werror"].flatten()
 LINUX.glass.linker = linker
-LINUX.glass.linkFlags = [linkFlags].flatten()
+LINUX.glass.linkFlags = [linkFlags ].flatten()
 LINUX.glass.lib = "glass"
 
 LINUX.decora = [:]
--- a/modules/graphics/src/main/java/com/sun/glass/ui/gtk/GtkApplication.java	Fri May 06 13:48:32 2016 -0700
+++ b/modules/graphics/src/main/java/com/sun/glass/ui/gtk/GtkApplication.java	Fri May 06 19:50:10 2016 -0400
@@ -61,6 +61,7 @@
     private final InvokeLaterDispatcher invokeLaterDispatcher;
 
     GtkApplication() {
+
         // Check whether the Display is valid and throw an exception if not.
         // We use UnsupportedOperationException rather than HeadlessException
         // so as not to introduce a dependency on AWT.
@@ -68,6 +69,27 @@
             throw new UnsupportedOperationException("Unable to open DISPLAY");
         }
 
+        int gtkVersion =
+                AccessController.doPrivileged((PrivilegedAction<Integer>) () -> {
+            String v = System.getProperty("jdk.gtk.version","2");
+            int ret = 0;
+            if ("3".equals(v) || v.startsWith("3.")) {
+                ret = 3;
+            } else if ("2".equals(v) || v.startsWith("2.")) {
+                ret = 2;
+            }
+            return ret;
+        });
+        boolean gtkVersionVerbose =
+                AccessController.doPrivileged((PrivilegedAction<Boolean>) () -> {
+            return Boolean.getBoolean("jdk.gtk.verbose");
+        });
+        int version = _initGTK(gtkVersion, gtkVersionVerbose);
+
+        if (version == -1) {
+            throw new RuntimeException("Error loading GTK libraries");
+        }
+
         // Embedded in SWT, with shared event thread
         boolean isEventThread = AccessController
                 .doPrivileged((PrivilegedAction<Boolean>) () -> Boolean.getBoolean("javafx.embed.isEventThread"));
@@ -79,6 +101,8 @@
         }
     }
 
+    private static native int _initGTK(int version, boolean verbose);
+
     private static boolean isDisplayValid() {
         return _isDisplayValid();
     }
--- a/modules/graphics/src/main/native-glass/gtk/GlassApplication.cpp	Fri May 06 13:48:32 2016 -0700
+++ b/modules/graphics/src/main/native-glass/gtk/GlassApplication.cpp	Fri May 06 19:50:10 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -79,6 +79,48 @@
     return is_display_valid();
 }
 
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+static void init_threads() {
+    gboolean is_g_thread_get_initialized = FALSE;
+    if (glib_check_version(2, 32, 0)) { // < 2.32
+        if (!glib_check_version(2, 20, 0)) {
+            is_g_thread_get_initialized = g_thread_get_initialized();
+        }
+        if (!is_g_thread_get_initialized) {
+            g_thread_init(NULL);
+        }
+    }
+    gdk_threads_init();
+}
+#pragma GCC diagnostic pop
+
+
+/*
+ * Class:     com_sun_glass_ui_gtk_GtkApplication
+ * Method:    _initGTK
+ * Signature: (IZ)I
+ */
+JNIEXPORT jint JNICALL Java_com_sun_glass_ui_gtk_GtkApplication__1initGTK
+  (JNIEnv *env, jclass clazz, jint version, jboolean verbose)
+{
+    (void) clazz;
+
+    int ret = wrapper_load_symbols(version, verbose);
+
+    if (ret == -1) {
+        return -1;
+    }
+
+    env->ExceptionClear();
+    init_threads();
+
+    gdk_threads_enter();
+    gtk_init(NULL, NULL);
+
+    return ret;
+}
+
 /*
  * Class:     com_sun_glass_ui_gtk_GtkApplication
  * Method:    _init
--- a/modules/graphics/src/main/native-glass/gtk/GlassCommonDialogs.cpp	Fri May 06 13:48:32 2016 -0700
+++ b/modules/graphics/src/main/native-glass/gtk/GlassCommonDialogs.cpp	Fri May 06 19:50:10 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -112,13 +112,12 @@
         return create_empty_result();
     }
 
-    GtkWidget* chooser = gtk_file_chooser_dialog_new(chooser_title, gdk_window_handle_to_gtk(parent),
+    GtkWidget* chooser = glass_file_chooser_dialog(
+            chooser_title,
+            gdk_window_handle_to_gtk(parent),
             static_cast<GtkFileChooserAction>(chooser_type),
-            GTK_STOCK_CANCEL,
-            GTK_RESPONSE_CANCEL,
-            (chooser_type == GTK_FILE_CHOOSER_ACTION_OPEN ? GTK_STOCK_OPEN : GTK_STOCK_SAVE),
-            GTK_RESPONSE_ACCEPT,
-            NULL);
+            (chooser_type == GTK_FILE_CHOOSER_ACTION_OPEN ? GTK_STOCK_OPEN : GTK_STOCK_SAVE)
+            );
 
     if (chooser_type == GTK_FILE_CHOOSER_ACTION_SAVE) {
         gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(chooser), chooser_filename);
@@ -197,15 +196,12 @@
         return NULL;
     }
 
-    GtkWidget* chooser = gtk_file_chooser_dialog_new(
+    GtkWidget* chooser = glass_file_chooser_dialog(
             chooser_title,
             gdk_window_handle_to_gtk(parent),
             GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
-            GTK_STOCK_CANCEL,
-            GTK_RESPONSE_CANCEL,
-            GTK_STOCK_OPEN,
-            GTK_RESPONSE_ACCEPT,
-            NULL);
+            GTK_STOCK_OPEN
+            );
 
     if (chooser_folder != NULL) {
         gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(chooser),
--- a/modules/graphics/src/main/native-glass/gtk/GlassRobot.cpp	Fri May 06 13:48:32 2016 -0700
+++ b/modules/graphics/src/main/native-glass/gtk/GlassRobot.cpp	Fri May 06 19:50:10 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,6 @@
 #include <com_sun_glass_ui_gtk_GtkRobot.h>
 #include <com_sun_glass_events_MouseEvent.h>
 #include "glass_general.h"
-#include "glass_gtkcompat.h"
 #include "glass_key.h"
 
 
@@ -247,8 +246,7 @@
     GdkPixbuf *screenshot, *tmp;
     GdkWindow *root_window = gdk_get_default_root_window();
 
-    tmp = gdk_pixbuf_get_from_drawable (NULL, root_window, NULL,
-                                           x, y, 0, 0, width, height);
+    tmp = glass_pixbuf_from_window(root_window, x, y, width, height);
     screenshot = gdk_pixbuf_add_alpha(tmp, FALSE, 0, 0, 0);
     g_object_unref(tmp);
 
--- a/modules/graphics/src/main/native-glass/gtk/GlassSystemClipboard.cpp	Fri May 06 13:48:32 2016 -0700
+++ b/modules/graphics/src/main/native-glass/gtk/GlassSystemClipboard.cpp	Fri May 06 19:50:10 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,6 @@
  * questions.
  */
 #include "com_sun_glass_ui_gtk_GtkSystemClipboard.h"
-#include "glass_gtkcompat.h"
 #include "glass_general.h"
 
 #include <gtk/gtk.h>
--- a/modules/graphics/src/main/native-glass/gtk/GlassView.cpp	Fri May 06 13:48:32 2016 -0700
+++ b/modules/graphics/src/main/native-glass/gtk/GlassView.cpp	Fri May 06 19:50:10 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,7 +32,6 @@
 #include "glass_general.h"
 #include "glass_view.h"
 #include "glass_window.h"
-#include "glass_gtkcompat.h"
 
 #define JLONG_TO_GLASSVIEW(value) ((GlassView *) JLONG_TO_PTR(value))
 
--- a/modules/graphics/src/main/native-glass/gtk/GlassWindow.cpp	Fri May 06 13:48:32 2016 -0700
+++ b/modules/graphics/src/main/native-glass/gtk/GlassWindow.cpp	Fri May 06 19:50:10 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,6 @@
 
 #include <cstdlib>
 #include <cstring>
-#include "glass_gtkcompat.h"
 #include "glass_general.h"
 #include "glass_evloop.h"
 #include "glass_window.h"
@@ -109,7 +108,7 @@
     WindowContextPlug *parent_ctx = NULL;
     WindowContext *ctx = NULL;
 
-    parent_window = GLASS_GDK_WINDOW_LOOKUP_FOR_DISPLAY(
+    parent_window = gdk_x11_window_lookup_for_display(
                         gdk_display_get_default(),
                         (GdkNativeWindow)PTR_TO_JLONG(owner));
 
--- a/modules/graphics/src/main/native-glass/gtk/glass_dnd.cpp	Fri May 06 13:48:32 2016 -0700
+++ b/modules/graphics/src/main/native-glass/gtk/glass_dnd.cpp	Fri May 06 19:50:10 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,6 @@
  * questions.
  */
 #include "glass_dnd.h"
-#include "glass_gtkcompat.h"
 #include "glass_general.h"
 #include "glass_evloop.h"
 
@@ -35,6 +34,8 @@
 
 #include <gtk/gtk.h>
 #include <gdk/gdkx.h>
+#include "glass_wrapper.h"
+#include <gdk/gdkkeysyms.h>
 
 /************************* COMMON *********************************************/
 static jint translate_gdk_action_to_glass(GdkDragAction action)
@@ -165,7 +166,7 @@
         return; // Do not process motion events if no enter event was received
     }
     jmethodID method = enter_ctx.just_entered ? jViewNotifyDragEnter : jViewNotifyDragOver;
-    GdkDragAction suggested = GLASS_GDK_DRAG_CONTEXT_GET_SUGGESTED_ACTION(event->context);
+    GdkDragAction suggested = gdk_drag_context_get_suggested_action(event->context);
     GdkDragAction result = translate_glass_action_to_gdk(mainEnv->CallIntMethod(ctx->get_jview(), method,
             (jint)event->x_root - enter_ctx.dx, (jint)event->y_root - enter_ctx.dy,
             (jint)event->x_root, (jint)event->y_root,
@@ -193,7 +194,7 @@
         gdk_drop_reply(event->context, FALSE, GDK_CURRENT_TIME);
         return; // Do not process drop events if no enter event and subsequent motion event were received
     }
-    GdkDragAction selected = GLASS_GDK_DRAG_CONTEXT_GET_SELECTED_ACTION(event->context);
+    GdkDragAction selected = gdk_drag_context_get_selected_action(event->context);
 
     mainEnv->CallIntMethod(ctx->get_jview(), jViewNotifyDragDrop,
             (jint)event->x_root - enter_ctx.dx, (jint)event->y_root - enter_ctx.dy,
@@ -245,7 +246,7 @@
         return NULL;
     }
     if (!enter_ctx.mimes) {
-        GList* targets = GLASS_GDK_DRAG_CONTEXT_LIST_TARGETS(enter_ctx.ctx);
+        GList* targets = gdk_drag_context_list_targets(enter_ctx.ctx);
         jobject set = env->NewObject(jHashSetCls, jHashSetInit, NULL);
         EXCEPTION_OCCURED(env);
 
@@ -312,13 +313,13 @@
     if (check_state_in_drag(env)) {
         return 0;
     }
-    return translate_gdk_action_to_glass(GLASS_GDK_DRAG_CONTEXT_GET_ACTIONS(enter_ctx.ctx));
+    return translate_gdk_action_to_glass(gdk_drag_context_get_actions(enter_ctx.ctx));
 }
 
 static void wait_for_selection_data_hook(GdkEvent * event, void * data)
 {
     selection_data_ctx *ctx = (selection_data_ctx*)data;
-    GdkWindow *dest = GLASS_GDK_DRAG_CONTEXT_GET_DEST_WINDOW(enter_ctx.ctx);
+    GdkWindow *dest = glass_gdk_drag_context_get_dest_window(enter_ctx.ctx);
     if (event->type == GDK_SELECTION_NOTIFY &&
             event->selection.window == dest) {
         if (event->selection.property) { // if 0, that we received negative response
@@ -334,7 +335,7 @@
 
     memset(selection_ctx, 0, sizeof(selection_data_ctx));
 
-    gdk_selection_convert(GLASS_GDK_DRAG_CONTEXT_GET_DEST_WINDOW(enter_ctx.ctx), gdk_drag_get_selection(enter_ctx.ctx), target,
+    gdk_selection_convert(glass_gdk_drag_context_get_dest_window(enter_ctx.ctx), gdk_drag_get_selection(enter_ctx.ctx), target,
                           GDK_CURRENT_TIME);
 
     hookReg =
@@ -560,7 +561,7 @@
     if (dnd_window) {
         dnd_set_performed_action(
                 translate_gdk_action_to_glass(
-                    GLASS_GDK_DRAG_CONTEXT_GET_SELECTED_ACTION(
+                    gdk_drag_context_get_selected_action(
                         get_drag_context())));
 
         gdk_window_destroy(dnd_window);
@@ -688,7 +689,7 @@
     mainEnv->CallVoidMethod(pixels, jPixelsAttachData, PTR_TO_JLONG(&pixbuf));
 
     if (!EXCEPTION_OCCURED(mainEnv)
-            && gdk_pixbuf_save_to_buffer(pixbuf, &buffer, &size, type, NULL, NULL)) {
+            && glass_gdk_pixbuf_save_to_buffer(pixbuf, &buffer, &size, type, NULL)) {
         gdk_property_change(requestor, property, target,
                 8, GDK_PROP_MODE_REPLACE, (guchar *)buffer, size);
         result = TRUE;
@@ -785,7 +786,9 @@
 {
     (void)window;
 
-    GdkWindow *requestor = GLASS_GDK_SELECTION_EVENT_GET_REQUESTOR(event);
+    GdkWindow *requestor = gdk_x11_window_foreign_new_for_display(
+            gdk_display_get_default(),
+            event->requestor);
 
     gboolean is_data_set = FALSE;
     if (event->target == TARGET_UTF8_STRING_ATOM
@@ -812,7 +815,7 @@
 
     glass_gdk_master_pointer_ungrab();
 
-    if (GLASS_GDK_DRAG_CONTEXT_GET_SELECTED_ACTION(get_drag_context())) {
+    if (gdk_drag_context_get_selected_action(get_drag_context())) {
         gdk_drag_drop(get_drag_context(), GDK_CURRENT_TIME);
     } else {
         gdk_drag_abort(get_drag_context(), GDK_CURRENT_TIME);
@@ -881,7 +884,7 @@
 {
     (void)window;
 
-    GdkDragAction selected = GLASS_GDK_DRAG_CONTEXT_GET_SELECTED_ACTION(event->context);
+    GdkDragAction selected = gdk_drag_context_get_selected_action(event->context);
     GdkCursor* cursor;
 
     if (selected & GDK_ACTION_COPY) {
@@ -1212,10 +1215,6 @@
 
     gtk_widget_realize(widget);
 
-    GdkRegion* region = gdk_region_new();
-    gdk_window_input_shape_combine_region(gtk_widget_get_window(widget), region, 0,0);
-    gdk_region_destroy(region);
-
     gtk_widget_set_app_paintable(widget, TRUE);
 
     g_signal_connect(G_OBJECT(widget), "expose-event", G_CALLBACK(on_expose), this);
@@ -1231,19 +1230,15 @@
 
 void DragView::View::screen_changed() {
     GdkScreen *screen = gtk_widget_get_screen(widget);
-    GdkColormap *colormap = gdk_screen_get_rgba_colormap(screen);
 
-    if (!colormap || !gdk_screen_is_composited(screen)) {
+    glass_configure_window_transparency(widget, true);
+
+    if (!gdk_screen_is_composited(screen)) {
         if (!is_offset_set) {
             offset_x = 1;
             offset_y = 1;
         }
     }
-
-    if (!colormap) {
-        colormap = gdk_screen_get_rgb_colormap(screen);
-    }
-    gtk_widget_set_colormap(widget, colormap);
 }
 
 void DragView::View::expose() {
--- a/modules/graphics/src/main/native-glass/gtk/glass_general.cpp	Fri May 06 13:48:32 2016 -0700
+++ b/modules/graphics/src/main/native-glass/gtk/glass_general.cpp	Fri May 06 19:50:10 2016 -0400
@@ -111,26 +111,6 @@
 jmethodID jApplicationGetApplication;
 jmethodID jApplicationGetName;
 
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-void init_threads() {
-    gboolean is_g_thread_get_initialized = FALSE;
-    if (glib_check_version(2, 32, 0)) { // < 2.32
-        if (!glib_check_version(2, 20, 0)) {
-            is_g_thread_get_initialized = g_thread_get_initialized();
-        }
-        if (!is_g_thread_get_initialized) {
-            // Calling g_thread_init() multiple times leads to crash on GLib < 2.24
-            // We can use g_thread_get_initialized () but it is available only for
-            // GLib >= 2.20. We rely on GThreadHelper for GLib < 2.20.
-            // g_thread_init is no longer necessary for GLib >=2.32
-            g_thread_init(NULL);
-        }
-    }
-    gdk_threads_init();
-}
-#pragma GCC diagnostic pop
-
 static jboolean displayValid = JNI_FALSE;
 
 jboolean
@@ -348,31 +328,6 @@
         return JNI_VERSION_1_6;
     }
 
-    clazz = env->FindClass("sun/misc/GThreadHelper");
-    if (env->ExceptionCheck()) return JNI_ERR;
-    if (clazz) {
-        jmethodID mid_getAndSetInitializationNeededFlag = env->GetStaticMethodID(clazz, "getAndSetInitializationNeededFlag", "()Z");
-        if (env->ExceptionCheck()) return JNI_ERR;
-        jmethodID mid_lock = env->GetStaticMethodID(clazz, "lock", "()V");
-        if (env->ExceptionCheck()) return JNI_ERR;
-        jmethodID mid_unlock = env->GetStaticMethodID(clazz, "unlock", "()V");
-        if (env->ExceptionCheck()) return JNI_ERR;
-
-        env->CallStaticVoidMethod(clazz, mid_lock);
-
-        if (!env->CallStaticBooleanMethod(clazz, mid_getAndSetInitializationNeededFlag)) {
-            init_threads();
-        }
-
-        env->CallStaticVoidMethod(clazz, mid_unlock);
-    } else {
-        env->ExceptionClear();
-        init_threads();
-    }
-
-    gdk_threads_enter();
-    gtk_init(NULL, NULL);
-
     return JNI_VERSION_1_6;
 }
 
--- a/modules/graphics/src/main/native-glass/gtk/glass_general.h	Fri May 06 13:48:32 2016 -0700
+++ b/modules/graphics/src/main/native-glass/gtk/glass_general.h	Fri May 06 19:50:10 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,12 +27,13 @@
 
 #include <jni.h>
 
-
 #include <stdint.h>
 #include <X11/Xlib.h>
 #include <gdk/gdk.h>
 #include <gtk/gtk.h>
 
+#include "glass_wrapper.h"
+
 #define JLONG_TO_PTR(value) ((void*)(intptr_t)(value))
 #define PTR_TO_JLONG(value) ((jlong)(intptr_t)(value))
 
--- a/modules/graphics/src/main/native-glass/gtk/glass_gtkcompat.cpp	Fri May 06 13:48:32 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,380 +0,0 @@
-/*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-#include "glass_gtkcompat.h"
-#include "glass_general.h"
-#include <gdk/gdk.h>
-#include <gtk/gtk.h>
-
-gboolean disableGrab = FALSE;
-
-static gboolean configure_transparent_window(GtkWidget *window);
-static void configure_opaque_window(GtkWidget *window);
-static gboolean configure_window_transparency(GtkWidget *window,
-                                              gboolean transparent);
-
-#if GTK_CHECK_VERSION(3, 0, 0)
-typedef struct _DeviceGrabContext {
-    GdkWindow * window;
-    gboolean grabbed;
-} DeviceGrabContext;
-
-static void grab_mouse_device(GdkDevice *device, DeviceGrabContext *context);
-static void ungrab_mouse_device(GdkDevice *device);
-
-GdkScreen *
-glass_gdk_window_get_screen(GdkWindow * gdkWindow) {
-    GdkVisual * gdkVisual = gdk_window_get_visual(gdkWindow);
-    return gdk_visual_get_screen(gdkVisual);
-}
-
-GdkDisplay * glass_gdk_window_get_display(GdkWindow * gdkWindow) {
-    return gdk_window_get_display(gdkWindow);
-}
-
-
-gboolean
-glass_gdk_mouse_devices_grab(GdkWindow *gdkWindow) {
-    if (disableGrab) {
-        return TRUE;
-    }
-
-    DeviceGrabContext context;
-    GList *devices = gdk_device_manager_list_devices(
-                         gdk_display_get_device_manager(
-                             gdk_display_get_default()),
-                             GDK_DEVICE_TYPE_MASTER);
-
-    context.window = gdkWindow;
-    context.grabbed = FALSE;
-    g_list_foreach(devices, (GFunc) grab_mouse_device, &context);
-
-    return context.grabbed;
-}
-
-void
-glass_gdk_mouse_devices_ungrab() {
-    GList *devices = gdk_device_manager_list_devices(
-                         gdk_display_get_device_manager(
-                             gdk_display_get_default()),
-                             GDK_DEVICE_TYPE_MASTER);
-    g_list_foreach(devices, (GFunc) ungrab_mouse_device, NULL);
-}
-
-void
-glass_gdk_master_pointer_grab(GdkWindow *window, GdkCursor *cursor) {
-    if (disableGrab) {
-        gdk_window_set_cursor(window, cursor);
-        return;
-    }
-    gdk_device_grab(gdk_device_manager_get_client_pointer(
-                        gdk_display_get_device_manager(
-                            gdk_display_get_default())),
-                    window, GDK_OWNERSHIP_NONE, FALSE, GDK_ALL_EVENTS_MASK,
-                    cursor, GDK_CURRENT_TIME);
-}
-
-void
-glass_gdk_master_pointer_ungrab() {
-    gdk_device_ungrab(gdk_device_manager_get_client_pointer(
-                          gdk_display_get_device_manager(
-                              gdk_display_get_default())),
-                      GDK_CURRENT_TIME);
-}
-
-void
-glass_gdk_master_pointer_get_position(gint *x, gint *y) {
-    gdk_device_get_position(gdk_device_manager_get_client_pointer(
-                                gdk_display_get_device_manager(
-                                    gdk_display_get_default())),
-                            NULL, x, y);
-}
-
-gboolean
-glass_gdk_device_is_grabbed(GdkDevice *device) {
-    return gdk_display_device_is_grabbed(gdk_display_get_default(), device);
-}
-
-void
-glass_gdk_device_ungrab(GdkDevice *device) {
-    gdk_device_ungrab(device, GDK_CURRENT_TIME);
-}
-
-GdkWindow *
-glass_gdk_device_get_window_at_position(GdkDevice *device, gint *x, gint *y) {
-    return gdk_device_get_window_at_position(device, x, y);
-}
-
-void
-glass_gtk_configure_transparency_and_realize(GtkWidget *window,
-                                             gboolean transparent) {
-    gboolean isTransparent = configure_window_transparency(window, transparent);
-    gtk_widget_realize(window);
-    if (isTransparent) {
-        GdkRGBA rgba = { 1.0, 1.0, 1.0, 0.0 };
-        gdk_window_set_background_rgba(gtk_widget_get_window(window), &rgba);
-    }
-}
-
-void
-glass_gtk_window_configure_from_visual(GtkWidget *widget, GdkVisual *visual) {
-    gtk_widget_set_visual(widget, visual);
-}
-
-static gboolean
-configure_transparent_window(GtkWidget *window) {
-    GdkScreen *default_screen = gdk_screen_get_default();
-    GdkDisplay *default_display = gdk_display_get_default();
-    GdkVisual *visual = gdk_screen_get_rgba_visual(default_screen);
-    if (visual
-            && gdk_display_supports_composite(default_display)
-            && gdk_screen_is_composited(default_screen)) {
-        gtk_widget_set_visual(window, visual);
-        return TRUE;
-    }
-
-    return FALSE;
-}
-
-static void
-grab_mouse_device(GdkDevice *device, DeviceGrabContext *context) {
-    GdkInputSource source = gdk_device_get_source(device);
-    if (source == GDK_SOURCE_MOUSE) {
-        GdkGrabStatus status = gdk_device_grab(device,
-                                               context->window,
-                                               GDK_OWNERSHIP_NONE,
-                                               TRUE,
-                                               GDK_ALL_EVENTS_MASK,
-                                               NULL,
-                                               GDK_CURRENT_TIME);
-        if (status == GDK_GRAB_SUCCESS) {
-            context->grabbed = TRUE;
-        }
-    }
-}
-
-static void
-ungrab_mouse_device(GdkDevice *device) {
-    GdkInputSource source = gdk_device_get_source(device);
-    if (source == GDK_SOURCE_MOUSE) {
-        gdk_device_ungrab(device, GDK_CURRENT_TIME);
-    }
-}
-
-int glass_gtk_fixup_typed_key(int key, int keyval) {
-    return key;
-}
-
-void glass_gdk_window_get_size(GdkWindow *window, gint *w, gint *h) {
-    *w = gdk_window_get_width(window);
-    *h = gdk_window_get_height(window);
-}
-
-void glass_gdk_display_get_pointer(GdkDisplay* display, gint* x, gint *y) {
-    gdk_device_get_position(gdk_device_manager_get_client_pointer(gdk_display_get_device_manager(display)),
-        NULL , x, y);
-}
-
-#else /* GTK_CHECK_VERSION(3, 0, 0) */
-
-GdkScreen *
-glass_gdk_window_get_screen(GdkWindow * gdkWindow) {
-    return gdk_window_get_screen(gdkWindow);
-}
-
-GdkDisplay * glass_gdk_window_get_display(GdkWindow * gdkWindow) {
-    return gdk_window_get_display(gdkWindow);
-}
-
-gboolean
-glass_gdk_mouse_devices_grab(GdkWindow *gdkWindow) {
-    return glass_gdk_mouse_devices_grab_with_cursor(gdkWindow, NULL, TRUE);
-}
-
-gboolean
-glass_gdk_mouse_devices_grab_with_cursor(GdkWindow *gdkWindow, GdkCursor *cursor) {
-    return glass_gdk_mouse_devices_grab_with_cursor(gdkWindow, cursor, TRUE);
-}
-
-gboolean
-glass_gdk_mouse_devices_grab_with_cursor(GdkWindow *gdkWindow, GdkCursor *cursor, gboolean owner_events) {
-    if (disableGrab) {
-        return TRUE;
-    }
-    GdkGrabStatus status = gdk_pointer_grab(gdkWindow, owner_events, (GdkEventMask)
-                                            (GDK_POINTER_MOTION_MASK
-                                                | GDK_POINTER_MOTION_HINT_MASK
-                                                | GDK_BUTTON_MOTION_MASK
-                                                | GDK_BUTTON1_MOTION_MASK
-                                                | GDK_BUTTON2_MOTION_MASK
-                                                | GDK_BUTTON3_MOTION_MASK
-                                                | GDK_BUTTON_PRESS_MASK
-                                                | GDK_BUTTON_RELEASE_MASK),
-                                            NULL, cursor, GDK_CURRENT_TIME);
-
-    return (status == GDK_GRAB_SUCCESS) ? TRUE : FALSE;
-}
-
-void
-glass_gdk_mouse_devices_ungrab() {
-    gdk_pointer_ungrab(GDK_CURRENT_TIME);
-}
-
-void
-glass_gdk_master_pointer_grab(GdkWindow *window, GdkCursor *cursor) {
-    if (disableGrab) {
-        gdk_window_set_cursor(window, cursor);
-        return;
-    }
-    gdk_pointer_grab(window, FALSE, (GdkEventMask)
-                     (GDK_POINTER_MOTION_MASK
-                         | GDK_BUTTON_MOTION_MASK
-                         | GDK_BUTTON1_MOTION_MASK
-                         | GDK_BUTTON2_MOTION_MASK
-                         | GDK_BUTTON3_MOTION_MASK
-                         | GDK_BUTTON_RELEASE_MASK),
-                     NULL, cursor, GDK_CURRENT_TIME);
-}
-
-void
-glass_gdk_master_pointer_ungrab() {
-    gdk_pointer_ungrab(GDK_CURRENT_TIME);
-}
-
-void
-glass_gdk_master_pointer_get_position(gint *x, gint *y) {
-    gdk_display_get_pointer(gdk_display_get_default(), NULL, x, y, NULL);
-}
-
-gboolean
-glass_gdk_device_is_grabbed(GdkDevice *device) {
-    (void) device;
-    return gdk_display_pointer_is_grabbed(gdk_display_get_default());
-}
-
-void
-glass_gdk_device_ungrab(GdkDevice *device) {
-    (void) device;
-    gdk_pointer_ungrab(GDK_CURRENT_TIME);
-}
-
-GdkWindow *
-glass_gdk_device_get_window_at_position(GdkDevice *device, gint *x, gint *y) {
-    (void) device;
-    return gdk_display_get_window_at_pointer(gdk_display_get_default(), x, y);
-}
-
-void
-glass_gtk_configure_transparency_and_realize(GtkWidget *window,
-                                             gboolean transparent) {
-    configure_window_transparency(window, transparent);
-    gtk_widget_realize(window);
-}
-
-void
-glass_gtk_window_configure_from_visual(GtkWidget *widget, GdkVisual *visual) {
-    GdkColormap *colormap = gdk_colormap_new(visual, TRUE);
-    gtk_widget_set_colormap(widget, colormap);
-}
-
-static gboolean
-configure_transparent_window(GtkWidget *window) {
-    GdkScreen *default_screen = gdk_screen_get_default();
-    GdkDisplay *default_display = gdk_display_get_default();
-    GdkColormap *colormap = gdk_screen_get_rgba_colormap(default_screen);
-    if (colormap
-            && gdk_display_supports_composite(default_display)
-            && gdk_screen_is_composited(default_screen)) {
-        gtk_widget_set_colormap(window, colormap);
-        return TRUE;
-    }
-
-    return FALSE;
-}
-
-int glass_gtk_fixup_typed_key(int key, int keyval) {
-    if (key == 0) {
-        // Work around "bug" fixed in gtk-3.0:
-        // http://mail.gnome.org/archives/commits-list/2011-March/msg06832.html
-        switch (keyval) {
-        case 0xFF08 /* Backspace */: return '\b';
-        case 0xFF09 /* Tab       */: return '\t';
-        case 0xFF0A /* Linefeed  */: return '\n';
-        case 0xFF0B /* Vert. Tab */: return '\v';
-        case 0xFF0D /* Return    */: return '\r';
-        case 0xFF1B /* Escape    */: return '\033';
-        case 0xFFFF /* Delete    */: return '\177';
-        }
-    }
-    return key;
-}
-
-void glass_gdk_window_get_size(GdkWindow *window, gint *w, gint *h) {
-    *w = gdk_window_get_width(window);
-    *h = gdk_window_get_height(window);
-}
-
-void glass_gdk_display_get_pointer(GdkDisplay* display, gint* x, gint *y) {
-    gdk_display_get_pointer(display, NULL, x, y, NULL);
-}
-
-#endif /* GTK_CHECK_VERSION(3, 0, 0) */
-
-const guchar*
-glass_gtk_selection_data_get_data_with_length(
-        GtkSelectionData * selectionData,
-        gint * length) {
-    if (selectionData == NULL) {
-        return NULL;
-    }
-
-    *length = gtk_selection_data_get_length(selectionData);
-    return gtk_selection_data_get_data(selectionData);
-}
-
-static void
-configure_opaque_window(GtkWidget *window) {
-    (void) window;
-
-    gtk_widget_set_visual(window,
-                          gdk_screen_get_system_visual(
-                              gdk_screen_get_default()));
-}
-
-static gboolean
-configure_window_transparency(GtkWidget *window, gboolean transparent) {
-    if (transparent) {
-        if (configure_transparent_window(window)) {
-            return TRUE;
-        }
-
-        ERROR0("Can't create transparent stage, because your screen doesn't"
-               " support alpha channel."
-               " You need to enable XComposite extension.\n");
-    }
-
-    configure_opaque_window(window);
-    return FALSE;
-}
-
--- a/modules/graphics/src/main/native-glass/gtk/glass_gtkcompat.h	Fri May 06 13:48:32 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,144 +0,0 @@
-/*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-#ifndef GLASS_GTKCOMPAT_H
-#define        GLASS_GTKCOMPAT_H
-
-#include <gtk/gtk.h>
-#include <gdk/gdkx.h>
-#include <gdk/gdkkeysyms.h>
-
-#if GTK_CHECK_VERSION(2, 22, 0)
-
-#define GLASS_GDK_DRAG_CONTEXT_GET_SELECTED_ACTION(context) \
-    gdk_drag_context_get_selected_action(context)
-
-#define GLASS_GDK_DRAG_CONTEXT_GET_ACTIONS(context) \
-    gdk_drag_context_get_actions(context)
-
-#define GLASS_GDK_DRAG_CONTEXT_LIST_TARGETS(context) \
-    gdk_drag_context_list_targets(context)
-
-#define GLASS_GDK_DRAG_CONTEXT_GET_SUGGESTED_ACTION(context) \
-    gdk_drag_context_get_suggested_action(context)
-
-#else /* GTK_CHECK_VERSION(2, 22, 0) */
-
-#define GLASS_GDK_DRAG_CONTEXT_GET_SELECTED_ACTION(context) \
-    (context->action)
-
-#define GLASS_GDK_DRAG_CONTEXT_GET_ACTIONS(context) \
-    (context->actions)
-
-#define GLASS_GDK_DRAG_CONTEXT_LIST_TARGETS(context) \
-    (context->targets)
-
-#define GLASS_GDK_DRAG_CONTEXT_GET_SUGGESTED_ACTION(context) \
-    (context->suggested_action)
-
-#endif /* GTK_CHECK_VERSION(2, 22, 0) */
-
-#if GTK_CHECK_VERSION(2, 24, 0)
-
-#define GLASS_GDK_KEY_CONSTANT(key) (GDK_KEY_ ## key)
-
-#define GLASS_GDK_WINDOW_FOREIGN_NEW_FOR_DISPLAY(display, anid) \
-    gdk_x11_window_foreign_new_for_display(display, anid)
-
-#define GLASS_GDK_WINDOW_LOOKUP_FOR_DISPLAY(display, anid) \
-    gdk_x11_window_lookup_for_display(display, anid)
-
-#else /* GTK_CHECK_VERSION(2, 24, 0) */
-
-#define GLASS_GDK_KEY_CONSTANT(key) (GDK_ ## key)
-
-#define GLASS_GDK_WINDOW_FOREIGN_NEW_FOR_DISPLAY(display, anid) \
-    gdk_window_foreign_new_for_display(display, anid)
-
-#define GLASS_GDK_WINDOW_LOOKUP_FOR_DISPLAY(display, anid) \
-    gdk_window_lookup_for_display(display, anid)
-
-#endif /* GTK_CHECK_VERSION(2, 24, 0) */
-
-#if GTK_CHECK_VERSION(3, 0, 0)
-
-#define GLASS_GTK_WINDOW_SET_HAS_RESIZE_GRIP(window, value) \
-    gtk_window_set_has_resize_grip(window, TRUE)
-
-#define GLASS_GDK_SELECTION_EVENT_GET_REQUESTOR(event) \
-    (event->requestor)
-
-#define GLASS_GDK_DRAG_CONTEXT_GET_DEST_WINDOW(context) \
-    gdk_drag_context_get_dest_window(context)
-
-#else /* GTK_CHECK_VERSION(3, 0, 0) */
-
-#define GLASS_GTK_WINDOW_SET_HAS_RESIZE_GRIP(window, value) \
-    (void) window;                                          \
-    (void) value;
-
-#define GLASS_GDK_SELECTION_EVENT_GET_REQUESTOR(event) \
-    GLASS_GDK_WINDOW_FOREIGN_NEW_FOR_DISPLAY(          \
-        gdk_display_get_default(), event->requestor)
-
-#define GLASS_GDK_DRAG_CONTEXT_GET_DEST_WINDOW(context) \
-    ((context != NULL) ? gdk_drag_context_get_dest_window(context) : NULL)
-
-#endif /* GTK_CHECK_VERSION(3, 0, 0) */
-
-GdkScreen * glass_gdk_window_get_screen(GdkWindow * gdkWindow);
-GdkDisplay * glass_gdk_window_get_display(GdkWindow * gdkWindow);
-
-gboolean glass_gdk_mouse_devices_grab(GdkWindow * gdkWindow);
-gboolean glass_gdk_mouse_devices_grab_with_cursor(GdkWindow * gdkWindow, GdkCursor *cursor);
-gboolean glass_gdk_mouse_devices_grab_with_cursor(GdkWindow * gdkWindow, GdkCursor *cursor, gboolean owner_events);
-void glass_gdk_mouse_devices_ungrab();
-
-void glass_gdk_master_pointer_grab(GdkWindow *window, GdkCursor *cursor);
-void glass_gdk_master_pointer_ungrab();
-void glass_gdk_master_pointer_get_position(gint *x, gint *y);
-
-gboolean glass_gdk_device_is_grabbed(GdkDevice *device);
-void glass_gdk_device_ungrab(GdkDevice *device);
-GdkWindow *glass_gdk_device_get_window_at_position(
-               GdkDevice *device, gint *x, gint *y);
-
-void glass_gtk_configure_transparency_and_realize(GtkWidget *window,
-                                                  gboolean transparent);
-
-const guchar * glass_gtk_selection_data_get_data_with_length(
-        GtkSelectionData * selectionData,
-        gint * length);
-
-void glass_gtk_window_configure_from_visual(GtkWidget *widget, GdkVisual *visual);
-
-int glass_gtk_fixup_typed_key(int key, int keyval);
-
-void glass_gdk_window_get_size(GdkWindow *window, gint *w, gint *h);
-
-void glass_gdk_display_get_pointer(GdkDisplay* display, gint* x, gint *y);
-
-
-#endif        /* GLASS_GTKCOMPAT_H */
-
--- a/modules/graphics/src/main/native-glass/gtk/glass_key.cpp	Fri May 06 13:48:32 2016 -0700
+++ b/modules/graphics/src/main/native-glass/gtk/glass_key.cpp	Fri May 06 19:50:10 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,13 +23,14 @@
  * questions.
  */
 #include "glass_key.h"
-#include "glass_gtkcompat.h"
 #include <com_sun_glass_events_KeyEvent.h>
 #include <com_sun_glass_ui_gtk_GtkApplication.h>
 
 #include <glib.h>
 #include <gdk/gdk.h>
 #include <gtk/gtk.h>
+#include "glass_wrapper.h"
+#include <gdk/gdkkeysyms.h>
 
 static gboolean key_initialized = FALSE;
 static GHashTable *keymap;
--- a/modules/graphics/src/main/native-glass/gtk/glass_screen.cpp	Fri May 06 13:48:32 2016 -0700
+++ b/modules/graphics/src/main/native-glass/gtk/glass_screen.cpp	Fri May 06 19:50:10 2016 -0400
@@ -119,7 +119,7 @@
     jobject jScreen = env->NewObject(jScreenCls, jScreenInit,
                                      (jlong)monitor_idx,
 
-                                     (visual ? gdk_visual_get_depth(visual) : 0),
+                                     (visual ? glass_gdk_visual_get_depth(visual) : 0),
 
                                      monitor_geometry.x,
                                      monitor_geometry.y,
--- a/modules/graphics/src/main/native-glass/gtk/glass_window.cpp	Fri May 06 13:48:32 2016 -0700
+++ b/modules/graphics/src/main/native-glass/gtk/glass_window.cpp	Fri May 06 19:50:10 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,6 @@
  */
 #include "glass_window.h"
 #include "glass_general.h"
-#include "glass_gtkcompat.h"
 #include "glass_key.h"
 #include "glass_screen.h"
 #include "glass_dnd.h"
@@ -50,8 +49,6 @@
 WindowContext * WindowContextBase::sm_grab_window = NULL;
 WindowContext * WindowContextBase::sm_mouse_drag_window = NULL;
 
-GdkAtom atom_net_wm_state = gdk_atom_intern_static_string("_NET_WM_STATE");
-
 GdkWindow* WindowContextBase::get_gdk_window(){
     return gdk_window;
 }
@@ -466,7 +463,7 @@
     }
 
     cairo_t* context;
-    context = gdk_cairo_create(GDK_DRAWABLE(gdk_window));
+    context = gdk_cairo_create(gdk_window);
 
     cairo_surface_t* cairo_surface;
     cairo_surface = cairo_image_surface_create_for_data(
@@ -600,7 +597,7 @@
                     WindowContextBase::sm_mouse_drag_window->get_gdk_window(), cursor, FALSE);
         } else if (WindowContextBase::sm_grab_window) {
             glass_gdk_mouse_devices_grab_with_cursor(
-                    WindowContextBase::sm_grab_window->get_gdk_window(), cursor);
+                    WindowContextBase::sm_grab_window->get_gdk_window(), cursor, TRUE);
         }
     }
     gdk_window_set_cursor(gdk_window, cursor);
@@ -720,7 +717,7 @@
 
 void
 WindowContextTop::request_frame_extents() {
-    Display *display = GDK_WINDOW_XDISPLAY(gdk_window);
+    Display *display = GDK_DISPLAY_XDISPLAY(gdk_window_get_display(gdk_window));
     Atom rfeAtom = XInternAtom(display, "_NET_REQUEST_FRAME_EXTENTS", True);
     if (rfeAtom != None) {
         XClientMessageEvent clientMessage;
@@ -739,7 +736,7 @@
 }
 
 void WindowContextTop::activate_window() {
-    Display *display = GDK_WINDOW_XDISPLAY(gdk_window);
+    Display *display = GDK_DISPLAY_XDISPLAY (gdk_window_get_display (gdk_window));
     Atom navAtom = XInternAtom(display, "_NET_ACTIVE_WINDOW", True);
     if (navAtom != None) {
         XClientMessageEvent clientMessage;
@@ -870,6 +867,7 @@
     // Workaround for https://bugs.launchpad.net/unity/+bug/998073
 
     static GdkAtom atom_atom = gdk_atom_intern_static_string("ATOM");
+    static GdkAtom atom_net_wm_state = gdk_atom_intern_static_string("_NET_WM_STATE");
     static GdkAtom atom_net_wm_state_hidden = gdk_atom_intern_static_string("_NET_WM_STATE_HIDDEN");
     static GdkAtom atom_net_wm_state_above = gdk_atom_intern_static_string("_NET_WM_STATE_ABOVE");
 
@@ -905,6 +903,8 @@
 }
 
 void WindowContextTop::process_property_notify(GdkEventProperty* event) {
+    static GdkAtom atom_net_wm_state = gdk_atom_intern_static_string("_NET_WM_STATE");
+
     if (event->atom == atom_net_wm_state && event->window == gdk_window) {
         process_net_wm_property();
     } else if (event->atom == get_net_frame_extents_atom() &&
@@ -1028,7 +1028,7 @@
     }
 
     if (resizable.request != REQUEST_NONE) {
-        set_window_resizable(resizable.request == REQUEST_RESIZABLE, true);
+        set_window_resizable(resizable.request == REQUEST_RESIZABLE);
         resizable.request = REQUEST_NONE;
     }
 }
@@ -1051,7 +1051,7 @@
     }
 }
 
-void WindowContextTop::set_window_resizable(bool res, bool grip) {
+void WindowContextTop::set_window_resizable(bool res) {
     if(!res) {
         int w = geometry_get_content_width(&geometry);
         int h = geometry_get_content_height(&geometry);
@@ -1061,16 +1061,12 @@
         GdkGeometry geom = {w, h, w, h, 0, 0, 0, 0, 0.0, 0.0, GDK_GRAVITY_NORTH_WEST};
         gtk_window_set_geometry_hints(GTK_WINDOW(gtk_widget), NULL, &geom,
                 static_cast<GdkWindowHints>(GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE));
-        GLASS_GTK_WINDOW_SET_HAS_RESIZE_GRIP(gdk_window, FALSE);
         resizable.prev = resizable.value;
         resizable.value = false;
     } else {
         resizable.prev = resizable.value;
         resizable.value = true;
         update_window_constraints();
-        if (grip) {
-            GLASS_GTK_WINDOW_SET_HAS_RESIZE_GRIP(gdk_window, TRUE);
-        }
     }
 }
 
@@ -1078,7 +1074,7 @@
     gint w, h;
     gtk_window_get_size(GTK_WINDOW(gtk_widget), &w, &h);
     if (map_received || w > 1 || h > 1) {
-        set_window_resizable(res, true);
+        set_window_resizable(res);
     } else {
         //Since window is not ready yet set only request for change of resizable.
         resizable.request  = res ? REQUEST_RESIZABLE : REQUEST_NOT_RESIZABLE;
@@ -1168,6 +1164,8 @@
         return;
     }
 
+    Display *display = GDK_DISPLAY_XDISPLAY (gdk_window_get_display (gdk_window));
+
     if (!gtk_widget_get_visible(gtk_widget)) {
         // not visible yet, synchronize with gtk only
         if (windowChangesMask & (CWX | CWY)) {
@@ -1220,11 +1218,11 @@
             sizeHints->min_height = 1;
             sizeHints->max_width = INT_MAX;
             sizeHints->max_height = INT_MAX;
-            XSetWMNormalHints(GDK_WINDOW_XDISPLAY(gdk_window),
+            XSetWMNormalHints(display,
                     GDK_WINDOW_XID(gdk_window),
                     sizeHints);
 
-            XConfigureWindow(GDK_WINDOW_XDISPLAY(gdk_window),
+            XConfigureWindow(display,
                     GDK_WINDOW_XID(gdk_window),
                     windowChangesMask,
                     windowChanges);
@@ -1233,7 +1231,7 @@
             sizeHints->min_height = fixedHeight;
             sizeHints->max_width = fixedWidth;
             sizeHints->max_height = fixedHeight;
-            XSetWMNormalHints(GDK_WINDOW_XDISPLAY(gdk_window),
+            XSetWMNormalHints(display,
                     GDK_WINDOW_XID(gdk_window),
                     sizeHints);
 
@@ -1242,7 +1240,7 @@
         }
     }
 
-    XConfigureWindow(GDK_WINDOW_XDISPLAY(gdk_window),
+    XConfigureWindow(display,
             GDK_WINDOW_XID(gdk_window),
             windowChangesMask,
             windowChanges);
@@ -1254,20 +1252,7 @@
         return;
     }
 
-    GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data((guchar *) data,
-            GDK_COLORSPACE_RGB, TRUE, 8, width, height, width * 4, NULL, NULL);
-
-    if (GDK_IS_PIXBUF(pixbuf)) {
-        GdkBitmap* mask = NULL;
-        gdk_pixbuf_render_pixmap_and_mask(pixbuf, NULL, &mask, 128);
-
-        gdk_window_input_shape_combine_mask(gdk_window, mask, 0, 0);
-
-        g_object_unref(pixbuf);
-        if (mask) {
-            g_object_unref(mask);
-        }
-    }
+    glass_window_apply_shape_mask(gtk_widget_get_window(gtk_widget), data, width, height);
 }
 
 void WindowContextTop::set_minimized(bool minimize) {
@@ -1275,7 +1260,7 @@
     if (minimize) {
         if (frame_type == TRANSPARENT) {
             // https://bugs.launchpad.net/ubuntu/+source/unity/+bug/1245571
-            gdk_window_input_shape_combine_mask(gdk_window, NULL, 0, 0);
+            glass_window_reset_input_shape_mask(gtk_widget_get_window(gtk_widget));
         }
 
         if ((gdk_windowManagerFunctions & GDK_FUNC_MINIMIZE) == 0) {
@@ -1326,10 +1311,10 @@
 void WindowContextTop::set_enabled(bool enabled) {
     if (enabled) {
         //set back proper resizable value.
-        set_window_resizable(resizable.prev, true);
+        set_window_resizable(resizable.prev);
     } else {
         //disabled window can't be resizable.
-        set_window_resizable(false, false);
+        set_window_resizable(false);
     }
 }
 
--- a/modules/graphics/src/main/native-glass/gtk/glass_window.h	Fri May 06 13:48:32 2016 -0700
+++ b/modules/graphics/src/main/native-glass/gtk/glass_window.h	Fri May 06 19:50:10 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -427,7 +427,7 @@
     void initialize_frame_extents();
     void window_configure(XWindowChanges *, unsigned int);
     void update_window_constraints();
-    void set_window_resizable(bool, bool);
+    void set_window_resizable(bool);
     void update_ontop_tree(bool);
     bool on_top_inherited();
     bool effective_on_top();
--- a/modules/graphics/src/main/native-glass/gtk/glass_window_ime.cpp	Fri May 06 13:48:32 2016 -0700
+++ b/modules/graphics/src/main/native-glass/gtk/glass_window_ime.cpp	Fri May 06 19:50:10 2016 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,6 @@
 #include "com_sun_glass_ui_View.h"
 #include "glass_window.h"
 #include "glass_general.h"
-#include "glass_gtkcompat.h"
 
 #include <cstring>
 #include <cstdlib>
@@ -41,7 +40,7 @@
 
     result.type = (event->type == GDK_KEY_PRESS) ? KeyPress : KeyRelease;
     result.send_event = event->send_event;
-    result.display = gdk_x11_display_get_xdisplay(glass_gdk_window_get_display(event->window));
+    result.display = gdk_x11_display_get_xdisplay(gdk_window_get_display(event->window));
     result.window = result.subwindow = GDK_WINDOW_XID(event->window);
     result.root = GDK_WINDOW_XID(gdk_screen_get_root_window(glass_gdk_window_get_screen(event->window)));
     result.time = event->time;
@@ -222,7 +221,7 @@
 }
 
 void WindowContextBase::enableOrResetIME() {
-    Display *display = gdk_x11_display_get_xdisplay(glass_gdk_window_get_display(gdk_window));
+    Display *display = gdk_x11_display_get_xdisplay(gdk_window_get_display(gdk_window));
     if (xim.im == NULL || xim.ic == NULL) {
         xim.im = XOpenIM(display, NULL, NULL, NULL);
         if (xim.im == NULL) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/native-glass/gtk/glass_wrapper.h	Fri May 06 19:50:10 2016 -0400
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef __GTK_WRAPPER_H__
+#define __GTK_WRAPPER_H__
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GLASS_GDK_KEY_CONSTANT(key) (GDK_KEY_ ## key)
+
+extern int wrapper_load_symbols(int version, int debug);
+extern int wrapper_load_symbols_gtk(int version, void *handle);
+extern int wrapper_load_symbols_gdk(int version, void *handle);
+extern int wrapper_load_symbols_pix(int version, void * handle);
+
+extern int wrapper_debug;
+extern int wrapper_loaded;
+extern int wrapper_gtk_version; // 2 or 3
+extern int wrapper_gtk_versionDebug;
+
+GtkWidget *
+glass_file_chooser_dialog (
+                           const gchar * title,
+                           GtkWindow * parent,
+                           GtkFileChooserAction action,
+                           const gchar * action_text
+                           );
+
+void
+glass_widget_set_visual (GtkWidget *widget, GdkVisual *visual);
+
+gboolean
+glass_gdk_pixbuf_save_to_buffer (GdkPixbuf * pixbuf,
+                    gchar ** buffer,
+                    gsize * buffer_size,
+                    const char *type, GError ** error);
+
+gint
+glass_gdk_visual_get_depth (GdkVisual * visual);
+
+GdkScreen *
+glass_gdk_window_get_screen(GdkWindow * gdkWindow);
+
+gboolean
+glass_gdk_mouse_devices_grab(GdkWindow * gdkWindow);
+
+gboolean
+glass_gdk_mouse_devices_grab_with_cursor(GdkWindow * gdkWindow, GdkCursor *cursor, gboolean owner_events);
+
+void
+glass_gdk_mouse_devices_ungrab();
+
+void
+glass_gdk_master_pointer_grab(GdkWindow *window, GdkCursor *cursor);
+
+void
+glass_gdk_master_pointer_ungrab();
+
+void
+glass_gdk_master_pointer_get_position(gint *x, gint *y);
+
+gboolean
+glass_gdk_device_is_grabbed(GdkDevice *device);
+
+void
+glass_gdk_device_ungrab(GdkDevice *device);
+
+GdkWindow *
+glass_gdk_device_get_window_at_position(
+               GdkDevice *device, gint *x, gint *y);
+
+void
+glass_gtk_configure_transparency_and_realize(GtkWidget *window,
+                                                  gboolean transparent);
+
+const guchar *
+glass_gtk_selection_data_get_data_with_length(
+        GtkSelectionData * selectionData,
+        gint * length);
+
+void
+glass_gtk_window_configure_from_visual(GtkWidget *widget, GdkVisual *visual);
+
+int
+glass_gtk_fixup_typed_key(int key, int keyval);
+
+void
+glass_gdk_window_get_size(GdkWindow *window, gint *w, gint *h);
+
+void
+glass_gdk_display_get_pointer(GdkDisplay* display, gint* x, gint *y);
+
+gboolean
+glass_configure_window_transparency(GtkWidget *window, gboolean transparent);
+
+GdkPixbuf *
+glass_pixbuf_from_window(GdkWindow *window,
+    gint srcx, gint srcy,
+    gint width, gint height);
+
+void
+glass_window_apply_shape_mask(GdkWindow *window,
+    void* data, uint width, uint height);
+
+void
+glass_window_reset_input_shape_mask(GdkWindow *window);
+
+GdkWindow *
+glass_gdk_drag_context_get_dest_window (GdkDragContext * context);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __GTK_WRAPPER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/native-glass/gtk/wrapper_gdk.c	Fri May 06 19:50:10 2016 -0400
@@ -0,0 +1,1700 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <linux/fb.h>
+#include <fcntl.h>
+#ifndef __USE_GNU       // required for dladdr() & Dl_info
+#define __USE_GNU
+#endif
+#include <dlfcn.h>
+#include <sys/ioctl.h>
+
+#include <string.h>
+#include <strings.h>
+
+#include <assert.h>
+
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+
+#include "glass_wrapper.h"
+
+static GdkAtom (*_gdk_atom_intern) (const gchar * atom_name,
+                    gboolean only_if_exists);
+static GdkAtom (*_gdk_atom_intern_static_string) (const gchar * atom_name);
+static gchar *(*_gdk_atom_name) (GdkAtom atom);
+static cairo_t *(*_gdk_cairo_create) (GdkDrawable * drawable);
+static GdkColormap *(*_gdk_colormap_new) (GdkVisual * visual,
+                      gboolean allocate);
+static GdkCursor *(*_gdk_cursor_new) (GdkCursorType cursor_type);
+static GdkCursor *(*_gdk_cursor_new_from_name) (GdkDisplay * display,
+                        const gchar * name);
+static GdkCursor *(*_gdk_cursor_new_from_pixbuf) (GdkDisplay * display,
+                          GdkPixbuf * pixbuf,
+                          gint x, gint y);
+static GdkDisplay *(*_gdk_display_get_default) (void);
+static guint (*_gdk_display_get_default_cursor_size) (GdkDisplay * display);
+static void (*_gdk_display_get_pointer) (GdkDisplay * display,
+                     GdkScreen ** screen,
+                     gint * x,
+                     gint * y, GdkModifierType * mask);
+static GdkWindow *(*_gdk_display_get_window_at_pointer) (GdkDisplay * display,
+                             gint * win_x,
+                             gint * win_y);
+static gboolean (*_gdk_display_pointer_is_grabbed) (GdkDisplay * display);
+static gboolean (*_gdk_display_supports_composite) (GdkDisplay * display);
+static void (*_gdk_drag_abort) (GdkDragContext * context, guint32 time_);
+static gboolean (*_gdk_drag_motion) (GdkDragContext * context,
+                     GdkWindow * dest_window,
+                     GdkDragProtocol protocol,
+                     gint x_root,
+                     gint y_root,
+                     GdkDragAction suggested_action,
+                     GdkDragAction possible_actions,
+                     guint32 time_);
+static void (*_gdk_drag_drop) (GdkDragContext * context, guint32 time_);
+static GdkDragContext *(*_gdk_drag_begin) (GdkWindow * window,
+                       GList * targets);
+static GdkDragAction (*_gdk_drag_context_get_actions) (GdkDragContext *
+                               context);
+static GdkDragAction (*_gdk_drag_context_get_selected_action) (GdkDragContext
+                                   * context);
+static GdkDragAction (*_gdk_drag_context_get_suggested_action) (GdkDragContext
+                                * context);
+static GList *(*_gdk_drag_context_list_targets) (GdkDragContext * context);
+static void (*_gdk_drag_find_window_for_screen) (GdkDragContext * context,
+                         GdkWindow * drag_window,
+                         GdkScreen * screen,
+                         gint x_root,
+                         gint y_root,
+                         GdkWindow ** dest_window,
+                         GdkDragProtocol * protocol);
+static GdkAtom (*_gdk_drag_get_selection) (GdkDragContext * context);
+static GdkWindow *(*_gdk_drag_context_get_dest_window) (GdkDragContext *
+                            context);
+static void (*_gdk_drag_status) (GdkDragContext * context,
+                 GdkDragAction action, guint32 time_);
+static void (*_gdk_drop_reply) (GdkDragContext * context, gboolean ok,
+                guint32 time_);
+static void (*_gdk_drop_finish) (GdkDragContext * context, gboolean success,
+                 guint32 time_);
+static GdkScreen *(*_gdk_window_get_screen) (GdkWindow * window);
+static GdkDisplay *(*_gdk_window_get_display) (GdkWindow * window);
+static int (*_gdk_window_get_width) (GdkWindow * window);
+static int (*_gdk_window_get_height) (GdkWindow * window);
+static void (*_gdk_error_trap_push) (void);
+static void (*_gdk_event_request_motions) (const GdkEventMotion * event);
+static void (*_gdk_event_handler_set) (GdkEventFunc func,
+                       gpointer data, GDestroyNotify notify);
+static GdkWindow *(*_gdk_get_default_root_window) (void);
+static GdkKeymap *(*_gdk_keymap_get_default) (void);
+static gboolean (*_gdk_keymap_get_entries_for_keyval) (GdkKeymap * keymap,
+                               guint keyval,
+                               GdkKeymapKey ** keys,
+                               gint * n_keys);
+static guint (*_gdk_keymap_lookup_key) (GdkKeymap * keymap,
+                    const GdkKeymapKey * key);
+static gboolean (*_gdk_keymap_translate_keyboard_state) (GdkKeymap * keymap,
+                             guint
+                             hardware_keycode,
+                             GdkModifierType
+                             state, gint group,
+                             guint * keyval,
+                             gint *
+                             effective_group,
+                             gint * level,
+                             GdkModifierType *
+                             consumed_modifiers);
+static guint32 (*_gdk_keyval_to_unicode) (guint keyval) G_GNUC_CONST;
+static GdkPixbuf *(*_gdk_pixbuf_get_from_drawable) (GdkPixbuf * dest,
+                            GdkDrawable * src,
+                            GdkColormap * cmap,
+                            int src_x,
+                            int src_y,
+                            int dest_x,
+                            int dest_y,
+                            int width, int height);
+static void (*_gdk_pixbuf_render_pixmap_and_mask) (GdkPixbuf * pixbuf,
+                           GdkPixmap ** pixmap_return,
+                           GdkBitmap ** mask_return,
+                           int alpha_threshold);
+static void (*_gdk_pixbuf_render_pixmap_and_mask_for_colormap) (GdkPixbuf *
+                                pixbuf,
+                                GdkColormap *
+                                colormap,
+                                GdkPixmap **
+                                pixmap_return,
+                                GdkBitmap **
+                                mask_return,
+                                int
+                                alpha_threshold);
+static GdkGrabStatus (*_gdk_pointer_grab) (GdkWindow * window,
+                       gboolean owner_events,
+                       GdkEventMask event_mask,
+                       GdkWindow * confine_to,
+                       GdkCursor * cursor, guint32 time_);
+static void (*_gdk_pointer_ungrab) (guint32 time_);
+static void (*_gdk_property_change) (GdkWindow * window,
+                     GdkAtom property,
+                     GdkAtom type,
+                     gint format,
+                     GdkPropMode mode,
+                     const guchar * data, gint nelements);
+static gboolean (*_gdk_property_get) (GdkWindow * window,
+                      GdkAtom property,
+                      GdkAtom type,
+                      gulong offset,
+                      gulong length,
+                      gint pdelete,
+                      GdkAtom * actual_property_type,
+                      gint * actual_format,
+                      gint * actual_length, guchar ** data);
+static gboolean (*_gdk_rectangle_intersect) (const GdkRectangle * src1,
+                         const GdkRectangle * src2,
+                         GdkRectangle * dest);
+static void (*_gdk_region_destroy) (GdkRegion * region);
+static GdkRegion *(*_gdk_region_new) (void);
+static GdkScreen *(*_gdk_screen_get_default) (void);
+static gint (*_gdk_screen_get_height) (GdkScreen * screen);
+static gint (*_gdk_screen_get_monitor_at_point) (GdkScreen * screen,
+                         gint x, gint y);
+static void (*_gdk_screen_get_monitor_geometry) (GdkScreen * screen,
+                         gint monitor_num,
+                         GdkRectangle * dest);
+static gint (*_gdk_screen_get_n_monitors) (GdkScreen * screen);
+static gdouble (*_gdk_screen_get_resolution) (GdkScreen * screen);
+static GdkColormap *(*_gdk_screen_get_rgba_colormap) (GdkScreen * screen);
+static GdkColormap *(*_gdk_screen_get_rgb_colormap) (GdkScreen * screen);
+static GdkWindow *(*_gdk_screen_get_root_window) (GdkScreen * screen);
+static GdkVisual *(*_gdk_screen_get_system_visual) (GdkScreen * screen);
+static gint (*_gdk_screen_get_width) (GdkScreen * screen);
+static gboolean (*_gdk_screen_is_composited) (GdkScreen * screen);
+static void (*_gdk_selection_convert) (GdkWindow * requestor,
+                       GdkAtom selection,
+                       GdkAtom target, guint32 time_);
+static gboolean (*_gdk_selection_owner_set) (GdkWindow * owner,
+                         GdkAtom selection,
+                         guint32 time_,
+                         gboolean send_event);
+static gint (*_gdk_selection_property_get) (GdkWindow * requestor,
+                        guchar ** data,
+                        GdkAtom * prop_type,
+                        gint * prop_format);
+static void (*_gdk_selection_send_notify) (GdkNativeWindow requestor,
+                       GdkAtom selection,
+                       GdkAtom target,
+                       GdkAtom property, guint32 time_);
+static guint (*_gdk_unicode_to_keyval) (guint32 wc) G_GNUC_CONST;
+static guint (*_gdk_threads_add_idle_full) (gint priority,
+                        GSourceFunc function,
+                        gpointer data,
+                        GDestroyNotify notify);
+static guint (*_gdk_threads_add_idle) (GSourceFunc function, gpointer data);
+static guint (*_gdk_threads_add_timeout_full) (gint priority,
+                           guint interval,
+                           GSourceFunc function,
+                           gpointer data,
+                           GDestroyNotify notify);
+static void (*_gdk_threads_enter) (void);
+static void (*_gdk_threads_init) (void);
+static void (*_gdk_threads_leave) (void);
+static void (*_gdk_window_destroy) (GdkWindow * window);
+static GdkCursor *(*_gdk_window_get_cursor) (GdkWindow * window);
+static GdkEventMask (*_gdk_window_get_events) (GdkWindow * window);
+static void (*_gdk_window_get_geometry) (GdkWindow * window,
+                     gint * x,
+                     gint * y,
+                     gint * width,
+                     gint * height, gint * depth);
+static gint (*_gdk_window_get_origin) (GdkWindow * window,
+                       gint * x, gint * y);
+static void (*_gdk_window_input_shape_combine_mask) (GdkWindow * window,
+                             GdkBitmap * mask,
+                             gint x, gint y);
+static void (*_gdk_window_shape_combine_region) (GdkWindow *window,
+                     const cairo_region_t *shape_region,
+                      gint offset_x,
+                      gint offset_y);
+static void (*_gdk_window_input_shape_combine_region) (GdkWindow * window,
+                               const cairo_region_t * shape_region,
+                               gint offset_x,
+                               gint offset_y);
+static gboolean (*_gdk_window_is_destroyed) (GdkWindow * window);
+static void (*_gdk_window_move) (GdkWindow * window, gint x, gint y);
+static GdkWindow *(*_gdk_window_new) (GdkWindow * parent,
+                      GdkWindowAttr * attributes,
+                      gint attributes_mask);
+static void (*_gdk_window_register_dnd) (GdkWindow * window);
+static void (*_gdk_window_resize) (GdkWindow * window,
+                   gint width, gint height);
+static void (*_gdk_window_restack) (GdkWindow * window,
+                    GdkWindow * sibling, gboolean above);
+static void (*_gdk_window_set_cursor) (GdkWindow * window,
+                       GdkCursor * cursor);
+static void (*_gdk_window_set_events) (GdkWindow * window,
+                       GdkEventMask event_mask);
+static void (*_gdk_window_set_functions) (GdkWindow * window,
+                      GdkWMFunction functions);
+static void (*_gdk_window_show) (GdkWindow * window);
+static Display *(*_gdk_x11_display_get_xdisplay) (GdkDisplay * display);
+static XID (*_gdk_x11_drawable_get_xid) (GdkDrawable * drawable);
+static gint (*_gdk_x11_get_default_screen) (void);
+static Display *(*_gdk_x11_get_default_xdisplay) (void);
+static guint32 (*_gdk_x11_get_server_time) (GdkWindow * window);
+static GdkVisual *(*_gdk_x11_screen_lookup_visual) (GdkScreen * screen,
+                            VisualID xvisualid);
+static GdkWindow *(*_gdk_x11_window_foreign_new_for_display) (GdkDisplay *
+                                  display,
+                                  Window window);
+static GdkWindow *(*_gdk_x11_window_lookup_for_display) (GdkDisplay * display,
+                             Window window);
+static gint (*_gdk_visual_get_depth) (GdkVisual * visual);
+
+static GType (*_gdk_window_object_get_type) (void);
+
+//----------- GTK 3.0 ------------------------------------------------------
+
+typedef struct _GdkDeviceManager      GdkDeviceManager;
+struct _GdkRGBA
+{
+  gdouble red;
+  gdouble green;
+  gdouble blue;
+  gdouble alpha;
+};
+typedef struct _GdkRGBA               GdkRGBA;
+
+typedef enum {
+  GDK_DEVICE_TYPE_MASTER,
+  GDK_DEVICE_TYPE_SLAVE,
+  GDK_DEVICE_TYPE_FLOATING
+} GdkDeviceType;
+
+typedef enum
+{
+  GDK_OWNERSHIP_NONE,
+  GDK_OWNERSHIP_WINDOW,
+  GDK_OWNERSHIP_APPLICATION
+} GdkGrabOwnership;
+
+
+static GdkVisual *   (*_gdk_window_get_visual) (GdkWindow     *window);
+static GdkScreen    *(*_gdk_visual_get_screen) (GdkVisual *visual);
+static GList * (*_gdk_device_manager_list_devices) (GdkDeviceManager *device_manager,
+                                 GdkDeviceType type);
+static GdkDeviceManager * (*_gdk_display_get_device_manager) (GdkDisplay *display);
+static GdkVisual *  (*_gdk_screen_get_rgba_visual) (GdkScreen   *screen);
+static GdkInputSource (*_gdk_device_get_source) (GdkDevice      *device);
+static GdkGrabStatus (*_gdk_device_grab) (GdkDevice        *device,
+                                      GdkWindow        *window,
+                                      GdkGrabOwnership  grab_ownership,
+                                      gboolean          owner_events,
+                                      GdkEventMask      event_mask,
+                                      GdkCursor        *cursor,
+                                      guint32           time_);
+static void (*_gdk_device_ungrab) (GdkDevice *device, guint32 time_);
+static GdkDevice * (*_gdk_device_manager_get_client_pointer) (GdkDeviceManager *device_manager);
+static void  (*_gdk_device_get_position) (GdkDevice         *device,
+                                  GdkScreen        **screen,
+                                  gint              *x,
+                                  gint              *y);
+static gboolean    (*_gdk_display_device_is_grabbed) (GdkDisplay  *display,
+                                            GdkDevice   *device);
+static GdkWindow * (*_gdk_device_get_window_at_position) (GdkDevice         *device,
+                                  gint              *win_x,
+                                  gint              *win_y);
+static void (*_gdk_window_set_background) (GdkWindow      *window,
+                      const GdkColor  *color);
+static void (*_gdk_window_set_background_rgba) (GdkWindow     *window,
+                                              const GdkRGBA *rgba);
+static Window   (*_gdk_x11_window_get_xid) (GdkWindow   *window);
+
+static GdkPixbuf *(*_gdk_pixbuf_get_from_window) (GdkWindow       *window,
+                                        gint             src_x,
+                                        gint             src_y,
+                                        gint             width,
+                                        gint             height);
+
+static GType (*_gdk_window_get_type) (void);
+
+static cairo_region_t * (*_gdk_cairo_region_create_from_surface) (cairo_surface_t *surface);
+
+/***** Utilities ***********************************************************/
+
+
+#define PRELOAD_SYMBOL_GDK(x) \
+    _##x = dlsym(libgdk, #x); \
+    if (_##x == NULL) { \
+        symbol_load_errors++; \
+        fprintf(stderr,"failed loading %s\n", #x); \
+    }
+
+int wrapper_load_symbols_gdk (int version, void * libgdk)
+{
+    int symbol_load_errors = 0;
+
+    PRELOAD_SYMBOL_GDK (gdk_atom_intern);
+    PRELOAD_SYMBOL_GDK (gdk_atom_intern_static_string);
+    PRELOAD_SYMBOL_GDK (gdk_atom_name);
+    PRELOAD_SYMBOL_GDK (gdk_cairo_create);
+    PRELOAD_SYMBOL_GDK (gdk_cursor_new);
+    PRELOAD_SYMBOL_GDK (gdk_cursor_new_from_name);
+    PRELOAD_SYMBOL_GDK (gdk_cursor_new_from_pixbuf);
+    PRELOAD_SYMBOL_GDK (gdk_display_get_default);
+    PRELOAD_SYMBOL_GDK (gdk_display_get_default_cursor_size);
+    PRELOAD_SYMBOL_GDK (gdk_display_get_pointer);
+    PRELOAD_SYMBOL_GDK (gdk_display_get_window_at_pointer);
+    PRELOAD_SYMBOL_GDK (gdk_display_pointer_is_grabbed);
+    PRELOAD_SYMBOL_GDK (gdk_display_supports_composite);
+    PRELOAD_SYMBOL_GDK (gdk_drag_abort);
+    PRELOAD_SYMBOL_GDK (gdk_drag_motion);
+    PRELOAD_SYMBOL_GDK (gdk_drag_drop);
+    PRELOAD_SYMBOL_GDK (gdk_drag_begin);
+    PRELOAD_SYMBOL_GDK (gdk_drag_context_get_actions);
+    PRELOAD_SYMBOL_GDK (gdk_drag_context_get_selected_action);
+    PRELOAD_SYMBOL_GDK (gdk_drag_context_get_suggested_action);
+    PRELOAD_SYMBOL_GDK (gdk_drag_context_list_targets);
+    PRELOAD_SYMBOL_GDK (gdk_drag_find_window_for_screen);
+    PRELOAD_SYMBOL_GDK (gdk_drag_get_selection);
+    PRELOAD_SYMBOL_GDK (gdk_drag_context_get_dest_window);
+    PRELOAD_SYMBOL_GDK (gdk_drag_status);
+    PRELOAD_SYMBOL_GDK (gdk_drop_reply);
+    PRELOAD_SYMBOL_GDK (gdk_drop_finish);
+    PRELOAD_SYMBOL_GDK (gdk_error_trap_push);
+    PRELOAD_SYMBOL_GDK (gdk_event_request_motions);
+    PRELOAD_SYMBOL_GDK (gdk_event_handler_set);
+    PRELOAD_SYMBOL_GDK (gdk_get_default_root_window);
+    PRELOAD_SYMBOL_GDK (gdk_keymap_get_default);
+    PRELOAD_SYMBOL_GDK (gdk_keymap_get_entries_for_keyval);
+    PRELOAD_SYMBOL_GDK (gdk_keymap_lookup_key);
+    PRELOAD_SYMBOL_GDK (gdk_keymap_translate_keyboard_state);
+    PRELOAD_SYMBOL_GDK (gdk_keyval_to_unicode);
+    PRELOAD_SYMBOL_GDK (gdk_pointer_grab);
+    PRELOAD_SYMBOL_GDK (gdk_pointer_ungrab);
+    PRELOAD_SYMBOL_GDK (gdk_property_change);
+    PRELOAD_SYMBOL_GDK (gdk_property_get);
+    PRELOAD_SYMBOL_GDK (gdk_rectangle_intersect);
+    PRELOAD_SYMBOL_GDK (gdk_screen_get_default);
+    PRELOAD_SYMBOL_GDK (gdk_screen_get_height);
+    PRELOAD_SYMBOL_GDK (gdk_screen_get_monitor_at_point);
+    PRELOAD_SYMBOL_GDK (gdk_screen_get_monitor_geometry);
+    PRELOAD_SYMBOL_GDK (gdk_screen_get_n_monitors);
+    PRELOAD_SYMBOL_GDK (gdk_screen_get_resolution);
+    PRELOAD_SYMBOL_GDK (gdk_screen_get_root_window);
+    PRELOAD_SYMBOL_GDK (gdk_screen_get_system_visual);
+    PRELOAD_SYMBOL_GDK (gdk_screen_get_width);
+    PRELOAD_SYMBOL_GDK (gdk_screen_is_composited);
+    PRELOAD_SYMBOL_GDK (gdk_selection_convert);
+    PRELOAD_SYMBOL_GDK (gdk_selection_owner_set);
+    PRELOAD_SYMBOL_GDK (gdk_selection_property_get);
+    PRELOAD_SYMBOL_GDK (gdk_selection_send_notify);
+    PRELOAD_SYMBOL_GDK (gdk_unicode_to_keyval);
+    PRELOAD_SYMBOL_GDK (gdk_threads_add_idle_full);
+    PRELOAD_SYMBOL_GDK (gdk_threads_add_idle);
+    PRELOAD_SYMBOL_GDK (gdk_threads_add_timeout_full);
+    PRELOAD_SYMBOL_GDK (gdk_threads_enter);
+    PRELOAD_SYMBOL_GDK (gdk_threads_init);
+    PRELOAD_SYMBOL_GDK (gdk_threads_leave);
+    PRELOAD_SYMBOL_GDK (gdk_window_destroy);
+    PRELOAD_SYMBOL_GDK (gdk_window_get_cursor);
+    PRELOAD_SYMBOL_GDK (gdk_window_get_events);
+    PRELOAD_SYMBOL_GDK (gdk_window_get_geometry);
+    PRELOAD_SYMBOL_GDK (gdk_window_get_origin);
+    PRELOAD_SYMBOL_GDK (gdk_window_is_destroyed);
+    PRELOAD_SYMBOL_GDK (gdk_window_move);
+    PRELOAD_SYMBOL_GDK (gdk_window_new);
+    PRELOAD_SYMBOL_GDK (gdk_window_register_dnd);
+    PRELOAD_SYMBOL_GDK (gdk_window_resize);
+    PRELOAD_SYMBOL_GDK (gdk_window_restack);
+    PRELOAD_SYMBOL_GDK (gdk_window_set_cursor);
+    PRELOAD_SYMBOL_GDK (gdk_window_set_events);
+    PRELOAD_SYMBOL_GDK (gdk_window_set_functions);
+    PRELOAD_SYMBOL_GDK (gdk_window_show);
+    PRELOAD_SYMBOL_GDK (gdk_x11_display_get_xdisplay);
+    PRELOAD_SYMBOL_GDK (gdk_x11_get_default_screen);
+    PRELOAD_SYMBOL_GDK (gdk_x11_get_default_xdisplay);
+    PRELOAD_SYMBOL_GDK (gdk_x11_get_server_time);
+    PRELOAD_SYMBOL_GDK (gdk_x11_screen_lookup_visual);
+    PRELOAD_SYMBOL_GDK (gdk_x11_window_foreign_new_for_display);
+    PRELOAD_SYMBOL_GDK (gdk_x11_window_lookup_for_display);
+    PRELOAD_SYMBOL_GDK (gdk_window_get_display);
+    PRELOAD_SYMBOL_GDK (gdk_window_get_height);
+    PRELOAD_SYMBOL_GDK (gdk_window_get_width);
+    PRELOAD_SYMBOL_GDK (gdk_window_get_screen);
+    PRELOAD_SYMBOL_GDK (gdk_visual_get_screen); // 2.2
+
+    if (version == 2) {
+        PRELOAD_SYMBOL_GDK (gdk_colormap_new);
+        PRELOAD_SYMBOL_GDK (gdk_pixbuf_get_from_drawable);
+        PRELOAD_SYMBOL_GDK (gdk_pixbuf_render_pixmap_and_mask);
+        PRELOAD_SYMBOL_GDK (gdk_pixbuf_render_pixmap_and_mask_for_colormap);
+        PRELOAD_SYMBOL_GDK (gdk_region_destroy);
+        PRELOAD_SYMBOL_GDK (gdk_region_new);
+        PRELOAD_SYMBOL_GDK (gdk_screen_get_rgba_colormap);
+        PRELOAD_SYMBOL_GDK (gdk_screen_get_rgb_colormap);
+        PRELOAD_SYMBOL_GDK (gdk_window_input_shape_combine_mask);
+        PRELOAD_SYMBOL_GDK (gdk_x11_drawable_get_xid);
+        PRELOAD_SYMBOL_GDK (gdk_window_object_get_type);
+        PRELOAD_SYMBOL_GDK (gdk_visual_get_depth);
+    }
+
+    if (version == 3) {
+        // gtk version 3 unique symbols
+        PRELOAD_SYMBOL_GDK (gdk_window_get_visual);  // both
+        PRELOAD_SYMBOL_GDK (gdk_device_manager_list_devices); //both
+        PRELOAD_SYMBOL_GDK (gdk_display_get_device_manager);
+        PRELOAD_SYMBOL_GDK (gdk_screen_get_rgba_visual);
+        PRELOAD_SYMBOL_GDK (gdk_device_get_source); // both
+        PRELOAD_SYMBOL_GDK (gdk_device_grab);
+        PRELOAD_SYMBOL_GDK (gdk_device_ungrab);
+        PRELOAD_SYMBOL_GDK (gdk_device_manager_get_client_pointer)
+        PRELOAD_SYMBOL_GDK (gdk_device_get_position)
+        PRELOAD_SYMBOL_GDK (gdk_display_device_is_grabbed)
+        PRELOAD_SYMBOL_GDK (gdk_device_get_window_at_position)
+        PRELOAD_SYMBOL_GDK (gdk_window_set_background_rgba)
+        PRELOAD_SYMBOL_GDK (gdk_x11_window_get_xid);
+        PRELOAD_SYMBOL_GDK (gdk_pixbuf_get_from_window);
+        PRELOAD_SYMBOL_GDK (gdk_window_get_type);
+        PRELOAD_SYMBOL_GDK (gdk_cairo_region_create_from_surface);
+        PRELOAD_SYMBOL_GDK (gdk_window_shape_combine_region);
+        PRELOAD_SYMBOL_GDK (gdk_window_input_shape_combine_region);
+    }
+
+    if (symbol_load_errors && wrapper_debug) {
+        fprintf (stderr, "failed to load %d gdk symbols", symbol_load_errors);
+    }
+
+    return symbol_load_errors;
+
+}
+
+#define CHECK_LOAD_SYMBOL_GDK(x) \
+    { \
+        if (!_##x) { \
+            if (wrapper_debug) fprintf(stderr,"missing %s\n", #x); \
+            assert(_##x); \
+        } else { \
+            if (wrapper_debug) { \
+               fprintf(stderr,"using %s\n", #x); \
+               fflush(stderr); \
+            } \
+        } \
+    }
+
+
+GdkAtom gdk_atom_intern (const gchar * atom_name, gboolean only_if_exists)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_atom_intern);
+    return (*_gdk_atom_intern) (atom_name, only_if_exists);
+}
+
+GdkAtom gdk_atom_intern_static_string (const gchar * atom_name)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_atom_intern_static_string);
+    return (*_gdk_atom_intern_static_string) (atom_name);
+}
+
+gchar *gdk_atom_name (GdkAtom atom)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_atom_name);
+    return (*_gdk_atom_name) (atom);
+}
+
+cairo_t *gdk_cairo_create (GdkDrawable * drawable)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_cairo_create);
+    return (*_gdk_cairo_create) (drawable);
+}
+
+GdkColormap *gdk_colormap_new (GdkVisual * visual, gboolean allocate)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_colormap_new);
+    return (*_gdk_colormap_new) (visual, allocate);
+}
+
+GdkCursor *gdk_cursor_new (GdkCursorType cursor_type)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_cursor_new);
+    return (*_gdk_cursor_new) (cursor_type);
+}
+
+GdkCursor *gdk_cursor_new_from_name (GdkDisplay * display, const gchar * name)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_cursor_new_from_name);
+    return (*_gdk_cursor_new_from_name) (display, name);
+}
+
+GdkCursor *gdk_cursor_new_from_pixbuf (GdkDisplay * display,
+                       GdkPixbuf * pixbuf, gint x, gint y)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_cursor_new_from_pixbuf);
+    return (*_gdk_cursor_new_from_pixbuf) (display, pixbuf, x, y);
+}
+
+GdkDisplay *gdk_display_get_default (void)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_display_get_default);
+    return (*_gdk_display_get_default) ();
+}
+
+guint gdk_display_get_default_cursor_size (GdkDisplay * display)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_display_get_default_cursor_size);
+    return (*_gdk_display_get_default_cursor_size) (display);
+}
+
+void gdk_display_get_pointer (GdkDisplay * display,
+                  GdkScreen ** screen,
+                  gint * x, gint * y, GdkModifierType * mask)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_display_get_pointer);
+    (*_gdk_display_get_pointer) (display, screen, x, y, mask);
+}
+
+GdkWindow *gdk_display_get_window_at_pointer (GdkDisplay * display,
+                          gint * win_x, gint * win_y)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_display_get_window_at_pointer);
+    return (*_gdk_display_get_window_at_pointer) (display, win_x, win_y);
+}
+
+gboolean gdk_display_pointer_is_grabbed (GdkDisplay * display)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_display_pointer_is_grabbed);
+    return (*_gdk_display_pointer_is_grabbed) (display);
+}
+
+gboolean gdk_display_supports_composite (GdkDisplay * display)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_display_supports_composite);
+    return (*_gdk_display_supports_composite) (display);
+}
+
+void gdk_drag_abort (GdkDragContext * context, guint32 time_)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_drag_abort);
+    (*_gdk_drag_abort) (context, time_);
+}
+
+gboolean gdk_drag_motion (GdkDragContext * context,
+              GdkWindow * dest_window,
+              GdkDragProtocol protocol,
+              gint x_root,
+              gint y_root,
+              GdkDragAction suggested_action,
+              GdkDragAction possible_actions, guint32 time_)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_drag_motion);
+    return (*_gdk_drag_motion) (context, dest_window, protocol, x_root,
+                y_root, suggested_action, possible_actions,
+                time_);
+}
+
+void gdk_drag_drop (GdkDragContext * context, guint32 time_)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_drag_drop);
+    (*_gdk_drag_drop) (context, time_);
+}
+
+GdkDragContext *gdk_drag_begin (GdkWindow * window, GList * targets)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_drag_begin);
+    return (*_gdk_drag_begin) (window, targets);
+}
+
+GdkDragAction gdk_drag_context_get_actions (GdkDragContext * context)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_drag_context_get_actions);
+    return (*_gdk_drag_context_get_actions) (context);
+}
+
+GdkDragAction gdk_drag_context_get_selected_action (GdkDragContext * context)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_drag_context_get_selected_action);
+    return (*_gdk_drag_context_get_selected_action) (context);
+}
+
+GdkDragAction gdk_drag_context_get_suggested_action (GdkDragContext * context)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_drag_context_get_suggested_action);
+    return (*_gdk_drag_context_get_suggested_action) (context);
+}
+
+GList *gdk_drag_context_list_targets (GdkDragContext * context)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_drag_context_list_targets);
+    return (*_gdk_drag_context_list_targets) (context);
+}
+
+void gdk_drag_find_window_for_screen (GdkDragContext * context,
+                      GdkWindow * drag_window,
+                      GdkScreen * screen,
+                      gint x_root,
+                      gint y_root,
+                      GdkWindow ** dest_window,
+                      GdkDragProtocol * protocol)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_drag_find_window_for_screen);
+    (*_gdk_drag_find_window_for_screen) (context, drag_window, screen, x_root,
+                     y_root, dest_window, protocol);
+}
+
+GdkAtom gdk_drag_get_selection (GdkDragContext * context)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_drag_get_selection);
+    return (*_gdk_drag_get_selection) (context);
+}
+
+GdkWindow *gdk_drag_context_get_dest_window (GdkDragContext * context)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_drag_context_get_dest_window);
+    return (*_gdk_drag_context_get_dest_window) (context);
+}
+
+void gdk_drag_status (GdkDragContext * context,
+              GdkDragAction action, guint32 time_)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_drag_status);
+    (*_gdk_drag_status) (context, action, time_);
+}
+
+void gdk_drop_reply (GdkDragContext * context, gboolean ok, guint32 time_)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_drop_reply);
+    (*_gdk_drop_reply) (context, ok, time_);
+}
+
+void gdk_drop_finish (GdkDragContext * context,
+              gboolean success, guint32 time_)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_drop_finish);
+    (*_gdk_drop_finish) (context, success, time_);
+}
+
+void gdk_error_trap_push (void)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_error_trap_push);
+    return (*_gdk_error_trap_push) ();
+}
+
+void gdk_event_request_motions (const GdkEventMotion * event)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_event_request_motions);
+    (*_gdk_event_request_motions) (event);
+}
+
+void gdk_event_handler_set (GdkEventFunc func,
+                gpointer data, GDestroyNotify notify)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_event_handler_set);
+    (*_gdk_event_handler_set) (func, data, notify);
+}
+
+GdkWindow *gdk_get_default_root_window (void)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_get_default_root_window);
+    return (*_gdk_get_default_root_window) ();
+}
+
+GdkKeymap *gdk_keymap_get_default (void)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_keymap_get_default);
+    return (*_gdk_keymap_get_default) ();
+}
+
+gboolean gdk_keymap_get_entries_for_keyval (GdkKeymap * keymap,
+                        guint keyval,
+                        GdkKeymapKey ** keys,
+                        gint * n_keys)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_keymap_get_entries_for_keyval);
+    return (*_gdk_keymap_get_entries_for_keyval) (keymap, keyval, keys,
+                          n_keys);
+}
+
+guint gdk_keymap_lookup_key (GdkKeymap * keymap, const GdkKeymapKey * key)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_keymap_lookup_key);
+    return (*_gdk_keymap_lookup_key) (keymap, key);
+}
+
+gboolean gdk_keymap_translate_keyboard_state (GdkKeymap * keymap,
+                          guint hardware_keycode,
+                          GdkModifierType state,
+                          gint group,
+                          guint * keyval,
+                          gint * effective_group,
+                          gint * level,
+                          GdkModifierType *
+                          consumed_modifiers)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_keymap_translate_keyboard_state);
+    return (*_gdk_keymap_translate_keyboard_state) (keymap, hardware_keycode,
+                            state, group, keyval,
+                            effective_group, level,
+                            consumed_modifiers);
+}
+
+guint32 gdk_keyval_to_unicode (guint keyval)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_keyval_to_unicode);
+    return (*_gdk_keyval_to_unicode) (keyval);
+}
+
+GdkPixbuf *gdk_pixbuf_get_from_drawable (GdkPixbuf * dest,
+                     GdkDrawable * src,
+                     GdkColormap * cmap,
+                     int src_x,
+                     int src_y,
+                     int dest_x,
+                     int dest_y, int width, int height)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_pixbuf_get_from_drawable);
+    return (*_gdk_pixbuf_get_from_drawable) (dest, src, cmap, src_x, src_y,
+                         dest_x, dest_y, width, height);
+}
+
+void gdk_pixbuf_render_pixmap_and_mask (GdkPixbuf * pixbuf,
+                    GdkPixmap ** pixmap_return,
+                    GdkBitmap ** mask_return,
+                    int alpha_threshold)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_pixbuf_render_pixmap_and_mask);
+    (*_gdk_pixbuf_render_pixmap_and_mask) (pixbuf, pixmap_return, mask_return,
+                       alpha_threshold);
+}
+
+void gdk_pixbuf_render_pixmap_and_mask_for_colormap (GdkPixbuf * pixbuf,
+                             GdkColormap * colormap,
+                             GdkPixmap **
+                             pixmap_return,
+                             GdkBitmap ** mask_return,
+                             int alpha_threshold)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_pixbuf_render_pixmap_and_mask_for_colormap);
+    (*_gdk_pixbuf_render_pixmap_and_mask_for_colormap) (pixbuf, colormap,
+                            pixmap_return,
+                            mask_return,
+                            alpha_threshold);
+}
+
+GdkGrabStatus gdk_pointer_grab (GdkWindow * window,
+                gboolean owner_events,
+                GdkEventMask event_mask,
+                GdkWindow * confine_to,
+                GdkCursor * cursor, guint32 time_)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_pointer_grab);
+    return (*_gdk_pointer_grab) (window, owner_events, event_mask, confine_to,
+                 cursor, time_);
+}
+
+void gdk_pointer_ungrab (guint32 time_)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_pointer_ungrab);
+    return (*_gdk_pointer_ungrab) (time_);
+}
+
+void gdk_property_change (GdkWindow * window,
+              GdkAtom property,
+              GdkAtom type,
+              gint format,
+              GdkPropMode mode,
+              const guchar * data, gint nelements)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_property_change);
+    return (*_gdk_property_change) (window, property, type, format, mode,
+                    data, nelements);
+}
+
+gboolean gdk_property_get (GdkWindow * window,
+               GdkAtom property,
+               GdkAtom type,
+               gulong offset,
+               gulong length,
+               gint pdelete,
+               GdkAtom * actual_property_type,
+               gint * actual_format,
+               gint * actual_length, guchar ** data)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_property_get);
+    return (*_gdk_property_get) (window, property, type, offset, length,
+                 pdelete, actual_property_type, actual_format,
+                 actual_length, data);
+}
+
+gboolean gdk_rectangle_intersect (const GdkRectangle * src1,
+                  const GdkRectangle * src2,
+                  GdkRectangle * dest)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_rectangle_intersect);
+    return (*_gdk_rectangle_intersect) (src1, src2, dest);
+}
+
+void gdk_region_destroy (GdkRegion * region)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_region_destroy);
+    (*_gdk_region_destroy) (region);
+}
+
+GdkRegion *gdk_region_new (void)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_region_new);
+    return (*_gdk_region_new) ();
+}
+
+GdkScreen *gdk_screen_get_default (void)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_screen_get_default);
+    return (*_gdk_screen_get_default) ();
+}
+
+gint gdk_screen_get_height (GdkScreen * screen)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_screen_get_height);
+    return (*_gdk_screen_get_height) (screen);
+}
+
+gint gdk_screen_get_monitor_at_point (GdkScreen * screen, gint x, gint y)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_screen_get_monitor_at_point);
+    return (*_gdk_screen_get_monitor_at_point) (screen, x, y);
+}
+
+void gdk_screen_get_monitor_geometry (GdkScreen * screen,
+                      gint monitor_num, GdkRectangle * dest)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_screen_get_monitor_geometry);
+    (*_gdk_screen_get_monitor_geometry) (screen, monitor_num, dest);
+}
+
+gint gdk_screen_get_n_monitors (GdkScreen * screen)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_screen_get_n_monitors);
+    return (*_gdk_screen_get_n_monitors) (screen);
+}
+
+gdouble gdk_screen_get_resolution (GdkScreen * screen)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_screen_get_resolution);
+    return (*_gdk_screen_get_resolution) (screen);
+}
+
+GdkColormap *gdk_screen_get_rgba_colormap (GdkScreen * screen)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_screen_get_rgba_colormap);
+    return (*_gdk_screen_get_rgba_colormap) (screen);
+}
+
+GdkColormap *gdk_screen_get_rgb_colormap (GdkScreen * screen)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_screen_get_rgb_colormap);
+    return (*_gdk_screen_get_rgb_colormap) (screen);
+}
+
+GdkWindow *gdk_screen_get_root_window (GdkScreen * screen)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_screen_get_root_window);
+    return (*_gdk_screen_get_root_window) (screen);
+}
+
+GdkVisual *gdk_screen_get_system_visual (GdkScreen * screen)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_screen_get_system_visual);
+    return (*_gdk_screen_get_system_visual) (screen);
+}
+
+gint gdk_screen_get_width (GdkScreen * screen)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_screen_get_width);
+    return (*_gdk_screen_get_width) (screen);
+}
+
+gboolean gdk_screen_is_composited (GdkScreen * screen)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_screen_is_composited);
+    return (*_gdk_screen_is_composited) (screen);
+}
+
+void gdk_selection_convert (GdkWindow * requestor,
+                GdkAtom selection, GdkAtom target, guint32 time_)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_selection_convert);
+    (*_gdk_selection_convert) (requestor, selection, target, time_);
+}
+
+gboolean gdk_selection_owner_set (GdkWindow * owner,
+                  GdkAtom selection,
+                  guint32 time_, gboolean send_event)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_selection_owner_set);
+    return (*_gdk_selection_owner_set) (owner, selection, time_, send_event);
+}
+
+gint gdk_selection_property_get (GdkWindow * requestor,
+                 guchar ** data,
+                 GdkAtom * prop_type, gint * prop_format)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_selection_property_get);
+    return (*_gdk_selection_property_get) (requestor, data, prop_type,
+                       prop_format);
+}
+
+void gdk_selection_send_notify (GdkNativeWindow requestor,
+                GdkAtom selection,
+                GdkAtom target,
+                GdkAtom property, guint32 time_)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_selection_send_notify);
+    return (*_gdk_selection_send_notify) (requestor, selection, target,
+                      property, time_);
+}
+
+guint gdk_unicode_to_keyval (guint32 wc)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_unicode_to_keyval);
+    return (*_gdk_unicode_to_keyval) (wc);
+}
+
+guint gdk_threads_add_idle_full (gint priority,
+                 GSourceFunc function,
+                 gpointer data, GDestroyNotify notify)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_threads_add_idle_full);
+    return (*_gdk_threads_add_idle_full) (priority, function, data, notify);
+}
+
+guint gdk_threads_add_idle (GSourceFunc function, gpointer data)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_threads_add_idle);
+    return (*_gdk_threads_add_idle) (function, data);
+}
+
+guint gdk_threads_add_timeout_full (gint priority,
+                    guint interval,
+                    GSourceFunc function,
+                    gpointer data, GDestroyNotify notify)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_threads_add_timeout_full);
+    return (*_gdk_threads_add_timeout_full) (priority, interval, function,
+                         data, notify);
+}
+
+void gdk_threads_enter (void)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_threads_enter);
+    (*_gdk_threads_enter) ();
+}
+
+void gdk_threads_init (void)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_threads_init);
+    (*_gdk_threads_init) ();
+}
+
+void gdk_threads_leave (void)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_threads_leave);
+    (*_gdk_threads_leave) ();
+}
+
+void gdk_window_destroy (GdkWindow * window)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_window_destroy);
+    (*_gdk_window_destroy) (window);
+}
+
+GdkCursor *gdk_window_get_cursor (GdkWindow * window)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_window_get_cursor);
+    return (*_gdk_window_get_cursor) (window);
+}
+
+GdkEventMask gdk_window_get_events (GdkWindow * window)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_window_get_events);
+    return (*_gdk_window_get_events) (window);
+}
+
+void gdk_window_get_geometry (GdkWindow * window,
+                  gint * x,
+                  gint * y,
+                  gint * width, gint * height, gint * depth)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_window_get_geometry);
+    (*_gdk_window_get_geometry) (window, x, y, width, height, depth);
+}
+
+gint gdk_window_get_origin (GdkWindow * window, gint * x, gint * y)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_window_get_origin);
+    return (*_gdk_window_get_origin) (window, x, y);
+}
+
+gboolean gdk_window_is_destroyed (GdkWindow * window)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_window_is_destroyed);
+    return (*_gdk_window_is_destroyed) (window);
+}
+
+void gdk_window_move (GdkWindow * window, gint x, gint y)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_window_move);
+    (*_gdk_window_move) (window, x, y);
+}
+
+GdkWindow *gdk_window_new (GdkWindow * parent,
+               GdkWindowAttr * attributes, gint attributes_mask)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_window_new);
+    return (*_gdk_window_new) (parent, attributes, attributes_mask);
+}
+
+void gdk_window_register_dnd (GdkWindow * window)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_window_register_dnd);
+    (*_gdk_window_register_dnd) (window);
+}
+
+void gdk_window_resize (GdkWindow * window, gint width, gint height)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_window_resize);
+    (*_gdk_window_resize) (window, width, height);
+}
+
+void gdk_window_restack (GdkWindow * window,
+             GdkWindow * sibling, gboolean above)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_window_restack);
+    (*_gdk_window_restack) (window, sibling, above);
+}
+
+void gdk_window_set_cursor (GdkWindow * window, GdkCursor * cursor)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_window_set_cursor);
+    (*_gdk_window_set_cursor) (window, cursor);
+}
+
+void gdk_window_set_events (GdkWindow * window, GdkEventMask event_mask)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_window_set_events);
+    (*_gdk_window_set_events) (window, event_mask);
+}
+
+void gdk_window_set_functions (GdkWindow * window, GdkWMFunction functions)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_window_set_functions);
+    (*_gdk_window_set_functions) (window, functions);
+}
+
+void gdk_window_show (GdkWindow * window)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_window_show);
+    (*_gdk_window_show) (window);
+}
+
+Display *gdk_x11_display_get_xdisplay (GdkDisplay * display)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_x11_display_get_xdisplay);
+    return (*_gdk_x11_display_get_xdisplay) (display);
+}
+
+XID gdk_x11_drawable_get_xid (GdkDrawable * drawable)
+{
+    if (wrapper_gtk_version == 2) {
+        CHECK_LOAD_SYMBOL_GDK (gdk_x11_drawable_get_xid);
+        return (*_gdk_x11_drawable_get_xid) (drawable);
+    } else {
+        CHECK_LOAD_SYMBOL_GDK (gdk_x11_window_get_xid);
+        return (*_gdk_x11_window_get_xid) (drawable);
+    }
+}
+
+gint gdk_x11_get_default_screen (void)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_x11_get_default_screen);
+    return (*_gdk_x11_get_default_screen) ();
+}
+
+Display *gdk_x11_get_default_xdisplay (void)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_x11_get_default_xdisplay);
+    return (*_gdk_x11_get_default_xdisplay) ();
+}
+
+guint32 gdk_x11_get_server_time (GdkWindow * window)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_x11_get_server_time);
+    return (*_gdk_x11_get_server_time) (window);
+}
+
+GdkVisual *gdk_x11_screen_lookup_visual (GdkScreen * screen,
+                     VisualID xvisualid)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_x11_screen_lookup_visual);
+    return (*_gdk_x11_screen_lookup_visual) (screen, xvisualid);
+}
+
+GdkWindow *gdk_x11_window_foreign_new_for_display (GdkDisplay * display,
+                           Window window)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_x11_window_foreign_new_for_display);
+    return (*_gdk_x11_window_foreign_new_for_display) (display, window);
+}
+
+GdkWindow *gdk_x11_window_lookup_for_display (GdkDisplay * display,
+                          Window window)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_x11_window_lookup_for_display);
+    return (*_gdk_x11_window_lookup_for_display) (display, window);
+}
+
+GdkDisplay *gdk_window_get_display (GdkWindow * window)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_window_get_display);
+    return (*_gdk_window_get_display) (window);
+}
+
+int gdk_window_get_height (GdkWindow * window)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_window_get_height);
+    return (*_gdk_window_get_height) (window);
+}
+
+int gdk_window_get_width (GdkWindow * window)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_window_get_width);
+    return (*_gdk_window_get_width) (window);
+}
+
+GdkScreen *gdk_window_get_screen (GdkWindow * window)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_window_get_screen);
+    return (*_gdk_window_get_screen) (window);
+}
+
+
+//--------------------------------------------------------------------------------------
+
+
+GdkVisual *   gdk_window_get_visual (GdkWindow     *window)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_window_get_visual);
+    return (*_gdk_window_get_visual)(window);
+}
+
+GdkScreen    *gdk_visual_get_screen (GdkVisual *visual)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_visual_get_screen);
+    return (*_gdk_visual_get_screen)(visual);
+}
+
+//--------------------------------------------------------------------------------------
+
+Window
+gdk_x11_window_get_xid(GdkWindow   *window)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_x11_window_get_xid);
+    return (*_gdk_x11_window_get_xid)(window);
+}
+
+GType
+gdk_window_object_get_type       (void)
+{
+    if (wrapper_gtk_version == 2) {
+        return (*_gdk_window_object_get_type)();
+    } else {
+        return (*_gdk_window_get_type)();
+    }
+}
+
+cairo_region_t *
+gdk_cairo_region_create_from_surface (cairo_surface_t *surface)
+{
+    return (*_gdk_cairo_region_create_from_surface)(surface);
+}
+
+//--------------------------------------------------------------------------------------
+
+typedef struct _DeviceGrabContext {
+    GdkWindow * window;
+    gboolean grabbed;
+} DeviceGrabContext;
+
+
+
+gboolean disableGrab = FALSE;
+static gboolean configure_transparent_window(GtkWidget *window);
+static void configure_opaque_window(GtkWidget *window);
+
+static void grab_mouse_device(GdkDevice *device, DeviceGrabContext *context);
+static void ungrab_mouse_device(GdkDevice *device);
+
+gint glass_gdk_visual_get_depth (GdkVisual * visual)
+{
+    // gdk_visual_get_depth is GTK 2.2 +
+    if (_gdk_visual_get_depth) {
+        CHECK_LOAD_SYMBOL_GDK (gdk_visual_get_depth);
+        return (*_gdk_visual_get_depth) (visual);
+    } else {
+        return visual ? visual->depth : 0;
+    }
+}
+
+GdkScreen * glass_gdk_window_get_screen(GdkWindow * gdkWindow)
+{
+    if (wrapper_gtk_version == 2) {
+        CHECK_LOAD_SYMBOL_GDK (gdk_window_get_screen);
+        return (*_gdk_window_get_screen)(gdkWindow);
+    } else {
+        GdkVisual * gdkVisual = gdk_window_get_visual(gdkWindow);
+        return gdk_visual_get_screen(gdkVisual);
+    }
+}
+
+gboolean
+glass_gdk_mouse_devices_grab(GdkWindow *gdkWindow) {
+    if (wrapper_gtk_version == 2) {
+        return glass_gdk_mouse_devices_grab_with_cursor(gdkWindow, NULL, TRUE);
+    } else {
+        if (disableGrab) {
+            return TRUE;
+        }
+
+        CHECK_LOAD_SYMBOL_GDK (gdk_device_manager_list_devices);
+        CHECK_LOAD_SYMBOL_GDK (gdk_display_get_device_manager);
+        CHECK_LOAD_SYMBOL_GDK (gdk_display_get_default);
+
+        DeviceGrabContext context;
+        GList *devices = (*_gdk_device_manager_list_devices) (
+                             (*_gdk_display_get_device_manager)(
+                                 gdk_display_get_default()),
+                                 GDK_DEVICE_TYPE_MASTER);
+
+        context.window = gdkWindow;
+        context.grabbed = FALSE;
+        g_list_foreach(devices, (GFunc) grab_mouse_device, &context);
+
+        return context.grabbed;
+    }
+}
+
+gboolean
+glass_gdk_mouse_devices_grab_with_cursor(GdkWindow *gdkWindow, GdkCursor *cursor, gboolean owner_events) {
+    if (disableGrab) {
+        return TRUE;
+    }
+    CHECK_LOAD_SYMBOL_GDK (gdk_pointer_grab);
+    GdkGrabStatus status = (*_gdk_pointer_grab)(gdkWindow, owner_events, (GdkEventMask)
+                                            (GDK_POINTER_MOTION_MASK
+                                                | GDK_POINTER_MOTION_HINT_MASK
+                                                | GDK_BUTTON_MOTION_MASK
+                                                | GDK_BUTTON1_MOTION_MASK
+                                                | GDK_BUTTON2_MOTION_MASK
+                                                | GDK_BUTTON3_MOTION_MASK
+                                                | GDK_BUTTON_PRESS_MASK
+                                                | GDK_BUTTON_RELEASE_MASK),
+                                            NULL, cursor, GDK_CURRENT_TIME);
+
+    return (status == GDK_GRAB_SUCCESS) ? TRUE : FALSE;
+}
+
+void
+glass_gdk_mouse_devices_ungrab() {
+    if (wrapper_gtk_version == 2) {
+        CHECK_LOAD_SYMBOL_GDK (gdk_pointer_ungrab);
+        (*_gdk_pointer_ungrab)(GDK_CURRENT_TIME);
+    } else {
+        CHECK_LOAD_SYMBOL_GDK (gdk_device_manager_list_devices);
+        CHECK_LOAD_SYMBOL_GDK (gdk_display_get_device_manager);
+        CHECK_LOAD_SYMBOL_GDK (gdk_display_get_default);
+
+        GList *devices = (*_gdk_device_manager_list_devices)(
+                             (*_gdk_display_get_device_manager)(
+                                 (*_gdk_display_get_default)()),
+                                 GDK_DEVICE_TYPE_MASTER);
+        g_list_foreach(devices, (GFunc) ungrab_mouse_device, NULL);
+    }
+}
+
+void
+glass_gdk_master_pointer_grab(GdkWindow *window, GdkCursor *cursor) {
+    if (disableGrab) {
+        CHECK_LOAD_SYMBOL_GDK (gdk_window_set_cursor);
+        (*_gdk_window_set_cursor)(window, cursor);
+        return;
+    }
+    if (wrapper_gtk_version == 2) {
+        CHECK_LOAD_SYMBOL_GDK (gdk_pointer_grab);
+        (*_gdk_pointer_grab)(window, FALSE, (GdkEventMask)
+                         (GDK_POINTER_MOTION_MASK
+                             | GDK_BUTTON_MOTION_MASK
+                             | GDK_BUTTON1_MOTION_MASK
+                             | GDK_BUTTON2_MOTION_MASK
+                             | GDK_BUTTON3_MOTION_MASK
+                             | GDK_BUTTON_RELEASE_MASK),
+                         NULL, cursor, GDK_CURRENT_TIME);
+    } else {
+        CHECK_LOAD_SYMBOL_GDK (gdk_device_grab);
+        CHECK_LOAD_SYMBOL_GDK (gdk_device_manager_get_client_pointer);
+        CHECK_LOAD_SYMBOL_GDK (gdk_display_get_device_manager);
+        CHECK_LOAD_SYMBOL_GDK (gdk_display_get_default);
+
+        (*_gdk_device_grab)((*_gdk_device_manager_get_client_pointer)(
+                    (*_gdk_display_get_device_manager)(
+                        (*_gdk_display_get_default)())),
+                    window, GDK_OWNERSHIP_NONE, FALSE, GDK_ALL_EVENTS_MASK,
+                    cursor, GDK_CURRENT_TIME);
+    }
+}
+
+void
+glass_gdk_master_pointer_ungrab() {
+    if (wrapper_gtk_version == 2) {
+        CHECK_LOAD_SYMBOL_GDK (gdk_pointer_ungrab);
+        (*_gdk_pointer_ungrab)(GDK_CURRENT_TIME);
+    } else {
+        CHECK_LOAD_SYMBOL_GDK (gdk_device_ungrab);
+        CHECK_LOAD_SYMBOL_GDK (gdk_device_manager_get_client_pointer);
+        CHECK_LOAD_SYMBOL_GDK (gdk_display_get_device_manager);
+        CHECK_LOAD_SYMBOL_GDK (gdk_display_get_default);
+        (*_gdk_device_ungrab)((*_gdk_device_manager_get_client_pointer)(
+                              (*_gdk_display_get_device_manager)(
+                                  (*_gdk_display_get_default)())),
+                          GDK_CURRENT_TIME);
+    }
+}
+
+void
+glass_gdk_master_pointer_get_position(gint *x, gint *y) {
+    if (wrapper_gtk_version == 2) {
+        CHECK_LOAD_SYMBOL_GDK (gdk_display_get_pointer);
+        (*_gdk_display_get_pointer)(gdk_display_get_default(), NULL, x, y, NULL);
+    } else {
+        CHECK_LOAD_SYMBOL_GDK (gdk_device_manager_get_client_pointer);
+        CHECK_LOAD_SYMBOL_GDK (gdk_display_get_device_manager);
+        CHECK_LOAD_SYMBOL_GDK (gdk_display_get_default);
+        (*_gdk_device_get_position)((*_gdk_device_manager_get_client_pointer)(
+                                    (*_gdk_display_get_device_manager)(
+                                        (*_gdk_display_get_default)())),
+                                NULL, x, y);
+    }
+}
+
+gboolean
+glass_gdk_device_is_grabbed(GdkDevice *device) {
+    if (wrapper_gtk_version == 2) {
+        (void) device;
+        CHECK_LOAD_SYMBOL_GDK (gdk_display_pointer_is_grabbed);
+        return (*_gdk_display_pointer_is_grabbed)(gdk_display_get_default());
+    } else {
+        CHECK_LOAD_SYMBOL_GDK (gdk_display_device_is_grabbed);
+        return (*_gdk_display_device_is_grabbed)((*_gdk_display_get_default)(), device);
+    }
+}
+
+void
+glass_gdk_device_ungrab(GdkDevice *device) {
+    if (wrapper_gtk_version == 2) {
+        (void) device;
+        CHECK_LOAD_SYMBOL_GDK (gdk_pointer_ungrab);
+        (*_gdk_pointer_ungrab)(GDK_CURRENT_TIME);
+    } else {
+        CHECK_LOAD_SYMBOL_GDK (gdk_device_ungrab);
+        (*_gdk_device_ungrab)(device, GDK_CURRENT_TIME);
+    }
+}
+
+GdkWindow *
+glass_gdk_device_get_window_at_position(GdkDevice *device, gint *x, gint *y) {
+    if (wrapper_gtk_version == 2) {
+        (void) device;
+        CHECK_LOAD_SYMBOL_GDK (gdk_display_get_window_at_pointer);
+        return (*_gdk_display_get_window_at_pointer)(gdk_display_get_default(), x, y);
+    } else {
+        CHECK_LOAD_SYMBOL_GDK (gdk_device_get_window_at_position);
+        return (*_gdk_device_get_window_at_position)(device, x, y);
+    }
+}
+
+void
+glass_gtk_configure_transparency_and_realize(GtkWidget *window,
+                                             gboolean transparent) {
+    if (wrapper_gtk_version == 2) {
+        glass_configure_window_transparency(window, transparent);
+        gtk_widget_realize(window);
+    } else {
+        CHECK_LOAD_SYMBOL_GDK (gdk_window_set_background_rgba);
+        gboolean isTransparent = glass_configure_window_transparency(window, transparent);
+        gtk_widget_realize(window);
+        if (isTransparent) {
+            GdkRGBA rgba = { 1.0, 1.0, 1.0, 0.0 };
+            (*_gdk_window_set_background_rgba)(gtk_widget_get_window(window), &rgba);
+        }
+    }
+}
+
+void
+glass_gtk_window_configure_from_visual(GtkWidget *widget, GdkVisual *visual) {
+    glass_widget_set_visual(widget, visual);
+}
+
+static gboolean
+configure_transparent_window(GtkWidget *window) {
+    GdkScreen *default_screen = (*_gdk_screen_get_default)();
+    GdkDisplay *default_display = (*_gdk_display_get_default)();
+
+    if (wrapper_gtk_version == 2) {
+        CHECK_LOAD_SYMBOL_GDK (gdk_screen_get_rgba_colormap);
+        CHECK_LOAD_SYMBOL_GDK (gdk_display_supports_composite);
+        CHECK_LOAD_SYMBOL_GDK (gdk_screen_is_composited);
+        GdkColormap *colormap = (*_gdk_screen_get_rgba_colormap)(default_screen);
+        if (colormap
+                && (*_gdk_display_supports_composite)(default_display)
+                && (*_gdk_screen_is_composited)(default_screen)) {
+            gtk_widget_set_colormap(window, colormap);
+            return TRUE;
+        }
+    } else {
+        CHECK_LOAD_SYMBOL_GDK (gdk_display_supports_composite);
+        CHECK_LOAD_SYMBOL_GDK (gdk_screen_is_composited);
+        GdkVisual *visual = (*_gdk_screen_get_rgba_visual)(default_screen);
+        if (visual
+                && (*_gdk_display_supports_composite)(default_display)
+                && (*_gdk_screen_is_composited)(default_screen)) {
+            glass_widget_set_visual(window, visual);
+            return TRUE;
+        }
+
+        return FALSE;
+    }
+
+    return FALSE;
+}
+
+int
+glass_gtk_fixup_typed_key(int key, int keyval) {
+    if (wrapper_gtk_version == 2) {
+        if (key == 0) {
+            // Work around "bug" fixed in gtk-3.0:
+            // http://mail.gnome.org/archives/commits-list/2011-March/msg06832.html
+            switch (keyval) {
+            case 0xFF08 /* Backspace */: return '\b';
+            case 0xFF09 /* Tab       */: return '\t';
+            case 0xFF0A /* Linefeed  */: return '\n';
+            case 0xFF0B /* Vert. Tab */: return '\v';
+            case 0xFF0D /* Return    */: return '\r';
+            case 0xFF1B /* Escape    */: return '\033';
+            case 0xFFFF /* Delete    */: return '\177';
+            }
+        }
+    }
+    return key;
+}
+
+void
+glass_gdk_window_get_size(GdkWindow *window, gint *w, gint *h) {
+    CHECK_LOAD_SYMBOL_GDK (gdk_window_get_width);
+    CHECK_LOAD_SYMBOL_GDK (gdk_window_get_height);
+    *w = (*_gdk_window_get_width)(window);
+    *h = (*_gdk_window_get_height)(window);
+}
+
+void
+glass_gdk_display_get_pointer(GdkDisplay* display, gint* x, gint *y) {
+    if (wrapper_gtk_version == 2) {
+        CHECK_LOAD_SYMBOL_GDK (gdk_display_get_pointer);
+        (*_gdk_display_get_pointer)(display, NULL, x, y, NULL);
+    } else {
+        CHECK_LOAD_SYMBOL_GDK (gdk_device_get_position);
+        CHECK_LOAD_SYMBOL_GDK (gdk_device_manager_get_client_pointer);
+        CHECK_LOAD_SYMBOL_GDK (gdk_display_get_device_manager);
+        (*_gdk_device_get_position)(
+            (*_gdk_device_manager_get_client_pointer)(
+                (*_gdk_display_get_device_manager)(display)), NULL , x, y);
+    }
+}
+
+
+const guchar*
+glass_gtk_selection_data_get_data_with_length(
+        GtkSelectionData * selectionData,
+        gint * length) {
+    if (selectionData == NULL) {
+        return NULL;
+    }
+
+    *length = gtk_selection_data_get_length(selectionData);
+    return gtk_selection_data_get_data(selectionData);
+}
+
+static void
+configure_opaque_window(GtkWidget *window) {
+    (void) window;
+/* We need to pick a visual that really is glx compatible
+ * instead of using the default visual
+ *
+    CHECK_LOAD_SYMBOL_GDK (gdk_screen_get_system_visual);
+    CHECK_LOAD_SYMBOL_GDK (gdk_screen_get_default);
+    glass_widget_set_visual(window,
+                          gdk_screen_get_system_visual(
+                              gdk_screen_get_default()));
+*/
+}
+
+gboolean
+glass_configure_window_transparency(GtkWidget *window, gboolean transparent) {
+    if (transparent) {
+        if (configure_transparent_window(window)) {
+            return TRUE;
+        }
+
+        fprintf(stderr,"Can't create transparent stage, because your screen doesn't"
+               " support alpha channel."
+               " You need to enable XComposite extension.\n");
+        fflush(stderr);
+    }
+
+    configure_opaque_window(window);
+    return FALSE;
+}
+
+static void
+grab_mouse_device(GdkDevice *device, DeviceGrabContext *context) {
+    CHECK_LOAD_SYMBOL_GDK (gdk_device_get_source);
+    CHECK_LOAD_SYMBOL_GDK (gdk_device_grab);
+    GdkInputSource source = (*_gdk_device_get_source)(device);
+    if (source == GDK_SOURCE_MOUSE) {
+        GdkGrabStatus status = (*_gdk_device_grab)(device,
+                                               context->window,
+                                               GDK_OWNERSHIP_NONE,
+                                               TRUE,
+                                               GDK_ALL_EVENTS_MASK,
+                                               NULL,
+                                               GDK_CURRENT_TIME);
+        if (status == GDK_GRAB_SUCCESS) {
+            context->grabbed = TRUE;
+        }
+    }
+}
+
+static void
+ungrab_mouse_device(GdkDevice *device) {
+    CHECK_LOAD_SYMBOL_GDK (gdk_device_get_source);
+    CHECK_LOAD_SYMBOL_GDK (gdk_device_ungrab);
+    GdkInputSource source = (*_gdk_device_get_source)(device);
+    if (source == GDK_SOURCE_MOUSE) {
+        (*_gdk_device_ungrab)(device, GDK_CURRENT_TIME);
+    }
+}
+
+GdkPixbuf *
+glass_pixbuf_from_window(GdkWindow *window,
+    gint srcx, gint srcy,
+    gint width, gint height)
+{
+    GdkPixbuf * ret = NULL;
+
+    if (wrapper_gtk_version == 2) {
+        CHECK_LOAD_SYMBOL_GDK (gdk_pixbuf_get_from_drawable);
+        ret = (*_gdk_pixbuf_get_from_drawable) (NULL,
+            window,
+            NULL,
+            srcx, srcy,
+            0, 0,
+            width, height);
+    } else {
+        CHECK_LOAD_SYMBOL_GDK (gdk_pixbuf_get_from_window);
+        ret = (*_gdk_pixbuf_get_from_window) (window, srcx, srcy, width, height);
+    }
+
+    return ret;
+}
+
+void
+glass_window_apply_shape_mask(GdkWindow *window,
+    void* data, uint width, uint height)
+{
+    if (wrapper_gtk_version == 2) {
+        CHECK_LOAD_SYMBOL_GDK (gdk_window_input_shape_combine_mask);
+
+        GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data((guchar *) data,
+                GDK_COLORSPACE_RGB, TRUE, 8, width, height, width * 4, NULL, NULL);
+
+        if (GDK_IS_PIXBUF(pixbuf)) {
+            GdkBitmap* mask = NULL;
+            gdk_pixbuf_render_pixmap_and_mask(pixbuf, NULL, &mask, 128);
+
+            (*_gdk_window_input_shape_combine_mask)(window, mask, 0, 0);
+
+            g_object_unref(pixbuf);
+            if (mask) {
+                g_object_unref(mask);
+            }
+        }
+    } else {
+        CHECK_LOAD_SYMBOL_GDK (gdk_window_shape_combine_region);
+        CHECK_LOAD_SYMBOL_GDK (gdk_window_input_shape_combine_region);
+        CHECK_LOAD_SYMBOL_GDK (gdk_cairo_region_create_from_surface);
+
+        cairo_surface_t * shape = cairo_image_surface_create_for_data(
+                 (unsigned char *)data,
+                 CAIRO_FORMAT_ARGB32,
+                 width, height,
+                 width * 4
+                 );
+        cairo_region_t *region = (*_gdk_cairo_region_create_from_surface) (shape);
+
+        (*_gdk_window_shape_combine_region) (window, region, 0, 0);
+
+        (*_gdk_window_input_shape_combine_region) (window, region, 0, 0);
+
+        cairo_region_destroy(region);
+        cairo_surface_finish (shape);
+    }
+}
+
+void
+glass_window_reset_input_shape_mask(GdkWindow *window)
+{
+    if (wrapper_gtk_version == 2) {
+        CHECK_LOAD_SYMBOL_GDK (gdk_window_input_shape_combine_mask);
+        (*_gdk_window_input_shape_combine_mask)(window, NULL, 0, 0);
+    } else {
+        CHECK_LOAD_SYMBOL_GDK (gdk_window_input_shape_combine_region);
+        (*_gdk_window_input_shape_combine_region) (window, NULL, 0, 0);
+    }
+}
+
+GdkWindow *
+glass_gdk_drag_context_get_dest_window (GdkDragContext * context)
+{
+    CHECK_LOAD_SYMBOL_GDK (gdk_drag_context_get_dest_window);
+    return ((context != NULL) ? gdk_drag_context_get_dest_window(context) : NULL);
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/native-glass/gtk/wrapper_gtk.c	Fri May 06 19:50:10 2016 -0400
@@ -0,0 +1,1045 @@
+/*
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <linux/fb.h>
+#include <fcntl.h>
+#ifndef __USE_GNU       // required for dladdr() & Dl_info
+#define __USE_GNU
+#endif
+#include <dlfcn.h>
+#include <sys/ioctl.h>
+
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+
+#include <assert.h>
+
+#include <gtk/gtk.h>
+
+#include "glass_wrapper.h"
+
+static GtkClipboard *(*_gtk_clipboard_get) (GdkAtom selection);
+static gboolean (*_gtk_clipboard_set_with_data) (GtkClipboard * clipboard,
+                         const GtkTargetEntry *
+                         targets, guint n_targets,
+                         GtkClipboardGetFunc get_func,
+                         GtkClipboardClearFunc
+                         clear_func,
+                         gpointer user_data);
+static GtkSelectionData *(*_gtk_clipboard_wait_for_contents) (GtkClipboard *
+                                  clipboard,
+                                  GdkAtom target);
+static gchar *(*_gtk_clipboard_wait_for_text) (GtkClipboard * clipboard);
+static GdkPixbuf *(*_gtk_clipboard_wait_for_image) (GtkClipboard * clipboard);
+static gchar **(*_gtk_clipboard_wait_for_uris) (GtkClipboard * clipboard);
+static gboolean (*_gtk_clipboard_wait_for_targets) (GtkClipboard * clipboard,
+                            GdkAtom ** targets,
+                            gint * n_targets);
+static void (*_gtk_container_add) (GtkContainer * container,
+                   GtkWidget * widget);
+static GType (*_gtk_container_get_type) (void) G_GNUC_CONST;
+static gint (*_gtk_dialog_run) (GtkDialog * dialog);
+static GType (*_gtk_dialog_get_type) (void) G_GNUC_CONST;
+static GtkWidget *(*_gtk_drawing_area_new) (void);
+static gboolean (*_gtk_events_pending) (void);
+static void (*_gtk_file_chooser_add_filter) (GtkFileChooser * chooser,
+                         GtkFileFilter * filter);
+static gchar *(*_gtk_file_chooser_get_filename) (GtkFileChooser * chooser);
+static GSList *(*_gtk_file_chooser_get_filenames) (GtkFileChooser * chooser);
+static GtkFileFilter *(*_gtk_file_chooser_get_filter) (GtkFileChooser *
+                               chooser);
+static GType (*_gtk_file_chooser_get_type) (void) G_GNUC_CONST;
+static gboolean (*_gtk_file_chooser_set_current_folder) (GtkFileChooser *
+                             chooser,
+                             const gchar *
+                             filename);
+static void (*_gtk_file_chooser_set_current_name) (GtkFileChooser * chooser,
+                           const gchar * name);
+static void (*_gtk_file_chooser_set_do_overwrite_confirmation) (GtkFileChooser
+                                * chooser,
+                                gboolean
+                                do_overwrite_confirmation);
+static void (*_gtk_file_chooser_set_filter) (GtkFileChooser * chooser,
+                         GtkFileFilter * filter);
+static void (*_gtk_file_chooser_set_select_multiple) (GtkFileChooser *
+                              chooser,
+                              gboolean
+                              select_multiple);
+
+
+static GtkWidget *(*_gtk_file_chooser_dialog_new) (const gchar * title,
+                           GtkWindow * parent,
+                           GtkFileChooserAction
+                           action,
+                           const gchar *
+                           first_button_text,
+                           ...)
+    G_GNUC_NULL_TERMINATED;
+
+
+static void (*_gtk_file_filter_add_pattern) (GtkFileFilter * filter,
+                         const gchar * pattern);
+static GtkFileFilter *(*_gtk_file_filter_new) (void);
+static void (*_gtk_file_filter_set_name) (GtkFileFilter * filter,
+                      const gchar * name);
+static GtkWidget *(*_gtk_fixed_new) (void);
+static void (*_gtk_init) (int *argc, char ***argv);
+static void (*_gtk_main_do_event) (GdkEvent * event);
+static void (*_gtk_main) (void);
+static gboolean (*_gtk_main_iteration) (void);
+static void (*_gtk_main_quit) (void);
+static GtkWidget *(*_gtk_plug_new) (GdkNativeWindow socket_id);
+static void (*_gtk_selection_data_free) (GtkSelectionData * data);
+static const guchar *(*_gtk_selection_data_get_data) (GtkSelectionData *
+                              selection_data);
+static gint (*_gtk_selection_data_get_length) (GtkSelectionData *
+                           selection_data);
+static GdkAtom (*_gtk_selection_data_get_target) (GtkSelectionData *
+                          selection_data);
+static void (*_gtk_selection_data_set) (GtkSelectionData * selection_data,
+                    GdkAtom type, gint format,
+                    const guchar * data, gint length);
+static gboolean (*_gtk_selection_data_set_pixbuf) (GtkSelectionData *
+                           selection_data,
+                           GdkPixbuf * pixbuf);
+static gboolean (*_gtk_selection_data_set_text) (GtkSelectionData *
+                         selection_data,
+                         const gchar * str, gint len);
+static gboolean (*_gtk_selection_data_set_uris) (GtkSelectionData *
+                         selection_data,
+                         gchar ** uris);
+static GtkSettings *(*_gtk_settings_get_default) (void);
+static void (*_gtk_target_list_add) (GtkTargetList * list,
+                     GdkAtom target, guint flags, guint info);
+static void (*_gtk_target_list_add_image_targets) (GtkTargetList * list,
+                           guint info,
+                           gboolean writable);
+static void (*_gtk_target_list_add_text_targets) (GtkTargetList * list,
+                          guint info);
+static GtkTargetList *(*_gtk_target_list_new) (const GtkTargetEntry * targets,
+                           guint ntargets);
+static void (*_gtk_target_list_unref) (GtkTargetList * list);
+static gboolean (*_gtk_targets_include_image) (GdkAtom * targets,
+                           gint n_targets,
+                           gboolean writable);
+static gboolean (*_gtk_targets_include_text) (GdkAtom * targets,
+                          gint n_targets);
+static void (*_gtk_target_table_free) (GtkTargetEntry * targets,
+                       gint n_targets);
+static GtkTargetEntry *(*_gtk_target_table_new_from_list) (GtkTargetList *
+                               list,
+                               gint * n_targets);
+static void (*_gtk_widget_destroy) (GtkWidget * widget);
+static GtkWidget *(*_gtk_widget_get_ancestor) (GtkWidget * widget,
+                           GType widget_type);
+static GdkScreen *(*_gtk_widget_get_screen) (GtkWidget * widget);
+static void (*_gtk_widget_get_allocation) (GtkWidget * widget,
+                       GtkAllocation * allocation);
+static GType (*_gtk_widget_get_type) (void) G_GNUC_CONST;
+static gboolean (*_gtk_widget_get_visible) (GtkWidget * widget);
+static GdkWindow *(*_gtk_widget_get_window) (GtkWidget * widget);
+static void (*_gtk_widget_grab_focus) (GtkWidget * widget);
+static void (*_gtk_widget_hide) (GtkWidget * widget);
+static void (*_gtk_widget_modify_bg) (GtkWidget * widget,
+                      GtkStateType state,
+                      const GdkColor * color);
+static void (*_gtk_widget_realize) (GtkWidget * widget);
+static void (*_gtk_widget_set_app_paintable) (GtkWidget * widget,
+                          gboolean app_paintable);
+static void (*_gtk_widget_set_can_focus) (GtkWidget * widget,
+                      gboolean can_focus);
+static void (*_gtk_widget_set_colormap) (GtkWidget * widget,
+                     GdkColormap * colormap);
+static void (*_gtk_widget_set_events) (GtkWidget * widget, gint events);
+static void (*_gtk_widget_set_size_request) (GtkWidget * widget,
+                         gint width, gint height);
+static void (*_gtk_widget_show_all) (GtkWidget * widget);
+static void (*_gtk_window_deiconify) (GtkWindow * window);
+static void (*_gtk_window_fullscreen) (GtkWindow * window);
+static gboolean (*_gtk_window_get_decorated) (GtkWindow * window);
+static gboolean (*_gtk_window_get_decorated) (GtkWindow * window);
+static void (*_gtk_window_get_position) (GtkWindow * window,
+                     gint * root_x, gint * root_y);
+static void (*_gtk_window_get_size) (GtkWindow * window,
+                     gint * width, gint * height);
+static GType (*_gtk_window_get_type) (void) G_GNUC_CONST;
+static void (*_gtk_window_iconify) (GtkWindow * window);
+static void (*_gtk_window_maximize) (GtkWindow * window);
+static void (*_gtk_window_move) (GtkWindow * window, gint x, gint y);
+static GtkWidget *(*_gtk_window_new) (GtkWindowType type);
+static void (*_gtk_window_present) (GtkWindow * window);
+static void (*_gtk_window_resize) (GtkWindow * window,
+                   gint width, gint height);
+static void (*_gtk_window_set_accept_focus) (GtkWindow * window,
+                         gboolean setting);
+static void (*_gtk_window_set_decorated) (GtkWindow * window,
+                      gboolean setting);
+static void (*_gtk_window_set_geometry_hints) (GtkWindow * window,
+                           GtkWidget * geometry_widget,
+                           GdkGeometry * geometry,
+                           GdkWindowHints geom_mask);
+static void (*_gtk_window_set_icon) (GtkWindow * window, GdkPixbuf * icon);
+static void (*_gtk_window_set_keep_above) (GtkWindow * window,
+                       gboolean setting);
+static void (*_gtk_window_set_keep_below) (GtkWindow * window,
+                       gboolean setting);
+static void (*_gtk_window_set_modal) (GtkWindow * window, gboolean modal);
+static void (*_gtk_window_set_opacity) (GtkWindow * window, gdouble opacity);
+static void (*_gtk_window_set_title) (GtkWindow * window,
+                      const gchar * title);
+static void (*_gtk_window_set_transient_for) (GtkWindow * window,
+                          GtkWindow * parent);
+static void (*_gtk_window_set_type_hint) (GtkWindow * window,
+                      GdkWindowTypeHint hint);
+static void (*_gtk_window_set_wmclass) (GtkWindow * window,
+                    const gchar * wmclass_name,
+                    const gchar * wmclass_class);
+static void (*_gtk_window_unfullscreen) (GtkWindow * window);
+static void (*_gtk_window_unmaximize) (GtkWindow * window);
+
+
+//--------------------------------------------------------------------------------------
+// GTK3 only
+static void (*_gtk_widget_set_visual) (GtkWidget *widget, GdkVisual *visual);
+
+static void (*_gtk_widget_shape_combine_region) (GtkWidget *widget,
+                                 cairo_region_t *region);
+
+static void (*_gtk_widget_input_shape_combine_region) (GtkWidget *widget,
+                                       cairo_region_t *region);
+
+
+//--------------------------------------------------------------------------------------
+
+#define PRELOAD_SYMBOL_GTK(x) \
+    _##x = dlsym(libgtk, #x); \
+    if (!_##x) { \
+        symbol_load_errors++; \
+        fprintf(stderr,"failed loading %s\n", #x); \
+    }
+
+int wrapper_load_symbols_gtk(int version, void * libgtk)
+{
+    int symbol_load_errors = 0;
+
+    PRELOAD_SYMBOL_GTK (gtk_clipboard_get);
+    PRELOAD_SYMBOL_GTK (gtk_clipboard_set_with_data);
+    PRELOAD_SYMBOL_GTK (gtk_clipboard_wait_for_contents);
+    PRELOAD_SYMBOL_GTK (gtk_clipboard_wait_for_text);
+    PRELOAD_SYMBOL_GTK (gtk_clipboard_wait_for_image);
+    PRELOAD_SYMBOL_GTK (gtk_clipboard_wait_for_uris);
+    PRELOAD_SYMBOL_GTK (gtk_clipboard_wait_for_targets);
+    PRELOAD_SYMBOL_GTK (gtk_container_add);
+    PRELOAD_SYMBOL_GTK (gtk_container_get_type);
+    PRELOAD_SYMBOL_GTK (gtk_dialog_run);
+    PRELOAD_SYMBOL_GTK (gtk_dialog_get_type);
+    PRELOAD_SYMBOL_GTK (gtk_drawing_area_new);
+    PRELOAD_SYMBOL_GTK (gtk_events_pending);
+    PRELOAD_SYMBOL_GTK (gtk_file_chooser_add_filter);
+    PRELOAD_SYMBOL_GTK (gtk_file_chooser_get_filename);
+    PRELOAD_SYMBOL_GTK (gtk_file_chooser_get_filenames);
+    PRELOAD_SYMBOL_GTK (gtk_file_chooser_get_filter);
+    PRELOAD_SYMBOL_GTK (gtk_file_chooser_get_type);
+    PRELOAD_SYMBOL_GTK (gtk_file_chooser_set_current_folder);
+    PRELOAD_SYMBOL_GTK (gtk_file_chooser_set_current_name);
+    PRELOAD_SYMBOL_GTK (gtk_file_chooser_set_do_overwrite_confirmation);
+    PRELOAD_SYMBOL_GTK (gtk_file_chooser_set_filter);
+    PRELOAD_SYMBOL_GTK (gtk_file_chooser_set_select_multiple);
+    PRELOAD_SYMBOL_GTK (gtk_file_chooser_dialog_new);
+    PRELOAD_SYMBOL_GTK (gtk_file_filter_add_pattern);
+    PRELOAD_SYMBOL_GTK (gtk_file_filter_new);
+    PRELOAD_SYMBOL_GTK (gtk_file_filter_set_name);
+    PRELOAD_SYMBOL_GTK (gtk_fixed_new);
+    PRELOAD_SYMBOL_GTK (gtk_init);
+    PRELOAD_SYMBOL_GTK (gtk_main_do_event);
+    PRELOAD_SYMBOL_GTK (gtk_main);
+    PRELOAD_SYMBOL_GTK (gtk_main_iteration);
+    PRELOAD_SYMBOL_GTK (gtk_main_quit);
+    PRELOAD_SYMBOL_GTK (gtk_plug_new);
+    PRELOAD_SYMBOL_GTK (gtk_selection_data_free);
+    PRELOAD_SYMBOL_GTK (gtk_selection_data_get_data);
+    PRELOAD_SYMBOL_GTK (gtk_selection_data_get_length);
+    PRELOAD_SYMBOL_GTK (gtk_selection_data_get_target);
+    PRELOAD_SYMBOL_GTK (gtk_selection_data_set);
+    PRELOAD_SYMBOL_GTK (gtk_selection_data_set_pixbuf);
+    PRELOAD_SYMBOL_GTK (gtk_selection_data_set_text);
+    PRELOAD_SYMBOL_GTK (gtk_selection_data_set_uris);
+    PRELOAD_SYMBOL_GTK (gtk_settings_get_default);
+    PRELOAD_SYMBOL_GTK (gtk_target_list_add);
+    PRELOAD_SYMBOL_GTK (gtk_target_list_add_image_targets);
+    PRELOAD_SYMBOL_GTK (gtk_target_list_add_text_targets);
+    PRELOAD_SYMBOL_GTK (gtk_target_list_new);
+    PRELOAD_SYMBOL_GTK (gtk_target_list_unref);
+    PRELOAD_SYMBOL_GTK (gtk_targets_include_image);
+    PRELOAD_SYMBOL_GTK (gtk_targets_include_text);
+    PRELOAD_SYMBOL_GTK (gtk_target_table_free);
+    PRELOAD_SYMBOL_GTK (gtk_target_table_new_from_list);
+    PRELOAD_SYMBOL_GTK (gtk_widget_destroy);
+    PRELOAD_SYMBOL_GTK (gtk_widget_get_ancestor);
+    PRELOAD_SYMBOL_GTK (gtk_widget_get_screen);
+    PRELOAD_SYMBOL_GTK (gtk_widget_get_allocation);
+    PRELOAD_SYMBOL_GTK (gtk_widget_get_type);
+    PRELOAD_SYMBOL_GTK (gtk_widget_get_visible);
+    PRELOAD_SYMBOL_GTK (gtk_widget_get_window);
+    PRELOAD_SYMBOL_GTK (gtk_widget_grab_focus);
+    PRELOAD_SYMBOL_GTK (gtk_widget_hide);
+    PRELOAD_SYMBOL_GTK (gtk_widget_modify_bg);
+    PRELOAD_SYMBOL_GTK (gtk_widget_realize);
+    PRELOAD_SYMBOL_GTK (gtk_widget_set_app_paintable);
+    PRELOAD_SYMBOL_GTK (gtk_widget_set_can_focus);
+    PRELOAD_SYMBOL_GTK (gtk_widget_set_events);
+    PRELOAD_SYMBOL_GTK (gtk_widget_set_size_request);
+    PRELOAD_SYMBOL_GTK (gtk_widget_show_all);
+    PRELOAD_SYMBOL_GTK (gtk_window_deiconify);
+    PRELOAD_SYMBOL_GTK (gtk_window_fullscreen);
+    PRELOAD_SYMBOL_GTK (gtk_window_get_decorated);
+    PRELOAD_SYMBOL_GTK (gtk_window_get_position);
+    PRELOAD_SYMBOL_GTK (gtk_window_get_size);
+    PRELOAD_SYMBOL_GTK (gtk_window_get_type);
+    PRELOAD_SYMBOL_GTK (gtk_window_iconify);
+    PRELOAD_SYMBOL_GTK (gtk_window_maximize);
+    PRELOAD_SYMBOL_GTK (gtk_window_move);
+    PRELOAD_SYMBOL_GTK (gtk_window_new);
+    PRELOAD_SYMBOL_GTK (gtk_window_present);
+    PRELOAD_SYMBOL_GTK (gtk_window_resize);
+    PRELOAD_SYMBOL_GTK (gtk_window_set_accept_focus);
+    PRELOAD_SYMBOL_GTK (gtk_window_set_decorated);
+    PRELOAD_SYMBOL_GTK (gtk_window_set_geometry_hints);
+    PRELOAD_SYMBOL_GTK (gtk_window_set_icon);
+    PRELOAD_SYMBOL_GTK (gtk_window_set_keep_above);
+    PRELOAD_SYMBOL_GTK (gtk_window_set_keep_below);
+    PRELOAD_SYMBOL_GTK (gtk_window_set_modal);
+    PRELOAD_SYMBOL_GTK (gtk_window_set_opacity);
+    PRELOAD_SYMBOL_GTK (gtk_window_set_title);
+    PRELOAD_SYMBOL_GTK (gtk_window_set_transient_for);
+    PRELOAD_SYMBOL_GTK (gtk_window_set_type_hint);
+    PRELOAD_SYMBOL_GTK (gtk_window_set_wmclass);
+    PRELOAD_SYMBOL_GTK (gtk_window_unfullscreen);
+    PRELOAD_SYMBOL_GTK (gtk_window_unmaximize);
+
+    if (version == 2) {
+        // gtk version 2 unique symbols
+
+        PRELOAD_SYMBOL_GTK (gtk_widget_set_colormap);
+    } else if (version == 3) {
+        // gtk version 3 unique symbols
+
+        PRELOAD_SYMBOL_GTK (gtk_widget_set_visual);
+        PRELOAD_SYMBOL_GTK (gtk_widget_shape_combine_region);
+        PRELOAD_SYMBOL_GTK (gtk_widget_input_shape_combine_region);
+    }
+
+    if (symbol_load_errors && wrapper_debug) {
+      fprintf (stderr, "failed to load %d gtk symbols",
+           symbol_load_errors);
+    }
+
+    return symbol_load_errors;
+
+}
+
+#define CHECK_LOAD_SYMBOL_GTK(x) \
+    { \
+        if (!_##x) { \
+            if (wrapper_debug) fprintf(stderr,"missing %s\n",#x); \
+            assert(_##x); \
+        } else { \
+            if (wrapper_debug) { \
+               fprintf(stderr,"using %s\n",#x); \
+               fflush(stderr); \
+            } \
+        } \
+    }
+
+GtkClipboard *gtk_clipboard_get (GdkAtom selection)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_clipboard_get);
+    return (*_gtk_clipboard_get) (selection);
+}
+
+gboolean gtk_clipboard_set_with_data (GtkClipboard * clipboard,
+                      const GtkTargetEntry * targets,
+                      guint n_targets,
+                      GtkClipboardGetFunc get_func,
+                      GtkClipboardClearFunc clear_func,
+                      gpointer user_data)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_clipboard_set_with_data);
+    return (*_gtk_clipboard_set_with_data) (clipboard, targets, n_targets,
+                        get_func, clear_func, user_data);
+}
+
+GtkSelectionData *gtk_clipboard_wait_for_contents (GtkClipboard * clipboard,
+                           GdkAtom target)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_clipboard_wait_for_contents);
+    return (*_gtk_clipboard_wait_for_contents) (clipboard, target);
+}
+
+gchar *gtk_clipboard_wait_for_text (GtkClipboard * clipboard)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_clipboard_wait_for_text);
+    return (*_gtk_clipboard_wait_for_text) (clipboard);
+}
+
+GdkPixbuf *gtk_clipboard_wait_for_image (GtkClipboard * clipboard)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_clipboard_wait_for_image);
+    return (*_gtk_clipboard_wait_for_image) (clipboard);
+}
+
+gchar **gtk_clipboard_wait_for_uris (GtkClipboard * clipboard)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_clipboard_wait_for_uris);
+    return (*_gtk_clipboard_wait_for_uris) (clipboard);
+}
+
+gboolean gtk_clipboard_wait_for_targets (GtkClipboard * clipboard,
+                     GdkAtom ** targets, gint * n_targets)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_clipboard_wait_for_targets);
+    return (*_gtk_clipboard_wait_for_targets) (clipboard, targets, n_targets);
+}
+
+void gtk_container_add (GtkContainer * container, GtkWidget * widget)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_container_add);
+    (*_gtk_container_add) (container, widget);
+}
+
+GType gtk_container_get_type (void)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_container_get_type);
+    return (*_gtk_container_get_type) ();
+}
+
+gint gtk_dialog_run (GtkDialog * dialog)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_dialog_run);
+    return (*_gtk_dialog_run) (dialog);
+}
+
+GType gtk_dialog_get_type (void)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_dialog_get_type);
+    return (*_gtk_dialog_get_type) ();
+}
+
+
+GtkWidget *gtk_drawing_area_new (void)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_drawing_area_new);
+    return (*_gtk_drawing_area_new) ();
+}
+
+gboolean gtk_events_pending (void)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_events_pending);
+    return (*_gtk_events_pending) ();
+}
+
+void gtk_file_chooser_add_filter (GtkFileChooser * chooser,
+                  GtkFileFilter * filter)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_file_chooser_add_filter);
+    (*_gtk_file_chooser_add_filter) (chooser, filter);
+}
+
+gchar *gtk_file_chooser_get_filename (GtkFileChooser * chooser)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_file_chooser_get_filename);
+    return (*_gtk_file_chooser_get_filename) (chooser);
+}
+
+GSList *gtk_file_chooser_get_filenames (GtkFileChooser * chooser)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_file_chooser_get_filenames);
+    return (*_gtk_file_chooser_get_filenames) (chooser);
+}
+
+GtkFileFilter *gtk_file_chooser_get_filter (GtkFileChooser * chooser)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_file_chooser_get_filter);
+    return (*_gtk_file_chooser_get_filter) (chooser);
+}
+
+GType gtk_file_chooser_get_type (void)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_file_chooser_get_type);
+    return (*_gtk_file_chooser_get_type) ();
+}
+
+gboolean gtk_file_chooser_set_current_folder (GtkFileChooser * chooser,
+                          const gchar * filename)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_file_chooser_set_current_folder);
+    return (*_gtk_file_chooser_set_current_folder) (chooser, filename);
+}
+
+void gtk_file_chooser_set_current_name (GtkFileChooser * chooser,
+                    const gchar * name)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_file_chooser_set_current_name);
+    (*_gtk_file_chooser_set_current_name) (chooser, name);
+}
+
+void gtk_file_chooser_set_do_overwrite_confirmation (GtkFileChooser * chooser,
+                             gboolean
+                             do_overwrite_confirmation)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_file_chooser_set_do_overwrite_confirmation);
+    (*_gtk_file_chooser_set_do_overwrite_confirmation) (chooser,
+                            do_overwrite_confirmation);
+}
+
+void gtk_file_chooser_set_filter (GtkFileChooser * chooser,
+                  GtkFileFilter * filter)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_file_chooser_set_filter);
+    (*_gtk_file_chooser_set_filter) (chooser, filter);
+}
+
+void gtk_file_chooser_set_select_multiple (GtkFileChooser * chooser,
+                       gboolean select_multiple)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_file_chooser_set_select_multiple);
+    return (*_gtk_file_chooser_set_select_multiple) (chooser,
+                             select_multiple);
+}
+
+
+void gtk_file_filter_add_pattern (GtkFileFilter * filter,
+                  const gchar * pattern)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_file_filter_add_pattern);
+    (*_gtk_file_filter_add_pattern) (filter, pattern);
+}
+
+GtkFileFilter *gtk_file_filter_new (void)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_file_filter_new);
+    return (*_gtk_file_filter_new) ();
+}
+
+void gtk_file_filter_set_name (GtkFileFilter * filter, const gchar * name)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_file_filter_set_name);
+    return (*_gtk_file_filter_set_name) (filter, name);
+}
+
+GtkWidget *gtk_fixed_new (void)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_fixed_new);
+    return (*_gtk_fixed_new) ();
+}
+
+void gtk_init (int *argc, char ***argv)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_init);
+    (*_gtk_init) (argc, argv);
+}
+
+void gtk_main_do_event (GdkEvent * event)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_main_do_event);
+    (*_gtk_main_do_event) (event);
+}
+
+void gtk_main (void)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_main);
+    (*_gtk_main) ();
+}
+
+gboolean gtk_main_iteration (void)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_main_iteration);
+    return (*_gtk_main_iteration) ();
+}
+
+void gtk_main_quit (void)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_main_quit);
+    (*_gtk_main_quit) ();
+}
+
+GtkWidget *gtk_plug_new (GdkNativeWindow socket_id)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_plug_new);
+    return (*_gtk_plug_new) (socket_id);
+}
+
+void gtk_selection_data_free (GtkSelectionData * data)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_selection_data_free);
+    return (*_gtk_selection_data_free) (data);
+}
+
+const guchar *gtk_selection_data_get_data (GtkSelectionData * selection_data)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_selection_data_get_data);
+    return (*_gtk_selection_data_get_data) (selection_data);
+}
+
+gint gtk_selection_data_get_length (GtkSelectionData * selection_data)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_selection_data_get_length);
+    return (*_gtk_selection_data_get_length) (selection_data);
+}
+
+GdkAtom gtk_selection_data_get_target (GtkSelectionData * selection_data)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_selection_data_get_target);
+    return (*_gtk_selection_data_get_target) (selection_data);
+}
+
+void gtk_selection_data_set (GtkSelectionData * selection_data,
+                 GdkAtom type,
+                 gint format, const guchar * data, gint length)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_selection_data_set);
+    return (*_gtk_selection_data_set) (selection_data, type, format, data,
+                       length);
+}
+
+gboolean gtk_selection_data_set_pixbuf (GtkSelectionData * selection_data,
+                    GdkPixbuf * pixbuf)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_selection_data_set_pixbuf);
+    return (*_gtk_selection_data_set_pixbuf) (selection_data, pixbuf);
+}
+
+gboolean gtk_selection_data_set_text (GtkSelectionData * selection_data,
+                      const gchar * str, gint len)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_selection_data_set_text);
+    return (*_gtk_selection_data_set_text) (selection_data, str, len);
+}
+
+gboolean gtk_selection_data_set_uris (GtkSelectionData * selection_data,
+                      gchar ** uris)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_selection_data_set_uris);
+    return (*_gtk_selection_data_set_uris) (selection_data, uris);
+}
+
+GtkSettings *gtk_settings_get_default (void)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_settings_get_default);
+    return (*_gtk_settings_get_default) ();
+}
+
+void gtk_target_list_add (GtkTargetList * list,
+              GdkAtom target, guint flags, guint info)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_target_list_add);
+    (*_gtk_target_list_add) (list, target, flags, info);
+}
+
+void gtk_target_list_add_image_targets (GtkTargetList * list,
+                    guint info, gboolean writable)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_target_list_add_image_targets);
+    (*_gtk_target_list_add_image_targets) (list, info, writable);
+}
+
+void gtk_target_list_add_text_targets (GtkTargetList * list, guint info)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_target_list_add_text_targets);
+    (*_gtk_target_list_add_text_targets) (list, info);
+}
+
+GtkTargetList *gtk_target_list_new (const GtkTargetEntry * targets,
+                    guint ntargets)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_target_list_new);
+    return (*_gtk_target_list_new) (targets, ntargets);
+}
+
+void gtk_target_list_unref (GtkTargetList * list)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_target_list_unref);
+    (*_gtk_target_list_unref) (list);
+}
+
+gboolean gtk_targets_include_image (GdkAtom * targets,
+                    gint n_targets, gboolean writable)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_targets_include_image);
+    return (*_gtk_targets_include_image) (targets, n_targets, writable);
+}
+
+gboolean gtk_targets_include_text (GdkAtom * targets, gint n_targets)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_targets_include_text);
+    return (*_gtk_targets_include_text) (targets, n_targets);
+}
+
+void gtk_target_table_free (GtkTargetEntry * targets, gint n_targets)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_target_table_free);
+    (*_gtk_target_table_free) (targets, n_targets);
+}
+
+GtkTargetEntry *gtk_target_table_new_from_list (GtkTargetList * list,
+                        gint * n_targets)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_target_table_new_from_list);
+    return (*_gtk_target_table_new_from_list) (list, n_targets);
+}
+
+
+void gtk_widget_destroy (GtkWidget * widget)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_widget_destroy);
+    return (*_gtk_widget_destroy) (widget);
+}
+
+GtkWidget *gtk_widget_get_ancestor (GtkWidget * widget, GType widget_type)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_widget_get_ancestor);
+    return (*_gtk_widget_get_ancestor) (widget, widget_type);
+}
+
+GdkScreen *gtk_widget_get_screen (GtkWidget * widget)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_widget_get_screen);
+    return (*_gtk_widget_get_screen) (widget);
+}
+
+void gtk_widget_get_allocation (GtkWidget * widget,
+                GtkAllocation * allocation)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_widget_get_allocation);
+    (*_gtk_widget_get_allocation) (widget, allocation);
+}
+
+
+
+GType gtk_widget_get_type (void)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_widget_get_type);
+    return (*_gtk_widget_get_type) ();
+}
+
+gboolean gtk_widget_get_visible (GtkWidget * widget)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_widget_get_visible);
+    return (*_gtk_widget_get_visible) (widget);
+}
+
+GdkWindow *gtk_widget_get_window (GtkWidget * widget)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_widget_get_window);
+    return (*_gtk_widget_get_window) (widget);
+}
+
+void gtk_widget_grab_focus (GtkWidget * widget)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_widget_grab_focus);
+    return (*_gtk_widget_grab_focus) (widget);
+}
+
+void gtk_widget_hide (GtkWidget * widget)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_widget_hide);
+    return (*_gtk_widget_hide) (widget);
+}
+
+void gtk_widget_modify_bg (GtkWidget * widget,
+               GtkStateType state, const GdkColor * color)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_widget_modify_bg);
+    return (*_gtk_widget_modify_bg) (widget, state, color);
+}
+
+void gtk_widget_realize (GtkWidget * widget)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_widget_realize);
+    return (*_gtk_widget_realize) (widget);
+}
+
+void gtk_widget_set_app_paintable (GtkWidget * widget, gboolean app_paintable)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_widget_set_app_paintable);
+    return (*_gtk_widget_set_app_paintable) (widget, app_paintable);
+}
+
+void gtk_widget_set_can_focus (GtkWidget * widget, gboolean can_focus)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_widget_set_can_focus);
+    return (*_gtk_widget_set_can_focus) (widget, can_focus);
+}
+
+void gtk_widget_set_events (GtkWidget * widget, gint events)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_widget_set_events);
+    return (*_gtk_widget_set_events) (widget, events);
+}
+
+void gtk_widget_set_size_request (GtkWidget * widget, gint width, gint height)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_widget_set_size_request);
+    return (*_gtk_widget_set_size_request) (widget, width, height);
+}
+
+void gtk_widget_show_all (GtkWidget * widget)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_widget_show_all);
+    return (*_gtk_widget_show_all) (widget);
+}
+
+
+void gtk_window_deiconify (GtkWindow * window)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_window_deiconify);
+    (*_gtk_window_deiconify) (window);
+}
+
+void gtk_window_fullscreen (GtkWindow * window)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_window_fullscreen);
+    (*_gtk_window_fullscreen) (window);
+}
+
+gboolean gtk_window_get_decorated (GtkWindow * window)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_window_get_decorated);
+    return (*_gtk_window_get_decorated) (window);
+}
+
+void gtk_window_get_position (GtkWindow * window,
+                  gint * root_x, gint * root_y)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_window_get_position);
+    (*_gtk_window_get_position) (window, root_x, root_y);
+}
+
+void gtk_window_get_size (GtkWindow * window, gint * width, gint * height)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_window_get_size);
+    (*_gtk_window_get_size) (window, width, height);
+}
+
+GType gtk_window_get_type (void)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_window_get_type);
+    return (*_gtk_window_get_type) ();
+}
+
+void gtk_window_iconify (GtkWindow * window)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_window_iconify);
+    (*_gtk_window_iconify) (window);
+}
+
+void gtk_window_maximize (GtkWindow * window)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_window_maximize);
+    (*_gtk_window_maximize) (window);
+}
+
+void gtk_window_move (GtkWindow * window, gint x, gint y)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_window_move);
+    (*_gtk_window_move) (window, x, y);
+}
+
+GtkWidget *gtk_window_new (GtkWindowType type)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_window_new);
+    return (*_gtk_window_new) (type);
+}
+
+void gtk_window_present (GtkWindow * window)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_window_present);
+    (*_gtk_window_present) (window);
+}
+
+void gtk_window_resize (GtkWindow * window, gint width, gint height)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_window_resize);
+    (*_gtk_window_resize) (window, width, height);
+}
+
+void gtk_window_set_accept_focus (GtkWindow * window, gboolean setting)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_window_set_accept_focus);
+    return (*_gtk_window_set_accept_focus) (window, setting);
+}
+
+void gtk_window_set_decorated (GtkWindow * window, gboolean setting)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_window_set_decorated);
+    (*_gtk_window_set_decorated) (window, setting);
+}
+
+void gtk_window_set_geometry_hints (GtkWindow * window,
+                    GtkWidget * geometry_widget,
+                    GdkGeometry * geometry,
+                    GdkWindowHints geom_mask)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_window_set_geometry_hints);
+    (*_gtk_window_set_geometry_hints) (window, geometry_widget, geometry,
+                       geom_mask);
+}
+
+void gtk_window_set_icon (GtkWindow * window, GdkPixbuf * icon)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_window_set_icon);
+    (*_gtk_window_set_icon) (window, icon);
+}
+
+void gtk_window_set_keep_above (GtkWindow * window, gboolean setting)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_window_set_keep_above);
+    (*_gtk_window_set_keep_above) (window, setting);
+}
+
+void gtk_window_set_keep_below (GtkWindow * window, gboolean setting)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_window_set_keep_below);
+    (*_gtk_window_set_keep_below) (window, setting);
+}
+
+void gtk_window_set_modal (GtkWindow * window, gboolean modal)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_window_set_modal);
+    (*_gtk_window_set_modal) (window, modal);
+}
+
+void gtk_window_set_opacity (GtkWindow * window, gdouble opacity)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_window_set_opacity);
+    (*_gtk_window_set_opacity) (window, opacity);
+}
+
+void gtk_window_set_title (GtkWindow * window, const gchar * title)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_window_set_title);
+    (*_gtk_window_set_title) (window, title);
+}
+
+void gtk_window_set_transient_for (GtkWindow * window, GtkWindow * parent)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_window_set_transient_for);
+    (*_gtk_window_set_transient_for) (window, parent);
+}
+
+void gtk_window_set_type_hint (GtkWindow * window, GdkWindowTypeHint hint)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_window_set_type_hint);
+    (*_gtk_window_set_type_hint) (window, hint);
+}
+
+void gtk_window_set_wmclass (GtkWindow * window,
+                 const gchar * wmclass_name,
+                 const gchar * wmclass_class)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_window_set_wmclass);
+    (*_gtk_window_set_wmclass) (window, wmclass_name, wmclass_class);
+}
+
+void gtk_window_unfullscreen (GtkWindow * window)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_window_unfullscreen);
+    (*_gtk_window_unfullscreen) (window);
+}
+
+void gtk_window_unmaximize (GtkWindow * window)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_window_unmaximize);
+    return (*_gtk_window_unmaximize) (window);
+}
+
+//--------------------------------------------------------------------------------------
+
+void gtk_widget_set_colormap (GtkWidget * widget,
+    // 2 only
+                     GdkColormap * colormap)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_widget_set_colormap);
+    (*_gtk_widget_set_colormap) (widget, colormap);
+}
+
+//-------- GTK 3 only -------------------------------------------
+
+void gtk_widget_shape_combine_region (GtkWidget *widget,
+                             cairo_region_t *region)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_widget_shape_combine_region);
+    (*_gtk_widget_shape_combine_region)(widget, region);
+}
+
+void gtk_widget_input_shape_combine_region (GtkWidget *widget,
+                                       cairo_region_t *region)
+{
+    CHECK_LOAD_SYMBOL_GTK (gtk_widget_input_shape_combine_region);
+    (*_gtk_widget_input_shape_combine_region)(widget, region);
+}
+
+//-------- Glass utility ----------------------------------------
+
+void
+glass_widget_set_visual(GtkWidget *widget, GdkVisual *visual)
+{
+    if (wrapper_gtk_version == 2) {
+        CHECK_LOAD_SYMBOL_GTK (gtk_widget_set_colormap);
+        GdkColormap *colormap = gdk_colormap_new(visual, TRUE); //2.0 only
+        (*_gtk_widget_set_colormap) (widget, colormap);
+    } else { // v3.0
+        CHECK_LOAD_SYMBOL_GTK (gtk_widget_set_visual);
+        (*_gtk_widget_set_visual) (widget, visual);
+    }
+}
+
+GtkWidget *
+glass_file_chooser_dialog (const gchar * title,
+                           GtkWindow * parent,
+                           GtkFileChooserAction action,
+                           const gchar *action_text
+       ) {
+
+    // Note: wrapped because G_GNUC_NULL_TERMINATED
+
+    CHECK_LOAD_SYMBOL_GTK (gtk_file_chooser_dialog_new);
+    return (*_gtk_file_chooser_dialog_new)(title,
+        parent,
+        action,
+
+        GTK_STOCK_CANCEL,
+        GTK_RESPONSE_CANCEL,
+
+        action_text,
+        GTK_RESPONSE_ACCEPT,
+
+        NULL);
+
+    return NULL;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/native-glass/gtk/wrapper_main.c	Fri May 06 19:50:10 2016 -0400
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <linux/fb.h>
+#include <fcntl.h>
+#ifndef __USE_GNU       // required for dladdr() & Dl_info
+#define __USE_GNU
+#endif
+#include <dlfcn.h>
+#include <sys/ioctl.h>
+
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+
+#include <assert.h>
+
+#include <gtk/gtk.h>
+
+#include "glass_wrapper.h"
+
+int wrapper_debug = 0; // enable for development only
+int wrapper_loaded = 0;
+int wrapper_gtk_version = 0;
+int wrapper_gtk_versionDebug = 0;
+
+// our library combinations defined
+// "version" "libgtk", "libdgdk", "libpixbuf"
+// note that currently only the first char of the version is used
+static char * gtk2_versioned[] = {
+   "2", "libgtk-x11-2.0.so.0", "libgdk-x11-2.0.so.0", "libgdk_pixbuf-2.0.so"
+};
+
+static char * gtk2_not_versioned[] = {
+   "2", "libgtk-x11-2.0.so", "libgdk-x11-2.0.so", "libgdk_pixbuf-2.0.so"
+};
+
+static char * gtk3_versioned[] = {
+   "3", "libgtk-3.so.0", "libgdk-3.so.0", "libgdk_pixbuf-2.0.so.0"
+};
+
+static char * gtk3_not_versioned[] = {
+   "3", "libgtk-3.so", "libgdk-3.so", "libgdk_pixbuf-2.0.so"
+};
+
+// our library set orders defined, null terminated
+static char ** two_to_three[] = {
+    gtk2_versioned, gtk2_not_versioned,
+    gtk3_versioned, gtk3_not_versioned,
+    0
+};
+
+static char ** three_to_two[] = {
+    gtk3_versioned, gtk3_not_versioned,
+    gtk2_versioned, gtk2_not_versioned,
+    0
+};
+
+static int try_opening_libraries(char *names[3], void** gtk, void** gdk, void ** pix)
+{
+    *gtk = dlopen (names[1], RTLD_LAZY | RTLD_GLOBAL);
+    if (!*gtk) {
+        if (wrapper_gtk_versionDebug) {
+            fprintf(stderr, "failed to load %s\n", names[1]);
+        }
+        return 0;
+    }
+
+    *gdk = dlopen (names[2], RTLD_LAZY | RTLD_GLOBAL);
+    if (!*gdk) {
+        if (wrapper_gtk_versionDebug) {
+            fprintf(stderr, "failed to load %s\n", names[2]);
+        }
+        dlclose(*gtk);
+        *gtk = 0;
+        return 0;
+    }
+
+    *pix = dlopen (names[3], RTLD_LAZY | RTLD_GLOBAL);
+    if (!*pix) {
+        if (wrapper_gtk_versionDebug) {
+            fprintf(stderr, "failed to load %s\n", names[3]);
+        }
+        dlclose(*gtk);
+        dlclose(*gdk);
+        *gtk = *gdk = 0;
+        return 0;
+    }
+
+    return 1;
+}
+
+int wrapper_load_symbols(int version, int verbose) {
+    if (wrapper_loaded) {
+        return wrapper_gtk_version;
+    }
+
+    wrapper_gtk_versionDebug = verbose;
+
+    void *libgtk = 0, *libgdk = 0, *libpix = 0;
+
+    int success = 1;
+    char *** use_chain;
+
+    if (version == 3) {
+        use_chain = three_to_two;
+        wrapper_gtk_version = 3;
+    } else if (version == 0 || version == 2) {
+        use_chain = two_to_three;
+        wrapper_gtk_version = 2;
+    } else {
+        // should never happen, java should pass validated values
+        fprintf(stderr, "Unrecognized GTK version requested, falling back to v 2.0\n");
+        fflush(stderr);
+        use_chain = two_to_three;
+        wrapper_gtk_version = 2;
+    }
+
+    if (wrapper_gtk_versionDebug) {
+        fprintf(stderr, "Loading GTK libraries version %d\n", version);
+    }
+
+    int i, found = 0;
+    for(i = 0; use_chain[i] && !found; i++) {
+        if (wrapper_gtk_versionDebug) {
+            printf("trying GTK library set %s, %s, %s\n",
+                 use_chain[i][1],
+                 use_chain[i][2],
+                 use_chain[i][3]);
+        }
+        found = try_opening_libraries(use_chain[i], &libgtk, &libgdk, &libpix);
+
+        if (found) {
+            if (use_chain[i][0][0] == '2') {
+                wrapper_gtk_version = 2;
+            } else { // (use_chain[i][1][0] == '3') {
+                wrapper_gtk_version = 3;
+            }
+
+            if (wrapper_load_symbols_gtk(wrapper_gtk_version, libgtk) != 0) {
+                found = 0;
+            } else if (wrapper_load_symbols_gdk(wrapper_gtk_version, libgdk) != 0) {
+                found = 0;
+            } else if (wrapper_load_symbols_pix(wrapper_gtk_version, libpix) != 0) {
+                found = 0;
+            }
+        }
+
+        if (!found) {
+            if (libgtk) dlclose(libgtk);
+            if (libgdk) dlclose(libgdk);
+            if (libpix) dlclose(libpix);
+        }
+    }
+
+    if (found) {
+        if (wrapper_gtk_versionDebug) {
+            i--;
+            printf("using GTK library set %s, %s, %s\n",
+                 use_chain[i][1],
+                 use_chain[i][2],
+                 use_chain[i][3]);
+        }
+    } else {
+        return -1;
+    }
+
+    wrapper_loaded = 1;
+
+    return wrapper_gtk_version;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/graphics/src/main/native-glass/gtk/wrapper_pix.c	Fri May 06 19:50:10 2016 -0400
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <linux/fb.h>
+#include <fcntl.h>
+#ifndef __USE_GNU       // required for dladdr() & Dl_info
+#define __USE_GNU
+#endif
+#include <dlfcn.h>
+#include <sys/ioctl.h>
+
+#include <string.h>
+#include <strings.h>
+
+#include <assert.h>
+
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+
+#include "glass_wrapper.h"
+
+static GdkPixbuf *(*_gdk_pixbuf_add_alpha) (const GdkPixbuf * pixbuf,
+                        gboolean substitute_color,
+                        guchar r, guchar g, guchar b);
+static gboolean (*_gdk_pixbuf_get_has_alpha) (const GdkPixbuf * pixbuf);
+static int (*_gdk_pixbuf_get_height) (const GdkPixbuf * pixbuf);
+static guchar *(*_gdk_pixbuf_get_pixels) (const GdkPixbuf * pixbuf);
+static int (*_gdk_pixbuf_get_rowstride) (const GdkPixbuf * pixbuf);
+static GType (*_gdk_pixbuf_get_type) (void) G_GNUC_CONST;
+static int (*_gdk_pixbuf_get_width) (const GdkPixbuf * pixbuf);
+static GdkPixbuf *(*_gdk_pixbuf_new_from_data) (const guchar * data,
+                        GdkColorspace colorspace,
+                        gboolean has_alpha,
+                        int bits_per_sample,
+                        int width, int height,
+                        int rowstride,
+                        GdkPixbufDestroyNotify
+                        destroy_fn,
+                        gpointer destroy_fn_data);
+static GdkPixbuf *(*_gdk_pixbuf_new_from_stream) (GInputStream * stream,
+                          GCancellable * cancellable,
+                          GError ** error);
+static GdkPixbuf *(*_gdk_pixbuf_scale_simple) (const GdkPixbuf * src,
+                           int dest_width,
+                           int dest_height,
+                           GdkInterpType interp_type);
+static gboolean (*_gdk_pixbuf_save_to_buffer) (GdkPixbuf * pixbuf,
+                           gchar ** buffer,
+                           gsize * buffer_size,
+                           const char *type,
+                           GError ** error,
+                           ...) G_GNUC_NULL_TERMINATED;
+
+/***************************************************************************/
+
+#define PRELOAD_SYMBOL_PIX(x) \
+    _##x = dlsym(libpix,#x); \
+    if (!_##x) { \
+        symbol_load_errors++; \
+        fprintf(stderr,"failed loading %s\n",#x); \
+    }
+
+int wrapper_load_symbols_pix (int version, void *libpix)
+{
+    int symbol_load_errors = 0;
+    (void) version; // currently not needed
+
+    PRELOAD_SYMBOL_PIX (gdk_pixbuf_add_alpha);
+    PRELOAD_SYMBOL_PIX (gdk_pixbuf_get_has_alpha);
+    PRELOAD_SYMBOL_PIX (gdk_pixbuf_get_height);
+    PRELOAD_SYMBOL_PIX (gdk_pixbuf_get_pixels);
+    PRELOAD_SYMBOL_PIX (gdk_pixbuf_get_rowstride);
+    PRELOAD_SYMBOL_PIX (gdk_pixbuf_get_type);
+    PRELOAD_SYMBOL_PIX (gdk_pixbuf_get_width);
+    PRELOAD_SYMBOL_PIX (gdk_pixbuf_new_from_data);
+    PRELOAD_SYMBOL_PIX (gdk_pixbuf_new_from_stream);
+    PRELOAD_SYMBOL_PIX (gdk_pixbuf_scale_simple);
+    PRELOAD_SYMBOL_PIX (gdk_pixbuf_save_to_buffer);
+
+    if (symbol_load_errors && wrapper_debug)
+    {
+      fprintf (stderr, "failed to load %d pix symbols",
+           symbol_load_errors);
+    }
+
+    return symbol_load_errors;
+}
+
+#define CHECK_LOAD_SYMBOL_PIX(x) \
+    { \
+        if (!_##x) { \
+            if (wrapper_debug) fprintf(stderr,"missing %s\n", #x); \
+            assert(_##x); \
+        } else { \
+            if (wrapper_debug) { \
+               fprintf(stderr,"using %s\n",#x); \
+               fflush(stderr); \
+            } \
+        } \
+    }
+
+GdkPixbuf *gdk_pixbuf_add_alpha (const GdkPixbuf * pixbuf,
+                 gboolean substitute_color, guchar r,
+                 guchar g, guchar b)
+{
+    CHECK_LOAD_SYMBOL_PIX (gdk_pixbuf_add_alpha);
+    return (*_gdk_pixbuf_add_alpha) (pixbuf, substitute_color, r, g, b);
+}
+
+gboolean gdk_pixbuf_get_has_alpha (const GdkPixbuf * pixbuf)
+{
+    CHECK_LOAD_SYMBOL_PIX (gdk_pixbuf_get_has_alpha);
+    return (*_gdk_pixbuf_get_has_alpha) (pixbuf);
+}
+
+int gdk_pixbuf_get_height (const GdkPixbuf * pixbuf)
+{
+    CHECK_LOAD_SYMBOL_PIX (gdk_pixbuf_get_height);
+    return (*_gdk_pixbuf_get_height) (pixbuf);
+}
+
+guchar *gdk_pixbuf_get_pixels (const GdkPixbuf * pixbuf)
+{
+    CHECK_LOAD_SYMBOL_PIX (gdk_pixbuf_get_pixels);
+    return (*_gdk_pixbuf_get_pixels) (pixbuf);
+}
+
+int gdk_pixbuf_get_rowstride (const GdkPixbuf * pixbuf)
+{
+    CHECK_LOAD_SYMBOL_PIX (gdk_pixbuf_get_rowstride);
+    return (*_gdk_pixbuf_get_rowstride) (pixbuf);
+}
+
+GType gdk_pixbuf_get_type (void)
+{
+    CHECK_LOAD_SYMBOL_PIX (gdk_pixbuf_get_type);
+    return (*_gdk_pixbuf_get_type) ();
+}
+
+int gdk_pixbuf_get_width (const GdkPixbuf * pixbuf)
+{
+    CHECK_LOAD_SYMBOL_PIX (gdk_pixbuf_get_width);
+    return (*_gdk_pixbuf_get_width) (pixbuf);
+}
+
+GdkPixbuf *gdk_pixbuf_new_from_data (const guchar * data,
+                     GdkColorspace colorspace,
+                     gboolean has_alpha,
+                     int bits_per_sample,
+                     int width, int height,
+                     int rowstride,
+                     GdkPixbufDestroyNotify destroy_fn,
+                     gpointer destroy_fn_data)
+{
+    CHECK_LOAD_SYMBOL_PIX (gdk_pixbuf_new_from_data);
+    return (*_gdk_pixbuf_new_from_data) (data, colorspace, has_alpha,
+                     bits_per_sample, width, height,
+                     rowstride, destroy_fn,
+                     destroy_fn_data);
+}
+
+GdkPixbuf *gdk_pixbuf_new_from_stream (GInputStream * stream,
+                       GCancellable * cancellable,
+                       GError ** error)
+{
+    CHECK_LOAD_SYMBOL_PIX (gdk_pixbuf_new_from_stream);
+    return (*_gdk_pixbuf_new_from_stream) (stream, cancellable, error);
+}
+
+GdkPixbuf *gdk_pixbuf_scale_simple (const GdkPixbuf * src,
+                    int dest_width,
+                    int dest_height,
+                    GdkInterpType interp_type)
+{
+    CHECK_LOAD_SYMBOL_PIX (gdk_pixbuf_scale_simple);
+    return (*_gdk_pixbuf_scale_simple) (src, dest_width, dest_height,
+                    interp_type);
+}
+
+
+//--------------------------------------------------------------------------------------
+
+gboolean glass_gdk_pixbuf_save_to_buffer (GdkPixbuf * pixbuf,
+                    gchar ** buffer,
+                    gsize * buffer_size,
+                    const char *type, GError ** error)
+{
+    // Note: wrapped because G_GNUC_NULL_TERMINATED
+    CHECK_LOAD_SYMBOL_PIX (gdk_pixbuf_save_to_buffer);
+    return (*_gdk_pixbuf_save_to_buffer) (
+            pixbuf, buffer, buffer_size, type,
+                      error, NULL);
+}