1 /*
   2  * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 #include <stdio.h>
  27 #include <stdlib.h>
  28 #include <linux/fb.h>
  29 #include <fcntl.h>
  30 #ifndef __USE_GNU       // required for dladdr() & Dl_info
  31 #define __USE_GNU
  32 #endif
  33 #include <dlfcn.h>
  34 #include <sys/ioctl.h>
  35 
  36 #include <string.h>
  37 #include <strings.h>
  38 
  39 #include <assert.h>
  40 
  41 #include <gdk/gdk.h>
  42 #include <gdk/gdkx.h>
  43 
  44 #include "glass_wrapper.h"
  45 
  46 static GdkAtom (*_gdk_atom_intern) (const gchar * atom_name,
  47                     gboolean only_if_exists);
  48 static GdkAtom (*_gdk_atom_intern_static_string) (const gchar * atom_name);
  49 static gchar *(*_gdk_atom_name) (GdkAtom atom);
  50 static cairo_t *(*_gdk_cairo_create) (GdkDrawable * drawable);
  51 static GdkColormap *(*_gdk_colormap_new) (GdkVisual * visual,
  52                       gboolean allocate);
  53 static GdkCursor *(*_gdk_cursor_new) (GdkCursorType cursor_type);
  54 static GdkCursor *(*_gdk_cursor_new_from_name) (GdkDisplay * display,
  55                         const gchar * name);
  56 static GdkCursor *(*_gdk_cursor_new_from_pixbuf) (GdkDisplay * display,
  57                           GdkPixbuf * pixbuf,
  58                           gint x, gint y);
  59 static GdkDisplay *(*_gdk_display_get_default) (void);
  60 static guint (*_gdk_display_get_default_cursor_size) (GdkDisplay * display);
  61 static void (*_gdk_display_get_pointer) (GdkDisplay * display,
  62                      GdkScreen ** screen,
  63                      gint * x,
  64                      gint * y, GdkModifierType * mask);
  65 static GdkWindow *(*_gdk_display_get_window_at_pointer) (GdkDisplay * display,
  66                              gint * win_x,
  67                              gint * win_y);
  68 static gboolean (*_gdk_display_pointer_is_grabbed) (GdkDisplay * display);
  69 static gboolean (*_gdk_display_supports_composite) (GdkDisplay * display);
  70 static void (*_gdk_drag_abort) (GdkDragContext * context, guint32 time_);
  71 static gboolean (*_gdk_drag_motion) (GdkDragContext * context,
  72                      GdkWindow * dest_window,
  73                      GdkDragProtocol protocol,
  74                      gint x_root,
  75                      gint y_root,
  76                      GdkDragAction suggested_action,
  77                      GdkDragAction possible_actions,
  78                      guint32 time_);
  79 static void (*_gdk_drag_drop) (GdkDragContext * context, guint32 time_);
  80 static GdkDragContext *(*_gdk_drag_begin) (GdkWindow * window,
  81                        GList * targets);
  82 static GdkDragAction (*_gdk_drag_context_get_actions) (GdkDragContext *
  83                                context);
  84 static GdkDragAction (*_gdk_drag_context_get_selected_action) (GdkDragContext
  85                                    * context);
  86 static GdkDragAction (*_gdk_drag_context_get_suggested_action) (GdkDragContext
  87                                 * context);
  88 static GList *(*_gdk_drag_context_list_targets) (GdkDragContext * context);
  89 static void (*_gdk_drag_find_window_for_screen) (GdkDragContext * context,
  90                          GdkWindow * drag_window,
  91                          GdkScreen * screen,
  92                          gint x_root,
  93                          gint y_root,
  94                          GdkWindow ** dest_window,
  95                          GdkDragProtocol * protocol);
  96 static GdkAtom (*_gdk_drag_get_selection) (GdkDragContext * context);
  97 static GdkWindow *(*_gdk_drag_context_get_dest_window) (GdkDragContext *
  98                             context);
  99 static void (*_gdk_drag_status) (GdkDragContext * context,
 100                  GdkDragAction action, guint32 time_);
 101 static void (*_gdk_drop_reply) (GdkDragContext * context, gboolean ok,
 102                 guint32 time_);
 103 static void (*_gdk_drop_finish) (GdkDragContext * context, gboolean success,
 104                  guint32 time_);
 105 static GdkScreen *(*_gdk_window_get_screen) (GdkWindow * window);
 106 static GdkDisplay *(*_gdk_window_get_display) (GdkWindow * window);
 107 static int (*_gdk_window_get_width) (GdkWindow * window);
 108 static int (*_gdk_window_get_height) (GdkWindow * window);
 109 static void (*_gdk_error_trap_push) (void);
 110 static void (*_gdk_event_request_motions) (const GdkEventMotion * event);
 111 static void (*_gdk_event_handler_set) (GdkEventFunc func,
 112                        gpointer data, GDestroyNotify notify);
 113 static GdkWindow *(*_gdk_get_default_root_window) (void);
 114 static GdkKeymap *(*_gdk_keymap_get_default) (void);
 115 static gboolean (*_gdk_keymap_get_entries_for_keyval) (GdkKeymap * keymap,
 116                                guint keyval,
 117                                GdkKeymapKey ** keys,
 118                                gint * n_keys);
 119 static guint (*_gdk_keymap_lookup_key) (GdkKeymap * keymap,
 120                     const GdkKeymapKey * key);
 121 static gboolean (*_gdk_keymap_translate_keyboard_state) (GdkKeymap * keymap,
 122                              guint
 123                              hardware_keycode,
 124                              GdkModifierType
 125                              state, gint group,
 126                              guint * keyval,
 127                              gint *
 128                              effective_group,
 129                              gint * level,
 130                              GdkModifierType *
 131                              consumed_modifiers);
 132 static guint32 (*_gdk_keyval_to_unicode) (guint keyval) G_GNUC_CONST;
 133 static GdkPixbuf *(*_gdk_pixbuf_get_from_drawable) (GdkPixbuf * dest,
 134                             GdkDrawable * src,
 135                             GdkColormap * cmap,
 136                             int src_x,
 137                             int src_y,
 138                             int dest_x,
 139                             int dest_y,
 140                             int width, int height);
 141 static void (*_gdk_pixbuf_render_pixmap_and_mask) (GdkPixbuf * pixbuf,
 142                            GdkPixmap ** pixmap_return,
 143                            GdkBitmap ** mask_return,
 144                            int alpha_threshold);
 145 static void (*_gdk_pixbuf_render_pixmap_and_mask_for_colormap) (GdkPixbuf *
 146                                 pixbuf,
 147                                 GdkColormap *
 148                                 colormap,
 149                                 GdkPixmap **
 150                                 pixmap_return,
 151                                 GdkBitmap **
 152                                 mask_return,
 153                                 int
 154                                 alpha_threshold);
 155 static GdkGrabStatus (*_gdk_pointer_grab) (GdkWindow * window,
 156                        gboolean owner_events,
 157                        GdkEventMask event_mask,
 158                        GdkWindow * confine_to,
 159                        GdkCursor * cursor, guint32 time_);
 160 static void (*_gdk_pointer_ungrab) (guint32 time_);
 161 static void (*_gdk_property_change) (GdkWindow * window,
 162                      GdkAtom property,
 163                      GdkAtom type,
 164                      gint format,
 165                      GdkPropMode mode,
 166                      const guchar * data, gint nelements);
 167 static gboolean (*_gdk_property_get) (GdkWindow * window,
 168                       GdkAtom property,
 169                       GdkAtom type,
 170                       gulong offset,
 171                       gulong length,
 172                       gint pdelete,
 173                       GdkAtom * actual_property_type,
 174                       gint * actual_format,
 175                       gint * actual_length, guchar ** data);
 176 static gboolean (*_gdk_rectangle_intersect) (const GdkRectangle * src1,
 177                          const GdkRectangle * src2,
 178                          GdkRectangle * dest);
 179 static void (*_gdk_region_destroy) (GdkRegion * region);
 180 static GdkRegion *(*_gdk_region_new) (void);
 181 static GdkScreen *(*_gdk_screen_get_default) (void);
 182 static gint (*_gdk_screen_get_height) (GdkScreen * screen);
 183 static gint (*_gdk_screen_get_monitor_at_point) (GdkScreen * screen,
 184                          gint x, gint y);
 185 static void (*_gdk_screen_get_monitor_geometry) (GdkScreen * screen,
 186                          gint monitor_num,
 187                          GdkRectangle * dest);
 188 static gint (*_gdk_screen_get_n_monitors) (GdkScreen * screen);
 189 static gdouble (*_gdk_screen_get_resolution) (GdkScreen * screen);
 190 static GdkColormap *(*_gdk_screen_get_rgba_colormap) (GdkScreen * screen);
 191 static GdkColormap *(*_gdk_screen_get_rgb_colormap) (GdkScreen * screen);
 192 static GdkWindow *(*_gdk_screen_get_root_window) (GdkScreen * screen);
 193 static GdkVisual *(*_gdk_screen_get_system_visual) (GdkScreen * screen);
 194 static gint (*_gdk_screen_get_width) (GdkScreen * screen);
 195 static gboolean (*_gdk_screen_is_composited) (GdkScreen * screen);
 196 static void (*_gdk_selection_convert) (GdkWindow * requestor,
 197                        GdkAtom selection,
 198                        GdkAtom target, guint32 time_);
 199 static gboolean (*_gdk_selection_owner_set) (GdkWindow * owner,
 200                          GdkAtom selection,
 201                          guint32 time_,
 202                          gboolean send_event);
 203 static gint (*_gdk_selection_property_get) (GdkWindow * requestor,
 204                         guchar ** data,
 205                         GdkAtom * prop_type,
 206                         gint * prop_format);
 207 static void (*_gdk_selection_send_notify) (GdkNativeWindow requestor,
 208                        GdkAtom selection,
 209                        GdkAtom target,
 210                        GdkAtom property, guint32 time_);
 211 static guint (*_gdk_unicode_to_keyval) (guint32 wc) G_GNUC_CONST;
 212 static guint (*_gdk_threads_add_idle_full) (gint priority,
 213                         GSourceFunc function,
 214                         gpointer data,
 215                         GDestroyNotify notify);
 216 static guint (*_gdk_threads_add_idle) (GSourceFunc function, gpointer data);
 217 static guint (*_gdk_threads_add_timeout_full) (gint priority,
 218                            guint interval,
 219                            GSourceFunc function,
 220                            gpointer data,
 221                            GDestroyNotify notify);
 222 static void (*_gdk_threads_enter) (void);
 223 static void (*_gdk_threads_init) (void);
 224 static void (*_gdk_threads_leave) (void);
 225 static void (*_gdk_window_destroy) (GdkWindow * window);
 226 static GdkCursor *(*_gdk_window_get_cursor) (GdkWindow * window);
 227 static GdkEventMask (*_gdk_window_get_events) (GdkWindow * window);
 228 static void (*_gdk_window_get_geometry) (GdkWindow * window,
 229                      gint * x,
 230                      gint * y,
 231                      gint * width,
 232                      gint * height, gint * depth);
 233 static gint (*_gdk_window_get_origin) (GdkWindow * window,
 234                        gint * x, gint * y);
 235 static void (*_gdk_window_input_shape_combine_mask) (GdkWindow * window,
 236                              GdkBitmap * mask,
 237                              gint x, gint y);
 238 static void (*_gdk_window_shape_combine_region) (GdkWindow *window,
 239                      const cairo_region_t *shape_region,
 240                       gint offset_x,
 241                       gint offset_y);
 242 static void (*_gdk_window_input_shape_combine_region) (GdkWindow * window,
 243                                const cairo_region_t * shape_region,
 244                                gint offset_x,
 245                                gint offset_y);
 246 static gboolean (*_gdk_window_is_destroyed) (GdkWindow * window);
 247 static void (*_gdk_window_move) (GdkWindow * window, gint x, gint y);
 248 static GdkWindow *(*_gdk_window_new) (GdkWindow * parent,
 249                       GdkWindowAttr * attributes,
 250                       gint attributes_mask);
 251 static void (*_gdk_window_register_dnd) (GdkWindow * window);
 252 static void (*_gdk_window_resize) (GdkWindow * window,
 253                    gint width, gint height);
 254 static void (*_gdk_window_restack) (GdkWindow * window,
 255                     GdkWindow * sibling, gboolean above);
 256 static void (*_gdk_window_set_cursor) (GdkWindow * window,
 257                        GdkCursor * cursor);
 258 static void (*_gdk_window_set_events) (GdkWindow * window,
 259                        GdkEventMask event_mask);
 260 static void (*_gdk_window_set_functions) (GdkWindow * window,
 261                       GdkWMFunction functions);
 262 static void (*_gdk_window_show) (GdkWindow * window);
 263 static Display *(*_gdk_x11_display_get_xdisplay) (GdkDisplay * display);
 264 static XID (*_gdk_x11_drawable_get_xid) (GdkDrawable * drawable);
 265 static gint (*_gdk_x11_get_default_screen) (void);
 266 static Display *(*_gdk_x11_get_default_xdisplay) (void);
 267 static guint32 (*_gdk_x11_get_server_time) (GdkWindow * window);
 268 static GdkVisual *(*_gdk_x11_screen_lookup_visual) (GdkScreen * screen,
 269                             VisualID xvisualid);
 270 static GdkWindow *(*_gdk_x11_window_foreign_new_for_display) (GdkDisplay *
 271                                   display,
 272                                   Window window);
 273 static GdkWindow *(*_gdk_x11_window_lookup_for_display) (GdkDisplay * display,
 274                              Window window);
 275 static gint (*_gdk_visual_get_depth) (GdkVisual * visual);
 276 
 277 static GType (*_gdk_window_object_get_type) (void);
 278 
 279 //----------- GTK 3.0 ------------------------------------------------------
 280 
 281 typedef struct _GdkDeviceManager      GdkDeviceManager;
 282 struct _GdkRGBA
 283 {
 284   gdouble red;
 285   gdouble green;
 286   gdouble blue;
 287   gdouble alpha;
 288 };
 289 typedef struct _GdkRGBA               GdkRGBA;
 290 
 291 typedef enum {
 292   GDK_DEVICE_TYPE_MASTER,
 293   GDK_DEVICE_TYPE_SLAVE,
 294   GDK_DEVICE_TYPE_FLOATING
 295 } GdkDeviceType;
 296 
 297 typedef enum
 298 {
 299   GDK_OWNERSHIP_NONE,
 300   GDK_OWNERSHIP_WINDOW,
 301   GDK_OWNERSHIP_APPLICATION
 302 } GdkGrabOwnership;
 303 
 304 
 305 static GdkVisual *   (*_gdk_window_get_visual) (GdkWindow     *window);
 306 static GdkScreen    *(*_gdk_visual_get_screen) (GdkVisual *visual);
 307 static GList * (*_gdk_device_manager_list_devices) (GdkDeviceManager *device_manager,
 308                                  GdkDeviceType type);
 309 static GdkDeviceManager * (*_gdk_display_get_device_manager) (GdkDisplay *display);
 310 static GdkVisual *  (*_gdk_screen_get_rgba_visual) (GdkScreen   *screen);
 311 static GdkInputSource (*_gdk_device_get_source) (GdkDevice      *device);
 312 static GdkGrabStatus (*_gdk_device_grab) (GdkDevice        *device,
 313                                       GdkWindow        *window,
 314                                       GdkGrabOwnership  grab_ownership,
 315                                       gboolean          owner_events,
 316                                       GdkEventMask      event_mask,
 317                                       GdkCursor        *cursor,
 318                                       guint32           time_);
 319 static void (*_gdk_device_ungrab) (GdkDevice *device, guint32 time_);
 320 static GdkDevice * (*_gdk_device_manager_get_client_pointer) (GdkDeviceManager *device_manager);
 321 static void  (*_gdk_device_get_position) (GdkDevice         *device,
 322                                   GdkScreen        **screen,
 323                                   gint              *x,
 324                                   gint              *y);
 325 static gboolean    (*_gdk_display_device_is_grabbed) (GdkDisplay  *display,
 326                                             GdkDevice   *device);
 327 static GdkWindow * (*_gdk_device_get_window_at_position) (GdkDevice         *device,
 328                                   gint              *win_x,
 329                                   gint              *win_y);
 330 static void (*_gdk_window_set_background) (GdkWindow      *window,
 331                       const GdkColor  *color);
 332 static void (*_gdk_window_set_background_rgba) (GdkWindow     *window,
 333                                               const GdkRGBA *rgba);
 334 static Window   (*_gdk_x11_window_get_xid) (GdkWindow   *window);
 335 
 336 static GdkPixbuf *(*_gdk_pixbuf_get_from_window) (GdkWindow       *window,
 337                                         gint             src_x,
 338                                         gint             src_y,
 339                                         gint             width,
 340                                         gint             height);
 341 
 342 static GType (*_gdk_window_get_type) (void);
 343 
 344 static cairo_region_t * (*_gdk_cairo_region_create_from_surface) (cairo_surface_t *surface);
 345 
 346 /***** Utilities ***********************************************************/
 347 
 348 
 349 #define PRELOAD_SYMBOL_GDK(x) \
 350     _##x = dlsym(libgdk, #x); \
 351     if (_##x == NULL) { \
 352         symbol_load_errors++; \
 353         fprintf(stderr,"failed loading %s\n", #x); \
 354     }
 355 
 356 int wrapper_load_symbols_gdk (int version, void * libgdk)
 357 {
 358     int symbol_load_errors = 0;
 359 
 360     PRELOAD_SYMBOL_GDK (gdk_atom_intern);
 361     PRELOAD_SYMBOL_GDK (gdk_atom_intern_static_string);
 362     PRELOAD_SYMBOL_GDK (gdk_atom_name);
 363     PRELOAD_SYMBOL_GDK (gdk_cairo_create);
 364     PRELOAD_SYMBOL_GDK (gdk_cursor_new);
 365     PRELOAD_SYMBOL_GDK (gdk_cursor_new_from_name);
 366     PRELOAD_SYMBOL_GDK (gdk_cursor_new_from_pixbuf);
 367     PRELOAD_SYMBOL_GDK (gdk_display_get_default);
 368     PRELOAD_SYMBOL_GDK (gdk_display_get_default_cursor_size);
 369     PRELOAD_SYMBOL_GDK (gdk_display_get_pointer);
 370     PRELOAD_SYMBOL_GDK (gdk_display_get_window_at_pointer);
 371     PRELOAD_SYMBOL_GDK (gdk_display_pointer_is_grabbed);
 372     PRELOAD_SYMBOL_GDK (gdk_display_supports_composite);
 373     PRELOAD_SYMBOL_GDK (gdk_drag_abort);
 374     PRELOAD_SYMBOL_GDK (gdk_drag_motion);
 375     PRELOAD_SYMBOL_GDK (gdk_drag_drop);
 376     PRELOAD_SYMBOL_GDK (gdk_drag_begin);
 377     PRELOAD_SYMBOL_GDK (gdk_drag_context_get_actions);
 378     PRELOAD_SYMBOL_GDK (gdk_drag_context_get_selected_action);
 379     PRELOAD_SYMBOL_GDK (gdk_drag_context_get_suggested_action);
 380     PRELOAD_SYMBOL_GDK (gdk_drag_context_list_targets);
 381     PRELOAD_SYMBOL_GDK (gdk_drag_find_window_for_screen);
 382     PRELOAD_SYMBOL_GDK (gdk_drag_get_selection);
 383     PRELOAD_SYMBOL_GDK (gdk_drag_context_get_dest_window);
 384     PRELOAD_SYMBOL_GDK (gdk_drag_status);
 385     PRELOAD_SYMBOL_GDK (gdk_drop_reply);
 386     PRELOAD_SYMBOL_GDK (gdk_drop_finish);
 387     PRELOAD_SYMBOL_GDK (gdk_error_trap_push);
 388     PRELOAD_SYMBOL_GDK (gdk_event_request_motions);
 389     PRELOAD_SYMBOL_GDK (gdk_event_handler_set);
 390     PRELOAD_SYMBOL_GDK (gdk_get_default_root_window);
 391     PRELOAD_SYMBOL_GDK (gdk_keymap_get_default);
 392     PRELOAD_SYMBOL_GDK (gdk_keymap_get_entries_for_keyval);
 393     PRELOAD_SYMBOL_GDK (gdk_keymap_lookup_key);
 394     PRELOAD_SYMBOL_GDK (gdk_keymap_translate_keyboard_state);
 395     PRELOAD_SYMBOL_GDK (gdk_keyval_to_unicode);
 396     PRELOAD_SYMBOL_GDK (gdk_pointer_grab);
 397     PRELOAD_SYMBOL_GDK (gdk_pointer_ungrab);
 398     PRELOAD_SYMBOL_GDK (gdk_property_change);
 399     PRELOAD_SYMBOL_GDK (gdk_property_get);
 400     PRELOAD_SYMBOL_GDK (gdk_rectangle_intersect);
 401     PRELOAD_SYMBOL_GDK (gdk_screen_get_default);
 402     PRELOAD_SYMBOL_GDK (gdk_screen_get_height);
 403     PRELOAD_SYMBOL_GDK (gdk_screen_get_monitor_at_point);
 404     PRELOAD_SYMBOL_GDK (gdk_screen_get_monitor_geometry);
 405     PRELOAD_SYMBOL_GDK (gdk_screen_get_n_monitors);
 406     PRELOAD_SYMBOL_GDK (gdk_screen_get_resolution);
 407     PRELOAD_SYMBOL_GDK (gdk_screen_get_root_window);
 408     PRELOAD_SYMBOL_GDK (gdk_screen_get_system_visual);
 409     PRELOAD_SYMBOL_GDK (gdk_screen_get_width);
 410     PRELOAD_SYMBOL_GDK (gdk_screen_is_composited);
 411     PRELOAD_SYMBOL_GDK (gdk_selection_convert);
 412     PRELOAD_SYMBOL_GDK (gdk_selection_owner_set);
 413     PRELOAD_SYMBOL_GDK (gdk_selection_property_get);
 414     PRELOAD_SYMBOL_GDK (gdk_selection_send_notify);
 415     PRELOAD_SYMBOL_GDK (gdk_unicode_to_keyval);
 416     PRELOAD_SYMBOL_GDK (gdk_threads_add_idle_full);
 417     PRELOAD_SYMBOL_GDK (gdk_threads_add_idle);
 418     PRELOAD_SYMBOL_GDK (gdk_threads_add_timeout_full);
 419     PRELOAD_SYMBOL_GDK (gdk_threads_enter);
 420     PRELOAD_SYMBOL_GDK (gdk_threads_init);
 421     PRELOAD_SYMBOL_GDK (gdk_threads_leave);
 422     PRELOAD_SYMBOL_GDK (gdk_window_destroy);
 423     PRELOAD_SYMBOL_GDK (gdk_window_get_cursor);
 424     PRELOAD_SYMBOL_GDK (gdk_window_get_events);
 425     PRELOAD_SYMBOL_GDK (gdk_window_get_geometry);
 426     PRELOAD_SYMBOL_GDK (gdk_window_get_origin);
 427     PRELOAD_SYMBOL_GDK (gdk_window_is_destroyed);
 428     PRELOAD_SYMBOL_GDK (gdk_window_move);
 429     PRELOAD_SYMBOL_GDK (gdk_window_new);
 430     PRELOAD_SYMBOL_GDK (gdk_window_register_dnd);
 431     PRELOAD_SYMBOL_GDK (gdk_window_resize);
 432     PRELOAD_SYMBOL_GDK (gdk_window_restack);
 433     PRELOAD_SYMBOL_GDK (gdk_window_set_cursor);
 434     PRELOAD_SYMBOL_GDK (gdk_window_set_events);
 435     PRELOAD_SYMBOL_GDK (gdk_window_set_functions);
 436     PRELOAD_SYMBOL_GDK (gdk_window_show);
 437     PRELOAD_SYMBOL_GDK (gdk_x11_display_get_xdisplay);
 438     PRELOAD_SYMBOL_GDK (gdk_x11_get_default_screen);
 439     PRELOAD_SYMBOL_GDK (gdk_x11_get_default_xdisplay);
 440     PRELOAD_SYMBOL_GDK (gdk_x11_get_server_time);
 441     PRELOAD_SYMBOL_GDK (gdk_x11_screen_lookup_visual);
 442     PRELOAD_SYMBOL_GDK (gdk_x11_window_foreign_new_for_display);
 443     PRELOAD_SYMBOL_GDK (gdk_x11_window_lookup_for_display);
 444     PRELOAD_SYMBOL_GDK (gdk_window_get_display);
 445     PRELOAD_SYMBOL_GDK (gdk_window_get_height);
 446     PRELOAD_SYMBOL_GDK (gdk_window_get_width);
 447     PRELOAD_SYMBOL_GDK (gdk_window_get_screen);
 448     PRELOAD_SYMBOL_GDK (gdk_visual_get_screen); // 2.2
 449 
 450     if (version == 2) {
 451         PRELOAD_SYMBOL_GDK (gdk_colormap_new);
 452         PRELOAD_SYMBOL_GDK (gdk_pixbuf_get_from_drawable);
 453         PRELOAD_SYMBOL_GDK (gdk_pixbuf_render_pixmap_and_mask);
 454         PRELOAD_SYMBOL_GDK (gdk_pixbuf_render_pixmap_and_mask_for_colormap);
 455         PRELOAD_SYMBOL_GDK (gdk_region_destroy);
 456         PRELOAD_SYMBOL_GDK (gdk_region_new);
 457         PRELOAD_SYMBOL_GDK (gdk_screen_get_rgba_colormap);
 458         PRELOAD_SYMBOL_GDK (gdk_screen_get_rgb_colormap);
 459         PRELOAD_SYMBOL_GDK (gdk_window_input_shape_combine_mask);
 460         PRELOAD_SYMBOL_GDK (gdk_x11_drawable_get_xid);
 461         PRELOAD_SYMBOL_GDK (gdk_window_object_get_type);
 462         PRELOAD_SYMBOL_GDK (gdk_visual_get_depth);
 463     }
 464 
 465     if (version == 3) {
 466         // gtk version 3 unique symbols
 467         PRELOAD_SYMBOL_GDK (gdk_window_get_visual);  // both
 468         PRELOAD_SYMBOL_GDK (gdk_device_manager_list_devices); //both
 469         PRELOAD_SYMBOL_GDK (gdk_display_get_device_manager);
 470         PRELOAD_SYMBOL_GDK (gdk_screen_get_rgba_visual);
 471         PRELOAD_SYMBOL_GDK (gdk_device_get_source); // both
 472         PRELOAD_SYMBOL_GDK (gdk_device_grab);
 473         PRELOAD_SYMBOL_GDK (gdk_device_ungrab);
 474         PRELOAD_SYMBOL_GDK (gdk_device_manager_get_client_pointer)
 475         PRELOAD_SYMBOL_GDK (gdk_device_get_position)
 476         PRELOAD_SYMBOL_GDK (gdk_display_device_is_grabbed)
 477         PRELOAD_SYMBOL_GDK (gdk_device_get_window_at_position)
 478         PRELOAD_SYMBOL_GDK (gdk_window_set_background_rgba)
 479         PRELOAD_SYMBOL_GDK (gdk_x11_window_get_xid);
 480         PRELOAD_SYMBOL_GDK (gdk_pixbuf_get_from_window);
 481         PRELOAD_SYMBOL_GDK (gdk_window_get_type);
 482         PRELOAD_SYMBOL_GDK (gdk_cairo_region_create_from_surface);
 483         PRELOAD_SYMBOL_GDK (gdk_window_shape_combine_region);
 484         PRELOAD_SYMBOL_GDK (gdk_window_input_shape_combine_region);
 485     }
 486 
 487     if (symbol_load_errors && wrapper_debug) {
 488         fprintf (stderr, "failed to load %d gdk symbols", symbol_load_errors);
 489     }
 490 
 491     return symbol_load_errors;
 492 
 493 }
 494 
 495 #define CHECK_LOAD_SYMBOL_GDK(x) \
 496     { \
 497         if (!_##x) { \
 498             if (wrapper_debug) fprintf(stderr,"missing %s\n", #x); \
 499             assert(_##x); \
 500         } else { \
 501             if (wrapper_debug) { \
 502                fprintf(stderr,"using %s\n", #x); \
 503                fflush(stderr); \
 504             } \
 505         } \
 506     }
 507 
 508 
 509 GdkAtom gdk_atom_intern (const gchar * atom_name, gboolean only_if_exists)
 510 {
 511     CHECK_LOAD_SYMBOL_GDK (gdk_atom_intern);
 512     return (*_gdk_atom_intern) (atom_name, only_if_exists);
 513 }
 514 
 515 GdkAtom gdk_atom_intern_static_string (const gchar * atom_name)
 516 {
 517     CHECK_LOAD_SYMBOL_GDK (gdk_atom_intern_static_string);
 518     return (*_gdk_atom_intern_static_string) (atom_name);
 519 }
 520 
 521 gchar *gdk_atom_name (GdkAtom atom)
 522 {
 523     CHECK_LOAD_SYMBOL_GDK (gdk_atom_name);
 524     return (*_gdk_atom_name) (atom);
 525 }
 526 
 527 cairo_t *gdk_cairo_create (GdkDrawable * drawable)
 528 {
 529     CHECK_LOAD_SYMBOL_GDK (gdk_cairo_create);
 530     return (*_gdk_cairo_create) (drawable);
 531 }
 532 
 533 GdkColormap *gdk_colormap_new (GdkVisual * visual, gboolean allocate)
 534 {
 535     CHECK_LOAD_SYMBOL_GDK (gdk_colormap_new);
 536     return (*_gdk_colormap_new) (visual, allocate);
 537 }
 538 
 539 GdkCursor *gdk_cursor_new (GdkCursorType cursor_type)
 540 {
 541     CHECK_LOAD_SYMBOL_GDK (gdk_cursor_new);
 542     return (*_gdk_cursor_new) (cursor_type);
 543 }
 544 
 545 GdkCursor *gdk_cursor_new_from_name (GdkDisplay * display, const gchar * name)
 546 {
 547     CHECK_LOAD_SYMBOL_GDK (gdk_cursor_new_from_name);
 548     return (*_gdk_cursor_new_from_name) (display, name);
 549 }
 550 
 551 GdkCursor *gdk_cursor_new_from_pixbuf (GdkDisplay * display,
 552                        GdkPixbuf * pixbuf, gint x, gint y)
 553 {
 554     CHECK_LOAD_SYMBOL_GDK (gdk_cursor_new_from_pixbuf);
 555     return (*_gdk_cursor_new_from_pixbuf) (display, pixbuf, x, y);
 556 }
 557 
 558 GdkDisplay *gdk_display_get_default (void)
 559 {
 560     CHECK_LOAD_SYMBOL_GDK (gdk_display_get_default);
 561     return (*_gdk_display_get_default) ();
 562 }
 563 
 564 guint gdk_display_get_default_cursor_size (GdkDisplay * display)
 565 {
 566     CHECK_LOAD_SYMBOL_GDK (gdk_display_get_default_cursor_size);
 567     return (*_gdk_display_get_default_cursor_size) (display);
 568 }
 569 
 570 void gdk_display_get_pointer (GdkDisplay * display,
 571                   GdkScreen ** screen,
 572                   gint * x, gint * y, GdkModifierType * mask)
 573 {
 574     CHECK_LOAD_SYMBOL_GDK (gdk_display_get_pointer);
 575     (*_gdk_display_get_pointer) (display, screen, x, y, mask);
 576 }
 577 
 578 GdkWindow *gdk_display_get_window_at_pointer (GdkDisplay * display,
 579                           gint * win_x, gint * win_y)
 580 {
 581     CHECK_LOAD_SYMBOL_GDK (gdk_display_get_window_at_pointer);
 582     return (*_gdk_display_get_window_at_pointer) (display, win_x, win_y);
 583 }
 584 
 585 gboolean gdk_display_pointer_is_grabbed (GdkDisplay * display)
 586 {
 587     CHECK_LOAD_SYMBOL_GDK (gdk_display_pointer_is_grabbed);
 588     return (*_gdk_display_pointer_is_grabbed) (display);
 589 }
 590 
 591 gboolean gdk_display_supports_composite (GdkDisplay * display)
 592 {
 593     CHECK_LOAD_SYMBOL_GDK (gdk_display_supports_composite);
 594     return (*_gdk_display_supports_composite) (display);
 595 }
 596 
 597 void gdk_drag_abort (GdkDragContext * context, guint32 time_)
 598 {
 599     CHECK_LOAD_SYMBOL_GDK (gdk_drag_abort);
 600     (*_gdk_drag_abort) (context, time_);
 601 }
 602 
 603 gboolean gdk_drag_motion (GdkDragContext * context,
 604               GdkWindow * dest_window,
 605               GdkDragProtocol protocol,
 606               gint x_root,
 607               gint y_root,
 608               GdkDragAction suggested_action,
 609               GdkDragAction possible_actions, guint32 time_)
 610 {
 611     CHECK_LOAD_SYMBOL_GDK (gdk_drag_motion);
 612     return (*_gdk_drag_motion) (context, dest_window, protocol, x_root,
 613                 y_root, suggested_action, possible_actions,
 614                 time_);
 615 }
 616 
 617 void gdk_drag_drop (GdkDragContext * context, guint32 time_)
 618 {
 619     CHECK_LOAD_SYMBOL_GDK (gdk_drag_drop);
 620     (*_gdk_drag_drop) (context, time_);
 621 }
 622 
 623 GdkDragContext *gdk_drag_begin (GdkWindow * window, GList * targets)
 624 {
 625     CHECK_LOAD_SYMBOL_GDK (gdk_drag_begin);
 626     return (*_gdk_drag_begin) (window, targets);
 627 }
 628 
 629 GdkDragAction gdk_drag_context_get_actions (GdkDragContext * context)
 630 {
 631     CHECK_LOAD_SYMBOL_GDK (gdk_drag_context_get_actions);
 632     return (*_gdk_drag_context_get_actions) (context);
 633 }
 634 
 635 GdkDragAction gdk_drag_context_get_selected_action (GdkDragContext * context)
 636 {
 637     CHECK_LOAD_SYMBOL_GDK (gdk_drag_context_get_selected_action);
 638     return (*_gdk_drag_context_get_selected_action) (context);
 639 }
 640 
 641 GdkDragAction gdk_drag_context_get_suggested_action (GdkDragContext * context)
 642 {
 643     CHECK_LOAD_SYMBOL_GDK (gdk_drag_context_get_suggested_action);
 644     return (*_gdk_drag_context_get_suggested_action) (context);
 645 }
 646 
 647 GList *gdk_drag_context_list_targets (GdkDragContext * context)
 648 {
 649     CHECK_LOAD_SYMBOL_GDK (gdk_drag_context_list_targets);
 650     return (*_gdk_drag_context_list_targets) (context);
 651 }
 652 
 653 void gdk_drag_find_window_for_screen (GdkDragContext * context,
 654                       GdkWindow * drag_window,
 655                       GdkScreen * screen,
 656                       gint x_root,
 657                       gint y_root,
 658                       GdkWindow ** dest_window,
 659                       GdkDragProtocol * protocol)
 660 {
 661     CHECK_LOAD_SYMBOL_GDK (gdk_drag_find_window_for_screen);
 662     (*_gdk_drag_find_window_for_screen) (context, drag_window, screen, x_root,
 663                      y_root, dest_window, protocol);
 664 }
 665 
 666 GdkAtom gdk_drag_get_selection (GdkDragContext * context)
 667 {
 668     CHECK_LOAD_SYMBOL_GDK (gdk_drag_get_selection);
 669     return (*_gdk_drag_get_selection) (context);
 670 }
 671 
 672 GdkWindow *gdk_drag_context_get_dest_window (GdkDragContext * context)
 673 {
 674     CHECK_LOAD_SYMBOL_GDK (gdk_drag_context_get_dest_window);
 675     return (*_gdk_drag_context_get_dest_window) (context);
 676 }
 677 
 678 void gdk_drag_status (GdkDragContext * context,
 679               GdkDragAction action, guint32 time_)
 680 {
 681     CHECK_LOAD_SYMBOL_GDK (gdk_drag_status);
 682     (*_gdk_drag_status) (context, action, time_);
 683 }
 684 
 685 void gdk_drop_reply (GdkDragContext * context, gboolean ok, guint32 time_)
 686 {
 687     CHECK_LOAD_SYMBOL_GDK (gdk_drop_reply);
 688     (*_gdk_drop_reply) (context, ok, time_);
 689 }
 690 
 691 void gdk_drop_finish (GdkDragContext * context,
 692               gboolean success, guint32 time_)
 693 {
 694     CHECK_LOAD_SYMBOL_GDK (gdk_drop_finish);
 695     (*_gdk_drop_finish) (context, success, time_);
 696 }
 697 
 698 void gdk_error_trap_push (void)
 699 {
 700     CHECK_LOAD_SYMBOL_GDK (gdk_error_trap_push);
 701     return (*_gdk_error_trap_push) ();
 702 }
 703 
 704 void gdk_event_request_motions (const GdkEventMotion * event)
 705 {
 706     CHECK_LOAD_SYMBOL_GDK (gdk_event_request_motions);
 707     (*_gdk_event_request_motions) (event);
 708 }
 709 
 710 void gdk_event_handler_set (GdkEventFunc func,
 711                 gpointer data, GDestroyNotify notify)
 712 {
 713     CHECK_LOAD_SYMBOL_GDK (gdk_event_handler_set);
 714     (*_gdk_event_handler_set) (func, data, notify);
 715 }
 716 
 717 GdkWindow *gdk_get_default_root_window (void)
 718 {
 719     CHECK_LOAD_SYMBOL_GDK (gdk_get_default_root_window);
 720     return (*_gdk_get_default_root_window) ();
 721 }
 722 
 723 GdkKeymap *gdk_keymap_get_default (void)
 724 {
 725     CHECK_LOAD_SYMBOL_GDK (gdk_keymap_get_default);
 726     return (*_gdk_keymap_get_default) ();
 727 }
 728 
 729 gboolean gdk_keymap_get_entries_for_keyval (GdkKeymap * keymap,
 730                         guint keyval,
 731                         GdkKeymapKey ** keys,
 732                         gint * n_keys)
 733 {
 734     CHECK_LOAD_SYMBOL_GDK (gdk_keymap_get_entries_for_keyval);
 735     return (*_gdk_keymap_get_entries_for_keyval) (keymap, keyval, keys,
 736                           n_keys);
 737 }
 738 
 739 guint gdk_keymap_lookup_key (GdkKeymap * keymap, const GdkKeymapKey * key)
 740 {
 741     CHECK_LOAD_SYMBOL_GDK (gdk_keymap_lookup_key);
 742     return (*_gdk_keymap_lookup_key) (keymap, key);
 743 }
 744 
 745 gboolean gdk_keymap_translate_keyboard_state (GdkKeymap * keymap,
 746                           guint hardware_keycode,
 747                           GdkModifierType state,
 748                           gint group,
 749                           guint * keyval,
 750                           gint * effective_group,
 751                           gint * level,
 752                           GdkModifierType *
 753                           consumed_modifiers)
 754 {
 755     CHECK_LOAD_SYMBOL_GDK (gdk_keymap_translate_keyboard_state);
 756     return (*_gdk_keymap_translate_keyboard_state) (keymap, hardware_keycode,
 757                             state, group, keyval,
 758                             effective_group, level,
 759                             consumed_modifiers);
 760 }
 761 
 762 guint32 gdk_keyval_to_unicode (guint keyval)
 763 {
 764     CHECK_LOAD_SYMBOL_GDK (gdk_keyval_to_unicode);
 765     return (*_gdk_keyval_to_unicode) (keyval);
 766 }
 767 
 768 GdkPixbuf *gdk_pixbuf_get_from_drawable (GdkPixbuf * dest,
 769                      GdkDrawable * src,
 770                      GdkColormap * cmap,
 771                      int src_x,
 772                      int src_y,
 773                      int dest_x,
 774                      int dest_y, int width, int height)
 775 {
 776     CHECK_LOAD_SYMBOL_GDK (gdk_pixbuf_get_from_drawable);
 777     return (*_gdk_pixbuf_get_from_drawable) (dest, src, cmap, src_x, src_y,
 778                          dest_x, dest_y, width, height);
 779 }
 780 
 781 void gdk_pixbuf_render_pixmap_and_mask (GdkPixbuf * pixbuf,
 782                     GdkPixmap ** pixmap_return,
 783                     GdkBitmap ** mask_return,
 784                     int alpha_threshold)
 785 {
 786     CHECK_LOAD_SYMBOL_GDK (gdk_pixbuf_render_pixmap_and_mask);
 787     (*_gdk_pixbuf_render_pixmap_and_mask) (pixbuf, pixmap_return, mask_return,
 788                        alpha_threshold);
 789 }
 790 
 791 void gdk_pixbuf_render_pixmap_and_mask_for_colormap (GdkPixbuf * pixbuf,
 792                              GdkColormap * colormap,
 793                              GdkPixmap **
 794                              pixmap_return,
 795                              GdkBitmap ** mask_return,
 796                              int alpha_threshold)
 797 {
 798     CHECK_LOAD_SYMBOL_GDK (gdk_pixbuf_render_pixmap_and_mask_for_colormap);
 799     (*_gdk_pixbuf_render_pixmap_and_mask_for_colormap) (pixbuf, colormap,
 800                             pixmap_return,
 801                             mask_return,
 802                             alpha_threshold);
 803 }
 804 
 805 GdkGrabStatus gdk_pointer_grab (GdkWindow * window,
 806                 gboolean owner_events,
 807                 GdkEventMask event_mask,
 808                 GdkWindow * confine_to,
 809                 GdkCursor * cursor, guint32 time_)
 810 {
 811     CHECK_LOAD_SYMBOL_GDK (gdk_pointer_grab);
 812     return (*_gdk_pointer_grab) (window, owner_events, event_mask, confine_to,
 813                  cursor, time_);
 814 }
 815 
 816 void gdk_pointer_ungrab (guint32 time_)
 817 {
 818     CHECK_LOAD_SYMBOL_GDK (gdk_pointer_ungrab);
 819     return (*_gdk_pointer_ungrab) (time_);
 820 }
 821 
 822 void gdk_property_change (GdkWindow * window,
 823               GdkAtom property,
 824               GdkAtom type,
 825               gint format,
 826               GdkPropMode mode,
 827               const guchar * data, gint nelements)
 828 {
 829     CHECK_LOAD_SYMBOL_GDK (gdk_property_change);
 830     return (*_gdk_property_change) (window, property, type, format, mode,
 831                     data, nelements);
 832 }
 833 
 834 gboolean gdk_property_get (GdkWindow * window,
 835                GdkAtom property,
 836                GdkAtom type,
 837                gulong offset,
 838                gulong length,
 839                gint pdelete,
 840                GdkAtom * actual_property_type,
 841                gint * actual_format,
 842                gint * actual_length, guchar ** data)
 843 {
 844     CHECK_LOAD_SYMBOL_GDK (gdk_property_get);
 845     return (*_gdk_property_get) (window, property, type, offset, length,
 846                  pdelete, actual_property_type, actual_format,
 847                  actual_length, data);
 848 }
 849 
 850 gboolean gdk_rectangle_intersect (const GdkRectangle * src1,
 851                   const GdkRectangle * src2,
 852                   GdkRectangle * dest)
 853 {
 854     CHECK_LOAD_SYMBOL_GDK (gdk_rectangle_intersect);
 855     return (*_gdk_rectangle_intersect) (src1, src2, dest);
 856 }
 857 
 858 void gdk_region_destroy (GdkRegion * region)
 859 {
 860     CHECK_LOAD_SYMBOL_GDK (gdk_region_destroy);
 861     (*_gdk_region_destroy) (region);
 862 }
 863 
 864 GdkRegion *gdk_region_new (void)
 865 {
 866     CHECK_LOAD_SYMBOL_GDK (gdk_region_new);
 867     return (*_gdk_region_new) ();
 868 }
 869 
 870 GdkScreen *gdk_screen_get_default (void)
 871 {
 872     CHECK_LOAD_SYMBOL_GDK (gdk_screen_get_default);
 873     return (*_gdk_screen_get_default) ();
 874 }
 875 
 876 gint gdk_screen_get_height (GdkScreen * screen)
 877 {
 878     CHECK_LOAD_SYMBOL_GDK (gdk_screen_get_height);
 879     return (*_gdk_screen_get_height) (screen);
 880 }
 881 
 882 gint gdk_screen_get_monitor_at_point (GdkScreen * screen, gint x, gint y)
 883 {
 884     CHECK_LOAD_SYMBOL_GDK (gdk_screen_get_monitor_at_point);
 885     return (*_gdk_screen_get_monitor_at_point) (screen, x, y);
 886 }
 887 
 888 void gdk_screen_get_monitor_geometry (GdkScreen * screen,
 889                       gint monitor_num, GdkRectangle * dest)
 890 {
 891     CHECK_LOAD_SYMBOL_GDK (gdk_screen_get_monitor_geometry);
 892     (*_gdk_screen_get_monitor_geometry) (screen, monitor_num, dest);
 893 }
 894 
 895 gint gdk_screen_get_n_monitors (GdkScreen * screen)
 896 {
 897     CHECK_LOAD_SYMBOL_GDK (gdk_screen_get_n_monitors);
 898     return (*_gdk_screen_get_n_monitors) (screen);
 899 }
 900 
 901 gdouble gdk_screen_get_resolution (GdkScreen * screen)
 902 {
 903     CHECK_LOAD_SYMBOL_GDK (gdk_screen_get_resolution);
 904     return (*_gdk_screen_get_resolution) (screen);
 905 }
 906 
 907 GdkColormap *gdk_screen_get_rgba_colormap (GdkScreen * screen)
 908 {
 909     CHECK_LOAD_SYMBOL_GDK (gdk_screen_get_rgba_colormap);
 910     return (*_gdk_screen_get_rgba_colormap) (screen);
 911 }
 912 
 913 GdkColormap *gdk_screen_get_rgb_colormap (GdkScreen * screen)
 914 {
 915     CHECK_LOAD_SYMBOL_GDK (gdk_screen_get_rgb_colormap);
 916     return (*_gdk_screen_get_rgb_colormap) (screen);
 917 }
 918 
 919 GdkWindow *gdk_screen_get_root_window (GdkScreen * screen)
 920 {
 921     CHECK_LOAD_SYMBOL_GDK (gdk_screen_get_root_window);
 922     return (*_gdk_screen_get_root_window) (screen);
 923 }
 924 
 925 GdkVisual *gdk_screen_get_system_visual (GdkScreen * screen)
 926 {
 927     CHECK_LOAD_SYMBOL_GDK (gdk_screen_get_system_visual);
 928     return (*_gdk_screen_get_system_visual) (screen);
 929 }
 930 
 931 gint gdk_screen_get_width (GdkScreen * screen)
 932 {
 933     CHECK_LOAD_SYMBOL_GDK (gdk_screen_get_width);
 934     return (*_gdk_screen_get_width) (screen);
 935 }
 936 
 937 gboolean gdk_screen_is_composited (GdkScreen * screen)
 938 {
 939     CHECK_LOAD_SYMBOL_GDK (gdk_screen_is_composited);
 940     return (*_gdk_screen_is_composited) (screen);
 941 }
 942 
 943 void gdk_selection_convert (GdkWindow * requestor,
 944                 GdkAtom selection, GdkAtom target, guint32 time_)
 945 {
 946     CHECK_LOAD_SYMBOL_GDK (gdk_selection_convert);
 947     (*_gdk_selection_convert) (requestor, selection, target, time_);
 948 }
 949 
 950 gboolean gdk_selection_owner_set (GdkWindow * owner,
 951                   GdkAtom selection,
 952                   guint32 time_, gboolean send_event)
 953 {
 954     CHECK_LOAD_SYMBOL_GDK (gdk_selection_owner_set);
 955     return (*_gdk_selection_owner_set) (owner, selection, time_, send_event);
 956 }
 957 
 958 gint gdk_selection_property_get (GdkWindow * requestor,
 959                  guchar ** data,
 960                  GdkAtom * prop_type, gint * prop_format)
 961 {
 962     CHECK_LOAD_SYMBOL_GDK (gdk_selection_property_get);
 963     return (*_gdk_selection_property_get) (requestor, data, prop_type,
 964                        prop_format);
 965 }
 966 
 967 void gdk_selection_send_notify (GdkNativeWindow requestor,
 968                 GdkAtom selection,
 969                 GdkAtom target,
 970                 GdkAtom property, guint32 time_)
 971 {
 972     CHECK_LOAD_SYMBOL_GDK (gdk_selection_send_notify);
 973     return (*_gdk_selection_send_notify) (requestor, selection, target,
 974                       property, time_);
 975 }
 976 
 977 guint gdk_unicode_to_keyval (guint32 wc)
 978 {
 979     CHECK_LOAD_SYMBOL_GDK (gdk_unicode_to_keyval);
 980     return (*_gdk_unicode_to_keyval) (wc);
 981 }
 982 
 983 guint gdk_threads_add_idle_full (gint priority,
 984                  GSourceFunc function,
 985                  gpointer data, GDestroyNotify notify)
 986 {
 987     CHECK_LOAD_SYMBOL_GDK (gdk_threads_add_idle_full);
 988     return (*_gdk_threads_add_idle_full) (priority, function, data, notify);
 989 }
 990 
 991 guint gdk_threads_add_idle (GSourceFunc function, gpointer data)
 992 {
 993     CHECK_LOAD_SYMBOL_GDK (gdk_threads_add_idle);
 994     return (*_gdk_threads_add_idle) (function, data);
 995 }
 996 
 997 guint gdk_threads_add_timeout_full (gint priority,
 998                     guint interval,
 999                     GSourceFunc function,
1000                     gpointer data, GDestroyNotify notify)
1001 {
1002     CHECK_LOAD_SYMBOL_GDK (gdk_threads_add_timeout_full);
1003     return (*_gdk_threads_add_timeout_full) (priority, interval, function,
1004                          data, notify);
1005 }
1006 
1007 void gdk_threads_enter (void)
1008 {
1009     CHECK_LOAD_SYMBOL_GDK (gdk_threads_enter);
1010     (*_gdk_threads_enter) ();
1011 }
1012 
1013 void gdk_threads_init (void)
1014 {
1015     CHECK_LOAD_SYMBOL_GDK (gdk_threads_init);
1016     (*_gdk_threads_init) ();
1017 }
1018 
1019 void gdk_threads_leave (void)
1020 {
1021     CHECK_LOAD_SYMBOL_GDK (gdk_threads_leave);
1022     (*_gdk_threads_leave) ();
1023 }
1024 
1025 void gdk_window_destroy (GdkWindow * window)
1026 {
1027     CHECK_LOAD_SYMBOL_GDK (gdk_window_destroy);
1028     (*_gdk_window_destroy) (window);
1029 }
1030 
1031 GdkCursor *gdk_window_get_cursor (GdkWindow * window)
1032 {
1033     CHECK_LOAD_SYMBOL_GDK (gdk_window_get_cursor);
1034     return (*_gdk_window_get_cursor) (window);
1035 }
1036 
1037 GdkEventMask gdk_window_get_events (GdkWindow * window)
1038 {
1039     CHECK_LOAD_SYMBOL_GDK (gdk_window_get_events);
1040     return (*_gdk_window_get_events) (window);
1041 }
1042 
1043 void gdk_window_get_geometry (GdkWindow * window,
1044                   gint * x,
1045                   gint * y,
1046                   gint * width, gint * height, gint * depth)
1047 {
1048     CHECK_LOAD_SYMBOL_GDK (gdk_window_get_geometry);
1049     (*_gdk_window_get_geometry) (window, x, y, width, height, depth);
1050 }
1051 
1052 gint gdk_window_get_origin (GdkWindow * window, gint * x, gint * y)
1053 {
1054     CHECK_LOAD_SYMBOL_GDK (gdk_window_get_origin);
1055     return (*_gdk_window_get_origin) (window, x, y);
1056 }
1057 
1058 gboolean gdk_window_is_destroyed (GdkWindow * window)
1059 {
1060     CHECK_LOAD_SYMBOL_GDK (gdk_window_is_destroyed);
1061     return (*_gdk_window_is_destroyed) (window);
1062 }
1063 
1064 void gdk_window_move (GdkWindow * window, gint x, gint y)
1065 {
1066     CHECK_LOAD_SYMBOL_GDK (gdk_window_move);
1067     (*_gdk_window_move) (window, x, y);
1068 }
1069 
1070 GdkWindow *gdk_window_new (GdkWindow * parent,
1071                GdkWindowAttr * attributes, gint attributes_mask)
1072 {
1073     CHECK_LOAD_SYMBOL_GDK (gdk_window_new);
1074     return (*_gdk_window_new) (parent, attributes, attributes_mask);
1075 }
1076 
1077 void gdk_window_register_dnd (GdkWindow * window)
1078 {
1079     CHECK_LOAD_SYMBOL_GDK (gdk_window_register_dnd);
1080     (*_gdk_window_register_dnd) (window);
1081 }
1082 
1083 void gdk_window_resize (GdkWindow * window, gint width, gint height)
1084 {
1085     CHECK_LOAD_SYMBOL_GDK (gdk_window_resize);
1086     (*_gdk_window_resize) (window, width, height);
1087 }
1088 
1089 void gdk_window_restack (GdkWindow * window,
1090              GdkWindow * sibling, gboolean above)
1091 {
1092     CHECK_LOAD_SYMBOL_GDK (gdk_window_restack);
1093     (*_gdk_window_restack) (window, sibling, above);
1094 }
1095 
1096 void gdk_window_set_cursor (GdkWindow * window, GdkCursor * cursor)
1097 {
1098     CHECK_LOAD_SYMBOL_GDK (gdk_window_set_cursor);
1099     (*_gdk_window_set_cursor) (window, cursor);
1100 }
1101 
1102 void gdk_window_set_events (GdkWindow * window, GdkEventMask event_mask)
1103 {
1104     CHECK_LOAD_SYMBOL_GDK (gdk_window_set_events);
1105     (*_gdk_window_set_events) (window, event_mask);
1106 }
1107 
1108 void gdk_window_set_functions (GdkWindow * window, GdkWMFunction functions)
1109 {
1110     CHECK_LOAD_SYMBOL_GDK (gdk_window_set_functions);
1111     (*_gdk_window_set_functions) (window, functions);
1112 }
1113 
1114 void gdk_window_show (GdkWindow * window)
1115 {
1116     CHECK_LOAD_SYMBOL_GDK (gdk_window_show);
1117     (*_gdk_window_show) (window);
1118 }
1119 
1120 Display *gdk_x11_display_get_xdisplay (GdkDisplay * display)
1121 {
1122     CHECK_LOAD_SYMBOL_GDK (gdk_x11_display_get_xdisplay);
1123     return (*_gdk_x11_display_get_xdisplay) (display);
1124 }
1125 
1126 XID gdk_x11_drawable_get_xid (GdkDrawable * drawable)
1127 {
1128     if (wrapper_gtk_version == 2) {
1129         CHECK_LOAD_SYMBOL_GDK (gdk_x11_drawable_get_xid);
1130         return (*_gdk_x11_drawable_get_xid) (drawable);
1131     } else {
1132         CHECK_LOAD_SYMBOL_GDK (gdk_x11_window_get_xid);
1133         return (*_gdk_x11_window_get_xid) (drawable);
1134     }
1135 }
1136 
1137 gint gdk_x11_get_default_screen (void)
1138 {
1139     CHECK_LOAD_SYMBOL_GDK (gdk_x11_get_default_screen);
1140     return (*_gdk_x11_get_default_screen) ();
1141 }
1142 
1143 Display *gdk_x11_get_default_xdisplay (void)
1144 {
1145     CHECK_LOAD_SYMBOL_GDK (gdk_x11_get_default_xdisplay);
1146     return (*_gdk_x11_get_default_xdisplay) ();
1147 }
1148 
1149 guint32 gdk_x11_get_server_time (GdkWindow * window)
1150 {
1151     CHECK_LOAD_SYMBOL_GDK (gdk_x11_get_server_time);
1152     return (*_gdk_x11_get_server_time) (window);
1153 }
1154 
1155 GdkVisual *gdk_x11_screen_lookup_visual (GdkScreen * screen,
1156                      VisualID xvisualid)
1157 {
1158     CHECK_LOAD_SYMBOL_GDK (gdk_x11_screen_lookup_visual);
1159     return (*_gdk_x11_screen_lookup_visual) (screen, xvisualid);
1160 }
1161 
1162 GdkWindow *gdk_x11_window_foreign_new_for_display (GdkDisplay * display,
1163                            Window window)
1164 {
1165     CHECK_LOAD_SYMBOL_GDK (gdk_x11_window_foreign_new_for_display);
1166     return (*_gdk_x11_window_foreign_new_for_display) (display, window);
1167 }
1168 
1169 GdkWindow *gdk_x11_window_lookup_for_display (GdkDisplay * display,
1170                           Window window)
1171 {
1172     CHECK_LOAD_SYMBOL_GDK (gdk_x11_window_lookup_for_display);
1173     return (*_gdk_x11_window_lookup_for_display) (display, window);
1174 }
1175 
1176 GdkDisplay *gdk_window_get_display (GdkWindow * window)
1177 {
1178     CHECK_LOAD_SYMBOL_GDK (gdk_window_get_display);
1179     return (*_gdk_window_get_display) (window);
1180 }
1181 
1182 int gdk_window_get_height (GdkWindow * window)
1183 {
1184     CHECK_LOAD_SYMBOL_GDK (gdk_window_get_height);
1185     return (*_gdk_window_get_height) (window);
1186 }
1187 
1188 int gdk_window_get_width (GdkWindow * window)
1189 {
1190     CHECK_LOAD_SYMBOL_GDK (gdk_window_get_width);
1191     return (*_gdk_window_get_width) (window);
1192 }
1193 
1194 GdkScreen *gdk_window_get_screen (GdkWindow * window)
1195 {
1196     CHECK_LOAD_SYMBOL_GDK (gdk_window_get_screen);
1197     return (*_gdk_window_get_screen) (window);
1198 }
1199 
1200 
1201 //--------------------------------------------------------------------------------------
1202 
1203 
1204 GdkVisual *   gdk_window_get_visual (GdkWindow     *window)
1205 {
1206     CHECK_LOAD_SYMBOL_GDK (gdk_window_get_visual);
1207     return (*_gdk_window_get_visual)(window);
1208 }
1209 
1210 GdkScreen    *gdk_visual_get_screen (GdkVisual *visual)
1211 {
1212     CHECK_LOAD_SYMBOL_GDK (gdk_visual_get_screen);
1213     return (*_gdk_visual_get_screen)(visual);
1214 }
1215 
1216 //--------------------------------------------------------------------------------------
1217 
1218 Window
1219 gdk_x11_window_get_xid(GdkWindow   *window)
1220 {
1221     CHECK_LOAD_SYMBOL_GDK (gdk_x11_window_get_xid);
1222     return (*_gdk_x11_window_get_xid)(window);
1223 }
1224 
1225 GType
1226 gdk_window_object_get_type       (void)
1227 {
1228     if (wrapper_gtk_version == 2) {
1229         return (*_gdk_window_object_get_type)();
1230     } else {
1231         return (*_gdk_window_get_type)();
1232     }
1233 }
1234 
1235 cairo_region_t *
1236 gdk_cairo_region_create_from_surface (cairo_surface_t *surface)
1237 {
1238     return (*_gdk_cairo_region_create_from_surface)(surface);
1239 }
1240 
1241 //--------------------------------------------------------------------------------------
1242 
1243 typedef struct _DeviceGrabContext {
1244     GdkWindow * window;
1245     gboolean grabbed;
1246 } DeviceGrabContext;
1247 
1248 
1249 
1250 gboolean disableGrab = FALSE;
1251 static gboolean configure_transparent_window(GtkWidget *window);
1252 static void configure_opaque_window(GtkWidget *window);
1253 
1254 static void grab_mouse_device(GdkDevice *device, DeviceGrabContext *context);
1255 static void ungrab_mouse_device(GdkDevice *device);
1256 
1257 gint glass_gdk_visual_get_depth (GdkVisual * visual)
1258 {
1259     // gdk_visual_get_depth is GTK 2.2 +
1260     if (_gdk_visual_get_depth) {
1261         CHECK_LOAD_SYMBOL_GDK (gdk_visual_get_depth);
1262         return (*_gdk_visual_get_depth) (visual);
1263     } else {
1264         return visual ? visual->depth : 0;
1265     }
1266 }
1267 
1268 GdkScreen * glass_gdk_window_get_screen(GdkWindow * gdkWindow)
1269 {
1270     if (wrapper_gtk_version == 2) {
1271         CHECK_LOAD_SYMBOL_GDK (gdk_window_get_screen);
1272         return (*_gdk_window_get_screen)(gdkWindow);
1273     } else {
1274         GdkVisual * gdkVisual = gdk_window_get_visual(gdkWindow);
1275         return gdk_visual_get_screen(gdkVisual);
1276     }
1277 }
1278 
1279 gboolean
1280 glass_gdk_mouse_devices_grab(GdkWindow *gdkWindow) {
1281     if (wrapper_gtk_version == 2) {
1282         return glass_gdk_mouse_devices_grab_with_cursor(gdkWindow, NULL, TRUE);
1283     } else {
1284         if (disableGrab) {
1285             return TRUE;
1286         }
1287 
1288         CHECK_LOAD_SYMBOL_GDK (gdk_device_manager_list_devices);
1289         CHECK_LOAD_SYMBOL_GDK (gdk_display_get_device_manager);
1290         CHECK_LOAD_SYMBOL_GDK (gdk_display_get_default);
1291 
1292         DeviceGrabContext context;
1293         GList *devices = (*_gdk_device_manager_list_devices) (
1294                              (*_gdk_display_get_device_manager)(
1295                                  gdk_display_get_default()),
1296                                  GDK_DEVICE_TYPE_MASTER);
1297 
1298         context.window = gdkWindow;
1299         context.grabbed = FALSE;
1300         g_list_foreach(devices, (GFunc) grab_mouse_device, &context);
1301 
1302         return context.grabbed;
1303     }
1304 }
1305 
1306 gboolean
1307 glass_gdk_mouse_devices_grab_with_cursor(GdkWindow *gdkWindow, GdkCursor *cursor, gboolean owner_events) {
1308     if (disableGrab) {
1309         return TRUE;
1310     }
1311     CHECK_LOAD_SYMBOL_GDK (gdk_pointer_grab);
1312     GdkGrabStatus status = (*_gdk_pointer_grab)(gdkWindow, owner_events, (GdkEventMask)
1313                                             (GDK_POINTER_MOTION_MASK
1314                                                 | GDK_POINTER_MOTION_HINT_MASK
1315                                                 | GDK_BUTTON_MOTION_MASK
1316                                                 | GDK_BUTTON1_MOTION_MASK
1317                                                 | GDK_BUTTON2_MOTION_MASK
1318                                                 | GDK_BUTTON3_MOTION_MASK
1319                                                 | GDK_BUTTON_PRESS_MASK
1320                                                 | GDK_BUTTON_RELEASE_MASK),
1321                                             NULL, cursor, GDK_CURRENT_TIME);
1322 
1323     return (status == GDK_GRAB_SUCCESS) ? TRUE : FALSE;
1324 }
1325 
1326 void
1327 glass_gdk_mouse_devices_ungrab() {
1328     if (wrapper_gtk_version == 2) {
1329         CHECK_LOAD_SYMBOL_GDK (gdk_pointer_ungrab);
1330         (*_gdk_pointer_ungrab)(GDK_CURRENT_TIME);
1331     } else {
1332         CHECK_LOAD_SYMBOL_GDK (gdk_device_manager_list_devices);
1333         CHECK_LOAD_SYMBOL_GDK (gdk_display_get_device_manager);
1334         CHECK_LOAD_SYMBOL_GDK (gdk_display_get_default);
1335 
1336         GList *devices = (*_gdk_device_manager_list_devices)(
1337                              (*_gdk_display_get_device_manager)(
1338                                  (*_gdk_display_get_default)()),
1339                                  GDK_DEVICE_TYPE_MASTER);
1340         g_list_foreach(devices, (GFunc) ungrab_mouse_device, NULL);
1341     }
1342 }
1343 
1344 void
1345 glass_gdk_master_pointer_grab(GdkWindow *window, GdkCursor *cursor) {
1346     if (disableGrab) {
1347         CHECK_LOAD_SYMBOL_GDK (gdk_window_set_cursor);
1348         (*_gdk_window_set_cursor)(window, cursor);
1349         return;
1350     }
1351     if (wrapper_gtk_version == 2) {
1352         CHECK_LOAD_SYMBOL_GDK (gdk_pointer_grab);
1353         (*_gdk_pointer_grab)(window, FALSE, (GdkEventMask)
1354                          (GDK_POINTER_MOTION_MASK
1355                              | GDK_BUTTON_MOTION_MASK
1356                              | GDK_BUTTON1_MOTION_MASK
1357                              | GDK_BUTTON2_MOTION_MASK
1358                              | GDK_BUTTON3_MOTION_MASK
1359                              | GDK_BUTTON_RELEASE_MASK),
1360                          NULL, cursor, GDK_CURRENT_TIME);
1361     } else {
1362         CHECK_LOAD_SYMBOL_GDK (gdk_device_grab);
1363         CHECK_LOAD_SYMBOL_GDK (gdk_device_manager_get_client_pointer);
1364         CHECK_LOAD_SYMBOL_GDK (gdk_display_get_device_manager);
1365         CHECK_LOAD_SYMBOL_GDK (gdk_display_get_default);
1366 
1367         (*_gdk_device_grab)((*_gdk_device_manager_get_client_pointer)(
1368                     (*_gdk_display_get_device_manager)(
1369                         (*_gdk_display_get_default)())),
1370                     window, GDK_OWNERSHIP_NONE, FALSE, GDK_ALL_EVENTS_MASK,
1371                     cursor, GDK_CURRENT_TIME);
1372     }
1373 }
1374 
1375 void
1376 glass_gdk_master_pointer_ungrab() {
1377     if (wrapper_gtk_version == 2) {
1378         CHECK_LOAD_SYMBOL_GDK (gdk_pointer_ungrab);
1379         (*_gdk_pointer_ungrab)(GDK_CURRENT_TIME);
1380     } else {
1381         CHECK_LOAD_SYMBOL_GDK (gdk_device_ungrab);
1382         CHECK_LOAD_SYMBOL_GDK (gdk_device_manager_get_client_pointer);
1383         CHECK_LOAD_SYMBOL_GDK (gdk_display_get_device_manager);
1384         CHECK_LOAD_SYMBOL_GDK (gdk_display_get_default);
1385         (*_gdk_device_ungrab)((*_gdk_device_manager_get_client_pointer)(
1386                               (*_gdk_display_get_device_manager)(
1387                                   (*_gdk_display_get_default)())),
1388                           GDK_CURRENT_TIME);
1389     }
1390 }
1391 
1392 void
1393 glass_gdk_master_pointer_get_position(gint *x, gint *y) {
1394     if (wrapper_gtk_version == 2) {
1395         CHECK_LOAD_SYMBOL_GDK (gdk_display_get_pointer);
1396         (*_gdk_display_get_pointer)(gdk_display_get_default(), NULL, x, y, NULL);
1397     } else {
1398         CHECK_LOAD_SYMBOL_GDK (gdk_device_manager_get_client_pointer);
1399         CHECK_LOAD_SYMBOL_GDK (gdk_display_get_device_manager);
1400         CHECK_LOAD_SYMBOL_GDK (gdk_display_get_default);
1401         (*_gdk_device_get_position)((*_gdk_device_manager_get_client_pointer)(
1402                                     (*_gdk_display_get_device_manager)(
1403                                         (*_gdk_display_get_default)())),
1404                                 NULL, x, y);
1405     }
1406 }
1407 
1408 gboolean
1409 glass_gdk_device_is_grabbed(GdkDevice *device) {
1410     if (wrapper_gtk_version == 2) {
1411         (void) device;
1412         CHECK_LOAD_SYMBOL_GDK (gdk_display_pointer_is_grabbed);
1413         return (*_gdk_display_pointer_is_grabbed)(gdk_display_get_default());
1414     } else {
1415         CHECK_LOAD_SYMBOL_GDK (gdk_display_device_is_grabbed);
1416         return (*_gdk_display_device_is_grabbed)((*_gdk_display_get_default)(), device);
1417     }
1418 }
1419 
1420 void
1421 glass_gdk_device_ungrab(GdkDevice *device) {
1422     if (wrapper_gtk_version == 2) {
1423         (void) device;
1424         CHECK_LOAD_SYMBOL_GDK (gdk_pointer_ungrab);
1425         (*_gdk_pointer_ungrab)(GDK_CURRENT_TIME);
1426     } else {
1427         CHECK_LOAD_SYMBOL_GDK (gdk_device_ungrab);
1428         (*_gdk_device_ungrab)(device, GDK_CURRENT_TIME);
1429     }
1430 }
1431 
1432 GdkWindow *
1433 glass_gdk_device_get_window_at_position(GdkDevice *device, gint *x, gint *y) {
1434     if (wrapper_gtk_version == 2) {
1435         (void) device;
1436         CHECK_LOAD_SYMBOL_GDK (gdk_display_get_window_at_pointer);
1437         return (*_gdk_display_get_window_at_pointer)(gdk_display_get_default(), x, y);
1438     } else {
1439         CHECK_LOAD_SYMBOL_GDK (gdk_device_get_window_at_position);
1440         return (*_gdk_device_get_window_at_position)(device, x, y);
1441     }
1442 }
1443 
1444 void
1445 glass_gtk_configure_transparency_and_realize(GtkWidget *window,
1446                                              gboolean transparent) {
1447     if (wrapper_gtk_version == 2) {
1448         glass_configure_window_transparency(window, transparent);
1449         gtk_widget_realize(window);
1450     } else {
1451         CHECK_LOAD_SYMBOL_GDK (gdk_window_set_background_rgba);
1452         gboolean isTransparent = glass_configure_window_transparency(window, transparent);
1453         gtk_widget_realize(window);
1454         if (isTransparent) {
1455             GdkRGBA rgba = { 1.0, 1.0, 1.0, 0.0 };
1456             (*_gdk_window_set_background_rgba)(gtk_widget_get_window(window), &rgba);
1457         }
1458     }
1459 }
1460 
1461 void
1462 glass_gtk_window_configure_from_visual(GtkWidget *widget, GdkVisual *visual) {
1463     glass_widget_set_visual(widget, visual);
1464 }
1465 
1466 static gboolean
1467 configure_transparent_window(GtkWidget *window) {
1468     GdkScreen *default_screen = (*_gdk_screen_get_default)();
1469     GdkDisplay *default_display = (*_gdk_display_get_default)();
1470 
1471     if (wrapper_gtk_version == 2) {
1472         CHECK_LOAD_SYMBOL_GDK (gdk_screen_get_rgba_colormap);
1473         CHECK_LOAD_SYMBOL_GDK (gdk_display_supports_composite);
1474         CHECK_LOAD_SYMBOL_GDK (gdk_screen_is_composited);
1475         GdkColormap *colormap = (*_gdk_screen_get_rgba_colormap)(default_screen);
1476         if (colormap
1477                 && (*_gdk_display_supports_composite)(default_display)
1478                 && (*_gdk_screen_is_composited)(default_screen)) {
1479             gtk_widget_set_colormap(window, colormap);
1480             return TRUE;
1481         }
1482     } else {
1483         CHECK_LOAD_SYMBOL_GDK (gdk_display_supports_composite);
1484         CHECK_LOAD_SYMBOL_GDK (gdk_screen_is_composited);
1485         GdkVisual *visual = (*_gdk_screen_get_rgba_visual)(default_screen);
1486         if (visual
1487                 && (*_gdk_display_supports_composite)(default_display)
1488                 && (*_gdk_screen_is_composited)(default_screen)) {
1489             glass_widget_set_visual(window, visual);
1490             return TRUE;
1491         }
1492 
1493         return FALSE;
1494     }
1495 
1496     return FALSE;
1497 }
1498 
1499 int
1500 glass_gtk_fixup_typed_key(int key, int keyval) {
1501     if (wrapper_gtk_version == 2) {
1502         if (key == 0) {
1503             // Work around "bug" fixed in gtk-3.0:
1504             // http://mail.gnome.org/archives/commits-list/2011-March/msg06832.html
1505             switch (keyval) {
1506             case 0xFF08 /* Backspace */: return '\b';
1507             case 0xFF09 /* Tab       */: return '\t';
1508             case 0xFF0A /* Linefeed  */: return '\n';
1509             case 0xFF0B /* Vert. Tab */: return '\v';
1510             case 0xFF0D /* Return    */: return '\r';
1511             case 0xFF1B /* Escape    */: return '\033';
1512             case 0xFFFF /* Delete    */: return '\177';
1513             }
1514         }
1515     }
1516     return key;
1517 }
1518 
1519 void
1520 glass_gdk_window_get_size(GdkWindow *window, gint *w, gint *h) {
1521     CHECK_LOAD_SYMBOL_GDK (gdk_window_get_width);
1522     CHECK_LOAD_SYMBOL_GDK (gdk_window_get_height);
1523     *w = (*_gdk_window_get_width)(window);
1524     *h = (*_gdk_window_get_height)(window);
1525 }
1526 
1527 void
1528 glass_gdk_display_get_pointer(GdkDisplay* display, gint* x, gint *y) {
1529     if (wrapper_gtk_version == 2) {
1530         CHECK_LOAD_SYMBOL_GDK (gdk_display_get_pointer);
1531         (*_gdk_display_get_pointer)(display, NULL, x, y, NULL);
1532     } else {
1533         CHECK_LOAD_SYMBOL_GDK (gdk_device_get_position);
1534         CHECK_LOAD_SYMBOL_GDK (gdk_device_manager_get_client_pointer);
1535         CHECK_LOAD_SYMBOL_GDK (gdk_display_get_device_manager);
1536         (*_gdk_device_get_position)(
1537             (*_gdk_device_manager_get_client_pointer)(
1538                 (*_gdk_display_get_device_manager)(display)), NULL , x, y);
1539     }
1540 }
1541 
1542 
1543 const guchar*
1544 glass_gtk_selection_data_get_data_with_length(
1545         GtkSelectionData * selectionData,
1546         gint * length) {
1547     if (selectionData == NULL) {
1548         return NULL;
1549     }
1550 
1551     *length = gtk_selection_data_get_length(selectionData);
1552     return gtk_selection_data_get_data(selectionData);
1553 }
1554 
1555 static void
1556 configure_opaque_window(GtkWidget *window) {
1557     (void) window;
1558 /* We need to pick a visual that really is glx compatible
1559  * instead of using the default visual
1560  *
1561     CHECK_LOAD_SYMBOL_GDK (gdk_screen_get_system_visual);
1562     CHECK_LOAD_SYMBOL_GDK (gdk_screen_get_default);
1563     glass_widget_set_visual(window,
1564                           gdk_screen_get_system_visual(
1565                               gdk_screen_get_default()));
1566 */
1567 }
1568 
1569 gboolean
1570 glass_configure_window_transparency(GtkWidget *window, gboolean transparent) {
1571     if (transparent) {
1572         if (configure_transparent_window(window)) {
1573             return TRUE;
1574         }
1575 
1576         fprintf(stderr,"Can't create transparent stage, because your screen doesn't"
1577                " support alpha channel."
1578                " You need to enable XComposite extension.\n");
1579         fflush(stderr);
1580     }
1581 
1582     configure_opaque_window(window);
1583     return FALSE;
1584 }
1585 
1586 static void
1587 grab_mouse_device(GdkDevice *device, DeviceGrabContext *context) {
1588     CHECK_LOAD_SYMBOL_GDK (gdk_device_get_source);
1589     CHECK_LOAD_SYMBOL_GDK (gdk_device_grab);
1590     GdkInputSource source = (*_gdk_device_get_source)(device);
1591     if (source == GDK_SOURCE_MOUSE) {
1592         GdkGrabStatus status = (*_gdk_device_grab)(device,
1593                                                context->window,
1594                                                GDK_OWNERSHIP_NONE,
1595                                                TRUE,
1596                                                GDK_ALL_EVENTS_MASK,
1597                                                NULL,
1598                                                GDK_CURRENT_TIME);
1599         if (status == GDK_GRAB_SUCCESS) {
1600             context->grabbed = TRUE;
1601         }
1602     }
1603 }
1604 
1605 static void
1606 ungrab_mouse_device(GdkDevice *device) {
1607     CHECK_LOAD_SYMBOL_GDK (gdk_device_get_source);
1608     CHECK_LOAD_SYMBOL_GDK (gdk_device_ungrab);
1609     GdkInputSource source = (*_gdk_device_get_source)(device);
1610     if (source == GDK_SOURCE_MOUSE) {
1611         (*_gdk_device_ungrab)(device, GDK_CURRENT_TIME);
1612     }
1613 }
1614 
1615 GdkPixbuf *
1616 glass_pixbuf_from_window(GdkWindow *window,
1617     gint srcx, gint srcy,
1618     gint width, gint height)
1619 {
1620     GdkPixbuf * ret = NULL;
1621 
1622     if (wrapper_gtk_version == 2) {
1623         CHECK_LOAD_SYMBOL_GDK (gdk_pixbuf_get_from_drawable);
1624         ret = (*_gdk_pixbuf_get_from_drawable) (NULL,
1625             window,
1626             NULL,
1627             srcx, srcy,
1628             0, 0,
1629             width, height);
1630     } else {
1631         CHECK_LOAD_SYMBOL_GDK (gdk_pixbuf_get_from_window);
1632         ret = (*_gdk_pixbuf_get_from_window) (window, srcx, srcy, width, height);
1633     }
1634 
1635     return ret;
1636 }
1637 
1638 void
1639 glass_window_apply_shape_mask(GdkWindow *window,
1640     void* data, uint width, uint height)
1641 {
1642     if (wrapper_gtk_version == 2) {
1643         CHECK_LOAD_SYMBOL_GDK (gdk_window_input_shape_combine_mask);
1644 
1645         GdkPixbuf* pixbuf = gdk_pixbuf_new_from_data((guchar *) data,
1646                 GDK_COLORSPACE_RGB, TRUE, 8, width, height, width * 4, NULL, NULL);
1647 
1648         if (GDK_IS_PIXBUF(pixbuf)) {
1649             GdkBitmap* mask = NULL;
1650             gdk_pixbuf_render_pixmap_and_mask(pixbuf, NULL, &mask, 128);
1651 
1652             (*_gdk_window_input_shape_combine_mask)(window, mask, 0, 0);
1653 
1654             g_object_unref(pixbuf);
1655             if (mask) {
1656                 g_object_unref(mask);
1657             }
1658         }
1659     } else {
1660         CHECK_LOAD_SYMBOL_GDK (gdk_window_shape_combine_region);
1661         CHECK_LOAD_SYMBOL_GDK (gdk_window_input_shape_combine_region);
1662         CHECK_LOAD_SYMBOL_GDK (gdk_cairo_region_create_from_surface);
1663 
1664         cairo_surface_t * shape = cairo_image_surface_create_for_data(
1665                  (unsigned char *)data,
1666                  CAIRO_FORMAT_ARGB32,
1667                  width, height,
1668                  width * 4
1669                  );
1670         cairo_region_t *region = (*_gdk_cairo_region_create_from_surface) (shape);
1671 
1672         (*_gdk_window_shape_combine_region) (window, region, 0, 0);
1673 
1674         (*_gdk_window_input_shape_combine_region) (window, region, 0, 0);
1675 
1676         cairo_region_destroy(region);
1677         cairo_surface_finish (shape);
1678     }
1679 }
1680 
1681 void
1682 glass_window_reset_input_shape_mask(GdkWindow *window)
1683 {
1684     if (wrapper_gtk_version == 2) {
1685         CHECK_LOAD_SYMBOL_GDK (gdk_window_input_shape_combine_mask);
1686         (*_gdk_window_input_shape_combine_mask)(window, NULL, 0, 0);
1687     } else {
1688         CHECK_LOAD_SYMBOL_GDK (gdk_window_input_shape_combine_region);
1689         (*_gdk_window_input_shape_combine_region) (window, NULL, 0, 0);
1690     }
1691 }
1692 
1693 GdkWindow *
1694 glass_gdk_drag_context_get_dest_window (GdkDragContext * context)
1695 {
1696     CHECK_LOAD_SYMBOL_GDK (gdk_drag_context_get_dest_window);
1697     return ((context != NULL) ? gdk_drag_context_get_dest_window(context) : NULL);
1698 }
1699 
1700