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 */
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. */

View File

@ -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);
/*****************************

View File

@ -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"

View File

@ -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 */

View File

@ -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;

View File

@ -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;

View File

@ -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)
{

View File

@ -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);
gdk_input_check_proximity(GDK_WINDOW_DISPLAY (window));
_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;
}
}
else
display->ignore_core_events = FALSE;
}
gboolean
_gdk_input_other_event (GdkEvent *event,
XEvent *xevent,
GdkWindow *window)
static GdkEventType
get_input_event_type (GdkDevicePrivate *gdkdev,
XEvent *xevent,
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;
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 */
if (gdkdev->info.mode == GDK_MODE_DISABLED ||
(gdkdev->info.mode == GDK_MODE_WINDOW
&& input_window->mode == GDK_EXTENSION_EVENTS_CURSOR))
event_type = get_input_event_type (gdkdev, xevent, &x, &y);
if (event_type == GDK_NOTHING)
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);
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.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 &&
display_impl->input_ignore_core)
gdk_input_check_proximity(GDK_WINDOW_DISPLAY (window));
display->ignore_core_events)
gdk_input_check_proximity (GDK_WINDOW_DISPLAY (window));
return return_val;
}
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;
}
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
_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 */

View File

@ -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,48 +331,56 @@ _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);
}
}
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
gdk_input_set_extension_events (GdkWindow *window, gint mask,
GdkExtensionMode mode)
{
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 = g_new0 (GdkInputWindow,1);
iw->window = window;
iw->mode = mode;
iw->impl_window = (GdkWindow *)impl_window;
iw->obscuring = NULL;
iw->num_obscuring = 0;
iw->grabbed = FALSE;
iw->windows = NULL;
iw->grabbed = FALSE;
display_x11->input_windows = g_list_append(display_x11->input_windows,iw);
}
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;
}

View File

@ -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 */

View File

@ -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,

View File

@ -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__