From b34d2618e30456d5984dc92132b28a5c59483bd0 Mon Sep 17 00:00:00 2001 From: Aleksandar Stojiljkovic Date: Mon, 25 Jan 2016 15:17:26 +0200 Subject: [PATCH] XWALK-4992 [windows] App does not support gamepad While chromium is bundling xinput1_3.dll from DirectX redist, using whatever platform suports. Logic about what dll is in use for different platforms is copied from Xinput.h. In order to target all of the Windows versions with the same binary, chosen to keep dynamic linking approach. Otherwise, there would be a problem with XInputEnable not available in xinput dll before Windows8 and deprecated on Windows 10. Snippet from \Windows Kits\10\Include\10.0.10586.0\um\Xinput.h: \#if(_WIN32_WINNT >= _WIN32_WINNT_WIN8) \#define XINPUT_DLL_A "xinput1_4.dll" \#define XINPUT_DLL_W L"xinput1_4.dll" \#else \#define XINPUT_DLL_A "xinput9_1_0.dll" \#define XINPUT_DLL_W L"xinput9_1_0.dll" \#endif For detailed information on Windows library loading and search path priorities, check https://msdn.microsoft.com documentation on LoadLibrary(). Upstreaming the patch planned, too. --- .../installer/mini_installer/chrome.release | 1 - chrome/tools/build/win/FILES.cfg | 5 ---- .../gamepad_platform_data_fetcher_win.cc | 23 ++++++++++++++---- .../gamepad_platform_data_fetcher_win.h | 9 ++++--- content/content_common.gypi | 24 ------------------- tools/checkbins/checkbins.py | 3 +-- 6 files changed, 23 insertions(+), 42 deletions(-) diff --git a/chrome/installer/mini_installer/chrome.release b/chrome/installer/mini_installer/chrome.release index 34fd53e873c23..5adef6b108379 100644 --- a/chrome/installer/mini_installer/chrome.release +++ b/chrome/installer/mini_installer/chrome.release @@ -39,7 +39,6 @@ natives_blob.bin: %(VersionDir)s\ resources.pak: %(VersionDir)s\ snapshot_blob.bin: %(VersionDir)s\ syzyasan_rtl.dll: %(VersionDir)s\ -xinput1_3.dll: %(VersionDir)s\ # # Sub directories living in the version dir # diff --git a/chrome/tools/build/win/FILES.cfg b/chrome/tools/build/win/FILES.cfg index 7807d426c666a..da6fa1bc979e2 100644 --- a/chrome/tools/build/win/FILES.cfg +++ b/chrome/tools/build/win/FILES.cfg @@ -382,11 +382,6 @@ FILES = [ 'buildtype': ['dev', 'official'], 'filegroup': ['default', 'symsrc'], }, - # XInput files: - { - 'filename': 'xinput1_3.dll', - 'buildtype': ['dev', 'official'], - }, # Native Client plugin files: { 'filename': 'nacl_irt_x86_32.nexe', diff --git a/content/browser/gamepad/gamepad_platform_data_fetcher_win.cc b/content/browser/gamepad/gamepad_platform_data_fetcher_win.cc index 4882efbf62fdf..de1dc704c7aa2 100644 --- a/content/browser/gamepad/gamepad_platform_data_fetcher_win.cc +++ b/content/browser/gamepad/gamepad_platform_data_fetcher_win.cc @@ -50,10 +50,22 @@ const WebUChar* const GamepadSubTypeName(BYTE sub_type) { } } +const WebUChar* XInputDllFileName() { + // Xinput.h defines filenames on different versions. + if (base::win::GetVersion() >= base::win::VERSION_WIN8) { + return FILE_PATH_LITERAL("xinput1_4.dll"); + } else if (base::win::GetVersion() >= base::win::VERSION_WIN7) { + return FILE_PATH_LITERAL("xinput9_1_0.dll"); + } else { + // Vista and before use DirectX redistributable. + return FILE_PATH_LITERAL("xinput1_3.dll"); + } +} + } // namespace GamepadPlatformDataFetcherWin::GamepadPlatformDataFetcherWin() - : xinput_dll_(base::FilePath(FILE_PATH_LITERAL("xinput1_3.dll"))), + : xinput_dll_(base::FilePath(XInputDllFileName())), xinput_available_(GetXInputDllFunctions()) { for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) { platform_pad_state_[i].status = DISCONNECTED; @@ -314,10 +326,8 @@ void GamepadPlatformDataFetcherWin::GetRawInputPadData( bool GamepadPlatformDataFetcherWin::GetXInputDllFunctions() { xinput_get_capabilities_ = NULL; xinput_get_state_ = NULL; - xinput_enable_ = reinterpret_cast( + XInputEnableFunc xinput_enable = reinterpret_cast( xinput_dll_.GetFunctionPointer("XInputEnable")); - if (!xinput_enable_) - return false; xinput_get_capabilities_ = reinterpret_cast( xinput_dll_.GetFunctionPointer("XInputGetCapabilities")); if (!xinput_get_capabilities_) @@ -326,7 +336,10 @@ bool GamepadPlatformDataFetcherWin::GetXInputDllFunctions() { xinput_dll_.GetFunctionPointer("XInputGetState")); if (!xinput_get_state_) return false; - xinput_enable_(true); + if (xinput_enable) { + // XInputEnable is unavailable before Win8 and deprecated in Win10. + xinput_enable(true); + } return true; } diff --git a/content/browser/gamepad/gamepad_platform_data_fetcher_win.h b/content/browser/gamepad/gamepad_platform_data_fetcher_win.h index 6680f99a19e13..0e5497e7e57b3 100644 --- a/content/browser/gamepad/gamepad_platform_data_fetcher_win.h +++ b/content/browser/gamepad/gamepad_platform_data_fetcher_win.h @@ -49,10 +49,10 @@ class GamepadPlatformDataFetcherWin : public GamepadDataFetcher { typedef DWORD (WINAPI *XInputGetStateFunc)( DWORD dwUserIndex, XINPUT_STATE* pState); - // Get functions from dynamically loaded xinput1_3.dll. We don't use - // DELAYLOAD because the import library for Win8 SDK pulls xinput1_4 which - // isn't redistributable. Returns true if loading was successful. We include - // xinput1_3.dll with Chrome. + // Get functions from dynamically loaded xinputX_Y.dll. We don't use + // DELAYLOAD because XInputEnable is not available on all versions (it is + // marked as deprecated on Win10) and thus the symbol is resolved in runtime. + // Returns true if loading was successful. bool GetXInputDllFunctions(); // Scan for connected XInput and DirectInput gamepads. @@ -71,7 +71,6 @@ class GamepadPlatformDataFetcherWin : public GamepadDataFetcher { // Function pointers to XInput functionality, retrieved in // |GetXinputDllFunctions|. - XInputEnableFunc xinput_enable_; XInputGetCapabilitiesFunc xinput_get_capabilities_; XInputGetStateFunc xinput_get_state_; diff --git a/content/content_common.gypi b/content/content_common.gypi index f9236da879bc5..56c115ef8b00c 100644 --- a/content/content_common.gypi +++ b/content/content_common.gypi @@ -1042,30 +1042,6 @@ '<(DEPTH)/third_party/khronos', ], }], - ['OS=="win" and directxsdk_exists=="True"', { - 'actions': [ - { - 'action_name': 'extract_xinput', - 'variables': { - 'input': 'APR2007_xinput_<(winsdk_arch).cab', - 'output': 'xinput1_3.dll', - }, - 'inputs': [ - '../third_party/directxsdk/files/Redist/<(input)', - ], - 'outputs': [ - '<(PRODUCT_DIR)/<(output)', - ], - 'action': [ - 'python', - '../build/extract_from_cab.py', - '..\\third_party\\directxsdk\\files\\Redist\\<(input)', - '<(output)', - '<(PRODUCT_DIR)', - ], - }, - ] - }], ['use_seccomp_bpf==0', { 'sources!': [ 'common/sandbox_linux/android/sandbox_bpf_base_policy_android.cc', diff --git a/tools/checkbins/checkbins.py b/tools/checkbins/checkbins.py index 213f30a303b2a..ec638275e58f7 100755 --- a/tools/checkbins/checkbins.py +++ b/tools/checkbins/checkbins.py @@ -30,8 +30,7 @@ # Windows guru for advice. EXCLUDED_FILES = ['chrome_frame_mini_installer.exe', 'mini_installer.exe', - 'wow_helper.exe', - 'xinput1_3.dll' # Microsoft DirectX redistributable. + 'wow_helper.exe' ] def IsPEFile(path):