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