1# ----------------------------------------------------------------------------
2# pyglet
3# Copyright (c) 2006-2008 Alex Holkner
4# Copyright (c) 2008-2021 pyglet contributors
5# All rights reserved.
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions
9# are met:
10#
11#  * Redistributions of source code must retain the above copyright
12#    notice, this list of conditions and the following disclaimer.
13#  * Redistributions in binary form must reproduce the above copyright
14#    notice, this list of conditions and the following disclaimer in
15#    the documentation and/or other materials provided with the
16#    distribution.
17#  * Neither the name of pyglet nor the names of its
18#    contributors may be used to endorse or promote products
19#    derived from this software without specific prior written
20#    permission.
21#
22# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33# POSSIBILITY OF SUCH DAMAGE.
34# ----------------------------------------------------------------------------
35
36"""Joystick, tablet and USB HID device support.
37
38This module provides a unified interface to almost any input device, besides
39the regular mouse and keyboard support provided by
40:py:class:`~pyglet.window.Window`.  At the lowest
41level, :py:func:`get_devices` can be used to retrieve a list of all supported
42devices, including joysticks, tablets, space controllers, wheels, pedals, remote
43controls, keyboards and mice.  The set of returned devices varies greatly
44depending on the operating system (and, of course, what's plugged in).
45
46At this level pyglet does not try to interpret *what* a particular device is,
47merely what controls it provides.  A :py:class:`Control` can be either a button,
48whose value is either ``True`` or ``False``, or a relative or absolute-valued
49axis, whose value is a float.  Sometimes the name of a control can be provided
50(for example, ``x``, representing the horizontal axis of a joystick), but often
51not.  In these cases the device API may still be useful -- the user will have
52to be asked to press each button in turn or move each axis separately to
53identify them.
54
55Higher-level interfaces are provided for joysticks, tablets and the Apple
56remote control.  These devices can usually be identified by pyglet positively,
57and a base level of functionality for each one provided through a common
58interface.
59
60To use an input device:
61
621. Call :py:func:`get_devices`, :py:func:`get_apple_remote` or
63   :py:func:`get_joysticks`
64   to retrieve and identify the device.
652. For low-level devices (retrieved by :py:func:`get_devices`), query the
66   devices list of controls and determine which ones you are interested in. For
67   high-level interfaces the set of controls is provided by the interface.
683. Optionally attach event handlers to controls on the device.
694. Call :py:meth:`Device.open` to begin receiving events on the device.  You can
70   begin querying the control values after this time; they will be updated
71   asynchronously.
725. Call :py:meth:`Device.close` when you are finished with the device (not
73   needed if your application quits at this time).
74
75To use a tablet, follow the procedure above using :py:func:`get_tablets`, but
76note that no control list is available; instead, calling :py:meth:`Tablet.open`
77returns a :py:class:`TabletCanvas` onto which you should set your event
78handlers.
79
80.. versionadded:: 1.2
81
82"""
83
84import sys
85
86from .base import Device, Control, RelativeAxis, AbsoluteAxis, Button
87from .base import Joystick, AppleRemote, Tablet
88from .base import DeviceException, DeviceOpenException, DeviceExclusiveException
89
90_is_pyglet_doc_run = hasattr(sys, "is_pyglet_doc_run") and sys.is_pyglet_doc_run
91
92
93def get_apple_remote(display=None):
94    """Get the Apple remote control device.
95
96    The Apple remote is the small white 6-button remote control that
97    accompanies most recent Apple desktops and laptops.  The remote can only
98    be used with Mac OS X.
99
100    :Parameters:
101        display : `~pyglet.canvas.Display`
102            Currently ignored.
103
104    :rtype: AppleRemote
105    :return: The remote device, or `None` if the computer does not support it.
106    """
107    return None
108
109if _is_pyglet_doc_run:
110    def get_devices(display=None):
111        """Get a list of all attached input devices.
112
113        :Parameters:
114            display : `~pyglet.canvas.Display`
115                The display device to query for input devices.  Ignored on Mac
116                OS X and Windows.  On Linux, defaults to the default display
117                device.
118
119        :rtype: list of :py:class:`Device`
120        """
121
122    def get_joysticks(display=None):
123        """Get a list of attached joysticks.
124
125        :Parameters:
126            display : `~pyglet.canvas.Display`
127                The display device to query for input devices.  Ignored on Mac
128                OS X and Windows.  On Linux, defaults to the default display
129                device.
130
131        :rtype: list of :py:class:`Joystick`
132        """
133
134    def get_tablets(display=None):
135        """Get a list of tablets.
136
137        This function may return a valid tablet device even if one is not
138        attached (for example, it is not possible on Mac OS X to determine if
139        a tablet device is connected).  Despite returning a list of tablets,
140        pyglet does not currently support multiple tablets, and the behaviour
141        is undefined if more than one is attached.
142
143        :Parameters:
144            display : `~pyglet.canvas.Display`
145                The display device to query for input devices.  Ignored on Mac
146                OS X and Windows.  On Linux, defaults to the default display
147                device.
148
149        :rtype: list of :py:class:`Tablet`
150        """
151
152else:
153    def get_tablets(display=None):
154        return []
155
156    from pyglet import compat_platform
157
158    if compat_platform.startswith('linux'):
159        from .x11_xinput import get_devices as xinput_get_devices
160        from .x11_xinput_tablet import get_tablets
161        from .evdev import get_devices as evdev_get_devices
162        from .evdev import get_joysticks
163        def get_devices(display=None):
164            return (evdev_get_devices(display) +
165                    xinput_get_devices(display))
166    elif compat_platform in ('cygwin', 'win32'):
167        from .directinput import get_devices, get_joysticks
168        try:
169            from .wintab import get_tablets
170        except:
171            pass
172    elif compat_platform == 'darwin':
173        from .darwin_hid import get_devices, get_joysticks, get_apple_remote
174