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 "gdkx11devicemanager-core.h"
21 #include "gdkdevicemanagerprivate-core.h"
22 #ifdef XINPUT_2
23 #include "gdkx11devicemanager-xi2.h"
24 #endif
25 #include "gdkinternals.h"
26 #include "gdkprivate-x11.h"
27 
28 /* Defines for VCP/VCK, to be used too
29  * for the core protocol device manager
30  */
31 #define VIRTUAL_CORE_POINTER_ID 2
32 #define VIRTUAL_CORE_KEYBOARD_ID 3
33 
34 GdkDeviceManager *
_gdk_x11_device_manager_new(GdkDisplay * display)35 _gdk_x11_device_manager_new (GdkDisplay *display)
36 {
37   if (!g_getenv ("GDK_CORE_DEVICE_EVENTS"))
38     {
39 #ifdef XINPUT_2
40       int opcode, firstevent, firsterror;
41       Display *xdisplay;
42 
43       xdisplay = GDK_DISPLAY_XDISPLAY (display);
44 
45       if (XQueryExtension (xdisplay, "XInputExtension",
46                            &opcode, &firstevent, &firsterror))
47         {
48           int major, minor;
49 
50           major = 2;
51           minor = 4;
52 
53           if (!_gdk_disable_multidevice &&
54               XIQueryVersion (xdisplay, &major, &minor) != BadRequest)
55             {
56               GdkX11DeviceManagerXI2 *device_manager_xi2;
57 
58               GDK_NOTE (INPUT, g_message ("Creating XI2 (version %d.%d) device manager",
59                                           major, minor));
60 
61               device_manager_xi2 = g_object_new (GDK_TYPE_X11_DEVICE_MANAGER_XI2,
62                                                  "display", display,
63                                                  "opcode", opcode,
64                                                  "major", major,
65                                                  "minor", minor,
66                                                  NULL);
67 
68               return GDK_DEVICE_MANAGER (device_manager_xi2);
69             }
70         }
71 #endif /* XINPUT_2 */
72     }
73 
74   GDK_NOTE (INPUT, g_message ("Creating core device manager"));
75 
76   return g_object_new (GDK_TYPE_X11_DEVICE_MANAGER_CORE,
77                        "display", display,
78                        NULL);
79 }
80 
81 /**
82  * gdk_x11_device_manager_lookup:
83  * @device_manager: (type GdkX11DeviceManagerCore): a #GdkDeviceManager
84  * @device_id: a device ID, as understood by the XInput2 protocol
85  *
86  * Returns the #GdkDevice that wraps the given device ID.
87  *
88  * Returns: (transfer none) (allow-none) (type GdkX11DeviceCore): The #GdkDevice wrapping the device ID,
89  *          or %NULL if the given ID doesn’t currently represent a device.
90  *
91  * Since: 3.2
92  **/
93 GdkDevice *
gdk_x11_device_manager_lookup(GdkDeviceManager * device_manager,gint device_id)94 gdk_x11_device_manager_lookup (GdkDeviceManager *device_manager,
95 			       gint              device_id)
96 {
97   GdkDevice *device = NULL;
98 
99   g_return_val_if_fail (GDK_IS_DEVICE_MANAGER (device_manager), NULL);
100 
101 #ifdef XINPUT_2
102   if (GDK_IS_X11_DEVICE_MANAGER_XI2 (device_manager))
103     device = _gdk_x11_device_manager_xi2_lookup (GDK_X11_DEVICE_MANAGER_XI2 (device_manager),
104                                                  device_id);
105   else
106 #endif /* XINPUT_2 */
107     if (GDK_IS_X11_DEVICE_MANAGER_CORE (device_manager))
108       {
109         /* It is a core/xi1 device manager, we only map
110          * IDs 2 and 3, matching XI2's Virtual Core Pointer
111          * and Keyboard.
112          */
113         if (device_id == VIRTUAL_CORE_POINTER_ID)
114           device = GDK_X11_DEVICE_MANAGER_CORE (device_manager)->core_pointer;
115         else if (device_id == VIRTUAL_CORE_KEYBOARD_ID)
116           device = GDK_X11_DEVICE_MANAGER_CORE (device_manager)->core_keyboard;
117       }
118 
119   return device;
120 }
121 
122 /**
123  * gdk_x11_device_get_id:
124  * @device: (type GdkX11DeviceCore): a #GdkDevice
125  *
126  * Returns the device ID as seen by XInput2.
127  *
128  * > If gdk_disable_multidevice() has been called, this function
129  * > will respectively return 2/3 for the core pointer and keyboard,
130  * > (matching the IDs for the Virtual Core Pointer and Keyboard in
131  * > XInput 2), but calling this function on any slave devices (i.e.
132  * > those managed via XInput 1.x), will return 0.
133  *
134  * Returns: the XInput2 device ID.
135  *
136  * Since: 3.2
137  **/
138 gint
gdk_x11_device_get_id(GdkDevice * device)139 gdk_x11_device_get_id (GdkDevice *device)
140 {
141   gint device_id = 0;
142 
143   g_return_val_if_fail (GDK_IS_DEVICE (device), 0);
144 
145 #ifdef XINPUT_2
146   if (GDK_IS_X11_DEVICE_XI2 (device))
147     device_id = _gdk_x11_device_xi2_get_id (GDK_X11_DEVICE_XI2 (device));
148   else
149 #endif /* XINPUT_2 */
150     if (GDK_IS_X11_DEVICE_CORE (device))
151       {
152         if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
153           device_id = VIRTUAL_CORE_KEYBOARD_ID;
154         else
155           device_id = VIRTUAL_CORE_POINTER_ID;
156       }
157 
158   return device_id;
159 }
160