Make GdkDevice parallel-implementable

Use the grab and ungrab vfuncs from the frontend instead of the
_gdk_windowing wrappers, and move some things around accordingly.
Again, only the X11 backend has been updated, other backends
need to be updated to match.
This commit is contained in:
Matthias Clasen 2010-12-10 12:13:25 -05:00
parent c7559f57ed
commit a169f6e32d
12 changed files with 130 additions and 138 deletions

View File

@ -21,9 +21,9 @@
#include "gdkdevice.h" #include "gdkdevice.h"
#include "gdkinternals.h"
#include "gdkdeviceprivate.h" #include "gdkdeviceprivate.h"
#include "gdkintl.h" #include "gdkintl.h"
#include "gdkinternals.h"
typedef struct _GdkDeviceKey GdkDeviceKey; typedef struct _GdkDeviceKey GdkDeviceKey;
@ -1185,8 +1185,8 @@ gdk_device_grab (GdkDevice *device,
GdkGrabStatus res; GdkGrabStatus res;
GdkWindow *native; GdkWindow *native;
g_return_val_if_fail (GDK_IS_DEVICE (device), 0); g_return_val_if_fail (GDK_IS_DEVICE (device), GDK_GRAB_SUCCESS);
g_return_val_if_fail (GDK_IS_WINDOW (window), 0); g_return_val_if_fail (GDK_IS_WINDOW (window), GDK_GRAB_SUCCESS);
if (_gdk_native_windows) if (_gdk_native_windows)
native = window; native = window;
@ -1198,21 +1198,23 @@ gdk_device_grab (GdkDevice *device,
native = gdk_offscreen_window_get_embedder (native); native = gdk_offscreen_window_get_embedder (native);
if (native == NULL || if (native == NULL ||
(!_gdk_window_has_impl (native) && (!_gdk_window_has_impl (native) &&
!gdk_window_is_viewable (native))) !gdk_window_is_viewable (native)))
return GDK_GRAB_NOT_VIEWABLE; return GDK_GRAB_NOT_VIEWABLE;
native = gdk_window_get_toplevel (native); native = gdk_window_get_toplevel (native);
} }
res = _gdk_windowing_device_grab (device, if (native == NULL || GDK_WINDOW_DESTROYED (native))
window, return GDK_GRAB_NOT_VIEWABLE;
native,
owner_events, res = GDK_DEVICE_GET_CLASS (device)->grab (device,
get_native_grab_event_mask (event_mask), native,
NULL, owner_events,
cursor, get_native_grab_event_mask (event_mask),
time_); NULL,
cursor,
time_);
if (res == GDK_GRAB_SUCCESS) if (res == GDK_GRAB_SUCCESS)
{ {
@ -1237,6 +1239,24 @@ gdk_device_grab (GdkDevice *device,
return res; return res;
} }
/**
* gdk_device_ungrab:
* @device: a #GdkDevice
* @time_: a timestap (e.g. %GDK_CURRENT_TIME).
*
* Release any grab on @device.
*
* Since: 3.0
*/
void
gdk_device_ungrab (GdkDevice *device,
guint32 time_)
{
g_return_if_fail (GDK_IS_DEVICE (device));
GDK_DEVICE_GET_CLASS (device)->ungrab (device, time_);
}
/* Private API */ /* Private API */
void void
_gdk_device_reset_axes (GdkDevice *device) _gdk_device_reset_axes (GdkDevice *device)
@ -1536,3 +1556,4 @@ _gdk_device_translate_axis (GdkDevice *device,
return TRUE; return TRUE;
} }

View File

@ -30,8 +30,6 @@
#define __GDK_INTERNALS_H__ #define __GDK_INTERNALS_H__
#include <gio/gio.h> #include <gio/gio.h>
#include <gdk/gdktypes.h>
#include <gdk/gdkwindow.h>
#include <gdk/gdkwindowimpl.h> #include <gdk/gdkwindowimpl.h>
#include <gdk/gdkprivate.h> #include <gdk/gdkprivate.h>
@ -634,14 +632,6 @@ GdkWindow* _gdk_windowing_window_at_device_position (GdkDisplay *display,
gint *win_y, gint *win_y,
GdkModifierType *mask, GdkModifierType *mask,
gboolean get_toplevel); gboolean get_toplevel);
GdkGrabStatus _gdk_windowing_device_grab (GdkDevice *device,
GdkWindow *window,
GdkWindow *native,
gboolean owner_events,
GdkEventMask event_mask,
GdkWindow *confine_to,
GdkCursor *cursor,
guint32 time);
void _gdk_windowing_got_event (GdkDisplay *display, void _gdk_windowing_got_event (GdkDisplay *display,
GList *event_link, GList *event_link,
GdkEvent *event, GdkEvent *event,

View File

@ -8726,14 +8726,13 @@ gdk_pointer_grab (GdkWindow * window,
if (gdk_device_get_source (device) != GDK_SOURCE_MOUSE) if (gdk_device_get_source (device) != GDK_SOURCE_MOUSE)
continue; continue;
res = _gdk_windowing_device_grab (device, res = GDK_DEVICE_GET_CLASS (device)->grab (device,
window, native,
native, owner_events,
owner_events, get_native_grab_event_mask (event_mask),
get_native_grab_event_mask (event_mask), confine_to,
confine_to, cursor,
cursor, time);
time);
if (res == GDK_GRAB_SUCCESS) if (res == GDK_GRAB_SUCCESS)
_gdk_display_add_device_grab (display, _gdk_display_add_device_grab (display,
@ -8831,14 +8830,13 @@ gdk_keyboard_grab (GdkWindow *window,
if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD) if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
continue; continue;
res = _gdk_windowing_device_grab (device, res = GDK_DEVICE_GET_CLASS (device)->grab (device,
window, native,
native, owner_events,
owner_events, GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK,
GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK, NULL,
NULL, NULL,
NULL, time);
time);
if (res == GDK_GRAB_SUCCESS) if (res == GDK_GRAB_SUCCESS)
_gdk_display_add_device_grab (display, _gdk_display_add_device_grab (display,

View File

@ -24,6 +24,7 @@
#include "gdkinternals.h" #include "gdkinternals.h"
#include "gdkwindow.h" #include "gdkwindow.h"
#include "gdkprivate-x11.h" #include "gdkprivate-x11.h"
#include "gdkasync.h"
#include "gdkx.h" #include "gdkx.h"
static gboolean gdk_device_core_get_history (GdkDevice *device, static gboolean gdk_device_core_get_history (GdkDevice *device,
@ -296,7 +297,7 @@ gdk_device_core_grab (GdkDevice *device,
{ {
GdkDisplay *display; GdkDisplay *display;
Window xwindow, xconfine_to; Window xwindow, xconfine_to;
int status; gint status;
display = gdk_device_get_display (device); display = gdk_device_get_display (device);
@ -310,6 +311,11 @@ gdk_device_core_grab (GdkDevice *device,
else else
xconfine_to = GDK_WINDOW_XID (confine_to); xconfine_to = GDK_WINDOW_XID (confine_to);
#ifdef G_ENABLE_DEBUG
if (_gdk_debug_flags & GDK_DEBUG_NOGRABS)
status = GrabSuccess;
else
#endif
if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD) if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
{ {
/* Device is a keyboard */ /* Device is a keyboard */
@ -357,6 +363,8 @@ gdk_device_core_grab (GdkDevice *device,
time_); time_);
} }
_gdk_x11_display_update_grab_info (display, device, status);
return _gdk_x11_convert_grab_status (status); return _gdk_x11_convert_grab_status (status);
} }
@ -365,13 +373,17 @@ gdk_device_core_ungrab (GdkDevice *device,
guint32 time_) guint32 time_)
{ {
GdkDisplay *display; GdkDisplay *display;
gulong serial;
display = gdk_device_get_display (device); display = gdk_device_get_display (device);
serial = NextRequest (GDK_DISPLAY_XDISPLAY (display));
if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD) if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
XUngrabKeyboard (GDK_DISPLAY_XDISPLAY (display), time_); XUngrabKeyboard (GDK_DISPLAY_XDISPLAY (display), time_);
else else
XUngrabPointer (GDK_DISPLAY_XDISPLAY (display), time_); XUngrabPointer (GDK_DISPLAY_XDISPLAY (display), time_);
_gdk_x11_display_update_grab_info_ungrab (display, device, time_, serial);
} }
static GdkWindow * static GdkWindow *

View File

@ -20,7 +20,7 @@
#ifndef __GDK_DEVICE_CORE_H__ #ifndef __GDK_DEVICE_CORE_H__
#define __GDK_DEVICE_CORE_H__ #define __GDK_DEVICE_CORE_H__
#include <gdk/gdkdeviceprivate.h> #include "gdkdeviceprivate.h"
G_BEGIN_DECLS G_BEGIN_DECLS

View File

@ -25,6 +25,7 @@
#include "gdkdeviceprivate.h" #include "gdkdeviceprivate.h"
#include "gdkprivate-x11.h" #include "gdkprivate-x11.h"
#include "gdkintl.h" #include "gdkintl.h"
#include "gdkasync.h"
#include "gdkx.h" #include "gdkx.h"
#define MAX_DEVICE_CLASSES 13 #define MAX_DEVICE_CLASSES 13
@ -437,11 +438,18 @@ gdk_device_xi_grab (GdkDevice *device,
XEventClass event_classes[MAX_DEVICE_CLASSES]; XEventClass event_classes[MAX_DEVICE_CLASSES];
gint status, num_classes; gint status, num_classes;
GdkDeviceXI *device_xi; GdkDeviceXI *device_xi;
GdkDisplay *display;
device_xi = GDK_DEVICE_XI (device); device_xi = GDK_DEVICE_XI (device);
display = gdk_device_get_display (device);
find_events (device, event_mask, event_classes, &num_classes); find_events (device, event_mask, event_classes, &num_classes);
status = XGrabDevice (GDK_WINDOW_XDISPLAY (window), #ifdef G_ENABLE_DEBUG
if (_gdk_debug_flags & GDK_DEBUG_NOGRABS)
status = GrabSuccess;
else
#endif
status = XGrabDevice (GDK_DISPLAY_XDISPLAY (display),
device_xi->xdevice, device_xi->xdevice,
GDK_WINDOW_XID (window), GDK_WINDOW_XID (window),
owner_events, owner_events,
@ -449,6 +457,8 @@ gdk_device_xi_grab (GdkDevice *device,
GrabModeAsync, GrabModeAsync, GrabModeAsync, GrabModeAsync,
time_); time_);
_gdk_x11_display_update_grab_info (display, device, status);
return _gdk_x11_convert_grab_status (status); return _gdk_x11_convert_grab_status (status);
} }
@ -456,15 +466,20 @@ static void
gdk_device_xi_ungrab (GdkDevice *device, gdk_device_xi_ungrab (GdkDevice *device,
guint32 time_) guint32 time_)
{ {
GdkDisplay *display;
GdkDeviceXI *device_xi; GdkDeviceXI *device_xi;
GdkDisplay *display;
Display *xdisplay;
unsigned long serial;
device_xi = GDK_DEVICE_XI (device); device_xi = GDK_DEVICE_XI (device);
display = gdk_device_get_display (device); display = gdk_device_get_display (device);
xdisplay = GDK_DISPLAY_XDISPLAY (display);
XUngrabDevice (GDK_DISPLAY_XDISPLAY (device), serial = NextRequest (xdisplay);
device_xi->xdevice,
time_); XUngrabDevice (xdisplay, device_xi->xdevice, time_);
_gdk_x11_display_update_grab_info_ungrab (display, device, time_, serial);
} }
static GdkWindow* static GdkWindow*

View File

@ -20,7 +20,8 @@
#ifndef __GDK_DEVICE_XI_H__ #ifndef __GDK_DEVICE_XI_H__
#define __GDK_DEVICE_XI_H__ #define __GDK_DEVICE_XI_H__
#include <gdk/gdkdeviceprivate.h> #include "gdkdeviceprivate.h"
#include <X11/extensions/XInput.h> #include <X11/extensions/XInput.h>
G_BEGIN_DECLS G_BEGIN_DECLS

View File

@ -22,6 +22,7 @@
#include "gdkdevice-xi2.h" #include "gdkdevice-xi2.h"
#include "gdkintl.h" #include "gdkintl.h"
#include "gdkasync.h"
#include "gdkx.h" #include "gdkx.h"
#include <X11/extensions/XInput2.h> #include <X11/extensions/XInput2.h>
@ -364,7 +365,7 @@ gdk_device_xi2_grab (GdkDevice *device,
XIEventMask mask; XIEventMask mask;
Window xwindow; Window xwindow;
Cursor xcursor; Cursor xcursor;
int status; gint status;
priv = GDK_DEVICE_XI2 (device)->priv; priv = GDK_DEVICE_XI2 (device)->priv;
display = gdk_device_get_display (device); display = gdk_device_get_display (device);
@ -384,6 +385,11 @@ gdk_device_xi2_grab (GdkDevice *device,
mask.deviceid = priv->device_id; mask.deviceid = priv->device_id;
mask.mask = gdk_device_xi2_translate_event_mask (event_mask, &mask.mask_len); mask.mask = gdk_device_xi2_translate_event_mask (event_mask, &mask.mask_len);
#ifdef G_ENABLE_DEBUG
if (_gdk_debug_flags & GDK_DEBUG_NOGRABS)
status = GrabSuccess;
else
#endif
status = XIGrabDevice (GDK_DISPLAY_XDISPLAY (display), status = XIGrabDevice (GDK_DISPLAY_XDISPLAY (display),
priv->device_id, priv->device_id,
xwindow, xwindow,
@ -395,6 +401,8 @@ gdk_device_xi2_grab (GdkDevice *device,
g_free (mask.mask); g_free (mask.mask);
_gdk_x11_display_update_grab_info (display, device, status);
return _gdk_x11_convert_grab_status (status); return _gdk_x11_convert_grab_status (status);
} }
@ -404,13 +412,15 @@ gdk_device_xi2_ungrab (GdkDevice *device,
{ {
GdkDeviceXI2Private *priv; GdkDeviceXI2Private *priv;
GdkDisplay *display; GdkDisplay *display;
gulong serial;
priv = GDK_DEVICE_XI2 (device)->priv; priv = GDK_DEVICE_XI2 (device)->priv;
display = gdk_device_get_display (device); display = gdk_device_get_display (device);
serial = NextRequest (GDK_DISPLAY_XDISPLAY (display));
XIUngrabDevice (GDK_DISPLAY_XDISPLAY (display), XIUngrabDevice (GDK_DISPLAY_XDISPLAY (display), priv->device_id, time_);
priv->device_id,
time_); _gdk_x11_display_update_grab_info_ungrab (display, device, time_, serial);
} }
static GdkWindow * static GdkWindow *

View File

@ -20,7 +20,8 @@
#ifndef __GDK_DEVICE_XI2_H__ #ifndef __GDK_DEVICE_XI2_H__
#define __GDK_DEVICE_XI2_H__ #define __GDK_DEVICE_XI2_H__
#include <gdk/gdkdeviceprivate.h> #include "gdkdeviceprivate.h"
#include <X11/extensions/XInput2.h> #include <X11/extensions/XInput2.h>
G_BEGIN_DECLS G_BEGIN_DECLS

View File

@ -1575,60 +1575,42 @@ struct XPointerUngrabInfo {
guint32 time; guint32 time;
}; };
static void
device_ungrab_callback (GdkDisplay *display,
gpointer data,
gulong serial)
{
GdkDevice *device = data;
_gdk_display_device_grab_update (display, device, NULL, serial);
}
#define XSERVER_TIME_IS_LATER(time1, time2) \ #define XSERVER_TIME_IS_LATER(time1, time2) \
( (( time1 > time2 ) && ( time1 - time2 < ((guint32)-1)/2 )) || \ ( (( time1 > time2 ) && ( time1 - time2 < ((guint32)-1)/2 )) || \
(( time1 < time2 ) && ( time2 - time1 > ((guint32)-1)/2 )) \ (( time1 < time2 ) && ( time2 - time1 > ((guint32)-1)/2 )) \
) )
/**
* gdk_device_ungrab:
* @device: a #GdkDevice
* @time_: a timestap (e.g. %GDK_CURRENT_TIME).
*
* Release any grab on @device.
*
* Since: 3.0
*/
void void
gdk_device_ungrab (GdkDevice *device, _gdk_x11_display_update_grab_info (GdkDisplay *display,
guint32 time_) GdkDevice *device,
gint status)
{
if (status == GrabSuccess)
_gdk_x11_roundtrip_async (display,
(GdkRoundTripCallback)_gdk_display_device_grab_update,
device);
}
void
_gdk_x11_display_update_grab_info_ungrab (GdkDisplay *display,
GdkDevice *device,
guint32 time,
gulong serial)
{ {
GdkDisplay *display;
Display *xdisplay;
GdkDeviceGrabInfo *grab; GdkDeviceGrabInfo *grab;
unsigned long serial;
g_return_if_fail (GDK_IS_DEVICE (device)); XFlush (GDK_DISPLAY_XDISPLAY (display));
display = gdk_device_get_display (device);
xdisplay = GDK_DISPLAY_XDISPLAY (display);
serial = NextRequest (xdisplay);
GDK_DEVICE_GET_CLASS (device)->ungrab (device, time_);
XFlush (xdisplay);
grab = _gdk_display_get_last_device_grab (display, device); grab = _gdk_display_get_last_device_grab (display, device);
if (grab && if (grab &&
(time_ == GDK_CURRENT_TIME || (time == GDK_CURRENT_TIME ||
grab->time == GDK_CURRENT_TIME || grab->time == GDK_CURRENT_TIME ||
!XSERVER_TIME_IS_LATER (grab->time, time_))) !XSERVER_TIME_IS_LATER (grab->time, time)))
{ {
grab->serial_end = serial; grab->serial_end = serial;
_gdk_x11_roundtrip_async (display, _gdk_x11_roundtrip_async (display,
device_ungrab_callback, (GdkRoundTripCallback)_gdk_display_device_grab_update,
device); device);
} }
} }

View File

@ -129,53 +129,6 @@ _gdk_x11_convert_grab_status (gint status)
return 0; return 0;
} }
static void
has_pointer_grab_callback (GdkDisplay *display,
gpointer data,
gulong serial)
{
GdkDevice *device = data;
_gdk_display_device_grab_update (display, device, NULL, serial);
}
GdkGrabStatus
_gdk_windowing_device_grab (GdkDevice *device,
GdkWindow *window,
GdkWindow *native,
gboolean owner_events,
GdkEventMask event_mask,
GdkWindow *confine_to,
GdkCursor *cursor,
guint32 time)
{
GdkDisplay *display;
GdkGrabStatus status = GDK_GRAB_SUCCESS;
if (!window || GDK_WINDOW_DESTROYED (window))
return GDK_GRAB_NOT_VIEWABLE;
display = gdk_device_get_display (device);
#ifdef G_ENABLE_DEBUG
if (_gdk_debug_flags & GDK_DEBUG_NOGRABS)
status = GrabSuccess;
else
#endif
status = GDK_DEVICE_GET_CLASS (device)->grab (device,
native,
owner_events,
event_mask,
confine_to,
cursor,
time);
if (status == GDK_GRAB_SUCCESS)
_gdk_x11_roundtrip_async (display,
has_pointer_grab_callback,
device);
return status;
}
/** /**
* _gdk_xgrab_check_unmap: * _gdk_xgrab_check_unmap:
* @window: a #GdkWindow * @window: a #GdkWindow

View File

@ -139,6 +139,15 @@ void _gdk_xgrab_check_destroy (GdkWindow *window);
gboolean _gdk_x11_display_is_root_window (GdkDisplay *display, gboolean _gdk_x11_display_is_root_window (GdkDisplay *display,
Window xroot_window); Window xroot_window);
void _gdk_x11_display_update_grab_info (GdkDisplay *display,
GdkDevice *device,
gint status);
void _gdk_x11_display_update_grab_info_ungrab (GdkDisplay *display,
GdkDevice *device,
guint32 time,
gulong serial);
void _gdk_x11_device_check_extension_events (GdkDevice *device);
void _gdk_x11_precache_atoms (GdkDisplay *display, void _gdk_x11_precache_atoms (GdkDisplay *display,
const gchar * const *atom_names, const gchar * const *atom_names,
gint n_atoms); gint n_atoms);