summaryrefslogtreecommitdiff
path: root/gdk
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>2002-10-07 19:42:49 +0000
committerOwen Taylor <otaylor@src.gnome.org>2002-10-07 19:42:49 +0000
commit253458ec525ac1d1ed45ce47a79365df7905e01f (patch)
tree3712ec56f7242c2d56b4c8dfbdb03e9aff4ff8df /gdk
parent55704fc7c1b5429bf8cc7e8100893b01898a9fe8 (diff)
downloadgtk+-253458ec525ac1d1ed45ce47a79365df7905e01f.tar.gz
- Replace GdkPointerHooks with a multihead-safe GdkDisplayPointerHooks,
Mon Oct 7 15:10:00 2002 Owen Taylor <otaylor@redhat.com> * gdk/gdkdisplay.[ch] gdk/gdkinternals.h gdk/gdkwindow.[ch] gdk/linux-fb/gdkwindow-fb.c gdk/win32/gdkwindow-win32.c gdk/x11/gdkwindow-x11.c: - Replace GdkPointerHooks with a multihead-safe GdkDisplayPointerHooks, leave GdkPointerHooks around for singlehead. - Add gdk_display_get_pointer() to get the pointer location with the screen it is on. * gdk/gdk.def gdk/gdkdisplay.[ch] gdk/gdkscreen.[ch]: Change gdk_screen_get_window_at_pointer() to gdk_display_get_window_at_pointer(). * gtk/gtktreeview.c demos/gtk-demo/changedisplay.c tests/testgtk.c: Use gdk_display_get_window_at_pointer(), not gdk_screen_get_window_at_pointer(). * gtk/gtkcolorsel.c: Fix grabbing color to be multihead safe. * gtk/gtkwidget.c: Allow gtk_widget_push_colormap (NULL). since it is useful for writing code that doesn't know the dcurrent state but needs a clean colormap. * gtk/gtkrc.c: When loading the settings for a particular screen, only reset toplevels on that screen. * gtk/gtkiconfactory.h: Fix #ifdef GTK_MULTIHEAD_SAFE that should have been #ifndef GTK_MULTIHEAD_SAFE.
Diffstat (limited to 'gdk')
-rw-r--r--gdk/gdk.def2
-rw-r--r--gdk/gdkdisplay.c232
-rw-r--r--gdk/gdkdisplay.h32
-rw-r--r--gdk/gdkinternals.h22
-rw-r--r--gdk/gdkscreen.c21
-rw-r--r--gdk/gdkscreen.h3
-rw-r--r--gdk/gdkwindow.c74
-rw-r--r--gdk/gdkwindow.h4
-rw-r--r--gdk/linux-fb/gdkwindow-fb.c40
-rw-r--r--gdk/win32/gdkwindow-win32.c79
-rw-r--r--gdk/x11/gdkwindow-x11.c83
11 files changed, 440 insertions, 152 deletions
diff --git a/gdk/gdk.def b/gdk/gdk.def
index a65785c323..04e402f6dd 100644
--- a/gdk/gdk.def
+++ b/gdk/gdk.def
@@ -62,6 +62,7 @@ EXPORTS
gdk_display_get_n_screens
gdk_display_get_screen
gdk_display_get_type
+ gdk_display_get_window_at_pointer
gdk_display_keyboard_ungrab
gdk_display_pointer_is_grabbed
gdk_display_pointer_ungrab
@@ -335,7 +336,6 @@ EXPORTS
gdk_screen_get_system_colormap
gdk_screen_get_type
gdk_screen_get_width
- gdk_screen_get_window_at_pointer
gdk_screen_height
gdk_screen_height_mm
gdk_screen_set_default_colormap
diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c
index 453188268e..bed6ef9ddc 100644
--- a/gdk/gdkdisplay.c
+++ b/gdk/gdkdisplay.c
@@ -38,11 +38,53 @@ static void gdk_display_init (GdkDisplay *display);
static void gdk_display_dispose (GObject *object);
static void gdk_display_finalize (GObject *object);
+
+void singlehead_get_pointer (GdkDisplay *display,
+ GdkScreen **screen,
+ gint *x,
+ gint *y,
+ GdkModifierType *mask);
+GdkWindow* singlehead_window_get_pointer (GdkDisplay *display,
+ GdkWindow *window,
+ gint *x,
+ gint *y,
+ GdkModifierType *mask);
+GdkWindow* singlehead_window_at_pointer (GdkDisplay *display,
+ gint *win_x,
+ gint *win_y);
+
+GdkWindow* singlehead_default_window_get_pointer (GdkWindow *window,
+ gint *x,
+ gint *y,
+ GdkModifierType *mask);
+GdkWindow* singlehead_default_window_at_pointer (GdkScreen *screen,
+ gint *win_x,
+ gint *win_y);
+
static guint signals[LAST_SIGNAL] = { 0 };
static GObjectClass *parent_class;
static char *gdk_sm_client_id;
+static const GdkDisplayPointerHooks default_pointer_hooks = {
+ _gdk_windowing_get_pointer,
+ _gdk_windowing_window_get_pointer,
+ _gdk_windowing_window_at_pointer
+};
+
+static const GdkDisplayPointerHooks singlehead_pointer_hooks = {
+ singlehead_get_pointer,
+ singlehead_window_get_pointer,
+ singlehead_window_at_pointer
+};
+
+static const GdkPointerHooks singlehead_default_pointer_hooks = {
+ singlehead_default_window_get_pointer,
+ singlehead_default_window_at_pointer
+};
+
+static const GdkPointerHooks *singlehead_current_pointer_hooks = &singlehead_default_pointer_hooks;
+
GType
gdk_display_get_type (void)
{
@@ -101,6 +143,8 @@ gdk_display_init (GdkDisplay *display)
display->button_number[0] = display->button_number[1] = -1;
display->double_click_time = 250;
+
+ display->pointer_hooks = &default_pointer_hooks;
}
static void
@@ -379,3 +423,191 @@ _gdk_get_sm_client_id (void)
{
return gdk_sm_client_id;
}
+
+/**
+ * gdk_display_get_pointer:
+ * @display: a #GdkDisplay
+ * @screen: location to store the screen that the
+ * cursor is on, or %NULL.
+ * @x: location to store root window X coordinate of pointer, or %NULL.
+ * @y: location to store root window Y coordinate of pointer, or %NULL.
+ * @mask: location to store current modifier mask, or %NULL
+ *
+ * Gets the current location of the pointer and the current modifier
+ * mask for a given display.
+ **/
+void
+gdk_display_get_pointer (GdkDisplay *display,
+ 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));
+
+ 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_window_at_pointer:
+ * @display: a #GdkDisplay
+ * @win_x: return location for origin of the window under the pointer
+ * @win_y: return location for origin of the window under the pointer
+ *
+ * Obtains the window underneath the mouse pointer, returning the location
+ * of that window in @win_x, @win_y for @screen. Returns %NULL if the window
+ * under the mouse pointer is not known to GDK (for example, belongs to
+ * another application).
+ *
+ * Returns: the window under the mouse pointer, or %NULL
+ **/
+GdkWindow *
+gdk_display_get_window_at_pointer (GdkDisplay *display,
+ gint *win_x,
+ gint *win_y)
+{
+ gint tmp_x, tmp_y;
+
+ g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
+
+ return display->pointer_hooks->window_at_pointer (display, &tmp_x, &tmp_y);
+
+ if (win_x)
+ *win_x = tmp_x;
+ if (win_y)
+ *win_y = tmp_y;
+}
+
+/**
+ * gdk_display_set_pointer_hooks:
+ * @new_hooks: a table of pointers to functions for getting
+ * quantities related to the current pointer position,
+ * or %NULL to restore the default table.
+ *
+ * This function allows for hooking into the operation
+ * of getting the current location of the pointer on a particular
+ * display. This is only useful for such low-level tools as an
+ * event recorder. Applications should never have any
+ * reason to use this facility.
+ *
+ * Return value: the previous pointer hook table
+ **/
+GdkDisplayPointerHooks *
+gdk_display_set_pointer_hooks (GdkDisplay *display,
+ const GdkDisplayPointerHooks *new_hooks)
+{
+ const GdkDisplayPointerHooks *result;
+
+ g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
+ result = display->pointer_hooks;
+
+ if (new_hooks)
+ display->pointer_hooks = new_hooks;
+ else
+ display->pointer_hooks = &default_pointer_hooks;
+
+ return (GdkDisplayPointerHooks *)result;
+}
+
+void
+singlehead_get_pointer (GdkDisplay *display,
+ GdkScreen **screen,
+ gint *x,
+ gint *y,
+ GdkModifierType *mask)
+{
+ GdkScreen *default_screen = gdk_display_get_default_screen (display);
+ GdkWindow *root_window = gdk_screen_get_root_window (default_screen);
+
+ *screen = default_screen;
+
+ singlehead_current_pointer_hooks->get_pointer (root_window, x, y, mask);
+}
+
+GdkWindow*
+singlehead_window_get_pointer (GdkDisplay *display,
+ GdkWindow *window,
+ gint *x,
+ gint *y,
+ GdkModifierType *mask)
+{
+ return singlehead_current_pointer_hooks->get_pointer (window, x, y, mask);
+}
+
+GdkWindow*
+singlehead_window_at_pointer (GdkDisplay *display,
+ gint *win_x,
+ gint *win_y)
+{
+ GdkScreen *default_screen = gdk_display_get_default_screen (display);
+
+ return singlehead_current_pointer_hooks->window_at_pointer (default_screen,
+ win_x, win_y);
+}
+
+GdkWindow*
+singlehead_default_window_get_pointer (GdkWindow *window,
+ gint *x,
+ gint *y,
+ GdkModifierType *mask)
+{
+ return _gdk_windowing_window_get_pointer (gdk_drawable_get_display (window),
+ window, x, y, mask);
+}
+
+GdkWindow*
+singlehead_default_window_at_pointer (GdkScreen *screen,
+ gint *win_x,
+ gint *win_y)
+{
+ return _gdk_windowing_window_at_pointer (gdk_screen_get_display (screen),
+ win_x, win_y);
+}
+
+/**
+ * gdk_set_pointer_hooks:
+ * @new_hooks: a table of pointers to functions for getting
+ * quantities related to the current pointer position,
+ * or %NULL to restore the default table.
+ *
+ * This function allows for hooking into the operation
+ * of getting the current location of the pointer. This
+ * is only useful for such low-level tools as an
+ * event recorder. Applications should never have any
+ * reason to use this facility.
+ *
+ * This function is not multihead safe. For multihead operation,
+ * see gdk_display_set_pointer_hooks().
+ *
+ * Return value: the previous pointer hook table
+ **/
+GdkPointerHooks *
+gdk_set_pointer_hooks (const GdkPointerHooks *new_hooks)
+{
+ const GdkPointerHooks *result = singlehead_current_pointer_hooks;
+
+ if (new_hooks)
+ singlehead_current_pointer_hooks = new_hooks;
+ else
+ singlehead_current_pointer_hooks = &singlehead_default_pointer_hooks;
+
+ gdk_display_set_pointer_hooks (gdk_display_get_default (),
+ &singlehead_pointer_hooks);
+
+ return (GdkPointerHooks *)result;
+}
+
+
diff --git a/gdk/gdkdisplay.h b/gdk/gdkdisplay.h
index f555517ece..a7f7234924 100644
--- a/gdk/gdkdisplay.h
+++ b/gdk/gdkdisplay.h
@@ -31,6 +31,7 @@
G_BEGIN_DECLS
typedef struct _GdkDisplayClass GdkDisplayClass;
+typedef struct _GdkDisplayPointerHooks GdkDisplayPointerHooks;
#define GDK_TYPE_DISPLAY (gdk_display_get_type ())
#define GDK_DISPLAY_OBJECT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_DISPLAY, GdkDisplay))
@@ -58,6 +59,8 @@ 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 */
+
guint closed : 1; /* Whether this display has been closed */
};
@@ -77,6 +80,23 @@ struct _GdkDisplayClass
gboolean is_error);
};
+struct _GdkDisplayPointerHooks
+{
+ void (*get_pointer) (GdkDisplay *display,
+ GdkScreen **screen,
+ gint *x,
+ gint *y,
+ GdkModifierType *mask);
+ GdkWindow* (*window_get_pointer) (GdkDisplay *display,
+ GdkWindow *window,
+ gint *x,
+ gint *y,
+ GdkModifierType *mask);
+ GdkWindow* (*window_at_pointer) (GdkDisplay *display,
+ gint *win_x,
+ gint *win_y);
+};
+
GType gdk_display_get_type (void);
GdkDisplay *gdk_display_open (const gchar *display_name);
@@ -114,6 +134,18 @@ GdkDisplay *gdk_display_get_default (void);
GdkDevice *gdk_display_get_core_pointer (GdkDisplay *display);
+void gdk_display_get_pointer (GdkDisplay *display,
+ GdkScreen **screen,
+ gint *x,
+ gint *y,
+ GdkModifierType *mask);
+GdkWindow * gdk_display_get_window_at_pointer (GdkDisplay *display,
+ gint *win_x,
+ gint *win_y);
+
+GdkDisplayPointerHooks *gdk_display_set_pointer_hooks (GdkDisplay *display,
+ const GdkDisplayPointerHooks *new_hooks);
+
G_END_DECLS
#endif /* __GDK_DISPLAY_H__ */
diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h
index bc00798b06..3805c15504 100644
--- a/gdk/gdkinternals.h
+++ b/gdk/gdkinternals.h
@@ -167,8 +167,6 @@ extern GDestroyNotify _gdk_event_notify;
extern GSList *_gdk_displays;
extern gchar *_gdk_display_name;
-extern const GdkPointerHooks *_gdk_current_pointer_hooks;
-
void _gdk_events_queue (GdkDisplay *display);
GdkEvent* _gdk_event_unqueue (GdkDisplay *display);
@@ -252,13 +250,19 @@ void _gdk_windowing_window_clear_area_e (GdkWindow *window,
gint width,
gint height);
-GdkWindow* _gdk_windowing_window_at_pointer (GdkScreen *screen,
- gint *win_x,
- gint *win_y);
-GdkWindow* _gdk_windowing_window_get_pointer (GdkWindow *window,
- gint *x,
- gint *y,
- GdkModifierType *mask);
+void _gdk_windowing_get_pointer (GdkDisplay *display,
+ GdkScreen **screen,
+ gint *x,
+ gint *y,
+ GdkModifierType *mask);
+GdkWindow* _gdk_windowing_window_get_pointer (GdkDisplay *display,
+ GdkWindow *window,
+ gint *x,
+ gint *y,
+ GdkModifierType *mask);
+GdkWindow* _gdk_windowing_window_at_pointer (GdkDisplay *display,
+ gint *win_x,
+ gint *win_y);
/* Return the number of bits-per-pixel for images of the specified depth. */
gint _gdk_windowing_get_bits_for_depth (GdkDisplay *display,
diff --git a/gdk/gdkscreen.c b/gdk/gdkscreen.c
index 508803e412..564328ff75 100644
--- a/gdk/gdkscreen.c
+++ b/gdk/gdkscreen.c
@@ -221,24 +221,3 @@ gdk_screen_height_mm (void)
{
return gdk_screen_get_height_mm (gdk_screen_get_default ());
}
-
-/**
- * gdk_screen_get_window_at_pointer:
- * @screen: a #GdkScreen
- * @win_x: return location for origin of the window under the pointer
- * @win_y: return location for origin of the window under the pointer
- *
- * Obtains the window underneath the mouse pointer, returning the location
- * of that window in @win_x, @win_y for @screen. Returns %NULL if the window
- * under the mouse pointer is not known to GDK (for example, belongs to
- * another application).
- *
- * Returns: the window under the mouse pointer, or %NULL
- **/
-GdkWindow *
-gdk_screen_get_window_at_pointer (GdkScreen *screen,
- gint *win_x,
- gint *win_y)
-{
- return _gdk_current_pointer_hooks->window_at_pointer (screen, win_x, win_y);
-}
diff --git a/gdk/gdkscreen.h b/gdk/gdkscreen.h
index 1308eaeacd..2e2b199286 100644
--- a/gdk/gdkscreen.h
+++ b/gdk/gdkscreen.h
@@ -64,9 +64,6 @@ GdkVisual * gdk_screen_get_rgb_visual (GdkScreen *screen);
GdkWindow * gdk_screen_get_root_window (GdkScreen *screen);
GdkDisplay * gdk_screen_get_display (GdkScreen *screen);
gint gdk_screen_get_number (GdkScreen *screen);
-GdkWindow * gdk_screen_get_window_at_pointer (GdkScreen *screen,
- gint *win_x,
- gint *win_y);
gint gdk_screen_get_width (GdkScreen *screen);
gint gdk_screen_get_height (GdkScreen *screen);
gint gdk_screen_get_width_mm (GdkScreen *screen);
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index 38e18064c8..f7fc5a3db4 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -44,13 +44,6 @@ struct _GdkWindowPaint
gint y_offset;
};
-static const GdkPointerHooks default_pointer_hooks = {
- _gdk_windowing_window_get_pointer,
- _gdk_windowing_window_at_pointer
-};
-
-const GdkPointerHooks *_gdk_current_pointer_hooks = &default_pointer_hooks;
-
static GdkGC *gdk_window_create_gc (GdkDrawable *drawable,
GdkGCValues *values,
GdkGCValuesMask mask);
@@ -2699,33 +2692,6 @@ gdk_window_constrain_size (GdkGeometry *geometry,
}
/**
- * gdk_set_pointer_hooks:
- * @new_hooks: a table of pointers to functions for getting
- * quantities related to the current pointer position,
- * or %NULL to restore the default table.
- *
- * This function allows for hooking into the operation
- * of getting the current location of the pointer. This
- * is only useful for such low-level tools as an
- * event recorder. Applications should never have any
- * reason to use this facility
- *
- * Return value: the previous pointer hook table
- **/
-GdkPointerHooks *
-gdk_set_pointer_hooks (const GdkPointerHooks *new_hooks)
-{
- const GdkPointerHooks *result = _gdk_current_pointer_hooks;
-
- if (new_hooks)
- _gdk_current_pointer_hooks = new_hooks;
- else
- _gdk_current_pointer_hooks = &default_pointer_hooks;
-
- return (GdkPointerHooks *)result;
-}
-
-/**
* gdk_window_get_pointer:
* @window: a #GdkWindow
* @x: return location for X coordinate of pointer
@@ -2743,11 +2709,41 @@ GdkWindow*
gdk_window_get_pointer (GdkWindow *window,
gint *x,
gint *y,
- GdkModifierType *mask)
+ GdkModifierType *mask)
{
- g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
+ GdkDisplay *display;
+ gint tmp_x, tmp_y;
+ GdkModifierType tmp_mask;
+ GdkWindow *child;
- return _gdk_current_pointer_hooks->get_pointer (window, x, y, mask);
+ g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
+
+ if (window)
+ {
+ display = gdk_drawable_get_display (window);
+ }
+ else
+ {
+ GdkScreen *screen = gdk_screen_get_default ();
+
+ display = gdk_screen_get_display (screen);
+ window = gdk_screen_get_root_window (screen);
+
+ GDK_NOTE (MULTIHEAD,
+ g_message ("Passing NULL for window to gdk_window_get_pointer()\n"
+ "is not multihead safe"));
+ }
+
+ child = display->pointer_hooks->window_get_pointer (display, window, &tmp_x, &tmp_y, &tmp_mask);
+
+ if (x)
+ *x = tmp_x;
+ if (y)
+ *y = tmp_y;
+ if (mask)
+ *mask = tmp_mask;
+
+ return child;
}
/**
@@ -2762,7 +2758,7 @@ gdk_window_get_pointer (GdkWindow *window,
* for it with gdk_window_foreign_new())
*
* NOTE: For multihead-aware widgets or applications use
- * gdk_screen_get_window_at_pointer() instead.
+ * gdk_display_get_window_at_pointer() instead.
*
* Return value: window under the mouse pointer
**/
@@ -2770,7 +2766,7 @@ GdkWindow*
gdk_window_at_pointer (gint *win_x,
gint *win_y)
{
- return gdk_screen_get_window_at_pointer (gdk_screen_get_default (), win_x, win_y);
+ return gdk_display_get_window_at_pointer (gdk_display_get_default (), win_x, win_y);
}
/**
diff --git a/gdk/gdkwindow.h b/gdk/gdkwindow.h
index 3f22ae8662..f8524c2ab7 100644
--- a/gdk/gdkwindow.h
+++ b/gdk/gdkwindow.h
@@ -207,7 +207,7 @@ struct _GdkPointerHooks
gint *x,
gint *y,
GdkModifierType *mask);
- GdkWindow* (*window_at_pointer) (GdkScreen *screen, /* unused for now*/
+ GdkWindow* (*window_at_pointer) (GdkScreen *screen, /* unused */
gint *win_x,
gint *win_y);
};
@@ -551,7 +551,9 @@ void gdk_window_get_internal_paint_info (GdkWindow *window,
gint *x_offset,
gint *y_offset);
+#ifndef GDK_MULTIHEAD_SAFE
GdkPointerHooks *gdk_set_pointer_hooks (const GdkPointerHooks *new_hooks);
+#endif /* GDK_MULTIHEAD_SAFE */
GdkWindow *gdk_get_default_root_window (void);
diff --git a/gdk/linux-fb/gdkwindow-fb.c b/gdk/linux-fb/gdkwindow-fb.c
index eab26faca2..bbb3a7adc4 100644
--- a/gdk/linux-fb/gdkwindow-fb.c
+++ b/gdk/linux-fb/gdkwindow-fb.c
@@ -1631,26 +1631,18 @@ _gdk_windowing_window_get_pointer (GdkWindow *window,
int winy = 0;
int x_int, y_int;
gint shape_dx, shape_dy;
- GdkModifierType my_mask;
GdkRegion *shape;
g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
- if (!window)
- window = _gdk_parent_root;
-
gdk_window_get_root_origin (window, &x_int, &y_int);
- gdk_fb_mouse_get_info (&winx, &winy, &my_mask);
+ gdk_fb_mouse_get_info (&winx, &winy, mask);
winx -= x_int;
winy -= y_int;
- if (x)
- *x = winx;
- if (y)
- *y = winy;
- if (mask)
- *mask = my_mask;
+ *x = winx;
+ *y = winy;
return_val = NULL;
@@ -1704,10 +1696,24 @@ _gdk_windowing_window_get_pointer (GdkWindow *window,
return return_val;
}
+void
+_gdk_windowing_get_pointer (GdkDisplay *display,
+ GdkScreen **screen,
+ gint *x,
+ gint *y,
+ GdkModifierType *mask)
+{
+ GdkScreen *default_screen = gdk_display_get_default_screen (display);
+ GdkWindow *root_window = gdk_screen_get_root_window (screen);
+
+ *screen = default_screen;
+ _gdk_windowing_window_get_pointer (root_window, x, y, mask);
+}
+
GdkWindow*
-_gdk_windowing_window_at_pointer (GdkScreen *screen,
- gint *win_x,
- gint *win_y)
+_gdk_windowing_window_at_pointer (GdkDisplay *display,
+ gint *win_x,
+ gint *win_y)
{
gint rx, ry;
GdkWindow *retval = gdk_window_get_pointer (NULL, win_x, win_y, NULL);
@@ -1715,10 +1721,8 @@ _gdk_windowing_window_at_pointer (GdkScreen *screen,
if (retval)
{
gdk_window_get_origin (retval, &ry, &rx);
- if (win_x)
- (*win_x) -= rx;
- if (win_y)
- (*win_y) -= ry;
+ (*win_x) -= rx;
+ (*win_y) -= ry;
}
return retval;
diff --git a/gdk/win32/gdkwindow-win32.c b/gdk/win32/gdkwindow-win32.c
index bdb952d019..e57bd626d4 100644
--- a/gdk/win32/gdkwindow-win32.c
+++ b/gdk/win32/gdkwindow-win32.c
@@ -1831,21 +1831,17 @@ _gdk_windowing_window_get_pointer (GdkWindow *window,
GdkWindow *return_val;
POINT screen_point, point;
HWND hwnd, hwndc;
+ BYTE kbd[256];
g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
- if (!window)
- window = _gdk_parent_root;
-
return_val = NULL;
GetCursorPos (&screen_point);
point = screen_point;
ScreenToClient (GDK_WINDOW_HWND (window), &point);
- if (x)
- *x = point.x;
- if (y)
- *y = point.y;
+ *x = point.x;
+ *y = point.y;
hwnd = WindowFromPoint (point);
if (hwnd != NULL)
@@ -1870,35 +1866,44 @@ _gdk_windowing_window_get_pointer (GdkWindow *window,
else
return_val = NULL;
- if (mask)
- {
- BYTE kbd[256];
-
- GetKeyboardState (kbd);
- *mask = 0;
- if (kbd[VK_SHIFT] & 0x80)
- *mask |= GDK_SHIFT_MASK;
- if (kbd[VK_CAPITAL] & 0x80)
- *mask |= GDK_LOCK_MASK;
- if (kbd[VK_CONTROL] & 0x80)
- *mask |= GDK_CONTROL_MASK;
- if (kbd[VK_MENU] & 0x80)
- *mask |= GDK_MOD1_MASK;
- if (kbd[VK_LBUTTON] & 0x80)
- *mask |= GDK_BUTTON1_MASK;
- if (kbd[VK_MBUTTON] & 0x80)
- *mask |= GDK_BUTTON2_MASK;
- if (kbd[VK_RBUTTON] & 0x80)
- *mask |= GDK_BUTTON3_MASK;
- }
+ GetKeyboardState (kbd);
+ *mask = 0;
+ if (kbd[VK_SHIFT] & 0x80)
+ *mask |= GDK_SHIFT_MASK;
+ if (kbd[VK_CAPITAL] & 0x80)
+ *mask |= GDK_LOCK_MASK;
+ if (kbd[VK_CONTROL] & 0x80)
+ *mask |= GDK_CONTROL_MASK;
+ if (kbd[VK_MENU] & 0x80)
+ *mask |= GDK_MOD1_MASK;
+ if (kbd[VK_LBUTTON] & 0x80)
+ *mask |= GDK_BUTTON1_MASK;
+ if (kbd[VK_MBUTTON] & 0x80)
+ *mask |= GDK_BUTTON2_MASK;
+ if (kbd[VK_RBUTTON] & 0x80)
+ *mask |= GDK_BUTTON3_MASK;
return return_val;
}
+void
+_gdk_windowing_get_pointer (GdkDisplay *display,
+ GdkScreen **screen,
+ gint *x,
+ gint *y,
+ GdkModifierType *mask)
+{
+ GdkScreen *default_screen = gdk_display_get_default_screen (display);
+ GdkWindow *root_window = gdk_screen_get_root_window (screen);
+
+ *screen = default_screen;
+ _gdk_windowing_window_get_pointer (root_window, x, y, mask);
+}
+
GdkWindow*
-_gdk_windowing_window_at_pointer (GdkScreen *screen,
- gint *win_x,
- gint *win_y)
+_gdk_windowing_window_at_pointer (GdkDisplay *display,
+ gint *win_x,
+ gint *win_y)
{
GdkWindow *window;
POINT point, pointc;
@@ -1912,10 +1917,8 @@ _gdk_windowing_window_at_pointer (GdkScreen *screen,
if (hwnd == NULL)
{
window = _gdk_parent_root;
- if (win_x)
- *win_x = pointc.x;
- if (win_y)
- *win_y = pointc.y;
+ *win_x = pointc.x;
+ *win_y = pointc.y;
return window;
}
@@ -1932,10 +1935,8 @@ _gdk_windowing_window_at_pointer (GdkScreen *screen,
if (window && (win_x || win_y))
{
GetClientRect (hwnd, &rect);
- if (win_x)
- *win_x = point.x - rect.left;
- if (win_y)
- *win_y = point.y - rect.top;
+ *win_x = point.x - rect.left;
+ *win_y = point.y - rect.top;
}
GDK_NOTE (MISC, g_print ("gdk_window_at_pointer: +%ld+%ld %p%s\n",
diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c
index 221f97d4ee..285887ce46 100644
--- a/gdk/x11/gdkwindow-x11.c
+++ b/gdk/x11/gdkwindow-x11.c
@@ -2596,8 +2596,44 @@ gdk_window_get_frame_extents (GdkWindow *window,
}
}
+void
+_gdk_windowing_get_pointer (GdkDisplay *display,
+ GdkScreen **screen,
+ gint *x,
+ gint *y,
+ GdkModifierType *mask)
+{
+ GdkScreen *default_screen;
+ 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);
+
+ XQueryPointer (GDK_SCREEN_XDISPLAY (default_screen),
+ GDK_SCREEN_XROOTWIN (default_screen),
+ &root, &child, &rootx, &rooty, &winx, &winy, &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;
+}
+
GdkWindow*
-_gdk_windowing_window_get_pointer (GdkWindow *window,
+_gdk_windowing_window_get_pointer (GdkDisplay *display,
+ GdkWindow *window,
gint *x,
gint *y,
GdkModifierType *mask)
@@ -2613,13 +2649,6 @@ _gdk_windowing_window_get_pointer (GdkWindow *window,
g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
- if (!window)
- {
- GDK_NOTE (MULTIHEAD,
- g_message ("_gdk_windowing_window_get_pointer(): window arg is need for multihead safe operation"));
- window = gdk_screen_get_root_window (gdk_screen_get_default ());
- }
-
_gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
return_val = NULL;
@@ -2632,34 +2661,48 @@ _gdk_windowing_window_get_pointer (GdkWindow *window,
return_val = gdk_window_lookup_for_display (GDK_WINDOW_DISPLAY (window), child);
}
- if (x)
- *x = winx + xoffset;
- if (y)
- *y = winy + yoffset;
- if (mask)
- *mask = xmask;
+ *x = winx + xoffset;
+ *y = winy + yoffset;
+ *mask = xmask;
return return_val;
}
GdkWindow*
-_gdk_windowing_window_at_pointer (GdkScreen *screen,
- gint *win_x,
- gint *win_y)
+_gdk_windowing_window_at_pointer (GdkDisplay *display,
+ gint *win_x,
+ gint *win_y)
{
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
+ * than we'll end up with inaccurate values for win_x, win_y
+ * and the result.
+ */
XGrabServer (xdisplay);
+ XQueryPointer (xdisplay, xwindow,
+ &root, &child, &rootx, &rooty, &winx, &winy, &xmask);
+
+ if (root == xwindow)
+ xwindow = child;
+ else
+ xwindow = root;
+
while (xwindow)
{
xwindow_last = xwindow;
@@ -2670,10 +2713,8 @@ _gdk_windowing_window_at_pointer (GdkScreen *screen,
window = gdk_window_lookup_for_display (GDK_SCREEN_DISPLAY(screen),
xwindow_last);
- if (win_x)
- *win_x = window ? winx : -1;
- if (win_y)
- *win_y = window ? winy : -1;
+ *win_x = window ? winx : -1;
+ *win_y = window ? winy : -1;
return window;
}