1 /* GDK - The GIMP Drawing Kit
2  * Copyright (C) 2009 Carlos Garnacho <carlosg@gnome.org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser 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.
8  *
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  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "config.h"
19 
20 #include <math.h>
21 
22 #include "gdkdeviceprivate.h"
23 #include "gdkdevicetool.h"
24 #include "gdkdisplayprivate.h"
25 #include "gdkinternals.h"
26 #include "gdkintl.h"
27 
28 /* for the use of round() */
29 #include "fallback-c89.c"
30 
31 /**
32  * SECTION:gdkdevice
33  * @Short_description: Object representing an input device
34  * @Title: GdkDevice
35  * @See_also: #GdkDeviceManager
36  *
37  * The #GdkDevice object represents a single input device, such
38  * as a keyboard, a mouse, a touchpad, etc.
39  *
40  * See the #GdkDeviceManager documentation for more information
41  * about the various kinds of master and slave devices, and their
42  * relationships.
43  */
44 
45 typedef struct _GdkAxisInfo GdkAxisInfo;
46 
47 struct _GdkAxisInfo
48 {
49   GdkAtom label;
50   GdkAxisUse use;
51 
52   gdouble min_axis;
53   gdouble max_axis;
54   gdouble min_value;
55   gdouble max_value;
56   gdouble resolution;
57 };
58 
59 enum {
60   CHANGED,
61   TOOL_CHANGED,
62   LAST_SIGNAL
63 };
64 
65 static guint signals [LAST_SIGNAL] = { 0 };
66 
67 
68 static void gdk_device_finalize     (GObject      *object);
69 static void gdk_device_dispose      (GObject      *object);
70 static void gdk_device_set_property (GObject      *object,
71                                      guint         prop_id,
72                                      const GValue *value,
73                                      GParamSpec   *pspec);
74 static void gdk_device_get_property (GObject      *object,
75                                      guint         prop_id,
76                                      GValue       *value,
77                                      GParamSpec   *pspec);
78 
79 
80 G_DEFINE_ABSTRACT_TYPE (GdkDevice, gdk_device, G_TYPE_OBJECT)
81 
82 enum {
83   PROP_0,
84   PROP_DISPLAY,
85   PROP_DEVICE_MANAGER,
86   PROP_NAME,
87   PROP_ASSOCIATED_DEVICE,
88   PROP_TYPE,
89   PROP_INPUT_SOURCE,
90   PROP_INPUT_MODE,
91   PROP_HAS_CURSOR,
92   PROP_N_AXES,
93   PROP_VENDOR_ID,
94   PROP_PRODUCT_ID,
95   PROP_SEAT,
96   PROP_NUM_TOUCHES,
97   PROP_AXES,
98   PROP_TOOL,
99   LAST_PROP
100 };
101 
102 static GParamSpec *device_props[LAST_PROP] = { NULL, };
103 
104 static void
gdk_device_class_init(GdkDeviceClass * klass)105 gdk_device_class_init (GdkDeviceClass *klass)
106 {
107   GObjectClass *object_class = G_OBJECT_CLASS (klass);
108 
109   object_class->finalize = gdk_device_finalize;
110   object_class->dispose = gdk_device_dispose;
111   object_class->set_property = gdk_device_set_property;
112   object_class->get_property = gdk_device_get_property;
113 
114   /**
115    * GdkDevice:display:
116    *
117    * The #GdkDisplay the #GdkDevice pertains to.
118    *
119    * Since: 3.0
120    */
121   device_props[PROP_DISPLAY] =
122       g_param_spec_object ("display",
123                            P_("Device Display"),
124                            P_("Display which the device belongs to"),
125                            GDK_TYPE_DISPLAY,
126                            G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
127                            G_PARAM_STATIC_STRINGS);
128 
129   /**
130    * GdkDevice:device-manager:
131    *
132    * The #GdkDeviceManager the #GdkDevice pertains to.
133    *
134    * Since: 3.0
135    */
136   device_props[PROP_DEVICE_MANAGER] =
137       g_param_spec_object ("device-manager",
138                            P_("Device manager"),
139                            P_("Device manager which the device belongs to"),
140                            GDK_TYPE_DEVICE_MANAGER,
141                            G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
142                            G_PARAM_STATIC_STRINGS);
143   /**
144    * GdkDevice:name:
145    *
146    * The device name.
147    *
148    * Since: 3.0
149    */
150   device_props[PROP_NAME] =
151       g_param_spec_string ("name",
152                            P_("Device name"),
153                            P_("Device name"),
154                            NULL,
155                            G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
156                            G_PARAM_STATIC_STRINGS);
157   /**
158    * GdkDevice:type:
159    *
160    * Device role in the device manager.
161    *
162    * Since: 3.0
163    */
164   device_props[PROP_TYPE] =
165       g_param_spec_enum ("type",
166                          P_("Device type"),
167                          P_("Device role in the device manager"),
168                          GDK_TYPE_DEVICE_TYPE,
169                          GDK_DEVICE_TYPE_MASTER,
170                          G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
171                          G_PARAM_STATIC_STRINGS);
172 
173   /**
174    * GdkDevice:associated-device:
175    *
176    * Associated pointer or keyboard with this device, if any. Devices of type #GDK_DEVICE_TYPE_MASTER
177    * always come in keyboard/pointer pairs. Other device types will have a %NULL associated device.
178    *
179    * Since: 3.0
180    */
181   device_props[PROP_ASSOCIATED_DEVICE] =
182       g_param_spec_object ("associated-device",
183                            P_("Associated device"),
184                            P_("Associated pointer or keyboard with this device"),
185                            GDK_TYPE_DEVICE,
186                            G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
187 
188   /**
189    * GdkDevice:input-source:
190    *
191    * Source type for the device.
192    *
193    * Since: 3.0
194    */
195   device_props[PROP_INPUT_SOURCE] =
196       g_param_spec_enum ("input-source",
197                          P_("Input source"),
198                          P_("Source type for the device"),
199                          GDK_TYPE_INPUT_SOURCE,
200                          GDK_SOURCE_MOUSE,
201                          G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
202                          G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
203 
204   /*
205    * GdkDevice:input-mode:
206    *
207    * Input mode for the device.
208    *
209    * Since: 3.0
210    */
211   device_props[PROP_INPUT_MODE] =
212       g_param_spec_enum ("input-mode",
213                          P_("Input mode for the device"),
214                          P_("Input mode for the device"),
215                          GDK_TYPE_INPUT_MODE,
216                          GDK_MODE_DISABLED,
217                          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
218 
219   /**
220    * GdkDevice:has-cursor:
221    *
222    * Whether the device is represented by a cursor on the screen. Devices of type
223    * %GDK_DEVICE_TYPE_MASTER will have %TRUE here.
224    *
225    * Since: 3.0
226    */
227   device_props[PROP_HAS_CURSOR] =
228       g_param_spec_boolean ("has-cursor",
229                             P_("Whether the device has a cursor"),
230                             P_("Whether there is a visible cursor following device motion"),
231                             FALSE,
232                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
233                             G_PARAM_STATIC_STRINGS);
234 
235   /**
236    * GdkDevice:n-axes:
237    *
238    * Number of axes in the device.
239    *
240    * Since: 3.0
241    */
242   device_props[PROP_N_AXES] =
243       g_param_spec_uint ("n-axes",
244                          P_("Number of axes in the device"),
245                          P_("Number of axes in the device"),
246                          0, G_MAXUINT,
247                          0,
248                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
249 
250   /**
251    * GdkDevice:vendor-id:
252    *
253    * Vendor ID of this device, see gdk_device_get_vendor_id().
254    *
255    * Since: 3.16
256    */
257   device_props[PROP_VENDOR_ID] =
258       g_param_spec_string ("vendor-id",
259                            P_("Vendor ID"),
260                            P_("Vendor ID"),
261                            NULL,
262                            G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
263                            G_PARAM_STATIC_STRINGS);
264 
265   /**
266    * GdkDevice:product-id:
267    *
268    * Product ID of this device, see gdk_device_get_product_id().
269    *
270    * Since: 3.16
271    */
272   device_props[PROP_PRODUCT_ID] =
273       g_param_spec_string ("product-id",
274                            P_("Product ID"),
275                            P_("Product ID"),
276                            NULL,
277                            G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
278                            G_PARAM_STATIC_STRINGS);
279 
280   /**
281    * GdkDevice:seat:
282    *
283    * #GdkSeat of this device.
284    *
285    * Since: 3.20
286    */
287   device_props[PROP_SEAT] =
288       g_param_spec_object ("seat",
289                            P_("Seat"),
290                            P_("Seat"),
291                            GDK_TYPE_SEAT,
292                            G_PARAM_READWRITE |
293                            G_PARAM_STATIC_STRINGS);
294 
295   /**
296    * GdkDevice:num-touches:
297    *
298    * The maximal number of concurrent touches on a touch device.
299    * Will be 0 if the device is not a touch device or if the number
300    * of touches is unknown.
301    *
302    * Since: 3.20
303    */
304   device_props[PROP_NUM_TOUCHES] =
305       g_param_spec_uint ("num-touches",
306                          P_("Number of concurrent touches"),
307                          P_("Number of concurrent touches"),
308                          0, G_MAXUINT,
309                          0,
310                          G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
311                          G_PARAM_STATIC_STRINGS);
312   /**
313    * GdkDevice:axes:
314    *
315    * The axes currently available for this device.
316    *
317    * Since: 3.22
318    */
319   device_props[PROP_AXES] =
320     g_param_spec_flags ("axes",
321                         P_("Axes"),
322                         P_("Axes"),
323                         GDK_TYPE_AXIS_FLAGS, 0,
324                         G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
325 
326   device_props[PROP_TOOL] =
327     g_param_spec_object ("tool",
328                          P_("Tool"),
329                          P_("The tool that is currently used with this device"),
330                          GDK_TYPE_DEVICE_TOOL,
331                          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
332 
333   g_object_class_install_properties (object_class, LAST_PROP, device_props);
334 
335   /**
336    * GdkDevice::changed:
337    * @device: the #GdkDevice that changed.
338    *
339    * The ::changed signal is emitted either when the #GdkDevice
340    * has changed the number of either axes or keys. For example
341    * In X this will normally happen when the slave device routing
342    * events through the master device changes (for example, user
343    * switches from the USB mouse to a tablet), in that case the
344    * master device will change to reflect the new slave device
345    * axes and keys.
346    */
347   signals[CHANGED] =
348     g_signal_new (g_intern_static_string ("changed"),
349                   G_TYPE_FROM_CLASS (object_class),
350                   G_SIGNAL_RUN_LAST,
351                   0, NULL, NULL,
352                   NULL,
353                   G_TYPE_NONE, 0);
354 
355   /**
356    * GdkDevice::tool-changed:
357    * @device: the #GdkDevice that changed.
358    * @tool: The new current tool
359    *
360    * The ::tool-changed signal is emitted on pen/eraser
361    * #GdkDevices whenever tools enter or leave proximity.
362    *
363    * Since: 3.22
364    */
365   signals[TOOL_CHANGED] =
366     g_signal_new (g_intern_static_string ("tool-changed"),
367                   G_TYPE_FROM_CLASS (object_class),
368                   G_SIGNAL_RUN_LAST,
369                   0, NULL, NULL,
370                   NULL,
371                   G_TYPE_NONE, 1, GDK_TYPE_DEVICE_TOOL);
372 }
373 
374 static void
gdk_device_init(GdkDevice * device)375 gdk_device_init (GdkDevice *device)
376 {
377   device->axes = g_array_new (FALSE, TRUE, sizeof (GdkAxisInfo));
378 }
379 
380 static void
gdk_device_finalize(GObject * object)381 gdk_device_finalize (GObject *object)
382 {
383   GdkDevice *device = GDK_DEVICE (object);
384 
385   if (device->axes)
386     {
387       g_array_free (device->axes, TRUE);
388       device->axes = NULL;
389     }
390 
391   g_clear_pointer (&device->name, g_free);
392   g_clear_pointer (&device->keys, g_free);
393   g_clear_pointer (&device->vendor_id, g_free);
394   g_clear_pointer (&device->product_id, g_free);
395 
396   G_OBJECT_CLASS (gdk_device_parent_class)->finalize (object);
397 }
398 
399 static void
gdk_device_dispose(GObject * object)400 gdk_device_dispose (GObject *object)
401 {
402   GdkDevice *device = GDK_DEVICE (object);
403   GdkDevice *associated = device->associated;
404 
405   if (associated && device->type == GDK_DEVICE_TYPE_SLAVE)
406     _gdk_device_remove_slave (associated, device);
407 
408   if (associated)
409     {
410       device->associated = NULL;
411 
412       if (device->type == GDK_DEVICE_TYPE_MASTER &&
413           associated->associated == device)
414         _gdk_device_set_associated_device (associated, NULL);
415 
416       g_object_unref (associated);
417     }
418 
419   g_clear_object (&device->last_tool);
420 
421   G_OBJECT_CLASS (gdk_device_parent_class)->dispose (object);
422 }
423 
424 static void
gdk_device_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)425 gdk_device_set_property (GObject      *object,
426                          guint         prop_id,
427                          const GValue *value,
428                          GParamSpec   *pspec)
429 {
430   GdkDevice *device = GDK_DEVICE (object);
431 
432   switch (prop_id)
433     {
434     case PROP_DISPLAY:
435       device->display = g_value_get_object (value);
436       break;
437     case PROP_DEVICE_MANAGER:
438       device->manager = g_value_get_object (value);
439       break;
440     case PROP_NAME:
441       g_free (device->name);
442 
443       device->name = g_value_dup_string (value);
444       break;
445     case PROP_TYPE:
446       device->type = g_value_get_enum (value);
447       break;
448     case PROP_INPUT_SOURCE:
449       device->source = g_value_get_enum (value);
450       break;
451     case PROP_INPUT_MODE:
452       gdk_device_set_mode (device, g_value_get_enum (value));
453       break;
454     case PROP_HAS_CURSOR:
455       device->has_cursor = g_value_get_boolean (value);
456       break;
457     case PROP_VENDOR_ID:
458       device->vendor_id = g_value_dup_string (value);
459       break;
460     case PROP_PRODUCT_ID:
461       device->product_id = g_value_dup_string (value);
462       break;
463     case PROP_SEAT:
464       device->seat = g_value_get_object (value);
465       break;
466     case PROP_NUM_TOUCHES:
467       device->num_touches = g_value_get_uint (value);
468       break;
469     default:
470       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
471       break;
472     }
473 }
474 
475 static void
gdk_device_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)476 gdk_device_get_property (GObject    *object,
477                          guint       prop_id,
478                          GValue     *value,
479                          GParamSpec *pspec)
480 {
481   GdkDevice *device = GDK_DEVICE (object);
482 
483   switch (prop_id)
484     {
485     case PROP_DISPLAY:
486       g_value_set_object (value, device->display);
487       break;
488     case PROP_DEVICE_MANAGER:
489       g_value_set_object (value, device->manager);
490       break;
491     case PROP_ASSOCIATED_DEVICE:
492       g_value_set_object (value, device->associated);
493       break;
494     case PROP_NAME:
495       g_value_set_string (value, device->name);
496       break;
497     case PROP_TYPE:
498       g_value_set_enum (value, device->type);
499       break;
500     case PROP_INPUT_SOURCE:
501       g_value_set_enum (value, device->source);
502       break;
503     case PROP_INPUT_MODE:
504       g_value_set_enum (value, device->mode);
505       break;
506     case PROP_HAS_CURSOR:
507       g_value_set_boolean (value, device->has_cursor);
508       break;
509     case PROP_N_AXES:
510       g_value_set_uint (value, device->axes->len);
511       break;
512     case PROP_VENDOR_ID:
513       g_value_set_string (value, device->vendor_id);
514       break;
515     case PROP_PRODUCT_ID:
516       g_value_set_string (value, device->product_id);
517       break;
518     case PROP_SEAT:
519       g_value_set_object (value, device->seat);
520       break;
521     case PROP_NUM_TOUCHES:
522       g_value_set_uint (value, device->num_touches);
523       break;
524     case PROP_AXES:
525       g_value_set_flags (value, device->axis_flags);
526       break;
527     case PROP_TOOL:
528       g_value_set_object (value, device->last_tool);
529       break;
530     default:
531       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
532       break;
533     }
534 }
535 
536 /**
537  * gdk_device_get_state: (skip)
538  * @device: a #GdkDevice.
539  * @window: a #GdkWindow.
540  * @axes: (nullable) (array): an array of doubles to store the values of
541  * the axes of @device in, or %NULL.
542  * @mask: (optional) (out): location to store the modifiers, or %NULL.
543  *
544  * Gets the current state of a pointer device relative to @window. As a slave
545  * device’s coordinates are those of its master pointer, this
546  * function may not be called on devices of type %GDK_DEVICE_TYPE_SLAVE,
547  * unless there is an ongoing grab on them. See gdk_device_grab().
548  */
549 void
gdk_device_get_state(GdkDevice * device,GdkWindow * window,gdouble * axes,GdkModifierType * mask)550 gdk_device_get_state (GdkDevice       *device,
551                       GdkWindow       *window,
552                       gdouble         *axes,
553                       GdkModifierType *mask)
554 {
555   g_return_if_fail (GDK_IS_DEVICE (device));
556   g_return_if_fail (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD);
557   g_return_if_fail (GDK_IS_WINDOW (window));
558   g_return_if_fail (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_SLAVE ||
559                     gdk_display_device_is_grabbed (gdk_device_get_display (device), device));
560 
561   if (GDK_DEVICE_GET_CLASS (device)->get_state)
562     GDK_DEVICE_GET_CLASS (device)->get_state (device, window, axes, mask);
563 }
564 
565 /**
566  * gdk_device_get_position_double:
567  * @device: pointer device to query status about.
568  * @screen: (out) (transfer none) (allow-none): location to store the #GdkScreen
569  *          the @device is on, or %NULL.
570  * @x: (out) (allow-none): location to store root window X coordinate of @device, or %NULL.
571  * @y: (out) (allow-none): location to store root window Y coordinate of @device, or %NULL.
572  *
573  * Gets the current location of @device in double precision. As a slave device's
574  * coordinates are those of its master pointer, this function
575  * may not be called on devices of type %GDK_DEVICE_TYPE_SLAVE,
576  * unless there is an ongoing grab on them. See gdk_device_grab().
577  *
578  * Since: 3.10
579  **/
580 void
gdk_device_get_position_double(GdkDevice * device,GdkScreen ** screen,gdouble * x,gdouble * y)581 gdk_device_get_position_double (GdkDevice        *device,
582                                 GdkScreen       **screen,
583                                 gdouble          *x,
584                                 gdouble          *y)
585 {
586   GdkDisplay *display;
587   gdouble tmp_x, tmp_y;
588   GdkScreen *default_screen;
589   GdkWindow *root;
590 
591   g_return_if_fail (GDK_IS_DEVICE (device));
592   g_return_if_fail (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD);
593 
594   display = gdk_device_get_display (device);
595 
596   g_return_if_fail (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_SLAVE ||
597                     gdk_display_device_is_grabbed (display, device));
598 
599   default_screen = gdk_display_get_default_screen (display);
600 
601   _gdk_device_query_state (device,
602                            gdk_screen_get_root_window (default_screen),
603                            &root, NULL,
604                            &tmp_x, &tmp_y,
605                            NULL, NULL, NULL);
606 
607   if (screen)
608     *screen = gdk_window_get_screen (root);
609   if (x)
610     *x = tmp_x;
611   if (y)
612     *y = tmp_y;
613 }
614 
615 /**
616  * gdk_device_get_position:
617  * @device: pointer device to query status about.
618  * @screen: (out) (transfer none) (allow-none): location to store the #GdkScreen
619  *          the @device is on, or %NULL.
620  * @x: (out) (allow-none): location to store root window X coordinate of @device, or %NULL.
621  * @y: (out) (allow-none): location to store root window Y coordinate of @device, or %NULL.
622  *
623  * Gets the current location of @device. As a slave device
624  * coordinates are those of its master pointer, This function
625  * may not be called on devices of type %GDK_DEVICE_TYPE_SLAVE,
626  * unless there is an ongoing grab on them, see gdk_device_grab().
627  *
628  * Since: 3.0
629  **/
630 void
gdk_device_get_position(GdkDevice * device,GdkScreen ** screen,gint * x,gint * y)631 gdk_device_get_position (GdkDevice        *device,
632                          GdkScreen       **screen,
633                          gint             *x,
634                          gint             *y)
635 {
636   gdouble tmp_x, tmp_y;
637 
638   gdk_device_get_position_double (device, screen, &tmp_x, &tmp_y);
639   if (x)
640     *x = round (tmp_x);
641   if (y)
642     *y = round (tmp_y);
643 }
644 
645 
646 /**
647  * gdk_device_get_window_at_position_double:
648  * @device: pointer #GdkDevice to query info to.
649  * @win_x: (out) (allow-none): return location for the X coordinate of the device location,
650  *         relative to the window origin, or %NULL.
651  * @win_y: (out) (allow-none): return location for the Y coordinate of the device location,
652  *         relative to the window origin, or %NULL.
653  *
654  * Obtains the window underneath @device, returning the location of the device in @win_x and @win_y in
655  * double precision. Returns %NULL if the window tree under @device is not known to GDK (for example,
656  * belongs to another application).
657  *
658  * As a slave device coordinates are those of its master pointer, This
659  * function may not be called on devices of type %GDK_DEVICE_TYPE_SLAVE,
660  * unless there is an ongoing grab on them, see gdk_device_grab().
661  *
662  * Returns: (nullable) (transfer none): the #GdkWindow under the
663  *   device position, or %NULL.
664  *
665  * Since: 3.0
666  **/
667 GdkWindow *
gdk_device_get_window_at_position_double(GdkDevice * device,gdouble * win_x,gdouble * win_y)668 gdk_device_get_window_at_position_double (GdkDevice  *device,
669                                           gdouble    *win_x,
670                                           gdouble    *win_y)
671 {
672   gdouble tmp_x, tmp_y;
673   GdkWindow *window;
674 
675   g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
676   g_return_val_if_fail (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD, NULL);
677   g_return_val_if_fail (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_SLAVE ||
678                         gdk_display_device_is_grabbed (gdk_device_get_display (device), device), NULL);
679 
680   window = _gdk_device_window_at_position (device, &tmp_x, &tmp_y, NULL, FALSE);
681 
682   /* This might need corrections, as the native window returned
683      may contain client side children */
684   if (window)
685     window = _gdk_window_find_descendant_at (window,
686                                              tmp_x, tmp_y,
687                                              &tmp_x, &tmp_y);
688 
689   if (win_x)
690     *win_x = tmp_x;
691   if (win_y)
692     *win_y = tmp_y;
693 
694   return window;
695 }
696 
697 /**
698  * gdk_device_get_window_at_position:
699  * @device: pointer #GdkDevice to query info to.
700  * @win_x: (out) (allow-none): return location for the X coordinate of the device location,
701  *         relative to the window origin, or %NULL.
702  * @win_y: (out) (allow-none): return location for the Y coordinate of the device location,
703  *         relative to the window origin, or %NULL.
704  *
705  * Obtains the window underneath @device, returning the location of the device in @win_x and @win_y. Returns
706  * %NULL if the window tree under @device is not known to GDK (for example, belongs to another application).
707  *
708  * As a slave device coordinates are those of its master pointer, This
709  * function may not be called on devices of type %GDK_DEVICE_TYPE_SLAVE,
710  * unless there is an ongoing grab on them, see gdk_device_grab().
711  *
712  * Returns: (nullable) (transfer none): the #GdkWindow under the
713  * device position, or %NULL.
714  *
715  * Since: 3.0
716  **/
717 GdkWindow *
gdk_device_get_window_at_position(GdkDevice * device,gint * win_x,gint * win_y)718 gdk_device_get_window_at_position (GdkDevice  *device,
719                                    gint       *win_x,
720                                    gint       *win_y)
721 {
722   gdouble tmp_x, tmp_y;
723   GdkWindow *window;
724 
725   window =
726     gdk_device_get_window_at_position_double (device, &tmp_x, &tmp_y);
727 
728   if (win_x)
729     *win_x = round (tmp_x);
730   if (win_y)
731     *win_y = round (tmp_y);
732 
733   return window;
734 }
735 
736 /**
737  * gdk_device_get_history: (skip)
738  * @device: a #GdkDevice
739  * @window: the window with respect to which which the event coordinates will be reported
740  * @start: starting timestamp for range of events to return
741  * @stop: ending timestamp for the range of events to return
742  * @events: (array length=n_events) (out) (transfer full) (optional):
743  *   location to store a newly-allocated array of #GdkTimeCoord, or
744  *   %NULL
745  * @n_events: (out) (optional): location to store the length of
746  *   @events, or %NULL
747  *
748  * Obtains the motion history for a pointer device; given a starting and
749  * ending timestamp, return all events in the motion history for
750  * the device in the given range of time. Some windowing systems
751  * do not support motion history, in which case, %FALSE will
752  * be returned. (This is not distinguishable from the case where
753  * motion history is supported and no events were found.)
754  *
755  * Note that there is also gdk_window_set_event_compression() to get
756  * more motion events delivered directly, independent of the windowing
757  * system.
758  *
759  * Returns: %TRUE if the windowing system supports motion history and
760  *  at least one event was found.
761  **/
762 gboolean
gdk_device_get_history(GdkDevice * device,GdkWindow * window,guint32 start,guint32 stop,GdkTimeCoord *** events,gint * n_events)763 gdk_device_get_history (GdkDevice      *device,
764                         GdkWindow      *window,
765                         guint32         start,
766                         guint32         stop,
767                         GdkTimeCoord ***events,
768                         gint           *n_events)
769 {
770   g_return_val_if_fail (GDK_IS_DEVICE (device), FALSE);
771   g_return_val_if_fail (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD, FALSE);
772   g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
773 
774   if (n_events)
775     *n_events = 0;
776 
777   if (events)
778     *events = NULL;
779 
780   if (GDK_WINDOW_DESTROYED (window))
781     return FALSE;
782 
783   if (!GDK_DEVICE_GET_CLASS (device)->get_history)
784     return FALSE;
785 
786   return GDK_DEVICE_GET_CLASS (device)->get_history (device, window,
787                                                      start, stop,
788                                                      events, n_events);
789 }
790 
791 GdkTimeCoord **
_gdk_device_allocate_history(GdkDevice * device,gint n_events)792 _gdk_device_allocate_history (GdkDevice *device,
793                               gint       n_events)
794 {
795   GdkTimeCoord **result = g_new (GdkTimeCoord *, n_events);
796   gint i;
797 
798   for (i = 0; i < n_events; i++)
799     result[i] = g_malloc (sizeof (GdkTimeCoord) -
800                           sizeof (double) * (GDK_MAX_TIMECOORD_AXES - device->axes->len));
801   return result;
802 }
803 
804 /**
805  * gdk_device_free_history: (skip)
806  * @events: (array length=n_events): an array of #GdkTimeCoord.
807  * @n_events: the length of the array.
808  *
809  * Frees an array of #GdkTimeCoord that was returned by gdk_device_get_history().
810  */
811 void
gdk_device_free_history(GdkTimeCoord ** events,gint n_events)812 gdk_device_free_history (GdkTimeCoord **events,
813                          gint           n_events)
814 {
815   gint i;
816 
817   for (i = 0; i < n_events; i++)
818     g_free (events[i]);
819 
820   g_free (events);
821 }
822 
823 /**
824  * gdk_device_get_name:
825  * @device: a #GdkDevice
826  *
827  * Determines the name of the device.
828  *
829  * Returns: a name
830  *
831  * Since: 2.20
832  **/
833 const gchar *
gdk_device_get_name(GdkDevice * device)834 gdk_device_get_name (GdkDevice *device)
835 {
836   g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
837 
838   return device->name;
839 }
840 
841 /**
842  * gdk_device_get_has_cursor:
843  * @device: a #GdkDevice
844  *
845  * Determines whether the pointer follows device motion.
846  * This is not meaningful for keyboard devices, which don't have a pointer.
847  *
848  * Returns: %TRUE if the pointer follows device motion
849  *
850  * Since: 2.20
851  **/
852 gboolean
gdk_device_get_has_cursor(GdkDevice * device)853 gdk_device_get_has_cursor (GdkDevice *device)
854 {
855   g_return_val_if_fail (GDK_IS_DEVICE (device), FALSE);
856 
857   return device->has_cursor;
858 }
859 
860 /**
861  * gdk_device_get_source:
862  * @device: a #GdkDevice
863  *
864  * Determines the type of the device.
865  *
866  * Returns: a #GdkInputSource
867  *
868  * Since: 2.20
869  **/
870 GdkInputSource
gdk_device_get_source(GdkDevice * device)871 gdk_device_get_source (GdkDevice *device)
872 {
873   g_return_val_if_fail (GDK_IS_DEVICE (device), 0);
874 
875   return device->source;
876 }
877 
878 /**
879  * gdk_device_get_mode:
880  * @device: a #GdkDevice
881  *
882  * Determines the mode of the device.
883  *
884  * Returns: a #GdkInputSource
885  *
886  * Since: 2.20
887  **/
888 GdkInputMode
gdk_device_get_mode(GdkDevice * device)889 gdk_device_get_mode (GdkDevice *device)
890 {
891   g_return_val_if_fail (GDK_IS_DEVICE (device), 0);
892 
893   return device->mode;
894 }
895 
896 /**
897  * gdk_device_set_mode:
898  * @device: a #GdkDevice.
899  * @mode: the input mode.
900  *
901  * Sets a the mode of an input device. The mode controls if the
902  * device is active and whether the device’s range is mapped to the
903  * entire screen or to a single window.
904  *
905  * Note: This is only meaningful for floating devices, master devices (and
906  * slaves connected to these) drive the pointer cursor, which is not limited
907  * by the input mode.
908  *
909  * Returns: %TRUE if the mode was successfully changed.
910  **/
911 gboolean
gdk_device_set_mode(GdkDevice * device,GdkInputMode mode)912 gdk_device_set_mode (GdkDevice    *device,
913                      GdkInputMode  mode)
914 {
915   g_return_val_if_fail (GDK_IS_DEVICE (device), FALSE);
916 
917   if (device->mode == mode)
918     return TRUE;
919 
920   if (mode == GDK_MODE_DISABLED &&
921       gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_MASTER)
922     return FALSE;
923 
924   device->mode = mode;
925   g_object_notify_by_pspec (G_OBJECT (device), device_props[PROP_INPUT_MODE]);
926 
927   return TRUE;
928 }
929 
930 /**
931  * gdk_device_get_n_keys:
932  * @device: a #GdkDevice
933  *
934  * Returns the number of keys the device currently has.
935  *
936  * Returns: the number of keys.
937  *
938  * Since: 2.24
939  **/
940 gint
gdk_device_get_n_keys(GdkDevice * device)941 gdk_device_get_n_keys (GdkDevice *device)
942 {
943   g_return_val_if_fail (GDK_IS_DEVICE (device), 0);
944 
945   return device->num_keys;
946 }
947 
948 /**
949  * gdk_device_get_key:
950  * @device: a #GdkDevice.
951  * @index_: the index of the macro button to get.
952  * @keyval: (out): return value for the keyval.
953  * @modifiers: (out): return value for modifiers.
954  *
955  * If @index_ has a valid keyval, this function will return %TRUE
956  * and fill in @keyval and @modifiers with the keyval settings.
957  *
958  * Returns: %TRUE if keyval is set for @index.
959  *
960  * Since: 2.20
961  **/
962 gboolean
gdk_device_get_key(GdkDevice * device,guint index_,guint * keyval,GdkModifierType * modifiers)963 gdk_device_get_key (GdkDevice       *device,
964                     guint            index_,
965                     guint           *keyval,
966                     GdkModifierType *modifiers)
967 {
968   g_return_val_if_fail (GDK_IS_DEVICE (device), FALSE);
969   g_return_val_if_fail (index_ < device->num_keys, FALSE);
970 
971   if (!device->keys[index_].keyval &&
972       !device->keys[index_].modifiers)
973     return FALSE;
974 
975   if (keyval)
976     *keyval = device->keys[index_].keyval;
977 
978   if (modifiers)
979     *modifiers = device->keys[index_].modifiers;
980 
981   return TRUE;
982 }
983 
984 /**
985  * gdk_device_set_key:
986  * @device: a #GdkDevice
987  * @index_: the index of the macro button to set
988  * @keyval: the keyval to generate
989  * @modifiers: the modifiers to set
990  *
991  * Specifies the X key event to generate when a macro button of a device
992  * is pressed.
993  **/
994 void
gdk_device_set_key(GdkDevice * device,guint index_,guint keyval,GdkModifierType modifiers)995 gdk_device_set_key (GdkDevice      *device,
996                     guint           index_,
997                     guint           keyval,
998                     GdkModifierType modifiers)
999 {
1000   g_return_if_fail (GDK_IS_DEVICE (device));
1001   g_return_if_fail (index_ < device->num_keys);
1002 
1003   device->keys[index_].keyval = keyval;
1004   device->keys[index_].modifiers = modifiers;
1005 }
1006 
1007 /**
1008  * gdk_device_get_axis_use:
1009  * @device: a pointer #GdkDevice.
1010  * @index_: the index of the axis.
1011  *
1012  * Returns the axis use for @index_.
1013  *
1014  * Returns: a #GdkAxisUse specifying how the axis is used.
1015  *
1016  * Since: 2.20
1017  **/
1018 GdkAxisUse
gdk_device_get_axis_use(GdkDevice * device,guint index_)1019 gdk_device_get_axis_use (GdkDevice *device,
1020                          guint      index_)
1021 {
1022   GdkAxisInfo *info;
1023 
1024   g_return_val_if_fail (GDK_IS_DEVICE (device), GDK_AXIS_IGNORE);
1025   g_return_val_if_fail (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD, GDK_AXIS_IGNORE);
1026   g_return_val_if_fail (index_ < device->axes->len, GDK_AXIS_IGNORE);
1027 
1028   info = &g_array_index (device->axes, GdkAxisInfo, index_);
1029 
1030   return info->use;
1031 }
1032 
1033 /**
1034  * gdk_device_set_axis_use:
1035  * @device: a pointer #GdkDevice
1036  * @index_: the index of the axis
1037  * @use: specifies how the axis is used
1038  *
1039  * Specifies how an axis of a device is used.
1040  **/
1041 void
gdk_device_set_axis_use(GdkDevice * device,guint index_,GdkAxisUse use)1042 gdk_device_set_axis_use (GdkDevice   *device,
1043                          guint        index_,
1044                          GdkAxisUse   use)
1045 {
1046   GdkAxisInfo *info;
1047 
1048   g_return_if_fail (GDK_IS_DEVICE (device));
1049   g_return_if_fail (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD);
1050   g_return_if_fail (index_ < device->axes->len);
1051 
1052   info = &g_array_index (device->axes, GdkAxisInfo, index_);
1053   info->use = use;
1054 
1055   switch (use)
1056     {
1057     case GDK_AXIS_X:
1058     case GDK_AXIS_Y:
1059       info->min_axis = 0;
1060       info->max_axis = 0;
1061       break;
1062     case GDK_AXIS_XTILT:
1063     case GDK_AXIS_YTILT:
1064       info->min_axis = -1;
1065       info->max_axis = 1;
1066       break;
1067     default:
1068       info->min_axis = 0;
1069       info->max_axis = 1;
1070       break;
1071     }
1072 }
1073 
1074 /**
1075  * gdk_device_get_display:
1076  * @device: a #GdkDevice
1077  *
1078  * Returns the #GdkDisplay to which @device pertains.
1079  *
1080  * Returns: (transfer none): a #GdkDisplay. This memory is owned
1081  *          by GTK+, and must not be freed or unreffed.
1082  *
1083  * Since: 3.0
1084  **/
1085 GdkDisplay *
gdk_device_get_display(GdkDevice * device)1086 gdk_device_get_display (GdkDevice *device)
1087 {
1088   g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
1089 
1090   return device->display;
1091 }
1092 
1093 /**
1094  * gdk_device_get_associated_device:
1095  * @device: a #GdkDevice
1096  *
1097  * Returns the associated device to @device, if @device is of type
1098  * %GDK_DEVICE_TYPE_MASTER, it will return the paired pointer or
1099  * keyboard.
1100  *
1101  * If @device is of type %GDK_DEVICE_TYPE_SLAVE, it will return
1102  * the master device to which @device is attached to.
1103  *
1104  * If @device is of type %GDK_DEVICE_TYPE_FLOATING, %NULL will be
1105  * returned, as there is no associated device.
1106  *
1107  * Returns: (nullable) (transfer none): The associated device, or
1108  *   %NULL
1109  *
1110  * Since: 3.0
1111  **/
1112 GdkDevice *
gdk_device_get_associated_device(GdkDevice * device)1113 gdk_device_get_associated_device (GdkDevice *device)
1114 {
1115   g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
1116 
1117   return device->associated;
1118 }
1119 
1120 static void
_gdk_device_set_device_type(GdkDevice * device,GdkDeviceType type)1121 _gdk_device_set_device_type (GdkDevice     *device,
1122                              GdkDeviceType  type)
1123 {
1124   if (device->type != type)
1125     {
1126       device->type = type;
1127 
1128       g_object_notify_by_pspec (G_OBJECT (device), device_props[PROP_TYPE]);
1129     }
1130 }
1131 
1132 void
_gdk_device_set_associated_device(GdkDevice * device,GdkDevice * associated)1133 _gdk_device_set_associated_device (GdkDevice *device,
1134                                    GdkDevice *associated)
1135 {
1136   g_return_if_fail (GDK_IS_DEVICE (device));
1137   g_return_if_fail (associated == NULL || GDK_IS_DEVICE (associated));
1138 
1139   if (device->associated == associated)
1140     return;
1141 
1142   if (device->associated)
1143     {
1144       g_object_unref (device->associated);
1145       device->associated = NULL;
1146     }
1147 
1148   if (associated)
1149     device->associated = g_object_ref (associated);
1150 
1151   if (device->type != GDK_DEVICE_TYPE_MASTER)
1152     {
1153       if (device->associated)
1154         _gdk_device_set_device_type (device, GDK_DEVICE_TYPE_SLAVE);
1155       else
1156         _gdk_device_set_device_type (device, GDK_DEVICE_TYPE_FLOATING);
1157     }
1158 }
1159 
1160 /**
1161  * gdk_device_list_slave_devices:
1162  * @device: a #GdkDevice
1163  *
1164  * If the device if of type %GDK_DEVICE_TYPE_MASTER, it will return
1165  * the list of slave devices attached to it, otherwise it will return
1166  * %NULL
1167  *
1168  * Returns: (nullable) (transfer container) (element-type GdkDevice):
1169  *          the list of slave devices, or %NULL. The list must be
1170  *          freed with g_list_free(), the contents of the list are
1171  *          owned by GTK+ and should not be freed.
1172  **/
1173 GList *
gdk_device_list_slave_devices(GdkDevice * device)1174 gdk_device_list_slave_devices (GdkDevice *device)
1175 {
1176   g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
1177   g_return_val_if_fail (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_MASTER, NULL);
1178 
1179   return g_list_copy (device->slaves);
1180 }
1181 
1182 void
_gdk_device_add_slave(GdkDevice * device,GdkDevice * slave)1183 _gdk_device_add_slave (GdkDevice *device,
1184                        GdkDevice *slave)
1185 {
1186   g_return_if_fail (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_MASTER);
1187   g_return_if_fail (gdk_device_get_device_type (slave) != GDK_DEVICE_TYPE_MASTER);
1188 
1189   if (!g_list_find (device->slaves, slave))
1190     device->slaves = g_list_prepend (device->slaves, slave);
1191 }
1192 
1193 void
_gdk_device_remove_slave(GdkDevice * device,GdkDevice * slave)1194 _gdk_device_remove_slave (GdkDevice *device,
1195                           GdkDevice *slave)
1196 {
1197   GList *elem;
1198 
1199   g_return_if_fail (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_MASTER);
1200   g_return_if_fail (gdk_device_get_device_type (slave) != GDK_DEVICE_TYPE_MASTER);
1201 
1202   elem = g_list_find (device->slaves, slave);
1203 
1204   if (!elem)
1205     return;
1206 
1207   device->slaves = g_list_delete_link (device->slaves, elem);
1208 }
1209 
1210 /**
1211  * gdk_device_get_device_type:
1212  * @device: a #GdkDevice
1213  *
1214  * Returns the device type for @device.
1215  *
1216  * Returns: the #GdkDeviceType for @device.
1217  *
1218  * Since: 3.0
1219  **/
1220 GdkDeviceType
gdk_device_get_device_type(GdkDevice * device)1221 gdk_device_get_device_type (GdkDevice *device)
1222 {
1223   g_return_val_if_fail (GDK_IS_DEVICE (device), GDK_DEVICE_TYPE_MASTER);
1224 
1225   return device->type;
1226 }
1227 
1228 /**
1229  * gdk_device_get_n_axes:
1230  * @device: a pointer #GdkDevice
1231  *
1232  * Returns the number of axes the device currently has.
1233  *
1234  * Returns: the number of axes.
1235  *
1236  * Since: 3.0
1237  **/
1238 gint
gdk_device_get_n_axes(GdkDevice * device)1239 gdk_device_get_n_axes (GdkDevice *device)
1240 {
1241   g_return_val_if_fail (GDK_IS_DEVICE (device), 0);
1242   g_return_val_if_fail (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD, 0);
1243 
1244   return device->axes->len;
1245 }
1246 
1247 /**
1248  * gdk_device_list_axes:
1249  * @device: a pointer #GdkDevice
1250  *
1251  * Returns a #GList of #GdkAtoms, containing the labels for
1252  * the axes that @device currently has.
1253  *
1254  * Returns: (transfer container) (element-type GdkAtom):
1255  *     A #GList of #GdkAtoms, free with g_list_free().
1256  *
1257  * Since: 3.0
1258  **/
1259 GList *
gdk_device_list_axes(GdkDevice * device)1260 gdk_device_list_axes (GdkDevice *device)
1261 {
1262   GList *axes = NULL;
1263   gint i;
1264 
1265   g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
1266   g_return_val_if_fail (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD, NULL);
1267 
1268   for (i = 0; i < device->axes->len; i++)
1269     {
1270       GdkAxisInfo axis_info;
1271 
1272       axis_info = g_array_index (device->axes, GdkAxisInfo, i);
1273       axes = g_list_prepend (axes, GDK_ATOM_TO_POINTER (axis_info.label));
1274     }
1275 
1276   return g_list_reverse (axes);
1277 }
1278 
1279 /**
1280  * gdk_device_get_axis_value: (skip)
1281  * @device: a pointer #GdkDevice.
1282  * @axes: (array): pointer to an array of axes
1283  * @axis_label: #GdkAtom with the axis label.
1284  * @value: (out): location to store the found value.
1285  *
1286  * Interprets an array of double as axis values for a given device,
1287  * and locates the value in the array for a given axis label, as returned
1288  * by gdk_device_list_axes()
1289  *
1290  * Returns: %TRUE if the given axis use was found, otherwise %FALSE.
1291  *
1292  * Since: 3.0
1293  **/
1294 gboolean
gdk_device_get_axis_value(GdkDevice * device,gdouble * axes,GdkAtom axis_label,gdouble * value)1295 gdk_device_get_axis_value (GdkDevice *device,
1296                            gdouble   *axes,
1297                            GdkAtom    axis_label,
1298                            gdouble   *value)
1299 {
1300   gint i;
1301 
1302   g_return_val_if_fail (GDK_IS_DEVICE (device), FALSE);
1303   g_return_val_if_fail (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD, FALSE);
1304 
1305   if (axes == NULL)
1306     return FALSE;
1307 
1308   for (i = 0; i < device->axes->len; i++)
1309     {
1310       GdkAxisInfo axis_info;
1311 
1312       axis_info = g_array_index (device->axes, GdkAxisInfo, i);
1313 
1314       if (axis_info.label != axis_label)
1315         continue;
1316 
1317       if (value)
1318         *value = axes[i];
1319 
1320       return TRUE;
1321     }
1322 
1323   return FALSE;
1324 }
1325 
1326 /**
1327  * gdk_device_get_axis: (skip)
1328  * @device: a #GdkDevice
1329  * @axes: (array): pointer to an array of axes
1330  * @use: the use to look for
1331  * @value: (out): location to store the found value.
1332  *
1333  * Interprets an array of double as axis values for a given device,
1334  * and locates the value in the array for a given axis use.
1335  *
1336  * Returns: %TRUE if the given axis use was found, otherwise %FALSE
1337  **/
1338 gboolean
gdk_device_get_axis(GdkDevice * device,gdouble * axes,GdkAxisUse use,gdouble * value)1339 gdk_device_get_axis (GdkDevice  *device,
1340                      gdouble    *axes,
1341                      GdkAxisUse  use,
1342                      gdouble    *value)
1343 {
1344   gint i;
1345 
1346   g_return_val_if_fail (GDK_IS_DEVICE (device), FALSE);
1347   g_return_val_if_fail (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD, FALSE);
1348 
1349   if (axes == NULL)
1350     return FALSE;
1351 
1352   g_return_val_if_fail (device->axes != NULL, FALSE);
1353 
1354   for (i = 0; i < device->axes->len; i++)
1355     {
1356       GdkAxisInfo axis_info;
1357 
1358       axis_info = g_array_index (device->axes, GdkAxisInfo, i);
1359 
1360       if (axis_info.use != use)
1361         continue;
1362 
1363       if (value)
1364         *value = axes[i];
1365 
1366       return TRUE;
1367     }
1368 
1369   return FALSE;
1370 }
1371 
1372 static GdkEventMask
get_native_grab_event_mask(GdkEventMask grab_mask)1373 get_native_grab_event_mask (GdkEventMask grab_mask)
1374 {
1375   /* Similar to the above but for pointer events only */
1376   return
1377     GDK_POINTER_MOTION_MASK |
1378     GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
1379     GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK |
1380     GDK_SCROLL_MASK |
1381     (grab_mask &
1382      ~(GDK_POINTER_MOTION_HINT_MASK |
1383        GDK_BUTTON_MOTION_MASK |
1384        GDK_BUTTON1_MOTION_MASK |
1385        GDK_BUTTON2_MOTION_MASK |
1386        GDK_BUTTON3_MOTION_MASK));
1387 }
1388 
1389 /**
1390  * gdk_device_grab:
1391  * @device: a #GdkDevice. To get the device you can use gtk_get_current_event_device()
1392  *   or gdk_event_get_device() if the grab is in reaction to an event. Also, you can use
1393  *   gdk_device_manager_get_client_pointer() but only in code that isn’t triggered by a
1394  *   #GdkEvent and there aren’t other means to get a meaningful #GdkDevice to operate on.
1395  * @window: the #GdkWindow which will own the grab (the grab window)
1396  * @grab_ownership: specifies the grab ownership.
1397  * @owner_events: if %FALSE then all device events are reported with respect to
1398  *                @window and are only reported if selected by @event_mask. If
1399  *                %TRUE then pointer events for this application are reported
1400  *                as normal, but pointer events outside this application are
1401  *                reported with respect to @window and only if selected by
1402  *                @event_mask. In either mode, unreported events are discarded.
1403  * @event_mask: specifies the event mask, which is used in accordance with
1404  *              @owner_events.
1405  * @cursor: (allow-none): the cursor to display while the grab is active if the device is
1406  *          a pointer. If this is %NULL then the normal cursors are used for
1407  *          @window and its descendants, and the cursor for @window is used
1408  *          elsewhere.
1409  * @time_: the timestamp of the event which led to this pointer grab. This
1410  *         usually comes from the #GdkEvent struct, though %GDK_CURRENT_TIME
1411  *         can be used if the time isn’t known.
1412  *
1413  * Grabs the device so that all events coming from this device are passed to
1414  * this application until the device is ungrabbed with gdk_device_ungrab(),
1415  * or the window becomes unviewable. This overrides any previous grab on the device
1416  * by this client.
1417  *
1418  * Note that @device and @window need to be on the same display.
1419  *
1420  * Device grabs are used for operations which need complete control over the
1421  * given device events (either pointer or keyboard). For example in GTK+ this
1422  * is used for Drag and Drop operations, popup menus and such.
1423  *
1424  * Note that if the event mask of an X window has selected both button press
1425  * and button release events, then a button press event will cause an automatic
1426  * pointer grab until the button is released. X does this automatically since
1427  * most applications expect to receive button press and release events in pairs.
1428  * It is equivalent to a pointer grab on the window with @owner_events set to
1429  * %TRUE.
1430  *
1431  * If you set up anything at the time you take the grab that needs to be
1432  * cleaned up when the grab ends, you should handle the #GdkEventGrabBroken
1433  * events that are emitted when the grab ends unvoluntarily.
1434  *
1435  * Returns: %GDK_GRAB_SUCCESS if the grab was successful.
1436  *
1437  * Since: 3.0
1438  *
1439  * Deprecated: 3.20. Use gdk_seat_grab() instead.
1440  **/
1441 GdkGrabStatus
gdk_device_grab(GdkDevice * device,GdkWindow * window,GdkGrabOwnership grab_ownership,gboolean owner_events,GdkEventMask event_mask,GdkCursor * cursor,guint32 time_)1442 gdk_device_grab (GdkDevice        *device,
1443                  GdkWindow        *window,
1444                  GdkGrabOwnership  grab_ownership,
1445                  gboolean          owner_events,
1446                  GdkEventMask      event_mask,
1447                  GdkCursor        *cursor,
1448                  guint32           time_)
1449 {
1450   GdkGrabStatus res;
1451   GdkWindow *native;
1452 
1453   g_return_val_if_fail (GDK_IS_DEVICE (device), GDK_GRAB_FAILED);
1454   g_return_val_if_fail (GDK_IS_WINDOW (window), GDK_GRAB_FAILED);
1455   g_return_val_if_fail (gdk_window_get_display (window) == gdk_device_get_display (device), GDK_GRAB_FAILED);
1456 
1457   native = gdk_window_get_toplevel (window);
1458 
1459   while (native->window_type == GDK_WINDOW_OFFSCREEN)
1460     {
1461       native = gdk_offscreen_window_get_embedder (native);
1462 
1463       if (native == NULL ||
1464           (!_gdk_window_has_impl (native) &&
1465            !gdk_window_is_viewable (native)))
1466         return GDK_GRAB_NOT_VIEWABLE;
1467 
1468       native = gdk_window_get_toplevel (native);
1469     }
1470 
1471   if (native == NULL || GDK_WINDOW_DESTROYED (native))
1472     return GDK_GRAB_NOT_VIEWABLE;
1473 
1474   res = GDK_DEVICE_GET_CLASS (device)->grab (device,
1475                                              native,
1476                                              owner_events,
1477                                              get_native_grab_event_mask (event_mask),
1478                                              NULL,
1479                                              cursor,
1480                                              time_);
1481 
1482   if (res == GDK_GRAB_SUCCESS)
1483     {
1484       GdkDisplay *display;
1485       gulong serial;
1486 
1487       display = gdk_window_get_display (window);
1488       serial = _gdk_display_get_next_serial (display);
1489 
1490       _gdk_display_add_device_grab (display,
1491                                     device,
1492                                     window,
1493                                     native,
1494                                     grab_ownership,
1495                                     owner_events,
1496                                     event_mask,
1497                                     serial,
1498                                     time_,
1499                                     FALSE);
1500     }
1501 
1502   return res;
1503 }
1504 
1505 /**
1506  * gdk_device_ungrab:
1507  * @device: a #GdkDevice
1508  * @time_: a timestap (e.g. %GDK_CURRENT_TIME).
1509  *
1510  * Release any grab on @device.
1511  *
1512  * Since: 3.0
1513  *
1514  * Deprecated: 3.20. Use gdk_seat_ungrab() instead.
1515  */
1516 void
gdk_device_ungrab(GdkDevice * device,guint32 time_)1517 gdk_device_ungrab (GdkDevice  *device,
1518                    guint32     time_)
1519 {
1520   g_return_if_fail (GDK_IS_DEVICE (device));
1521 
1522   GDK_DEVICE_GET_CLASS (device)->ungrab (device, time_);
1523 }
1524 
1525 /**
1526  * gdk_device_warp:
1527  * @device: the device to warp.
1528  * @screen: the screen to warp @device to.
1529  * @x: the X coordinate of the destination.
1530  * @y: the Y coordinate of the destination.
1531  *
1532  * Warps @device in @display to the point @x,@y on
1533  * the screen @screen, unless the device is confined
1534  * to a window by a grab, in which case it will be moved
1535  * as far as allowed by the grab. Warping the pointer
1536  * creates events as if the user had moved the mouse
1537  * instantaneously to the destination.
1538  *
1539  * Note that the pointer should normally be under the
1540  * control of the user. This function was added to cover
1541  * some rare use cases like keyboard navigation support
1542  * for the color picker in the #GtkColorSelectionDialog.
1543  *
1544  * Since: 3.0
1545  **/
1546 void
gdk_device_warp(GdkDevice * device,GdkScreen * screen,gint x,gint y)1547 gdk_device_warp (GdkDevice  *device,
1548                  GdkScreen  *screen,
1549                  gint        x,
1550                  gint        y)
1551 {
1552   g_return_if_fail (GDK_IS_DEVICE (device));
1553   g_return_if_fail (GDK_IS_SCREEN (screen));
1554   g_return_if_fail (gdk_device_get_display (device) == gdk_screen_get_display (screen));
1555 
1556   GDK_DEVICE_GET_CLASS (device)->warp (device, screen, x, y);
1557 }
1558 
1559 /* Private API */
1560 void
_gdk_device_reset_axes(GdkDevice * device)1561 _gdk_device_reset_axes (GdkDevice *device)
1562 {
1563   gint i;
1564 
1565   for (i = device->axes->len - 1; i >= 0; i--)
1566     g_array_remove_index (device->axes, i);
1567 
1568   device->axis_flags = 0;
1569 
1570   g_object_notify_by_pspec (G_OBJECT (device), device_props[PROP_N_AXES]);
1571   g_object_notify_by_pspec (G_OBJECT (device), device_props[PROP_AXES]);
1572 }
1573 
1574 guint
_gdk_device_add_axis(GdkDevice * device,GdkAtom label_atom,GdkAxisUse use,gdouble min_value,gdouble max_value,gdouble resolution)1575 _gdk_device_add_axis (GdkDevice   *device,
1576                       GdkAtom      label_atom,
1577                       GdkAxisUse   use,
1578                       gdouble      min_value,
1579                       gdouble      max_value,
1580                       gdouble      resolution)
1581 {
1582   GdkAxisInfo axis_info;
1583   guint pos;
1584 
1585   axis_info.use = use;
1586   axis_info.label = label_atom;
1587   axis_info.min_value = min_value;
1588   axis_info.max_value = max_value;
1589   axis_info.resolution = resolution;
1590 
1591   switch (use)
1592     {
1593     case GDK_AXIS_X:
1594     case GDK_AXIS_Y:
1595       axis_info.min_axis = 0;
1596       axis_info.max_axis = 0;
1597       break;
1598     case GDK_AXIS_XTILT:
1599     case GDK_AXIS_YTILT:
1600       axis_info.min_axis = -1;
1601       axis_info.max_axis = 1;
1602       break;
1603     default:
1604       axis_info.min_axis = 0;
1605       axis_info.max_axis = 1;
1606       break;
1607     }
1608 
1609   device->axes = g_array_append_val (device->axes, axis_info);
1610   pos = device->axes->len - 1;
1611 
1612   device->axis_flags |= (1 << use);
1613 
1614   g_object_notify_by_pspec (G_OBJECT (device), device_props[PROP_N_AXES]);
1615   g_object_notify_by_pspec (G_OBJECT (device), device_props[PROP_AXES]);
1616 
1617   return pos;
1618 }
1619 
1620 void
_gdk_device_get_axis_info(GdkDevice * device,guint index_,GdkAtom * label_atom,GdkAxisUse * use,gdouble * min_value,gdouble * max_value,gdouble * resolution)1621 _gdk_device_get_axis_info (GdkDevice   *device,
1622 			   guint        index_,
1623 			   GdkAtom      *label_atom,
1624 			   GdkAxisUse   *use,
1625 			   gdouble      *min_value,
1626 			   gdouble      *max_value,
1627 			   gdouble      *resolution)
1628 {
1629   GdkAxisInfo *info;
1630 
1631   g_return_if_fail (GDK_IS_DEVICE (device));
1632   g_return_if_fail (index_ < device->axes->len);
1633 
1634   info = &g_array_index (device->axes, GdkAxisInfo, index_);
1635 
1636   *label_atom = info->label;
1637   *use = info->use;
1638   *min_value = info->min_value;
1639   *max_value = info->max_value;
1640   *resolution = info->resolution;
1641 }
1642 
1643 void
_gdk_device_set_keys(GdkDevice * device,guint num_keys)1644 _gdk_device_set_keys (GdkDevice *device,
1645                       guint      num_keys)
1646 {
1647   g_free (device->keys);
1648 
1649   device->num_keys = num_keys;
1650   device->keys = g_new0 (GdkDeviceKey, num_keys);
1651 }
1652 
1653 static GdkAxisInfo *
find_axis_info(GArray * array,GdkAxisUse use)1654 find_axis_info (GArray     *array,
1655                 GdkAxisUse  use)
1656 {
1657   GdkAxisInfo *info;
1658   gint i;
1659 
1660   for (i = 0; i < GDK_AXIS_LAST; i++)
1661     {
1662       info = &g_array_index (array, GdkAxisInfo, i);
1663 
1664       if (info->use == use)
1665         return info;
1666     }
1667 
1668   return NULL;
1669 }
1670 
1671 gboolean
_gdk_device_translate_window_coord(GdkDevice * device,GdkWindow * window,guint index_,gdouble value,gdouble * axis_value)1672 _gdk_device_translate_window_coord (GdkDevice *device,
1673                                     GdkWindow *window,
1674                                     guint      index_,
1675                                     gdouble    value,
1676                                     gdouble   *axis_value)
1677 {
1678   GdkAxisInfo axis_info;
1679   GdkAxisInfo *axis_info_x, *axis_info_y;
1680   gdouble device_width, device_height;
1681   gdouble x_offset, y_offset;
1682   gdouble x_scale, y_scale;
1683   gdouble x_min, y_min;
1684   gdouble x_resolution, y_resolution;
1685   gdouble device_aspect;
1686   gint window_width, window_height;
1687 
1688   if (index_ >= device->axes->len)
1689     return FALSE;
1690 
1691   axis_info = g_array_index (device->axes, GdkAxisInfo, index_);
1692 
1693   if (axis_info.use != GDK_AXIS_X &&
1694       axis_info.use != GDK_AXIS_Y)
1695     return FALSE;
1696 
1697   if (axis_info.use == GDK_AXIS_X)
1698     {
1699       axis_info_x = &axis_info;
1700       axis_info_y = find_axis_info (device->axes, GDK_AXIS_Y);
1701     }
1702   else
1703     {
1704       axis_info_x = find_axis_info (device->axes, GDK_AXIS_X);
1705       axis_info_y = &axis_info;
1706     }
1707 
1708   device_width = axis_info_x->max_value - axis_info_x->min_value;
1709   device_height = axis_info_y->max_value - axis_info_y->min_value;
1710 
1711 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
1712   if (device_width > 0)
1713     x_min = axis_info_x->min_value;
1714   else
1715     {
1716       device_width = gdk_screen_get_width (gdk_window_get_screen (window));
1717       x_min = 0;
1718     }
1719 
1720   if (device_height > 0)
1721     y_min = axis_info_y->min_value;
1722   else
1723     {
1724       device_height = gdk_screen_get_height (gdk_window_get_screen (window));
1725       y_min = 0;
1726     }
1727 G_GNUC_END_IGNORE_DEPRECATIONS
1728 
1729   window_width = gdk_window_get_width (window);
1730   window_height = gdk_window_get_height (window);
1731 
1732   x_resolution = axis_info_x->resolution;
1733   y_resolution = axis_info_y->resolution;
1734 
1735   /*
1736    * Some drivers incorrectly report the resolution of the device
1737    * as zero (in partiular linuxwacom < 0.5.3 with usb tablets).
1738    * This causes the device_aspect to become NaN and totally
1739    * breaks windowed mode.  If this is the case, the best we can
1740    * do is to assume the resolution is non-zero is equal in both
1741    * directions (which is true for many devices).  The absolute
1742    * value of the resolution doesn't matter since we only use the
1743    * ratio.
1744    */
1745   if (x_resolution == 0 || y_resolution == 0)
1746     {
1747       x_resolution = 1;
1748       y_resolution = 1;
1749     }
1750 
1751   device_aspect = (device_height * y_resolution) /
1752     (device_width * x_resolution);
1753 
1754   if (device_aspect * window_width >= window_height)
1755     {
1756       /* device taller than window */
1757       x_scale = window_width / device_width;
1758       y_scale = (x_scale * x_resolution) / y_resolution;
1759 
1760       x_offset = 0;
1761       y_offset = - (device_height * y_scale - window_height) / 2;
1762     }
1763   else
1764     {
1765       /* window taller than device */
1766       y_scale = window_height / device_height;
1767       x_scale = (y_scale * y_resolution) / x_resolution;
1768 
1769       y_offset = 0;
1770       x_offset = - (device_width * x_scale - window_width) / 2;
1771     }
1772 
1773   if (axis_value)
1774     {
1775       if (axis_info.use == GDK_AXIS_X)
1776         *axis_value = x_offset + x_scale * (value - x_min);
1777       else
1778         *axis_value = y_offset + y_scale * (value - y_min);
1779     }
1780 
1781   return TRUE;
1782 }
1783 
1784 gboolean
_gdk_device_translate_screen_coord(GdkDevice * device,GdkWindow * window,gdouble window_root_x,gdouble window_root_y,guint index_,gdouble value,gdouble * axis_value)1785 _gdk_device_translate_screen_coord (GdkDevice *device,
1786                                     GdkWindow *window,
1787                                     gdouble    window_root_x,
1788                                     gdouble    window_root_y,
1789                                     guint      index_,
1790                                     gdouble    value,
1791                                     gdouble   *axis_value)
1792 {
1793   GdkAxisInfo axis_info;
1794   gdouble axis_width, scale, offset;
1795 
1796   if (device->mode != GDK_MODE_SCREEN)
1797     return FALSE;
1798 
1799   if (index_ >= device->axes->len)
1800     return FALSE;
1801 
1802   axis_info = g_array_index (device->axes, GdkAxisInfo, index_);
1803 
1804   if (axis_info.use != GDK_AXIS_X &&
1805       axis_info.use != GDK_AXIS_Y)
1806     return FALSE;
1807 
1808   axis_width = axis_info.max_value - axis_info.min_value;
1809 
1810 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
1811   if (axis_info.use == GDK_AXIS_X)
1812     {
1813       if (axis_width > 0)
1814         scale = gdk_screen_get_width (gdk_window_get_screen (window)) / axis_width;
1815       else
1816         scale = 1;
1817 
1818       offset = - window_root_x - window->abs_x;
1819     }
1820   else
1821     {
1822       if (axis_width > 0)
1823         scale = gdk_screen_get_height (gdk_window_get_screen (window)) / axis_width;
1824       else
1825         scale = 1;
1826 
1827       offset = - window_root_y - window->abs_y;
1828     }
1829 G_GNUC_END_IGNORE_DEPRECATIONS
1830 
1831   if (axis_value)
1832     *axis_value = offset + scale * (value - axis_info.min_value);
1833 
1834   return TRUE;
1835 }
1836 
1837 gboolean
_gdk_device_translate_axis(GdkDevice * device,guint index_,gdouble value,gdouble * axis_value)1838 _gdk_device_translate_axis (GdkDevice *device,
1839                             guint      index_,
1840                             gdouble    value,
1841                             gdouble   *axis_value)
1842 {
1843   GdkAxisInfo axis_info;
1844   gdouble axis_width, out;
1845 
1846   if (index_ >= device->axes->len)
1847     return FALSE;
1848 
1849   axis_info = g_array_index (device->axes, GdkAxisInfo, index_);
1850 
1851   if (axis_info.use == GDK_AXIS_X ||
1852       axis_info.use == GDK_AXIS_Y)
1853     return FALSE;
1854 
1855   axis_width = axis_info.max_value - axis_info.min_value;
1856   out = (axis_info.max_axis * (value - axis_info.min_value) +
1857          axis_info.min_axis * (axis_info.max_value - value)) / axis_width;
1858 
1859   if (axis_value)
1860     *axis_value = out;
1861 
1862   return TRUE;
1863 }
1864 
1865 void
_gdk_device_query_state(GdkDevice * device,GdkWindow * window,GdkWindow ** root_window,GdkWindow ** child_window,gdouble * root_x,gdouble * root_y,gdouble * win_x,gdouble * win_y,GdkModifierType * mask)1866 _gdk_device_query_state (GdkDevice        *device,
1867                          GdkWindow        *window,
1868                          GdkWindow       **root_window,
1869                          GdkWindow       **child_window,
1870                          gdouble          *root_x,
1871                          gdouble          *root_y,
1872                          gdouble          *win_x,
1873                          gdouble          *win_y,
1874                          GdkModifierType  *mask)
1875 {
1876   GDK_DEVICE_GET_CLASS (device)->query_state (device,
1877                                               window,
1878                                               root_window,
1879                                               child_window,
1880                                               root_x,
1881                                               root_y,
1882                                               win_x,
1883                                               win_y,
1884                                               mask);
1885 }
1886 
1887 GdkWindow *
_gdk_device_window_at_position(GdkDevice * device,gdouble * win_x,gdouble * win_y,GdkModifierType * mask,gboolean get_toplevel)1888 _gdk_device_window_at_position (GdkDevice        *device,
1889                                 gdouble          *win_x,
1890                                 gdouble          *win_y,
1891                                 GdkModifierType  *mask,
1892                                 gboolean          get_toplevel)
1893 {
1894   return GDK_DEVICE_GET_CLASS (device)->window_at_position (device,
1895                                                             win_x,
1896                                                             win_y,
1897                                                             mask,
1898                                                             get_toplevel);
1899 }
1900 
1901 /**
1902  * gdk_device_get_last_event_window:
1903  * @device: a #GdkDevice, with a source other than %GDK_SOURCE_KEYBOARD
1904  *
1905  * Gets information about which window the given pointer device is in, based on events
1906  * that have been received so far from the display server. If another application
1907  * has a pointer grab, or this application has a grab with owner_events = %FALSE,
1908  * %NULL may be returned even if the pointer is physically over one of this
1909  * application's windows.
1910  *
1911  * Returns: (transfer none) (allow-none): the last window the device
1912  *
1913  * Since: 3.12
1914  */
1915 GdkWindow *
gdk_device_get_last_event_window(GdkDevice * device)1916 gdk_device_get_last_event_window (GdkDevice *device)
1917 {
1918   GdkDisplay *display;
1919   GdkPointerWindowInfo *info;
1920 
1921   g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
1922   g_return_val_if_fail (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD, NULL);
1923 
1924   display = gdk_device_get_display (device);
1925   info = _gdk_display_get_pointer_info (display, device);
1926 
1927   return info->window_under_pointer;
1928 }
1929 
1930 /**
1931  * gdk_device_get_vendor_id:
1932  * @device: a slave #GdkDevice
1933  *
1934  * Returns the vendor ID of this device, or %NULL if this information couldn't
1935  * be obtained. This ID is retrieved from the device, and is thus constant for
1936  * it.
1937  *
1938  * This function, together with gdk_device_get_product_id(), can be used to eg.
1939  * compose #GSettings paths to store settings for this device.
1940  *
1941  * |[<!-- language="C" -->
1942  *  static GSettings *
1943  *  get_device_settings (GdkDevice *device)
1944  *  {
1945  *    const gchar *vendor, *product;
1946  *    GSettings *settings;
1947  *    GdkDevice *device;
1948  *    gchar *path;
1949  *
1950  *    vendor = gdk_device_get_vendor_id (device);
1951  *    product = gdk_device_get_product_id (device);
1952  *
1953  *    path = g_strdup_printf ("/org/example/app/devices/%s:%s/", vendor, product);
1954  *    settings = g_settings_new_with_path (DEVICE_SCHEMA, path);
1955  *    g_free (path);
1956  *
1957  *    return settings;
1958  *  }
1959  * ]|
1960  *
1961  * Returns: (nullable): the vendor ID, or %NULL
1962  *
1963  * Since: 3.16
1964  */
1965 const gchar *
gdk_device_get_vendor_id(GdkDevice * device)1966 gdk_device_get_vendor_id (GdkDevice *device)
1967 {
1968   g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
1969   g_return_val_if_fail (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER, NULL);
1970 
1971   return device->vendor_id;
1972 }
1973 
1974 /**
1975  * gdk_device_get_product_id:
1976  * @device: a slave #GdkDevice
1977  *
1978  * Returns the product ID of this device, or %NULL if this information couldn't
1979  * be obtained. This ID is retrieved from the device, and is thus constant for
1980  * it. See gdk_device_get_vendor_id() for more information.
1981  *
1982  * Returns: (nullable): the product ID, or %NULL
1983  *
1984  * Since: 3.16
1985  */
1986 const gchar *
gdk_device_get_product_id(GdkDevice * device)1987 gdk_device_get_product_id (GdkDevice *device)
1988 {
1989   g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
1990   g_return_val_if_fail (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER, NULL);
1991 
1992   return device->product_id;
1993 }
1994 
1995 void
gdk_device_set_seat(GdkDevice * device,GdkSeat * seat)1996 gdk_device_set_seat (GdkDevice *device,
1997                      GdkSeat   *seat)
1998 {
1999   g_return_if_fail (GDK_IS_DEVICE (device));
2000   g_return_if_fail (!seat || GDK_IS_SEAT (seat));
2001 
2002   if (device->seat == seat)
2003     return;
2004 
2005   device->seat = seat;
2006   g_object_notify (G_OBJECT (device), "seat");
2007 }
2008 
2009 /**
2010  * gdk_device_get_seat:
2011  * @device: A #GdkDevice
2012  *
2013  * Returns the #GdkSeat the device belongs to.
2014  *
2015  * Returns: (transfer none): A #GdkSeat. This memory is owned by GTK+ and
2016  *          must not be freed.
2017  *
2018  * Since: 3.20
2019  **/
2020 GdkSeat *
gdk_device_get_seat(GdkDevice * device)2021 gdk_device_get_seat (GdkDevice *device)
2022 {
2023   g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
2024 
2025   return device->seat;
2026 }
2027 
2028 /**
2029  * gdk_device_get_axes:
2030  * @device: a #GdkDevice
2031  *
2032  * Returns the axes currently available on the device.
2033  *
2034  * Since: 3.22
2035  **/
2036 GdkAxisFlags
gdk_device_get_axes(GdkDevice * device)2037 gdk_device_get_axes (GdkDevice *device)
2038 {
2039   g_return_val_if_fail (GDK_IS_DEVICE (device), 0);
2040 
2041   return device->axis_flags;
2042 }
2043 
2044 void
gdk_device_update_tool(GdkDevice * device,GdkDeviceTool * tool)2045 gdk_device_update_tool (GdkDevice     *device,
2046                         GdkDeviceTool *tool)
2047 {
2048   g_return_if_fail (GDK_IS_DEVICE (device));
2049   g_return_if_fail (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER);
2050 
2051   if (g_set_object (&device->last_tool, tool))
2052     {
2053       g_object_notify (G_OBJECT (device), "tool");
2054       g_signal_emit (device, signals[TOOL_CHANGED], 0, tool);
2055     }
2056 }
2057 
2058 GdkInputMode
gdk_device_get_input_mode(GdkDevice * device)2059 gdk_device_get_input_mode (GdkDevice *device)
2060 {
2061   return device->mode;
2062 }
2063