[gtk+/xi2: 816/1239] GdkDisplay: Add replacement to GdkDisplayPointerHooks.



commit ea62c26aa706941d0f5883c5dc18b416e0373783
Author: Carlos Garnacho <carlos lanedo com>
Date:   Fri Aug 21 19:38:11 2009 +0200

    GdkDisplay: Add replacement to GdkDisplayPointerHooks.
    
    GdkDisplayDeviceHooks was added, this has also modified all the machinery
    underneath gdk_display_get_pointer(), gdk_display_get_window_at_pointer()
    and gdk_window_get_pointer(), device-aware functions have been added.
    
    Also, _gdk_windowing_get_pointer() _gdk_windowing_window_at_pointer() and
    GdkWindowImpl::get_pointer() have been replaced with their device-aware
    counterparts, so other Gdk backends should keep in mind these changes.

 gdk/gdkdisplay.c         |  280 ++++++++++++++++++++++++++++++++++++----------
 gdk/gdkdisplay.h         |   47 +++++++-
 gdk/gdkinternals.h       |   12 +-
 gdk/gdkoffscreenwindow.c |   13 +-
 gdk/gdkwindow.c          |   39 ++++---
 gdk/gdkwindow.h          |    5 +
 gdk/gdkwindowimpl.h      |    5 +-
 gdk/x11/gdkwindow-x11.c  |  200 ++++++++++++++++-----------------
 8 files changed, 406 insertions(+), 195 deletions(-)
---
diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c
index 52cd7cc..1870336 100644
--- a/gdk/gdkdisplay.c
+++ b/gdk/gdkdisplay.c
@@ -40,6 +40,37 @@ enum {
 static void gdk_display_dispose    (GObject         *object);
 static void gdk_display_finalize   (GObject         *object);
 
+static void        multihead_get_device_state           (GdkDisplay       *display,
+                                                         GdkDevice        *device,
+                                                         GdkScreen       **screen,
+                                                         gint             *x,
+                                                         gint             *y,
+                                                         GdkModifierType  *mask);
+static GdkWindow * multihead_window_get_device_position (GdkDisplay       *display,
+                                                         GdkDevice        *device,
+                                                         GdkWindow        *window,
+                                                         gint             *x,
+                                                         gint             *y,
+                                                         GdkModifierType  *mask);
+static GdkWindow * multihead_window_at_device_position  (GdkDisplay       *display,
+                                                         GdkDevice        *device,
+                                                         gint             *win_x,
+                                                         gint             *win_y);
+
+static void        multihead_default_get_pointer        (GdkDisplay       *display,
+                                                         GdkScreen       **screen,
+                                                         gint             *x,
+                                                         gint             *y,
+                                                         GdkModifierType  *mask);
+static GdkWindow * multihead_default_window_get_pointer (GdkDisplay      *display,
+                                                         GdkWindow       *window,
+                                                         gint            *x,
+                                                         gint            *y,
+                                                         GdkModifierType *mask);
+static GdkWindow * multihead_default_window_at_pointer  (GdkDisplay      *display,
+                                                         gint            *win_x,
+                                                         gint            *win_y);
+
 
 static void       singlehead_get_pointer (GdkDisplay       *display,
 					  GdkScreen       **screen,
@@ -62,23 +93,37 @@ static GdkWindow* singlehead_default_window_get_pointer (GdkWindow       *window
 static GdkWindow* singlehead_default_window_at_pointer  (GdkScreen       *screen,
 							 gint            *win_x,
 							 gint            *win_y);
-static GdkWindow *gdk_window_real_window_get_pointer     (GdkDisplay       *display,
-                                                          GdkWindow        *window,
-                                                          gint             *x,
-                                                          gint             *y,
-                                                          GdkModifierType  *mask);
-static GdkWindow *gdk_display_real_get_window_at_pointer (GdkDisplay       *display,
-                                                          gint             *win_x,
-                                                          gint             *win_y);
+static GdkWindow *gdk_window_real_window_get_device_position     (GdkDisplay       *display,
+                                                                  GdkDevice        *device,
+                                                                  GdkWindow        *window,
+                                                                  gint             *x,
+                                                                  gint             *y,
+                                                                  GdkModifierType  *mask);
+static GdkWindow *gdk_display_real_get_window_at_device_position (GdkDisplay       *display,
+                                                                  GdkDevice        *device,
+                                                                  gint             *win_x,
+                                                                  gint             *win_y);
 
 static guint signals[LAST_SIGNAL] = { 0 };
 
 static char *gdk_sm_client_id;
 
-static const GdkDisplayPointerHooks default_pointer_hooks = {
-  _gdk_windowing_get_pointer,
-  gdk_window_real_window_get_pointer,
-  gdk_display_real_get_window_at_pointer
+static const GdkDisplayDeviceHooks default_device_hooks = {
+  _gdk_windowing_get_device_state,
+  gdk_window_real_window_get_device_position,
+  gdk_display_real_get_window_at_device_position
+};
+
+static const GdkDisplayDeviceHooks multihead_pointer_hooks = {
+  multihead_get_device_state,
+  multihead_window_get_device_position,
+  multihead_window_at_device_position
+};
+
+static const GdkDisplayPointerHooks multihead_default_pointer_hooks = {
+  multihead_default_get_pointer,
+  multihead_default_window_get_pointer,
+  multihead_default_window_at_pointer
 };
 
 static const GdkDisplayPointerHooks singlehead_pointer_hooks = {
@@ -93,6 +138,7 @@ static const GdkPointerHooks singlehead_default_pointer_hooks = {
 };
 
 static const GdkPointerHooks *singlehead_current_pointer_hooks = &singlehead_default_pointer_hooks;
+static const GdkDisplayPointerHooks *multihead_current_pointer_hooks = &multihead_default_pointer_hooks;
 
 G_DEFINE_TYPE (GdkDisplay, gdk_display, G_TYPE_OBJECT)
 
@@ -141,7 +187,7 @@ gdk_display_init (GdkDisplay *display)
   display->double_click_time = 250;
   display->double_click_distance = 5;
 
-  display->pointer_hooks = &default_pointer_hooks;
+  display->device_hooks = &default_device_hooks;
 
   display->pointers_info = g_hash_table_new_full (NULL, NULL, NULL,
                                                   (GDestroyNotify) free_pointer_info);
@@ -475,6 +521,72 @@ _gdk_display_enable_motion_hints (GdkDisplay *display)
     }
 }
 
+void
+gdk_display_get_device_state (GdkDisplay       *display,
+                              GdkDevice        *device,
+                              GdkScreen       **screen,
+                              gint             *x,
+                              gint             *y,
+                              GdkModifierType  *mask)
+{
+  GdkScreen *tmp_screen;
+  gint tmp_x, tmp_y;
+  GdkModifierType tmp_mask;
+
+  g_return_if_fail (GDK_IS_DISPLAY (display));
+  g_return_if_fail (GDK_IS_DEVICE (device));
+
+  display->device_hooks->get_device_state (display, device, &tmp_screen, &tmp_x, &tmp_y, &tmp_mask);
+
+  if (screen)
+    *screen = tmp_screen;
+  if (x)
+    *x = tmp_x;
+  if (y)
+    *y = tmp_y;
+  if (mask)
+    *mask = tmp_mask;
+}
+
+GdkWindow *
+gdk_display_get_window_at_device_position (GdkDisplay *display,
+                                           GdkDevice  *device,
+                                           gint       *win_x,
+                                           gint       *win_y)
+{
+  gint tmp_x, tmp_y;
+  GdkWindow *window;
+
+  g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
+  g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
+
+  window = display->device_hooks->window_at_device_position (display, device, &tmp_x, &tmp_y);
+
+  if (win_x)
+    *win_x = tmp_x;
+  if (win_y)
+    *win_y = tmp_y;
+
+  return window;
+}
+
+GdkDisplayDeviceHooks *
+gdk_display_set_device_hooks (GdkDisplay                  *display,
+                              const GdkDisplayDeviceHooks *new_hooks)
+{
+  const GdkDisplayDeviceHooks *result;
+
+  g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
+  result = display->device_hooks;
+
+  if (new_hooks)
+    display->device_hooks = new_hooks;
+  else
+    display->device_hooks = &default_device_hooks;
+
+  return (GdkDisplayDeviceHooks *) result;
+}
+
 /**
  * gdk_display_get_pointer:
  * @display: a #GdkDisplay
@@ -496,33 +608,21 @@ gdk_display_get_pointer (GdkDisplay      *display,
 			 gint            *y,
 			 GdkModifierType *mask)
 {
-  GdkScreen *tmp_screen;
-  gint tmp_x, tmp_y;
-  GdkModifierType tmp_mask;
-  
   g_return_if_fail (GDK_IS_DISPLAY (display));
 
-  display->pointer_hooks->get_pointer (display, &tmp_screen, &tmp_x, &tmp_y, &tmp_mask);
-
-  if (screen)
-    *screen = tmp_screen;
-  if (x)
-    *x = tmp_x;
-  if (y)
-    *y = tmp_y;
-  if (mask)
-    *mask = tmp_mask;
+  gdk_display_get_device_state (display, display->core_pointer, screen, x, y, mask);
 }
 
 static GdkWindow *
-gdk_display_real_get_window_at_pointer (GdkDisplay *display,
-                                        gint       *win_x,
-                                        gint       *win_y)
+gdk_display_real_get_window_at_device_position (GdkDisplay *display,
+                                                GdkDevice  *device,
+                                                gint       *win_x,
+                                                gint       *win_y)
 {
   GdkWindow *window;
   gint x, y;
 
-  window = _gdk_windowing_window_at_pointer (display, &x, &y, NULL);
+  window = _gdk_windowing_window_at_device_position (display, device, &x, &y, NULL);
 
   /* This might need corrections, as the native window returned
      may contain client side children */
@@ -544,11 +644,12 @@ gdk_display_real_get_window_at_pointer (GdkDisplay *display,
 }
 
 static GdkWindow *
-gdk_window_real_window_get_pointer (GdkDisplay       *display,
-                                    GdkWindow        *window,
-                                    gint             *x,
-                                    gint             *y,
-                                    GdkModifierType  *mask)
+gdk_window_real_window_get_device_position (GdkDisplay       *display,
+                                            GdkDevice        *device,
+                                            GdkWindow        *window,
+                                            gint             *x,
+                                            gint             *y,
+                                            GdkModifierType  *mask)
 {
   GdkWindowObject *private;
   gint tmpx, tmpy;
@@ -557,9 +658,10 @@ gdk_window_real_window_get_pointer (GdkDisplay       *display,
 
   private = (GdkWindowObject *) window;
 
-  normal_child = GDK_WINDOW_IMPL_GET_IFACE (private->impl)->get_pointer (window,
-									 &tmpx, &tmpy,
-									 &tmp_mask);
+  normal_child = GDK_WINDOW_IMPL_GET_IFACE (private->impl)->get_device_state (window,
+                                                                              device,
+                                                                              &tmpx, &tmpy,
+                                                                              &tmp_mask);
   /* We got the coords on the impl, convert to the window */
   tmpx -= private->abs_x;
   tmpy -= private->abs_y;
@@ -598,19 +700,72 @@ gdk_display_get_window_at_pointer (GdkDisplay *display,
 				   gint       *win_x,
 				   gint       *win_y)
 {
-  gint tmp_x, tmp_y;
-  GdkWindow *window;
-
   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
 
-  window = display->pointer_hooks->window_at_pointer (display, &tmp_x, &tmp_y);
+  gdk_display_get_window_at_device_position (display, display->core_pointer, win_x, win_y);
+}
 
-  if (win_x)
-    *win_x = tmp_x;
-  if (win_y)
-    *win_y = tmp_y;
+static void
+multihead_get_device_state (GdkDisplay       *display,
+                            GdkDevice        *device,
+                            GdkScreen       **screen,
+                            gint             *x,
+                            gint             *y,
+                            GdkModifierType  *mask)
+{
+  multihead_current_pointer_hooks->get_pointer (display, screen, x, y, mask);
+}
 
-  return window;
+static GdkWindow *
+multihead_window_get_device_position (GdkDisplay      *display,
+                                      GdkDevice       *device,
+                                      GdkWindow       *window,
+                                      gint            *x,
+                                      gint            *y,
+                                      GdkModifierType *mask)
+{
+  return multihead_current_pointer_hooks->window_get_pointer (display, window, x, y, mask);
+}
+
+static GdkWindow *
+multihead_window_at_device_position (GdkDisplay *display,
+                                     GdkDevice  *device,
+                                     gint       *win_x,
+                                     gint       *win_y)
+{
+  return multihead_current_pointer_hooks->window_at_pointer (display, win_x, win_y);
+}
+
+static void
+multihead_default_get_pointer (GdkDisplay       *display,
+                               GdkScreen       **screen,
+                               gint             *x,
+                               gint             *y,
+                               GdkModifierType  *mask)
+{
+  /* FIXME: Call equivalent to _gdk_windowing_get_pointer() */
+}
+
+static GdkWindow *
+multihead_default_window_get_pointer (GdkDisplay      *display,
+                                      GdkWindow       *window,
+                                      gint            *x,
+                                      gint            *y,
+                                      GdkModifierType *mask)
+{
+  return gdk_window_real_window_get_device_position (display,
+                                                  display->core_pointer,
+                                                  window, x, y, mask);
+}
+
+static GdkWindow *
+multihead_default_window_at_pointer (GdkDisplay *display,
+                                     gint       *win_x,
+                                     gint       *win_y)
+{
+  return gdk_display_real_get_window_at_device_position (display,
+                                                         display->core_pointer,
+                                                         win_x, win_y);
 }
 
 /**
@@ -634,15 +789,16 @@ GdkDisplayPointerHooks *
 gdk_display_set_pointer_hooks (GdkDisplay                   *display,
 			       const GdkDisplayPointerHooks *new_hooks)
 {
-  const GdkDisplayPointerHooks *result;
+  const GdkDisplayPointerHooks *result = multihead_current_pointer_hooks;
 
   g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
-  result = display->pointer_hooks;
 
   if (new_hooks)
-    display->pointer_hooks = new_hooks;
+    multihead_current_pointer_hooks = new_hooks;
   else
-    display->pointer_hooks = &default_pointer_hooks;
+    multihead_current_pointer_hooks = &multihead_default_pointer_hooks;
+
+  gdk_display_set_device_hooks (display, &multihead_pointer_hooks);
 
   return (GdkDisplayPointerHooks *)result;
 }
@@ -689,8 +845,13 @@ singlehead_default_window_get_pointer (GdkWindow       *window,
 				       gint            *y,
 				       GdkModifierType *mask)
 {
-  return gdk_window_real_window_get_pointer (gdk_drawable_get_display (window),
-                                             window, x, y, mask);
+  GdkDisplay *display;
+
+  display = gdk_drawable_get_display (window);
+
+  return gdk_window_real_window_get_device_position (display,
+                                                     display->core_pointer,
+                                                     window, x, y, mask);
 }
 
 static GdkWindow*
@@ -698,8 +859,13 @@ singlehead_default_window_at_pointer  (GdkScreen       *screen,
 				       gint            *win_x,
 				       gint            *win_y)
 {
-  return gdk_display_real_get_window_at_pointer (gdk_screen_get_display (screen),
-                                                 win_x, win_y);
+  GdkDisplay *display;
+
+  display = gdk_screen_get_display (screen);
+
+  return gdk_display_real_get_window_at_device_position (display,
+                                                         display->core_pointer,
+                                                         win_x, win_y);
 }
 
 /**
@@ -974,7 +1140,7 @@ switch_to_pointer_grab (GdkDisplay         *display,
     }
   else if (last_grab)
     {
-      pointer_window = _gdk_windowing_window_at_pointer (display,  &x, &y, &state);
+      pointer_window = _gdk_windowing_window_at_device_position (display, device, &x, &y, &state);
       if (pointer_window != NULL &&
 	  (GDK_WINDOW_DESTROYED (pointer_window) ||
 	   GDK_WINDOW_TYPE (pointer_window) == GDK_WINDOW_ROOT ||
diff --git a/gdk/gdkdisplay.h b/gdk/gdkdisplay.h
index 2fd775e..0e56a49 100644
--- a/gdk/gdkdisplay.h
+++ b/gdk/gdkdisplay.h
@@ -35,6 +35,7 @@ G_BEGIN_DECLS
 
 typedef struct _GdkDisplayClass GdkDisplayClass;
 typedef struct _GdkDisplayPointerHooks GdkDisplayPointerHooks;
+typedef struct _GdkDisplayDeviceHooks GdkDisplayDeviceHooks;
 
 #define GDK_TYPE_DISPLAY              (gdk_display_get_type ())
 #define GDK_DISPLAY_OBJECT(object)    (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_DISPLAY, GdkDisplay))
@@ -94,7 +95,7 @@ struct _GdkDisplay
   guint double_click_time;	/* Maximum time between clicks in msecs */
   GdkDevice *core_pointer;	/* Core pointer device */
 
-  const GdkDisplayPointerHooks *pointer_hooks; /* Current hooks for querying pointer */
+  const GdkDisplayDeviceHooks *device_hooks; /* Current hooks for querying pointer */
   
   guint closed : 1;		/* Whether this display has been closed */
   guint ignore_core_events : 1; /* Don't send core motion and button event */
@@ -146,6 +147,26 @@ struct _GdkDisplayPointerHooks
 				    gint            *win_y);
 };
 
+struct _GdkDisplayDeviceHooks
+{
+  void (* get_device_state)                  (GdkDisplay       *display,
+                                              GdkDevice        *device,
+                                              GdkScreen       **screen,
+                                              gint             *x,
+                                              gint             *y,
+                                              GdkModifierType  *mask);
+  GdkWindow * (* window_get_device_position) (GdkDisplay      *display,
+                                              GdkDevice       *device,
+                                              GdkWindow       *window,
+                                              gint            *x,
+                                              gint            *y,
+                                              GdkModifierType *mask);
+  GdkWindow * (* window_at_device_position)  (GdkDisplay *display,
+                                              GdkDevice  *device,
+                                              gint       *win_x,
+                                              gint       *win_y);
+};
+
 GType       gdk_display_get_type (void) G_GNUC_CONST;
 GdkDisplay *gdk_display_open                (const gchar *display_name);
 
@@ -199,15 +220,29 @@ void             gdk_display_warp_pointer          (GdkDisplay             *disp
 						    GdkScreen              *screen,
 						    gint                   x,
 						    gint                   y);
-void             gdk_display_warp_device           (GdkDisplay             *display,
-                                                    GdkDevice              *device,
-                                                    GdkScreen              *screen,
-                                                    gint                    x,
-                                                    gint                    y);
+
+void             gdk_display_get_device_state              (GdkDisplay            *display,
+                                                            GdkDevice             *device,
+                                                            GdkScreen            **screen,
+                                                            gint                  *x,
+                                                            gint                  *y,
+                                                            GdkModifierType       *mask);
+GdkWindow *      gdk_display_get_window_at_device_position (GdkDisplay            *display,
+                                                            GdkDevice             *device,
+                                                            gint                  *win_x,
+                                                            gint                  *win_y);
+void             gdk_display_warp_device                   (GdkDisplay            *display,
+                                                            GdkDevice             *device,
+                                                            GdkScreen             *screen,
+                                                            gint                   x,
+                                                            gint                   y);
 
 GdkDisplayPointerHooks *gdk_display_set_pointer_hooks (GdkDisplay                   *display,
 						       const GdkDisplayPointerHooks *new_hooks);
 
+GdkDisplayDeviceHooks *gdk_display_set_device_hooks (GdkDisplay                  *display,
+                                                     const GdkDisplayDeviceHooks *new_hooks);
+
 GdkDisplay *gdk_display_open_default_libgtk_only (void);
 
 gboolean gdk_display_supports_cursor_alpha     (GdkDisplay    *display);
diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h
index 022dde7..ade95ba 100644
--- a/gdk/gdkinternals.h
+++ b/gdk/gdkinternals.h
@@ -456,15 +456,17 @@ GdkRegion *_gdk_windowing_get_shape_for_mask    (GdkBitmap *mask);
 void     _gdk_windowing_window_beep             (GdkWindow *window);
 
 
-void       _gdk_windowing_get_pointer        (GdkDisplay       *display,
+void       _gdk_windowing_get_device_state   (GdkDisplay       *display,
+                                              GdkDevice        *device,
 					      GdkScreen       **screen,
 					      gint             *x,
 					      gint             *y,
 					      GdkModifierType  *mask);
-GdkWindow* _gdk_windowing_window_at_pointer  (GdkDisplay       *display,
-					      gint             *win_x,
-					      gint             *win_y,
-					      GdkModifierType  *mask);
+GdkWindow* _gdk_windowing_window_at_device_position  (GdkDisplay       *display,
+                                                      GdkDevice        *device,
+                                                      gint             *win_x,
+                                                      gint             *win_y,
+                                                      GdkModifierType  *mask);
 GdkGrabStatus _gdk_windowing_pointer_grab    (GdkWindow        *window,
 					      GdkWindow        *native,
 					      gboolean          owner_events,
diff --git a/gdk/gdkoffscreenwindow.c b/gdk/gdkoffscreenwindow.c
index a5ce61d..9970983 100644
--- a/gdk/gdkoffscreenwindow.c
+++ b/gdk/gdkoffscreenwindow.c
@@ -793,10 +793,11 @@ gdk_offscreen_window_get_deskrelative_origin (GdkWindow *window,
 }
 
 static gboolean
-gdk_offscreen_window_get_pointer (GdkWindow       *window,
-				  gint            *x,
-				  gint            *y,
-				  GdkModifierType *mask)
+gdk_offscreen_window_get_device_state (GdkWindow       *window,
+                                       GdkDevice       *device,
+                                       gint            *x,
+                                       gint            *y,
+                                       GdkModifierType *mask)
 {
   GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
   GdkOffscreenWindow *offscreen;
@@ -811,7 +812,7 @@ gdk_offscreen_window_get_pointer (GdkWindow       *window,
   offscreen = GDK_OFFSCREEN_WINDOW (private->impl);
   if (offscreen->embedder != NULL)
     {
-      gdk_window_get_pointer (offscreen->embedder, &tmpx, &tmpy, &tmpmask);
+      gdk_window_get_device_position (offscreen->embedder, device, &tmpx, &tmpy, &tmpmask);
       from_embedder (window,
 		     tmpx, tmpy,
 		     &dtmpx, &dtmpy);
@@ -1251,7 +1252,7 @@ gdk_offscreen_window_impl_iface_init (GdkWindowImplIface *iface)
   iface->queue_translation = gdk_offscreen_window_queue_translation;
   iface->get_root_coords = gdk_offscreen_window_get_root_coords;
   iface->get_deskrelative_origin = gdk_offscreen_window_get_deskrelative_origin;
-  iface->get_pointer = gdk_offscreen_window_get_pointer;
+  iface->get_device_state = gdk_offscreen_window_get_device_state;
   iface->destroy = gdk_offscreen_window_destroy;
 }
 
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index 8186aab..cf9f783 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -5602,29 +5602,32 @@ gdk_window_get_pointer (GdkWindow	  *window,
 			GdkModifierType   *mask)
 {
   GdkDisplay *display;
-  gint tmp_x, tmp_y;
-  GdkModifierType tmp_mask;
-  GdkWindow *child;
 
-  g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
+  g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
 
-  if (window)
-    {
-      display = gdk_drawable_get_display (window);
-    }
-  else
-    {
-      GdkScreen *screen = gdk_screen_get_default ();
+  display = gdk_drawable_get_display (window);
 
-      display = gdk_screen_get_display (screen);
-      window = gdk_screen_get_root_window (screen);
+  return gdk_window_get_device_position (window, display->core_pointer, x, y, mask);
+}
 
-      GDK_NOTE (MULTIHEAD,
-		g_message ("Passing NULL for window to gdk_window_get_pointer()\n"
-			   "is not multihead safe"));
-    }
+GdkWindow *
+gdk_window_get_device_position (GdkWindow       *window,
+                                GdkDevice       *device,
+                                gint            *x,
+                                gint            *y,
+                                GdkModifierType *mask)
+{
+  GdkDisplay *display;
+  gint tmp_x, tmp_y;
+  GdkModifierType tmp_mask;
+  GdkWindow *child;
 
-  child = display->pointer_hooks->window_get_pointer (display, window, &tmp_x, &tmp_y, &tmp_mask);
+  g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
+  g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
+
+  display = gdk_drawable_get_display (window);
+  child = display->device_hooks->window_get_device_position (display, device, window,
+                                                             &tmp_x, &tmp_y, &tmp_mask);
 
   if (x)
     *x = tmp_x;
diff --git a/gdk/gdkwindow.h b/gdk/gdkwindow.h
index 6018d06..7b48b62 100644
--- a/gdk/gdkwindow.h
+++ b/gdk/gdkwindow.h
@@ -556,6 +556,11 @@ GdkWindow*    gdk_window_get_pointer	 (GdkWindow	  *window,
 					  gint		  *x,
 					  gint		  *y,
 					  GdkModifierType *mask);
+GdkWindow *   gdk_window_get_device_position (GdkWindow       *window,
+                                              GdkDevice       *device,
+                                              gint            *x,
+                                              gint            *y,
+                                              GdkModifierType *mask);
 GdkWindow *   gdk_window_get_parent      (GdkWindow       *window);
 GdkWindow *   gdk_window_get_toplevel    (GdkWindow       *window);
 
diff --git a/gdk/gdkwindowimpl.h b/gdk/gdkwindowimpl.h
index 2e5800f..044ec48 100644
--- a/gdk/gdkwindowimpl.h
+++ b/gdk/gdkwindowimpl.h
@@ -93,10 +93,11 @@ struct _GdkWindowImplIface
   gint         (* get_deskrelative_origin) (GdkWindow       *window,
                                          gint            *x,
                                          gint            *y);
-  gboolean     (* get_pointer)          (GdkWindow       *window,
+  gboolean     (* get_device_state)     (GdkWindow       *window,
+                                         GdkDevice       *device,
                                          gint            *x,
                                          gint            *y,
-					 GdkModifierType  *mask);
+                                         GdkModifierType *mask);
 
   void         (* shape_combine_region) (GdkWindow       *window,
                                          const GdkRegion *shape_region,
diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c
index f8ed7d2..f136645 100644
--- a/gdk/x11/gdkwindow-x11.c
+++ b/gdk/x11/gdkwindow-x11.c
@@ -3050,106 +3050,112 @@ gdk_window_get_frame_extents (GdkWindow    *window,
 }
 
 void
-_gdk_windowing_get_pointer (GdkDisplay       *display,
-			    GdkScreen       **screen,
-			    gint             *x,
-			    gint             *y,
-			    GdkModifierType  *mask)
+_gdk_windowing_get_device_state (GdkDisplay       *display,
+                                 GdkDevice        *device,
+                                 GdkScreen       **screen,
+                                 gint             *x,
+                                 gint             *y,
+                                 GdkModifierType  *mask)
 {
   GdkScreen *default_screen;
-  Display *xdisplay;
-  Window xwindow;
-  Window root = None;
-  Window child;
-  int rootx, rooty;
-  int winx;
-  int winy;
-  unsigned int xmask;
 
   if (display->closed)
     return;
 
   default_screen = gdk_display_get_default_screen (display);
 
-  xdisplay = GDK_SCREEN_XDISPLAY (default_screen);
-  xwindow = GDK_SCREEN_XROOTWIN (default_screen);
-  
-  if (G_LIKELY (GDK_DISPLAY_X11 (display)->trusted_client)) 
+
+  if (G_LIKELY (GDK_DISPLAY_X11 (display)->trusted_client))
     {
-      XQueryPointer (xdisplay, xwindow,
-		     &root, &child, &rootx, &rooty, &winx, &winy, &xmask);
-    } 
-  else 
+      GdkWindow *root;
+
+      GDK_DEVICE_GET_CLASS (device)->query_state (device,
+                                                  gdk_screen_get_root_window (default_screen),
+                                                  &root, NULL,
+                                                  x, y,
+                                                  NULL, NULL,
+                                                  mask);
+      *screen = gdk_drawable_get_screen (root);
+    }
+  else
     {
       XSetWindowAttributes attributes;
-      Window w;
-      
-      w = XCreateWindow (xdisplay, xwindow, 0, 0, 1, 1, 0, 
-			 CopyFromParent, InputOnly, CopyFromParent, 
+      Display *xdisplay;
+      Window xwindow, w, root, child;
+      int rootx, rooty, winx, winy;
+      unsigned int xmask;
+
+      /* FIXME: untrusted clients not multidevice-safe */
+
+      xdisplay = GDK_SCREEN_XDISPLAY (default_screen);
+      xwindow = GDK_SCREEN_XROOTWIN (default_screen);
+
+      w = XCreateWindow (xdisplay, xwindow, 0, 0, 1, 1, 0,
+			 CopyFromParent, InputOnly, CopyFromParent,
 			 0, &attributes);
-      XQueryPointer (xdisplay, w, 
+      XQueryPointer (xdisplay, w,
 		     &root, &child, &rootx, &rooty, &winx, &winy, &xmask);
       XDestroyWindow (xdisplay, w);
+
+      if (root != None)
+        {
+          GdkWindow *gdk_root = gdk_window_lookup_for_display (display, root);
+          *screen = gdk_drawable_get_screen (gdk_root);
+        }
+
+      *x = rootx;
+      *y = rooty;
+      *mask = xmask;
     }
-  
-  if (root != None)
-    {
-      GdkWindow *gdk_root = gdk_window_lookup_for_display (display, root);
-      *screen = gdk_drawable_get_screen (gdk_root);
-    }
-  
-  *x = rootx;
-  *y = rooty;
-  *mask = xmask;
 }
 
 static gboolean
-gdk_window_x11_get_pointer (GdkWindow       *window,
-			    gint            *x,
-			    gint            *y,
-			    GdkModifierType *mask)
+gdk_window_x11_get_device_state (GdkWindow       *window,
+                                 GdkDevice       *device,
+                                 gint            *x,
+                                 gint            *y,
+                                 GdkModifierType *mask)
 {
   GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
   gboolean return_val;
-  Window root;
-  Window child;
-  int rootx, rooty;
-  int winx = 0;
-  int winy = 0;
-  unsigned int xmask = 0;
 
   g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), FALSE);
 
-  
   return_val = TRUE;
+
   if (!GDK_WINDOW_DESTROYED (window))
     {
       if (G_LIKELY (GDK_DISPLAY_X11 (display)->trusted_client))
 	{
-	  if (XQueryPointer (GDK_WINDOW_XDISPLAY (window),
-			     GDK_WINDOW_XID (window),
-			     &root, &child, &rootx, &rooty, &winx, &winy, &xmask))
-	    {
-	      if (child)
-		return_val = gdk_window_lookup_for_display (GDK_WINDOW_DISPLAY (window), child) != NULL;
-	    }
+          GdkWindow *child;
+
+          GDK_DEVICE_GET_CLASS (device)->query_state (device, window,
+                                                      NULL, &child,
+                                                      NULL, NULL,
+                                                      x, y, mask);
+          return_val = (child != NULL);
 	}
       else
 	{
 	  GdkScreen *screen;
 	  int originx, originy;
-	  _gdk_windowing_get_pointer (gdk_drawable_get_display (window), &screen,
-				      &rootx, &rooty, &xmask);
+          int rootx, rooty;
+          int winx = 0;
+          int winy = 0;
+          unsigned int xmask = 0;
+
+          _gdk_windowing_get_device_state (gdk_drawable_get_display (window), device,
+                                           &screen, &rootx, &rooty, &xmask);
 	  gdk_window_get_origin (window, &originx, &originy);
 	  winx = rootx - originx;
 	  winy = rooty - originy;
+
+          *x = winx;
+          *y = winy;
+          *mask = xmask;
 	}
     }
 
-  *x = winx;
-  *y = winy;
-  *mask = xmask;
-
   return return_val;
 }
 
@@ -3205,26 +3211,16 @@ gdk_display_warp_device (GdkDisplay *display,
 }
 
 GdkWindow*
-_gdk_windowing_window_at_pointer (GdkDisplay *display,
-                                  gint       *win_x,
-				  gint       *win_y,
-				  GdkModifierType *mask)
+_gdk_windowing_window_at_device_position (GdkDisplay      *display,
+                                          GdkDevice       *device,
+                                          gint            *win_x,
+                                          gint            *win_y,
+                                          GdkModifierType *mask)
 {
   GdkWindow *window;
   GdkScreen *screen;
-  Window root;
-  Window xwindow;
-  Window child;
-  Window xwindow_last = 0;
-  Display *xdisplay;
-  int rootx = -1, rooty = -1;
-  int winx, winy;
-  unsigned int xmask;
 
   screen = gdk_display_get_default_screen (display);
-  
-  xwindow = GDK_SCREEN_XROOTWIN (screen);
-  xdisplay = GDK_SCREEN_XDISPLAY (screen);
 
   /* This function really only works if the mouse pointer is held still
    * during its operation. If it moves from one leaf window to another
@@ -3232,28 +3228,28 @@ _gdk_windowing_window_at_pointer (GdkDisplay *display,
    * and the result.
    */
   gdk_x11_display_grab (display);
-  if (G_LIKELY (GDK_DISPLAY_X11 (display)->trusted_client)) 
+  if (G_LIKELY (GDK_DISPLAY_X11 (display)->trusted_client))
     {
-      XQueryPointer (xdisplay, xwindow,
-		     &root, &child, &rootx, &rooty, &winx, &winy, &xmask);
-      if (root == xwindow)
-	xwindow = child;
-      else
-	xwindow = root;
-      
-      while (xwindow)
-	{
-	  xwindow_last = xwindow;
-	  XQueryPointer (xdisplay, xwindow,
-			 &root, &xwindow, &rootx, &rooty, &winx, &winy, &xmask);
-	}
-    } 
-  else 
+      window = GDK_DEVICE_GET_CLASS (device)->window_at_position (device, win_x, win_y);
+      GDK_DEVICE_GET_CLASS (device)->query_state (device, window, NULL, NULL,
+                                                  NULL, NULL, NULL, NULL, mask);
+    }
+  else
     {
       gint i, screens, width, height;
       GList *toplevels, *list;
-      Window pointer_window;
-      
+      Window pointer_window, root, xwindow, child;
+      Window xwindow_last = 0;
+      Display *xdisplay;
+      int rootx = -1, rooty = -1;
+      int winx, winy;
+      unsigned int xmask;
+
+      /* FIXME: untrusted clients case not multidevice-safe */
+
+      xwindow = GDK_SCREEN_XROOTWIN (screen);
+      xdisplay = GDK_SCREEN_XDISPLAY (screen);
+
       pointer_window = None;
       screens = gdk_display_get_n_screens (display);
       for (i = 0; i < screens; ++i) {
@@ -3310,16 +3306,18 @@ _gdk_windowing_window_at_pointer (GdkDisplay *display,
 	  if (gdk_error_trap_pop ())
 	    break;
 	}
+
+      window = gdk_window_lookup_for_display (display, xwindow_last);
+
+      *win_x = window ? winx : -1;
+      *win_y = window ? winy : -1;
+      if (mask)
+        *mask = xmask;
     }
-  
+
   gdk_x11_display_ungrab (display);
 
-  window = gdk_window_lookup_for_display (display, xwindow_last);
-  *win_x = window ? winx : -1;
-  *win_y = window ? winy : -1;
-  if (mask)
-    *mask = xmask;
-  
+
   return window;
 }
 
@@ -5589,7 +5587,7 @@ gdk_window_impl_iface_init (GdkWindowImplIface *iface)
   iface->set_device_cursor = gdk_window_x11_set_device_cursor;
   iface->get_geometry = gdk_window_x11_get_geometry;
   iface->get_root_coords = gdk_window_x11_get_root_coords;
-  iface->get_pointer = gdk_window_x11_get_pointer;
+  iface->get_device_state = gdk_window_x11_get_device_state;
   iface->get_deskrelative_origin = gdk_window_x11_get_deskrelative_origin;
   iface->shape_combine_region = gdk_window_x11_shape_combine_region;
   iface->input_shape_combine_region = gdk_window_x11_input_shape_combine_region;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]