Skip to content

Commit 7ed8b01

Browse files
committed
Merge branch 'input-overhaul'
2 parents aa750f4 + f852077 commit 7ed8b01

File tree

138 files changed

+10221
-1911
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

138 files changed

+10221
-1911
lines changed

direct/src/showbase/ShowBase.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ def __init__(self, fStartDirect = True, windowType = None):
170170
self.trackball = None
171171
self.texmem = None
172172
self.showVertices = None
173+
self.deviceButtonThrowers = []
173174

174175
## This is a NodePath pointing to the Camera object set up for the 3D scene.
175176
## This is usually a child of self.camera.
@@ -294,6 +295,7 @@ def __init__(self, fStartDirect = True, windowType = None):
294295
## The global job manager, as imported from JobManagerGlobal.
295296
self.jobMgr = jobMgr
296297

298+
297299
## Particle manager
298300
self.particleMgr = None
299301
self.particleMgrEnabled = 0
@@ -303,6 +305,11 @@ def __init__(self, fStartDirect = True, windowType = None):
303305
self.physicsMgrEnabled = 0
304306
self.physicsMgrAngular = 0
305307

308+
## This is the global input device manager, which keeps track of
309+
## connected input devices.
310+
self.devices = InputDeviceManager.getGlobalPtr()
311+
self.__inputDeviceNodes = {}
312+
306313
self.createStats()
307314

308315
self.AppHasAudioFocus = 1
@@ -1670,6 +1677,57 @@ def getMeta(self):
16701677
return self.mouseWatcherNode.getModifierButtons().isDown(
16711678
KeyboardButton.meta())
16721679

1680+
def attachInputDevice(self, device, prefix=None):
1681+
"""
1682+
This function attaches an input device to the data graph, which will
1683+
cause the device to be polled and generate events. If a prefix is
1684+
given and not None, it is used to prefix events generated by this
1685+
device, separated by a hyphen.
1686+
1687+
If you call this, you should consider calling detachInputDevice when
1688+
you are done with the device or when it is disconnected.
1689+
"""
1690+
1691+
# Protect against the same device being attached multiple times.
1692+
assert device not in self.__inputDeviceNodes
1693+
1694+
idn = self.dataRoot.attachNewNode(InputDeviceNode(device, device.name))
1695+
1696+
# Setup the button thrower to generate events for the device.
1697+
bt = idn.attachNewNode(ButtonThrower(device.name))
1698+
if prefix is not None:
1699+
bt.node().setPrefix(prefix + '-')
1700+
1701+
assert self.notify.debug("Attached input device {0} with prefix {1}".format(device, prefix))
1702+
self.__inputDeviceNodes[device] = idn
1703+
self.deviceButtonThrowers.append(bt)
1704+
1705+
def detachInputDevice(self, device):
1706+
"""
1707+
This should be called after attaching an input device using
1708+
attachInputDevice and the device is disconnected or you no longer wish
1709+
to keep polling this device for events.
1710+
1711+
You do not strictly need to call this if you expect the device to be
1712+
reconnected (but be careful that you don't reattach it).
1713+
"""
1714+
1715+
if device not in self.__inputDeviceNodes:
1716+
assert device in self.__inputDeviceNodes
1717+
return
1718+
1719+
assert self.notify.debug("Detached device {0}".format(device.name))
1720+
1721+
# Remove the ButtonThrower from the deviceButtonThrowers list.
1722+
idn = self.__inputDeviceNodes[device]
1723+
for bt in self.deviceButtonThrowers:
1724+
if idn.isAncestorOf(bt):
1725+
self.deviceButtonThrowers.remove(bt)
1726+
break
1727+
1728+
idn.removeNode()
1729+
del self.__inputDeviceNodes[device]
1730+
16731731
def addAngularIntegrator(self):
16741732
if not self.physicsMgrAngular:
16751733
physics = importlib.import_module('panda3d.physics')
@@ -1859,6 +1917,9 @@ def __resetPrevTransform(self, state):
18591917
return Task.cont
18601918

18611919
def __dataLoop(self, state):
1920+
# Check if there were newly connected devices.
1921+
self.devices.update()
1922+
18621923
# traverse the data graph. This reads all the control
18631924
# inputs (from the mouse and keyboard, for instance) and also
18641925
# directly acts upon them (for instance, to move the avatar).
@@ -3074,6 +3135,8 @@ def run(self):
30743135
setup_mouse = setupMouse
30753136
setup_mouse_cb = setupMouseCB
30763137
enable_software_mouse_pointer = enableSoftwareMousePointer
3138+
detach_input_device = detachInputDevice
3139+
attach_input_device = attachInputDevice
30773140
add_angular_integrator = addAngularIntegrator
30783141
enable_particles = enableParticles
30793142
disable_particles = disableParticles

dtool/src/parser-inc/XInput.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
typedef struct _XINPUT_STATE XINPUT_STATE, *PXINPUT_STATE;
2+
typedef struct _XINPUT_CAPABILITIES XINPUT_CAPABILITIES, *PXINPUT_CAPABILITIES;
3+
typedef struct _XINPUT_VIBRATION XINPUT_VIBRATION, *PXINPUT_VIBRATION;
4+
typedef struct _XINPUT_GAMEPAD XINPUT_GAMEPAD, *PXINPUT_GAMEPAD;
5+
typedef struct _XINPUT_KEYSTROKE XINPUT_KEYSTROKE, *PXINPUT_KEYSTROKE;

dtool/src/parser-inc/windows.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,10 @@ typedef unsigned long ULONG_PTR;
3838
// http://msdn.microsoft.com/en-us/library/cc230309.aspx
3939
typedef bool BOOL;
4040
typedef unsigned long DWORD;
41+
typedef unsigned short WORD;
4142
typedef long LONG;
4243
typedef long UINT;
44+
typedef unsigned char BYTE;
4345
typedef unsigned long ULONG;
4446
typedef long long LONGLONG;
4547
typedef long HRESULT;

makepanda/makepanda.py

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,7 @@ def parseopts(args):
616616
LibName("WINGDI", "gdi32.lib")
617617
LibName("ADVAPI", "advapi32.lib")
618618
LibName("IPHLPAPI", "iphlpapi.lib")
619+
LibName("SETUPAPI", "setupapi.lib")
619620
LibName("GL", "opengl32.lib")
620621
LibName("GLES", "libgles_cm.lib")
621622
LibName("GLES2", "libGLESv2.lib")
@@ -2440,6 +2441,7 @@ def WriteConfigSettings():
24402441
dtool_config["HAVE_GLX"] = 'UNDEF'
24412442
dtool_config["IS_LINUX"] = 'UNDEF'
24422443
dtool_config["HAVE_VIDEO4LINUX"] = 'UNDEF'
2444+
dtool_config["PHAVE_LINUX_INPUT_H"] = 'UNDEF'
24432445
dtool_config["IS_OSX"] = '1'
24442446
# 10.4 had a broken ucontext implementation
24452447
if int(platform.mac_ver()[0][3]) <= 4:
@@ -3867,6 +3869,34 @@ def get_config_express():
38673869
TargetAdd('libp3cull.in', opts=OPTS, input=IGATEFILES)
38683870
TargetAdd('libp3cull.in', opts=['IMOD:panda3d.core', 'ILIB:libp3cull', 'SRCDIR:panda/src/cull'])
38693871

3872+
#
3873+
# DIRECTORY: panda/src/dgraph/
3874+
#
3875+
3876+
if (not RUNTIME):
3877+
OPTS=['DIR:panda/src/dgraph', 'BUILDING:PANDA']
3878+
TargetAdd('p3dgraph_composite1.obj', opts=OPTS, input='p3dgraph_composite1.cxx')
3879+
TargetAdd('p3dgraph_composite2.obj', opts=OPTS, input='p3dgraph_composite2.cxx')
3880+
3881+
OPTS=['DIR:panda/src/dgraph']
3882+
IGATEFILES=GetDirectoryContents('panda/src/dgraph', ["*.h", "*_composite*.cxx"])
3883+
TargetAdd('libp3dgraph.in', opts=OPTS, input=IGATEFILES)
3884+
TargetAdd('libp3dgraph.in', opts=['IMOD:panda3d.core', 'ILIB:libp3dgraph', 'SRCDIR:panda/src/dgraph'])
3885+
3886+
#
3887+
# DIRECTORY: panda/src/device/
3888+
#
3889+
3890+
if (not RUNTIME):
3891+
OPTS=['DIR:panda/src/device', 'BUILDING:PANDA']
3892+
TargetAdd('p3device_composite1.obj', opts=OPTS, input='p3device_composite1.cxx')
3893+
TargetAdd('p3device_composite2.obj', opts=OPTS, input='p3device_composite2.cxx')
3894+
3895+
OPTS=['DIR:panda/src/device']
3896+
IGATEFILES=GetDirectoryContents('panda/src/device', ["*.h", "*_composite*.cxx"])
3897+
TargetAdd('libp3device.in', opts=OPTS, input=IGATEFILES)
3898+
TargetAdd('libp3device.in', opts=['IMOD:panda3d.core', 'ILIB:libp3device', 'SRCDIR:panda/src/device'])
3899+
38703900
#
38713901
# DIRECTORY: panda/src/display/
38723902
#
@@ -3919,34 +3949,6 @@ def get_config_express():
39193949
TargetAdd('libp3char.in', opts=OPTS, input=IGATEFILES)
39203950
TargetAdd('libp3char.in', opts=['IMOD:panda3d.core', 'ILIB:libp3char', 'SRCDIR:panda/src/char'])
39213951

3922-
#
3923-
# DIRECTORY: panda/src/dgraph/
3924-
#
3925-
3926-
if (not RUNTIME):
3927-
OPTS=['DIR:panda/src/dgraph', 'BUILDING:PANDA']
3928-
TargetAdd('p3dgraph_composite1.obj', opts=OPTS, input='p3dgraph_composite1.cxx')
3929-
TargetAdd('p3dgraph_composite2.obj', opts=OPTS, input='p3dgraph_composite2.cxx')
3930-
3931-
OPTS=['DIR:panda/src/dgraph']
3932-
IGATEFILES=GetDirectoryContents('panda/src/dgraph', ["*.h", "*_composite*.cxx"])
3933-
TargetAdd('libp3dgraph.in', opts=OPTS, input=IGATEFILES)
3934-
TargetAdd('libp3dgraph.in', opts=['IMOD:panda3d.core', 'ILIB:libp3dgraph', 'SRCDIR:panda/src/dgraph'])
3935-
3936-
#
3937-
# DIRECTORY: panda/src/device/
3938-
#
3939-
3940-
if (not RUNTIME):
3941-
OPTS=['DIR:panda/src/device', 'BUILDING:PANDA']
3942-
TargetAdd('p3device_composite1.obj', opts=OPTS, input='p3device_composite1.cxx')
3943-
TargetAdd('p3device_composite2.obj', opts=OPTS, input='p3device_composite2.cxx')
3944-
3945-
OPTS=['DIR:panda/src/device']
3946-
IGATEFILES=GetDirectoryContents('panda/src/device', ["*.h", "*_composite*.cxx"])
3947-
TargetAdd('libp3device.in', opts=OPTS, input=IGATEFILES)
3948-
TargetAdd('libp3device.in', opts=['IMOD:panda3d.core', 'ILIB:libp3device', 'SRCDIR:panda/src/device'])
3949-
39503952
#
39513953
# DIRECTORY: panda/src/pnmtext/
39523954
#
@@ -4111,7 +4113,8 @@ def get_config_express():
41114113
if (not RUNTIME):
41124114
OPTS=['DIR:panda/metalibs/panda', 'BUILDING:PANDA', 'JPEG', 'PNG', 'HARFBUZZ',
41134115
'TIFF', 'OPENEXR', 'ZLIB', 'OPENSSL', 'FREETYPE', 'FFTW', 'ADVAPI', 'WINSOCK2',
4114-
'SQUISH', 'NVIDIACG', 'VORBIS', 'OPUS', 'WINUSER', 'WINMM', 'WINGDI', 'IPHLPAPI']
4116+
'SQUISH', 'NVIDIACG', 'VORBIS', 'OPUS', 'WINUSER', 'WINMM', 'WINGDI', 'IPHLPAPI',
4117+
'SETUPAPI']
41154118

41164119
TargetAdd('panda_panda.obj', opts=OPTS, input='panda.cxx')
41174120

panda/src/cocoadisplay/cocoaGraphicsWindow.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ class CocoaGraphicsWindow : public GraphicsWindow {
8989
NSUInteger _modifier_keys;
9090
UInt32 _dead_key_state;
9191
CGDirectDisplayID _display;
92+
PT(GraphicsWindowInputDevice) _input;
9293
bool _mouse_hidden;
9394
bool _context_needs_update;
9495

panda/src/cocoadisplay/cocoaGraphicsWindow.mm

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,10 @@
9999
[NSApp finishLaunching];
100100
}
101101

102-
GraphicsWindowInputDevice device =
102+
PT(GraphicsWindowInputDevice) device =
103103
GraphicsWindowInputDevice::pointer_and_keyboard(this, "keyboard_mouse");
104-
add_input_device(device);
104+
_input_devices.push_back(device.p());
105+
_input = std::move(device);
105106

106107
CocoaGraphicsPipe *cocoa_pipe;
107108
DCAST_INTO_V(cocoa_pipe, _pipe);
@@ -981,7 +982,7 @@
981982

982983
if (properties.has_cursor_hidden()) {
983984
if (properties.get_cursor_hidden() != _properties.get_cursor_hidden()) {
984-
if (properties.get_cursor_hidden() && _input_devices[0].get_pointer().get_in_window()) {
985+
if (properties.get_cursor_hidden() && _input->get_pointer().get_in_window()) {
985986
[NSCursor hide];
986987
_mouse_hidden = true;
987988
} else if (_mouse_hidden) {
@@ -1558,7 +1559,7 @@
15581559
// flaws are: - OS eats unmodified F11, F12, scroll lock, pause - no up
15591560
// events for caps lock - no robust way to distinguish updown for modkeys
15601561
if ([event type] == NSKeyUp) {
1561-
_input_devices[0].raw_button_up(raw_button);
1562+
_input->raw_button_up(raw_button);
15621563

15631564
} else if ([event type] == NSFlagsChanged) {
15641565
bool down = false;
@@ -1580,15 +1581,15 @@
15801581
down = (modifierFlags & 0x0010);
15811582
} else if (raw_button == KeyboardButton::caps_lock()) {
15821583
// Emulate down-up, annoying hack!
1583-
_input_devices[0].raw_button_down(raw_button);
1584+
_input->raw_button_down(raw_button);
15841585
}
15851586
if (down) {
1586-
_input_devices[0].raw_button_down(raw_button);
1587+
_input->raw_button_down(raw_button);
15871588
} else {
1588-
_input_devices[0].raw_button_up(raw_button);
1589+
_input->raw_button_up(raw_button);
15891590
}
15901591
} else if (![event isARepeat]) {
1591-
_input_devices[0].raw_button_down(raw_button);
1592+
_input->raw_button_down(raw_button);
15921593
}
15931594
}
15941595

@@ -1622,7 +1623,7 @@
16221623
}
16231624
cocoadisplay_cat.spam(false) << "\n";
16241625
}
1625-
_input_devices[0].keystroke(c);
1626+
_input->keystroke(c);
16261627
}
16271628
}
16281629

@@ -1634,6 +1635,7 @@
16341635
unichar c = [str characterAtIndex: 0];
16351636

16361637
ButtonHandle button = map_key(c);
1638+
16371639
if (button == ButtonHandle::none()) {
16381640
// That done, continue trying to find out the button handle.
16391641
if ([str canBeConvertedToEncoding: NSASCIIStringEncoding]) {
@@ -1659,9 +1661,9 @@
16591661

16601662
// Let's get it off our chest.
16611663
if ([event type] == NSKeyUp) {
1662-
_input_devices[0].button_up(button);
1664+
_input->button_up(button);
16631665
} else {
1664-
_input_devices[0].button_down(button);
1666+
_input->button_down(button);
16651667
}
16661668
}
16671669

@@ -1672,9 +1674,9 @@
16721674
handle_modifier(NSUInteger modifierFlags, NSUInteger mask, ButtonHandle button) {
16731675
if ((modifierFlags ^ _modifier_keys) & mask) {
16741676
if (modifierFlags & mask) {
1675-
_input_devices[0].button_down(button);
1677+
_input->button_down(button);
16761678
} else {
1677-
_input_devices[0].button_up(button);
1679+
_input->button_up(button);
16781680
}
16791681
}
16801682
}
@@ -1686,14 +1688,14 @@
16861688
void CocoaGraphicsWindow::
16871689
handle_mouse_button_event(int button, bool down) {
16881690
if (down) {
1689-
_input_devices[0].button_down(MouseButton::button(button));
1691+
_input->button_down(MouseButton::button(button));
16901692

16911693
#ifndef NDEBUG
16921694
cocoadisplay_cat.spam()
16931695
<< "Mouse button " << button << " down\n";
16941696
#endif
16951697
} else {
1696-
_input_devices[0].button_up(MouseButton::button(button));
1698+
_input->button_up(MouseButton::button(button));
16971699

16981700
#ifndef NDEBUG
16991701
cocoadisplay_cat.spam()
@@ -1712,7 +1714,7 @@
17121714

17131715
if (absolute) {
17141716
if (cocoadisplay_cat.is_spam()) {
1715-
if (in_window != _input_devices[0].get_pointer().get_in_window()) {
1717+
if (in_window != _input->get_pointer().get_in_window()) {
17161718
if (in_window) {
17171719
cocoadisplay_cat.spam() << "Mouse pointer entered window\n";
17181720
} else {
@@ -1727,7 +1729,7 @@
17271729

17281730
} else {
17291731
// We received deltas, so add it to the current mouse position.
1730-
MouseData md = _input_devices[0].get_pointer();
1732+
MouseData md = _input->get_pointer();
17311733
nx = md.get_x() + x;
17321734
ny = md.get_y() + y;
17331735
}
@@ -1753,8 +1755,11 @@
17531755
}
17541756
}
17551757

1756-
_input_devices[0].set_pointer(in_window, nx, ny,
1757-
ClockObject::get_global_clock()->get_frame_time());
1758+
if (in_window) {
1759+
_input->set_pointer_in_window(nx, ny);
1760+
} else {
1761+
_input->set_pointer_out_of_window();
1762+
}
17581763

17591764
if (in_window != _mouse_hidden && _properties.get_cursor_hidden()) {
17601765
// Hide the cursor if the mouse enters the window, and unhide it when the
@@ -1777,20 +1782,20 @@
17771782
<< "Wheel delta " << x << ", " << y << "\n";
17781783

17791784
if (y > 0.0) {
1780-
_input_devices[0].button_down(MouseButton::wheel_up());
1781-
_input_devices[0].button_up(MouseButton::wheel_up());
1785+
_input->button_down(MouseButton::wheel_up());
1786+
_input->button_up(MouseButton::wheel_up());
17821787
} else if (y < 0.0) {
1783-
_input_devices[0].button_down(MouseButton::wheel_down());
1784-
_input_devices[0].button_up(MouseButton::wheel_down());
1788+
_input->button_down(MouseButton::wheel_down());
1789+
_input->button_up(MouseButton::wheel_down());
17851790
}
17861791

17871792
// TODO: check if this is correct, I don't own a MacBook
17881793
if (x > 0.0) {
1789-
_input_devices[0].button_down(MouseButton::wheel_right());
1790-
_input_devices[0].button_up(MouseButton::wheel_right());
1794+
_input->button_down(MouseButton::wheel_right());
1795+
_input->button_up(MouseButton::wheel_right());
17911796
} else if (x < 0.0) {
1792-
_input_devices[0].button_down(MouseButton::wheel_left());
1793-
_input_devices[0].button_up(MouseButton::wheel_left());
1797+
_input->button_down(MouseButton::wheel_left());
1798+
_input->button_up(MouseButton::wheel_left());
17941799
}
17951800
}
17961801

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy