[gtk+/client-side-windows] Initial version of input support
- From: Alexander Larsson <alexl src gnome org>
- To: svn-commits-list gnome org
- Subject: [gtk+/client-side-windows] Initial version of input support
- Date: Fri, 29 May 2009 10:42:10 -0400 (EDT)
commit 7372379c24d183aa23e33cef031b774a5cb25ce4
Author: Alexander Larsson <alexl redhat com>
Date: Fri May 29 16:39:12 2009 +0200
Initial version of input support
---
gdk/gdkdisplay.h | 1 +
gdk/gdkinternals.h | 6 +
gdk/gdkwindow.c | 113 +++++++++++++++++-
gdk/gdkwindowimpl.h | 4 +
gdk/x11/gdkdisplay-x11.h | 5 -
gdk/x11/gdkevents-x11.c | 24 +---
gdk/x11/gdkinput-x11.c | 259 +++++++++++++++++++++--------------------
gdk/x11/gdkinput-xfree.c | 289 +++++++++++++++++++++++++++------------------
gdk/x11/gdkinput.c | 230 +++++++++++++++++-------------------
gdk/x11/gdkinputprivate.h | 41 +++----
gdk/x11/gdkmain-x11.c | 3 +-
gdk/x11/gdkwindow-x11.c | 5 +-
12 files changed, 557 insertions(+), 423 deletions(-)
diff --git a/gdk/gdkdisplay.h b/gdk/gdkdisplay.h
index 3c7bde3..2838d44 100644
--- a/gdk/gdkdisplay.h
+++ b/gdk/gdkdisplay.h
@@ -91,6 +91,7 @@ struct _GdkDisplay
const GdkDisplayPointerHooks *pointer_hooks; /* Current hooks for querying pointer */
guint closed : 1; /* Whether this display has been closed */
+ guint ignore_core_events : 1; /* Don't send core motion and button event */
guint double_click_distance; /* Maximum distance between clicks in pixels */
gint button_x[2]; /* The last 2 button click positions. */
diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h
index 94cce6a..a0c2d51 100644
--- a/gdk/gdkinternals.h
+++ b/gdk/gdkinternals.h
@@ -187,6 +187,7 @@ typedef struct
gboolean grab_one_pointer_release_event;
} GdkPointerGrabInfo;
+typedef struct _GdkInputWindow GdkInputWindow;
/* Private version of GdkWindowObject. The initial part of this strucuture
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 */
GdkWindowPaint *implicit_paint;
+ GdkInputWindow *input_window; /* only for impl windows */
GList *outstanding_moves;
@@ -640,6 +642,10 @@ GdkRegion *_gdk_window_calculate_full_clip_region (GdkWindow *window,
gint *base_y_offset);
gboolean _gdk_window_has_impl (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);
/*****************************
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index a2b5d6d..b20cf69 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -1596,6 +1596,10 @@ _gdk_window_destroy_hierarchy (GdkWindow *window,
NULL, NULL);
}
+
+ if (private->extension_events)
+ GDK_WINDOW_IMPL_GET_IFACE (private->impl)->input_window_destroy (window);
+
if (gdk_window_has_impl (private))
{
GDK_WINDOW_IMPL_GET_IFACE (private->impl)->destroy (window, recursing_native, foreign_destroy);
@@ -8240,6 +8244,10 @@ send_crossing_event (GdkDisplay *display,
else
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)
{
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->motion.time = time_;
@@ -8814,7 +8822,7 @@ proxy_button_event (GdkEvent *source_event,
type, state,
NULL, serial);
- if (event_win == NULL)
+ if (event_win == NULL || display->ignore_core_events)
return TRUE;
event = _gdk_make_event (event_win, type, source_event, FALSE);
@@ -8914,6 +8922,22 @@ gdk_window_print_tree (GdkWindow *window,
#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
_gdk_windowing_got_event (GdkDisplay *display,
GList *event_link,
@@ -8958,6 +8982,9 @@ _gdk_windowing_got_event (GdkDisplay *display,
return;
}
+ if (is_input_event (display, event))
+ return;
+
if (!(is_button_type (event->type) ||
is_motion_type (event->type)) ||
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__
#include "gdkaliasdef.c"
diff --git a/gdk/gdkwindowimpl.h b/gdk/gdkwindowimpl.h
index d63e5a1..1bedb35 100644
--- a/gdk/gdkwindowimpl.h
+++ b/gdk/gdkwindowimpl.h
@@ -128,6 +128,10 @@ struct _GdkWindowImplIface
void (* destroy) (GdkWindow *window,
gboolean recursing,
gboolean foreign_destroy);
+
+ void (* input_window_destroy) (GdkWindow *window);
+ void (* input_window_crossing)(GdkWindow *window,
+ gboolean enter);
};
/* Interface Functions */
diff --git a/gdk/x11/gdkdisplay-x11.h b/gdk/x11/gdkdisplay-x11.h
index e92418d..2873c2d 100644
--- a/gdk/x11/gdkdisplay-x11.h
+++ b/gdk/x11/gdkdisplay-x11.h
@@ -133,11 +133,6 @@ struct _GdkDisplayX11
/* input GdkWindow list */
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 */
gchar *startup_notification_id;
diff --git a/gdk/x11/gdkevents-x11.c b/gdk/x11/gdkevents-x11.c
index 8d3141a..4565b39 100644
--- a/gdk/x11/gdkevents-x11.c
+++ b/gdk/x11/gdkevents-x11.c
@@ -1125,9 +1125,7 @@ gdk_event_translate (GdkDisplay *display,
xevent->xbutton.x, xevent->xbutton.y,
xevent->xbutton.button));
- if (window_private == NULL ||
- ((window_private->extension_events != 0) &&
- display_x11->input_ignore_core))
+ if (window_private == NULL)
{
return_val = FALSE;
break;
@@ -1201,9 +1199,7 @@ gdk_event_translate (GdkDisplay *display,
xevent->xbutton.x, xevent->xbutton.y,
xevent->xbutton.button));
- if (window_private == NULL ||
- ((window_private->extension_events != 0) &&
- display_x11->input_ignore_core))
+ if (window_private == NULL)
{
return_val = FALSE;
break;
@@ -1241,9 +1237,7 @@ gdk_event_translate (GdkDisplay *display,
xevent->xmotion.x, xevent->xmotion.y,
(xevent->xmotion.is_hint) ? "true" : "false"));
- if (window_private == NULL ||
- ((window_private->extension_events != 0) &&
- display_x11->input_ignore_core))
+ if (window_private == NULL)
{
return_val = FALSE;
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.window = window;
@@ -1854,7 +1842,7 @@ gdk_event_translate (GdkDisplay *display,
if (window &&
xevent->xconfigure.event == xevent->xconfigure.window &&
!GDK_WINDOW_DESTROYED (window) &&
- (window_private->extension_events != 0))
+ window_private->input_window != NULL)
_gdk_input_configure_event (&xevent->xconfigure, window);
#ifdef HAVE_XSYNC
@@ -2171,8 +2159,8 @@ gdk_event_translate (GdkDisplay *display,
if (window_private &&
!GDK_WINDOW_DESTROYED (window_private) &&
- (window_private->extension_events != 0))
- return_val = _gdk_input_other_event(event, xevent, window);
+ window_private->input_window)
+ return_val = _gdk_input_other_event (event, xevent, window);
else
return_val = FALSE;
diff --git a/gdk/x11/gdkinput-x11.c b/gdk/x11/gdkinput-x11.c
index 9e2d818..22e39a0 100644
--- a/gdk/x11/gdkinput-x11.c
+++ b/gdk/x11/gdkinput-x11.c
@@ -21,7 +21,7 @@
* 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
* 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"
@@ -39,7 +39,7 @@ static GdkDevicePrivate *gdk_input_device_new (GdkDisplay *disp
XDeviceInfo *device,
gint include_core);
static void gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev,
- GdkInputWindow *input_window,
+ GdkWindow *window,
gint *axis_data,
gdouble *axis_out,
gdouble *x_out,
@@ -64,37 +64,26 @@ _gdk_input_find_device (GdkDisplay *display,
}
void
-_gdk_input_get_root_relative_geometry(Display *display, Window w, int *x_ret, int *y_ret,
- int *width_ret, int *height_ret)
+_gdk_input_get_root_relative_geometry (GdkWindow *window,
+ int *x_ret, int *y_ret)
{
- Window root, parent, child;
- Window *children;
- guint nchildren;
+ Window child;
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)
*x_ret = x;
if (y_ret)
*y_ret = y;
- if (width_ret)
- *width_ret = width;
- if (height_ret)
- *height_ret = height;
}
static GdkDevicePrivate *
gdk_input_device_new (GdkDisplay *display,
- XDeviceInfo *device,
+ XDeviceInfo *device,
gint include_core)
{
GdkDevicePrivate *gdkdev;
@@ -121,7 +110,7 @@ gdk_input_device_new (GdkDisplay *display,
for comparison purposes */
tmp_name = g_ascii_strdown (gdkdev->info.name, -1);
-
+
if (!strcmp (tmp_name, "pointer"))
gdkdev->info.source = GDK_SOURCE_MOUSE;
else if (!strcmp (tmp_name, "wacom") ||
@@ -151,7 +140,7 @@ gdk_input_device_new (GdkDisplay *display,
gdkdev->button_state = 0;
class = device->inputclassinfo;
- for (i=0;i<device->num_classes;i++)
+ for (i=0;i<device->num_classes;i++)
{
switch (class->class) {
case ButtonClass:
@@ -160,7 +149,7 @@ gdk_input_device_new (GdkDisplay *display,
{
XKeyInfo *xki = (XKeyInfo *)class;
/* 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))
{
@@ -190,7 +179,7 @@ gdk_input_device_new (GdkDisplay *display,
gdkdev->info.axes = g_new0 (GdkDeviceAxis, xvi->num_axes);
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].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);
if (j<xvi->num_axes)
gdk_device_set_axis_use (&gdkdev->info, j++, GDK_AXIS_WHEEL);
-
+
break;
}
}
@@ -247,20 +236,19 @@ gdk_input_device_new (GdkDisplay *display,
error:
g_object_unref (gdkdev);
-
+
return NULL;
}
void
-_gdk_input_common_find_events(GdkWindow *window,
- GdkDevicePrivate *gdkdev,
- gint mask,
- XEventClass *classes,
- int *num_classes)
+_gdk_input_common_find_events (GdkDevicePrivate *gdkdev,
+ gint mask,
+ XEventClass *classes,
+ int *num_classes)
{
gint i;
XEventClass class;
-
+
i = 0;
if (mask & GDK_BUTTON_PRESS_MASK)
{
@@ -354,25 +342,42 @@ _gdk_input_common_find_events(GdkWindow *window,
}
void
-_gdk_input_common_select_events(GdkWindow *window,
- GdkDevicePrivate *gdkdev)
+_gdk_input_select_events (GdkWindow *impl_window,
+ GdkDevicePrivate *gdkdev)
{
XEventClass classes[GDK_MAX_DEVICE_CLASSES];
gint num_classes;
+ guint event_mask;
+ GdkWindowObject *w;
+ GdkInputWindow *iw;
+ GList *l;
- if (gdkdev->info.mode == GDK_MODE_DISABLED)
- _gdk_input_common_find_events(window, gdkdev, 0, classes, &num_classes);
- else
- _gdk_input_common_find_events(window, gdkdev,
- ((GdkWindowObject *)window)->extension_events,
- classes, &num_classes);
-
- XSelectExtensionEvent (GDK_WINDOW_XDISPLAY (window),
- GDK_WINDOW_XWINDOW (window),
+ event_mask = 0;
+ iw = ((GdkWindowObject *)impl_window)->input_window;
+
+ if (gdkdev->info.mode != GDK_MODE_DISABLED &&
+ iw != NULL)
+ {
+ for (l = iw->windows; l != NULL; l = l->next)
+ {
+ 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);
}
-gint
+gint
_gdk_input_common_init (GdkDisplay *display,
gint include_core)
{
@@ -391,7 +396,7 @@ _gdk_input_common_init (GdkDisplay *display,
event_base, 15 /* Number of events */);
devices = XListInputDevices(display_x11->xdisplay, &num_devices);
-
+
for(loop=0; loop<num_devices; loop++)
{
GdkDevicePrivate *gdkdev = gdk_input_device_new(display,
@@ -410,21 +415,23 @@ _gdk_input_common_init (GdkDisplay *display,
static void
gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev,
- GdkInputWindow *input_window,
+ GdkWindow *window,
gint *axis_data,
gdouble *axis_out,
gdouble *x_out,
gdouble *y_out)
{
- GdkWindowObject *window_private;
+ GdkWindowObject *priv, *impl_window;
+
int i;
int x_axis = 0;
int y_axis = 0;
double device_width, device_height;
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++)
{
@@ -440,26 +447,24 @@ gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev,
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;
- y_scale = gdk_screen_get_height (gdk_drawable_get_screen (input_window->window)) / device_height;
+ x_scale = gdk_screen_get_width (gdk_drawable_get_screen (window)) / device_width;
+ y_scale = gdk_screen_get_height (gdk_drawable_get_screen (window)) / device_height;
- x_offset = - input_window->root_x;
- y_offset = - input_window->root_y;
+ x_offset = - impl_window->input_window->root_x;
+ y_offset = - impl_window->input_window->root_y;
}
else /* GDK_MODE_WINDOW */
{
double x_resolution = gdkdev->axes[x_axis].resolution;
double y_resolution = gdkdev->axes[y_axis].resolution;
double device_aspect;
- /*
+ /*
* Some drivers incorrectly report the resolution of the device
* as zero (in partiular linuxwacom < 0.5.3 with usb tablets).
* This causes the device_aspect to become NaN and totally
@@ -475,27 +480,24 @@ gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev,
y_resolution = 1;
}
device_aspect = (device_height*y_resolution) /
- (device_width*x_resolution);
- if (device_aspect * window_private->width >= window_private->height)
+ (device_width*x_resolution);
+ if (device_aspect * priv->width >= priv->height)
{
/* device taller than window */
- x_scale = window_private->width / device_width;
- y_scale = (x_scale * x_resolution)
- / y_resolution;
+ x_scale = priv->width / device_width;
+ y_scale = (x_scale * x_resolution) / y_resolution;
x_offset = 0;
- y_offset = -(device_height * y_scale -
- window_private->height)/2;
+ y_offset = -(device_height * y_scale - priv->height)/2;
}
else
{
/* window taller than device */
- y_scale = window_private->height / device_height;
- x_scale = (y_scale * y_resolution)
- / x_resolution;
+ y_scale = priv->height / device_height;
+ x_scale = (y_scale * y_resolution) / x_resolution;
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)
{
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);
if (x_out)
*x_out = axis_out[i];
break;
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);
if (y_out)
*y_out = axis_out[i];
@@ -541,11 +543,18 @@ gdk_input_translate_state(guint state, guint device_state)
gboolean
_gdk_input_common_other_event (GdkEvent *event,
XEvent *xevent,
- GdkInputWindow *input_window,
+ GdkWindow *window,
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) ||
- (xevent->type == gdkdev->buttonrelease_type))
+ (xevent->type == gdkdev->buttonrelease_type))
{
XDeviceButtonEvent *xdbe = (XDeviceButtonEvent *)(xevent);
@@ -560,16 +569,16 @@ _gdk_input_common_other_event (GdkEvent *event,
gdkdev->button_state &= ~(1 << xdbe->button);
}
event->button.device = &gdkdev->info;
- event->button.window = input_window->window;
+ event->button.window = window;
event->button.time = xdbe->time;
event->button.axes = g_new (gdouble, gdkdev->info.num_axes);
- gdk_input_translate_coordinates (gdkdev,input_window, xdbe->axis_data,
- event->button.axes,
- &event->button.x,&event->button.y);
- event->button.x_root = event->button.x + input_window->root_x;
- event->button.y_root = event->button.y + input_window->root_y;
- event->button.state = gdk_input_translate_state(xdbe->state,xdbe->device_state);
+ gdk_input_translate_coordinates (gdkdev, window, xdbe->axis_data,
+ event->button.axes,
+ &event->button.x, &event->button.y);
+ event->button.x_root = event->button.x + priv->abs_x + input_window->root_x;
+ 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.button = xdbe->button;
if (event->button.type == GDK_BUTTON_PRESS)
@@ -588,8 +597,8 @@ _gdk_input_common_other_event (GdkEvent *event,
* a valid timestamp.
*/
if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
- gdk_x11_window_set_user_time (gdk_window_get_toplevel (input_window->window),
- gdk_event_get_time (event));
+ gdk_x11_window_set_user_time (gdk_window_get_toplevel (window),
+ gdk_event_get_time (event));
return TRUE;
}
@@ -611,21 +620,21 @@ _gdk_input_common_other_event (GdkEvent *event,
g_warning ("Invalid device key code received");
return FALSE;
}
-
+
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,
g_print ("\t\ttranslation - NONE\n"));
-
+
return FALSE;
}
event->key.type = (xdke->type == gdkdev->keypress_type) ?
GDK_KEY_PRESS : GDK_KEY_RELEASE;
- event->key.window = input_window->window;
+ event->key.window = window;
event->key.time = xdke->time;
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.
*/
if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
- gdk_x11_window_set_user_time (gdk_window_get_toplevel (input_window->window),
- gdk_event_get_time (event));
+ gdk_x11_window_set_user_time (gdk_window_get_toplevel (window),
+ gdk_event_get_time (event));
return TRUE;
}
- if (xevent->type == gdkdev->motionnotify_type)
+ if (xevent->type == gdkdev->motionnotify_type)
{
XDeviceMotionEvent *xdme = (XDeviceMotionEvent *)(xevent);
event->motion.device = &gdkdev->info;
-
+
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.x,&event->motion.y);
- event->motion.x_root = event->motion.x + input_window->root_x;
- event->motion.y_root = event->motion.y + input_window->root_y;
+ event->motion.x_root = event->motion.x + priv->abs_x + input_window->root_x;
+ event->motion.y_root = event->motion.y + priv->abs_y + input_window->root_y;
event->motion.type = GDK_MOTION_NOTIFY;
- event->motion.window = input_window->window;
+ event->motion.window = window;
event->motion.time = xdme->time;
event->motion.state = gdk_input_translate_state(xdme->state,
xdme->device_state);
@@ -686,14 +695,14 @@ _gdk_input_common_other_event (GdkEvent *event,
event->motion.x, event->motion.y,
event->motion.state,
(xdme->is_hint) ? "true" : "false"));
-
-
+
+
/* Update the timestamp of the latest user interaction, if the event has
* a valid timestamp.
*/
if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
- gdk_x11_window_set_user_time (gdk_window_get_toplevel (input_window->window),
- gdk_event_get_time (event));
+ gdk_x11_window_set_user_time (gdk_window_get_toplevel (window),
+ gdk_event_get_time (event));
return TRUE;
}
@@ -704,16 +713,16 @@ _gdk_input_common_other_event (GdkEvent *event,
event->proximity.device = &gdkdev->info;
event->proximity.type = (xevent->type == gdkdev->proximityin_type)?
- GDK_PROXIMITY_IN:GDK_PROXIMITY_OUT;
- event->proximity.window = input_window->window;
+ GDK_PROXIMITY_IN:GDK_PROXIMITY_OUT;
+ event->proximity.window = window;
event->proximity.time = xpne->time;
-
+
/* Update the timestamp of the latest user interaction, if the event has
* a valid timestamp.
*/
if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
- gdk_x11_window_set_user_time (gdk_window_get_toplevel (input_window->window),
- gdk_event_get_time (event));
+ gdk_x11_window_set_user_time (gdk_window_get_toplevel (window),
+ gdk_event_get_time (event));
return TRUE;
}
@@ -730,18 +739,17 @@ _gdk_device_get_history (GdkDevice *device,
{
GdkTimeCoord **coords;
XDeviceTimeCoord *device_coords;
- GdkInputWindow *input_window;
+ GdkWindow *impl_window;
GdkDevicePrivate *gdkdev;
gint mode_return;
gint axis_count_return;
gint i;
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,
start, stop,
n_events, &mode_return,
@@ -752,13 +760,13 @@ _gdk_device_get_history (GdkDevice *device,
coords = _gdk_device_allocate_history (device, *n_events);
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,
- device_coords[i].data,
- coords[i]->axes, NULL, NULL);
- }
+ gdk_input_translate_coordinates (gdkdev, window,
+ device_coords[i].data,
+ coords[i]->axes, NULL, NULL);
+ }
XFreeDeviceMotionEvents (device_coords);
@@ -770,7 +778,7 @@ _gdk_device_get_history (GdkDevice *device,
return FALSE;
}
-void
+void
gdk_device_get_state (GdkDevice *device,
GdkWindow *window,
gdouble *axes,
@@ -784,7 +792,7 @@ gdk_device_get_state (GdkDevice *device,
if (GDK_IS_CORE (device))
{
gint x_int, y_int;
-
+
gdk_window_get_pointer (window, &x_int, &y_int, mask);
if (axes)
@@ -796,16 +804,13 @@ gdk_device_get_state (GdkDevice *device,
else
{
GdkDevicePrivate *gdkdev;
- GdkInputWindow *input_window;
XDeviceState *state;
XInputClass *input_class;
-
+
if (mask)
gdk_window_get_pointer (window, NULL, NULL, mask);
-
+
gdkdev = (GdkDevicePrivate *)device;
- input_window = _gdk_input_window_find (window);
- g_return_if_fail (input_window != NULL);
state = XQueryDeviceState (GDK_WINDOW_XDISPLAY (window),
gdkdev->xdevice);
@@ -816,11 +821,11 @@ gdk_device_get_state (GdkDevice *device,
{
case ValuatorClass:
if (axes)
- gdk_input_translate_coordinates (gdkdev, input_window,
+ gdk_input_translate_coordinates (gdkdev, window,
((XValuatorState *)input_class)->valuators,
axes, NULL, NULL);
break;
-
+
case ButtonClass:
if (mask)
{
diff --git a/gdk/x11/gdkinput-xfree.c b/gdk/x11/gdkinput-xfree.c
index b51516b..10fd33d 100644
--- a/gdk/x11/gdkinput-xfree.c
+++ b/gdk/x11/gdkinput-xfree.c
@@ -26,18 +26,18 @@
* 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
* 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 */
static void gdk_input_check_proximity (GdkDisplay *display);
-void
+void
_gdk_input_init(GdkDisplay *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);
}
@@ -47,7 +47,6 @@ gdk_device_set_mode (GdkDevice *device,
{
GList *tmp_list;
GdkDevicePrivate *gdkdev;
- GdkInputMode old_mode;
GdkInputWindow *input_window;
GdkDisplayX11 *display_impl;
@@ -59,58 +58,35 @@ gdk_device_set_mode (GdkDevice *device,
if (device->mode == mode)
return TRUE;
- old_mode = device->mode;
device->mode = mode;
- display_impl = GDK_DISPLAY_X11 (gdkdev->display);
-
if (mode == GDK_MODE_WINDOW)
- {
- 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);
- }
- }
+ device->has_cursor = FALSE;
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;
- for (tmp_list = display_impl->input_windows; tmp_list; tmp_list = tmp_list->next)
- _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);
- }
+ input_window = (GdkInputWindow *)tmp_list->data;
+ _gdk_input_select_events (input_window->impl_window, gdkdev);
}
return TRUE;
-
}
static void
gdk_input_check_proximity (GdkDisplay *display)
{
- gint new_proximity = 0;
GdkDisplayX11 *display_impl = GDK_DISPLAY_X11 (display);
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);
- if (gdkdev->info.mode != GDK_MODE_DISABLED
+ if (gdkdev->info.mode != GDK_MODE_DISABLED
&& !GDK_IS_CORE (gdkdev)
&& gdkdev->xdevice)
{
@@ -118,7 +94,7 @@ gdk_input_check_proximity (GdkDisplay *display)
gdkdev->xdevice);
XInputClass *xic;
int i;
-
+
xic = state->data;
for (i=0; i<state->num_classes; i++)
{
@@ -135,117 +111,197 @@ gdk_input_check_proximity (GdkDisplay *display)
}
XFreeDeviceState (state);
- }
+ }
tmp_list = tmp_list->next;
}
- display_impl->input_ignore_core = new_proximity;
+ display->ignore_core_events = new_proximity;
}
void
_gdk_input_configure_event (XConfigureEvent *xevent,
GdkWindow *window)
{
+ GdkWindowObject *priv = (GdkWindowObject *)window;
GdkInputWindow *input_window;
gint root_x, root_y;
- input_window = _gdk_input_window_find(window);
- g_return_if_fail (input_window != NULL);
-
- _gdk_input_get_root_relative_geometry(GDK_WINDOW_XDISPLAY (window),
- GDK_WINDOW_XWINDOW (window),
- &root_x, &root_y, NULL, NULL);
-
- input_window->root_x = root_x;
- input_window->root_y = root_y;
+ input_window = priv->input_window;
+ if (input_window != NULL)
+ {
+ _gdk_input_get_root_relative_geometry (window, &root_x, &root_y);
+ input_window->root_x = root_x;
+ input_window->root_y = root_y;
+ }
}
-void
-_gdk_input_enter_event (XCrossingEvent *xevent,
- GdkWindow *window)
+void
+_gdk_input_crossing_event (GdkWindow *window,
+ gboolean enter)
{
+ GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
+ GdkDisplayX11 *display_impl = GDK_DISPLAY_X11 (display);
+ GdkWindowObject *priv = (GdkWindowObject *)window;
GdkInputWindow *input_window;
gint root_x, root_y;
- input_window = _gdk_input_window_find (window);
- g_return_if_fail (input_window != NULL);
+ if (enter)
+ {
+ gdk_input_check_proximity(display);
+
+ input_window = priv->input_window;
+ if (input_window != NULL)
+ {
+ _gdk_input_get_root_relative_geometry (window, &root_x, &root_y);
+ input_window->root_x = root_x;
+ input_window->root_y = root_y;
+ }
+ }
+ else
+ display->ignore_core_events = FALSE;
+}
+
+static GdkEventType
+get_input_event_type (GdkDevicePrivate *gdkdev,
+ XEvent *xevent,
+ int *core_x, int *core_y)
+{
+ 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;
+ }
- gdk_input_check_proximity(GDK_WINDOW_DISPLAY (window));
+ if (xevent->type == gdkdev->proximityin_type)
+ {
+ XProximityNotifyEvent *xie = (XProximityNotifyEvent *)(xevent);
+ *core_x = xie->x;
+ *core_y = xie->y;
+ return GDK_PROXIMITY_IN;
+ }
- _gdk_input_get_root_relative_geometry(GDK_WINDOW_XDISPLAY (window),
- GDK_WINDOW_XWINDOW(window),
- &root_x, &root_y, NULL, NULL);
+ if (xevent->type == gdkdev->proximityout_type)
+ {
+ XProximityNotifyEvent *xie = (XProximityNotifyEvent *)(xevent);
+ *core_x = xie->x;
+ *core_y = xie->y;
+ return GDK_PROXIMITY_OUT;
+ }
- input_window->root_x = root_x;
- input_window->root_y = root_y;
+ *core_x = 0;
+ *core_y = 0;
+ return GDK_NOTHING;
}
-gboolean
-_gdk_input_other_event (GdkEvent *event,
- XEvent *xevent,
- GdkWindow *window)
+
+gboolean
+_gdk_input_other_event (GdkEvent *event,
+ XEvent *xevent,
+ GdkWindow *event_window)
{
- GdkInputWindow *input_window;
-
+ GdkWindow *window;
+ GdkWindowObject *priv;
+ GdkInputWindow *iw;
GdkDevicePrivate *gdkdev;
gint return_val;
- GdkDisplayX11 *display_impl = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window));
-
- input_window = _gdk_input_window_find(window);
- g_return_val_if_fail (input_window != NULL, FALSE);
+ GdkEventType event_type;
+ int x, y;
+ GdkDisplay *display = GDK_WINDOW_DISPLAY (event_window);
+ GdkDisplayX11 *display_impl = GDK_DISPLAY_X11 (display);
/* This is a sort of a hack, as there isn't any XDeviceAnyEvent -
but it's potentially faster than scanning through the types of
every device. If we were deceived, then it won't match any of
the types for the device anyways */
- gdkdev = _gdk_input_find_device (GDK_WINDOW_DISPLAY (window),
+ gdkdev = _gdk_input_find_device (display,
((XDeviceButtonEvent *)xevent)->deviceid);
if (!gdkdev)
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
- entirely, instead of having to ignore them */
+ event_type = get_input_event_type (gdkdev, xevent, &x, &y);
+ if (event_type == GDK_NOTHING)
+ return FALSE;
+
+ window = _gdk_window_get_input_window_for_event (event_window,
+ 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.mode == GDK_MODE_WINDOW
- && input_window->mode == GDK_EXTENSION_EVENTS_CURSOR))
+ !(gdkdev->info.has_cursor || (priv->extension_events & GDK_ALL_DEVICES_MASK)))
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,
- input_window, gdkdev);
+ if (!display->ignore_core_events && priv->extension_events != 0)
+ gdk_input_check_proximity (GDK_WINDOW_DISPLAY (window));
- if (return_val && event->type == GDK_PROXIMITY_OUT &&
- display_impl->input_ignore_core)
- gdk_input_check_proximity(GDK_WINDOW_DISPLAY (window));
+ return_val = _gdk_input_common_other_event (event, xevent, window, gdkdev);
- return return_val;
-}
+ 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;
-gboolean
-_gdk_input_enable_window(GdkWindow *window, GdkDevicePrivate *gdkdev)
-{
- /* FIXME: watchout, gdkdev might be core pointer, never opened */
- _gdk_input_common_select_events (window, gdkdev);
- return TRUE;
-}
+ if (return_val && event->type == GDK_PROXIMITY_OUT &&
+ display->ignore_core_events)
+ gdk_input_check_proximity (GDK_WINDOW_DISPLAY (window));
-gboolean
-_gdk_input_disable_window(GdkWindow *window, GdkDevicePrivate *gdkdev)
-{
- _gdk_input_common_select_events (window, gdkdev);
- return TRUE;
+ return return_val;
}
-gint
-_gdk_input_grab_pointer (GdkWindow * window,
+gint
+_gdk_input_grab_pointer (GdkWindow *window,
+ GdkWindow *native_window, /* This is the toplevel */
gint owner_events,
GdkEventMask event_mask,
GdkWindow * confine_to,
guint32 time)
{
- GdkInputWindow *input_window, *new_window;
+ GdkInputWindow *input_window;
+ GdkWindowObject *priv, *impl_window;
gboolean need_ungrab;
GdkDevicePrivate *gdkdev;
GList *tmp_list;
@@ -255,36 +311,36 @@ _gdk_input_grab_pointer (GdkWindow * window,
GdkDisplayX11 *display_impl = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window));
tmp_list = display_impl->input_windows;
- new_window = NULL;
need_ungrab = FALSE;
while (tmp_list)
{
input_window = (GdkInputWindow *)tmp_list->data;
- if (input_window->window == window)
- new_window = input_window;
- else if (input_window->grabbed)
+ if (input_window->grabbed)
{
input_window->grabbed = FALSE;
need_ungrab = TRUE;
+ break;
}
-
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;
while (tmp_list)
{
gdkdev = (GdkDevicePrivate *)tmp_list->data;
if (!GDK_IS_CORE (gdkdev) && gdkdev->xdevice)
{
- _gdk_input_common_find_events (window, gdkdev,
- event_mask,
+ _gdk_input_common_find_events (gdkdev, event_mask,
event_classes, &num_classes);
#ifdef G_ENABLE_DEBUG
if (_gdk_debug_flags & GDK_DEBUG_NOGRABS)
@@ -292,10 +348,10 @@ _gdk_input_grab_pointer (GdkWindow * window,
else
#endif
result = XGrabDevice (display_impl->xdisplay, gdkdev->xdevice,
- GDK_WINDOW_XWINDOW (window),
+ GDK_WINDOW_XWINDOW (native_window),
owner_events, num_classes, event_classes,
GrabModeAsync, GrabModeAsync, time);
-
+
/* FIXME: if failure occurs on something other than the first
device, things will be badly inconsistent */
if (result != Success)
@@ -305,7 +361,7 @@ _gdk_input_grab_pointer (GdkWindow * window,
}
}
else
- {
+ {
tmp_list = display_impl->input_devices;
while (tmp_list)
{
@@ -316,17 +372,16 @@ _gdk_input_grab_pointer (GdkWindow * window,
XUngrabDevice (display_impl->xdisplay, gdkdev->xdevice, time);
gdkdev->button_state = 0;
}
-
+
tmp_list = tmp_list->next;
}
}
return Success;
-
}
-void
-_gdk_input_ungrab_pointer (GdkDisplay *display,
+void
+_gdk_input_ungrab_pointer (GdkDisplay *display,
guint32 time)
{
GdkInputWindow *input_window = NULL; /* Quiet GCC */
diff --git a/gdk/x11/gdkinput.c b/gdk/x11/gdkinput.c
index 95a301d..c33f09c 100644
--- a/gdk/x11/gdkinput.c
+++ b/gdk/x11/gdkinput.c
@@ -21,7 +21,7 @@
* 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
* 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"
@@ -47,10 +47,10 @@ void
_gdk_init_input_core (GdkDisplay *display)
{
GdkDevicePrivate *private;
-
+
display->core_pointer = g_object_new (GDK_TYPE_DEVICE, NULL);
private = (GdkDevicePrivate *)display->core_pointer;
-
+
display->core_pointer->name = "Core Pointer";
display->core_pointer->source = GDK_SOURCE_MOUSE;
display->core_pointer->mode = GDK_MODE_SCREEN;
@@ -87,12 +87,12 @@ gdk_device_get_type (void)
0, /* n_preallocs */
(GInstanceInitFunc) NULL,
};
-
+
object_type = g_type_register_static (G_TYPE_OBJECT,
- g_intern_static_string ("GdkDevice"),
- &object_info, 0);
+ g_intern_static_string ("GdkDevice"),
+ &object_info, 0);
}
-
+
return object_type;
}
@@ -115,10 +115,10 @@ gdk_device_dispose (GObject *object)
{
#ifndef XINPUT_NONE
if (gdkdev->xdevice)
- {
- XCloseDevice (GDK_DISPLAY_XDISPLAY (gdkdev->display), gdkdev->xdevice);
- gdkdev->xdevice = NULL;
- }
+ {
+ XCloseDevice (GDK_DISPLAY_XDISPLAY (gdkdev->display), gdkdev->xdevice);
+ gdkdev->xdevice = NULL;
+ }
g_free (gdkdev->axes);
gdkdev->axes = NULL;
#endif /* !XINPUT_NONE */
@@ -140,7 +140,7 @@ gdk_device_dispose (GObject *object)
*
* Returns the list of available input devices for the default display.
* The list is statically allocated and should not be freed.
- *
+ *
* Return value: a list of #GdkDevice
**/
GList *
@@ -155,16 +155,16 @@ gdk_devices_list (void)
*
* Returns the list of available input devices attached to @display.
* The list is statically allocated and should not be freed.
- *
+ *
* Return value: a list of #GdkDevice
*
* Since: 2.2
**/
-GList *
+GList *
gdk_display_list_devices (GdkDisplay *display)
{
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
-
+
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:
* @device: a #GdkDevice
@@ -227,14 +243,14 @@ gdk_device_set_axis_use (GdkDevice *device,
* @stop: ending timestamp for the range of events to return
* @events: location to store a newly-allocated array of #GdkTimeCoord, or %NULL
* @n_events: location to store the length of @events, or %NULL
- *
+ *
* Obtains the motion history for a device; given a starting and
* ending timestamp, return all events in the motion history for
* the device in the given range of time. Some windowing systems
* do not support motion history, in which case, %FALSE will
* be returned. (This is not distinguishable from the case where
* motion history is supported and no events were found.)
- *
+ *
* Return value: %TRUE if the windowing system supports motion history and
* at least one event was found.
**/
@@ -247,29 +263,38 @@ gdk_device_get_history (GdkDevice *device,
gint *n_events)
{
GdkTimeCoord **coords = NULL;
+ GdkWindow *impl_window;
gboolean result = FALSE;
int tmp_n_events = 0;
- int i;
+ int i, j;
g_return_val_if_fail (GDK_WINDOW_IS_X11 (window), FALSE);
+ impl_window = _gdk_window_get_impl_window (window);
+
if (GDK_WINDOW_DESTROYED (window))
/* Nothing */ ;
else if (GDK_IS_CORE (device))
{
XTimeCoord *xcoords;
-
+
xcoords = XGetMotionEvents (GDK_DRAWABLE_XDISPLAY (window),
- GDK_DRAWABLE_XID (window),
+ GDK_DRAWABLE_XID (impl_window),
start, stop, &tmp_n_events);
if (xcoords)
{
+ GdkWindowObject *priv = (GdkWindowObject *)window;
coords = _gdk_device_allocate_history (device, tmp_n_events);
+ j = 0;
for (i=0; i<tmp_n_events; i++)
{
- coords[i]->time = xcoords[i].time;
- coords[i]->axes[0] = xcoords[i].x;
- coords[i]->axes[1] = xcoords[i].y;
+ if (impl_coord_in_window (window, xcoords[i].x, 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);
@@ -292,7 +317,7 @@ gdk_device_get_history (GdkDevice *device,
return result;
}
-GdkTimeCoord **
+GdkTimeCoord **
_gdk_device_allocate_history (GdkDevice *device,
gint n_events)
{
@@ -306,41 +331,48 @@ _gdk_device_allocate_history (GdkDevice *device,
return result;
}
-void
+void
gdk_device_free_history (GdkTimeCoord **events,
gint n_events)
{
gint i;
-
+
for (i=0; i<n_events; i++)
g_free (events[i]);
g_free (events);
}
-GdkInputWindow *
-_gdk_input_window_find(GdkWindow *window)
+static void
+unset_extension_events (GdkWindow *window)
{
- GList *tmp_list;
- GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window));
+ GdkWindowObject *window_private;
+ GdkWindowObject *impl_window;
+ GdkDisplayX11 *display_x11;
+ GdkInputWindow *iw;
- /* Ensure we have a native window, or the input stuff won't work.
- Its possible we could emulate this also, but at least this should make
- it work. */
- gdk_window_set_has_native (window, TRUE);
+ window_private = (GdkWindowObject*) window;
+ impl_window = (GdkWindowObject *)_gdk_window_get_impl_window (window);
+ iw = impl_window->input_window;
- for (tmp_list=display_x11->input_windows; tmp_list; tmp_list=tmp_list->next)
- if (((GdkInputWindow *)(tmp_list->data))->window == window)
- return (GdkInputWindow *)(tmp_list->data);
+ display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window));
- 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);
+ }
+ }
-/* 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 */
+ window_private->extension_events = 0;
+}
void
gdk_input_set_extension_events (GdkWindow *window, gint mask,
@@ -348,6 +380,7 @@ gdk_input_set_extension_events (GdkWindow *window, gint mask,
{
GdkWindowObject *window_private;
GList *tmp_list;
+ GdkWindowObject *impl_window;
GdkInputWindow *iw;
GdkDisplayX11 *display_x11;
@@ -359,52 +392,44 @@ gdk_input_set_extension_events (GdkWindow *window, gint mask,
if (GDK_WINDOW_DESTROYED (window))
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)
mask = 0;
- iw = _gdk_input_window_find (window);
+ iw = impl_window->input_window;
if (mask != 0)
{
if (!iw)
- {
- iw = g_new(GdkInputWindow,1);
-
- iw->window = window;
- iw->mode = mode;
+ {
+ iw = g_new0 (GdkInputWindow,1);
- iw->obscuring = NULL;
- iw->num_obscuring = 0;
- iw->grabbed = FALSE;
+ iw->impl_window = (GdkWindow *)impl_window;
- display_x11->input_windows = g_list_append(display_x11->input_windows,iw);
- }
+ iw->windows = NULL;
+ iw->grabbed = FALSE;
- window_private->extension_events = mask;
+ display_x11->input_windows = g_list_append (display_x11->input_windows, iw);
#ifndef XINPUT_NONE
- /* Add enter window events to the event mask */
- /* this is not needed for XINPUT_NONE */
- gdk_window_set_events (window,
- 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);
+ /* we might not receive ConfigureNotify so get the root_relative_geometry
+ * now, just in case */
+ _gdk_input_get_root_relative_geometry (window, &iw->root_x, &iw->root_y);
#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
{
- if (iw)
- {
- display_x11->input_windows = g_list_remove(display_x11->input_windows,iw);
- g_free(iw);
- }
-
- window_private->extension_events = 0;
+ unset_extension_events (window);
}
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;
if (!GDK_IS_CORE (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);
- }
+ _gdk_input_select_events ((GdkWindow *)impl_window, gdkdev);
}
}
void
_gdk_input_window_destroy (GdkWindow *window)
{
- GdkInputWindow *input_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);
- }
+ unset_extension_events (window);
}
/**
@@ -471,10 +453,10 @@ _gdk_input_exit (void)
* @axes: pointer to an array of axes
* @use: the use to look for
* @value: location to store the found value.
- *
+ *
* Interprets an array of double as axis values for a given device,
* and locates the value in the array for a given axis use.
- *
+ *
* Return value: %TRUE if the given axis use was found, otherwise %FALSE
**/
gboolean
@@ -484,12 +466,12 @@ gdk_device_get_axis (GdkDevice *device,
gdouble *value)
{
gint i;
-
+
g_return_val_if_fail (device != NULL, FALSE);
if (axes == NULL)
return FALSE;
-
+
for (i=0; i<device->num_axes; i++)
if (device->axes[i].use == use)
{
@@ -497,7 +479,7 @@ gdk_device_get_axis (GdkDevice *device,
*value = axes[i];
return TRUE;
}
-
+
return FALSE;
}
diff --git a/gdk/x11/gdkinputprivate.h b/gdk/x11/gdkinputprivate.h
index 5cbd809..217e28c 100644
--- a/gdk/x11/gdkinputprivate.h
+++ b/gdk/x11/gdkinputprivate.h
@@ -41,7 +41,6 @@
typedef struct _GdkAxisInfo GdkAxisInfo;
typedef struct _GdkDevicePrivate GdkDevicePrivate;
-typedef struct _GdkInputWindow GdkInputWindow;
/* information about a device axis */
struct _GdkAxisInfo
@@ -102,28 +101,25 @@ struct _GdkDeviceClass
GObjectClass parent_class;
};
+/* Addition used for extension_events mask */
+#define GDK_ALL_DEVICES_MASK (1<<30)
+
struct _GdkInputWindow
{
- /* gdk window */
- GdkWindow *window;
+ GList *windows; /* GdkWindow:s with extension_events set */
- /* Extension mode (GDK_EXTENSION_EVENTS_ALL/CURSOR) */
- GdkExtensionMode mode;
+ /* gdk window */
+ GdkWindow *impl_window; /* an impl window */
+ GdkWindow *button_down_window;
/* position relative to root window */
gint root_x;
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 ? */
gint grabbed;
};
-
-
/* Global data */
#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
* (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,
GdkWindow *window);
-void _gdk_input_enter_event (XCrossingEvent *xevent,
- GdkWindow *window);
+void _gdk_input_crossing_event (GdkWindow *window,
+ gboolean enter);
gboolean _gdk_input_other_event (GdkEvent *event,
XEvent *xevent,
GdkWindow *window);
gint _gdk_input_grab_pointer (GdkWindow *window,
+ GdkWindow *native_window,
gint owner_events,
GdkEventMask event_mask,
GdkWindow *confine_to,
@@ -172,22 +165,18 @@ gint _gdk_input_common_init (GdkDisplay *display,
gint include_core);
GdkDevicePrivate * _gdk_input_find_device (GdkDisplay *display,
guint32 id);
-void _gdk_input_get_root_relative_geometry(Display *display,
- Window w,
+void _gdk_input_get_root_relative_geometry(GdkWindow *window,
int *x_ret,
- int *y_ret,
- int *width_ret,
- int *height_ret);
-void _gdk_input_common_find_events (GdkWindow *window,
- GdkDevicePrivate *gdkdev,
+ int *y_ret);
+void _gdk_input_common_find_events (GdkDevicePrivate *gdkdev,
gint mask,
XEventClass *classes,
int *num_classes);
-void _gdk_input_common_select_events (GdkWindow *window,
+void _gdk_input_select_events (GdkWindow *impl_window,
GdkDevicePrivate *gdkdev);
gint _gdk_input_common_other_event (GdkEvent *event,
XEvent *xevent,
- GdkInputWindow *input_window,
+ GdkWindow *window,
GdkDevicePrivate *gdkdev);
#endif /* !XINPUT_NONE */
diff --git a/gdk/x11/gdkmain-x11.c b/gdk/x11/gdkmain-x11.c
index 41639c4..08c7cff 100644
--- a/gdk/x11/gdkmain-x11.c
+++ b/gdk/x11/gdkmain-x11.c
@@ -251,7 +251,8 @@ gdk_pointer_grab (GdkWindow * window,
*/
xevent_mask &= ~PointerMotionHintMask;
- return_val = _gdk_input_grab_pointer (native,
+ return_val = _gdk_input_grab_pointer (window,
+ native,
owner_events,
event_mask,
confine_to,
diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c
index e29dc7b..4d38fcb 100644
--- a/gdk/x11/gdkwindow-x11.c
+++ b/gdk/x11/gdkwindow-x11.c
@@ -1036,9 +1036,6 @@ _gdk_x11_window_destroy (GdkWindow *window,
_gdk_selection_window_destroyed (window);
- if (private->extension_events != 0)
- _gdk_input_window_destroy (window);
-
toplevel = _gdk_x11_window_get_toplevel (window);
if (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_translation = _gdk_x11_window_queue_translation;
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__
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]