1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
20 #if defined(XINPUT_GXI) || defined(XINPUT_XFREE)
22 /* Forward declarations */
23 static void gdk_input_get_root_relative_geometry (Display *dpy, Window w,
24 int *x_ret, int *y_ret,
27 static GdkDevicePrivate *gdk_input_device_new(XDeviceInfo *device,
29 static void gdk_input_common_find_events(GdkWindow *window,
30 GdkDevicePrivate *gdkdev,
34 static void gdk_input_common_select_events(GdkWindow *window,
35 GdkDevicePrivate *gdkdev);
36 static void gdk_input_translate_coordinates(GdkDevicePrivate *gdkdev,
37 GdkInputWindow *input_window,
39 gdouble *x, gdouble *y,
41 gdouble *xtilt, gdouble *ytilt);
42 static guint gdk_input_translate_state(guint state, guint device_state);
43 static gint gdk_input_common_init(gint include_core);
44 static gint gdk_input_common_other_event (GdkEvent *event,
46 GdkInputWindow *input_window,
47 GdkDevicePrivate *gdkdev);
48 static void gdk_input_common_set_axes (guint32 deviceid, GdkAxisUse *axes);
49 static GdkTimeCoord * gdk_input_common_motion_events (GdkWindow *window,
53 gint *nevents_return);
54 static void gdk_input_common_get_pointer (GdkWindow *window,
61 GdkModifierType *mask);
63 #define GDK_MAX_DEVICE_CLASSES 13
65 /* Global variables */
67 static gint gdk_input_root_width;
68 static gint gdk_input_root_height;
71 gdk_input_get_root_relative_geometry(Display *dpy, Window w, int *x_ret, int *y_ret,
72 int *width_ret, int *height_ret)
80 guint widthc,heightc,border_widthc,depthc;
82 XQueryTree(dpy,w,&root,&parent,&children,&nchildren);
83 if (children) XFree(children);
84 XGetGeometry(dpy,w,&root,&x,&y,&width,&height,&border_widthc,
89 while (root != parent)
92 XQueryTree(dpy,w,&root,&parent,&children,&nchildren);
93 if (children) XFree(children);
94 XGetGeometry(dpy,w,&root,&xc,&yc,&widthc,&heightc,
95 &border_widthc,&depthc);
96 x += xc + border_widthc;
97 y += yc + border_widthc;
107 *height_ret = height;
110 static GdkDevicePrivate *
111 gdk_input_device_new(XDeviceInfo *device, gint include_core)
113 GdkDevicePrivate *gdkdev;
118 gdkdev = g_new(GdkDevicePrivate,1);
120 gdkdev->info.deviceid = device->id;
121 if (device->name[0]) {
122 gdkdev->info.name = g_new(char, strlen(device->name)+1);
123 strcpy(gdkdev->info.name,device->name);
125 /* XFree86 3.2 gives an empty name to the default core devices,
127 gdkdev->info.name = g_strdup("pointer");
128 strcpy(gdkdev->info.name,"pointer");
129 gdkdev->info.source = GDK_SOURCE_MOUSE;
132 gdkdev->info.mode = GDK_MODE_DISABLED;
134 /* Try to figure out what kind of device this is by its name -
135 could invite a very, very, long list... Lowercase name
136 for comparison purposes */
138 tmp_name = g_strdup(gdkdev->info.name);
139 for (p = tmp_name; *p; p++)
141 if (*p >= 'A' && *p <= 'Z')
145 if (!strcmp (tmp_name, "pointer"))
146 gdkdev->info.source = GDK_SOURCE_MOUSE;
147 else if (!strcmp (tmp_name, "wacom") ||
148 !strcmp (tmp_name, "pen"))
149 gdkdev->info.source = GDK_SOURCE_PEN;
150 else if (!strcmp (tmp_name, "eraser"))
151 gdkdev->info.source = GDK_SOURCE_ERASER;
152 else if (!strcmp (tmp_name, "cursor"))
153 gdkdev->info.source = GDK_SOURCE_CURSOR;
155 gdkdev->info.source = GDK_SOURCE_PEN;
159 gdkdev->xdevice = NULL;
161 /* step through the classes */
163 gdkdev->info.num_axes = 0;
164 gdkdev->info.num_keys = 0;
165 gdkdev->info.keys = NULL;
167 gdkdev->info.has_cursor = 0;
168 gdkdev->needs_update = FALSE;
169 gdkdev->claimed = FALSE;
170 gdkdev->button_state = 0;
172 class = device->inputclassinfo;
173 for (i=0;i<device->num_classes;i++)
175 switch (class->class) {
182 XKeyInfo *xki = (XKeyInfo *)class;
183 /* Hack to catch XFree86 3.3.1 bug. Other devices better
184 * not have exactly 25 keys...
186 if ((xki->min_keycode == 8) && (xki->max_keycode == 32))
188 gdkdev->info.num_keys = 32;
189 gdkdev->min_keycode = 1;
193 gdkdev->info.num_keys = xki->max_keycode - xki->min_keycode + 1;
194 gdkdev->min_keycode = xki->min_keycode;
196 gdkdev->info.keys = g_new (GdkDeviceKey, gdkdev->info.num_keys);
198 for (j=0; j<gdkdev->info.num_keys; j++)
200 gdkdev->info.keys[j].keyval = 0;
201 gdkdev->info.keys[j].modifiers = 0;
208 XValuatorInfo *xvi = (XValuatorInfo *)class;
209 gdkdev->info.num_axes = xvi->num_axes;
210 gdkdev->axes = g_new(GdkAxisInfo, xvi->num_axes);
211 gdkdev->info.axes = g_new(GdkAxisUse, xvi->num_axes);
212 for (j=0;j<xvi->num_axes;j++)
214 gdkdev->axes[j].resolution =
215 gdkdev->axes[j].xresolution = xvi->axes[j].resolution;
216 gdkdev->axes[j].min_value =
217 gdkdev->axes[j].xmin_value = xvi->axes[j].min_value;
218 gdkdev->axes[j].max_value =
219 gdkdev->axes[j].xmax_value = xvi->axes[j].max_value;
220 gdkdev->info.axes[j] = GDK_AXIS_IGNORE;
224 gdkdev->info.axes[j++] = GDK_AXIS_X;
226 gdkdev->info.axes[j++] = GDK_AXIS_Y;
228 gdkdev->info.axes[j++] = GDK_AXIS_PRESSURE;
230 gdkdev->info.axes[j++] = GDK_AXIS_XTILT;
232 gdkdev->info.axes[j++] = GDK_AXIS_YTILT;
234 /* set up reverse lookup on axis use */
235 for (j=GDK_AXIS_IGNORE;j<GDK_AXIS_LAST;j++)
236 gdkdev->axis_for_use[j] = -1;
238 for (j=0;j<xvi->num_axes;j++)
239 if (gdkdev->info.axes[j] != GDK_AXIS_IGNORE)
240 gdkdev->axis_for_use[gdkdev->info.axes[j]] = j;
245 class = (XAnyClassPtr)(((char *)class) + class->length);
247 /* return NULL if no axes */
248 if (!gdkdev->info.num_axes || !gdkdev->axes ||
249 (!include_core && device->use == IsXPointer))
251 g_free(gdkdev->info.name);
253 g_free(gdkdev->axes);
254 if (gdkdev->info.keys)
255 g_free(gdkdev->info.keys);
260 if (device->use != IsXPointer)
262 int error_warn = gdk_error_warnings;
264 gdk_error_warnings = 0;
266 gdkdev->xdevice = XOpenDevice(gdk_display, gdkdev->info.deviceid);
267 gdk_error_warnings = error_warn;
269 /* return NULL if device is not ready */
272 g_free (gdkdev->info.name);
274 g_free (gdkdev->axes);
275 if (gdkdev->info.keys)
276 g_free (gdkdev->info.keys);
277 if (gdkdev->info.axes)
278 g_free (gdkdev->info.axes);
285 gdkdev->buttonpress_type = 0;
286 gdkdev->buttonrelease_type = 0;
287 gdkdev->keypress_type = 0;
288 gdkdev->keyrelease_type = 0;
289 gdkdev->motionnotify_type = 0;
290 gdkdev->proximityin_type = 0;
291 gdkdev->proximityout_type = 0;
292 gdkdev->changenotify_type = 0;
298 gdk_input_common_find_events(GdkWindow *window,
299 GdkDevicePrivate *gdkdev,
301 XEventClass *classes,
308 /* We have to track press and release events in pairs to keep
309 track of button state correctly and implement grabbing for
311 if (mask & GDK_BUTTON_PRESS_MASK || mask & GDK_BUTTON_RELEASE_MASK)
313 DeviceButtonPress (gdkdev->xdevice, gdkdev->buttonpress_type,
316 classes[i++] = class;
317 DeviceButtonPressGrab (gdkdev->xdevice, 0, class);
319 classes[i++] = class;
320 DeviceButtonRelease (gdkdev->xdevice, gdkdev->buttonrelease_type,
323 classes[i++] = class;
325 if (mask & GDK_POINTER_MOTION_MASK)
327 DeviceMotionNotify (gdkdev->xdevice, gdkdev->motionnotify_type, class);
329 classes[i++] = class;
332 if (mask & (GDK_BUTTON1_MOTION_MASK | GDK_BUTTON2_MOTION_MASK |
333 GDK_BUTTON3_MOTION_MASK | GDK_BUTTON_MOTION_MASK |
334 GDK_POINTER_MOTION_HINT_MASK))
336 /* Make sure gdkdev->motionnotify_type is set */
337 DeviceMotionNotify (gdkdev->xdevice, gdkdev->motionnotify_type, class);
339 if (mask & GDK_BUTTON1_MOTION_MASK)
341 DeviceButton1Motion (gdkdev->xdevice, 0, class);
343 classes[i++] = class;
345 if (mask & GDK_BUTTON2_MOTION_MASK)
347 DeviceButton2Motion (gdkdev->xdevice, 0, class);
349 classes[i++] = class;
351 if (mask & GDK_BUTTON3_MOTION_MASK)
353 DeviceButton3Motion (gdkdev->xdevice, 0, class);
355 classes[i++] = class;
357 if (mask & GDK_BUTTON_MOTION_MASK)
359 DeviceButtonMotion (gdkdev->xdevice, 0, class);
361 classes[i++] = class;
363 if (mask & GDK_POINTER_MOTION_HINT_MASK)
365 /* We'll get into trouble if the macros change, but at least we'll
366 know about it, and we avoid warnings now */
367 DevicePointerMotionHint (gdkdev->xdevice, 0, class);
369 classes[i++] = class;
371 if (mask & GDK_KEY_PRESS_MASK)
373 DeviceKeyPress (gdkdev->xdevice, gdkdev->keypress_type, class);
375 classes[i++] = class;
377 if (mask & GDK_KEY_RELEASE_MASK)
379 DeviceKeyRelease (gdkdev->xdevice, gdkdev->keyrelease_type, class);
381 classes[i++] = class;
383 if (mask & GDK_PROXIMITY_IN_MASK)
385 ProximityIn (gdkdev->xdevice, gdkdev->proximityin_type, class);
387 classes[i++] = class;
389 if (mask & GDK_PROXIMITY_OUT_MASK)
391 ProximityOut (gdkdev->xdevice, gdkdev->proximityout_type, class);
393 classes[i++] = class;
400 gdk_input_common_select_events(GdkWindow *window,
401 GdkDevicePrivate *gdkdev)
403 XEventClass classes[GDK_MAX_DEVICE_CLASSES];
406 if (gdkdev->info.mode == GDK_MODE_DISABLED)
407 gdk_input_common_find_events(window, gdkdev, 0, classes, &num_classes);
409 gdk_input_common_find_events(window, gdkdev,
410 ((GdkWindowPrivate *)window)->extension_events,
411 classes, &num_classes);
413 XSelectExtensionEvent (gdk_display,
414 GDK_WINDOW_XWINDOW(window),
415 classes, num_classes);
419 gdk_input_common_init(gint include_core)
422 XDeviceInfo *devices;
424 int num_extensions, loop;
425 Display *display = gdk_display;
427 /* Init global vars */
428 gdk_window_get_geometry(NULL, /* use root window */
430 &gdk_input_root_width,&gdk_input_root_height,
433 /* Init XInput extension */
435 extensions = XListExtensions(display, &num_extensions);
436 for (loop = 0; loop < num_extensions &&
437 (strcmp(extensions[loop], "XInputExtension") != 0); loop++);
438 XFreeExtensionList(extensions);
439 gdk_input_devices = NULL;
440 if (loop < num_extensions)
442 /* XInput extension found */
444 devices = XListInputDevices(display, &num_devices);
446 for(loop=0; loop<num_devices; loop++)
448 GdkDevicePrivate *gdkdev = gdk_input_device_new(&devices[loop],
451 gdk_input_devices = g_list_append(gdk_input_devices, gdkdev);
453 XFreeDeviceList(devices);
456 gdk_input_devices = g_list_append (gdk_input_devices, &gdk_input_core_info);
462 gdk_input_translate_coordinates (GdkDevicePrivate *gdkdev,
463 GdkInputWindow *input_window,
465 gdouble *x, gdouble *y, gdouble *pressure,
466 gdouble *xtilt, gdouble *ytilt)
468 GdkWindowPrivate *win_priv;
470 int x_axis, y_axis, pressure_axis, xtilt_axis, ytilt_axis;
472 double device_width, device_height;
473 double x_offset, y_offset, x_scale, y_scale;
475 win_priv = (GdkWindowPrivate *) input_window->window;
477 x_axis = gdkdev->axis_for_use[GDK_AXIS_X];
478 y_axis = gdkdev->axis_for_use[GDK_AXIS_Y];
479 pressure_axis = gdkdev->axis_for_use[GDK_AXIS_PRESSURE];
480 xtilt_axis = gdkdev->axis_for_use[GDK_AXIS_XTILT];
481 ytilt_axis = gdkdev->axis_for_use[GDK_AXIS_YTILT];
483 device_width = gdkdev->axes[x_axis].max_value -
484 gdkdev->axes[x_axis].min_value;
485 device_height = gdkdev->axes[y_axis].max_value -
486 gdkdev->axes[y_axis].min_value;
488 if (gdkdev->info.mode == GDK_MODE_SCREEN)
490 x_scale = gdk_input_root_width / device_width;
491 y_scale = gdk_input_root_height / device_height;
493 x_offset = - input_window->root_x;
494 y_offset = - input_window->root_y;
496 else /* GDK_MODE_WINDOW */
498 double device_aspect = (device_height*gdkdev->axes[y_axis].resolution) /
499 (device_width*gdkdev->axes[x_axis].resolution);
501 if (device_aspect * win_priv->width >= win_priv->height)
503 /* device taller than window */
504 x_scale = win_priv->width / device_width;
505 y_scale = (x_scale * gdkdev->axes[x_axis].resolution)
506 / gdkdev->axes[y_axis].resolution;
509 y_offset = -(device_height * y_scale -
514 /* window taller than device */
515 y_scale = win_priv->height / device_height;
516 x_scale = (y_scale * gdkdev->axes[y_axis].resolution)
517 / gdkdev->axes[x_axis].resolution;
520 x_offset = - (device_width * x_scale - win_priv->width)/2;
524 if (x) *x = x_offset + x_scale*axis_data[x_axis];
525 if (y) *y = y_offset + y_scale*axis_data[y_axis];
529 if (pressure_axis != -1)
530 *pressure = ((double)axis_data[pressure_axis]
531 - gdkdev->axes[pressure_axis].min_value)
532 / (gdkdev->axes[pressure_axis].max_value
533 - gdkdev->axes[pressure_axis].min_value);
540 if (xtilt_axis != -1)
542 *xtilt = 2. * (double)(axis_data[xtilt_axis] -
543 (gdkdev->axes[xtilt_axis].min_value +
544 gdkdev->axes[xtilt_axis].max_value)/2) /
545 (gdkdev->axes[xtilt_axis].max_value -
546 gdkdev->axes[xtilt_axis].min_value);
553 if (ytilt_axis != -1)
555 *ytilt = 2. * (double)(axis_data[ytilt_axis] -
556 (gdkdev->axes[ytilt_axis].min_value +
557 gdkdev->axes[ytilt_axis].max_value)/2) /
558 (gdkdev->axes[ytilt_axis].max_value -
559 gdkdev->axes[ytilt_axis].min_value);
566 /* combine the state of the core device and the device state
567 into one - for now we do this in a simple-minded manner -
568 we just take the keyboard portion of the core device and
569 the button portion (all of?) the device state.
570 Any button remapping should go on here. */
572 gdk_input_translate_state(guint state, guint device_state)
574 return device_state | (state & 0xFF);
578 gdk_input_common_other_event (GdkEvent *event,
580 GdkInputWindow *input_window,
581 GdkDevicePrivate *gdkdev)
583 if ((xevent->type == gdkdev->buttonpress_type) ||
584 (xevent->type == gdkdev->buttonrelease_type))
586 XDeviceButtonEvent *xdbe = (XDeviceButtonEvent *)(xevent);
588 if (xdbe->type == gdkdev->buttonpress_type)
590 event->button.type = GDK_BUTTON_PRESS;
591 gdkdev->button_state |= 1 << xdbe->button;
595 event->button.type = GDK_BUTTON_RELEASE;
596 gdkdev->button_state &= ~(1 << xdbe->button);
598 event->button.window = input_window->window;
599 event->button.time = xdbe->time;
600 event->button.source = gdkdev->info.source;
601 event->button.deviceid = xdbe->deviceid;
603 gdk_input_translate_coordinates (gdkdev,input_window, xdbe->axis_data,
604 &event->button.x,&event->button.y,
605 &event->button.pressure,
606 &event->button.xtilt,
607 &event->button.ytilt);
608 event->button.state = gdk_input_translate_state(xdbe->state,xdbe->device_state);
609 event->button.button = xdbe->button;
612 g_print ("button %s:\t\twindow: %ld device: %ld x,y: %f %f button: %d\n",
613 (event->button.type == GDK_BUTTON_PRESS) ? "press" : "release",
616 event->button.x, event->button.y,
622 if ((xevent->type == gdkdev->keypress_type) ||
623 (xevent->type == gdkdev->keyrelease_type))
625 XDeviceKeyEvent *xdke = (XDeviceKeyEvent *)(xevent);
628 g_print ("device key %s:\twindow: %ld device: %ld keycode: %d\n",
629 (event->key.type == GDK_KEY_PRESS) ? "press" : "release",
634 if (xdke->keycode < gdkdev->min_keycode ||
635 xdke->keycode >= gdkdev->min_keycode + gdkdev->info.num_keys)
637 g_warning ("Invalid device key code received");
641 event->key.keyval = gdkdev->info.keys[xdke->keycode - gdkdev->min_keycode].keyval;
643 if (event->key.keyval == 0)
646 g_print ("\t\ttranslation - NONE\n"));
651 event->key.type = (xdke->type == gdkdev->keypress_type) ?
652 GDK_KEY_PRESS : GDK_KEY_RELEASE;
654 event->key.window = input_window->window;
655 event->key.time = xdke->time;
657 event->key.state = gdk_input_translate_state(xdke->state, xdke->device_state)
658 | gdkdev->info.keys[xdke->keycode - gdkdev->min_keycode].modifiers;
660 /* Add a string translation for the key event */
661 if ((event->key.keyval >= 0x20) && (event->key.keyval <= 0xFF))
663 event->key.length = 1;
664 event->key.string = g_new (gchar, 2);
665 event->key.string[0] = (gchar)event->key.keyval;
666 event->key.string[1] = 0;
670 event->key.length = 0;
671 event->key.string = g_new0 (gchar, 1);
675 g_print ("\t\ttranslation - keyval: %d modifiers: %#x\n",
682 if (xevent->type == gdkdev->motionnotify_type)
684 XDeviceMotionEvent *xdme = (XDeviceMotionEvent *)(xevent);
686 gdk_input_translate_coordinates(gdkdev,input_window,xdme->axis_data,
687 &event->motion.x,&event->motion.y,
688 &event->motion.pressure,
689 &event->motion.xtilt,
690 &event->motion.ytilt);
692 event->motion.type = GDK_MOTION_NOTIFY;
693 event->motion.window = input_window->window;
694 event->motion.time = xdme->time;
695 event->motion.deviceid = xdme->deviceid;
696 event->motion.state = gdk_input_translate_state(xdme->state,
698 event->motion.is_hint = xdme->is_hint;
699 event->motion.source = gdkdev->info.source;
700 event->motion.deviceid = xdme->deviceid;
703 g_print ("motion notify:\t\twindow: %ld device: %ld x,y: %f %f state %#4x hint: %s\n",
706 event->motion.x, event->motion.y,
708 (xdme->is_hint) ? "true" : "false"));
714 if (xevent->type == gdkdev->proximityin_type ||
715 xevent->type == gdkdev->proximityout_type)
717 XProximityNotifyEvent *xpne = (XProximityNotifyEvent *)(xevent);
719 event->proximity.type = (xevent->type == gdkdev->proximityin_type)?
720 GDK_PROXIMITY_IN:GDK_PROXIMITY_OUT;
721 event->proximity.window = input_window->window;
722 event->proximity.time = xpne->time;
723 event->proximity.source = gdkdev->info.source;
724 event->proximity.deviceid = xpne->deviceid;
729 return -1; /* wasn't one of our event types */
733 gdk_input_common_set_axes (guint32 deviceid, GdkAxisUse *axes)
736 GdkDevicePrivate *gdkdev = gdk_input_find_device(deviceid);
737 g_return_if_fail (gdkdev != NULL);
739 for (i=GDK_AXIS_IGNORE;i<GDK_AXIS_LAST;i++)
741 gdkdev->axis_for_use[i] = -1;
744 for (i=0;i<gdkdev->info.num_axes;i++)
746 gdkdev->info.axes[i] = axes[i];
747 gdkdev->axis_for_use[axes[i]] = i;
751 void gdk_input_common_set_key (guint32 deviceid,
754 GdkModifierType modifiers)
756 GdkDevicePrivate *gdkdev = gdk_input_find_device(deviceid);
758 gdkdev = gdk_input_find_device (deviceid);
759 g_return_if_fail (gdkdev != NULL);
760 g_return_if_fail (index < gdkdev->info.num_keys);
762 gdkdev->info.keys[index].keyval = keyval;
763 gdkdev->info.keys[index].modifiers = modifiers;
766 static GdkTimeCoord *
767 gdk_input_common_motion_events (GdkWindow *window,
771 gint *nevents_return)
773 GdkTimeCoord *coords;
774 XDeviceTimeCoord *device_coords;
775 GdkInputWindow *input_window;
776 GdkDevicePrivate *gdkdev;
779 int axis_count_return;
782 gdkdev = gdk_input_find_device (deviceid);
783 input_window = gdk_input_window_find (window);
785 g_return_val_if_fail (gdkdev != NULL, NULL);
786 g_return_val_if_fail (gdkdev->xdevice != NULL, NULL);
787 g_return_val_if_fail (input_window != NULL, NULL);
789 device_coords = XGetDeviceMotionEvents (gdk_display,
792 nevents_return, &mode_return,
797 coords = g_new (GdkTimeCoord, *nevents_return);
799 for (i=0; i<*nevents_return; i++)
801 gdk_input_translate_coordinates (gdkdev, input_window,
802 device_coords[i].data,
803 &coords[i].x, &coords[i].y,
805 &coords[i].xtilt, &coords[i].ytilt);
807 XFreeDeviceMotionEvents (device_coords);
816 gdk_input_common_get_pointer (GdkWindow *window,
823 GdkModifierType *mask)
825 GdkDevicePrivate *gdkdev;
826 GdkInputWindow *input_window;
828 XInputClass *input_class;
832 /* we probably need to get the mask in any case */
834 if (deviceid == GDK_CORE_POINTER)
836 gdk_window_get_pointer (window, &x_int, &y_int, mask);
839 if (pressure) *pressure = 0.5;
840 if (xtilt) *xtilt = 0;
841 if (ytilt) *ytilt = 0;
846 gdk_window_get_pointer (window, NULL, NULL, mask);
848 gdkdev = gdk_input_find_device (deviceid);
849 input_window = gdk_input_window_find (window);
851 g_return_if_fail (gdkdev != NULL);
852 g_return_if_fail (gdkdev->xdevice != NULL);
853 g_return_if_fail (input_window != NULL);
855 state = XQueryDeviceState (gdk_display, gdkdev->xdevice);
856 input_class = state->data;
857 for (i=0; i<state->num_classes; i++)
859 switch (input_class->class)
862 gdk_input_translate_coordinates (gdkdev, input_window,
863 ((XValuatorState *)input_class)->valuators,
873 if (((XButtonState *)input_class)->num_buttons > 0)
874 *mask |= ((XButtonState *)input_class)->buttons[0] << 7;
875 /* GDK_BUTTON1_MASK = 1 << 8, and button n is stored
876 * in bit 1<<(n%8) in byte n/8. n = 1,2,... */
880 input_class = (XInputClass *)(((char *)input_class)+input_class->length);