1 // Copyright 2005-2019 The Mumble Developers. All rights reserved.
2 // Use of this source code is governed by a BSD-style license
3 // that can be found in the LICENSE file at the root of the
4 // Mumble source tree or at <https://www.mumble.info/LICENSE>.
5
6 #include "mumble_pch.hpp"
7
8 #include "XboxInput.h"
9
10 const QUuid XboxInput::s_XboxInputGuid = QUuid(QString::fromLatin1("ca3937e3-640c-4d9e-9ef3-903f8b4fbcab"));
11
XboxInput()12 XboxInput::XboxInput()
13 : GetState(NULL)
14 , m_getStateFunc(NULL)
15 , m_getStateExFunc(NULL)
16 , m_xinputlib(NULL)
17 , m_valid(false) {
18
19 // Load the most suitable XInput DLL available.
20 //
21 // We prefer 1_4 and 1_3 over the others because they provide
22 // XInputGetStateEx(), which allows us to query the state of
23 // the guide button.
24 //
25 // See https://msdn.microsoft.com/en-us/library/windows/desktop/hh405051(v=vs.85).aspx
26 // for more information.
27 QStringList alternatives;
28 alternatives << QLatin1String("XInput1_4.dll");
29 alternatives << QLatin1String("xinput1_3.dll");
30 alternatives << QLatin1String("XInput9_1_0.dll");
31 alternatives << QLatin1String("xinput1_2.dll");
32 alternatives << QLatin1String("xinput1_1.dll");
33
34 foreach(const QString &lib, alternatives) {
35 m_xinputlib = LoadLibraryW(reinterpret_cast<const wchar_t *>(lib.utf16()));
36 if (m_xinputlib != NULL) {
37 qWarning("XboxInput: using XInput DLL '%s'", qPrintable(lib));
38 m_valid = true;
39 break;
40 }
41 }
42
43 if (!m_valid) {
44 qWarning("XboxInput: no valid XInput DLL was found on the system.");
45 return;
46 }
47
48 m_getStateFunc = reinterpret_cast<XboxInputGetStateFunc>(GetProcAddress(m_xinputlib, "XInputGetState"));
49 // Undocumented XInputGetStateEx -- ordinal 100. It is available in XInput 1.3 and greater.
50 // It provides access to the state of the guide button.
51 // For reference, see SDL's XInput support: http://www.libsdl.org/tmp/SDL/src/core/windows/SDL_xinput.c
52 m_getStateExFunc = reinterpret_cast<XboxInputGetStateFunc>(GetProcAddress(m_xinputlib, (char *)100));
53
54 if (m_getStateExFunc != NULL) {
55 GetState = m_getStateExFunc;
56 qWarning("XboxInput: using XInputGetStateEx() as querying function.");
57 } else if (m_getStateFunc != NULL) {
58 GetState = m_getStateFunc;
59 qWarning("XboxInput: using XInputGetState() as querying function.");
60 } else {
61 m_valid = false;
62 qWarning("XboxInput: no valid querying function found.");
63 }
64 }
65
~XboxInput()66 XboxInput::~XboxInput() {
67 if (m_xinputlib) {
68 FreeLibrary(m_xinputlib);
69 }
70 }
71
isValid() const72 bool XboxInput::isValid() const {
73 return m_valid;
74 }
75