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 "gdkinternals.h"
#include "gdkdeviceprivate.h"
#include "gdkintl.h"
#include "gdkinternals.h"
typedef struct _GdkDeviceKey GdkDeviceKey;
@ -1185,8 +1185,8 @@ gdk_device_grab (GdkDevice *device,
GdkGrabStatus res;
GdkWindow *native;
g_return_val_if_fail (GDK_IS_DEVICE (device), 0);
g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
g_return_val_if_fail (GDK_IS_DEVICE (device), GDK_GRAB_SUCCESS);
g_return_val_if_fail (GDK_IS_WINDOW (window), GDK_GRAB_SUCCESS);
if (_gdk_native_windows)
native = window;
@ -1198,21 +1198,23 @@ gdk_device_grab (GdkDevice *device,
native = gdk_offscreen_window_get_embedder (native);
if (native == NULL ||
(!_gdk_window_has_impl (native) &&
!gdk_window_is_viewable (native)))
return GDK_GRAB_NOT_VIEWABLE;
(!_gdk_window_has_impl (native) &&
!gdk_window_is_viewable (native)))
return GDK_GRAB_NOT_VIEWABLE;
native = gdk_window_get_toplevel (native);
}
res = _gdk_windowing_device_grab (device,
window,
native,
owner_events,
get_native_grab_event_mask (event_mask),
NULL,
cursor,
time_);
if (native == NULL || GDK_WINDOW_DESTROYED (native))
return GDK_GRAB_NOT_VIEWABLE;
res = GDK_DEVICE_GET_CLASS (device)->grab (device,
native,
owner_events,
get_native_grab_event_mask (event_mask),
NULL,
cursor,
time_);
if (res == GDK_GRAB_SUCCESS)
{
@ -1237,6 +1239,24 @@ gdk_device_grab (GdkDevice *device,
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 */
void
_gdk_device_reset_axes (GdkDevice *device)
@ -1536,3 +1556,4 @@ _gdk_device_translate_axis (GdkDevice *device,
return TRUE;
}

View File

@ -30,8 +30,6 @@
#define __GDK_INTERNALS_H__
#include <gio/gio.h>
#include <gdk/gdktypes.h>
#include <gdk/gdkwindow.h>
#include <gdk/gdkwindowimpl.h>
#include <gdk/gdkprivate.h>
@ -634,14 +632,6 @@ GdkWindow* _gdk_windowing_window_at_device_position (GdkDisplay *display,
gint *win_y,
GdkModifierType *mask,
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,
GList *event_link,
GdkEvent *event,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1575,60 +1575,42 @@ struct XPointerUngrabInfo {
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) \
( (( time1 > time2 ) && ( time1 - time2 < ((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
gdk_device_ungrab (GdkDevice *device,
guint32 time_)
_gdk_x11_display_update_grab_info (GdkDisplay *display,
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;
unsigned long serial;
g_return_if_fail (GDK_IS_DEVICE (device));
display = gdk_device_get_display (device);
xdisplay = GDK_DISPLAY_XDISPLAY (display);
serial = NextRequest (xdisplay);
GDK_DEVICE_GET_CLASS (device)->ungrab (device, time_);
XFlush (xdisplay);
XFlush (GDK_DISPLAY_XDISPLAY (display));
grab = _gdk_display_get_last_device_grab (display, device);
if (grab &&
(time_ == GDK_CURRENT_TIME ||
(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;
_gdk_x11_roundtrip_async (display,
device_ungrab_callback,
device);
(GdkRoundTripCallback)_gdk_display_device_grab_update,
device);
}
}

View File

@ -129,53 +129,6 @@ _gdk_x11_convert_grab_status (gint status)
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:
* @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,
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,
const gchar * const *atom_names,
gint n_atoms);