1 /*
2  * This file is part of gtkD.
3  *
4  * gtkD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 3
7  * of the License, or (at your option) any later version, with
8  * some exceptions, please read the COPYING file.
9  *
10  * gtkD is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with gtkD; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 
20 // generated automatically - do not change
21 // find conversion definition on APILookup.txt
22 // implement new conversion functionalities on the wrap.utils pakage
23 
24 
25 module gdk.DeviceManager;
26 
27 private import gdk.Device;
28 private import gdk.Display;
29 private import glib.ListG;
30 private import gobject.ObjectG;
31 private import gobject.Signals;
32 private import gtkc.gdk;
33 public  import gtkc.gdktypes;
34 
35 
36 /**
37  * In addition to a single pointer and keyboard for user interface input,
38  * GDK contains support for a variety of input devices, including graphics
39  * tablets, touchscreens and multiple pointers/keyboards interacting
40  * simultaneously with the user interface. Such input devices often have
41  * additional features, such as sub-pixel positioning information and
42  * additional device-dependent information.
43  * 
44  * In order to query the device hierarchy and be aware of changes in the
45  * device hierarchy (such as virtual devices being created or removed, or
46  * physical devices being plugged or unplugged), GDK provides
47  * #GdkDeviceManager.
48  * 
49  * By default, and if the platform supports it, GDK is aware of multiple
50  * keyboard/pointer pairs and multitouch devices. This behavior can be
51  * changed by calling gdk_disable_multidevice() before gdk_display_open().
52  * There should rarely be a need to do that though, since GDK defaults
53  * to a compatibility mode in which it will emit just one enter/leave
54  * event pair for all devices on a window. To enable per-device
55  * enter/leave events and other multi-pointer interaction features,
56  * gdk_window_set_support_multidevice() must be called on
57  * #GdkWindows (or gtk_widget_set_support_multidevice() on widgets).
58  * window. See the gdk_window_set_support_multidevice() documentation
59  * for more information.
60  * 
61  * On X11, multi-device support is implemented through XInput 2.
62  * Unless gdk_disable_multidevice() is called, the XInput 2
63  * #GdkDeviceManager implementation will be used as the input source.
64  * Otherwise either the core or XInput 1 implementations will be used.
65  * 
66  * For simple applications that don’t have any special interest in
67  * input devices, the so-called “client pointer”
68  * provides a reasonable approximation to a simple setup with a single
69  * pointer and keyboard. The device that has been set as the client
70  * pointer can be accessed via gdk_device_manager_get_client_pointer().
71  * 
72  * Conceptually, in multidevice mode there are 2 device types. Virtual
73  * devices (or master devices) are represented by the pointer cursors
74  * and keyboard foci that are seen on the screen. Physical devices (or
75  * slave devices) represent the hardware that is controlling the virtual
76  * devices, and thus have no visible cursor on the screen.
77  * 
78  * Virtual devices are always paired, so there is a keyboard device for every
79  * pointer device. Associations between devices may be inspected through
80  * gdk_device_get_associated_device().
81  * 
82  * There may be several virtual devices, and several physical devices could
83  * be controlling each of these virtual devices. Physical devices may also
84  * be “floating”, which means they are not attached to any virtual device.
85  * 
86  * # Master and slave devices
87  * 
88  * |[
89  * carlos@sacarino:~$ xinput list
90  * ⎡ Virtual core pointer                          id=2    [master pointer  (3)]
91  * ⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
92  * ⎜   ↳ Wacom ISDv4 E6 Pen stylus                 id=10   [slave  pointer  (2)]
93  * ⎜   ↳ Wacom ISDv4 E6 Finger touch               id=11   [slave  pointer  (2)]
94  * ⎜   ↳ SynPS/2 Synaptics TouchPad                id=13   [slave  pointer  (2)]
95  * ⎜   ↳ TPPS/2 IBM TrackPoint                     id=14   [slave  pointer  (2)]
96  * ⎜   ↳ Wacom ISDv4 E6 Pen eraser                 id=16   [slave  pointer  (2)]
97  * ⎣ Virtual core keyboard                         id=3    [master keyboard (2)]
98  * ↳ Virtual core XTEST keyboard               id=5    [slave  keyboard (3)]
99  * ↳ Power Button                              id=6    [slave  keyboard (3)]
100  * ↳ Video Bus                                 id=7    [slave  keyboard (3)]
101  * ↳ Sleep Button                              id=8    [slave  keyboard (3)]
102  * ↳ Integrated Camera                         id=9    [slave  keyboard (3)]
103  * ↳ AT Translated Set 2 keyboard              id=12   [slave  keyboard (3)]
104  * ↳ ThinkPad Extra Buttons                    id=15   [slave  keyboard (3)]
105  * ]|
106  * 
107  * By default, GDK will automatically listen for events coming from all
108  * master devices, setting the #GdkDevice for all events coming from input
109  * devices. Events containing device information are #GDK_MOTION_NOTIFY,
110  * #GDK_BUTTON_PRESS, #GDK_2BUTTON_PRESS, #GDK_3BUTTON_PRESS,
111  * #GDK_BUTTON_RELEASE, #GDK_SCROLL, #GDK_KEY_PRESS, #GDK_KEY_RELEASE,
112  * #GDK_ENTER_NOTIFY, #GDK_LEAVE_NOTIFY, #GDK_FOCUS_CHANGE,
113  * #GDK_PROXIMITY_IN, #GDK_PROXIMITY_OUT, #GDK_DRAG_ENTER, #GDK_DRAG_LEAVE,
114  * #GDK_DRAG_MOTION, #GDK_DRAG_STATUS, #GDK_DROP_START, #GDK_DROP_FINISHED
115  * and #GDK_GRAB_BROKEN. When dealing with an event on a master device,
116  * it is possible to get the source (slave) device that the event originated
117  * from via gdk_event_get_source_device().
118  * 
119  * On a standard session, all physical devices are connected by default to
120  * the "Virtual Core Pointer/Keyboard" master devices, hence routing all events
121  * through these. This behavior is only modified by device grabs, where the
122  * slave device is temporarily detached for as long as the grab is held, and
123  * more permanently by user modifications to the device hierarchy.
124  * 
125  * On certain application specific setups, it may make sense
126  * to detach a physical device from its master pointer, and mapping it to
127  * an specific window. This can be achieved by the combination of
128  * gdk_device_grab() and gdk_device_set_mode().
129  * 
130  * In order to listen for events coming from devices
131  * other than a virtual device, gdk_window_set_device_events() must be
132  * called. Generally, this function can be used to modify the event mask
133  * for any given device.
134  * 
135  * Input devices may also provide additional information besides X/Y.
136  * For example, graphics tablets may also provide pressure and X/Y tilt
137  * information. This information is device-dependent, and may be
138  * queried through gdk_device_get_axis(). In multidevice mode, virtual
139  * devices will change axes in order to always represent the physical
140  * device that is routing events through it. Whenever the physical device
141  * changes, the #GdkDevice:n-axes property will be notified, and
142  * gdk_device_list_axes() will return the new device axes.
143  * 
144  * Devices may also have associated “keys” or
145  * macro buttons. Such keys can be globally set to map into normal X
146  * keyboard events. The mapping is set using gdk_device_set_key().
147  * 
148  * In GTK+ 3.20, a new #GdkSeat object has been introduced that
149  * supersedes #GdkDeviceManager and should be preferred in newly
150  * written code.
151  */
152 public class DeviceManager : ObjectG
153 {
154 	/** the main Gtk struct */
155 	protected GdkDeviceManager* gdkDeviceManager;
156 
157 	/** Get the main Gtk struct */
158 	public GdkDeviceManager* getDeviceManagerStruct()
159 	{
160 		return gdkDeviceManager;
161 	}
162 
163 	/** the main Gtk struct as a void* */
164 	protected override void* getStruct()
165 	{
166 		return cast(void*)gdkDeviceManager;
167 	}
168 
169 	protected override void setStruct(GObject* obj)
170 	{
171 		gdkDeviceManager = cast(GdkDeviceManager*)obj;
172 		super.setStruct(obj);
173 	}
174 
175 	/**
176 	 * Sets our main struct and passes it to the parent class.
177 	 */
178 	public this (GdkDeviceManager* gdkDeviceManager, bool ownedRef = false)
179 	{
180 		this.gdkDeviceManager = gdkDeviceManager;
181 		super(cast(GObject*)gdkDeviceManager, ownedRef);
182 	}
183 
184 
185 	/** */
186 	public static GType getType()
187 	{
188 		return gdk_device_manager_get_type();
189 	}
190 
191 	/**
192 	 * Returns the client pointer, that is, the master pointer that acts as the core pointer
193 	 * for this application. In X11, window managers may change this depending on the interaction
194 	 * pattern under the presence of several pointers.
195 	 *
196 	 * You should use this function seldomly, only in code that isn’t triggered by a #GdkEvent
197 	 * and there aren’t other means to get a meaningful #GdkDevice to operate on.
198 	 *
199 	 * Deprecated: Use gdk_seat_get_pointer() instead.
200 	 *
201 	 * Return: The client pointer. This memory is
202 	 *     owned by GDK and must not be freed or unreferenced.
203 	 *
204 	 * Since: 3.0
205 	 */
206 	public Device getClientPointer()
207 	{
208 		auto p = gdk_device_manager_get_client_pointer(gdkDeviceManager);
209 		
210 		if(p is null)
211 		{
212 			return null;
213 		}
214 		
215 		return ObjectG.getDObject!(Device)(cast(GdkDevice*) p);
216 	}
217 
218 	/**
219 	 * Gets the #GdkDisplay associated to @device_manager.
220 	 *
221 	 * Return: the #GdkDisplay to which
222 	 *     @device_manager is associated to, or #NULL. This memory is
223 	 *     owned by GDK and must not be freed or unreferenced.
224 	 *
225 	 * Since: 3.0
226 	 */
227 	public Display getDisplay()
228 	{
229 		auto p = gdk_device_manager_get_display(gdkDeviceManager);
230 		
231 		if(p is null)
232 		{
233 			return null;
234 		}
235 		
236 		return ObjectG.getDObject!(Display)(cast(GdkDisplay*) p);
237 	}
238 
239 	/**
240 	 * Returns the list of devices of type @type currently attached to
241 	 * @device_manager.
242 	 *
243 	 * Deprecated: , use gdk_seat_get_pointer(), gdk_seat_get_keyboard()
244 	 * and gdk_seat_get_slaves() instead.
245 	 *
246 	 * Params:
247 	 *     type = device type to get.
248 	 *
249 	 * Return: a list of
250 	 *     #GdkDevices. The returned list must be
251 	 *     freed with g_list_free (). The list elements are owned by
252 	 *     GTK+ and must not be freed or unreffed.
253 	 *
254 	 * Since: 3.0
255 	 */
256 	public ListG listDevices(GdkDeviceType type)
257 	{
258 		auto p = gdk_device_manager_list_devices(gdkDeviceManager, type);
259 		
260 		if(p is null)
261 		{
262 			return null;
263 		}
264 		
265 		return new ListG(cast(GList*) p);
266 	}
267 
268 	int[string] connectedSignals;
269 
270 	void delegate(Device, DeviceManager)[] onDeviceAddedListeners;
271 	/**
272 	 * The ::device-added signal is emitted either when a new master
273 	 * pointer is created, or when a slave (Hardware) input device
274 	 * is plugged in.
275 	 *
276 	 * Params:
277 	 *     device = the newly added #GdkDevice.
278 	 */
279 	void addOnDeviceAdded(void delegate(Device, DeviceManager) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
280 	{
281 		if ( "device-added" !in connectedSignals )
282 		{
283 			Signals.connectData(
284 				this,
285 				"device-added",
286 				cast(GCallback)&callBackDeviceAdded,
287 				cast(void*)this,
288 				null,
289 				connectFlags);
290 			connectedSignals["device-added"] = 1;
291 		}
292 		onDeviceAddedListeners ~= dlg;
293 	}
294 	extern(C) static void callBackDeviceAdded(GdkDeviceManager* devicemanagerStruct, GdkDevice* device, DeviceManager _devicemanager)
295 	{
296 		foreach ( void delegate(Device, DeviceManager) dlg; _devicemanager.onDeviceAddedListeners )
297 		{
298 			dlg(ObjectG.getDObject!(Device)(device), _devicemanager);
299 		}
300 	}
301 
302 	void delegate(Device, DeviceManager)[] onDeviceChangedListeners;
303 	/**
304 	 * The ::device-changed signal is emitted whenever a device
305 	 * has changed in the hierarchy, either slave devices being
306 	 * disconnected from their master device or connected to
307 	 * another one, or master devices being added or removed
308 	 * a slave device.
309 	 *
310 	 * If a slave device is detached from all master devices
311 	 * (gdk_device_get_associated_device() returns %NULL), its
312 	 * #GdkDeviceType will change to %GDK_DEVICE_TYPE_FLOATING,
313 	 * if it's attached, it will change to %GDK_DEVICE_TYPE_SLAVE.
314 	 *
315 	 * Params:
316 	 *     device = the #GdkDevice that changed.
317 	 */
318 	void addOnDeviceChanged(void delegate(Device, DeviceManager) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
319 	{
320 		if ( "device-changed" !in connectedSignals )
321 		{
322 			Signals.connectData(
323 				this,
324 				"device-changed",
325 				cast(GCallback)&callBackDeviceChanged,
326 				cast(void*)this,
327 				null,
328 				connectFlags);
329 			connectedSignals["device-changed"] = 1;
330 		}
331 		onDeviceChangedListeners ~= dlg;
332 	}
333 	extern(C) static void callBackDeviceChanged(GdkDeviceManager* devicemanagerStruct, GdkDevice* device, DeviceManager _devicemanager)
334 	{
335 		foreach ( void delegate(Device, DeviceManager) dlg; _devicemanager.onDeviceChangedListeners )
336 		{
337 			dlg(ObjectG.getDObject!(Device)(device), _devicemanager);
338 		}
339 	}
340 
341 	void delegate(Device, DeviceManager)[] onDeviceRemovedListeners;
342 	/**
343 	 * The ::device-removed signal is emitted either when a master
344 	 * pointer is removed, or when a slave (Hardware) input device
345 	 * is unplugged.
346 	 *
347 	 * Params:
348 	 *     device = the just removed #GdkDevice.
349 	 */
350 	void addOnDeviceRemoved(void delegate(Device, DeviceManager) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
351 	{
352 		if ( "device-removed" !in connectedSignals )
353 		{
354 			Signals.connectData(
355 				this,
356 				"device-removed",
357 				cast(GCallback)&callBackDeviceRemoved,
358 				cast(void*)this,
359 				null,
360 				connectFlags);
361 			connectedSignals["device-removed"] = 1;
362 		}
363 		onDeviceRemovedListeners ~= dlg;
364 	}
365 	extern(C) static void callBackDeviceRemoved(GdkDeviceManager* devicemanagerStruct, GdkDevice* device, DeviceManager _devicemanager)
366 	{
367 		foreach ( void delegate(Device, DeviceManager) dlg; _devicemanager.onDeviceRemovedListeners )
368 		{
369 			dlg(ObjectG.getDObject!(Device)(device), _devicemanager);
370 		}
371 	}
372 
373 	/**
374 	 * Disables multidevice support in GDK. This call must happen prior
375 	 * to gdk_display_open(), gtk_init(), gtk_init_with_args() or
376 	 * gtk_init_check() in order to take effect.
377 	 *
378 	 * Most common GTK+ applications won’t ever need to call this. Only
379 	 * applications that do mixed GDK/Xlib calls could want to disable
380 	 * multidevice support if such Xlib code deals with input devices in
381 	 * any way and doesn’t observe the presence of XInput 2.
382 	 *
383 	 * Since: 3.0
384 	 */
385 	public static void disableMultidevice()
386 	{
387 		gdk_disable_multidevice();
388 	}
389 }