Initial version of input support

This commit is contained in:
Alexander Larsson 2009-05-29 16:39:12 +02:00
parent a6e3da1319
commit 7372379c24
12 changed files with 559 additions and 425 deletions

View File

@ -91,6 +91,7 @@ struct _GdkDisplay
const GdkDisplayPointerHooks *pointer_hooks; /* Current hooks for querying pointer */ const GdkDisplayPointerHooks *pointer_hooks; /* Current hooks for querying pointer */
guint closed : 1; /* Whether this display has been closed */ guint closed : 1; /* Whether this display has been closed */
guint ignore_core_events : 1; /* Don't send core motion and button event */
guint double_click_distance; /* Maximum distance between clicks in pixels */ guint double_click_distance; /* Maximum distance between clicks in pixels */
gint button_x[2]; /* The last 2 button click positions. */ gint button_x[2]; /* The last 2 button click positions. */

View File

@ -187,6 +187,7 @@ typedef struct
gboolean grab_one_pointer_release_event; gboolean grab_one_pointer_release_event;
} GdkPointerGrabInfo; } GdkPointerGrabInfo;
typedef struct _GdkInputWindow GdkInputWindow;
/* Private version of GdkWindowObject. The initial part of this strucuture /* Private version of GdkWindowObject. The initial part of this strucuture
is public for historical reasons. Don't change that part */ is public for historical reasons. Don't change that part */
@ -260,6 +261,7 @@ struct _GdkWindowObject
guint native_visibility : 2; /* the native visibility of a impl windows */ guint native_visibility : 2; /* the native visibility of a impl windows */
GdkWindowPaint *implicit_paint; GdkWindowPaint *implicit_paint;
GdkInputWindow *input_window; /* only for impl windows */
GList *outstanding_moves; GList *outstanding_moves;
@ -640,6 +642,10 @@ GdkRegion *_gdk_window_calculate_full_clip_region (GdkWindow *window,
gint *base_y_offset); gint *base_y_offset);
gboolean _gdk_window_has_impl (GdkWindow *window); gboolean _gdk_window_has_impl (GdkWindow *window);
GdkWindow * _gdk_window_get_impl_window (GdkWindow *window); GdkWindow * _gdk_window_get_impl_window (GdkWindow *window);
GdkWindow *_gdk_window_get_input_window_for_event (GdkWindow *native_window,
GdkEventType event_type,
int x, int y,
gulong serial);
GdkRegion *_gdk_region_new_from_yxbanded_rects (GdkRectangle *rects, int n_rects); GdkRegion *_gdk_region_new_from_yxbanded_rects (GdkRectangle *rects, int n_rects);
/***************************** /*****************************

View File

@ -1596,6 +1596,10 @@ _gdk_window_destroy_hierarchy (GdkWindow *window,
NULL, NULL); NULL, NULL);
} }
if (private->extension_events)
GDK_WINDOW_IMPL_GET_IFACE (private->impl)->input_window_destroy (window);
if (gdk_window_has_impl (private)) if (gdk_window_has_impl (private))
{ {
GDK_WINDOW_IMPL_GET_IFACE (private->impl)->destroy (window, recursing_native, foreign_destroy); GDK_WINDOW_IMPL_GET_IFACE (private->impl)->destroy (window, recursing_native, foreign_destroy);
@ -8240,6 +8244,10 @@ send_crossing_event (GdkDisplay *display,
else else
event_mask = GDK_ENTER_NOTIFY_MASK; event_mask = GDK_ENTER_NOTIFY_MASK;
if (window->extension_events != 0)
GDK_WINDOW_IMPL_GET_IFACE (window->impl)->input_window_crossing (window,
type == GDK_ENTER_NOTIFY);
if (window->event_mask & event_mask) if (window->event_mask & event_mask)
{ {
event = _gdk_make_event ((GdkWindow *)window, type, event_in_queue, TRUE); event = _gdk_make_event ((GdkWindow *)window, type, event_in_queue, TRUE);
@ -8724,7 +8732,7 @@ proxy_pointer_event (GdkDisplay *display,
} }
} }
if (event_win) if (event_win && !display->ignore_core_events)
{ {
event = _gdk_make_event (event_win, GDK_MOTION_NOTIFY, source_event, FALSE); event = _gdk_make_event (event_win, GDK_MOTION_NOTIFY, source_event, FALSE);
event->motion.time = time_; event->motion.time = time_;
@ -8814,7 +8822,7 @@ proxy_button_event (GdkEvent *source_event,
type, state, type, state,
NULL, serial); NULL, serial);
if (event_win == NULL) if (event_win == NULL || display->ignore_core_events)
return TRUE; return TRUE;
event = _gdk_make_event (event_win, type, source_event, FALSE); event = _gdk_make_event (event_win, type, source_event, FALSE);
@ -8914,6 +8922,22 @@ gdk_window_print_tree (GdkWindow *window,
#endif /* DEBUG_WINDOW_PRINTING */ #endif /* DEBUG_WINDOW_PRINTING */
static gboolean
is_input_event (GdkDisplay *display,
GdkEvent *event)
{
GdkDevice *core_pointer;
core_pointer = gdk_display_get_core_pointer (display);
if ((event->type == GDK_MOTION_NOTIFY &&
event->motion.device != core_pointer) ||
(event->type == GDK_BUTTON_PRESS ||
event->type == GDK_BUTTON_RELEASE) &&
event->button.device != core_pointer)
return TRUE;
return FALSE;
}
void void
_gdk_windowing_got_event (GdkDisplay *display, _gdk_windowing_got_event (GdkDisplay *display,
GList *event_link, GList *event_link,
@ -8958,6 +8982,9 @@ _gdk_windowing_got_event (GdkDisplay *display,
return; return;
} }
if (is_input_event (display, event))
return;
if (!(is_button_type (event->type) || if (!(is_button_type (event->type) ||
is_motion_type (event->type)) || is_motion_type (event->type)) ||
GDK_WINDOW_TYPE (event_private) == GDK_WINDOW_ROOT) GDK_WINDOW_TYPE (event_private) == GDK_WINDOW_ROOT)
@ -9075,5 +9102,87 @@ _gdk_windowing_got_event (GdkDisplay *display,
} }
} }
static GdkWindow *
get_extension_event_window (GdkDisplay *display,
GdkWindow *pointer_window,
GdkEventType type,
gulong serial)
{
guint evmask;
GdkWindow *grab_window;
GdkWindowObject *w;
GdkPointerGrabInfo *grab;
grab = _gdk_display_has_pointer_grab (display, serial);
if (grab != NULL && !grab->owner_events)
{
evmask = grab->event_mask;
grab_window = grab->window;
if (evmask & type_masks[type])
return grab_window;
else
return NULL;
}
w = (GdkWindowObject *)pointer_window;
while (w != NULL)
{
evmask = w->extension_events;
if (evmask & type_masks[type])
return (GdkWindow *)w;
w = w->parent;
}
if (grab != NULL &&
grab->owner_events)
{
evmask = grab->event_mask;
if (evmask & type_masks[type])
return grab->window;
else
return NULL;
}
return NULL;
}
GdkWindow *
_gdk_window_get_input_window_for_event (GdkWindow *native_window,
GdkEventType event_type,
int x, int y,
gulong serial)
{
GdkDisplay *display;
GdkWindow *toplevel_window;
GdkWindow *pointer_window;
GdkWindow *event_win;
gdouble toplevel_x, toplevel_y;
toplevel_x = x;
toplevel_y = y;
display = gdk_drawable_get_display (native_window);
toplevel_window = convert_coords_to_toplevel (native_window,
toplevel_x, toplevel_y,
&toplevel_x, &toplevel_y);
pointer_window = get_pointer_window (display, toplevel_window,
toplevel_x, toplevel_y, serial);
event_win = get_extension_event_window (display,
pointer_window,
event_type,
serial);
return event_win;
}
#define __GDK_WINDOW_C__ #define __GDK_WINDOW_C__
#include "gdkaliasdef.c" #include "gdkaliasdef.c"

View File

@ -128,6 +128,10 @@ struct _GdkWindowImplIface
void (* destroy) (GdkWindow *window, void (* destroy) (GdkWindow *window,
gboolean recursing, gboolean recursing,
gboolean foreign_destroy); gboolean foreign_destroy);
void (* input_window_destroy) (GdkWindow *window);
void (* input_window_crossing)(GdkWindow *window,
gboolean enter);
}; };
/* Interface Functions */ /* Interface Functions */

View File

@ -133,11 +133,6 @@ struct _GdkDisplayX11
/* input GdkWindow list */ /* input GdkWindow list */
GList *input_windows; GList *input_windows;
gint input_ignore_core;
/* information about network port and host for gxid daemon */
gchar *input_gxid_host;
gint input_gxid_port;
/* Startup notification */ /* Startup notification */
gchar *startup_notification_id; gchar *startup_notification_id;

View File

@ -1125,9 +1125,7 @@ gdk_event_translate (GdkDisplay *display,
xevent->xbutton.x, xevent->xbutton.y, xevent->xbutton.x, xevent->xbutton.y,
xevent->xbutton.button)); xevent->xbutton.button));
if (window_private == NULL || if (window_private == NULL)
((window_private->extension_events != 0) &&
display_x11->input_ignore_core))
{ {
return_val = FALSE; return_val = FALSE;
break; break;
@ -1201,9 +1199,7 @@ gdk_event_translate (GdkDisplay *display,
xevent->xbutton.x, xevent->xbutton.y, xevent->xbutton.x, xevent->xbutton.y,
xevent->xbutton.button)); xevent->xbutton.button));
if (window_private == NULL || if (window_private == NULL)
((window_private->extension_events != 0) &&
display_x11->input_ignore_core))
{ {
return_val = FALSE; return_val = FALSE;
break; break;
@ -1241,9 +1237,7 @@ gdk_event_translate (GdkDisplay *display,
xevent->xmotion.x, xevent->xmotion.y, xevent->xmotion.x, xevent->xmotion.y,
(xevent->xmotion.is_hint) ? "true" : "false")); (xevent->xmotion.is_hint) ? "true" : "false"));
if (window_private == NULL || if (window_private == NULL)
((window_private->extension_events != 0) &&
display_x11->input_ignore_core))
{ {
return_val = FALSE; return_val = FALSE;
break; break;
@ -1304,12 +1298,6 @@ gdk_event_translate (GdkDisplay *display,
} }
} }
/* Tell XInput stuff about it if appropriate */
if (window_private &&
!GDK_WINDOW_DESTROYED (window) &&
window_private->extension_events != 0)
_gdk_input_enter_event (&xevent->xcrossing, window);
event->crossing.type = GDK_ENTER_NOTIFY; event->crossing.type = GDK_ENTER_NOTIFY;
event->crossing.window = window; event->crossing.window = window;
@ -1854,7 +1842,7 @@ gdk_event_translate (GdkDisplay *display,
if (window && if (window &&
xevent->xconfigure.event == xevent->xconfigure.window && xevent->xconfigure.event == xevent->xconfigure.window &&
!GDK_WINDOW_DESTROYED (window) && !GDK_WINDOW_DESTROYED (window) &&
(window_private->extension_events != 0)) window_private->input_window != NULL)
_gdk_input_configure_event (&xevent->xconfigure, window); _gdk_input_configure_event (&xevent->xconfigure, window);
#ifdef HAVE_XSYNC #ifdef HAVE_XSYNC
@ -2171,8 +2159,8 @@ gdk_event_translate (GdkDisplay *display,
if (window_private && if (window_private &&
!GDK_WINDOW_DESTROYED (window_private) && !GDK_WINDOW_DESTROYED (window_private) &&
(window_private->extension_events != 0)) window_private->input_window)
return_val = _gdk_input_other_event(event, xevent, window); return_val = _gdk_input_other_event (event, xevent, window);
else else
return_val = FALSE; return_val = FALSE;

View File

@ -21,7 +21,7 @@
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog * file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with * files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/. * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/ */
#include "config.h" #include "config.h"
@ -39,7 +39,7 @@ static GdkDevicePrivate *gdk_input_device_new (GdkDisplay *disp
XDeviceInfo *device, XDeviceInfo *device,
gint include_core); gint include_core);
static void gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev, static void gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev,
GdkInputWindow *input_window, GdkWindow *window,
gint *axis_data, gint *axis_data,
gdouble *axis_out, gdouble *axis_out,
gdouble *x_out, gdouble *x_out,
@ -64,37 +64,26 @@ _gdk_input_find_device (GdkDisplay *display,
} }
void void
_gdk_input_get_root_relative_geometry(Display *display, Window w, int *x_ret, int *y_ret, _gdk_input_get_root_relative_geometry (GdkWindow *window,
int *width_ret, int *height_ret) int *x_ret, int *y_ret)
{ {
Window root, parent, child; Window child;
Window *children;
guint nchildren;
gint x,y; gint x,y;
guint width, height;
guint border_widthc, depthc;
XQueryTree (display, w, &root, &parent, &children, &nchildren);
if (children)
XFree(children);
XGetGeometry (display, w, &root, &x, &y, &width, &height, &border_widthc, &depthc);
XTranslateCoordinates (display, w, root, 0, 0, &x, &y, &child); XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window),
GDK_WINDOW_XWINDOW (window),
GDK_WINDOW_XROOTWIN (window),
0, 0, &x, &y, &child);
if (x_ret) if (x_ret)
*x_ret = x; *x_ret = x;
if (y_ret) if (y_ret)
*y_ret = y; *y_ret = y;
if (width_ret)
*width_ret = width;
if (height_ret)
*height_ret = height;
} }
static GdkDevicePrivate * static GdkDevicePrivate *
gdk_input_device_new (GdkDisplay *display, gdk_input_device_new (GdkDisplay *display,
XDeviceInfo *device, XDeviceInfo *device,
gint include_core) gint include_core)
{ {
GdkDevicePrivate *gdkdev; GdkDevicePrivate *gdkdev;
@ -121,7 +110,7 @@ gdk_input_device_new (GdkDisplay *display,
for comparison purposes */ for comparison purposes */
tmp_name = g_ascii_strdown (gdkdev->info.name, -1); tmp_name = g_ascii_strdown (gdkdev->info.name, -1);
if (!strcmp (tmp_name, "pointer")) if (!strcmp (tmp_name, "pointer"))
gdkdev->info.source = GDK_SOURCE_MOUSE; gdkdev->info.source = GDK_SOURCE_MOUSE;
else if (!strcmp (tmp_name, "wacom") || else if (!strcmp (tmp_name, "wacom") ||
@ -151,7 +140,7 @@ gdk_input_device_new (GdkDisplay *display,
gdkdev->button_state = 0; gdkdev->button_state = 0;
class = device->inputclassinfo; class = device->inputclassinfo;
for (i=0;i<device->num_classes;i++) for (i=0;i<device->num_classes;i++)
{ {
switch (class->class) { switch (class->class) {
case ButtonClass: case ButtonClass:
@ -160,7 +149,7 @@ gdk_input_device_new (GdkDisplay *display,
{ {
XKeyInfo *xki = (XKeyInfo *)class; XKeyInfo *xki = (XKeyInfo *)class;
/* Hack to catch XFree86 3.3.1 bug. Other devices better /* Hack to catch XFree86 3.3.1 bug. Other devices better
* not have exactly 25 keys... * not have exactly 25 keys...
*/ */
if ((xki->min_keycode == 8) && (xki->max_keycode == 32)) if ((xki->min_keycode == 8) && (xki->max_keycode == 32))
{ {
@ -190,7 +179,7 @@ gdk_input_device_new (GdkDisplay *display,
gdkdev->info.axes = g_new0 (GdkDeviceAxis, xvi->num_axes); gdkdev->info.axes = g_new0 (GdkDeviceAxis, xvi->num_axes);
for (j=0;j<xvi->num_axes;j++) for (j=0;j<xvi->num_axes;j++)
{ {
gdkdev->axes[j].resolution = gdkdev->axes[j].resolution =
gdkdev->axes[j].xresolution = xvi->axes[j].resolution; gdkdev->axes[j].xresolution = xvi->axes[j].resolution;
gdkdev->axes[j].min_value = gdkdev->axes[j].min_value =
gdkdev->axes[j].xmin_value = xvi->axes[j].min_value; gdkdev->axes[j].xmin_value = xvi->axes[j].min_value;
@ -211,7 +200,7 @@ gdk_input_device_new (GdkDisplay *display,
gdk_device_set_axis_use (&gdkdev->info, j++, GDK_AXIS_YTILT); gdk_device_set_axis_use (&gdkdev->info, j++, GDK_AXIS_YTILT);
if (j<xvi->num_axes) if (j<xvi->num_axes)
gdk_device_set_axis_use (&gdkdev->info, j++, GDK_AXIS_WHEEL); gdk_device_set_axis_use (&gdkdev->info, j++, GDK_AXIS_WHEEL);
break; break;
} }
} }
@ -247,20 +236,19 @@ gdk_input_device_new (GdkDisplay *display,
error: error:
g_object_unref (gdkdev); g_object_unref (gdkdev);
return NULL; return NULL;
} }
void void
_gdk_input_common_find_events(GdkWindow *window, _gdk_input_common_find_events (GdkDevicePrivate *gdkdev,
GdkDevicePrivate *gdkdev, gint mask,
gint mask, XEventClass *classes,
XEventClass *classes, int *num_classes)
int *num_classes)
{ {
gint i; gint i;
XEventClass class; XEventClass class;
i = 0; i = 0;
if (mask & GDK_BUTTON_PRESS_MASK) if (mask & GDK_BUTTON_PRESS_MASK)
{ {
@ -354,25 +342,42 @@ _gdk_input_common_find_events(GdkWindow *window,
} }
void void
_gdk_input_common_select_events(GdkWindow *window, _gdk_input_select_events (GdkWindow *impl_window,
GdkDevicePrivate *gdkdev) GdkDevicePrivate *gdkdev)
{ {
XEventClass classes[GDK_MAX_DEVICE_CLASSES]; XEventClass classes[GDK_MAX_DEVICE_CLASSES];
gint num_classes; gint num_classes;
guint event_mask;
GdkWindowObject *w;
GdkInputWindow *iw;
GList *l;
if (gdkdev->info.mode == GDK_MODE_DISABLED) event_mask = 0;
_gdk_input_common_find_events(window, gdkdev, 0, classes, &num_classes); iw = ((GdkWindowObject *)impl_window)->input_window;
else
_gdk_input_common_find_events(window, gdkdev, if (gdkdev->info.mode != GDK_MODE_DISABLED &&
((GdkWindowObject *)window)->extension_events, iw != NULL)
classes, &num_classes); {
for (l = iw->windows; l != NULL; l = l->next)
XSelectExtensionEvent (GDK_WINDOW_XDISPLAY (window), {
GDK_WINDOW_XWINDOW (window), w = l->data;
if (gdkdev->info.has_cursor || (w->extension_events & GDK_ALL_DEVICES_MASK))
event_mask |= w->extension_events;
}
}
event_mask &= ~GDK_ALL_DEVICES_MASK;
if (event_mask)
event_mask |= GDK_PROXIMITY_OUT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK;
_gdk_input_common_find_events (gdkdev, event_mask,
classes, &num_classes);
XSelectExtensionEvent (GDK_WINDOW_XDISPLAY (impl_window),
GDK_WINDOW_XWINDOW (impl_window),
classes, num_classes); classes, num_classes);
} }
gint gint
_gdk_input_common_init (GdkDisplay *display, _gdk_input_common_init (GdkDisplay *display,
gint include_core) gint include_core)
{ {
@ -391,7 +396,7 @@ _gdk_input_common_init (GdkDisplay *display,
event_base, 15 /* Number of events */); event_base, 15 /* Number of events */);
devices = XListInputDevices(display_x11->xdisplay, &num_devices); devices = XListInputDevices(display_x11->xdisplay, &num_devices);
for(loop=0; loop<num_devices; loop++) for(loop=0; loop<num_devices; loop++)
{ {
GdkDevicePrivate *gdkdev = gdk_input_device_new(display, GdkDevicePrivate *gdkdev = gdk_input_device_new(display,
@ -410,21 +415,23 @@ _gdk_input_common_init (GdkDisplay *display,
static void static void
gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev, gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev,
GdkInputWindow *input_window, GdkWindow *window,
gint *axis_data, gint *axis_data,
gdouble *axis_out, gdouble *axis_out,
gdouble *x_out, gdouble *x_out,
gdouble *y_out) gdouble *y_out)
{ {
GdkWindowObject *window_private; GdkWindowObject *priv, *impl_window;
int i; int i;
int x_axis = 0; int x_axis = 0;
int y_axis = 0; int y_axis = 0;
double device_width, device_height; double device_width, device_height;
double x_offset, y_offset, x_scale, y_scale; double x_offset, y_offset, x_scale, y_scale;
window_private = (GdkWindowObject *) input_window->window; priv = (GdkWindowObject *) window;
impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window);
for (i=0; i<gdkdev->info.num_axes; i++) for (i=0; i<gdkdev->info.num_axes; i++)
{ {
@ -440,26 +447,24 @@ gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev,
break; break;
} }
} }
device_width = gdkdev->axes[x_axis].max_value -
gdkdev->axes[x_axis].min_value;
device_height = gdkdev->axes[y_axis].max_value -
gdkdev->axes[y_axis].min_value;
if (gdkdev->info.mode == GDK_MODE_SCREEN) device_width = gdkdev->axes[x_axis].max_value - gdkdev->axes[x_axis].min_value;
device_height = gdkdev->axes[y_axis].max_value - gdkdev->axes[y_axis].min_value;
if (gdkdev->info.mode == GDK_MODE_SCREEN)
{ {
x_scale = gdk_screen_get_width (gdk_drawable_get_screen (input_window->window)) / device_width; x_scale = gdk_screen_get_width (gdk_drawable_get_screen (window)) / device_width;
y_scale = gdk_screen_get_height (gdk_drawable_get_screen (input_window->window)) / device_height; y_scale = gdk_screen_get_height (gdk_drawable_get_screen (window)) / device_height;
x_offset = - input_window->root_x; x_offset = - impl_window->input_window->root_x;
y_offset = - input_window->root_y; y_offset = - impl_window->input_window->root_y;
} }
else /* GDK_MODE_WINDOW */ else /* GDK_MODE_WINDOW */
{ {
double x_resolution = gdkdev->axes[x_axis].resolution; double x_resolution = gdkdev->axes[x_axis].resolution;
double y_resolution = gdkdev->axes[y_axis].resolution; double y_resolution = gdkdev->axes[y_axis].resolution;
double device_aspect; double device_aspect;
/* /*
* Some drivers incorrectly report the resolution of the device * Some drivers incorrectly report the resolution of the device
* as zero (in partiular linuxwacom < 0.5.3 with usb tablets). * as zero (in partiular linuxwacom < 0.5.3 with usb tablets).
* This causes the device_aspect to become NaN and totally * This causes the device_aspect to become NaN and totally
@ -475,27 +480,24 @@ gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev,
y_resolution = 1; y_resolution = 1;
} }
device_aspect = (device_height*y_resolution) / device_aspect = (device_height*y_resolution) /
(device_width*x_resolution); (device_width*x_resolution);
if (device_aspect * window_private->width >= window_private->height) if (device_aspect * priv->width >= priv->height)
{ {
/* device taller than window */ /* device taller than window */
x_scale = window_private->width / device_width; x_scale = priv->width / device_width;
y_scale = (x_scale * x_resolution) y_scale = (x_scale * x_resolution) / y_resolution;
/ y_resolution;
x_offset = 0; x_offset = 0;
y_offset = -(device_height * y_scale - y_offset = -(device_height * y_scale - priv->height)/2;
window_private->height)/2;
} }
else else
{ {
/* window taller than device */ /* window taller than device */
y_scale = window_private->height / device_height; y_scale = priv->height / device_height;
x_scale = (y_scale * y_resolution) x_scale = (y_scale * y_resolution) / x_resolution;
/ x_resolution;
y_offset = 0; y_offset = 0;
x_offset = - (device_width * x_scale - window_private->width)/2; x_offset = - (device_width * x_scale - priv->width)/2;
} }
} }
@ -504,13 +506,13 @@ gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev,
switch (gdkdev->info.axes[i].use) switch (gdkdev->info.axes[i].use)
{ {
case GDK_AXIS_X: case GDK_AXIS_X:
axis_out[i] = x_offset + x_scale * (axis_data[x_axis] - axis_out[i] = x_offset + x_scale * (axis_data[x_axis] -
gdkdev->axes[x_axis].min_value); gdkdev->axes[x_axis].min_value);
if (x_out) if (x_out)
*x_out = axis_out[i]; *x_out = axis_out[i];
break; break;
case GDK_AXIS_Y: case GDK_AXIS_Y:
axis_out[i] = y_offset + y_scale * (axis_data[y_axis] - axis_out[i] = y_offset + y_scale * (axis_data[y_axis] -
gdkdev->axes[y_axis].min_value); gdkdev->axes[y_axis].min_value);
if (y_out) if (y_out)
*y_out = axis_out[i]; *y_out = axis_out[i];
@ -541,11 +543,18 @@ gdk_input_translate_state(guint state, guint device_state)
gboolean gboolean
_gdk_input_common_other_event (GdkEvent *event, _gdk_input_common_other_event (GdkEvent *event,
XEvent *xevent, XEvent *xevent,
GdkInputWindow *input_window, GdkWindow *window,
GdkDevicePrivate *gdkdev) GdkDevicePrivate *gdkdev)
{ {
GdkWindowObject *priv, *impl_window;
GdkInputWindow *input_window;
priv = (GdkWindowObject *) window;
impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window);
input_window = impl_window->input_window;
if ((xevent->type == gdkdev->buttonpress_type) || if ((xevent->type == gdkdev->buttonpress_type) ||
(xevent->type == gdkdev->buttonrelease_type)) (xevent->type == gdkdev->buttonrelease_type))
{ {
XDeviceButtonEvent *xdbe = (XDeviceButtonEvent *)(xevent); XDeviceButtonEvent *xdbe = (XDeviceButtonEvent *)(xevent);
@ -560,16 +569,16 @@ _gdk_input_common_other_event (GdkEvent *event,
gdkdev->button_state &= ~(1 << xdbe->button); gdkdev->button_state &= ~(1 << xdbe->button);
} }
event->button.device = &gdkdev->info; event->button.device = &gdkdev->info;
event->button.window = input_window->window; event->button.window = window;
event->button.time = xdbe->time; event->button.time = xdbe->time;
event->button.axes = g_new (gdouble, gdkdev->info.num_axes); event->button.axes = g_new (gdouble, gdkdev->info.num_axes);
gdk_input_translate_coordinates (gdkdev,input_window, xdbe->axis_data, gdk_input_translate_coordinates (gdkdev, window, xdbe->axis_data,
event->button.axes, event->button.axes,
&event->button.x,&event->button.y); &event->button.x, &event->button.y);
event->button.x_root = event->button.x + input_window->root_x; event->button.x_root = event->button.x + priv->abs_x + input_window->root_x;
event->button.y_root = event->button.y + input_window->root_y; event->button.y_root = event->button.y + priv->abs_y + input_window->root_y;
event->button.state = gdk_input_translate_state(xdbe->state,xdbe->device_state); event->button.state = gdk_input_translate_state (xdbe->state,xdbe->device_state);
event->button.button = xdbe->button; event->button.button = xdbe->button;
if (event->button.type == GDK_BUTTON_PRESS) if (event->button.type == GDK_BUTTON_PRESS)
@ -588,8 +597,8 @@ _gdk_input_common_other_event (GdkEvent *event,
* a valid timestamp. * a valid timestamp.
*/ */
if (gdk_event_get_time (event) != GDK_CURRENT_TIME) if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
gdk_x11_window_set_user_time (gdk_window_get_toplevel (input_window->window), gdk_x11_window_set_user_time (gdk_window_get_toplevel (window),
gdk_event_get_time (event)); gdk_event_get_time (event));
return TRUE; return TRUE;
} }
@ -611,21 +620,21 @@ _gdk_input_common_other_event (GdkEvent *event,
g_warning ("Invalid device key code received"); g_warning ("Invalid device key code received");
return FALSE; return FALSE;
} }
event->key.keyval = gdkdev->info.keys[xdke->keycode - gdkdev->min_keycode].keyval; event->key.keyval = gdkdev->info.keys[xdke->keycode - gdkdev->min_keycode].keyval;
if (event->key.keyval == 0) if (event->key.keyval == 0)
{ {
GDK_NOTE (EVENTS, GDK_NOTE (EVENTS,
g_print ("\t\ttranslation - NONE\n")); g_print ("\t\ttranslation - NONE\n"));
return FALSE; return FALSE;
} }
event->key.type = (xdke->type == gdkdev->keypress_type) ? event->key.type = (xdke->type == gdkdev->keypress_type) ?
GDK_KEY_PRESS : GDK_KEY_RELEASE; GDK_KEY_PRESS : GDK_KEY_RELEASE;
event->key.window = input_window->window; event->key.window = window;
event->key.time = xdke->time; event->key.time = xdke->time;
event->key.state = gdk_input_translate_state(xdke->state, xdke->device_state) event->key.state = gdk_input_translate_state(xdke->state, xdke->device_state)
@ -654,26 +663,26 @@ _gdk_input_common_other_event (GdkEvent *event,
* a valid timestamp. * a valid timestamp.
*/ */
if (gdk_event_get_time (event) != GDK_CURRENT_TIME) if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
gdk_x11_window_set_user_time (gdk_window_get_toplevel (input_window->window), gdk_x11_window_set_user_time (gdk_window_get_toplevel (window),
gdk_event_get_time (event)); gdk_event_get_time (event));
return TRUE; return TRUE;
} }
if (xevent->type == gdkdev->motionnotify_type) if (xevent->type == gdkdev->motionnotify_type)
{ {
XDeviceMotionEvent *xdme = (XDeviceMotionEvent *)(xevent); XDeviceMotionEvent *xdme = (XDeviceMotionEvent *)(xevent);
event->motion.device = &gdkdev->info; event->motion.device = &gdkdev->info;
event->motion.axes = g_new (gdouble, gdkdev->info.num_axes); event->motion.axes = g_new (gdouble, gdkdev->info.num_axes);
gdk_input_translate_coordinates(gdkdev,input_window,xdme->axis_data, gdk_input_translate_coordinates(gdkdev,window,xdme->axis_data,
event->motion.axes, event->motion.axes,
&event->motion.x,&event->motion.y); &event->motion.x,&event->motion.y);
event->motion.x_root = event->motion.x + input_window->root_x; event->motion.x_root = event->motion.x + priv->abs_x + input_window->root_x;
event->motion.y_root = event->motion.y + input_window->root_y; event->motion.y_root = event->motion.y + priv->abs_y + input_window->root_y;
event->motion.type = GDK_MOTION_NOTIFY; event->motion.type = GDK_MOTION_NOTIFY;
event->motion.window = input_window->window; event->motion.window = window;
event->motion.time = xdme->time; event->motion.time = xdme->time;
event->motion.state = gdk_input_translate_state(xdme->state, event->motion.state = gdk_input_translate_state(xdme->state,
xdme->device_state); xdme->device_state);
@ -686,14 +695,14 @@ _gdk_input_common_other_event (GdkEvent *event,
event->motion.x, event->motion.y, event->motion.x, event->motion.y,
event->motion.state, event->motion.state,
(xdme->is_hint) ? "true" : "false")); (xdme->is_hint) ? "true" : "false"));
/* Update the timestamp of the latest user interaction, if the event has /* Update the timestamp of the latest user interaction, if the event has
* a valid timestamp. * a valid timestamp.
*/ */
if (gdk_event_get_time (event) != GDK_CURRENT_TIME) if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
gdk_x11_window_set_user_time (gdk_window_get_toplevel (input_window->window), gdk_x11_window_set_user_time (gdk_window_get_toplevel (window),
gdk_event_get_time (event)); gdk_event_get_time (event));
return TRUE; return TRUE;
} }
@ -704,16 +713,16 @@ _gdk_input_common_other_event (GdkEvent *event,
event->proximity.device = &gdkdev->info; event->proximity.device = &gdkdev->info;
event->proximity.type = (xevent->type == gdkdev->proximityin_type)? event->proximity.type = (xevent->type == gdkdev->proximityin_type)?
GDK_PROXIMITY_IN:GDK_PROXIMITY_OUT; GDK_PROXIMITY_IN:GDK_PROXIMITY_OUT;
event->proximity.window = input_window->window; event->proximity.window = window;
event->proximity.time = xpne->time; event->proximity.time = xpne->time;
/* Update the timestamp of the latest user interaction, if the event has /* Update the timestamp of the latest user interaction, if the event has
* a valid timestamp. * a valid timestamp.
*/ */
if (gdk_event_get_time (event) != GDK_CURRENT_TIME) if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
gdk_x11_window_set_user_time (gdk_window_get_toplevel (input_window->window), gdk_x11_window_set_user_time (gdk_window_get_toplevel (window),
gdk_event_get_time (event)); gdk_event_get_time (event));
return TRUE; return TRUE;
} }
@ -730,18 +739,17 @@ _gdk_device_get_history (GdkDevice *device,
{ {
GdkTimeCoord **coords; GdkTimeCoord **coords;
XDeviceTimeCoord *device_coords; XDeviceTimeCoord *device_coords;
GdkInputWindow *input_window; GdkWindow *impl_window;
GdkDevicePrivate *gdkdev; GdkDevicePrivate *gdkdev;
gint mode_return; gint mode_return;
gint axis_count_return; gint axis_count_return;
gint i; gint i;
gdkdev = (GdkDevicePrivate *)device; gdkdev = (GdkDevicePrivate *)device;
input_window = _gdk_input_window_find (window);
g_return_val_if_fail (input_window != NULL, FALSE); impl_window = _gdk_window_get_impl_window (window);
device_coords = XGetDeviceMotionEvents (GDK_WINDOW_XDISPLAY (window), device_coords = XGetDeviceMotionEvents (GDK_WINDOW_XDISPLAY (impl_window),
gdkdev->xdevice, gdkdev->xdevice,
start, stop, start, stop,
n_events, &mode_return, n_events, &mode_return,
@ -752,13 +760,13 @@ _gdk_device_get_history (GdkDevice *device,
coords = _gdk_device_allocate_history (device, *n_events); coords = _gdk_device_allocate_history (device, *n_events);
for (i = 0; i < *n_events; i++) for (i = 0; i < *n_events; i++)
{ {
coords[i]->time = device_coords[i].time; coords[i]->time = device_coords[i].time;
gdk_input_translate_coordinates (gdkdev, input_window, gdk_input_translate_coordinates (gdkdev, window,
device_coords[i].data, device_coords[i].data,
coords[i]->axes, NULL, NULL); coords[i]->axes, NULL, NULL);
} }
XFreeDeviceMotionEvents (device_coords); XFreeDeviceMotionEvents (device_coords);
@ -770,7 +778,7 @@ _gdk_device_get_history (GdkDevice *device,
return FALSE; return FALSE;
} }
void void
gdk_device_get_state (GdkDevice *device, gdk_device_get_state (GdkDevice *device,
GdkWindow *window, GdkWindow *window,
gdouble *axes, gdouble *axes,
@ -784,7 +792,7 @@ gdk_device_get_state (GdkDevice *device,
if (GDK_IS_CORE (device)) if (GDK_IS_CORE (device))
{ {
gint x_int, y_int; gint x_int, y_int;
gdk_window_get_pointer (window, &x_int, &y_int, mask); gdk_window_get_pointer (window, &x_int, &y_int, mask);
if (axes) if (axes)
@ -796,16 +804,13 @@ gdk_device_get_state (GdkDevice *device,
else else
{ {
GdkDevicePrivate *gdkdev; GdkDevicePrivate *gdkdev;
GdkInputWindow *input_window;
XDeviceState *state; XDeviceState *state;
XInputClass *input_class; XInputClass *input_class;
if (mask) if (mask)
gdk_window_get_pointer (window, NULL, NULL, mask); gdk_window_get_pointer (window, NULL, NULL, mask);
gdkdev = (GdkDevicePrivate *)device; gdkdev = (GdkDevicePrivate *)device;
input_window = _gdk_input_window_find (window);
g_return_if_fail (input_window != NULL);
state = XQueryDeviceState (GDK_WINDOW_XDISPLAY (window), state = XQueryDeviceState (GDK_WINDOW_XDISPLAY (window),
gdkdev->xdevice); gdkdev->xdevice);
@ -816,11 +821,11 @@ gdk_device_get_state (GdkDevice *device,
{ {
case ValuatorClass: case ValuatorClass:
if (axes) if (axes)
gdk_input_translate_coordinates (gdkdev, input_window, gdk_input_translate_coordinates (gdkdev, window,
((XValuatorState *)input_class)->valuators, ((XValuatorState *)input_class)->valuators,
axes, NULL, NULL); axes, NULL, NULL);
break; break;
case ButtonClass: case ButtonClass:
if (mask) if (mask)
{ {

View File

@ -26,18 +26,18 @@
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog * file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with * files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/. * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/ */
/* forward declarations */ /* forward declarations */
static void gdk_input_check_proximity (GdkDisplay *display); static void gdk_input_check_proximity (GdkDisplay *display);
void void
_gdk_input_init(GdkDisplay *display) _gdk_input_init(GdkDisplay *display)
{ {
_gdk_init_input_core (display); _gdk_init_input_core (display);
GDK_DISPLAY_X11 (display)->input_ignore_core = FALSE; display->ignore_core_events = FALSE;
_gdk_input_common_init (display, FALSE); _gdk_input_common_init (display, FALSE);
} }
@ -47,7 +47,6 @@ gdk_device_set_mode (GdkDevice *device,
{ {
GList *tmp_list; GList *tmp_list;
GdkDevicePrivate *gdkdev; GdkDevicePrivate *gdkdev;
GdkInputMode old_mode;
GdkInputWindow *input_window; GdkInputWindow *input_window;
GdkDisplayX11 *display_impl; GdkDisplayX11 *display_impl;
@ -59,58 +58,35 @@ gdk_device_set_mode (GdkDevice *device,
if (device->mode == mode) if (device->mode == mode)
return TRUE; return TRUE;
old_mode = device->mode;
device->mode = mode; device->mode = mode;
display_impl = GDK_DISPLAY_X11 (gdkdev->display);
if (mode == GDK_MODE_WINDOW) if (mode == GDK_MODE_WINDOW)
{ device->has_cursor = FALSE;
device->has_cursor = FALSE;
for (tmp_list = display_impl->input_windows; tmp_list; tmp_list = tmp_list->next)
{
input_window = (GdkInputWindow *)tmp_list->data;
if (input_window->mode != GDK_EXTENSION_EVENTS_CURSOR)
_gdk_input_enable_window (input_window->window, gdkdev);
else
if (old_mode != GDK_MODE_DISABLED)
_gdk_input_disable_window (input_window->window, gdkdev);
}
}
else if (mode == GDK_MODE_SCREEN) else if (mode == GDK_MODE_SCREEN)
device->has_cursor = TRUE;
display_impl = GDK_DISPLAY_X11 (gdkdev->display);
for (tmp_list = display_impl->input_windows; tmp_list; tmp_list = tmp_list->next)
{ {
device->has_cursor = TRUE; input_window = (GdkInputWindow *)tmp_list->data;
for (tmp_list = display_impl->input_windows; tmp_list; tmp_list = tmp_list->next) _gdk_input_select_events (input_window->impl_window, gdkdev);
_gdk_input_enable_window (((GdkInputWindow *)tmp_list->data)->window,
gdkdev);
}
else /* mode == GDK_MODE_DISABLED */
{
for (tmp_list = display_impl->input_windows; tmp_list; tmp_list = tmp_list->next)
{
input_window = (GdkInputWindow *)tmp_list->data;
if (old_mode != GDK_MODE_WINDOW ||
input_window->mode != GDK_EXTENSION_EVENTS_CURSOR)
_gdk_input_disable_window (input_window->window, gdkdev);
}
} }
return TRUE; return TRUE;
} }
static void static void
gdk_input_check_proximity (GdkDisplay *display) gdk_input_check_proximity (GdkDisplay *display)
{ {
gint new_proximity = 0;
GdkDisplayX11 *display_impl = GDK_DISPLAY_X11 (display); GdkDisplayX11 *display_impl = GDK_DISPLAY_X11 (display);
GList *tmp_list = display_impl->input_devices; GList *tmp_list = display_impl->input_devices;
gint new_proximity = 0;
while (tmp_list && !new_proximity) while (tmp_list && !new_proximity)
{ {
GdkDevicePrivate *gdkdev = (GdkDevicePrivate *)(tmp_list->data); GdkDevicePrivate *gdkdev = (GdkDevicePrivate *)(tmp_list->data);
if (gdkdev->info.mode != GDK_MODE_DISABLED if (gdkdev->info.mode != GDK_MODE_DISABLED
&& !GDK_IS_CORE (gdkdev) && !GDK_IS_CORE (gdkdev)
&& gdkdev->xdevice) && gdkdev->xdevice)
{ {
@ -118,7 +94,7 @@ gdk_input_check_proximity (GdkDisplay *display)
gdkdev->xdevice); gdkdev->xdevice);
XInputClass *xic; XInputClass *xic;
int i; int i;
xic = state->data; xic = state->data;
for (i=0; i<state->num_classes; i++) for (i=0; i<state->num_classes; i++)
{ {
@ -135,117 +111,197 @@ gdk_input_check_proximity (GdkDisplay *display)
} }
XFreeDeviceState (state); XFreeDeviceState (state);
} }
tmp_list = tmp_list->next; tmp_list = tmp_list->next;
} }
display_impl->input_ignore_core = new_proximity; display->ignore_core_events = new_proximity;
} }
void void
_gdk_input_configure_event (XConfigureEvent *xevent, _gdk_input_configure_event (XConfigureEvent *xevent,
GdkWindow *window) GdkWindow *window)
{ {
GdkWindowObject *priv = (GdkWindowObject *)window;
GdkInputWindow *input_window; GdkInputWindow *input_window;
gint root_x, root_y; gint root_x, root_y;
input_window = _gdk_input_window_find(window); input_window = priv->input_window;
g_return_if_fail (input_window != NULL); if (input_window != NULL)
{
_gdk_input_get_root_relative_geometry(GDK_WINDOW_XDISPLAY (window), _gdk_input_get_root_relative_geometry (window, &root_x, &root_y);
GDK_WINDOW_XWINDOW (window), input_window->root_x = root_x;
&root_x, &root_y, NULL, NULL); input_window->root_y = root_y;
}
input_window->root_x = root_x;
input_window->root_y = root_y;
} }
void void
_gdk_input_enter_event (XCrossingEvent *xevent, _gdk_input_crossing_event (GdkWindow *window,
GdkWindow *window) gboolean enter)
{ {
GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
GdkDisplayX11 *display_impl = GDK_DISPLAY_X11 (display);
GdkWindowObject *priv = (GdkWindowObject *)window;
GdkInputWindow *input_window; GdkInputWindow *input_window;
gint root_x, root_y; gint root_x, root_y;
input_window = _gdk_input_window_find (window); if (enter)
g_return_if_fail (input_window != NULL); {
gdk_input_check_proximity(display);
gdk_input_check_proximity(GDK_WINDOW_DISPLAY (window)); input_window = priv->input_window;
if (input_window != NULL)
_gdk_input_get_root_relative_geometry(GDK_WINDOW_XDISPLAY (window), {
GDK_WINDOW_XWINDOW(window), _gdk_input_get_root_relative_geometry (window, &root_x, &root_y);
&root_x, &root_y, NULL, NULL); input_window->root_x = root_x;
input_window->root_y = root_y;
input_window->root_x = root_x; }
input_window->root_y = root_y; }
else
display->ignore_core_events = FALSE;
} }
gboolean static GdkEventType
_gdk_input_other_event (GdkEvent *event, get_input_event_type (GdkDevicePrivate *gdkdev,
XEvent *xevent, XEvent *xevent,
GdkWindow *window) int *core_x, int *core_y)
{ {
GdkInputWindow *input_window; if (xevent->type == gdkdev->buttonpress_type)
{
XDeviceButtonEvent *xie = (XDeviceButtonEvent *)(xevent);
*core_x = xie->x;
*core_y = xie->y;
return GDK_BUTTON_PRESS;
}
if (xevent->type == gdkdev->buttonrelease_type)
{
XDeviceButtonEvent *xie = (XDeviceButtonEvent *)(xevent);
*core_x = xie->x;
*core_y = xie->y;
return GDK_BUTTON_RELEASE;
}
if (xevent->type == gdkdev->keypress_type)
{
XDeviceKeyEvent *xie = (XDeviceKeyEvent *)(xevent);
*core_x = xie->x;
*core_y = xie->y;
return GDK_KEY_PRESS;
}
if (xevent->type == gdkdev->keyrelease_type)
{
XDeviceKeyEvent *xie = (XDeviceKeyEvent *)(xevent);
*core_x = xie->x;
*core_y = xie->y;
return GDK_KEY_RELEASE;
}
if (xevent->type == gdkdev->motionnotify_type)
{
XDeviceMotionEvent *xie = (XDeviceMotionEvent *)(xevent);
*core_x = xie->x;
*core_y = xie->y;
return GDK_MOTION_NOTIFY;
}
if (xevent->type == gdkdev->proximityin_type)
{
XProximityNotifyEvent *xie = (XProximityNotifyEvent *)(xevent);
*core_x = xie->x;
*core_y = xie->y;
return GDK_PROXIMITY_IN;
}
if (xevent->type == gdkdev->proximityout_type)
{
XProximityNotifyEvent *xie = (XProximityNotifyEvent *)(xevent);
*core_x = xie->x;
*core_y = xie->y;
return GDK_PROXIMITY_OUT;
}
*core_x = 0;
*core_y = 0;
return GDK_NOTHING;
}
gboolean
_gdk_input_other_event (GdkEvent *event,
XEvent *xevent,
GdkWindow *event_window)
{
GdkWindow *window;
GdkWindowObject *priv;
GdkInputWindow *iw;
GdkDevicePrivate *gdkdev; GdkDevicePrivate *gdkdev;
gint return_val; gint return_val;
GdkDisplayX11 *display_impl = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window)); GdkEventType event_type;
int x, y;
input_window = _gdk_input_window_find(window); GdkDisplay *display = GDK_WINDOW_DISPLAY (event_window);
g_return_val_if_fail (input_window != NULL, FALSE); GdkDisplayX11 *display_impl = GDK_DISPLAY_X11 (display);
/* This is a sort of a hack, as there isn't any XDeviceAnyEvent - /* This is a sort of a hack, as there isn't any XDeviceAnyEvent -
but it's potentially faster than scanning through the types of but it's potentially faster than scanning through the types of
every device. If we were deceived, then it won't match any of every device. If we were deceived, then it won't match any of
the types for the device anyways */ the types for the device anyways */
gdkdev = _gdk_input_find_device (GDK_WINDOW_DISPLAY (window), gdkdev = _gdk_input_find_device (display,
((XDeviceButtonEvent *)xevent)->deviceid); ((XDeviceButtonEvent *)xevent)->deviceid);
if (!gdkdev) if (!gdkdev)
return FALSE; /* we don't handle it - not an XInput event */ return FALSE; /* we don't handle it - not an XInput event */
/* FIXME: It would be nice if we could just get rid of the events event_type = get_input_event_type (gdkdev, xevent, &x, &y);
entirely, instead of having to ignore them */ if (event_type == GDK_NOTHING)
if (gdkdev->info.mode == GDK_MODE_DISABLED ||
(gdkdev->info.mode == GDK_MODE_WINDOW
&& input_window->mode == GDK_EXTENSION_EVENTS_CURSOR))
return FALSE; return FALSE;
if (!display_impl->input_ignore_core)
gdk_input_check_proximity(GDK_WINDOW_DISPLAY (window));
return_val = _gdk_input_common_other_event (event, xevent, window = _gdk_window_get_input_window_for_event (event_window,
input_window, gdkdev); event_type,
x, y,
xevent->xany.serial);
/* If we're not getting any event window its likely because we're outside the
window and there is no grab. We should still report according to the
implicit grab though. */
iw = ((GdkWindowObject *)event_window)->input_window;
if (window == NULL)
window = iw->button_down_window;
priv = (GdkWindowObject *)window;
if (window == NULL)
return FALSE;
if (gdkdev->info.mode == GDK_MODE_DISABLED ||
!(gdkdev->info.has_cursor || (priv->extension_events & GDK_ALL_DEVICES_MASK)))
return FALSE;
if (!display->ignore_core_events && priv->extension_events != 0)
gdk_input_check_proximity (GDK_WINDOW_DISPLAY (window));
return_val = _gdk_input_common_other_event (event, xevent, window, gdkdev);
if (return_val && event->type == GDK_BUTTON_PRESS)
iw->button_down_window = window;
if (return_val && event->type == GDK_BUTTON_RELEASE)
iw->button_down_window = NULL;
if (return_val && event->type == GDK_PROXIMITY_OUT && if (return_val && event->type == GDK_PROXIMITY_OUT &&
display_impl->input_ignore_core) display->ignore_core_events)
gdk_input_check_proximity(GDK_WINDOW_DISPLAY (window)); gdk_input_check_proximity (GDK_WINDOW_DISPLAY (window));
return return_val; return return_val;
} }
gboolean gint
_gdk_input_enable_window(GdkWindow *window, GdkDevicePrivate *gdkdev) _gdk_input_grab_pointer (GdkWindow *window,
{ GdkWindow *native_window, /* This is the toplevel */
/* FIXME: watchout, gdkdev might be core pointer, never opened */
_gdk_input_common_select_events (window, gdkdev);
return TRUE;
}
gboolean
_gdk_input_disable_window(GdkWindow *window, GdkDevicePrivate *gdkdev)
{
_gdk_input_common_select_events (window, gdkdev);
return TRUE;
}
gint
_gdk_input_grab_pointer (GdkWindow * window,
gint owner_events, gint owner_events,
GdkEventMask event_mask, GdkEventMask event_mask,
GdkWindow * confine_to, GdkWindow * confine_to,
guint32 time) guint32 time)
{ {
GdkInputWindow *input_window, *new_window; GdkInputWindow *input_window;
GdkWindowObject *priv, *impl_window;
gboolean need_ungrab; gboolean need_ungrab;
GdkDevicePrivate *gdkdev; GdkDevicePrivate *gdkdev;
GList *tmp_list; GList *tmp_list;
@ -255,36 +311,36 @@ _gdk_input_grab_pointer (GdkWindow * window,
GdkDisplayX11 *display_impl = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window)); GdkDisplayX11 *display_impl = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window));
tmp_list = display_impl->input_windows; tmp_list = display_impl->input_windows;
new_window = NULL;
need_ungrab = FALSE; need_ungrab = FALSE;
while (tmp_list) while (tmp_list)
{ {
input_window = (GdkInputWindow *)tmp_list->data; input_window = (GdkInputWindow *)tmp_list->data;
if (input_window->window == window) if (input_window->grabbed)
new_window = input_window;
else if (input_window->grabbed)
{ {
input_window->grabbed = FALSE; input_window->grabbed = FALSE;
need_ungrab = TRUE; need_ungrab = TRUE;
break;
} }
tmp_list = tmp_list->next; tmp_list = tmp_list->next;
} }
if (new_window) priv = (GdkWindowObject *)window;
impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window);
input_window = impl_window->input_window;
if (priv->extension_events)
{ {
new_window->grabbed = TRUE; g_assert (input_window != NULL);
input_window->grabbed = TRUE;
tmp_list = display_impl->input_devices; tmp_list = display_impl->input_devices;
while (tmp_list) while (tmp_list)
{ {
gdkdev = (GdkDevicePrivate *)tmp_list->data; gdkdev = (GdkDevicePrivate *)tmp_list->data;
if (!GDK_IS_CORE (gdkdev) && gdkdev->xdevice) if (!GDK_IS_CORE (gdkdev) && gdkdev->xdevice)
{ {
_gdk_input_common_find_events (window, gdkdev, _gdk_input_common_find_events (gdkdev, event_mask,
event_mask,
event_classes, &num_classes); event_classes, &num_classes);
#ifdef G_ENABLE_DEBUG #ifdef G_ENABLE_DEBUG
if (_gdk_debug_flags & GDK_DEBUG_NOGRABS) if (_gdk_debug_flags & GDK_DEBUG_NOGRABS)
@ -292,10 +348,10 @@ _gdk_input_grab_pointer (GdkWindow * window,
else else
#endif #endif
result = XGrabDevice (display_impl->xdisplay, gdkdev->xdevice, result = XGrabDevice (display_impl->xdisplay, gdkdev->xdevice,
GDK_WINDOW_XWINDOW (window), GDK_WINDOW_XWINDOW (native_window),
owner_events, num_classes, event_classes, owner_events, num_classes, event_classes,
GrabModeAsync, GrabModeAsync, time); GrabModeAsync, GrabModeAsync, time);
/* FIXME: if failure occurs on something other than the first /* FIXME: if failure occurs on something other than the first
device, things will be badly inconsistent */ device, things will be badly inconsistent */
if (result != Success) if (result != Success)
@ -305,7 +361,7 @@ _gdk_input_grab_pointer (GdkWindow * window,
} }
} }
else else
{ {
tmp_list = display_impl->input_devices; tmp_list = display_impl->input_devices;
while (tmp_list) while (tmp_list)
{ {
@ -316,17 +372,16 @@ _gdk_input_grab_pointer (GdkWindow * window,
XUngrabDevice (display_impl->xdisplay, gdkdev->xdevice, time); XUngrabDevice (display_impl->xdisplay, gdkdev->xdevice, time);
gdkdev->button_state = 0; gdkdev->button_state = 0;
} }
tmp_list = tmp_list->next; tmp_list = tmp_list->next;
} }
} }
return Success; return Success;
} }
void void
_gdk_input_ungrab_pointer (GdkDisplay *display, _gdk_input_ungrab_pointer (GdkDisplay *display,
guint32 time) guint32 time)
{ {
GdkInputWindow *input_window = NULL; /* Quiet GCC */ GdkInputWindow *input_window = NULL; /* Quiet GCC */

View File

@ -21,7 +21,7 @@
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog * file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with * files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/. * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/ */
#include "config.h" #include "config.h"
@ -47,10 +47,10 @@ void
_gdk_init_input_core (GdkDisplay *display) _gdk_init_input_core (GdkDisplay *display)
{ {
GdkDevicePrivate *private; GdkDevicePrivate *private;
display->core_pointer = g_object_new (GDK_TYPE_DEVICE, NULL); display->core_pointer = g_object_new (GDK_TYPE_DEVICE, NULL);
private = (GdkDevicePrivate *)display->core_pointer; private = (GdkDevicePrivate *)display->core_pointer;
display->core_pointer->name = "Core Pointer"; display->core_pointer->name = "Core Pointer";
display->core_pointer->source = GDK_SOURCE_MOUSE; display->core_pointer->source = GDK_SOURCE_MOUSE;
display->core_pointer->mode = GDK_MODE_SCREEN; display->core_pointer->mode = GDK_MODE_SCREEN;
@ -87,12 +87,12 @@ gdk_device_get_type (void)
0, /* n_preallocs */ 0, /* n_preallocs */
(GInstanceInitFunc) NULL, (GInstanceInitFunc) NULL,
}; };
object_type = g_type_register_static (G_TYPE_OBJECT, object_type = g_type_register_static (G_TYPE_OBJECT,
g_intern_static_string ("GdkDevice"), g_intern_static_string ("GdkDevice"),
&object_info, 0); &object_info, 0);
} }
return object_type; return object_type;
} }
@ -115,10 +115,10 @@ gdk_device_dispose (GObject *object)
{ {
#ifndef XINPUT_NONE #ifndef XINPUT_NONE
if (gdkdev->xdevice) if (gdkdev->xdevice)
{ {
XCloseDevice (GDK_DISPLAY_XDISPLAY (gdkdev->display), gdkdev->xdevice); XCloseDevice (GDK_DISPLAY_XDISPLAY (gdkdev->display), gdkdev->xdevice);
gdkdev->xdevice = NULL; gdkdev->xdevice = NULL;
} }
g_free (gdkdev->axes); g_free (gdkdev->axes);
gdkdev->axes = NULL; gdkdev->axes = NULL;
#endif /* !XINPUT_NONE */ #endif /* !XINPUT_NONE */
@ -140,7 +140,7 @@ gdk_device_dispose (GObject *object)
* *
* Returns the list of available input devices for the default display. * Returns the list of available input devices for the default display.
* The list is statically allocated and should not be freed. * The list is statically allocated and should not be freed.
* *
* Return value: a list of #GdkDevice * Return value: a list of #GdkDevice
**/ **/
GList * GList *
@ -155,16 +155,16 @@ gdk_devices_list (void)
* *
* Returns the list of available input devices attached to @display. * Returns the list of available input devices attached to @display.
* The list is statically allocated and should not be freed. * The list is statically allocated and should not be freed.
* *
* Return value: a list of #GdkDevice * Return value: a list of #GdkDevice
* *
* Since: 2.2 * Since: 2.2
**/ **/
GList * GList *
gdk_display_list_devices (GdkDisplay *display) gdk_display_list_devices (GdkDisplay *display)
{ {
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
return GDK_DISPLAY_X11 (display)->input_devices; return GDK_DISPLAY_X11 (display)->input_devices;
} }
@ -219,6 +219,22 @@ gdk_device_set_axis_use (GdkDevice *device,
} }
} }
static gboolean
impl_coord_in_window (GdkWindow *window,
int impl_x,
int impl_y)
{
GdkWindowObject *priv = (GdkWindowObject *)window;
if (impl_x < priv->abs_x ||
impl_x > priv->abs_x + priv->width)
return FALSE;
if (impl_y < priv->abs_y ||
impl_y > priv->abs_y + priv->height)
return FALSE;
return TRUE;
}
/** /**
* gdk_device_get_history: * gdk_device_get_history:
* @device: a #GdkDevice * @device: a #GdkDevice
@ -227,14 +243,14 @@ gdk_device_set_axis_use (GdkDevice *device,
* @stop: ending timestamp for the range of events to return * @stop: ending timestamp for the range of events to return
* @events: location to store a newly-allocated array of #GdkTimeCoord, or %NULL * @events: location to store a newly-allocated array of #GdkTimeCoord, or %NULL
* @n_events: location to store the length of @events, or %NULL * @n_events: location to store the length of @events, or %NULL
* *
* Obtains the motion history for a device; given a starting and * Obtains the motion history for a device; given a starting and
* ending timestamp, return all events in the motion history for * ending timestamp, return all events in the motion history for
* the device in the given range of time. Some windowing systems * the device in the given range of time. Some windowing systems
* do not support motion history, in which case, %FALSE will * do not support motion history, in which case, %FALSE will
* be returned. (This is not distinguishable from the case where * be returned. (This is not distinguishable from the case where
* motion history is supported and no events were found.) * motion history is supported and no events were found.)
* *
* Return value: %TRUE if the windowing system supports motion history and * Return value: %TRUE if the windowing system supports motion history and
* at least one event was found. * at least one event was found.
**/ **/
@ -247,29 +263,38 @@ gdk_device_get_history (GdkDevice *device,
gint *n_events) gint *n_events)
{ {
GdkTimeCoord **coords = NULL; GdkTimeCoord **coords = NULL;
GdkWindow *impl_window;
gboolean result = FALSE; gboolean result = FALSE;
int tmp_n_events = 0; int tmp_n_events = 0;
int i; int i, j;
g_return_val_if_fail (GDK_WINDOW_IS_X11 (window), FALSE); g_return_val_if_fail (GDK_WINDOW_IS_X11 (window), FALSE);
impl_window = _gdk_window_get_impl_window (window);
if (GDK_WINDOW_DESTROYED (window)) if (GDK_WINDOW_DESTROYED (window))
/* Nothing */ ; /* Nothing */ ;
else if (GDK_IS_CORE (device)) else if (GDK_IS_CORE (device))
{ {
XTimeCoord *xcoords; XTimeCoord *xcoords;
xcoords = XGetMotionEvents (GDK_DRAWABLE_XDISPLAY (window), xcoords = XGetMotionEvents (GDK_DRAWABLE_XDISPLAY (window),
GDK_DRAWABLE_XID (window), GDK_DRAWABLE_XID (impl_window),
start, stop, &tmp_n_events); start, stop, &tmp_n_events);
if (xcoords) if (xcoords)
{ {
GdkWindowObject *priv = (GdkWindowObject *)window;
coords = _gdk_device_allocate_history (device, tmp_n_events); coords = _gdk_device_allocate_history (device, tmp_n_events);
j = 0;
for (i=0; i<tmp_n_events; i++) for (i=0; i<tmp_n_events; i++)
{ {
coords[i]->time = xcoords[i].time; if (impl_coord_in_window (window, xcoords[i].x, xcoords[i].y))
coords[i]->axes[0] = xcoords[i].x; {
coords[i]->axes[1] = xcoords[i].y; coords[j]->time = xcoords[i].time;
coords[j]->axes[0] = xcoords[i].x - priv->abs_x;
coords[j]->axes[1] = xcoords[i].y - priv->abs_y;
j++;
}
} }
XFree (xcoords); XFree (xcoords);
@ -292,7 +317,7 @@ gdk_device_get_history (GdkDevice *device,
return result; return result;
} }
GdkTimeCoord ** GdkTimeCoord **
_gdk_device_allocate_history (GdkDevice *device, _gdk_device_allocate_history (GdkDevice *device,
gint n_events) gint n_events)
{ {
@ -306,48 +331,56 @@ _gdk_device_allocate_history (GdkDevice *device,
return result; return result;
} }
void void
gdk_device_free_history (GdkTimeCoord **events, gdk_device_free_history (GdkTimeCoord **events,
gint n_events) gint n_events)
{ {
gint i; gint i;
for (i=0; i<n_events; i++) for (i=0; i<n_events; i++)
g_free (events[i]); g_free (events[i]);
g_free (events); g_free (events);
} }
GdkInputWindow * static void
_gdk_input_window_find(GdkWindow *window) unset_extension_events (GdkWindow *window)
{ {
GList *tmp_list; GdkWindowObject *window_private;
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window)); GdkWindowObject *impl_window;
GdkDisplayX11 *display_x11;
GdkInputWindow *iw;
/* Ensure we have a native window, or the input stuff won't work. window_private = (GdkWindowObject*) window;
Its possible we could emulate this also, but at least this should make impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window);
it work. */ iw = impl_window->input_window;
gdk_window_set_has_native (window, TRUE);
for (tmp_list=display_x11->input_windows; tmp_list; tmp_list=tmp_list->next) display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window));
if (((GdkInputWindow *)(tmp_list->data))->window == window)
return (GdkInputWindow *)(tmp_list->data);
return NULL; /* Not found */ if (window_private->extension_events != 0)
{
g_assert (iw != NULL);
g_assert (g_list_find (iw->windows, window) != NULL);
iw->windows = g_list_remove (iw->windows, window);
if (iw->windows == NULL)
{
impl_window->input_window = NULL;
display_x11->input_windows = g_list_remove (display_x11->input_windows, iw);
g_free (iw);
}
}
window_private->extension_events = 0;
} }
/* FIXME: this routine currently needs to be called between creation
and the corresponding configure event (because it doesn't get the
root_relative_geometry). This should work with
gtk_window_set_extension_events, but will likely fail in other
cases */
void void
gdk_input_set_extension_events (GdkWindow *window, gint mask, gdk_input_set_extension_events (GdkWindow *window, gint mask,
GdkExtensionMode mode) GdkExtensionMode mode)
{ {
GdkWindowObject *window_private; GdkWindowObject *window_private;
GList *tmp_list; GList *tmp_list;
GdkWindowObject *impl_window;
GdkInputWindow *iw; GdkInputWindow *iw;
GdkDisplayX11 *display_x11; GdkDisplayX11 *display_x11;
@ -359,52 +392,44 @@ gdk_input_set_extension_events (GdkWindow *window, gint mask,
if (GDK_WINDOW_DESTROYED (window)) if (GDK_WINDOW_DESTROYED (window))
return; return;
impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window);
if (mode == GDK_EXTENSION_EVENTS_ALL && mask != 0)
mask |= GDK_ALL_DEVICES_MASK;
if (mode == GDK_EXTENSION_EVENTS_NONE) if (mode == GDK_EXTENSION_EVENTS_NONE)
mask = 0; mask = 0;
iw = _gdk_input_window_find (window); iw = impl_window->input_window;
if (mask != 0) if (mask != 0)
{ {
if (!iw) if (!iw)
{ {
iw = g_new(GdkInputWindow,1); iw = g_new0 (GdkInputWindow,1);
iw->window = window; iw->impl_window = (GdkWindow *)impl_window;
iw->mode = mode;
iw->obscuring = NULL; iw->windows = NULL;
iw->num_obscuring = 0; iw->grabbed = FALSE;
iw->grabbed = FALSE;
display_x11->input_windows = g_list_append(display_x11->input_windows,iw); display_x11->input_windows = g_list_append (display_x11->input_windows, iw);
}
window_private->extension_events = mask;
#ifndef XINPUT_NONE #ifndef XINPUT_NONE
/* Add enter window events to the event mask */ /* we might not receive ConfigureNotify so get the root_relative_geometry
/* this is not needed for XINPUT_NONE */ * now, just in case */
gdk_window_set_events (window, _gdk_input_get_root_relative_geometry (window, &iw->root_x, &iw->root_y);
gdk_window_get_events (window) |
GDK_ENTER_NOTIFY_MASK);
/* we might not receive ConfigureNotify so get the root_relative_geometry
* now, just in case */
_gdk_input_get_root_relative_geometry (GDK_WINDOW_XDISPLAY (window),
GDK_WINDOW_XWINDOW (window),
&iw->root_x, &iw->root_y, NULL, NULL);
#endif /* !XINPUT_NONE */ #endif /* !XINPUT_NONE */
impl_window->input_window = iw;
}
if (window_private->extension_events == 0)
iw->windows = g_list_append (iw->windows, window);
window_private->extension_events = mask;
} }
else else
{ {
if (iw) unset_extension_events (window);
{
display_x11->input_windows = g_list_remove(display_x11->input_windows,iw);
g_free(iw);
}
window_private->extension_events = 0;
} }
for (tmp_list = display_x11->input_devices; tmp_list; tmp_list = tmp_list->next) for (tmp_list = display_x11->input_devices; tmp_list; tmp_list = tmp_list->next)
@ -412,57 +437,14 @@ gdk_input_set_extension_events (GdkWindow *window, gint mask,
GdkDevicePrivate *gdkdev = tmp_list->data; GdkDevicePrivate *gdkdev = tmp_list->data;
if (!GDK_IS_CORE (gdkdev)) if (!GDK_IS_CORE (gdkdev))
{ _gdk_input_select_events ((GdkWindow *)impl_window, gdkdev);
if (mask != 0 && gdkdev->info.mode != GDK_MODE_DISABLED
&& (gdkdev->info.has_cursor || mode == GDK_EXTENSION_EVENTS_ALL))
_gdk_input_enable_window (window,gdkdev);
else
_gdk_input_disable_window (window,gdkdev);
}
} }
} }
void void
_gdk_input_window_destroy (GdkWindow *window) _gdk_input_window_destroy (GdkWindow *window)
{ {
GdkInputWindow *input_window; unset_extension_events (window);
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window));
input_window = _gdk_input_window_find (window);
g_return_if_fail (input_window != NULL);
display_x11->input_windows = g_list_remove (display_x11->input_windows, input_window);
g_free(input_window);
}
void
_gdk_input_exit (void)
{
GList *tmp_list;
GSList *display_list;
GdkDevicePrivate *gdkdev;
for (display_list = _gdk_displays ; display_list ; display_list = display_list->next)
{
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display_list->data);
for (tmp_list = display_x11->input_devices; tmp_list; tmp_list = tmp_list->next)
{
gdkdev = (GdkDevicePrivate *)(tmp_list->data);
if (!GDK_IS_CORE (gdkdev))
{
gdk_device_set_mode (&gdkdev->info, GDK_MODE_DISABLED);
g_object_unref(gdkdev);
}
}
g_list_free(display_x11->input_devices);
for (tmp_list = display_x11->input_windows; tmp_list; tmp_list = tmp_list->next)
g_free(tmp_list->data);
g_list_free(display_x11->input_windows);
}
} }
/** /**
@ -471,10 +453,10 @@ _gdk_input_exit (void)
* @axes: pointer to an array of axes * @axes: pointer to an array of axes
* @use: the use to look for * @use: the use to look for
* @value: location to store the found value. * @value: location to store the found value.
* *
* Interprets an array of double as axis values for a given device, * Interprets an array of double as axis values for a given device,
* and locates the value in the array for a given axis use. * and locates the value in the array for a given axis use.
* *
* Return value: %TRUE if the given axis use was found, otherwise %FALSE * Return value: %TRUE if the given axis use was found, otherwise %FALSE
**/ **/
gboolean gboolean
@ -484,12 +466,12 @@ gdk_device_get_axis (GdkDevice *device,
gdouble *value) gdouble *value)
{ {
gint i; gint i;
g_return_val_if_fail (device != NULL, FALSE); g_return_val_if_fail (device != NULL, FALSE);
if (axes == NULL) if (axes == NULL)
return FALSE; return FALSE;
for (i=0; i<device->num_axes; i++) for (i=0; i<device->num_axes; i++)
if (device->axes[i].use == use) if (device->axes[i].use == use)
{ {
@ -497,7 +479,7 @@ gdk_device_get_axis (GdkDevice *device,
*value = axes[i]; *value = axes[i];
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
} }

View File

@ -41,7 +41,6 @@
typedef struct _GdkAxisInfo GdkAxisInfo; typedef struct _GdkAxisInfo GdkAxisInfo;
typedef struct _GdkDevicePrivate GdkDevicePrivate; typedef struct _GdkDevicePrivate GdkDevicePrivate;
typedef struct _GdkInputWindow GdkInputWindow;
/* information about a device axis */ /* information about a device axis */
struct _GdkAxisInfo struct _GdkAxisInfo
@ -102,28 +101,25 @@ struct _GdkDeviceClass
GObjectClass parent_class; GObjectClass parent_class;
}; };
/* Addition used for extension_events mask */
#define GDK_ALL_DEVICES_MASK (1<<30)
struct _GdkInputWindow struct _GdkInputWindow
{ {
/* gdk window */ GList *windows; /* GdkWindow:s with extension_events set */
GdkWindow *window;
/* Extension mode (GDK_EXTENSION_EVENTS_ALL/CURSOR) */ /* gdk window */
GdkExtensionMode mode; GdkWindow *impl_window; /* an impl window */
GdkWindow *button_down_window;
/* position relative to root window */ /* position relative to root window */
gint root_x; gint root_x;
gint root_y; gint root_y;
/* rectangles relative to window of windows obscuring this one */
GdkRectangle *obscuring;
gint num_obscuring;
/* Is there a pointer grab for this window ? */ /* Is there a pointer grab for this window ? */
gint grabbed; gint grabbed;
}; };
/* Global data */ /* Global data */
#define GDK_IS_CORE(d) (((GdkDevice *)(d)) == ((GdkDevicePrivate *)(d))->display->core_pointer) #define GDK_IS_CORE(d) (((GdkDevice *)(d)) == ((GdkDevicePrivate *)(d))->display->core_pointer)
@ -139,18 +135,15 @@ void _gdk_init_input_core (GdkDisplay *display);
/* The following functions are provided by each implementation /* The following functions are provided by each implementation
* (xfree, gxi, and none) * (xfree, gxi, and none)
*/ */
gint _gdk_input_enable_window (GdkWindow *window,
GdkDevicePrivate *gdkdev);
gint _gdk_input_disable_window (GdkWindow *window,
GdkDevicePrivate *gdkdev);
void _gdk_input_configure_event (XConfigureEvent *xevent, void _gdk_input_configure_event (XConfigureEvent *xevent,
GdkWindow *window); GdkWindow *window);
void _gdk_input_enter_event (XCrossingEvent *xevent, void _gdk_input_crossing_event (GdkWindow *window,
GdkWindow *window); gboolean enter);
gboolean _gdk_input_other_event (GdkEvent *event, gboolean _gdk_input_other_event (GdkEvent *event,
XEvent *xevent, XEvent *xevent,
GdkWindow *window); GdkWindow *window);
gint _gdk_input_grab_pointer (GdkWindow *window, gint _gdk_input_grab_pointer (GdkWindow *window,
GdkWindow *native_window,
gint owner_events, gint owner_events,
GdkEventMask event_mask, GdkEventMask event_mask,
GdkWindow *confine_to, GdkWindow *confine_to,
@ -172,22 +165,18 @@ gint _gdk_input_common_init (GdkDisplay *display,
gint include_core); gint include_core);
GdkDevicePrivate * _gdk_input_find_device (GdkDisplay *display, GdkDevicePrivate * _gdk_input_find_device (GdkDisplay *display,
guint32 id); guint32 id);
void _gdk_input_get_root_relative_geometry(Display *display, void _gdk_input_get_root_relative_geometry(GdkWindow *window,
Window w,
int *x_ret, int *x_ret,
int *y_ret, int *y_ret);
int *width_ret, void _gdk_input_common_find_events (GdkDevicePrivate *gdkdev,
int *height_ret);
void _gdk_input_common_find_events (GdkWindow *window,
GdkDevicePrivate *gdkdev,
gint mask, gint mask,
XEventClass *classes, XEventClass *classes,
int *num_classes); int *num_classes);
void _gdk_input_common_select_events (GdkWindow *window, void _gdk_input_select_events (GdkWindow *impl_window,
GdkDevicePrivate *gdkdev); GdkDevicePrivate *gdkdev);
gint _gdk_input_common_other_event (GdkEvent *event, gint _gdk_input_common_other_event (GdkEvent *event,
XEvent *xevent, XEvent *xevent,
GdkInputWindow *input_window, GdkWindow *window,
GdkDevicePrivate *gdkdev); GdkDevicePrivate *gdkdev);
#endif /* !XINPUT_NONE */ #endif /* !XINPUT_NONE */

View File

@ -251,7 +251,8 @@ gdk_pointer_grab (GdkWindow * window,
*/ */
xevent_mask &= ~PointerMotionHintMask; xevent_mask &= ~PointerMotionHintMask;
return_val = _gdk_input_grab_pointer (native, return_val = _gdk_input_grab_pointer (window,
native,
owner_events, owner_events,
event_mask, event_mask,
confine_to, confine_to,

View File

@ -1036,9 +1036,6 @@ _gdk_x11_window_destroy (GdkWindow *window,
_gdk_selection_window_destroyed (window); _gdk_selection_window_destroyed (window);
if (private->extension_events != 0)
_gdk_input_window_destroy (window);
toplevel = _gdk_x11_window_get_toplevel (window); toplevel = _gdk_x11_window_get_toplevel (window);
if (toplevel) if (toplevel)
gdk_toplevel_x11_free_contents (GDK_WINDOW_DISPLAY (window), toplevel); gdk_toplevel_x11_free_contents (GDK_WINDOW_DISPLAY (window), toplevel);
@ -5585,6 +5582,8 @@ gdk_window_impl_iface_init (GdkWindowImplIface *iface)
iface->queue_antiexpose = _gdk_x11_window_queue_antiexpose; iface->queue_antiexpose = _gdk_x11_window_queue_antiexpose;
iface->queue_translation = _gdk_x11_window_queue_translation; iface->queue_translation = _gdk_x11_window_queue_translation;
iface->destroy = _gdk_x11_window_destroy; iface->destroy = _gdk_x11_window_destroy;
iface->input_window_destroy = _gdk_input_window_destroy;
iface->input_window_crossing = _gdk_input_crossing_event;
} }
#define __GDK_WINDOW_X11_C__ #define __GDK_WINDOW_X11_C__