Compare commits

...
113 Commits
Author SHA1 Message Date
Sam Lantinga cc016b0046 Updated to version 2.28.4 for release 2023-10-01 12:05:05 -07:00
Anonymous Maartenandelahav 8c3fd5aec2 snd_pcm_plugin_flush was removed in QNX 7.1 and later
Co-authored-by: elahav <elahav@users.noreply.github.com>
2023-09-30 16:53:53 +02:00
Anonymous Maartenandelahav 24d145f4b6 cmake: add qnx support
Co-authored-by: elahav <elahav@users.noreply.github.com>
2023-09-30 16:53:53 +02:00
Anonymous Maartenandelahav 145ad48c0e Allow the use of posix_spawn() instead of vfork/execlp()
Backport of #7041

Co-authored-by: elahav <elahav@users.noreply.github.com>
2023-09-30 16:53:53 +02:00
Simon McVittie fd495bb57c SDLTest_CompareSurfaces: Decode pixels correctly on big-endian platforms
Previously, if acting on a surface with less than 32 bits per pixel,
this code was placing the pixel value from the surface in the first
few bytes of the Uint32 to be decoded, and unrelated data from a
subsequent pixel in the remaining bytes.

Because SDL_GetRGBA takes the bits to be decoded from the
least-significant bits of the given value, ignoring the higher-order
bits if any, this happened to be correct on little-endian platforms,
where the first few bytes store the least-significant bits of an
integer.

However, it was incorrect on big-endian, where the first few bytes are
the most-significant bits of an integer.

The previous implementation also assumed that unaligned access to a
32-bit quantity is possible, which is not the case on all CPUs (but
happens to be true on x86).

These issues were not discovered until now because
SDLTest_CompareSurfaces() is only used in testautomation, which until
recently was not being run routinely at build-time, because it contained
other assumptions that can fail in an autobuilder or CI environment.

Resolves: https://github.com/libsdl-org/SDL/issues/8315
Signed-off-by: Simon McVittie <smcv@collabora.com>
(cherry picked from commit d95d2d7051)
(cherry picked from commit 6b5eadb10f)
2023-09-29 06:57:07 -07:00
Sam Lantinga d58fa94ee9 SDL_iconv_string() defaults to UTF-8
Fixes https://github.com/libsdl-org/SDL/issues/8287

(cherry picked from commit 1375d2049d)
(cherry picked from commit 9772d0512c)
2023-09-24 17:28:23 -07:00
Sam Lantinga d691010686 Check for NULL before dereferencing newly allocated memory
Fixes https://github.com/libsdl-org/SDL/issues/8289

(cherry picked from commit 70a1bc6973)
(cherry picked from commit 27f2df2292)
2023-09-24 17:19:03 -07:00
Ryan C. Gordon b93a8a86ab emscripten: Restore compatibility with existing emsdk releases.
(cherry picked from commit 5008521538)
2023-09-20 14:37:56 -04:00
Jaswant Panchumarti 536f625bde Use EM_ASM_PTR when the return value is a pointer
- closes https://github.com/libsdl-org/SDL/issues/8241

(cherry picked from commit 953b55dd6d)
2023-09-20 14:37:24 -04:00
Ozkan Sezer 1e18dc594e update config.guess and config.sub from mainstream 2023-09-20 14:50:56 +03:00
Sam Lantinga cc4973ea45 Fixed sensor timestamp units for third-party PS5 controllers
(cherry picked from commit a72dfa6a5f)
(cherry picked from commit 37dee79b74)
2023-09-18 13:00:50 -07:00
Sam Lantinga 8114bd9108 Fixed error: array subscript 2 is above array bounds of ‘const Uint8[2]’
Smart compilers don't like dereferencing off the end of arrays

(cherry picked from commit f6756047a4)
(cherry picked from commit 62e7049a4f)
2023-09-18 12:20:36 -07:00
Sam Lantinga 495fca1517 Fixed sensor timestamp calculation for third-party PS5 controllers
(cherry picked from commit 7059a55ccc)
(cherry picked from commit fff3c2573a)
2023-09-18 11:59:00 -07:00
Sam Clegg 7d80e20883 emscripten: Add JS library dependencies using EM_JS_DEPS macro
See https://github.com/emscripten-core/emscripten/pull/19780

(cherry picked from commit 042243471f)
2023-09-15 15:29:47 -07:00
Guldoman f3847c157a x11: Always update clipboard owner
This allows utilities like clipboard managers to keep track of the
changes.

(cherry picked from commit 65aaf3a9ab)
(cherry picked from commit 70a2ac2f1c)
2023-09-15 05:23:21 -07:00
Max Bachmann b576e29d9b detect fanatec steering wheels
(cherry picked from commit fd1c54a004)
(cherry picked from commit a8b9414697)
2023-09-12 15:36:41 -07:00
Anonymous Maarten c7ad8e5431 cmake: make sure SDL_GetPrefPath is run before testfilesystem
60 seconds timeout ought to be sufficient.
2023-09-10 15:34:29 +02:00
Anonymous Maarten 9c8ee3a154 ci: run tests in parallel 2023-09-10 15:34:29 +02:00
Simon McVittie d710e0be27 render: Enable clipping for zero-sized rectangles
Battle for Wesnoth apparently relies on being able to disable rendering
of UI elements by setting the clip rectangle to be empty.

Resolves: https://github.com/libsdl-org/SDL/issues/6896
Fixes: 00f05dcf "render: only enable clipping when the rectangle is valid"
Signed-off-by: Simon McVittie <smcv@collabora.com>
(cherry picked from commit 8ad043fc38)
2023-09-09 11:14:25 -07:00
Anonymous Maarten b8d1f852db cmake: use MSVC_RUNTIME_LIBRARY to force MT 2023-09-09 19:17:36 +02:00
Makarenko Oleg e9ab663c43 Detect Simagic wheel bases as wheels (#8198)
Simagic DirectDrive wheel bases have the same vendor + product id's

(cherry picked from commit a2c1984d37)
(cherry picked from commit 1d495351a0)
2023-09-04 12:12:37 -07:00
Oleg c8d1de1a9b Detect Logitech G923 Playstation as wheel
G923 have two different versions - Xbox version is already present in the wheel list, but not the PS version.

(cherry picked from commit 266b91d2fd)
(cherry picked from commit 365a36386a)
2023-09-04 11:06:06 -07:00
Oleg bf8c9cd6bf Detect Logitech PRO Racing Wheel for Xbox (PC mode) as wheel
Logitech PRO Racing Wheel have two different versions - for Playstation and Xbox. Vendor + Product ID for Playstation version already present in SDL sources, but not an Xbox version

(cherry picked from commit cde67ea49a)
(cherry picked from commit 242b25aba4)
2023-09-04 11:02:09 -07:00
Sam Lantinga 8a5ba43d00 Updated to version 2.28.3 for release 2023-09-01 11:22:07 -07:00
Jeremy Demeule c25a49c406 metal: Add hint to select low power device instead of the default one (#8182)
On some system like MacBook Pro Intel with AMD card, asking for the default device will always return the AMD GPU.
This is not an issue for 99% of the case when the renderer context is here to provide the maximum performance level like for game.
However, for video application using GPU for 1 quad and 1 texture, using the discrete GPU for that lead to an important power consumption (4 to 8W), heat increase, and fan noise.
With this patch, I successfully amend ffplay to only use the integrated GPU (i.e. the Intel one), instead of the discrete GPU (i.e. the AMD one).

(cherry picked from commit aa7ba62978)
2023-08-31 01:55:40 -07:00
Anonymous Maarten d46fdfa3ee wayland: add SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL 2023-08-30 23:03:29 +02:00
Anonymous Maarten 787d339282 wayland: don't define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_* macro's
They mess with #ifdef conditional in headers.
2023-08-30 22:46:53 +02:00
Sam Lantinga 874f6feab4 Fixed the report format for the Razer Wolverine V2 Pro
(cherry picked from commit 69aec8c915)
(cherry picked from commit 6ff48dddcb)
2023-08-24 11:39:15 -07:00
Sam Lantinga 1df4dce78f Accept key events from any source
This allows TV remotes to navigate SDL applications (with source HDMI)

Fixes https://github.com/libsdl-org/SDL/issues/8137
2023-08-24 10:12:04 -07:00
Sam Lantinga cc58a09c09 Updated to Android minSdkVersion 19 and targetSdkVersion 34
This is updated to meet the latest requirements for apps on the Google Play store

(cherry picked from commit 8e27a69370)
2023-08-24 08:33:04 -07:00
Sam Lantinga ae72cd57b5 Quiet spurious warning
Fixes https://github.com/libsdl-org/SDL/issues/8112

(cherry picked from commit 0b9d8e679a)
2023-08-13 13:54:45 -07:00
David CARLIER 8f858d7908 SDL_TriggerBreakppoint for riscv arch (both 32/64) version.
`ebreak` acts like int3 for x86, giving control of running process to debuggers.
(cherry picked from commit 723bcd0a8b)
2023-08-13 23:02:20 +03:00
Anonymous Maarten 5bfdb6e02f Fix overflow when doing SDL_sscanf("%hd", ...)
An overflow occured in the stdlib_sscanf test, when using msys2 clang32 toolchain.

(cherry picked from commit 342ec51131)
(cherry picked from commit 10135b2d7b)
2023-08-10 15:07:11 -07:00
Mathieu Eyraud 739d3ec189 Fix out of bound read of 'has_hat' array
(cherry picked from commit 94b3f78c44)
(cherry picked from commit f348370e1b)
2023-08-10 08:27:11 -07:00
Sam Lantinga 2319b2635b Fixed testautomation --filter pixels_allocFreePalette
Error messages are not part of the ABI, so we can't validate those.

Hand-picked from https://github.com/libsdl-org/sdl2-compat/commit/c9323f8face982983668fca216a2eef12dc8b1f7
2023-08-08 11:50:00 +03:00
Sam Lantinga bda161d22b Fixed testautomation --filter pixels_allocFreeFormat
Error messages are not part of the ABI, so we can't validate those.

Technically SDL_AllocFormat() on a FOURCC format in SDL2 should fail, but SDL3 supports it and we don't expect SDL2 applications to actually do this, so skip that test.

Hand-picked from https://github.com/libsdl-org/sdl2-compat/commit/5cf9438f8870bb1f517935febf9d07b4f910a308
2023-08-08 11:50:00 +03:00
Anonymous Maarten dbfd47e77d cmake: update cmake_minimum_required to avoid deprecated warning 2023-08-07 19:03:18 +02:00
Ryan C. Gordon dbb6cd02aa include: fixed a typo in SDL_RenderGetMetalCommandEncoder docs.
(cherry picked from commit 8087c0a5d2)
2023-08-06 10:45:34 -04:00
Ozkan Sezer 841263c9d6 updated config.guess and config.sub from mainstream 2023-08-05 14:03:02 +03:00
Sam Lantinga 2ccb311cb7 Added a gamepad mapping for the G-Shark GS-GP702
Fixes https://github.com/libsdl-org/SDL/issues/8068

(cherry picked from commit 06bea1eb55)
(cherry picked from commit 2304b4e86a)
2023-08-02 14:39:09 -07:00
Sam Lantinga e0a345702d The Flydigi Vader and Apex series controllers all have the same VID, PID, and name
(cherry picked from commit 58e3084477)
(cherry picked from commit 0f753d9794)
2023-08-02 14:39:09 -07:00
Sam Lantinga 9fba36511f Removed Flydigi Vader 2 mappings
Many of the Flydigi controllers use the same VID/PID and have different mappings, so let's revisit this once we have more data.

(cherry picked from commit 5388edd549)
(cherry picked from commit 805fc29ae8)
2023-08-02 14:39:09 -07:00
Ozkan Sezer 45fb778fe5 adjusted coding style in SDL_os2_joystick.c to match rest of SDL better
(cherry picked from commit 57f3c41b97)
2023-08-02 20:40:24 +03:00
Sam Lantinga 031912c4b6 Updated to version 2.28.2 for release 2023-08-02 08:31:42 -07:00
Ozkan Sezer 348cc05b4f minor os/2 stuff merged from the bitwiseworks' fork
(cosmetics only.)
(cherry picked from commit b58557a3a6)
2023-08-02 17:10:50 +03:00
Ozkan Sezer e2e87a536c SDL_video.c: move ngage video before offscreen.
Reference issue: https://github.com/libsdl-org/SDL/pull/8069.
2023-08-02 17:00:10 +03:00
Ozkan Sezer 66d5ad19f0 SDL_video.c: move os2 video before offscreen.
as offscreen is enabled in CMakeLists.txt, we get a blanks window
otherwise.

From a patch by Silvan Scherrer, at Bitwiseworks' fork.
2023-08-02 09:26:41 -04:00
Sam Lantinga 94e945ccff Fixed build
(cherry picked from commit ebf2c49b50)
2023-08-02 01:37:24 -07:00
Sam Lantinga 3f93f56b6e Fixed duplicate key press/release events on iOS
When a hardware keyboard is attached, it can take over 100 ms for the keyboard event to generate text input. In that case we want to record that we recently received a keyboard event so we don't synthesize duplicate virtual key press/release events for the input text.

(cherry picked from commit 648de4f9b8)
(cherry picked from commit 38c63afd64)
2023-08-02 01:29:30 -07:00
Sam Lantinga ed5ef8fed4 Synchronize on-screen keyboard state with text input active state
When a hardware keyboard is attached to an iPad, you can easily trigger a set of on-screen keyboard transitions that will take place over time, and we need to track whether we're currently showing or hiding the keyboard and make sure we don't clobber the existing state during those transitions.

Testing:
* Connected a hardware keyboard to an iPad
* Launched checkkeys
* Noted the keyboard bar was active at the bottom of the screen and text input was active
* Tapped with both fingers to quickly toggle text input off and back on
* Noted the keyboard bar slid down and then back up, and text input was active
* Tapped on the keyboard bar to bring up the full on-screen keyboard and then closed it so the keyboard bar was still active, and text input was still active
* Tapped on the screen to turn text input off, noted the keyboard bar slid down
* Tapped with both fingers to quickly toggle text input on and back off
* Noted that the keyboard bar slid up and then back down, and text input was inactive
* Tapped on the screen to turn text input on, tapped on the keyboard bar to bring up the full on-screen keyboard, and text input was active
* Pressed a key on the physical keyboard, the on-screen keyboard closed, the key press and release was delivered (with no text input) and then the keyboard bar slid up, and text input was active again

Fixes https://github.com/libsdl-org/SDL/issues/7979

(cherry picked from commit c3288d113e)
(cherry picked from commit 030bb7282a)
2023-08-02 01:29:30 -07:00
Sam Lantinga 39781eef09 Only pass keypresses up the responder chain when text input is active
This is another attempt to make sure we don't cause beeps from unhandled key presses while still allowing full text input functionalty.

If this isn't selective enough, we might need to go up the responder chain to see what's going to handle the event before passing it along.

Fixes https://github.com/libsdl-org/SDL/pull/6962

(cherry picked from commit a8abe612ed)
(cherry picked from commit 335e9c769a)
2023-08-02 01:29:30 -07:00
Sam Lantinga 3436124804 Revert "Stop beep when running iOS apps on ARM-based Macs"
This reverts commit bbf38bbbc3, which prevented text input from working when a hardware keyboard was connected, since key strokes don't get to the text input field.

Fixes https://github.com/libsdl-org/SDL/issues/7958

(cherry picked from commit f5ea6ae18d)
(cherry picked from commit 5e9320f6b5)
2023-08-02 01:29:30 -07:00
Sam Lantinga 9267a9032e Fixed build
(cherry picked from commit e2afc1f37a)
2023-08-01 18:58:40 -07:00
Sam Lantinga 02be870c54 Fixed crash if a display is enumerated twice
This can happen if a monitor is in the process of becoming primary because another monitor was disconnected.

(cherry picked from commit 07578fde3d)
(cherry picked from commit 2468fccf7f)
2023-08-01 18:30:46 -07:00
Ryan C. Gordon 84ad531689 cocoa: Ignore first mouse motion event after enabling relative mode.
Fixes #7918.

(cherry picked from commit dc5dda0f31)
2023-08-01 18:40:24 -04:00
Ryan C. Gordon e73a81b28a x11: Blocking for window maximization should wait 100 ms, not 1000.
Reference Issue #7070.

(cherry picked from commit 3030fd815c)
2023-08-01 13:55:58 -04:00
Ryan C. Gordon 133ad1915c Revert "x11: check if window size/position has changed during SDL_ShowWindow."
This reverts commit aa536217b3.

(cherry picked from commit 5c3df60ec9)
2023-08-01 13:51:37 -04:00
Sam Lantinga 5733f42c7c Fall back to Xlib if XRandR isn't available
This fixes video initialization on headless systems with VNC

Fixes https://github.com/libsdl-org/SDL/issues/8054

(cherry picked from commit 71099149b8)
(cherry picked from commit 8825fbf713)
2023-07-31 14:41:51 -07:00
Mathieu Eyraud dda971833e Add missing break
(cherry picked from commit 0500fca00c)
2023-07-29 17:33:20 +03:00
Ozkan Sezer 38a5aed974 minor os/2 stuff merged from the bitwiseworks' fork 2023-07-28 23:56:20 +03:00
Ozkan Sezer 3845fd3c49 fixed typo in prev. patch. 2023-07-28 07:35:24 +03:00
Ozkan Sezer 0d62ce6070 test/testnativecocoa.m: fixed deprecation warnings. 2023-07-28 07:21:28 +03:00
Sam Lantinga 301f227879 Sorted controller list
(cherry picked from commit 3174d0b970)
(cherry picked from commit 507be6c3f8)
2023-07-27 12:50:32 -07:00
Max Maisel 2ca4c0233a Add Steam Deck controller mapping to database.
This adds support for the back paddles, and the "..." key
which are not automatically detected.
* "Back" is mapped to the top left "two windows" key.
* "Start" is mapped to the top right "hambuger menu" key.
* "Guide" is mapped to the "Steam" key.
* The "..." key is just a generic button.

When looking at the screen, paddles are number
* P1: Top right
* P2: Top left
* P3: Bottom right
* P4: Botom Left

The new controller mapping was created with the SDL3 gamepadmap tool.

(cherry picked from commit 27b8abb056)
(cherry picked from commit f4561db69a)
2023-07-27 12:50:32 -07:00
Anonymous Maarten 44903d8aee SDL_atomic.h: __ARM_ARCH is not always defined for an arm platform
e.g. riscos toolchain
(cherry picked from commit 8105f1d5b5)
2023-07-26 20:39:30 +03:00
Ozkan Sezer e3f90c6068 remove unused vulkan/*.hpp files.
(cherry picked from commit 611b3dd1fd)
2023-07-26 18:10:00 +03:00
Ozkan Sezer 8cdc2b3eec update docs/README-os2 after the last os/2 audio patch. 2023-07-25 20:51:32 +03:00
Ozkan Sezer b4d8765426 os2 audio refactoring and capture support
- Fixed audio device detection and usage.
- Implemented audio capture support
- Refactored buffer handling to separate pointers to fill and drain buffers.

Based on patches by josch1710 and Lars Erdmann:
https://github.com/bitwiseworks/SDL2-os2/pull/7
(cherry picked from commit 890bee64a4)
2023-07-25 14:03:00 +03:00
Anonymous Maarten e6f044ddda ci: bump mymindstorm/setup-emsdk to latest tag 2023-07-22 18:09:14 +02:00
Weng Xuetian 2eb73e2419 Remove the unimplemented CloseIC in fcitx module
This call is actually a left-over when porting from fcitx4 service to the new org.freedesktop.portal.Fcitx supported by both fcitx4/fcitx5. CloseIC is actually never a part of the new interface on org.freedesktop.portal.Fcitx. It cause any issue user visible effect.
2023-07-20 13:37:31 -07:00
Sam Lantinga fb57ba763d Fixed LED pending check failing when the controller timestamp is very large
In this case we know the controller has been on for a while and the Bluetooth connection LED cycle is complete.

Also fixed the timestamp being zero the first time it is checked

(cherry picked from commit bd4f155bbb)
(cherry picked from commit f7dc8c0eaa)
2023-07-17 17:46:30 -07:00
Sam Lantinga 63a98d0da2 Don't send k_EPS5FeatureReportIdCapabilities to Sony PS5 controllers
This report is for third party controllers only.

(cherry picked from commit 16dd5f0da4)
(cherry picked from commit bb036ef544)
2023-07-17 17:46:29 -07:00
Sam Lantinga 78f11e05ff Don't tickle Bluetooth PS5 controllers in simple mode with an effects packet
That will put the PS5 controller into enhanced mode, which breaks DirectInput games

(cherry picked from commit 2fef0be2f6)
(cherry picked from commit 910dad505a)
2023-07-17 17:46:29 -07:00
Sam Lantinga ac4f5dcadd Relicensed testutils to match other test code
Permission granted in https://github.com/libsdl-org/SDL/commit/76a7b629bfc4869df7659c2f2e47d9253c73696f#commitcomment-121408342

(cherry picked from commit 6c2472d459)
(cherry picked from commit a4ad293d4a)
2023-07-16 04:38:48 -07:00
Sam Lantinga ff4fd93f4c Fixed getting the CRC of virtual joysticks without a VID/PID
(cherry picked from commit b40fb5c51e)
(cherry picked from commit 6089b35706)
2023-07-16 04:38:48 -07:00
Frank Praznik 52a14998a8 wayland/video: Validate the returned window display pointer before dereferencing it
If, in the case where all displays has been disconnected, and some window state change occurs before an active display is re-added and finalized, the pointer returned by SDL_GetDisplayForWindow() will be null necessitating that the returned pointer be checked for validity before dereferencing it.

(cherry picked from commit a999100858)
2023-07-14 11:30:31 -04:00
Anonymous Maarten 14b0b0e6c8 ci: move 'set -eu' to after source_cmd 2023-07-14 15:03:19 +02:00
Sam Lantinga cb4b41ddf7 RAWINPUT_RegisterNotifications() should return int, for consistency
(cherry picked from commit 1903d7b1bf)
(cherry picked from commit e8b6edd5a0)
2023-07-11 10:54:44 -07:00
Sam Lantinga 5a2d165b7b Improved RAWINPUT <-> XInput/WGI device correlation
If there is only one controller slot available, assume that's the one matching new RAWINPUt devices. This will be right most of the time, and uncorrelation will fix any bad guesses.

(cherry picked from commit 41882a1acb)
(cherry picked from commit 34c5bde355)
2023-07-11 10:54:44 -07:00
Sam Lantinga 11022c23b2 Fixed crash if RAWINPUT is not initialized
We shouldn't be doing any of this work in that case

(cherry picked from commit dfc5e6964e)
(cherry picked from commit 9117b2e300)
2023-07-11 10:54:44 -07:00
Sam Lantinga b7c93a2d77 Don't send k_ePS4FeatureReportIdCapabilities to Sony PS4 controllers
This report is for third party controllers only, and might be causing issues with fake PS4 controllers.

Reference https://github.com/libsdl-org/SDL/issues/7960

(cherry picked from commit 092a4b780c)
(cherry picked from commit 6bf5f5a221)
2023-07-10 09:49:17 -07:00
Christopher WellonsandOzkan Sezer 078e817ceb Unaligned stacks on i686-w64-mingw32, may lead to crashes (#7607)
Co-authored-by: Ozkan Sezer <sezeroz@gmail.com>(cherry picked from commit 8231278817)
2023-07-10 03:10:20 +03:00
Ozkan Sezer aba2be820c SDL_RWFromMem, SDL_RWFromConstMem: reject negative size parameters.
(cherry picked from commit 0ad822eb70)
2023-07-10 00:15:56 +03:00
Sam Lantinga 0dbeec449f Re-added mappings for older Xbox One controllers on Linux
The xpad kernel driver doesn't know about these controllers and ends up using BTN_C and BTN_Z and the automatic mapping doesn't work correctly.

It turns out VID 0x045e and PID 0x02e0 is used by the 8BitDo SN30 Pro when connecting via Bluetooth in XInput mode.

Fixes https://github.com/libsdl-org/SDL/issues/7925

(cherry picked from commit 80e1c75e1c)
(cherry picked from commit 156c7badf5)
2023-07-09 09:51:10 -07:00
Joshua Barnett 3f46546f79 Add kernel32 to SDL_EXTRA_LIBS required for cross-compilation to Win32 native
Linking error experienced while compiling with the following toolchain
due to lack of kernel32.lib

https://github.com/llvm-mirror/llvm/blob/d35e5f8dded4c884ca25ca88f184e1505cad106c/cmake/platforms/WinMsvc.cmake#L317-L321
2023-07-09 14:03:36 +02:00
Sam Lantinga a614d8f8f7 Fixed mapping BTN_TR2 to right trigger
(cherry picked from commit ea60da5b94)
(cherry picked from commit 4b1dd54a56)
2023-07-08 18:19:06 -07:00
Sam Lantinga bb3997d81d Added WGI gamepad added/removed listeners for RAWINPUT
This fixes WGI correlation on startup when the WGI gamepad list isn't populated yet

(cherry picked from commit f047e178b6)
(cherry picked from commit f8a0135edf)
2023-07-08 10:40:56 -07:00
Sam Lantinga 035121040f Don't tickle Bluetooth PS4 controllers in simple mode with an effects packet
That will put the PS4 controller into enhanced mode, which breaks DirectInput games

(cherry picked from commit efed24850a)
(cherry picked from commit 1f7bc08884)
2023-07-08 10:40:55 -07:00
Sam Lantinga f2d016e353 Lazily initialize the WGI gamepad support
Initializing "Windows.Gaming.Input.Gamepad" will put Bluetooth PS4 controllers into enhanced report mode, which breaks any game using DirectInput. Let's wait to do this until absolutely necessary.

(cherry picked from commit 785f57eb91)
(cherry picked from commit de849d5e6f)
2023-07-08 10:40:55 -07:00
Sam Lantinga b858242823 Added the hint SDL_HINT_JOYSTICK_WGI to control whether to use Windows.Gaming.Input for controllers
(cherry picked from commit a6228e7aaf)
2023-07-08 09:35:22 -07:00
Sam Lantinga 46927b1362 Prefer using XInput for rumble over WGI, as it allows rumble in the background
(cherry picked from commit e16a83d393)
2023-07-07 09:48:25 -07:00
Sam Lantinga 3bee5cf538 Continue running XInput detection while RAWINPUT is active
This allows us to re-enable XInput correlation for RAWINPUT devices without reintroducing the controller shutdown bug for controllers using the wireless adapter in https://github.com/libsdl-org/SDL/issues/3468.

Fixes https://github.com/libsdl-org/SDL/issues/7940

(cherry picked from commit a0a3957eb6)
2023-07-07 09:48:25 -07:00
Takase 03dcee1731 video(wayland): use both --icon and --icon-name for Zenity (#7897)
video(wayland): use both --icon and --icon-name for Zenity

Many distros ship an older version of Zenity that supports GTK3, while some distros ship newer version of Zenity which uses libadwaita.

This command tries to use --icon and fall back to --icon-name when it fails.

(cherry picked from commit b90343e512)
2023-07-06 18:00:37 -07:00
Sam Lantinga fdcc1d59b9 Fixed crash if mutex functions are used before any mutex has been created
(cherry picked from commit cc49f1e279)
(cherry picked from commit 488a91eb40)
2023-07-05 10:17:42 -07:00
Anonymous Maarten 2633540746 cmake: explicitly disable WINDOWS_EXPORT_ALL_SYMBOLS for SDL2
This fixes the following errors when a dll attempts to link to a shared SDL2::SDL2:

m.c.obj : error LNK2019: unresolved external symbol __imp___acrt_iob_func referenced in function printf
m.c.obj : error LNK2019: unresolved external symbol __imp___stdio_common_vfprintf referenced in function _vfprintf_l
MSVCRTD.lib(init.obj) : error LNK2019: unresolved external symbol _CrtDbgReport referenced in function _CRT_RTC_INIT
MSVCRTD.lib(init.obj) : error LNK2019: unresolved external symbol _CrtDbgReportW referenced in function _CRT_RTC_INITW
MSVCRTD.lib(error.obj) : error LNK2019: unresolved external symbol strcpy_s referenced in function "void __cdecl _RTC_StackFailure(void *,char const *)" (?_RTC_StackFailure@@YAXPEAXPEBD@Z)
MSVCRTD.lib(error.obj) : error LNK2019: unresolved external symbol strcat_s referenced in function "void __cdecl _RTC_StackFailure(void *,char const *)" (?_RTC_StackFailure@@YAXPEAXPEBD@Z)
MSVCRTD.lib(error.obj) : error LNK2019: unresolved external symbol __stdio_common_vsprintf_s referenced in function _vsprintf_s_l
MSVCRTD.lib(error.obj) : error LNK2001: unresolved external symbol __C_specific_handler_noexcept
MSVCRTD.lib(pdblkup.obj) : error LNK2019: unresolved external symbol _wmakepath_s referenced in function "int __cdecl GetPdbDllPathFromFilePath(wchar_t const *,wchar_t *,unsigned __int64)" (?GetPdbDllPathFromFilePath@@YAHPEB_WPEA_W_K@Z)
MSVCRTD.lib(pdblkup.obj) : error LNK2019: unresolved external symbol _wsplitpath_s referenced in function "int __cdecl GetPdbDllPathFromFilePath(wchar_t const *,wchar_t *,unsigned __int64)" (?GetPdbDllPathFromFilePath@@YAHPEB_WPEA_W_K@Z)
MSVCRTD.lib(pdblkup.obj) : error LNK2019: unresolved external symbol wcscpy_s referenced in function "int __cdecl GetPdbDllPathFromFilePath(wchar_t const *,wchar_t *,unsigned __int64)" (?GetPdbDllPathFromFilePath@@YAHPEB_WPEA_W_K@Z)
MSVCRTD.lib(pdblkup.obj) : error LNK2019: unresolved external symbol __vcrt_GetModuleFileNameW referenced in function "struct HINSTANCE__ * __cdecl GetPdbDll(void)" (?GetPdbDll@@YAPEAUHINSTANCE__@@XZ)
MSVCRTD.lib(pdblkup.obj) : error LNK2019: unresolved external symbol __vcrt_GetModuleHandleW referenced in function "struct HINSTANCE__ * __cdecl GetPdbDll(void)" (?GetPdbDll@@YAPEAUHINSTANCE__@@XZ)
MSVCRTD.lib(pdblkup.obj) : error LNK2019: unresolved external symbol __vcrt_LoadLibraryExW referenced in function "struct HINSTANCE__ * __cdecl GetPdbDll(void)" (?GetPdbDll@@YAPEAUHINSTANCE__@@XZ)
2023-07-05 00:18:13 +02:00
Sam Lantinga 116a5344ff Fixed resource leak and crash at exit in the D3D11 renderer
Also, for some reason ID3D11DeviceContext_OMGetRenderTargets() was failing in the second read pixels call in the "testautomation --filter render_testViewport" test.

We already know the target view, so just use that.

(cherry picked from commit 619f65af0c)
(cherry picked from commit 61808b03b5)
2023-07-03 17:43:21 -07:00
Sam Lantinga f3436bc103 The clip rect is defined in terms of the current viewport
Don't use the viewport offset when setting the clip rect in the D3D12 renderer.

This fixes "testautomation --filter render_testViewport" on Windows

(cherry picked from commit 304d425f99)
(cherry picked from commit bf277eb808)
2023-07-03 17:16:03 -07:00
Ozkan Sezer 5e21571374 fixed windows build after commit 7e8be3f 2023-07-04 02:29:10 +03:00
Sam Lantinga 699f8697fe Retry to open the clipboard in case another application has it open
This fixes 'testautomation --filter clipboard_testClipboardTextFunctions' on Windows

(cherry picked from commit c24496727cdd40d5c0ffdf7b6a61085ec3a2766d)
(cherry picked from commit 7e8be3f280)
2023-07-03 16:13:46 -07:00
scribam 0352301e1a cmake: use SDL_CPU_ARM32 instead of CMAKE_GENERATOR_PLATFORM STREQUAL "ARM" 2023-07-01 23:26:38 +02:00
Sam Lantinga 4761467b2e Updated to version 2.28.1 for release 2023-07-01 09:56:20 -07:00
Ryan C. Gordon cd662ceb54 rwops: Use SetFilePointerEx on Windows for appending writes.
Fixes #7900.

(cherry picked from commit 769bf2ebcc)
2023-07-01 00:40:51 -04:00
Sam Lantinga 7207f5155b Added Linux mapping for the Logitech Chillstream
Fixes https://github.com/libsdl-org/SDL/issues/7829

(cherry picked from commit 675fc8c38f)
(cherry picked from commit fc0854651b)
2023-06-29 16:16:10 -07:00
Anonymous Maarten 5d9013beb9 wayland: don't use libdecor_frame_get_* functions when header doesn't have it
and we're statically linking to the library.
This fixes building SDL with -DSDL_WAYLAND_SHARED=OFF

(cherry picked from commit 5b5b67df20)
(cherry picked from commit e6f635ca17)
2023-06-29 16:14:23 -04:00
Sam Lantinga 4af1f6ed0c Fixed build
(cherry picked from commit 099e53f3a5)
2023-06-29 11:26:16 -07:00
Sam Lantinga 446fb3028e Added support for the Nintendo Online Famicom controllers
(cherry picked from commit baa9c57581)
(cherry picked from commit 0f940cb6ce)
2023-06-29 11:18:30 -07:00
Sam Lantinga ba170daf84 Don't crash if SDL_MapRGB() and SDL_MapRGBA() are passed a NULL format
(cherry picked from commit fadc4916a9bcc410c2148a91bf0adf742410a4ba)
(cherry picked from commit 0ba93e4aac)
2023-06-27 16:10:49 -07:00
Sam Lantinga 7fa2ddb0de Fixed Nintendo Switch Pro controllers that don't have readable user calibration
(cherry picked from commit 9ee1200e6f)
(cherry picked from commit 170428b107)
2023-06-27 07:50:41 -07:00
Narr the Reg 9aca2a4339 hidapi: switch: Handle MCU input reports
(cherry picked from commit 425062c123)
(cherry picked from commit 950ff0056a)
2023-06-26 10:07:35 -07:00
Sam Lantinga 491fba1d06 SDL_FindFreePlayerIndex() will always return the next available player index
Fixes https://github.com/libsdl-org/SDL/issues/7868

(cherry picked from commit 87e916dd21)
(cherry picked from commit 38619bb28d)
2023-06-24 15:40:30 -07:00
Sam Lantinga c27f3ead7c Removed 100 ms hitch when querying third party Nintendo Switch controllers that don't respond to request for info
(cherry picked from commit 8acf729650)
2023-06-21 14:13:09 -07:00
Sam Lantinga 1429e525fb Use default sensor calibration if we can't read it from the Nintendo Switch controller
Fixes https://github.com/libsdl-org/SDL/issues/7830

(cherry picked from commit 3694dabe7c)
(cherry picked from commit dfbdaca2b8)
2023-06-21 10:41:58 -07:00
Sam Lantinga de6963ea99 Apply DPI scale to mouse coordinates in SDL_WarpMouseInWindow()
Fixes https://github.com/libsdl-org/SDL/issues/7855

(cherry picked from commit 657c346556)
2023-06-21 08:46:45 -07:00
105 changed files with 2421 additions and 209815 deletions

No files matched your search

+1 -1
View File
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.0)
cmake_minimum_required(VERSION 3.0...3.5)
project(ci_utils C CXX)
set(txt "CC=${CMAKE_C_COMPILER}
+2 -2
View File
@@ -7,9 +7,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: mymindstorm/setup-emsdk@v10
- uses: mymindstorm/setup-emsdk@v12
with:
version: 2.0.32
version: 3.1.35
- name: Install ninja
run: |
sudo apt-get -y update
+7 -7
View File
@@ -104,10 +104,10 @@ jobs:
- name: Run build-time tests (CMake)
if: "! matrix.platform.autotools"
run: |
set -eu
${{ matrix.platform.source_cmd }}
set -eu
export SDL_TESTS_QUICK=1
ctest -VV --test-dir build/
ctest -VV --test-dir build/ -j2
if test "${{ runner.os }}" = "Linux"; then
# This should show us the SDL_REVISION
strings build/libSDL2-2.0.so.0 | grep SDL-
@@ -122,8 +122,8 @@ jobs:
- name: Configure (Autotools)
if: matrix.platform.autotools
run: |
set -eu
${{ matrix.platform.source_cmd }}
set -eu
rm -fr build-autotools
mkdir build-autotools
./autogen.sh
@@ -154,8 +154,8 @@ jobs:
- name: Build (Autotools)
if: matrix.platform.autotools
run: |
set -eu
${{ matrix.platform.source_cmd }}
set -eu
parallel="$(getconf _NPROCESSORS_ONLN)"
make -j"${parallel}" -C build-autotools V=1
if test "${{ runner.os }}" != "macOS" ; then
@@ -164,8 +164,8 @@ jobs:
- name: Run build-time tests (Autotools)
if: ${{ matrix.platform.autotools && (runner.os != 'macOS') }}
run: |
set -eu
${{ matrix.platform.source_cmd }}
set -eu
curdir="$(pwd)"
parallel="$(getconf _NPROCESSORS_ONLN)"
export SDL_TESTS_QUICK=1
@@ -177,8 +177,8 @@ jobs:
- name: Install (Autotools)
if: matrix.platform.autotools
run: |
set -eu
${{ matrix.platform.source_cmd }}
set -eu
curdir="$(pwd)"
parallel="$(getconf _NPROCESSORS_ONLN)"
make -j"${parallel}" -C build-autotools install V=1
@@ -219,8 +219,8 @@ jobs:
- name: Run installed-tests (Autotools)
if: "runner.os == 'Linux' && matrix.platform.autotools"
run: |
set -eu
${{ matrix.platform.source_cmd }}
set -eu
parallel="$(getconf _NPROCESSORS_ONLN)"
sudo make -j"${parallel}" -C build-autotools install
sudo make -j"${parallel}" -C build-autotools/test install
+2 -2
View File
@@ -34,7 +34,7 @@ jobs:
os.makedirs(builddir)
with open(f"{ builddir }/CMakeLists.txt", "w") as f:
f.write(textwrap.dedent(f"""\
cmake_minimum_required(VERSION 3.0)
cmake_minimum_required(VERSION 3.0...3.5)
project(sdl_user)
add_subdirectory("{ srcdir }" SDL)
"""))
@@ -53,7 +53,7 @@ jobs:
if: "! contains(matrix.platform.name, 'ARM')"
run: |
$env:SDL_TESTS_QUICK=1
ctest -VV --test-dir build/ -C Release
ctest -VV --test-dir build/ -C Release -j2
- name: Install (CMake)
run: |
echo "SDL2_DIR=$Env:GITHUB_WORKSPACE/prefix" >> $Env:GITHUB_ENV
+30 -12
View File
@@ -2,6 +2,9 @@ if(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR})
message(FATAL_ERROR "Prevented in-tree build. Please create a build directory outside of the SDL source code and run \"cmake -S ${CMAKE_SOURCE_DIR} -B .\" from there")
endif()
# MSVC runtime library flags are selected by an abstraction.
set(CMAKE_POLICY_DEFAULT_CMP0091 NEW)
cmake_minimum_required(VERSION 3.0.0...3.5)
project(SDL2 C CXX)
@@ -84,7 +87,7 @@ endif()
# See docs/release_checklist.md
set(SDL_MAJOR_VERSION 2)
set(SDL_MINOR_VERSION 28)
set(SDL_MICRO_VERSION 0)
set(SDL_MICRO_VERSION 4)
set(SDL_VERSION "${SDL_MAJOR_VERSION}.${SDL_MINOR_VERSION}.${SDL_MICRO_VERSION}")
# Set defaults preventing destination file conflicts
@@ -224,11 +227,13 @@ elseif(MSVC_VERSION GREATER 1400) # VisualStudio 8.0+
elseif(CMAKE_C_COMPILER_ID MATCHES "^Intel$")
set(OPT_DEF_ASM TRUE)
set(USE_INTELCC TRUE)
elseif(CMAKE_C_COMPILER_ID MATCHES "QCC")
set(USE_QCC TRUE)
else()
set(OPT_DEF_ASM FALSE)
endif()
if(USE_GCC OR USE_CLANG OR USE_INTELCC)
if(USE_GCC OR USE_CLANG OR USE_INTELCC OR USE_QCC)
set(OPT_DEF_GCC_ATOMICS ON)
endif()
@@ -253,6 +258,9 @@ endif()
if(MSVC)
option(SDL_FORCE_STATIC_VCRT "Force /MT for static VC runtimes" OFF)
if(SDL_FORCE_STATIC_VCRT)
if(NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
endif()
foreach(flag_var
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO)
@@ -563,7 +571,7 @@ if(NOT SDL_FOREGROUNDING_SIGNAL STREQUAL "OFF")
endif()
# Compiler option evaluation
if(USE_GCC OR USE_CLANG OR USE_INTELCC)
if(USE_GCC OR USE_CLANG OR USE_INTELCC OR USE_QCC)
# Check for -Wall first, so later things can override pieces of it.
# Note: clang-cl treats -Wall as -Weverything (which is very loud),
# /W3 as -Wall, and /W4 as -Wall -Wextra. So: /W3 is enough.
@@ -620,11 +628,6 @@ if(USE_GCC OR USE_CLANG OR USE_INTELCC)
endif()
endif()
set(CMAKE_REQUIRED_FLAGS "-mpreferred-stack-boundary=2")
check_c_source_compiles("int x = 0; int main(int argc, char **argv) { return 0; }"
HAVE_GCC_PREFERRED_STACK_BOUNDARY)
set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
set(CMAKE_REQUIRED_FLAGS "-fvisibility=hidden -Werror")
check_c_source_compiles("
#if !defined(__GNUC__) || __GNUC__ < 4
@@ -1427,6 +1430,12 @@ elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU)
file(GLOB AIX_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/paudio/*.c)
list(APPEND SOURCE_FILES ${AIX_AUDIO_SOURCES})
set(HAVE_SDL_AUDIO TRUE)
elseif(QNX)
set(SDL_AUDIO_DRIVER_QSA 1)
file(GLOB QSA_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/qsa/*.c)
list(APPEND SOURCE_FILES ${QSA_AUDIO_SOURCES})
list(APPEND EXTRA_LIBS asound)
set(HAVE_SDL_AUDIO TRUE)
endif()
CheckOSS()
CheckALSA()
@@ -1458,6 +1467,7 @@ elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU)
set(SDL_VIDEO_VULKAN 1)
set(HAVE_VULKAN TRUE)
endif()
CheckQNXScreen()
endif()
if(UNIX)
@@ -1708,6 +1718,13 @@ elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU)
set(HAVE_RPATH TRUE)
endif()
if(QNX)
# QNX's *printf() family generates a SIGSEGV if NULL is passed for a string
# specifier (on purpose), but SDL expects "(null)". Use the built-in
# implementation.
set(HAVE_VSNPRINTF 0)
set(USE_POSIX_SPAWN 1)
endif()
elseif(WINDOWS)
find_program(WINDRES windres)
@@ -1766,7 +1783,7 @@ elseif(WINDOWS)
check_include_file(ddraw.h HAVE_DDRAW_H)
check_include_file(dsound.h HAVE_DSOUND_H)
check_include_file(dinput.h HAVE_DINPUT_H)
if(WINDOWS_STORE OR CMAKE_GENERATOR_PLATFORM STREQUAL "ARM")
if(WINDOWS_STORE OR SDL_CPU_ARM32)
set(HAVE_DINPUT_H 0)
endif()
check_include_file(dxgi.h HAVE_DXGI_H)
@@ -1926,7 +1943,7 @@ elseif(WINDOWS)
# Libraries for Win32 native and MinGW
if(NOT WINDOWS_STORE)
list(APPEND EXTRA_LIBS user32 gdi32 winmm imm32 ole32 oleaut32 version uuid advapi32 setupapi shell32)
list(APPEND EXTRA_LIBS kernel32 user32 gdi32 winmm imm32 ole32 oleaut32 version uuid advapi32 setupapi shell32)
endif()
if(WINDOWS_STORE)
@@ -3187,7 +3204,7 @@ if (SDL_ASAN)
endif()
if(SDL_CCACHE AND NOT CMAKE_VERSION VERSION_LESS 3.4)
cmake_minimum_required(VERSION 3.4)
cmake_minimum_required(VERSION 3.4...3.5)
find_program(CCACHE_BINARY ccache)
if(CCACHE_BINARY)
set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE_BINARY})
@@ -3334,6 +3351,7 @@ if(SDL_SHARED)
# alias target for in-tree builds
add_library(SDL2::SDL2 ALIAS SDL2)
set_target_properties(SDL2 PROPERTIES POSITION_INDEPENDENT_CODE TRUE)
set_target_properties(SDL2 PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS FALSE)
if(NOT SDL_LIBC)
if(SDL_CPU_X86)
# FIXME: should be added for all architectures (missing symbols for ARM)
@@ -3368,7 +3386,7 @@ if(SDL_SHARED)
OUTPUT_NAME "SDL2")
endif()
# Note: The clang toolset for Visual Studio does not support /NODEFAULTLIB.
if(MSVC AND NOT SDL_LIBC AND NOT MSVC_CLANG AND NOT CMAKE_GENERATOR_PLATFORM STREQUAL "ARM")
if(MSVC AND NOT SDL_LIBC AND NOT MSVC_CLANG AND NOT SDL_CPU_ARM32)
# Don't try to link with the default set of libraries.
if(NOT WINDOWS_STORE)
set_property(TARGET SDL2 APPEND_STRING PROPERTY LINK_FLAGS " /NODEFAULTLIB")
+1 -1
View File
@@ -15,7 +15,7 @@
LIBNAME = SDL2
MAJOR_VERSION = 2
MINOR_VERSION = 28
MICRO_VERSION = 0
MICRO_VERSION = 4
VERSION = $(MAJOR_VERSION).$(MINOR_VERSION).$(MICRO_VERSION)
DESCRIPTION = Simple DirectMedia Layer 2
+1 -1
View File
@@ -6,7 +6,7 @@
LIBNAME = SDL2
MAJOR_VERSION = 2
MINOR_VERSION = 28
MICRO_VERSION = 0
MICRO_VERSION = 4
VERSION = $(MAJOR_VERSION).$(MINOR_VERSION).$(MICRO_VERSION)
LIBHOME = .
+1 -1
View File
@@ -1,7 +1,7 @@
# SDL2 CMake configuration file:
# This file is meant to be placed in a cmake subfolder of SDL2-devel-2.x.y-VC
cmake_minimum_required(VERSION 3.0)
cmake_minimum_required(VERSION 3.0...3.5)
include(FeatureSummary)
set_package_properties(SDL2 PROPERTIES
+7
View File
@@ -1,6 +1,13 @@
This is a list of major changes in SDL's version history.
---------------------------------------------------------------------------
2.28.2:
---------------------------------------------------------------------------
General:
* Added the hint SDL_HINT_JOYSTICK_WGI to control whether to use Windows.Gaming.Input for controllers
---------------------------------------------------------------------------
2.28.0:
---------------------------------------------------------------------------
+2 -2
View File
@@ -19,10 +19,10 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>2.28.0</string>
<string>2.28.4</string>
<key>CFBundleSignature</key>
<string>SDLX</string>
<key>CFBundleVersion</key>
<string>2.28.0</string>
<string>2.28.4</string>
</dict>
</plist>
+6 -6
View File
@@ -9529,7 +9529,7 @@
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEPLOYMENT_POSTPROCESSING = YES;
DYLIB_COMPATIBILITY_VERSION = 2801.0.0;
DYLIB_CURRENT_VERSION = 2801.0.0;
DYLIB_CURRENT_VERSION = 2801.4.0;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_ALTIVEC_EXTENSIONS = YES;
@@ -9570,7 +9570,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_LINK_OBJC_RUNTIME = NO;
MARKETING_VERSION = 2.28.0;
MARKETING_VERSION = 2.28.4;
OTHER_LDFLAGS = "-liconv";
};
name = Release;
@@ -9614,7 +9614,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
DYLIB_COMPATIBILITY_VERSION = 2801.0.0;
DYLIB_CURRENT_VERSION = 2801.0.0;
DYLIB_CURRENT_VERSION = 2801.4.0;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
@@ -9656,7 +9656,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CLANG_LINK_OBJC_RUNTIME = NO;
MARKETING_VERSION = 2.28.0;
MARKETING_VERSION = 2.28.4;
OTHER_LDFLAGS = "-liconv";
};
name = Debug;
@@ -9863,7 +9863,7 @@
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 2801.0.0;
DYLIB_CURRENT_VERSION = 2801.0.0;
DYLIB_CURRENT_VERSION = 2801.4.0;
DYLIB_INSTALL_NAME_BASE = "@rpath";
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
@@ -9915,7 +9915,7 @@
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 2801.0.0;
DYLIB_CURRENT_VERSION = 2801.0.0;
DYLIB_CURRENT_VERSION = 2801.4.0;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_NS_ASSERTIONS = NO;
GCC_C_LANGUAGE_STANDARD = gnu11;
+1 -1
View File
@@ -1,4 +1,4 @@
Title SDL 2.28.0
Title SDL 2.28.4
Version 1
Description SDL Library for Mac OS X (http://www.libsdl.org)
DefaultLocation /Library/Frameworks
+10 -10
View File
@@ -8,22 +8,22 @@ else {
}
android {
compileSdkVersion 31
if (buildAsApplication) {
namespace "org.libsdl.app"
}
compileSdkVersion 34
defaultConfig {
if (buildAsApplication) {
applicationId "org.libsdl.app"
}
minSdkVersion 16
targetSdkVersion 31
minSdkVersion 19
targetSdkVersion 34
versionCode 1
versionName "1.0"
externalNativeBuild {
ndkBuild {
arguments "APP_PLATFORM=android-16"
arguments "APP_PLATFORM=android-19"
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
}
// cmake {
// arguments "-DANDROID_APP_PLATFORM=android-16", "-DANDROID_STL=c++_static"
// arguments "-DANDROID_APP_PLATFORM=android-19", "-DANDROID_STL=c++_static"
// // abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
// abiFilters 'arm64-v8a'
// }
@@ -53,10 +53,10 @@ android {
}
}
lintOptions {
lint {
abortOnError false
}
if (buildAsLibrary) {
libraryVariants.all { variant ->
variant.outputs.each { output ->
@@ -3,7 +3,6 @@
com.gamemaker.game
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.libsdl.app"
android:versionCode="1"
android:versionName="1.0"
android:installLocation="auto">
@@ -61,7 +61,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
private static final String TAG = "SDL";
private static final int SDL_MAJOR_VERSION = 2;
private static final int SDL_MINOR_VERSION = 28;
private static final int SDL_MICRO_VERSION = 0;
private static final int SDL_MICRO_VERSION = 4;
/*
// Display InputType.SOURCE/CLASS of events and devices
//
@@ -1345,23 +1345,6 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
}
}
if ((source & InputDevice.SOURCE_KEYBOARD) == InputDevice.SOURCE_KEYBOARD) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
if (isTextInputEvent(event)) {
if (ic != null) {
ic.commitText(String.valueOf((char) event.getUnicodeChar()), 1);
} else {
SDLInputConnection.nativeCommitText(String.valueOf((char) event.getUnicodeChar()), 1);
}
}
onNativeKeyDown(keyCode);
return true;
} else if (event.getAction() == KeyEvent.ACTION_UP) {
onNativeKeyUp(keyCode);
return true;
}
}
if ((source & InputDevice.SOURCE_MOUSE) == InputDevice.SOURCE_MOUSE) {
// on some devices key events are sent for mouse BUTTON_BACK/FORWARD presses
// they are ignored here because sending them as mouse input to SDL is messy
@@ -1376,6 +1359,21 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
}
}
if (event.getAction() == KeyEvent.ACTION_DOWN) {
if (isTextInputEvent(event)) {
if (ic != null) {
ic.commitText(String.valueOf((char) event.getUnicodeChar()), 1);
} else {
SDLInputConnection.nativeCommitText(String.valueOf((char) event.getUnicodeChar()), 1);
}
}
onNativeKeyDown(keyCode);
return true;
} else if (event.getAction() == KeyEvent.ACTION_UP) {
onNativeKeyUp(keyCode);
return true;
}
return false;
}
+1 -1
View File
@@ -6,7 +6,7 @@ buildscript {
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.0.3'
classpath 'com.android.tools.build:gradle:8.1.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
+1 -1
View File
@@ -1,6 +1,6 @@
#Thu Nov 11 18:20:34 PST 2021
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
+52 -13
View File
@@ -1,10 +1,10 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright 1992-2022 Free Software Foundation, Inc.
# Copyright 1992-2023 Free Software Foundation, Inc.
# shellcheck disable=SC2006,SC2268 # see below for rationale
timestamp='2022-05-25'
timestamp='2023-08-22'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -47,7 +47,7 @@ me=`echo "$0" | sed -e 's,.*/,,'`
usage="\
Usage: $0 [OPTION]
Output the configuration name of the system \`$me' is run on.
Output the configuration name of the system '$me' is run on.
Options:
-h, --help print this help, then exit
@@ -60,13 +60,13 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
Copyright 1992-2022 Free Software Foundation, Inc.
Copyright 1992-2023 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
help="
Try \`$me --help' for more information."
Try '$me --help' for more information."
# Parse command line
while test $# -gt 0 ; do
@@ -102,8 +102,8 @@ GUESS=
# temporary files to be created and, as you can see below, it is a
# headache to deal with in a portable fashion.
# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
# use `HOST_CC' if defined, but it is deprecated.
# Historically, 'CC_FOR_BUILD' used to be named 'HOST_CC'. We still
# use 'HOST_CC' if defined, but it is deprecated.
# Portable tmp directory creation inspired by the Autoconf team.
@@ -155,6 +155,9 @@ Linux|GNU|GNU/*)
set_cc_for_build
cat <<-EOF > "$dummy.c"
#if defined(__ANDROID__)
LIBC=android
#else
#include <features.h>
#if defined(__UCLIBC__)
LIBC=uclibc
@@ -169,6 +172,7 @@ Linux|GNU|GNU/*)
LIBC=musl
#endif
#endif
#endif
EOF
cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
eval "$cc_set_libc"
@@ -459,7 +463,7 @@ case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in
UNAME_RELEASE=`uname -v`
;;
esac
# Japanese Language versions have a version number like `4.1.3-JL'.
# Japanese Language versions have a version number like '4.1.3-JL'.
SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'`
GUESS=sparc-sun-sunos$SUN_REL
;;
@@ -904,7 +908,7 @@ EOF
fi
;;
*:FreeBSD:*:*)
UNAME_PROCESSOR=`/usr/bin/uname -p`
UNAME_PROCESSOR=`uname -p`
case $UNAME_PROCESSOR in
amd64)
UNAME_PROCESSOR=x86_64 ;;
@@ -966,11 +970,37 @@ EOF
GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC
;;
x86_64:[Mm]anagarm:*:*|i?86:[Mm]anagarm:*:*)
GUESS="$UNAME_MACHINE-pc-managarm-mlibc"
;;
*:[Mm]anagarm:*:*)
GUESS="$UNAME_MACHINE-unknown-managarm-mlibc"
;;
*:Minix:*:*)
GUESS=$UNAME_MACHINE-unknown-minix
;;
aarch64:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
set_cc_for_build
CPU=$UNAME_MACHINE
LIBCABI=$LIBC
if test "$CC_FOR_BUILD" != no_compiler_found; then
ABI=64
sed 's/^ //' << EOF > "$dummy.c"
#ifdef __ARM_EABI__
#ifdef __ARM_PCS_VFP
ABI=eabihf
#else
ABI=eabi
#endif
#endif
EOF
cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'`
eval "$cc_set_abi"
case $ABI in
eabi | eabihf) CPU=armv8l; LIBCABI=$LIBC$ABI ;;
esac
fi
GUESS=$CPU-unknown-linux-$LIBCABI
;;
aarch64_be:Linux:*:*)
UNAME_MACHINE=aarch64_be
@@ -1036,7 +1066,16 @@ EOF
k1om:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*)
kvx:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
kvx:cos:*:*)
GUESS=$UNAME_MACHINE-unknown-cos
;;
kvx:mbr:*:*)
GUESS=$UNAME_MACHINE-unknown-mbr
;;
loongarch32:Linux:*:* | loongarch64:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
;;
m32r*:Linux:*:*)
@@ -1191,7 +1230,7 @@ EOF
GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION
;;
i*86:OS/2:*:*)
# If we were able to find `uname', then EMX Unix compatibility
# If we were able to find 'uname', then EMX Unix compatibility
# is probably installed.
GUESS=$UNAME_MACHINE-pc-os2-emx
;;
@@ -1332,7 +1371,7 @@ EOF
GUESS=ns32k-sni-sysv
fi
;;
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
PENTIUM:*:4.0*:*) # Unisys 'ClearPath HMP IX 4000' SVR4/MP effort
# says <Richard.M.Bartel@ccMail.Census.GOV>
GUESS=i586-unisys-sysv4
;;
+146 -76
View File
@@ -1,10 +1,10 @@
#! /bin/sh
# Configuration validation subroutine script.
# Copyright 1992-2022 Free Software Foundation, Inc.
# Copyright 1992-2023 Free Software Foundation, Inc.
# shellcheck disable=SC2006,SC2268 # see below for rationale
timestamp='2022-01-03'
timestamp='2023-09-19'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -76,13 +76,13 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
Copyright 1992-2022 Free Software Foundation, Inc.
Copyright 1992-2023 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
help="
Try \`$me --help' for more information."
Try '$me --help' for more information."
# Parse command line
while test $# -gt 0 ; do
@@ -130,7 +130,7 @@ IFS=$saved_IFS
# Separate into logical components for further validation
case $1 in
*-*-*-*-*)
echo Invalid configuration \`"$1"\': more than four components >&2
echo "Invalid configuration '$1': more than four components" >&2
exit 1
;;
*-*-*-*)
@@ -145,7 +145,8 @@ case $1 in
nto-qnx* | linux-* | uclinux-uclibc* \
| uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \
| netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \
| storm-chaos* | os2-emx* | rtmk-nova*)
| storm-chaos* | os2-emx* | rtmk-nova* | managarm-* \
| windows-* )
basic_machine=$field1
basic_os=$maybe_os
;;
@@ -943,7 +944,7 @@ $basic_machine
EOF
IFS=$saved_IFS
;;
# We use `pc' rather than `unknown'
# We use 'pc' rather than 'unknown'
# because (1) that's what they normally are, and
# (2) the word "unknown" tends to confuse beginning users.
i*86 | x86_64)
@@ -1180,7 +1181,7 @@ case $cpu-$vendor in
case $cpu in
1750a | 580 \
| a29k \
| aarch64 | aarch64_be \
| aarch64 | aarch64_be | aarch64c | arm64ec \
| abacus \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \
@@ -1199,45 +1200,23 @@ case $cpu-$vendor in
| d10v | d30v | dlx | dsp16xx \
| e2k | elxsi | epiphany \
| f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \
| javascript \
| h8300 | h8500 \
| hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| hexagon \
| i370 | i*86 | i860 | i960 | ia16 | ia64 \
| ip2k | iq2000 \
| k1om \
| kvx \
| le32 | le64 \
| lm32 \
| loongarch32 | loongarch64 | loongarchx32 \
| loongarch32 | loongarch64 \
| m32c | m32r | m32rle \
| m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \
| m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \
| m88110 | m88k | maxq | mb | mcore | mep | metag \
| microblaze | microblazeel \
| mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \
| mips64 | mips64eb | mips64el \
| mips64octeon | mips64octeonel \
| mips64orion | mips64orionel \
| mips64r5900 | mips64r5900el \
| mips64vr | mips64vrel \
| mips64vr4100 | mips64vr4100el \
| mips64vr4300 | mips64vr4300el \
| mips64vr5000 | mips64vr5000el \
| mips64vr5900 | mips64vr5900el \
| mipsisa32 | mipsisa32el \
| mipsisa32r2 | mipsisa32r2el \
| mipsisa32r3 | mipsisa32r3el \
| mipsisa32r5 | mipsisa32r5el \
| mipsisa32r6 | mipsisa32r6el \
| mipsisa64 | mipsisa64el \
| mipsisa64r2 | mipsisa64r2el \
| mipsisa64r3 | mipsisa64r3el \
| mipsisa64r5 | mipsisa64r5el \
| mipsisa64r6 | mipsisa64r6el \
| mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \
| mipsr5900 | mipsr5900el \
| mipstx39 | mipstx39el \
| mips* \
| mmix \
| mn10200 | mn10300 \
| moxie \
@@ -1285,7 +1264,7 @@ case $cpu-$vendor in
;;
*)
echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2
echo "Invalid configuration '$1': machine '$cpu-$vendor' not recognized" 1>&2
exit 1
;;
esac
@@ -1306,11 +1285,12 @@ esac
# Decode manufacturer-specific aliases for certain operating systems.
if test x$basic_os != x
if test x"$basic_os" != x
then
# First recognize some ad-hoc cases, or perhaps split kernel-os, or else just
# set os.
obj=
case $basic_os in
gnu/linux*)
kernel=linux
@@ -1341,6 +1321,10 @@ EOF
kernel=linux
os=`echo "$basic_os" | sed -e 's|linux|gnu|'`
;;
managarm*)
kernel=managarm
os=`echo "$basic_os" | sed -e 's|managarm|mlibc|'`
;;
*)
kernel=
os=$basic_os
@@ -1506,10 +1490,16 @@ case $os in
os=eabi
;;
*)
os=elf
os=
obj=elf
;;
esac
;;
aout* | coff* | elf* | pe*)
# These are machine code file formats, not OSes
obj=$os
os=
;;
*)
# No normalization, but not necessarily accepted, that comes below.
;;
@@ -1528,12 +1518,15 @@ else
# system, and we'll never get to this point.
kernel=
obj=
case $cpu-$vendor in
score-*)
os=elf
os=
obj=elf
;;
spu-*)
os=elf
os=
obj=elf
;;
*-acorn)
os=riscix1.2
@@ -1543,28 +1536,35 @@ case $cpu-$vendor in
os=gnu
;;
arm*-semi)
os=aout
os=
obj=aout
;;
c4x-* | tic4x-*)
os=coff
os=
obj=coff
;;
c8051-*)
os=elf
os=
obj=elf
;;
clipper-intergraph)
os=clix
;;
hexagon-*)
os=elf
os=
obj=elf
;;
tic54x-*)
os=coff
os=
obj=coff
;;
tic55x-*)
os=coff
os=
obj=coff
;;
tic6x-*)
os=coff
os=
obj=coff
;;
# This must come before the *-dec entry.
pdp10-*)
@@ -1586,19 +1586,24 @@ case $cpu-$vendor in
os=sunos3
;;
m68*-cisco)
os=aout
os=
obj=aout
;;
mep-*)
os=elf
os=
obj=elf
;;
mips*-cisco)
os=elf
os=
obj=elf
;;
mips*-*)
os=elf
os=
obj=elf
;;
or32-*)
os=coff
os=
obj=coff
;;
*-tti) # must be before sparc entry or we get the wrong os.
os=sysv3
@@ -1607,7 +1612,8 @@ case $cpu-$vendor in
os=sunos4.1.1
;;
pru-*)
os=elf
os=
obj=elf
;;
*-be)
os=beos
@@ -1688,10 +1694,12 @@ case $cpu-$vendor in
os=uxpv
;;
*-rom68k)
os=coff
os=
obj=coff
;;
*-*bug)
os=coff
os=
obj=coff
;;
*-apple)
os=macos
@@ -1709,7 +1717,8 @@ esac
fi
# Now, validate our (potentially fixed-up) OS.
# Now, validate our (potentially fixed-up) individual pieces (OS, OBJ).
case $os in
# Sometimes we do "kernel-libc", so those need to count as OSes.
musl* | newlib* | relibc* | uclibc*)
@@ -1720,6 +1729,9 @@ case $os in
# VxWorks passes extra cpu info in the 4th filed.
simlinux | simwindows | spe)
;;
# See `case $cpu-$os` validation below
ghcjs)
;;
# Now accept the basic system types.
# The portable systems comes first.
# Each alternative MUST end in a * to match a version number.
@@ -1728,7 +1740,7 @@ case $os in
| hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \
| sym* | plan9* | psp* | sim* | xray* | os68k* | v88r* \
| hiux* | abug | nacl* | netware* | windows* \
| os9* | macos* | osx* | ios* \
| os9* | macos* | osx* | ios* | tvos* | watchos* \
| mpw* | magic* | mmixware* | mon960* | lnews* \
| amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \
| aos* | aros* | cloudabi* | sortix* | twizzler* \
@@ -1737,11 +1749,11 @@ case $os in
| mirbsd* | netbsd* | dicos* | openedition* | ose* \
| bitrig* | openbsd* | secbsd* | solidbsd* | libertybsd* | os108* \
| ekkobsd* | freebsd* | riscix* | lynxos* | os400* \
| bosx* | nextstep* | cxux* | aout* | elf* | oabi* \
| ptx* | coff* | ecoff* | winnt* | domain* | vsta* \
| bosx* | nextstep* | cxux* | oabi* \
| ptx* | ecoff* | winnt* | domain* | vsta* \
| udi* | lites* | ieee* | go32* | aux* | hcos* \
| chorusrdb* | cegcc* | glidix* | serenity* \
| cygwin* | msys* | pe* | moss* | proelf* | rtems* \
| cygwin* | msys* | moss* | proelf* | rtems* \
| midipix* | mingw32* | mingw64* | mint* \
| uxpv* | beos* | mpeix* | udk* | moxiebox* \
| interix* | uwin* | mks* | rhapsody* | darwin* \
@@ -1754,7 +1766,7 @@ case $os in
| onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
| midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
| nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \
| fiwix* )
| fiwix* | mlibc* | cos* | mbr* )
;;
# This one is extra strict with allowed versions
sco3.2v2 | sco3.2v[4-9]* | sco5v6*)
@@ -1762,41 +1774,99 @@ case $os in
;;
none)
;;
kernel* | msvc* )
# Restricted further below
;;
'')
if test x"$obj" = x
then
echo "Invalid configuration '$1': Blank OS only allowed with explicit machine code file format" 1>&2
fi
;;
*)
echo Invalid configuration \`"$1"\': OS \`"$os"\' not recognized 1>&2
echo "Invalid configuration '$1': OS '$os' not recognized" 1>&2
exit 1
;;
esac
case $obj in
aout* | coff* | elf* | pe*)
;;
'')
# empty is fine
;;
*)
echo "Invalid configuration '$1': Machine code format '$obj' not recognized" 1>&2
exit 1
;;
esac
# Here we handle the constraint that a (synthetic) cpu and os are
# valid only in combination with each other and nowhere else.
case $cpu-$os in
# The "javascript-unknown-ghcjs" triple is used by GHC; we
# accept it here in order to tolerate that, but reject any
# variations.
javascript-ghcjs)
;;
javascript-* | *-ghcjs)
echo "Invalid configuration '$1': cpu '$cpu' is not valid with os '$os$obj'" 1>&2
exit 1
;;
esac
# As a final step for OS-related things, validate the OS-kernel combination
# (given a valid OS), if there is a kernel.
case $kernel-$os in
linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \
| linux-musl* | linux-relibc* | linux-uclibc* )
case $kernel-$os-$obj in
linux-gnu*- | linux-dietlibc*- | linux-android*- | linux-newlib*- \
| linux-musl*- | linux-relibc*- | linux-uclibc*- | linux-mlibc*- )
;;
uclinux-uclibc* )
uclinux-uclibc*- )
;;
-dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* )
managarm-mlibc*- | managarm-kernel*- )
;;
windows*-msvc*-)
;;
-dietlibc*- | -newlib*- | -musl*- | -relibc*- | -uclibc*- | -mlibc*- )
# These are just libc implementations, not actual OSes, and thus
# require a kernel.
echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2
echo "Invalid configuration '$1': libc '$os' needs explicit kernel." 1>&2
exit 1
;;
kfreebsd*-gnu* | kopensolaris*-gnu*)
-kernel*- )
echo "Invalid configuration '$1': '$os' needs explicit kernel." 1>&2
exit 1
;;
vxworks-simlinux | vxworks-simwindows | vxworks-spe)
*-kernel*- )
echo "Invalid configuration '$1': '$kernel' does not support '$os'." 1>&2
exit 1
;;
nto-qnx*)
*-msvc*- )
echo "Invalid configuration '$1': '$os' needs 'windows'." 1>&2
exit 1
;;
os2-emx)
kfreebsd*-gnu*- | kopensolaris*-gnu*-)
;;
*-eabi* | *-gnueabi*)
vxworks-simlinux- | vxworks-simwindows- | vxworks-spe-)
;;
-*)
nto-qnx*-)
;;
os2-emx-)
;;
*-eabi*- | *-gnueabi*-)
;;
none--*)
# None (no kernel, i.e. freestanding / bare metal),
# can be paired with an machine code file format
;;
-*-)
# Blank kernel with real OS is always fine.
;;
*-*)
echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2
--*)
# Blank kernel and OS with real machine code file format is always fine.
;;
*-*-*)
echo "Invalid configuration '$1': Kernel '$kernel' not known to work with OS '$os'." 1>&2
exit 1
;;
esac
@@ -1879,7 +1949,7 @@ case $vendor in
;;
esac
echo "$cpu-$vendor-${kernel:+$kernel-}$os"
echo "$cpu-$vendor${kernel:+-$kernel}${os:+-$os}${obj:+-$obj}"
exit
# Local variables:
+18
View File
@@ -905,6 +905,22 @@ macro(CheckOpenGLES)
endif()
endmacro()
# Requires:
# - EGL
macro(CheckQNXScreen)
if(QNX AND HAVE_OPENGL_EGL)
check_c_source_compiles("
#include <screen/screen.h>
int main (int argc, char** argv) { return 0; }" HAVE_QNX_SCREEN)
if(HAVE_QNX_SCREEN)
set(SDL_VIDEO_DRIVER_QNX 1)
file(GLOB QNX_VIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/qnx/*.c)
list(APPEND SOURCE_FILES ${QNX_VIDEO_SOURCES})
list(APPEND EXTRA_LIBS screen EGL)
endif()
endif()
endmacro()
# Requires:
# - nada
# Optional:
@@ -955,6 +971,8 @@ macro(CheckPTHREAD)
elseif(EMSCRIPTEN)
set(PTHREAD_CFLAGS "-D_REENTRANT -pthread")
set(PTHREAD_LDFLAGS "-pthread")
elseif(QNX)
# pthread support is baked in
else()
set(PTHREAD_CFLAGS "-D_REENTRANT")
set(PTHREAD_LDFLAGS "-lpthread")
+4
View File
@@ -28,6 +28,8 @@ macro(SDL_DetectCMakePlatform)
set(SDL_CMAKE_PLATFORM AIX)
elseif(CMAKE_SYSTEM_NAME MATCHES "Minix.*")
set(SDL_CMAKE_PLATFORM MINIX)
elseif(CMAKE_SYSTEM_NAME MATCHES "QNX")
set(SDL_CMAKE_PLATFORM QNX)
endif()
elseif(APPLE)
if(CMAKE_SYSTEM_NAME MATCHES ".*Darwin.*")
@@ -48,6 +50,8 @@ macro(SDL_DetectCMakePlatform)
set(SDL_CMAKE_PLATFORM HAIKU)
elseif(NINTENDO_3DS)
set(SDL_CMAKE_PLATFORM N3DS)
elseif(OS2)
set(SDL_CMAKE_PLATFORM OS2)
endif()
if(SDL_CMAKE_PLATFORM)
set(${SDL_CMAKE_PLATFORM} TRUE)
Vendored
+4 -42
View File
@@ -3507,7 +3507,7 @@ orig_CFLAGS="$CFLAGS"
# See docs/release_checklist.md
SDL_MAJOR_VERSION=2
SDL_MINOR_VERSION=28
SDL_MICRO_VERSION=0
SDL_MICRO_VERSION=4
SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION
SDL_BINARY_AGE=`expr $SDL_MINOR_VERSION \* 100 + $SDL_MICRO_VERSION`
@@ -23026,41 +23026,6 @@ printf "%s\n" "$have_gcc_no_strict_aliasing" >&6; }
fi
}
CheckStackBoundary()
{
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GCC -mpreferred-stack-boundary option" >&5
printf %s "checking for GCC -mpreferred-stack-boundary option... " >&6; }
have_gcc_preferred_stack_boundary=no
save_CFLAGS="$CFLAGS"
CFLAGS="$save_CFLAGS -mpreferred-stack-boundary=2"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int x = 0;
int
main (void)
{
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
have_gcc_preferred_stack_boundary=yes
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_gcc_preferred_stack_boundary" >&5
printf "%s\n" "$have_gcc_preferred_stack_boundary" >&6; }
CFLAGS="$save_CFLAGS"
if test x$have_gcc_preferred_stack_boundary = xyes; then
EXTRA_CFLAGS="$EXTRA_CFLAGS -mpreferred-stack-boundary=2"
fi
}
CheckWerror()
{
# Check whether --enable-werror was given.
@@ -27474,9 +27439,6 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_wince" >&5
printf "%s\n" "$have_wince" >&6; }
# This fixes Windows stack alignment with newer GCC
CheckStackBoundary
# headers needed elsewhere
ac_fn_c_check_header_compile "$LINENO" "tpcshrd.h" "ac_cv_header_tpcshrd_h" "$ac_includes_default"
if test "x$ac_cv_header_tpcshrd_h" = xyes
@@ -28285,7 +28247,7 @@ fi
enable_hidapi_libusb=yes
require_hidapi_libusb=yes
;;
*-*-os2* )
*-*-os2* )
enable_hidapi_libusb=yes
;;
esac
@@ -29678,7 +29640,7 @@ printf "%s\n" "#define SDL_VIDEO_DRIVER_OS2 1" >>confdefs.h
SOURCES="$SOURCES $srcdir/src/video/os2/*.c"
have_video=yes
SUMMARY_video="${SUMMARY_video} os/2"
SUMMARY_video="${SUMMARY_video} OS/2"
fi
# Set up files for the audio library
if test x$enable_audio = xyes; then
@@ -29687,7 +29649,7 @@ printf "%s\n" "#define SDL_AUDIO_DRIVER_OS2 1" >>confdefs.h
SOURCES="$SOURCES $srcdir/src/audio/os2/*.c"
have_audio=yes
SUMMARY_audio="${SUMMARY_audio} os/2"
SUMMARY_audio="${SUMMARY_audio} OS/2"
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lmmpm2"
fi
# Set up files for the thread library
+4 -27
View File
@@ -13,7 +13,7 @@ dnl Set various version strings - taken gratefully from the GTk sources
# See docs/release_checklist.md
SDL_MAJOR_VERSION=2
SDL_MINOR_VERSION=28
SDL_MICRO_VERSION=0
SDL_MICRO_VERSION=4
SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION
SDL_BINARY_AGE=`expr $SDL_MINOR_VERSION \* 100 + $SDL_MICRO_VERSION`
@@ -1558,26 +1558,6 @@ CheckNoStrictAliasing()
fi
}
dnl See if GCC's -mpreferred-stack-boundary is supported.
dnl Reference: http://bugzilla.libsdl.org/show_bug.cgi?id=1296
CheckStackBoundary()
{
AC_MSG_CHECKING(for GCC -mpreferred-stack-boundary option)
have_gcc_preferred_stack_boundary=no
save_CFLAGS="$CFLAGS"
CFLAGS="$save_CFLAGS -mpreferred-stack-boundary=2"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
int x = 0;
]],[])], [have_gcc_preferred_stack_boundary=yes],[])
AC_MSG_RESULT($have_gcc_preferred_stack_boundary)
CFLAGS="$save_CFLAGS"
if test x$have_gcc_preferred_stack_boundary = xyes; then
EXTRA_CFLAGS="$EXTRA_CFLAGS -mpreferred-stack-boundary=2"
fi
}
dnl See if GCC's -Werror is supported.
CheckWerror()
{
@@ -3306,9 +3286,6 @@ CheckWINDOWS()
],[])
AC_MSG_RESULT($have_wince)
# This fixes Windows stack alignment with newer GCC
CheckStackBoundary
# headers needed elsewhere
AC_CHECK_HEADER(tpcshrd.h,have_tpcshrd_h=yes)
if test x$have_tpcshrd_h = xyes; then
@@ -3637,7 +3614,7 @@ CheckHIDAPI()
enable_hidapi_libusb=yes
require_hidapi_libusb=yes
;;
*-*-os2* )
*-*-os2* )
enable_hidapi_libusb=yes
;;
esac
@@ -4648,14 +4625,14 @@ dnl BeOS support removed after SDL 2.0.1. Haiku still works. --ryan.
AC_DEFINE(SDL_VIDEO_DRIVER_OS2, 1, [ ])
SOURCES="$SOURCES $srcdir/src/video/os2/*.c"
have_video=yes
SUMMARY_video="${SUMMARY_video} os/2"
SUMMARY_video="${SUMMARY_video} OS/2"
fi
# Set up files for the audio library
if test x$enable_audio = xyes; then
AC_DEFINE(SDL_AUDIO_DRIVER_OS2, 1, [ ])
SOURCES="$SOURCES $srcdir/src/audio/os2/*.c"
have_audio=yes
SUMMARY_audio="${SUMMARY_audio} os/2"
SUMMARY_audio="${SUMMARY_audio} OS/2"
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lmmpm2"
fi
# Set up files for the thread library
+7 -7
View File
@@ -13,13 +13,13 @@ supported, but you can use the "android-project-ant" directory as a template.
Requirements
================================================================================
Android SDK (version 31 or later)
Android SDK (version 34 or later)
https://developer.android.com/sdk/index.html
Android NDK r15c or later
https://developer.android.com/tools/sdk/ndk/index.html
Minimum API level supported by SDL: 16 (Android 4.1)
Minimum API level supported by SDL: 19 (Android 4.4)
How the port works
@@ -431,13 +431,13 @@ The Tegra Graphics Debugger is available from NVidia here:
https://developer.nvidia.com/tegra-graphics-debugger
Why is API level 16 the minimum required?
Why is API level 19 the minimum required?
================================================================================
The latest NDK toolchain doesn't support targeting earlier than API level 16.
As of this writing, according to https://developer.android.com/about/dashboards/index.html
about 99% of the Android devices accessing Google Play support API level 16 or
higher (January 2018).
The latest NDK toolchain doesn't support targeting earlier than API level 19.
As of this writing, according to https://www.composables.com/tools/distribution-chart
about 99.7% of the Android devices accessing Google Play support API level 19 or
higher (August 2023).
A note regarding the use of the "dirty rectangles" rendering technique
+1 -1
View File
@@ -48,7 +48,7 @@ SDL can be included in your project in 2 major ways:
The following CMake script supports both, depending on the value of `MYGAME_VENDORED`.
```cmake
cmake_minimum_required(VERSION 3.0)
cmake_minimum_required(VERSION 3.5)
project(mygame)
# Create an option to switch between a system sdl library and a vendored sdl library
+1 -1
View File
@@ -38,7 +38,7 @@ for some Javascript code to steal for this approach.
## Building SDL/emscripten
SDL currently requires at least Emscripten 2.0.32 to build. Newer versions
SDL currently requires at least Emscripten 3.1.35 to build. Newer versions
are likely to work, as well.
+1 -1
View File
@@ -3,7 +3,7 @@ Simple DirectMedia Layer 2 for OS/2 & eComStation
SDL port for OS/2, authored by Andrey Vasilkin <digi@os2.snc.ru>, 2016
OpenGL and audio capture not supported by this port.
OpenGL not supported by this port.
Additional optional environment variables:
+2
View File
@@ -55,6 +55,8 @@ assert can have unique static variables associated with it.
#define SDL_TriggerBreakpoint() __builtin_debugtrap()
#elif ( (!defined(__NACL__)) && ((defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__))) )
#define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "int $3\n\t" )
#elif (defined(__GNUC__) || defined(__clang__)) && defined(__riscv)
#define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "ebreak\n\t" )
#elif ( defined(__APPLE__) && (defined(__arm64__) || defined(__aarch64__)) ) /* this might work on other ARM targets, but this is a known quantity... */
#define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "brk #22\n\t" )
#elif defined(__APPLE__) && defined(__arm__)
+1 -1
View File
@@ -240,7 +240,7 @@ typedef void (*SDL_KernelMemoryBarrierFunc)();
/* "REP NOP" is PAUSE, coded for tools that don't know it by that name. */
#if (defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__))
#define SDL_CPUPauseInstruction() __asm__ __volatile__("pause\n") /* Some assemblers can't do REP NOP, so go with PAUSE. */
#elif (defined(__arm__) && __ARM_ARCH >= 7) || defined(__aarch64__)
#elif (defined(__arm__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7) || defined(__aarch64__)
#define SDL_CPUPauseInstruction() __asm__ __volatile__("yield" ::: "memory")
#elif (defined(__powerpc__) || defined(__powerpc64__))
#define SDL_CPUPauseInstruction() __asm__ __volatile__("or 27,27,27");
+2
View File
@@ -262,6 +262,8 @@
#cmakedefine HAVE_XINPUT_GAMEPAD_EX @HAVE_XINPUT_GAMEPAD_EX@
#cmakedefine HAVE_XINPUT_STATE_EX @HAVE_XINPUT_STATE_EX@
#cmakedefine USE_POSIX_SPAWN @USE_POSIX_SPAWN@
/* SDL internal assertion support */
#if @SDL_DEFAULT_ASSERT_LEVEL_CONFIGURED@
#cmakedefine SDL_DEFAULT_ASSERT_LEVEL @SDL_DEFAULT_ASSERT_LEVEL@
+20
View File
@@ -1007,6 +1007,15 @@ extern "C" {
*/
#define SDL_HINT_JOYSTICK_THREAD "SDL_JOYSTICK_THREAD"
/**
* \brief A variable controlling whether Windows.Gaming.Input should be used for controller handling.
*
* This variable can be set to the following values:
* "0" - WGI is not used
* "1" - WGI is used (the default)
*/
#define SDL_HINT_JOYSTICK_WGI "SDL_JOYSTICK_WGI"
/**
* \brief Determines whether SDL enforces that DRM master is required in order
* to initialize the KMSDRM video backend.
@@ -1465,6 +1474,17 @@ extern "C" {
*/
#define SDL_HINT_RENDER_VSYNC "SDL_RENDER_VSYNC"
/**
* \brief A variable controlling whether the Metal render driver select low power device over default one
*
* This variable can be set to the following values:
* "0" - Use the prefered OS device
* "1" - Select a low power one
*
* By default the prefered OS device is used.
*/
#define SDL_HINT_RENDER_METAL_PREFER_LOW_POWER_DEVICE "SDL_RENDER_METAL_PREFER_LOW_POWER_DEVICE"
/**
* \brief A variable controlling if VSYNC is automatically disable if doesn't reach the enough FPS
*
+1 -1
View File
@@ -1890,7 +1890,7 @@ extern DECLSPEC void *SDLCALL SDL_RenderGetMetalLayer(SDL_Renderer * renderer);
* Note that as of SDL 2.0.18, this will return NULL if Metal refuses to give
* SDL a drawable to render to, which might happen if the window is
* hidden/minimized/offscreen. This doesn't apply to command encoders for
* render targets, just the window's backbacker. Check your return values!
* render targets, just the window's backbuffer. Check your return values!
*
* \param renderer The renderer to query
* \returns an `id<MTLRenderCommandEncoder>` on success, or NULL if the
+1 -1
View File
@@ -59,7 +59,7 @@ typedef struct SDL_version
*/
#define SDL_MAJOR_VERSION 2
#define SDL_MINOR_VERSION 28
#define SDL_PATCHLEVEL 0
#define SDL_PATCHLEVEL 4
/**
* Macro to determine SDL version program was compiled against.
+2 -2
View File
@@ -631,9 +631,9 @@ SDL_bool SDL_IsTablet(void)
#if defined(__WIN32__)
#if (!defined(HAVE_LIBC) || defined(__WATCOMC__)) && !defined(SDL_STATIC_LIB)
/* Need to include DllMain() on Watcom C for some reason.. */
/* FIXME: Still need to include DllMain() on Watcom C ? */
BOOL APIENTRY _DllMainCRTStartup(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
BOOL APIENTRY MINGW32_FORCEALIGN _DllMainCRTStartup(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
+10 -2
View File
@@ -42,7 +42,15 @@
#endif
#if defined(__EMSCRIPTEN__)
#include <emscripten.h>
#include <emscripten.h>
/* older Emscriptens don't have this, but we need to for wasm64 compatibility. */
#ifndef MAIN_THREAD_EM_ASM_PTR
#ifdef __wasm64__
#error You need to upgrade your Emscripten compiler to support wasm64
#else
#define MAIN_THREAD_EM_ASM_PTR MAIN_THREAD_EM_ASM_INT
#endif
#endif
#endif
/* The size of the stack buffer to use for rendering assert messages. */
@@ -251,7 +259,7 @@ static SDL_assert_state SDLCALL SDL_PromptAssertion(const SDL_assert_data *data,
for (;;) {
SDL_bool okay = SDL_TRUE;
/* *INDENT-OFF* */ /* clang-format off */
char *buf = (char *) EM_ASM_INT({
char *buf = (char *) MAIN_THREAD_EM_ASM_PTR({
var str =
UTF8ToString($0) + '\n\n' +
'Abort/Retry/Ignore/AlwaysIgnore? [ariA] :';
@@ -197,6 +197,8 @@ static void EMSCRIPTENAUDIO_CloseDevice(_THIS)
#endif
}
EM_JS_DEPS(sdlaudio, "$autoResumeAudioContext,$dynCall");
static int EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname)
{
SDL_AudioFormat test_format;
+221 -70
View File
@@ -30,17 +30,12 @@
#include "../SDL_audio_c.h"
#include "SDL_os2audio.h"
/*
void lockIncr(volatile int *piVal);
#pragma aux lockIncr = \
"lock add [eax], 1 "\
parm [eax];
void lockDecr(volatile int *piVal);
#pragma aux lockDecr = \
"lock sub [eax], 1 "\
parm [eax];
*/
static PMCI_MIX_BUFFER _getNextBuffer(SDL_PrivateAudioData *pAData, PMCI_MIX_BUFFER pBuffer)
{
PMCI_MIX_BUFFER pFirstBuffer = &pAData->aMixBuffers[0];
PMCI_MIX_BUFFER pLastBuffer = &pAData->aMixBuffers[pAData->cMixBuffers -1];
return (pBuffer == pLastBuffer ? pFirstBuffer : pBuffer+1);
}
static ULONG _getEnvULong(const char *name, ULONG ulMax, ULONG ulDefault)
{
@@ -64,7 +59,7 @@ static int _MCIError(const char *func, ULONG ulResult)
static void _mixIOError(const char *function, ULONG ulRC)
{
debug_os2("%s() - failed, rc = 0x%X (%s)",
debug_os2("%s() - failed, rc = 0x%lX (%s)",
function, ulRC,
(ulRC == MCIERR_INVALID_MODE) ? "Mixer mode does not match request" :
(ulRC == MCIERR_INVALID_BUFFER) ? "Caller sent an invalid buffer" : "unknown");
@@ -73,18 +68,33 @@ static void _mixIOError(const char *function, ULONG ulRC)
static LONG APIENTRY cbAudioWriteEvent(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer,
ULONG ulFlags)
{
SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)pBuffer->ulUserParm;
SDL_AudioDevice *_this = (SDL_AudioDevice *)pBuffer->ulUserParm;
SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)_this->hidden;
ULONG ulRC;
debug_os2("cbAudioWriteEvent: ulStatus = %lu, pBuffer = %p, ulFlags = %#lX",ulStatus,pBuffer,ulFlags);
if (pAData->ulState == 2)
{
return 0;
}
if (ulFlags != MIX_WRITE_COMPLETE) {
debug_os2("flags = 0x%X", ulFlags);
debug_os2("flags = 0x%lX", ulFlags);
return 0;
}
pAData->pDrainBuffer = pBuffer;
ulRC = pAData->stMCIMixSetup.pmixWrite(pAData->stMCIMixSetup.ulMixHandle,
pAData->pDrainBuffer, 1);
if (ulRC != MCIERR_SUCCESS) {
_mixIOError("pmixWrite", ulRC);
return 0;
}
/*lockDecr((int *)&pAData->ulQueuedBuf);*/
ulRC = DosPostEventSem(pAData->hevBuf);
if (ulRC != NO_ERROR && ulRC != ERROR_ALREADY_POSTED) {
debug_os2("DosPostEventSem(), rc = %u", ulRC);
debug_os2("DosPostEventSem(), rc = %lu", ulRC);
}
return 1; /* return value doesn't seem to matter. */
@@ -93,19 +103,36 @@ static LONG APIENTRY cbAudioWriteEvent(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer,
static LONG APIENTRY cbAudioReadEvent(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer,
ULONG ulFlags)
{
SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)pBuffer->ulUserParm;
SDL_AudioDevice *_this = (SDL_AudioDevice *)pBuffer->ulUserParm;
SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)_this->hidden;
ULONG ulRC;
if (ulFlags != MIX_READ_COMPLETE) {
debug_os2("flags = 0x%X", ulFlags);
debug_os2("cbAudioReadEvent: ulStatus = %lu, pBuffer = %p, ulFlags = %#lX",ulStatus,pBuffer,ulFlags);
if (pAData->ulState == 2)
{
return 0;
}
pAData->stMCIMixSetup.pmixRead(pAData->stMCIMixSetup.ulMixHandle, pBuffer, 1);
if (ulFlags != MIX_READ_COMPLETE) {
debug_os2("flags = 0x%lX", ulFlags);
return 0;
}
pAData->pFillBuffer = pBuffer;
if (pAData->pFillBuffer == pAData->aMixBuffers)
{
ulRC = pAData->stMCIMixSetup.pmixRead(pAData->stMCIMixSetup.ulMixHandle,
pAData->pFillBuffer, pAData->cMixBuffers);
if (ulRC != MCIERR_SUCCESS) {
_mixIOError("pmixRead", ulRC);
return 0;
}
}
ulRC = DosPostEventSem(pAData->hevBuf);
if (ulRC != NO_ERROR && ulRC != ERROR_ALREADY_POSTED) {
debug_os2("DosPostEventSem(), rc = %u", ulRC);
debug_os2("DosPostEventSem(), rc = %lu", ulRC);
}
return 1;
@@ -120,31 +147,36 @@ static void OS2_DetectDevices(void)
MCI_SYSINFO_LOGDEVICE stLogDevice;
MCI_SYSINFO_PARMS stSysInfoParams;
ULONG ulRC;
ULONG ulHandle = 0;
ULONG ulNumber;
MCI_GETDEVCAPS_PARMS stDevCapsParams;
MCI_OPEN_PARMS stMCIOpen;
MCI_GENERIC_PARMS stMCIGenericParams;
SDL_memset(&stMCISysInfo, 0, sizeof(stMCISysInfo));
acBuf[0] = '\0';
stMCISysInfo.pszReturn = acBuf;
stMCISysInfo.ulRetSize = sizeof(acBuf);
stMCISysInfo.usDeviceType = MCI_DEVTYPE_AUDIO_AMPMIX;
ulRC = mciSendCommand(0, MCI_SYSINFO, MCI_WAIT | MCI_SYSINFO_QUANTITY,
&stMCISysInfo, 0);
if (ulRC != NO_ERROR) {
debug_os2("MCI_SYSINFO, MCI_SYSINFO_QUANTITY - failed, rc = 0x%X", ulRC);
if (LOUSHORT(ulRC) != MCIERR_SUCCESS) {
debug_os2("MCI_SYSINFO, MCI_SYSINFO_QUANTITY - failed, rc = 0x%hX", LOUSHORT(ulRC));
return;
}
ulDevicesNum = SDL_strtoul(stMCISysInfo.pszReturn, NULL, 10);
for (stSysInfoParams.ulNumber = 0; stSysInfoParams.ulNumber < ulDevicesNum;
stSysInfoParams.ulNumber++) {
for (ulNumber = 1; ulNumber <= ulDevicesNum;
ulNumber++) {
/* Get device install name. */
stSysInfoParams.ulNumber = ulNumber;
stSysInfoParams.pszReturn = acBuf;
stSysInfoParams.ulRetSize = sizeof(acBuf);
stSysInfoParams.usDeviceType = MCI_DEVTYPE_AUDIO_AMPMIX;
ulRC = mciSendCommand(0, MCI_SYSINFO, MCI_WAIT | MCI_SYSINFO_INSTALLNAME,
&stSysInfoParams, 0);
if (ulRC != NO_ERROR) {
debug_os2("MCI_SYSINFO, MCI_SYSINFO_INSTALLNAME - failed, rc = 0x%X", ulRC);
if (LOUSHORT(ulRC) != MCIERR_SUCCESS) {
debug_os2("MCI_SYSINFO, MCI_SYSINFO_INSTALLNAME - failed, rc = 0x%hX", LOUSHORT(ulRC));
continue;
}
@@ -154,15 +186,45 @@ static void OS2_DetectDevices(void)
SDL_strlcpy(stLogDevice.szInstallName, stSysInfoParams.pszReturn, MAX_DEVICE_NAME);
ulRC = mciSendCommand(0, MCI_SYSINFO, MCI_WAIT | MCI_SYSINFO_ITEM,
&stSysInfoParams, 0);
if (ulRC != NO_ERROR) {
debug_os2("MCI_SYSINFO, MCI_SYSINFO_ITEM - failed, rc = 0x%X", ulRC);
if (LOUSHORT(ulRC) != MCIERR_SUCCESS) {
debug_os2("MCI_SYSINFO, MCI_SYSINFO_ITEM - failed, rc = 0x%hX", LOUSHORT(ulRC));
continue;
}
ulHandle++;
SDL_AddAudioDevice(0, stLogDevice.szProductInfo, NULL, (void *)(ulHandle));
ulHandle++;
SDL_AddAudioDevice(1, stLogDevice.szProductInfo, NULL, (void *)(ulHandle));
SDL_AddAudioDevice(0, stLogDevice.szProductInfo, NULL, (void *)ulNumber);
/* Open audio device for querying its capabilities */
/* at this point we HAVE TO OPEN the waveaudio device and not the ampmix device */
/* because only the waveaudio device (tied to the ampmix device) supports querying for playback/record capability */
SDL_memset(&stMCIOpen, 0, sizeof(stMCIOpen));
stMCIOpen.pszDeviceType = (PSZ)MAKEULONG(MCI_DEVTYPE_WAVEFORM_AUDIO,LOUSHORT(ulNumber));
ulRC = mciSendCommand(0, MCI_OPEN,MCI_WAIT | MCI_OPEN_TYPE_ID | MCI_OPEN_SHAREABLE,&stMCIOpen, 0);
if (LOUSHORT(ulRC) != MCIERR_SUCCESS) {
debug_os2("MCI_OPEN (getDevCaps) - failed");
continue;
}
/* check for recording capability */
SDL_memset(&stDevCapsParams, 0, sizeof(stDevCapsParams));
stDevCapsParams.ulItem = MCI_GETDEVCAPS_CAN_RECORD;
ulRC = mciSendCommand(stMCIOpen.usDeviceID, MCI_GETDEVCAPS, MCI_WAIT | MCI_GETDEVCAPS_ITEM,
&stDevCapsParams, 0);
if (LOUSHORT(ulRC) != MCIERR_SUCCESS) {
debug_os2("MCI_GETDEVCAPS, MCI_GETDEVCAPS_ITEM - failed, rc = 0x%hX", LOUSHORT(ulRC));
}
else {
if (stDevCapsParams.ulReturn) {
SDL_AddAudioDevice(1, stLogDevice.szProductInfo, NULL, (void *)(ulNumber | 0x80000000));
}
}
/* close the audio device, we are done querying its capabilities */
SDL_memset(&stMCIGenericParams, 0, sizeof(stMCIGenericParams));
ulRC = mciSendCommand(stMCIOpen.usDeviceID, MCI_CLOSE, MCI_WAIT,
&stMCIGenericParams, 0);
if (LOUSHORT(ulRC) != MCIERR_SUCCESS) {
debug_os2("MCI_CLOSE (getDevCaps) - failed");
}
}
}
@@ -171,52 +233,145 @@ static void OS2_WaitDevice(_THIS)
SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)_this->hidden;
ULONG ulRC;
debug_os2("Enter");
/* Wait for an audio chunk to finish */
ulRC = DosWaitEventSem(pAData->hevBuf, 5000);
if (ulRC != NO_ERROR) {
debug_os2("DosWaitEventSem(), rc = %u", ulRC);
debug_os2("DosWaitEventSem(), rc = %lu", ulRC);
}
}
static Uint8 *OS2_GetDeviceBuf(_THIS)
{
SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)_this->hidden;
return (Uint8 *) pAData->aMixBuffers[pAData->ulNextBuf].pBuffer;
debug_os2("Enter");
return (Uint8 *) pAData->pFillBuffer->pBuffer;
}
static void OS2_PlayDevice(_THIS)
{
SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)_this->hidden;
ULONG ulRC;
PMCI_MIX_BUFFER pMixBuffer = &pAData->aMixBuffers[pAData->ulNextBuf];
PMCI_MIX_BUFFER pMixBuffer = NULL;
/* Queue it up */
/*lockIncr((int *)&pAData->ulQueuedBuf);*/
ulRC = pAData->stMCIMixSetup.pmixWrite(pAData->stMCIMixSetup.ulMixHandle,
pMixBuffer, 1);
if (ulRC != MCIERR_SUCCESS) {
_mixIOError("pmixWrite", ulRC);
} else {
pAData->ulNextBuf = (pAData->ulNextBuf + 1) % pAData->cMixBuffers;
debug_os2("Enter");
pMixBuffer = pAData->pDrainBuffer;
pAData->pFillBuffer = _getNextBuffer(pAData, pAData->pFillBuffer);
if (!pAData->ulState && pAData->pFillBuffer != pMixBuffer)
{
/*
* this buffer was filled but we have not yet filled all buffers
* so just signal event sem so that OS2_WaitDevice does not need
* to block
*/
ulRC = DosPostEventSem(pAData->hevBuf);
}
if (!pAData->ulState && (pAData->pFillBuffer == pMixBuffer) )
{
debug_os2("!hasStarted");
pAData->ulState = 1;
/* Write buffers to kick off the amp mixer */
ulRC = pAData->stMCIMixSetup.pmixWrite(pAData->stMCIMixSetup.ulMixHandle,
pMixBuffer, pAData->cMixBuffers);
if (ulRC != MCIERR_SUCCESS) {
_mixIOError("pmixWrite", ulRC);
}
}
}
static int OS2_CaptureFromDevice(_THIS,void *buffer,int buflen)
{
SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)_this->hidden;
ULONG ulRC;
PMCI_MIX_BUFFER pMixBuffer = NULL;
int len = 0;
if (!pAData->ulState)
{
pAData->ulState = 1;
ulRC = pAData->stMCIMixSetup.pmixRead(pAData->stMCIMixSetup.ulMixHandle,
pAData->aMixBuffers, pAData->cMixBuffers);
if (ulRC != MCIERR_SUCCESS) {
_mixIOError("pmixRead", ulRC);
return -1;
}
}
/* Wait for an audio chunk to finish */
ulRC = DosWaitEventSem(pAData->hevBuf, 5000);
if (ulRC != NO_ERROR)
{
debug_os2("DosWaitEventSem(), rc = %lu", ulRC);
return -1;
}
pMixBuffer = pAData->pDrainBuffer;
len = SDL_min((int)pMixBuffer->ulBufferLength, buflen);
SDL_memcpy(buffer,pMixBuffer->pBuffer, len);
pAData->pDrainBuffer = _getNextBuffer(pAData, pMixBuffer);
debug_os2("buflen = %u, ulBufferLength = %lu",buflen,pMixBuffer->ulBufferLength);
return len;
}
static void OS2_FlushCapture(_THIS)
{
SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)_this->hidden;
ULONG ulIdx;
debug_os2("Enter");
/* Fill all device buffers with data */
for (ulIdx = 0; ulIdx < pAData->cMixBuffers; ulIdx++) {
pAData->aMixBuffers[ulIdx].ulFlags = 0;
pAData->aMixBuffers[ulIdx].ulBufferLength = _this->spec.size;
pAData->aMixBuffers[ulIdx].ulUserParm = (ULONG)_this;
SDL_memset(((PMCI_MIX_BUFFER)pAData->aMixBuffers)[ulIdx].pBuffer,
_this->spec.silence, _this->spec.size);
}
pAData->pFillBuffer = pAData->aMixBuffers;
pAData->pDrainBuffer = pAData->aMixBuffers;
}
static void OS2_CloseDevice(_THIS)
{
SDL_PrivateAudioData *pAData = (SDL_PrivateAudioData *)_this->hidden;
MCI_GENERIC_PARMS sMCIGenericParms;
ULONG ulRC;
debug_os2("Enter");
if (pAData == NULL)
return;
pAData->ulState = 2;
/* Close up audio */
if (pAData->usDeviceId != (USHORT)~0) { /* Device is open. */
SDL_zero(sMCIGenericParms);
ulRC = mciSendCommand(pAData->usDeviceId, MCI_STOP,
MCI_WAIT,
&sMCIGenericParms, 0);
if (LOUSHORT(ulRC) != MCIERR_SUCCESS) {
debug_os2("MCI_STOP - failed" );
}
if (pAData->stMCIMixSetup.ulBitsPerSample != 0) { /* Mixer was initialized. */
ulRC = mciSendCommand(pAData->usDeviceId, MCI_MIXSETUP,
MCI_WAIT | MCI_MIXSETUP_DEINIT,
&pAData->stMCIMixSetup, 0);
if (ulRC != MCIERR_SUCCESS) {
if (LOUSHORT(ulRC) != MCIERR_SUCCESS) {
debug_os2("MCI_MIXSETUP, MCI_MIXSETUP_DEINIT - failed");
}
}
@@ -230,14 +385,14 @@ static void OS2_CloseDevice(_THIS)
ulRC = mciSendCommand(pAData->usDeviceId, MCI_BUFFER,
MCI_WAIT | MCI_DEALLOCATE_MEMORY, &stMCIBuffer, 0);
if (ulRC != MCIERR_SUCCESS) {
if (LOUSHORT(ulRC) != MCIERR_SUCCESS) {
debug_os2("MCI_BUFFER, MCI_DEALLOCATE_MEMORY - failed");
}
}
ulRC = mciSendCommand(pAData->usDeviceId, MCI_CLOSE, MCI_WAIT,
&sMCIGenericParms, 0);
if (ulRC != MCIERR_SUCCESS) {
if (LOUSHORT(ulRC) != MCIERR_SUCCESS) {
debug_os2("MCI_CLOSE - failed");
}
}
@@ -257,6 +412,7 @@ static int OS2_OpenDevice(_THIS, const char *devname)
ULONG ulRC;
ULONG ulIdx;
BOOL new_freq;
ULONG ulHandle = (ULONG)_this->handle;
SDL_bool iscapture = _this->iscapture;
new_freq = FALSE;
@@ -279,20 +435,21 @@ static int OS2_OpenDevice(_THIS, const char *devname)
ulRC = DosCreateEventSem(NULL, &pAData->hevBuf, DCE_AUTORESET, TRUE);
if (ulRC != NO_ERROR) {
debug_os2("DosCreateEventSem() failed, rc = %u", ulRC);
debug_os2("DosCreateEventSem() failed, rc = %lu", ulRC);
return -1;
}
/* Open audio device */
stMCIAmpOpen.usDeviceID = (_this->handle != NULL) ? ((ULONG)_this->handle - 1) : 0;
stMCIAmpOpen.pszDeviceType = (PSZ)MCI_DEVTYPE_AUDIO_AMPMIX;
stMCIAmpOpen.usDeviceID = 0;
stMCIAmpOpen.pszDeviceType = (PSZ)MAKEULONG(MCI_DEVTYPE_AUDIO_AMPMIX,LOUSHORT(ulHandle));
ulRC = mciSendCommand(0, MCI_OPEN,
(_getEnvULong("SDL_AUDIO_SHARE", 1, 0) != 0)?
MCI_WAIT | MCI_OPEN_TYPE_ID | MCI_OPEN_SHAREABLE :
MCI_WAIT | MCI_OPEN_TYPE_ID,
&stMCIAmpOpen, 0);
if (ulRC != MCIERR_SUCCESS) {
stMCIAmpOpen.usDeviceID = (USHORT)~0;
if (LOUSHORT(ulRC) != MCIERR_SUCCESS) {
DosCloseEventSem(pAData->hevBuf);
pAData->usDeviceId = (USHORT)~0;
return _MCIError("MCI_OPEN", ulRC);
}
pAData->usDeviceId = stMCIAmpOpen.usDeviceID;
@@ -355,7 +512,7 @@ static int OS2_OpenDevice(_THIS, const char *devname)
ulRC = mciSendCommand(pAData->usDeviceId, MCI_MIXSETUP,
MCI_WAIT | MCI_MIXSETUP_INIT, &pAData->stMCIMixSetup, 0);
if (ulRC != MCIERR_SUCCESS && _this->spec.freq > 44100) {
if (LOUSHORT(ulRC) != MCIERR_SUCCESS && _this->spec.freq > 44100) {
new_freq = TRUE;
pAData->stMCIMixSetup.ulSamplesPerSec = 44100;
_this->spec.freq = 44100;
@@ -363,7 +520,7 @@ static int OS2_OpenDevice(_THIS, const char *devname)
MCI_WAIT | MCI_MIXSETUP_INIT, &pAData->stMCIMixSetup, 0);
}
debug_os2("Setup mixer [BPS: %u, Freq.: %u, Channels: %u]: %s",
debug_os2("Setup mixer [BPS: %lu, Freq.: %lu, Channels: %lu]: %s",
pAData->stMCIMixSetup.ulBitsPerSample,
pAData->stMCIMixSetup.ulSamplesPerSec,
pAData->stMCIMixSetup.ulChannels,
@@ -394,29 +551,25 @@ static int OS2_OpenDevice(_THIS, const char *devname)
ulRC = mciSendCommand(pAData->usDeviceId, MCI_BUFFER,
MCI_WAIT | MCI_ALLOCATE_MEMORY, &stMCIBuffer, 0);
if (ulRC != MCIERR_SUCCESS) {
if (LOUSHORT(ulRC) != MCIERR_SUCCESS) {
return _MCIError("MCI_BUFFER", ulRC);
}
pAData->cMixBuffers = stMCIBuffer.ulNumBuffers;
_this->spec.size = stMCIBuffer.ulBufferSize;
debug_os2("%s, number of mix buffers: %lu",iscapture ? "capture": "play",pAData->cMixBuffers);
/* Fill all device buffers with data */
for (ulIdx = 0; ulIdx < stMCIBuffer.ulNumBuffers; ulIdx++) {
pAData->aMixBuffers[ulIdx].ulFlags = 0;
pAData->aMixBuffers[ulIdx].ulBufferLength = stMCIBuffer.ulBufferSize;
pAData->aMixBuffers[ulIdx].ulUserParm = (ULONG)pAData;
pAData->aMixBuffers[ulIdx].ulUserParm = (ULONG)_this;
SDL_memset(((PMCI_MIX_BUFFER)stMCIBuffer.pBufList)[ulIdx].pBuffer,
_this->spec.silence, stMCIBuffer.ulBufferSize);
}
/* Write buffers to kick off the amp mixer */
ulRC = pAData->stMCIMixSetup.pmixWrite(pAData->stMCIMixSetup.ulMixHandle,
pAData->aMixBuffers, 1);
if (ulRC != MCIERR_SUCCESS) {
_mixIOError("pmixWrite", ulRC);
return -1;
}
pAData->pFillBuffer = pAData->aMixBuffers;
pAData->pDrainBuffer = pAData->aMixBuffers;
return 0;
}
@@ -431,12 +584,10 @@ static SDL_bool OS2_Init(SDL_AudioDriverImpl * impl)
impl->WaitDevice = OS2_WaitDevice;
impl->GetDeviceBuf = OS2_GetDeviceBuf;
impl->CloseDevice = OS2_CloseDevice;
/* TODO: IMPLEMENT CAPTURE SUPPORT:
impl->CaptureFromDevice = ;
impl->FlushCapture = ;
impl->CaptureFromDevice = OS2_CaptureFromDevice ;
impl->FlushCapture = OS2_FlushCapture;
impl->HasCaptureSupport = SDL_TRUE;
*/
return SDL_TRUE; /* this audio target is available. */
}
+3 -2
View File
@@ -43,10 +43,11 @@ typedef struct SDL_PrivateAudioData
BYTE _pad[2];
MCI_MIXSETUP_PARMS stMCIMixSetup;
HEV hevBuf;
ULONG ulNextBuf;
PMCI_MIX_BUFFER pFillBuffer;
PMCI_MIX_BUFFER pDrainBuffer;
ULONG ulState;
ULONG cMixBuffers;
MCI_MIX_BUFFER aMixBuffers[NUM_BUFFERS];
/* ULONG ulQueuedBuf;*/
} SDL_PrivateAudioData;
#endif /* SDL_os2mm_h_ */
+2
View File
@@ -233,6 +233,7 @@ static Uint8 *QSA_GetDeviceBuf(_THIS)
static void QSA_CloseDevice(_THIS)
{
if (this->hidden->audio_handle != NULL) {
#if _NTO_VERSION < 710
if (!this->iscapture) {
/* Finish playing available samples */
snd_pcm_plugin_flush(this->hidden->audio_handle,
@@ -242,6 +243,7 @@ static void QSA_CloseDevice(_THIS)
snd_pcm_plugin_flush(this->hidden->audio_handle,
SND_PCM_CHANNEL_CAPTURE);
}
#endif
snd_pcm_close(this->hidden->audio_handle);
}
-1
View File
@@ -401,7 +401,6 @@ void SDL_Fcitx_SetFocus(SDL_bool focused)
void SDL_Fcitx_Reset(void)
{
FcitxClientICCallMethod(&fcitx_client, "Reset");
FcitxClientICCallMethod(&fcitx_client, "CloseIC");
}
SDL_bool SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state)
+13
View File
@@ -76,6 +76,19 @@
#define WINVER _WIN32_WINNT
#endif
/* See https://github.com/libsdl-org/SDL/pull/7607 */
/* force_align_arg_pointer attribute requires gcc >= 4.2.x. */
#if defined(__clang__)
#define HAVE_FORCE_ALIGN_ARG_POINTER
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
#define HAVE_FORCE_ALIGN_ARG_POINTER
#endif
#if defined(__GNUC__) && defined(__i386__) && defined(HAVE_FORCE_ALIGN_ARG_POINTER)
#define MINGW32_FORCEALIGN __attribute__((force_align_arg_pointer))
#else
#define MINGW32_FORCEALIGN
#endif
#include <windows.h>
#include <basetyps.h> /* for REFIID with broken mingw.org headers */
+24 -7
View File
@@ -34,7 +34,8 @@
/* Global keyboard information */
#define KEYBOARD_HARDWARE 0x01
#define KEYBOARD_AUTORELEASE 0x02
#define KEYBOARD_VIRTUAL 0x02
#define KEYBOARD_AUTORELEASE 0x04
typedef struct SDL_Keyboard SDL_Keyboard;
@@ -47,6 +48,7 @@ struct SDL_Keyboard
Uint8 keystate[SDL_NUM_SCANCODES];
SDL_Keycode keymap[SDL_NUM_SCANCODES];
SDL_bool autorelease_pending;
Uint32 hardware_timestamp;
};
static SDL_Keyboard SDL_keyboard;
@@ -865,7 +867,9 @@ static int SDL_SendKeyboardKeyInternal(Uint8 source, Uint8 state, SDL_Scancode s
keycode = keyboard->keymap[scancode];
}
if (source == KEYBOARD_AUTORELEASE) {
if (source == KEYBOARD_HARDWARE) {
keyboard->hardware_timestamp = SDL_GetTicks();
} else if (source == KEYBOARD_AUTORELEASE) {
keyboard->autorelease_pending = SDL_TRUE;
}
@@ -965,20 +969,25 @@ int SDL_SendKeyboardUnicodeKey(Uint32 ch)
if (mod & KMOD_SHIFT) {
/* If the character uses shift, press shift down */
SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LSHIFT);
SDL_SendKeyboardKeyInternal(KEYBOARD_VIRTUAL, SDL_PRESSED, SDL_SCANCODE_LSHIFT, SDLK_UNKNOWN);
}
/* Send a keydown and keyup for the character */
SDL_SendKeyboardKey(SDL_PRESSED, code);
SDL_SendKeyboardKey(SDL_RELEASED, code);
SDL_SendKeyboardKeyInternal(KEYBOARD_VIRTUAL, SDL_PRESSED, code, SDLK_UNKNOWN);
SDL_SendKeyboardKeyInternal(KEYBOARD_VIRTUAL, SDL_RELEASED, code, SDLK_UNKNOWN);
if (mod & KMOD_SHIFT) {
/* If the character uses shift, release shift */
SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LSHIFT);
SDL_SendKeyboardKeyInternal(KEYBOARD_VIRTUAL, SDL_RELEASED, SDL_SCANCODE_LSHIFT, SDLK_UNKNOWN);
}
return 0;
}
int SDL_SendVirtualKeyboardKey(Uint8 state, SDL_Scancode scancode)
{
return SDL_SendKeyboardKeyInternal(KEYBOARD_VIRTUAL, state, scancode, SDLK_UNKNOWN);
}
int SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode)
{
return SDL_SendKeyboardKeyInternal(KEYBOARD_HARDWARE, state, scancode, SDLK_UNKNOWN);
@@ -1007,6 +1016,13 @@ void SDL_ReleaseAutoReleaseKeys(void)
}
keyboard->autorelease_pending = SDL_FALSE;
}
if (keyboard->hardware_timestamp) {
/* Keep hardware keyboard "active" for 250 ms */
if (SDL_TICKS_PASSED(SDL_GetTicks(), keyboard->hardware_timestamp + 250)) {
keyboard->hardware_timestamp = 0;
}
}
}
SDL_bool SDL_HardwareKeyboardKeyPressed(void)
@@ -1019,7 +1035,8 @@ SDL_bool SDL_HardwareKeyboardKeyPressed(void)
return SDL_TRUE;
}
}
return SDL_FALSE;
return keyboard->hardware_timestamp ? SDL_TRUE : SDL_FALSE;
}
int SDL_SendKeyboardText(const char *text)
+3
View File
@@ -52,6 +52,9 @@ extern void SDL_SetKeyboardFocus(SDL_Window *window);
*/
extern int SDL_SendKeyboardUnicodeKey(Uint32 ch);
/* Send a key from a virtual key source, like an on-screen keyboard */
extern int SDL_SendVirtualKeyboardKey(Uint8 state, SDL_Scancode scancode);
/* Send a keyboard key event */
extern int SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode);
extern int SDL_SendKeyboardKeyAutoRelease(SDL_Scancode scancode);
+5 -4
View File
@@ -277,8 +277,9 @@ windows_file_write(SDL_RWops *context, const void *ptr, size_t size,
/* if in append mode, we must go to the EOF before write */
if (context->hidden.windowsio.append) {
if (SetFilePointer(context->hidden.windowsio.h, 0L, NULL, FILE_END) ==
INVALID_SET_FILE_POINTER) {
LARGE_INTEGER windowsoffset;
windowsoffset.QuadPart = 0;
if (!SetFilePointerEx(context->hidden.windowsio.h, windowsoffset, &windowsoffset, FILE_END)) {
SDL_Error(SDL_EFWRITE);
return 0;
}
@@ -647,7 +648,7 @@ SDL_RWops *SDL_RWFromMem(void *mem, int size)
SDL_InvalidParamError("mem");
return rwops;
}
if (!size) {
if (size <= 0) {
SDL_InvalidParamError("size");
return rwops;
}
@@ -674,7 +675,7 @@ SDL_RWops *SDL_RWFromConstMem(const void *mem, int size)
SDL_InvalidParamError("mem");
return rwops;
}
if (!size) {
if (size <= 0) {
SDL_InvalidParamError("size");
return rwops;
}
+3 -3
View File
@@ -884,9 +884,9 @@ int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data,
unsigned char report = data[0];
res = ioctl(dev->device_handle, HIDIOCGFEATURE(length), data);
if (res < 0)
perror("ioctl (GFEATURE)");
else if (dev->needs_ble_hack) {
if (res < 0) {
/* perror("ioctl (GFEATURE)"); */
} else if (dev->needs_ble_hack) {
/* Versions of BlueZ before 5.56 don't include the report in the data,
* and versions of BlueZ >= 5.56 include 2 copies of the report.
* We'll fix it so that there is a single copy of the report in both cases
+9 -1
View File
@@ -572,7 +572,9 @@ static ControllerMapping_t *SDL_CreateMappingForHIDAPIController(SDL_JoystickGUI
/* GameCube driver has 12 buttons and 6 axes */
SDL_strlcat(mapping_string, "a:b0,b:b1,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3,start:b8,x:b2,y:b3,", sizeof(mapping_string));
} else if (vendor == USB_VENDOR_NINTENDO &&
(guid.data[15] == k_eSwitchDeviceInfoControllerType_NESLeft ||
(guid.data[15] == k_eSwitchDeviceInfoControllerType_HVCLeft ||
guid.data[15] == k_eSwitchDeviceInfoControllerType_HVCRight ||
guid.data[15] == k_eSwitchDeviceInfoControllerType_NESLeft ||
guid.data[15] == k_eSwitchDeviceInfoControllerType_NESRight ||
guid.data[15] == k_eSwitchDeviceInfoControllerType_SNES ||
guid.data[15] == k_eSwitchDeviceInfoControllerType_N64 ||
@@ -582,6 +584,12 @@ static ControllerMapping_t *SDL_CreateMappingForHIDAPIController(SDL_JoystickGUI
guid.data[15] == k_eSwitchDeviceInfoControllerType_JoyConLeft ||
guid.data[15] == k_eSwitchDeviceInfoControllerType_JoyConRight)) {
switch (guid.data[15]) {
case k_eSwitchDeviceInfoControllerType_HVCLeft:
SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,rightshoulder:b10,start:b6,", sizeof(mapping_string));
break;
case k_eSwitchDeviceInfoControllerType_HVCRight:
SDL_strlcat(mapping_string, "a:b0,b:b1,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,rightshoulder:b10,", sizeof(mapping_string));
break;
case k_eSwitchDeviceInfoControllerType_NESLeft:
case k_eSwitchDeviceInfoControllerType_NESRight:
SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,rightshoulder:b10,start:b6,", sizeof(mapping_string));
+5 -10
View File
@@ -134,9 +134,7 @@ static const char *s_ControllerMappings[] = {
"03000000b80500000610000000000000,Elecom Gamepad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b1,",
"03000000852100000201000000000000,FF-GP1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"030000000d0f00002700000000000000,FIGHTING STICK V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,",
"03000000151900004000000000000000,Flydigi Vader 2,a:b27,b:b26,back:b19,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b23,leftstick:b17,lefttrigger:b21,leftx:a0,lefty:a1,misc1:b15,paddle1:b11,paddle2:b10,paddle3:b13,paddle4:b12,rightshoulder:b22,rightstick:b16,righttrigger:b20,rightx:a3,righty:a4,start:b18,x:b25,y:b24,", /* Bluetooth */
"03000000b40400001124000000000000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:b8,leftx:a0,lefty:a1,misc1:b14,paddle1:b4,paddle2:b5,paddle3:b16,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b2,y:b3,", /* Dongle */
"03000000b40400001224000000000000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:b8,leftx:a0,lefty:a1,misc1:b2,paddle1:b16,paddle2:b17,paddle3:b14,paddle4:b15,rightshoulder:b7,rightstick:b13,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,", /* Wired */
"03000000790000000600000000000000,G-Shark GS-GP702,crc:8e4f,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,",
"030000008f0e00000d31000000000000,GAMEPAD 3 TURBO,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"03000000300f00000b01000000000000,GGE909 Recoil Pad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,",
"03000000790000002201000000000000,Game Controller for PC,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,",
@@ -416,9 +414,6 @@ static const char *s_ControllerMappings[] = {
"03000000a306000022f6000001030000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,",
"030000000d0f00008400000000010000,Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
"030000000d0f00008500000000010000,Fighting Commander,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"03000000151900004000000001000000,Flydigi Vader 2,a:b14,b:b15,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,paddle1:b2,paddle2:b5,paddle3:b16,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b0,y:b1,", /* Bluetooth */
"03000000b40400001124000001040000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b14,paddle1:b2,paddle2:b5,paddle3:b16,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", /* Dongle */
"03000000b40400001224000003030000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b2,paddle1:b16,paddle2:b17,paddle3:b14,paddle4:b15,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", /* Wired */
"03000000ac0500001a06000002020000,GameSir-T3 2.02,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
"0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
"03000000c01100000140000000010000,GameStop PS4 Fun Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
@@ -610,9 +605,6 @@ static const char *s_ControllerMappings[] = {
"050000004c050000f20d000000010000,DualSense Edge Wireless Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
"030000006f0e00003001000001010000,EA Sports PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"03000000790000001100000010010000,Elecom Gamepad,crc:e86c,a:b2,b:b3,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b0,y:b1,",
"03000000b40400001124000011010000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b14,paddle1:b2,paddle2:b5,paddle3:b16,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", /* Dongle */
"03000000b40400001224000011010000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b2,paddle1:b16,paddle2:b17,paddle3:b14,paddle4:b15,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", /* Wired */
"05000000151900004000000001000000,Flydigi Vader 2,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b12,lefttrigger:a5,leftx:a0,lefty:a1,misc1:b14,paddle1:b2,paddle2:b5,paddle3:b16,paddle4:b17,rightshoulder:b7,rightstick:b13,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", /* Bluetooth */
"0300000079000000d418000000010000,GPD Win 2 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"0500000047532067616d657061640000,GS Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
"03000000341a000005f7000010010000,GameCube {HuiJia USB box},a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,",
@@ -660,6 +652,7 @@ static const char *s_ControllerMappings[] = {
"03000000300f00001001000010010000,Jess Tech Dual Analog Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,",
"03000000ba2200002010000001010000,Jess Technology USB Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,",
"030000006f0e00000103000000020000,Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"030000006d040000d1ca000011010000,Logitech Chillstream,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"030000006d04000016c2000010010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
"030000006d04000016c2000011010000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
@@ -823,6 +816,7 @@ static const char *s_ControllerMappings[] = {
"05000000de2800000212000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,",
"05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,",
"05000000de2800000611000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,",
"03000000de2800000512000011010000,Steam Deck,a:b3,b:b4,back:b11,dpdown:b17,dpleft:b18,dpright:b19,dpup:b16,guide:b13,leftshoulder:b7,leftstick:b14,lefttrigger:a9,leftx:a0,lefty:a1,misc1:b2,paddle1:b21,paddle2:b20,paddle3:b23,paddle4:b22,rightshoulder:b8,rightstick:b15,righttrigger:a8,rightx:a2,righty:a3,start:b12,x:b5,y:b6,",
"03000000de280000ff11000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"0500000011010000311400001b010000,SteelSeries Stratus Duo,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b32,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
"05000000110100001914000009010000,SteelSeries Stratus XL,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b18,leftshoulder:b6,leftstick:b13,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:+a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
@@ -855,6 +849,8 @@ static const char *s_ControllerMappings[] = {
"0000000058626f782033363020576900,Xbox 360 Wireless Controller,a:b0,b:b1,back:b14,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b7,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,",
"030000005e040000a102000014010000,Xbox 360 Wireless Receiver (XBOX),a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"0000000058626f782047616d65706100,Xbox Gamepad (userspace driver),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,",
"050000005e040000e002000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"050000005e040000fd02000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
"05000000172700004431000029010000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,",
"03000000c0160000e105000010010000,Xin-Mo Dual Arcade,crc:82d5,a:b1,b:b2,back:b9,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,rightshoulder:b4,righttrigger:b5,start:b8,x:b0,y:b3,", /* Ultimate Atari Fight Stick */
"03000000120c0000100e000011010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
@@ -906,7 +902,6 @@ static const char *s_ControllerMappings[] = {
"05000000c82d000018900000ffff0f00,8BitDo Zero 2,a:b1,b:b0,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"05000000c82d000030320000ffff0f00,8BitDo Zero 2,a:b0,b:b1,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"05000000c82d000030320000ffff0f00,8BitDo Zero 2,a:b1,b:b0,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"05000000b404000011240000dfff3f00,Flydigi Vader 2,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,paddle1:b17,paddle2:b18,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,",
"05000000d6020000e5890000dfff3f80,GPD XD Plus,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a3,rightx:a4,righty:a5,start:b6,x:b2,y:b3,",
"0500000031366332860c44aadfff0f00,GS Gamepad,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:b15,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b16,rightx:a2,righty:a3,start:b6,x:b2,y:b3,",
"05000000bc20000000550000ffff3f00,GameSir G3w,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,",
+17 -3
View File
@@ -221,10 +221,10 @@ static int SDL_FindFreePlayerIndex()
for (player_index = 0; player_index < SDL_joystick_player_count; ++player_index) {
if (SDL_joystick_players[player_index] == -1) {
return player_index;
break;
}
}
return -1;
return player_index;
}
static int SDL_GetPlayerIndexForJoystickID(SDL_JoystickID instance_id)
@@ -1906,7 +1906,7 @@ void SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint16 *prod
if (crc16) {
*crc16 = SDL_SwapLE16(guid16[1]);
}
} else if (bus < ' ') {
} else if (bus < ' ' || bus == SDL_HARDWARE_BUS_VIRTUAL) {
/* This GUID fits the unknown VID/PID form:
* 16-bit bus
* 16-bit CRC16 of the joystick name (can be zero)
@@ -2479,8 +2479,11 @@ static SDL_bool SDL_IsJoystickProductWheel(Uint32 vidpid)
MAKE_VIDPID(0x046d, 0xc262), /* Logitech G920 (active mode) */
MAKE_VIDPID(0x046d, 0xc268), /* Logitech PRO Racing Wheel (PC mode) */
MAKE_VIDPID(0x046d, 0xc269), /* Logitech PRO Racing Wheel (PS4/PS5 mode) */
MAKE_VIDPID(0x046d, 0xc272), /* Logitech PRO Racing Wheel for Xbox (PC mode) */
MAKE_VIDPID(0x046d, 0xc26d), /* Logitech G923 (Xbox) */
MAKE_VIDPID(0x046d, 0xc26e), /* Logitech G923 */
MAKE_VIDPID(0x046d, 0xc266), /* Logitech G923 for Playstation 4 and PC (PC mode) */
MAKE_VIDPID(0x046d, 0xc267), /* Logitech G923 for Playstation 4 and PC (PS4 mode)*/
MAKE_VIDPID(0x046d, 0xca03), /* Logitech Momo Racing */
MAKE_VIDPID(0x044f, 0xb65d), /* Thrustmaster Wheel FFB */
MAKE_VIDPID(0x044f, 0xb66d), /* Thrustmaster Wheel FFB */
@@ -2492,6 +2495,17 @@ static SDL_bool SDL_IsJoystickProductWheel(Uint32 vidpid)
MAKE_VIDPID(0x044f, 0xb65e), /* Thrustmaster T500RS */
MAKE_VIDPID(0x044f, 0xb664), /* Thrustmaster TX (initial mode) */
MAKE_VIDPID(0x044f, 0xb669), /* Thrustmaster TX (active mode) */
MAKE_VIDPID(0x0483, 0x0522), /* Simagic Wheelbase (including M10, Alpha Mini, Alpha, Alpha U) */
MAKE_VIDPID(0x0eb7, 0x0001), /* Fanatec ClubSport Wheel Base V2 */
MAKE_VIDPID(0x0eb7, 0x0004), /* Fanatec ClubSport Wheel Base V2.5 */
MAKE_VIDPID(0x0eb7, 0x0005), /* Fanatec CSL Elite Wheel Base+ (PS4) */
MAKE_VIDPID(0x0eb7, 0x0006), /* Fanatec Podium Wheel Base DD1 */
MAKE_VIDPID(0x0eb7, 0x0007), /* Fanatec Podium Wheel Base DD2 */
MAKE_VIDPID(0x0eb7, 0x0011), /* Fanatec Forza Motorsport (CSR Wheel / CSR Elite Wheel) */
MAKE_VIDPID(0x0eb7, 0x0020), /* Fanatec generic wheel / CSL DD / GT DD Pro */
MAKE_VIDPID(0x0eb7, 0x0197), /* Fanatec Porsche Wheel (Turbo / GT3 RS / Turbo S / GT3 V2 / GT2) */
MAKE_VIDPID(0x0eb7, 0x038e), /* Fanatec ClubSport Wheel Base V1 */
MAKE_VIDPID(0x0eb7, 0x0e03), /* Fanatec CSL Elite Wheel Base */
MAKE_VIDPID(0x11ff, 0x0511), /* DragonRise Inc. Wired Wheel (initial mode) (also known as PXN V900 (PS3), Superdrive SV-750, or a Genesis Seaborg 400) */
};
int i;
@@ -29,6 +29,8 @@ typedef enum
k_eSwitchDeviceInfoControllerType_JoyConRight = 2,
k_eSwitchDeviceInfoControllerType_ProController = 3,
k_eSwitchDeviceInfoControllerType_LicProController = 6,
k_eSwitchDeviceInfoControllerType_HVCLeft = 7,
k_eSwitchDeviceInfoControllerType_HVCRight = 8,
k_eSwitchDeviceInfoControllerType_NESLeft = 9,
k_eSwitchDeviceInfoControllerType_NESRight = 10,
k_eSwitchDeviceInfoControllerType_SNES = 11,
+87 -76
View File
@@ -320,81 +320,83 @@ static SDL_bool HIDAPI_DriverPS4_InitDevice(SDL_HIDAPI_Device *device)
SDL_Log("PS4 dongle = %s, bluetooth = %s\n", ctx->is_dongle ? "TRUE" : "FALSE", device->is_bluetooth ? "TRUE" : "FALSE");
#endif
size = ReadFeatureReport(device->dev, k_ePS4FeatureReportIdCapabilities, data, sizeof(data));
/* Get the device capabilities */
if (size == 48 && data[2] == 0x27) {
Uint8 capabilities = data[4];
Uint8 device_type = data[5];
Uint16 gyro_numerator = LOAD16(data[10], data[11]);
Uint16 gyro_denominator = LOAD16(data[12], data[13]);
Uint16 accel_numerator = LOAD16(data[14], data[15]);
Uint16 accel_denominator = LOAD16(data[16], data[17]);
#ifdef DEBUG_PS4_PROTOCOL
HIDAPI_DumpPacket("PS4 capabilities: size = %d", data, size);
#endif
if (capabilities & 0x02) {
ctx->sensors_supported = SDL_TRUE;
}
if (capabilities & 0x04) {
ctx->lightbar_supported = SDL_TRUE;
}
if (capabilities & 0x08) {
ctx->vibration_supported = SDL_TRUE;
}
if (capabilities & 0x40) {
ctx->touchpad_supported = SDL_TRUE;
}
switch (device_type) {
case 0x00:
joystick_type = SDL_JOYSTICK_TYPE_GAMECONTROLLER;
break;
case 0x01:
joystick_type = SDL_JOYSTICK_TYPE_GUITAR;
break;
case 0x02:
joystick_type = SDL_JOYSTICK_TYPE_DRUM_KIT;
break;
case 0x04:
joystick_type = SDL_JOYSTICK_TYPE_DANCE_PAD;
break;
case 0x06:
joystick_type = SDL_JOYSTICK_TYPE_WHEEL;
break;
case 0x07:
joystick_type = SDL_JOYSTICK_TYPE_ARCADE_STICK;
break;
case 0x08:
joystick_type = SDL_JOYSTICK_TYPE_FLIGHT_STICK;
break;
default:
joystick_type = SDL_JOYSTICK_TYPE_UNKNOWN;
break;
}
if (gyro_numerator && gyro_denominator) {
ctx->gyro_numerator = gyro_numerator;
ctx->gyro_denominator = gyro_denominator;
}
if (accel_numerator && accel_denominator) {
ctx->accel_numerator = accel_numerator;
ctx->accel_denominator = accel_denominator;
}
} else if (device->vendor_id == USB_VENDOR_SONY) {
if (device->vendor_id == USB_VENDOR_SONY) {
ctx->official_controller = SDL_TRUE;
ctx->sensors_supported = SDL_TRUE;
ctx->lightbar_supported = SDL_TRUE;
ctx->vibration_supported = SDL_TRUE;
ctx->touchpad_supported = SDL_TRUE;
} else if (device->vendor_id == USB_VENDOR_RAZER) {
/* The Razer Raiju doesn't respond to the detection protocol, but has a touchpad and vibration */
ctx->vibration_supported = SDL_TRUE;
ctx->touchpad_supported = SDL_TRUE;
} else {
size = ReadFeatureReport(device->dev, k_ePS4FeatureReportIdCapabilities, data, sizeof(data));
/* Get the device capabilities */
if (size == 48 && data[2] == 0x27) {
Uint8 capabilities = data[4];
Uint8 device_type = data[5];
Uint16 gyro_numerator = LOAD16(data[10], data[11]);
Uint16 gyro_denominator = LOAD16(data[12], data[13]);
Uint16 accel_numerator = LOAD16(data[14], data[15]);
Uint16 accel_denominator = LOAD16(data[16], data[17]);
if (device->product_id == USB_PRODUCT_RAZER_TOURNAMENT_EDITION_BLUETOOTH ||
device->product_id == USB_PRODUCT_RAZER_ULTIMATE_EDITION_BLUETOOTH) {
device->is_bluetooth = SDL_TRUE;
#ifdef DEBUG_PS4_PROTOCOL
HIDAPI_DumpPacket("PS4 capabilities: size = %d", data, size);
#endif
if (capabilities & 0x02) {
ctx->sensors_supported = SDL_TRUE;
}
if (capabilities & 0x04) {
ctx->lightbar_supported = SDL_TRUE;
}
if (capabilities & 0x08) {
ctx->vibration_supported = SDL_TRUE;
}
if (capabilities & 0x40) {
ctx->touchpad_supported = SDL_TRUE;
}
switch (device_type) {
case 0x00:
joystick_type = SDL_JOYSTICK_TYPE_GAMECONTROLLER;
break;
case 0x01:
joystick_type = SDL_JOYSTICK_TYPE_GUITAR;
break;
case 0x02:
joystick_type = SDL_JOYSTICK_TYPE_DRUM_KIT;
break;
case 0x04:
joystick_type = SDL_JOYSTICK_TYPE_DANCE_PAD;
break;
case 0x06:
joystick_type = SDL_JOYSTICK_TYPE_WHEEL;
break;
case 0x07:
joystick_type = SDL_JOYSTICK_TYPE_ARCADE_STICK;
break;
case 0x08:
joystick_type = SDL_JOYSTICK_TYPE_FLIGHT_STICK;
break;
default:
joystick_type = SDL_JOYSTICK_TYPE_UNKNOWN;
break;
}
if (gyro_numerator && gyro_denominator) {
ctx->gyro_numerator = gyro_numerator;
ctx->gyro_denominator = gyro_denominator;
}
if (accel_numerator && accel_denominator) {
ctx->accel_numerator = accel_numerator;
ctx->accel_denominator = accel_denominator;
}
} else if (device->vendor_id == USB_VENDOR_RAZER) {
/* The Razer Raiju doesn't respond to the detection protocol, but has a touchpad and vibration */
ctx->vibration_supported = SDL_TRUE;
ctx->touchpad_supported = SDL_TRUE;
if (device->product_id == USB_PRODUCT_RAZER_TOURNAMENT_EDITION_BLUETOOTH ||
device->product_id == USB_PRODUCT_RAZER_ULTIMATE_EDITION_BLUETOOTH) {
device->is_bluetooth = SDL_TRUE;
}
}
}
ctx->effects_supported = (ctx->lightbar_supported || ctx->vibration_supported);
@@ -660,16 +662,25 @@ static int HIDAPI_DriverPS4_UpdateEffects(SDL_HIDAPI_Device *device)
static void HIDAPI_DriverPS4_TickleBluetooth(SDL_HIDAPI_Device *device)
{
/* This is just a dummy packet that should have no effect, since we don't set the CRC */
Uint8 data[78];
SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context;
SDL_zeroa(data);
if (ctx->enhanced_mode) {
/* This is just a dummy packet that should have no effect, since we don't set the CRC */
Uint8 data[78];
data[0] = k_EPS4ReportIdBluetoothEffects;
data[1] = 0xC0; /* Magic value HID + CRC */
SDL_zeroa(data);
if (SDL_HIDAPI_LockRumble() == 0) {
SDL_HIDAPI_SendRumbleAndUnlock(device, data, sizeof(data));
data[0] = k_EPS4ReportIdBluetoothEffects;
data[1] = 0xC0; /* Magic value HID + CRC */
if (SDL_HIDAPI_LockRumble() == 0) {
SDL_HIDAPI_SendRumbleAndUnlock(device, data, sizeof(data));
}
} else {
/* We can't even send an invalid effects packet, or it will put the controller in enhanced mode */
if (device->num_joysticks > 0) {
HIDAPI_JoystickDisconnected(device, device->joysticks[0]);
}
}
}
+123 -82
View File
@@ -102,7 +102,7 @@ typedef struct
Uint8 rgucAccelX[2]; /* 21 */
Uint8 rgucAccelY[2]; /* 23 */
Uint8 rgucAccelZ[2]; /* 25 */
Uint8 rgucSensorTimestamp[4]; /* 27 - 32 bit little endian */
Uint8 rgucSensorTimestamp[4]; /* 27 - 16/32 bit little endian */
} PS5StatePacketCommon_t;
@@ -154,7 +154,9 @@ typedef struct
Uint8 rgucAccelX[2]; /* 21 */
Uint8 rgucAccelY[2]; /* 23 */
Uint8 rgucAccelZ[2]; /* 25 */
Uint8 rgucSensorTimestamp[4]; /* 27 - 32 bit little endian */
Uint8 rgucSensorTimestamp[2]; /* 27 - 16 bit little endian */
Uint8 ucBatteryLevel; /* 29 */
Uint8 ucUnknown; /* 30 */
Uint8 ucTouchpadCounter1; /* 31 - high bit clear + counter */
Uint8 rgucTouchpadData1[3]; /* 32 - X/Y, 12 bits per axis */
Uint8 ucTouchpadCounter2; /* 35 - high bit clear + counter */
@@ -421,7 +423,6 @@ static SDL_bool HIDAPI_DriverPS5_InitDevice(SDL_HIDAPI_Device *device)
}
}
size = ReadFeatureReport(device->dev, k_EPS5FeatureReportIdCapabilities, data, sizeof(data));
/* Get the device capabilities */
if (device->vendor_id == USB_VENDOR_SONY) {
ctx->sensors_supported = SDL_TRUE;
@@ -429,61 +430,66 @@ static SDL_bool HIDAPI_DriverPS5_InitDevice(SDL_HIDAPI_Device *device)
ctx->vibration_supported = SDL_TRUE;
ctx->playerled_supported = SDL_TRUE;
ctx->touchpad_supported = SDL_TRUE;
} else if (size == 48 && data[2] == 0x28) {
Uint8 capabilities = data[4];
Uint8 capabilities2 = data[20];
Uint8 device_type = data[5];
} else {
/* Third party controller capability request */
size = ReadFeatureReport(device->dev, k_EPS5FeatureReportIdCapabilities, data, sizeof(data));
if (size == 48 && data[2] == 0x28) {
Uint8 capabilities = data[4];
Uint8 capabilities2 = data[20];
Uint8 device_type = data[5];
#ifdef DEBUG_PS5_PROTOCOL
HIDAPI_DumpPacket("PS5 capabilities: size = %d", data, size);
HIDAPI_DumpPacket("PS5 capabilities: size = %d", data, size);
#endif
if (capabilities & 0x02) {
if (capabilities & 0x02) {
ctx->sensors_supported = SDL_TRUE;
}
if (capabilities & 0x04) {
ctx->lightbar_supported = SDL_TRUE;
}
if (capabilities & 0x08) {
ctx->vibration_supported = SDL_TRUE;
}
if (capabilities & 0x40) {
ctx->touchpad_supported = SDL_TRUE;
}
if (capabilities2 & 0x80) {
ctx->playerled_supported = SDL_TRUE;
}
switch (device_type) {
case 0x00:
joystick_type = SDL_JOYSTICK_TYPE_GAMECONTROLLER;
break;
case 0x01:
joystick_type = SDL_JOYSTICK_TYPE_GUITAR;
break;
case 0x02:
joystick_type = SDL_JOYSTICK_TYPE_DRUM_KIT;
break;
case 0x06:
joystick_type = SDL_JOYSTICK_TYPE_WHEEL;
break;
case 0x07:
joystick_type = SDL_JOYSTICK_TYPE_ARCADE_STICK;
break;
case 0x08:
joystick_type = SDL_JOYSTICK_TYPE_FLIGHT_STICK;
break;
default:
joystick_type = SDL_JOYSTICK_TYPE_UNKNOWN;
break;
}
ctx->use_alternate_report = SDL_TRUE;
} else if (device->vendor_id == USB_VENDOR_RAZER &&
(device->product_id == USB_PRODUCT_RAZER_WOLVERINE_V2_PRO_PS5_WIRED ||
device->product_id == USB_PRODUCT_RAZER_WOLVERINE_V2_PRO_PS5_WIRELESS)) {
/* The Razer Wolverine V2 Pro doesn't respond to the detection protocol, but has a touchpad and sensors, but no vibration */
ctx->sensors_supported = SDL_TRUE;
}
if (capabilities & 0x04) {
ctx->lightbar_supported = SDL_TRUE;
}
if (capabilities & 0x08) {
ctx->vibration_supported = SDL_TRUE;
}
if (capabilities & 0x40) {
ctx->touchpad_supported = SDL_TRUE;
ctx->use_alternate_report = SDL_TRUE;
}
if (capabilities2 & 0x80) {
ctx->playerled_supported = SDL_TRUE;
}
switch (device_type) {
case 0x00:
joystick_type = SDL_JOYSTICK_TYPE_GAMECONTROLLER;
break;
case 0x01:
joystick_type = SDL_JOYSTICK_TYPE_GUITAR;
break;
case 0x02:
joystick_type = SDL_JOYSTICK_TYPE_DRUM_KIT;
break;
case 0x06:
joystick_type = SDL_JOYSTICK_TYPE_WHEEL;
break;
case 0x07:
joystick_type = SDL_JOYSTICK_TYPE_ARCADE_STICK;
break;
case 0x08:
joystick_type = SDL_JOYSTICK_TYPE_FLIGHT_STICK;
break;
default:
joystick_type = SDL_JOYSTICK_TYPE_UNKNOWN;
break;
}
ctx->use_alternate_report = SDL_TRUE;
} else if (device->vendor_id == USB_VENDOR_RAZER &&
(device->product_id == USB_PRODUCT_RAZER_WOLVERINE_V2_PRO_PS5_WIRED ||
device->product_id == USB_PRODUCT_RAZER_WOLVERINE_V2_PRO_PS5_WIRELESS)) {
/* The Razer Wolverine V2 Pro doesn't respond to the detection protocol, but has a touchpad and sensors, but no vibration */
ctx->sensors_supported = SDL_TRUE;
ctx->touchpad_supported = SDL_TRUE;
}
ctx->effects_supported = (ctx->lightbar_supported || ctx->vibration_supported || ctx->playerled_supported);
@@ -717,7 +723,7 @@ static void HIDAPI_DriverPS5_CheckPendingLEDReset(SDL_HIDAPI_Device *device)
SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context;
SDL_bool led_reset_complete = SDL_FALSE;
if (ctx->sensors_supported) {
if (ctx->enhanced_mode && ctx->sensors_supported && !ctx->use_alternate_report) {
const PS5StatePacketCommon_t *packet = &ctx->last_state.state;
/* Check the timer to make sure the Bluetooth connection LED animation is complete */
@@ -726,7 +732,7 @@ static void HIDAPI_DriverPS5_CheckPendingLEDReset(SDL_HIDAPI_Device *device)
packet->rgucSensorTimestamp[1],
packet->rgucSensorTimestamp[2],
packet->rgucSensorTimestamp[3]);
if (SDL_TICKS_PASSED(timestamp, connection_complete)) {
if (timestamp >= connection_complete) {
led_reset_complete = SDL_TRUE;
}
} else {
@@ -745,16 +751,25 @@ static void HIDAPI_DriverPS5_CheckPendingLEDReset(SDL_HIDAPI_Device *device)
static void HIDAPI_DriverPS5_TickleBluetooth(SDL_HIDAPI_Device *device)
{
/* This is just a dummy packet that should have no effect, since we don't set the CRC */
Uint8 data[78];
SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context;
SDL_zeroa(data);
if (ctx->enhanced_mode) {
/* This is just a dummy packet that should have no effect, since we don't set the CRC */
Uint8 data[78];
data[0] = k_EPS5ReportIdBluetoothEffects;
data[1] = 0x02; /* Magic value */
SDL_zeroa(data);
if (SDL_HIDAPI_LockRumble() == 0) {
SDL_HIDAPI_SendRumbleAndUnlock(device, data, sizeof(data));
data[0] = k_EPS5ReportIdBluetoothEffects;
data[1] = 0x02; /* Magic value */
if (SDL_HIDAPI_LockRumble() == 0) {
SDL_HIDAPI_SendRumbleAndUnlock(device, data, sizeof(data));
}
} else {
/* We can't even send an invalid effects packet, or it will put the controller in enhanced mode */
if (device->num_joysticks > 0) {
HIDAPI_JoystickDisconnected(device, device->joysticks[0]);
}
}
}
@@ -1216,30 +1231,56 @@ static void HIDAPI_DriverPS5_HandleStatePacketCommon(SDL_Joystick *joystick, SDL
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis);
if (ctx->report_sensors) {
Uint32 timestamp;
Uint64 timestamp_us;
float data[3];
Uint64 timestamp_us;
timestamp = LOAD32(packet->rgucSensorTimestamp[0],
packet->rgucSensorTimestamp[1],
packet->rgucSensorTimestamp[2],
packet->rgucSensorTimestamp[3]);
if (ctx->timestamp) {
Uint32 delta;
if (ctx->use_alternate_report) {
/* 16-bit timestamp */
Uint16 timestamp;
if (ctx->last_timestamp > timestamp) {
delta = (SDL_MAX_UINT32 - ctx->last_timestamp + timestamp + 1);
timestamp = LOAD16(packet->rgucSensorTimestamp[0],
packet->rgucSensorTimestamp[1]);
if (ctx->timestamp) {
Uint16 delta;
if (ctx->last_timestamp > timestamp) {
delta = (SDL_MAX_UINT16 - ctx->last_timestamp + timestamp + 1);
} else {
delta = (timestamp - ctx->last_timestamp);
}
ctx->timestamp += delta;
} else {
delta = (timestamp - ctx->last_timestamp);
ctx->timestamp = timestamp;
}
ctx->timestamp += delta;
} else {
ctx->timestamp = timestamp;
}
ctx->last_timestamp = timestamp;
ctx->last_timestamp = timestamp;
/* Sensor timestamp is in 0.33us units */
timestamp_us = ctx->timestamp / 3;
/* Sensor timestamp is in 1us units */
timestamp_us = ctx->timestamp;
} else {
/* 32-bit timestamp */
Uint32 timestamp;
timestamp = LOAD32(packet->rgucSensorTimestamp[0],
packet->rgucSensorTimestamp[1],
packet->rgucSensorTimestamp[2],
packet->rgucSensorTimestamp[3]);
if (ctx->timestamp) {
Uint32 delta;
if (ctx->last_timestamp > timestamp) {
delta = (SDL_MAX_UINT32 - ctx->last_timestamp + timestamp + 1);
} else {
delta = (timestamp - ctx->last_timestamp);
}
ctx->timestamp += delta;
} else {
ctx->timestamp = timestamp;
}
ctx->last_timestamp = timestamp;
/* Sensor timestamp is in 0.33us units */
timestamp_us = ctx->timestamp / 3;
}
data[0] = HIDAPI_DriverPS5_ApplyCalibrationData(ctx, 0, LOAD16(packet->rgucGyroX[0], packet->rgucGyroX[1]));
data[1] = HIDAPI_DriverPS5_ApplyCalibrationData(ctx, 1, LOAD16(packet->rgucGyroY[0], packet->rgucGyroY[1]));
@@ -1395,15 +1436,15 @@ static SDL_bool HIDAPI_DriverPS5_UpdateDevice(SDL_HIDAPI_Device *device)
/* This is the extended report, we can enable effects now */
HIDAPI_DriverPS5_SetEnhancedMode(device, joystick);
}
if (ctx->led_reset_state == k_EDS5LEDResetStatePending) {
HIDAPI_DriverPS5_CheckPendingLEDReset(device);
}
HIDAPI_DriverPS5_HandleStatePacketCommon(joystick, device->dev, ctx, (PS5StatePacketCommon_t *)&data[2]);
if (ctx->use_alternate_report) {
HIDAPI_DriverPS5_HandleStatePacketAlt(joystick, device->dev, ctx, (PS5StatePacketAlt_t *)&data[2]);
} else {
HIDAPI_DriverPS5_HandleStatePacket(joystick, device->dev, ctx, (PS5StatePacket_t *)&data[2]);
}
if (ctx->led_reset_state == k_EDS5LEDResetStatePending) {
HIDAPI_DriverPS5_CheckPendingLEDReset(device);
}
break;
default:
#ifdef DEBUG_JOYSTICK
+69 -53
View File
@@ -71,6 +71,7 @@ typedef enum
{
k_eSwitchInputReportIDs_SubcommandReply = 0x21,
k_eSwitchInputReportIDs_FullControllerState = 0x30,
k_eSwitchInputReportIDs_FullControllerAndMcuState = 0x31,
k_eSwitchInputReportIDs_SimpleControllerState = 0x3F,
k_eSwitchInputReportIDs_CommandAck = 0x81,
} ESwitchInputReportIDs;
@@ -760,9 +761,8 @@ static SDL_bool LoadStickCalibration(SDL_DriverSwitch_Context *ctx)
readUserParams.unAddress = k_unSPIStickUserCalibrationStartOffset;
readUserParams.ucLength = k_unSPIStickUserCalibrationLength;
if (!WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t *)&readUserParams, sizeof(readUserParams), &user_reply)) {
return SDL_FALSE;
}
/* This isn't readable on all controllers, so ignore failure */
WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t *)&readUserParams, sizeof(readUserParams), &user_reply);
/* Read Factory Calibration Info */
readFactoryParams.unAddress = k_unSPIStickFactoryCalibrationStartOffset;
@@ -773,13 +773,13 @@ static SDL_bool LoadStickCalibration(SDL_DriverSwitch_Context *ctx)
}
/* Automatically select the user calibration if magic bytes are set */
if (user_reply->stickUserCalibration.rgucLeftMagic[0] == 0xB2 && user_reply->stickUserCalibration.rgucLeftMagic[1] == 0xA1) {
if (user_reply && user_reply->stickUserCalibration.rgucLeftMagic[0] == 0xB2 && user_reply->stickUserCalibration.rgucLeftMagic[1] == 0xA1) {
pLeftStickCal = user_reply->stickUserCalibration.rgucLeftCalibration;
} else {
pLeftStickCal = factory_reply->stickFactoryCalibration.rgucLeftCalibration;
}
if (user_reply->stickUserCalibration.rgucRightMagic[0] == 0xB2 && user_reply->stickUserCalibration.rgucRightMagic[1] == 0xA1) {
if (user_reply && user_reply->stickUserCalibration.rgucRightMagic[0] == 0xB2 && user_reply->stickUserCalibration.rgucRightMagic[1] == 0xA1) {
pRightStickCal = user_reply->stickUserCalibration.rgucRightCalibration;
} else {
pRightStickCal = factory_reply->stickFactoryCalibration.rgucRightCalibration;
@@ -841,16 +841,55 @@ static SDL_bool LoadStickCalibration(SDL_DriverSwitch_Context *ctx)
static SDL_bool LoadIMUCalibration(SDL_DriverSwitch_Context *ctx)
{
Uint8 *pIMUScale;
SwitchSubcommandInputPacket_t *reply = NULL;
Sint16 sAccelRawX, sAccelRawY, sAccelRawZ, sGyroRawX, sGyroRawY, sGyroRawZ;
/* Read Calibration Info */
SwitchSPIOpData_t readParams;
readParams.unAddress = k_unSPIIMUScaleStartOffset;
readParams.ucLength = k_unSPIIMUScaleLength;
if (!WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t *)&readParams, sizeof(readParams), &reply)) {
if (WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t *)&readParams, sizeof(readParams), &reply)) {
Uint8 *pIMUScale;
Sint16 sAccelRawX, sAccelRawY, sAccelRawZ, sGyroRawX, sGyroRawY, sGyroRawZ;
/* IMU scale gives us multipliers for converting raw values to real world values */
pIMUScale = reply->spiReadData.rgucReadData;
sAccelRawX = (pIMUScale[1] << 8) | pIMUScale[0];
sAccelRawY = (pIMUScale[3] << 8) | pIMUScale[2];
sAccelRawZ = (pIMUScale[5] << 8) | pIMUScale[4];
sGyroRawX = (pIMUScale[13] << 8) | pIMUScale[12];
sGyroRawY = (pIMUScale[15] << 8) | pIMUScale[14];
sGyroRawZ = (pIMUScale[17] << 8) | pIMUScale[16];
/* Check for user calibration data. If it's present and set, it'll override the factory settings */
readParams.unAddress = k_unSPIIMUUserScaleStartOffset;
readParams.ucLength = k_unSPIIMUUserScaleLength;
if (WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t *)&readParams, sizeof(readParams), &reply) && (pIMUScale[0] | pIMUScale[1] << 8) == 0xA1B2) {
pIMUScale = reply->spiReadData.rgucReadData;
sAccelRawX = (pIMUScale[3] << 8) | pIMUScale[2];
sAccelRawY = (pIMUScale[5] << 8) | pIMUScale[4];
sAccelRawZ = (pIMUScale[7] << 8) | pIMUScale[6];
sGyroRawX = (pIMUScale[15] << 8) | pIMUScale[14];
sGyroRawY = (pIMUScale[17] << 8) | pIMUScale[16];
sGyroRawZ = (pIMUScale[19] << 8) | pIMUScale[18];
}
/* Accelerometer scale */
ctx->m_IMUScaleData.fAccelScaleX = SWITCH_ACCEL_SCALE_MULT / (SWITCH_ACCEL_SCALE_OFFSET - (float)sAccelRawX) * SDL_STANDARD_GRAVITY;
ctx->m_IMUScaleData.fAccelScaleY = SWITCH_ACCEL_SCALE_MULT / (SWITCH_ACCEL_SCALE_OFFSET - (float)sAccelRawY) * SDL_STANDARD_GRAVITY;
ctx->m_IMUScaleData.fAccelScaleZ = SWITCH_ACCEL_SCALE_MULT / (SWITCH_ACCEL_SCALE_OFFSET - (float)sAccelRawZ) * SDL_STANDARD_GRAVITY;
/* Gyro scale */
ctx->m_IMUScaleData.fGyroScaleX = SWITCH_GYRO_SCALE_MULT / (SWITCH_GYRO_SCALE_OFFSET - (float)sGyroRawX) * (float)M_PI / 180.0f;
ctx->m_IMUScaleData.fGyroScaleY = SWITCH_GYRO_SCALE_MULT / (SWITCH_GYRO_SCALE_OFFSET - (float)sGyroRawY) * (float)M_PI / 180.0f;
ctx->m_IMUScaleData.fGyroScaleZ = SWITCH_GYRO_SCALE_MULT / (SWITCH_GYRO_SCALE_OFFSET - (float)sGyroRawZ) * (float)M_PI / 180.0f;
} else {
/* Use default values */
const float accelScale = SDL_STANDARD_GRAVITY / SWITCH_ACCEL_SCALE;
const float gyroScale = (float)M_PI / 180.0f / SWITCH_GYRO_SCALE;
@@ -861,46 +900,7 @@ static SDL_bool LoadIMUCalibration(SDL_DriverSwitch_Context *ctx)
ctx->m_IMUScaleData.fGyroScaleX = gyroScale;
ctx->m_IMUScaleData.fGyroScaleY = gyroScale;
ctx->m_IMUScaleData.fGyroScaleZ = gyroScale;
return SDL_FALSE;
}
/* IMU scale gives us multipliers for converting raw values to real world values */
pIMUScale = reply->spiReadData.rgucReadData;
sAccelRawX = (pIMUScale[1] << 8) | pIMUScale[0];
sAccelRawY = (pIMUScale[3] << 8) | pIMUScale[2];
sAccelRawZ = (pIMUScale[5] << 8) | pIMUScale[4];
sGyroRawX = (pIMUScale[13] << 8) | pIMUScale[12];
sGyroRawY = (pIMUScale[15] << 8) | pIMUScale[14];
sGyroRawZ = (pIMUScale[17] << 8) | pIMUScale[16];
/* Check for user calibration data. If it's present and set, it'll override the factory settings */
readParams.unAddress = k_unSPIIMUUserScaleStartOffset;
readParams.ucLength = k_unSPIIMUUserScaleLength;
if (WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t *)&readParams, sizeof(readParams), &reply) && (pIMUScale[0] | pIMUScale[1] << 8) == 0xA1B2) {
pIMUScale = reply->spiReadData.rgucReadData;
sAccelRawX = (pIMUScale[3] << 8) | pIMUScale[2];
sAccelRawY = (pIMUScale[5] << 8) | pIMUScale[4];
sAccelRawZ = (pIMUScale[7] << 8) | pIMUScale[6];
sGyroRawX = (pIMUScale[15] << 8) | pIMUScale[14];
sGyroRawY = (pIMUScale[17] << 8) | pIMUScale[16];
sGyroRawZ = (pIMUScale[19] << 8) | pIMUScale[18];
}
/* Accelerometer scale */
ctx->m_IMUScaleData.fAccelScaleX = SWITCH_ACCEL_SCALE_MULT / (SWITCH_ACCEL_SCALE_OFFSET - (float)sAccelRawX) * SDL_STANDARD_GRAVITY;
ctx->m_IMUScaleData.fAccelScaleY = SWITCH_ACCEL_SCALE_MULT / (SWITCH_ACCEL_SCALE_OFFSET - (float)sAccelRawY) * SDL_STANDARD_GRAVITY;
ctx->m_IMUScaleData.fAccelScaleZ = SWITCH_ACCEL_SCALE_MULT / (SWITCH_ACCEL_SCALE_OFFSET - (float)sAccelRawZ) * SDL_STANDARD_GRAVITY;
/* Gyro scale */
ctx->m_IMUScaleData.fGyroScaleX = SWITCH_GYRO_SCALE_MULT / (float)(SWITCH_GYRO_SCALE_OFFSET - (float)sGyroRawX) * (float)M_PI / 180.0f;
ctx->m_IMUScaleData.fGyroScaleY = SWITCH_GYRO_SCALE_MULT / (float)(SWITCH_GYRO_SCALE_OFFSET - (float)sGyroRawY) * (float)M_PI / 180.0f;
ctx->m_IMUScaleData.fGyroScaleZ = SWITCH_GYRO_SCALE_MULT / (float)(SWITCH_GYRO_SCALE_OFFSET - (float)sGyroRawZ) * (float)M_PI / 180.0f;
return SDL_TRUE;
}
@@ -998,7 +998,9 @@ static ESwitchDeviceInfoControllerType ReadJoyConControllerType(SDL_HIDAPI_Devic
ctx->m_bSyncWrite = SDL_TRUE;
ctx->m_nMaxWriteAttempts = GetMaxWriteAttempts(device);
for (attempts = 0; attempts < MAX_ATTEMPTS; ++attempts) {
for ( ; ; ) {
++attempts;
device->is_bluetooth = SDL_FALSE;
if (WriteProprietary(ctx, k_eSwitchProprietaryCommandIDs_Status, NULL, 0, SDL_TRUE)) {
SwitchProprietaryStatusPacket_t *status = (SwitchProprietaryStatusPacket_t *)&ctx->m_rgucReadBuffer[0];
@@ -1011,13 +1013,12 @@ static ESwitchDeviceInfoControllerType ReadJoyConControllerType(SDL_HIDAPI_Devic
eControllerType = CalculateControllerType(ctx, (ESwitchDeviceInfoControllerType)reply->deviceInfo.ucDeviceType);
}
}
if (eControllerType == k_eSwitchDeviceInfoControllerType_Unknown) {
if (eControllerType == k_eSwitchDeviceInfoControllerType_Unknown && attempts < MAX_ATTEMPTS) {
/* Wait a bit and try again */
SDL_Delay(100);
continue;
} else {
break;
}
break;
}
SDL_free(ctx);
}
@@ -1058,6 +1059,8 @@ static SDL_bool AlwaysUsesLabels(int vendor_id, int product_id, ESwitchDeviceInf
{
/* These controllers don't have a diamond button configuration, so always use labels */
switch (eControllerType) {
case k_eSwitchDeviceInfoControllerType_HVCLeft:
case k_eSwitchDeviceInfoControllerType_HVCRight:
case k_eSwitchDeviceInfoControllerType_NESLeft:
case k_eSwitchDeviceInfoControllerType_NESRight:
case k_eSwitchDeviceInfoControllerType_N64:
@@ -1104,7 +1107,8 @@ static SDL_bool HIDAPI_DriverNintendoClassic_IsSupportedDevice(SDL_HIDAPI_Device
{
if (vendor_id == USB_VENDOR_NINTENDO) {
if (product_id == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_RIGHT) {
if (SDL_strncmp(name, "NES Controller", 14) == 0) {
if (SDL_strncmp(name, "NES Controller", 14) == 0 ||
SDL_strncmp(name, "HVC Controller", 14) == 0) {
return SDL_TRUE;
}
}
@@ -1219,6 +1223,14 @@ static void UpdateDeviceIdentity(SDL_HIDAPI_Device *device)
HIDAPI_SetDeviceProduct(device, USB_VENDOR_NINTENDO, USB_PRODUCT_NINTENDO_SWITCH_PRO);
device->type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO;
break;
case k_eSwitchDeviceInfoControllerType_HVCLeft:
HIDAPI_SetDeviceName(device, "Nintendo HVC Controller (1)");
device->type = SDL_CONTROLLER_TYPE_UNKNOWN;
break;
case k_eSwitchDeviceInfoControllerType_HVCRight:
HIDAPI_SetDeviceName(device, "Nintendo HVC Controller (2)");
device->type = SDL_CONTROLLER_TYPE_UNKNOWN;
break;
case k_eSwitchDeviceInfoControllerType_NESLeft:
HIDAPI_SetDeviceName(device, "Nintendo NES Controller (L)");
device->type = SDL_CONTROLLER_TYPE_UNKNOWN;
@@ -1246,6 +1258,7 @@ static void UpdateDeviceIdentity(SDL_HIDAPI_Device *device)
/* We couldn't read the device info for this controller, might not be fully compliant */
return;
default:
device->type = SDL_CONTROLLER_TYPE_UNKNOWN;
break;
}
device->guid.data[15] = ctx->m_eControllerType;
@@ -1347,7 +1360,9 @@ static SDL_bool HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_
return SDL_FALSE;
}
if (ctx->m_eControllerType != k_eSwitchDeviceInfoControllerType_NESLeft &&
if (ctx->m_eControllerType != k_eSwitchDeviceInfoControllerType_HVCLeft &&
ctx->m_eControllerType != k_eSwitchDeviceInfoControllerType_HVCRight &&
ctx->m_eControllerType != k_eSwitchDeviceInfoControllerType_NESLeft &&
ctx->m_eControllerType != k_eSwitchDeviceInfoControllerType_NESRight &&
ctx->m_eControllerType != k_eSwitchDeviceInfoControllerType_SNES &&
ctx->m_eControllerType != k_eSwitchDeviceInfoControllerType_N64 &&
@@ -2165,6 +2180,7 @@ static SDL_bool HIDAPI_DriverSwitch_UpdateDevice(SDL_HIDAPI_Device *device)
HandleSimpleControllerState(joystick, ctx, (SwitchSimpleStatePacket_t *)&ctx->m_rgucReadBuffer[1]);
break;
case k_eSwitchInputReportIDs_FullControllerState:
case k_eSwitchInputReportIDs_FullControllerAndMcuState:
HandleFullControllerState(joystick, ctx, (SwitchStatePacket_t *)&ctx->m_rgucReadBuffer[1]);
break;
default:
+3 -3
View File
@@ -1041,7 +1041,7 @@ static void ConfigJoystick(SDL_Joystick *joystick, int fd)
}
for (i = 0; i < ABS_MAX; ++i) {
/* Skip digital hats */
if (joystick->hwdata->has_hat[(i - ABS_HAT0X) / 2]) {
if (i >= ABS_HAT0X && i <= ABS_HAT3Y && joystick->hwdata->has_hat[(i - ABS_HAT0X) / 2]) {
continue;
}
if (test_bit(i, absbit)) {
@@ -1752,11 +1752,11 @@ static SDL_bool LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMap
/* We temporarily open the device to check how it's configured. Make
a fake SDL_Joystick object to do so. */
joystick = (SDL_Joystick *)SDL_calloc(sizeof(*joystick), 1);
joystick->magic = &SDL_joystick_magic;
if (joystick == NULL) {
SDL_OutOfMemory();
return SDL_FALSE;
}
joystick->magic = &SDL_joystick_magic;
SDL_memcpy(&joystick->guid, &item->guid, sizeof(item->guid));
joystick->hwdata = (struct joystick_hwdata *)
@@ -2026,7 +2026,7 @@ static SDL_bool LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMap
#endif
}
if (!(mapped & MAPPED_TRIGGER_LEFT) && joystick->hwdata->has_key[BTN_TR2]) {
if (!(mapped & MAPPED_TRIGGER_RIGHT) && joystick->hwdata->has_key[BTN_TR2]) {
out->righttrigger.kind = EMappingKind_Button;
out->righttrigger.target = joystick->hwdata->key_map[BTN_TR2];
mapped |= MAPPED_TRIGGER_RIGHT;
File diff suppressed because it is too large. Load diff
+1
View File
@@ -22,6 +22,7 @@ standard_guid_pattern = re.compile(r'^([0-9a-fA-F]{4})([0-9a-fA-F]{2})([0-9a-fA-
invalid_controllers = (
('0079', '0006', '0000'), # DragonRise Inc. Generic USB Joystick
('0079', '0006', '6120'), # DragonRise Inc. Generic USB Joystick
('04b4', '2412', 'c529'), # Flydigi Vader 2, Vader 2 Pro, Apex 2, Apex 3
('16c0', '05e1', '0000'), # Xinmotek Controller
)
+175 -34
View File
@@ -33,6 +33,7 @@
#if SDL_JOYSTICK_RAWINPUT
#include "SDL_atomic.h"
#include "SDL_endian.h"
#include "SDL_events.h"
#include "SDL_hints.h"
@@ -47,7 +48,7 @@
raw input will turn off the Xbox Series X controller when it is connected via the
Xbox One Wireless Adapter.
*/
#if 0 /*def HAVE_XINPUT_H*/
#ifdef HAVE_XINPUT_H
#define SDL_JOYSTICK_RAWINPUT_XINPUT
#endif
#ifdef HAVE_WINDOWS_GAMING_INPUT_H
@@ -78,7 +79,9 @@ typedef struct WindowsGamingInputGamepadState WindowsGamingInputGamepadState;
#endif
#endif
/*#define DEBUG_RAWINPUT*/
#if 0
#define DEBUG_RAWINPUT
#endif
#ifndef RIDEV_EXINPUTSINK
#define RIDEV_EXINPUTSINK 0x00001000
@@ -401,6 +404,21 @@ static SDL_bool RAWINPUT_GuessXInputSlot(const WindowsMatchState *state, Uint8 *
int user_index;
int match_count;
/* If there is only one available slot, let's use that
* That will be right most of the time, and uncorrelation will fix any bad guesses
*/
match_count = 0;
for (user_index = 0; user_index < XUSER_MAX_COUNT; ++user_index) {
if (xinput_state[user_index].connected && !xinput_state[user_index].used) {
*slot_idx = user_index;
++match_count;
}
}
if (match_count == 1) {
*correlation_id = ++xinput_state[*slot_idx].correlation_id;
return SDL_TRUE;
}
*slot_idx = 0;
match_count = 0;
@@ -445,8 +463,86 @@ static struct
SDL_bool need_device_list_update;
int ref_count;
__x_ABI_CWindows_CGaming_CInput_CIGamepadStatics *gamepad_statics;
EventRegistrationToken gamepad_added_token;
EventRegistrationToken gamepad_removed_token;
} wgi_state;
typedef struct GamepadDelegate
{
__FIEventHandler_1_Windows__CGaming__CInput__CGamepad iface;
SDL_atomic_t refcount;
} GamepadDelegate;
static const IID IID_IEventHandler_Gamepad = { 0x8a7639ee, 0x624a, 0x501a, { 0xbb, 0x53, 0x56, 0x2d, 0x1e, 0xc1, 0x1b, 0x52 } };
static HRESULT STDMETHODCALLTYPE IEventHandler_CGamepadVtbl_QueryInterface(__FIEventHandler_1_Windows__CGaming__CInput__CGamepad *This, REFIID riid, void **ppvObject)
{
if (ppvObject == NULL) {
return E_INVALIDARG;
}
*ppvObject = NULL;
if (WIN_IsEqualIID(riid, &IID_IUnknown) || WIN_IsEqualIID(riid, &IID_IAgileObject) || WIN_IsEqualIID(riid, &IID_IEventHandler_Gamepad)) {
*ppvObject = This;
__FIEventHandler_1_Windows__CGaming__CInput__CGamepad_AddRef(This);
return S_OK;
} else if (WIN_IsEqualIID(riid, &IID_IMarshal)) {
/* This seems complicated. Let's hope it doesn't happen. */
return E_OUTOFMEMORY;
} else {
return E_NOINTERFACE;
}
}
static ULONG STDMETHODCALLTYPE IEventHandler_CGamepadVtbl_AddRef(__FIEventHandler_1_Windows__CGaming__CInput__CGamepad *This)
{
GamepadDelegate *self = (GamepadDelegate *)This;
return SDL_AtomicAdd(&self->refcount, 1) + 1UL;
}
static ULONG STDMETHODCALLTYPE IEventHandler_CGamepadVtbl_Release(__FIEventHandler_1_Windows__CGaming__CInput__CGamepad *This)
{
GamepadDelegate *self = (GamepadDelegate *)This;
int rc = SDL_AtomicAdd(&self->refcount, -1) - 1;
/* Should never free the static delegate objects */
SDL_assert(rc > 0);
return rc;
}
static HRESULT STDMETHODCALLTYPE IEventHandler_CGamepadVtbl_InvokeAdded(__FIEventHandler_1_Windows__CGaming__CInput__CGamepad *This, IInspectable *sender, __x_ABI_CWindows_CGaming_CInput_CIGamepad *e)
{
wgi_state.need_device_list_update = SDL_TRUE;
return S_OK;
}
static HRESULT STDMETHODCALLTYPE IEventHandler_CGamepadVtbl_InvokeRemoved(__FIEventHandler_1_Windows__CGaming__CInput__CGamepad *This, IInspectable *sender, __x_ABI_CWindows_CGaming_CInput_CIGamepad *e)
{
wgi_state.need_device_list_update = SDL_TRUE;
return S_OK;
}
static __FIEventHandler_1_Windows__CGaming__CInput__CGamepadVtbl gamepad_added_vtbl = {
IEventHandler_CGamepadVtbl_QueryInterface,
IEventHandler_CGamepadVtbl_AddRef,
IEventHandler_CGamepadVtbl_Release,
IEventHandler_CGamepadVtbl_InvokeAdded
};
static GamepadDelegate gamepad_added = {
{ &gamepad_added_vtbl },
{ 1 }
};
static __FIEventHandler_1_Windows__CGaming__CInput__CGamepadVtbl gamepad_removed_vtbl = {
IEventHandler_CGamepadVtbl_QueryInterface,
IEventHandler_CGamepadVtbl_AddRef,
IEventHandler_CGamepadVtbl_Release,
IEventHandler_CGamepadVtbl_InvokeRemoved
};
static GamepadDelegate gamepad_removed = {
{ &gamepad_removed_vtbl },
{ 1 }
};
static void RAWINPUT_MarkWindowsGamingInputSlotUsed(WindowsGamingInputGamepadState *wgi_slot, RAWINPUT_DeviceContext *ctx)
{
wgi_slot->used = SDL_TRUE;
@@ -564,7 +660,10 @@ static void RAWINPUT_UpdateWindowsGamingInput()
}
static void RAWINPUT_InitWindowsGamingInput(RAWINPUT_DeviceContext *ctx)
{
wgi_state.need_device_list_update = SDL_TRUE;
if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_WGI, SDL_TRUE)) {
return;
}
wgi_state.ref_count++;
if (!wgi_state.initialized) {
static const IID SDL_IID_IGamepadStatics = { 0x8BBCE529, 0xD49C, 0x39E9, { 0x95, 0x60, 0xE4, 0x7D, 0xDE, 0x96, 0xB7, 0xC8 } };
@@ -596,6 +695,20 @@ static void RAWINPUT_InitWindowsGamingInput(RAWINPUT_DeviceContext *ctx)
if (SUCCEEDED(hr)) {
RoGetActivationFactoryFunc(hNamespaceString, &SDL_IID_IGamepadStatics, (void **)&wgi_state.gamepad_statics);
}
if (wgi_state.gamepad_statics) {
wgi_state.need_device_list_update = SDL_TRUE;
hr = __x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_add_GamepadAdded(wgi_state.gamepad_statics, &gamepad_added.iface, &wgi_state.gamepad_added_token);
if (!SUCCEEDED(hr)) {
SDL_SetError("add_GamepadAdded() failed: 0x%lx\n", hr);
}
hr = __x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_add_GamepadRemoved(wgi_state.gamepad_statics, &gamepad_removed.iface, &wgi_state.gamepad_removed_token);
if (!SUCCEEDED(hr)) {
SDL_SetError("add_GamepadRemoved() failed: 0x%lx\n", hr);
}
}
}
}
}
@@ -621,10 +734,27 @@ static SDL_bool RAWINPUT_WindowsGamingInputSlotMatches(const WindowsMatchState *
static SDL_bool RAWINPUT_GuessWindowsGamingInputSlot(const WindowsMatchState *state, Uint8 *correlation_id, WindowsGamingInputGamepadState **slot, SDL_bool xinput_correlated)
{
int match_count, user_index;
WindowsGamingInputGamepadState *gamepad_state = NULL;
/* If there is only one available slot, let's use that
* That will be right most of the time, and uncorrelation will fix any bad guesses
*/
match_count = 0;
for (user_index = 0; user_index < wgi_state.per_gamepad_count; ++user_index) {
gamepad_state = wgi_state.per_gamepad[user_index];
if (gamepad_state->connected && !gamepad_state->used) {
*slot = gamepad_state;
++match_count;
}
}
if (match_count == 1) {
*correlation_id = ++gamepad_state->correlation_id;
return SDL_TRUE;
}
match_count = 0;
for (user_index = 0; user_index < wgi_state.per_gamepad_count; ++user_index) {
WindowsGamingInputGamepadState *gamepad_state = wgi_state.per_gamepad[user_index];
gamepad_state = wgi_state.per_gamepad[user_index];
if (RAWINPUT_WindowsGamingInputSlotMatches(state, gamepad_state, xinput_correlated)) {
++match_count;
*slot = gamepad_state;
@@ -643,7 +773,6 @@ static SDL_bool RAWINPUT_GuessWindowsGamingInputSlot(const WindowsMatchState *st
static void RAWINPUT_QuitWindowsGamingInput(RAWINPUT_DeviceContext *ctx)
{
wgi_state.need_device_list_update = SDL_TRUE;
--wgi_state.ref_count;
if (!wgi_state.ref_count && wgi_state.initialized) {
int ii;
@@ -656,6 +785,8 @@ static void RAWINPUT_QuitWindowsGamingInput(RAWINPUT_DeviceContext *ctx)
}
wgi_state.per_gamepad_count = 0;
if (wgi_state.gamepad_statics) {
__x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_remove_GamepadAdded(wgi_state.gamepad_statics, wgi_state.gamepad_added_token);
__x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_remove_GamepadRemoved(wgi_state.gamepad_statics, wgi_state.gamepad_removed_token);
__x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_Release(wgi_state.gamepad_statics);
wgi_state.gamepad_statics = NULL;
}
@@ -879,12 +1010,12 @@ static int RAWINPUT_JoystickInit(void)
{
SDL_assert(!SDL_RAWINPUT_inited);
if (!WIN_IsWindowsVistaOrGreater()) {
/* According to bug 6400, this doesn't work on Windows XP */
return -1;
if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_RAWINPUT, SDL_TRUE)) {
return 0;
}
if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_RAWINPUT, SDL_TRUE)) {
if (!WIN_IsWindowsVistaOrGreater()) {
/* According to bug 6400, this doesn't work on Windows XP */
return -1;
}
@@ -917,9 +1048,6 @@ SDL_bool RAWINPUT_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 ve
#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT
xinput_device_change = SDL_TRUE;
#endif
#ifdef SDL_JOYSTICK_RAWINPUT_WGI
wgi_state.need_device_list_update = SDL_TRUE;
#endif
device = SDL_RAWINPUT_devices;
while (device) {
@@ -1008,8 +1136,13 @@ static void RAWINPUT_PostUpdate(void)
static void RAWINPUT_JoystickDetect(void)
{
SDL_bool remote_desktop = GetSystemMetrics(SM_REMOTESESSION) ? SDL_TRUE : SDL_FALSE;
SDL_bool remote_desktop;
if (!SDL_RAWINPUT_inited) {
return;
}
remote_desktop = GetSystemMetrics(SM_REMOTESESSION) ? SDL_TRUE : SDL_FALSE;
if (remote_desktop != SDL_RAWINPUT_remote_desktop) {
SDL_RAWINPUT_remote_desktop = remote_desktop;
@@ -1281,20 +1414,8 @@ static int RAWINPUT_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_
#endif
SDL_bool rumbled = SDL_FALSE;
#ifdef SDL_JOYSTICK_RAWINPUT_WGI
if (!rumbled && ctx->wgi_correlated) {
WindowsGamingInputGamepadState *gamepad_state = ctx->wgi_slot;
HRESULT hr;
gamepad_state->vibration.LeftMotor = (DOUBLE)low_frequency_rumble / SDL_MAX_UINT16;
gamepad_state->vibration.RightMotor = (DOUBLE)high_frequency_rumble / SDL_MAX_UINT16;
hr = __x_ABI_CWindows_CGaming_CInput_CIGamepad_put_Vibration(gamepad_state->gamepad, gamepad_state->vibration);
if (SUCCEEDED(hr)) {
rumbled = SDL_TRUE;
}
}
#endif
#ifdef SDL_JOYSTICK_RAWINPUT_XINPUT
/* Prefer XInput over WGI because it allows rumble in the background */
if (!rumbled && ctx->xinput_correlated) {
XINPUT_VIBRATION XVibration;
@@ -1312,6 +1433,19 @@ static int RAWINPUT_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_
}
#endif /* SDL_JOYSTICK_RAWINPUT_XINPUT */
#ifdef SDL_JOYSTICK_RAWINPUT_WGI
if (!rumbled && ctx->wgi_correlated) {
WindowsGamingInputGamepadState *gamepad_state = ctx->wgi_slot;
HRESULT hr;
gamepad_state->vibration.LeftMotor = (DOUBLE)low_frequency_rumble / SDL_MAX_UINT16;
gamepad_state->vibration.RightMotor = (DOUBLE)high_frequency_rumble / SDL_MAX_UINT16;
hr = __x_ABI_CWindows_CGaming_CInput_CIGamepad_put_Vibration(gamepad_state->gamepad, gamepad_state->vibration);
if (SUCCEEDED(hr)) {
rumbled = SDL_TRUE;
}
}
#endif
if (!rumbled) {
#if defined(SDL_JOYSTICK_RAWINPUT_WGI) || defined(SDL_JOYSTICK_RAWINPUT_XINPUT)
return SDL_SetError("Controller isn't correlated yet, try hitting a button first");
@@ -1911,10 +2045,14 @@ static void RAWINPUT_JoystickClose(SDL_Joystick *joystick)
}
}
SDL_bool RAWINPUT_RegisterNotifications(HWND hWnd)
int RAWINPUT_RegisterNotifications(HWND hWnd)
{
RAWINPUTDEVICE rid[SDL_arraysize(subscribed_devices)];
int i;
RAWINPUTDEVICE rid[SDL_arraysize(subscribed_devices)];
if (!SDL_RAWINPUT_inited) {
return 0;
}
for (i = 0; i < SDL_arraysize(subscribed_devices); i++) {
rid[i].usUsagePage = USB_USAGEPAGE_GENERIC_DESKTOP;
@@ -1924,17 +2062,20 @@ SDL_bool RAWINPUT_RegisterNotifications(HWND hWnd)
}
if (!RegisterRawInputDevices(rid, SDL_arraysize(rid), sizeof(RAWINPUTDEVICE))) {
SDL_SetError("Couldn't register for raw input events");
return SDL_FALSE;
return SDL_SetError("Couldn't register for raw input events");
}
return SDL_TRUE;
return 0;
}
void RAWINPUT_UnregisterNotifications()
int RAWINPUT_UnregisterNotifications()
{
int i;
RAWINPUTDEVICE rid[SDL_arraysize(subscribed_devices)];
if (!SDL_RAWINPUT_inited) {
return 0;
}
for (i = 0; i < SDL_arraysize(subscribed_devices); i++) {
rid[i].usUsagePage = USB_USAGEPAGE_GENERIC_DESKTOP;
rid[i].usUsage = subscribed_devices[i];
@@ -1943,9 +2084,9 @@ void RAWINPUT_UnregisterNotifications()
}
if (!RegisterRawInputDevices(rid, SDL_arraysize(rid), sizeof(RAWINPUTDEVICE))) {
SDL_SetError("Couldn't unregister for raw input events");
return;
return SDL_SetError("Couldn't unregister for raw input events");
}
return 0;
}
LRESULT CALLBACK
@@ -28,8 +28,8 @@ extern SDL_bool RAWINPUT_IsEnabled();
extern SDL_bool RAWINPUT_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name);
/* Registers for input events */
extern SDL_bool RAWINPUT_RegisterNotifications(HWND hWnd);
extern void RAWINPUT_UnregisterNotifications();
extern int RAWINPUT_RegisterNotifications(HWND hWnd);
extern int RAWINPUT_UnregisterNotifications();
/* Returns 0 if message was handled */
extern LRESULT CALLBACK RAWINPUT_WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
+162 -108
View File
@@ -101,6 +101,9 @@ static const IID IID_IRacingWheelStatics = { 0x3AC12CD5, 0x581B, 0x4936, { 0x9F,
static const IID IID_IRacingWheelStatics2 = { 0xE666BCAA, 0xEDFD, 0x4323, { 0xA9, 0xF6, 0x3C, 0x38, 0x40, 0x48, 0xD1, 0xED } };
/*static const IID IID_IRacingWheel = { 0xF546656F, 0xE106, 0x4C82, { 0xA9, 0x0F, 0x55, 0x40, 0x12, 0x90, 0x4B, 0x85 } };*/
typedef HRESULT(WINAPI *WindowsCreateStringReference_t)(PCWSTR sourceString, UINT32 length, HSTRING_HEADER *hstringHeader, HSTRING *string);
typedef HRESULT(WINAPI *RoGetActivationFactory_t)(HSTRING activatableClassId, REFIID iid, void **factory);
extern SDL_bool SDL_XINPUT_Enabled(void);
extern SDL_bool SDL_DINPUT_JoystickPresent(Uint16 vendor, Uint16 product, Uint16 version);
@@ -211,6 +214,136 @@ static SDL_bool SDL_IsXInputDevice(Uint16 vendor, Uint16 product)
return SDL_FALSE;
}
static void WGI_LoadRawGameControllerStatics()
{
WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = NULL;
RoGetActivationFactory_t RoGetActivationFactoryFunc = NULL;
HRESULT hr;
#ifdef __WINRT__
WindowsCreateStringReferenceFunc = WindowsCreateStringReference;
RoGetActivationFactoryFunc = RoGetActivationFactory;
#else
{
WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)WIN_LoadComBaseFunction("WindowsCreateStringReference");
RoGetActivationFactoryFunc = (RoGetActivationFactory_t)WIN_LoadComBaseFunction("RoGetActivationFactory");
}
#endif /* __WINRT__ */
if (WindowsCreateStringReferenceFunc && RoGetActivationFactoryFunc) {
PCWSTR pNamespace;
HSTRING_HEADER hNamespaceStringHeader;
HSTRING hNamespaceString;
pNamespace = L"Windows.Gaming.Input.RawGameController";
hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString);
if (SUCCEEDED(hr)) {
hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IRawGameControllerStatics, (void **)&wgi.statics);
if (!SUCCEEDED(hr)) {
SDL_SetError("Couldn't find IRawGameControllerStatics: 0x%lx", hr);
}
}
}
}
static void WGI_LoadOtherControllerStatics()
{
WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = NULL;
RoGetActivationFactory_t RoGetActivationFactoryFunc = NULL;
HRESULT hr;
#ifdef __WINRT__
WindowsCreateStringReferenceFunc = WindowsCreateStringReference;
RoGetActivationFactoryFunc = RoGetActivationFactory;
#else
{
WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)WIN_LoadComBaseFunction("WindowsCreateStringReference");
RoGetActivationFactoryFunc = (RoGetActivationFactory_t)WIN_LoadComBaseFunction("RoGetActivationFactory");
}
#endif /* __WINRT__ */
if (WindowsCreateStringReferenceFunc && RoGetActivationFactoryFunc) {
PCWSTR pNamespace;
HSTRING_HEADER hNamespaceStringHeader;
HSTRING hNamespaceString;
pNamespace = L"Windows.Gaming.Input.ArcadeStick";
hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString);
if (SUCCEEDED(hr)) {
hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IArcadeStickStatics, (void **)&wgi.arcade_stick_statics);
if (SUCCEEDED(hr)) {
__x_ABI_CWindows_CGaming_CInput_CIArcadeStickStatics_QueryInterface(wgi.arcade_stick_statics, &IID_IArcadeStickStatics2, (void **)&wgi.arcade_stick_statics2);
} else {
SDL_SetError("Couldn't find IID_IArcadeStickStatics: 0x%lx", hr);
}
}
pNamespace = L"Windows.Gaming.Input.FlightStick";
hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString);
if (SUCCEEDED(hr)) {
hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IFlightStickStatics, (void **)&wgi.flight_stick_statics);
if (!SUCCEEDED(hr)) {
SDL_SetError("Couldn't find IID_IFlightStickStatics: 0x%lx", hr);
}
}
pNamespace = L"Windows.Gaming.Input.Gamepad";
hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString);
if (SUCCEEDED(hr)) {
hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IGamepadStatics, (void **)&wgi.gamepad_statics);
if (SUCCEEDED(hr)) {
__x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_QueryInterface(wgi.gamepad_statics, &IID_IGamepadStatics2, (void **)&wgi.gamepad_statics2);
} else {
SDL_SetError("Couldn't find IGamepadStatics: 0x%lx", hr);
}
}
pNamespace = L"Windows.Gaming.Input.RacingWheel";
hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString);
if (SUCCEEDED(hr)) {
hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IRacingWheelStatics, (void **)&wgi.racing_wheel_statics);
if (SUCCEEDED(hr)) {
__x_ABI_CWindows_CGaming_CInput_CIRacingWheelStatics_QueryInterface(wgi.racing_wheel_statics, &IID_IRacingWheelStatics2, (void **)&wgi.racing_wheel_statics2);
} else {
SDL_SetError("Couldn't find IRacingWheelStatics: 0x%lx", hr);
}
}
}
}
static SDL_JoystickType GetGameControllerType(__x_ABI_CWindows_CGaming_CInput_CIGameController *gamecontroller)
{
__x_ABI_CWindows_CGaming_CInput_CIArcadeStick *arcade_stick = NULL;
__x_ABI_CWindows_CGaming_CInput_CIFlightStick *flight_stick = NULL;
__x_ABI_CWindows_CGaming_CInput_CIGamepad *gamepad = NULL;
__x_ABI_CWindows_CGaming_CInput_CIRacingWheel *racing_wheel = NULL;
/* Wait to initialize these interfaces until we need them.
* Initializing the gamepad interface will switch Bluetooth PS4 controllers into enhanced mode, breaking DirectInput
*/
WGI_LoadOtherControllerStatics();
if (wgi.gamepad_statics2 && SUCCEEDED(__x_ABI_CWindows_CGaming_CInput_CIGamepadStatics2_FromGameController(wgi.gamepad_statics2, gamecontroller, &gamepad)) && gamepad) {
__x_ABI_CWindows_CGaming_CInput_CIGamepad_Release(gamepad);
return SDL_JOYSTICK_TYPE_GAMECONTROLLER;
}
if (wgi.arcade_stick_statics2 && SUCCEEDED(__x_ABI_CWindows_CGaming_CInput_CIArcadeStickStatics2_FromGameController(wgi.arcade_stick_statics2, gamecontroller, &arcade_stick)) && arcade_stick) {
__x_ABI_CWindows_CGaming_CInput_CIArcadeStick_Release(arcade_stick);
return SDL_JOYSTICK_TYPE_ARCADE_STICK;
}
if (wgi.flight_stick_statics && SUCCEEDED(__x_ABI_CWindows_CGaming_CInput_CIFlightStickStatics_FromGameController(wgi.flight_stick_statics, gamecontroller, &flight_stick)) && flight_stick) {
__x_ABI_CWindows_CGaming_CInput_CIFlightStick_Release(flight_stick);
return SDL_JOYSTICK_TYPE_FLIGHT_STICK;
}
if (wgi.racing_wheel_statics2 && SUCCEEDED(__x_ABI_CWindows_CGaming_CInput_CIRacingWheelStatics2_FromGameController(wgi.racing_wheel_statics2, gamecontroller, &racing_wheel)) && racing_wheel) {
__x_ABI_CWindows_CGaming_CInput_CIRacingWheel_Release(racing_wheel);
return SDL_JOYSTICK_TYPE_WHEEL;
}
return SDL_JOYSTICK_TYPE_UNKNOWN;
}
typedef struct RawGameControllerDelegate
{
__FIEventHandler_1_Windows__CGaming__CInput__CRawGameController iface;
@@ -226,7 +359,7 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_QueryInter
*ppvObject = NULL;
if (WIN_IsEqualIID(riid, &IID_IUnknown) || WIN_IsEqualIID(riid, &IID_IAgileObject) || WIN_IsEqualIID(riid, &IID_IEventHandler_RawGameController)) {
*ppvObject = This;
__x_ABI_CWindows_CGaming_CInput_CIRawGameControllerStatics_AddRef(This);
__FIEventHandler_1_Windows__CGaming__CInput__CRawGameController_AddRef(This);
return S_OK;
} else if (WIN_IsEqualIID(riid, &IID_IMarshal)) {
/* This seems complicated. Let's hope it doesn't happen. */
@@ -313,38 +446,6 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeAdde
name = SDL_strdup("");
}
hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController_QueryInterface(controller, &IID_IGameController, (void **)&gamecontroller);
if (SUCCEEDED(hr)) {
__x_ABI_CWindows_CGaming_CInput_CIArcadeStick *arcade_stick = NULL;
__x_ABI_CWindows_CGaming_CInput_CIFlightStick *flight_stick = NULL;
__x_ABI_CWindows_CGaming_CInput_CIGamepad *gamepad = NULL;
__x_ABI_CWindows_CGaming_CInput_CIRacingWheel *racing_wheel = NULL;
boolean wireless;
if (wgi.gamepad_statics2 && SUCCEEDED(__x_ABI_CWindows_CGaming_CInput_CIGamepadStatics2_FromGameController(wgi.gamepad_statics2, gamecontroller, &gamepad)) && gamepad) {
type = SDL_JOYSTICK_TYPE_GAMECONTROLLER;
__x_ABI_CWindows_CGaming_CInput_CIGamepad_Release(gamepad);
} else if (wgi.arcade_stick_statics2 && SUCCEEDED(__x_ABI_CWindows_CGaming_CInput_CIArcadeStickStatics2_FromGameController(wgi.arcade_stick_statics2, gamecontroller, &arcade_stick)) && arcade_stick) {
type = SDL_JOYSTICK_TYPE_ARCADE_STICK;
__x_ABI_CWindows_CGaming_CInput_CIArcadeStick_Release(arcade_stick);
} else if (wgi.flight_stick_statics && SUCCEEDED(__x_ABI_CWindows_CGaming_CInput_CIFlightStickStatics_FromGameController(wgi.flight_stick_statics, gamecontroller, &flight_stick)) && flight_stick) {
type = SDL_JOYSTICK_TYPE_FLIGHT_STICK;
__x_ABI_CWindows_CGaming_CInput_CIFlightStick_Release(flight_stick);
} else if (wgi.racing_wheel_statics2 && SUCCEEDED(__x_ABI_CWindows_CGaming_CInput_CIRacingWheelStatics2_FromGameController(wgi.racing_wheel_statics2, gamecontroller, &racing_wheel)) && racing_wheel) {
type = SDL_JOYSTICK_TYPE_WHEEL;
__x_ABI_CWindows_CGaming_CInput_CIRacingWheel_Release(racing_wheel);
}
hr = __x_ABI_CWindows_CGaming_CInput_CIGameController_get_IsWireless(gamecontroller, &wireless);
if (SUCCEEDED(hr) && wireless) {
bus = SDL_HARDWARE_BUS_BLUETOOTH;
}
__x_ABI_CWindows_CGaming_CInput_CIGameController_Release(gamecontroller);
}
guid = SDL_CreateJoystickGUID(bus, vendor, product, version, name, 'w', (Uint8)type);
#ifdef SDL_JOYSTICK_HIDAPI
if (!ignore_joystick && HIDAPI_IsDevicePresent(vendor, product, version, name)) {
ignore_joystick = SDL_TRUE;
@@ -365,13 +466,29 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeAdde
ignore_joystick = SDL_TRUE;
}
if (!ignore_joystick && SDL_ShouldIgnoreJoystick(name, guid)) {
ignore_joystick = SDL_TRUE;
if (!ignore_joystick) {
hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController_QueryInterface(controller, &IID_IGameController, (void **)&gamecontroller);
if (SUCCEEDED(hr)) {
boolean wireless;
type = GetGameControllerType(gamecontroller);
hr = __x_ABI_CWindows_CGaming_CInput_CIGameController_get_IsWireless(gamecontroller, &wireless);
if (SUCCEEDED(hr) && wireless) {
bus = SDL_HARDWARE_BUS_BLUETOOTH;
}
__x_ABI_CWindows_CGaming_CInput_CIGameController_Release(gamecontroller);
}
guid = SDL_CreateJoystickGUID(bus, vendor, product, version, name, 'w', (Uint8)type);
if (SDL_ShouldIgnoreJoystick(name, guid)) {
ignore_joystick = SDL_TRUE;
}
}
if (ignore_joystick) {
SDL_free(name);
} else {
if (!ignore_joystick) {
/* New device, add it */
WindowsGamingInputControllerState *controllers = SDL_realloc(wgi.controllers, sizeof(wgi.controllers[0]) * (wgi.controller_count + 1));
if (controllers) {
@@ -398,6 +515,8 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeAdde
} else {
SDL_free(name);
}
} else {
SDL_free(name);
}
__x_ABI_CWindows_CGaming_CInput_CIRawGameController_Release(controller);
@@ -476,13 +595,12 @@ static RawGameControllerDelegate controller_removed = {
static int WGI_JoystickInit(void)
{
typedef HRESULT(WINAPI * WindowsCreateStringReference_t)(PCWSTR sourceString, UINT32 length, HSTRING_HEADER * hstringHeader, HSTRING * string);
typedef HRESULT(WINAPI * RoGetActivationFactory_t)(HSTRING activatableClassId, REFIID iid, void **factory);
WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = NULL;
RoGetActivationFactory_t RoGetActivationFactoryFunc = NULL;
HRESULT hr;
if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_WGI, SDL_TRUE)) {
return 0;
}
if (FAILED(WIN_RoInitialize())) {
return SDL_SetError("RoInitialize() failed");
}
@@ -511,71 +629,7 @@ static int WGI_JoystickInit(void)
}
#endif
#ifdef __WINRT__
WindowsCreateStringReferenceFunc = WindowsCreateStringReference;
RoGetActivationFactoryFunc = RoGetActivationFactory;
#else
{
WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)WIN_LoadComBaseFunction("WindowsCreateStringReference");
RoGetActivationFactoryFunc = (RoGetActivationFactory_t)WIN_LoadComBaseFunction("RoGetActivationFactory");
}
#endif /* __WINRT__ */
if (WindowsCreateStringReferenceFunc && RoGetActivationFactoryFunc) {
PCWSTR pNamespace;
HSTRING_HEADER hNamespaceStringHeader;
HSTRING hNamespaceString;
pNamespace = L"Windows.Gaming.Input.RawGameController";
hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString);
if (SUCCEEDED(hr)) {
hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IRawGameControllerStatics, (void **)&wgi.statics);
if (!SUCCEEDED(hr)) {
SDL_SetError("Couldn't find IRawGameControllerStatics: 0x%lx", hr);
}
}
pNamespace = L"Windows.Gaming.Input.ArcadeStick";
hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString);
if (SUCCEEDED(hr)) {
hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IArcadeStickStatics, (void **)&wgi.arcade_stick_statics);
if (SUCCEEDED(hr)) {
__x_ABI_CWindows_CGaming_CInput_CIArcadeStickStatics_QueryInterface(wgi.arcade_stick_statics, &IID_IArcadeStickStatics2, (void **)&wgi.arcade_stick_statics2);
} else {
SDL_SetError("Couldn't find IID_IArcadeStickStatics: 0x%lx", hr);
}
}
pNamespace = L"Windows.Gaming.Input.FlightStick";
hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString);
if (SUCCEEDED(hr)) {
hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IFlightStickStatics, (void **)&wgi.flight_stick_statics);
if (!SUCCEEDED(hr)) {
SDL_SetError("Couldn't find IID_IFlightStickStatics: 0x%lx", hr);
}
}
pNamespace = L"Windows.Gaming.Input.Gamepad";
hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString);
if (SUCCEEDED(hr)) {
hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IGamepadStatics, (void **)&wgi.gamepad_statics);
if (SUCCEEDED(hr)) {
__x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_QueryInterface(wgi.gamepad_statics, &IID_IGamepadStatics2, (void **)&wgi.gamepad_statics2);
} else {
SDL_SetError("Couldn't find IGamepadStatics: 0x%lx", hr);
}
}
pNamespace = L"Windows.Gaming.Input.RacingWheel";
hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString);
if (SUCCEEDED(hr)) {
hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IRacingWheelStatics, (void **)&wgi.racing_wheel_statics);
if (SUCCEEDED(hr)) {
__x_ABI_CWindows_CGaming_CInput_CIRacingWheelStatics_QueryInterface(wgi.racing_wheel_statics, &IID_IRacingWheelStatics2, (void **)&wgi.racing_wheel_statics2);
} else {
SDL_SetError("Couldn't find IRacingWheelStatics: 0x%lx", hr);
}
}
}
WGI_LoadRawGameControllerStatics();
if (wgi.statics) {
__FIVectorView_1_Windows__CGaming__CInput__CRawGameController *controllers;
+14 -7
View File
@@ -235,6 +235,20 @@ static void AddXInputDevice(Uint8 userid, BYTE SubType, JoyStick_DeviceData **pC
JoyStick_DeviceData *pPrevJoystick = NULL;
JoyStick_DeviceData *pNewJoystick = *pContext;
#ifdef SDL_JOYSTICK_RAWINPUT
if (RAWINPUT_IsEnabled()) {
/* The raw input driver handles more than 4 controllers, so prefer that when available */
/* We do this check here rather than at the top of SDL_XINPUT_JoystickDetect() because
we need to check XInput state before RAWINPUT gets a hold of the device, otherwise
when a controller is connected via the wireless adapter, it will shut down at the
first subsequent XInput call. This seems like a driver stack bug?
Reference: https://github.com/libsdl-org/SDL/issues/3468
*/
return;
}
#endif
if (SDL_XInputUseOldJoystickMapping() && SubType != XINPUT_DEVSUBTYPE_GAMEPAD) {
return;
}
@@ -322,13 +336,6 @@ void SDL_XINPUT_JoystickDetect(JoyStick_DeviceData **pContext)
return;
}
#ifdef SDL_JOYSTICK_RAWINPUT
if (RAWINPUT_IsEnabled()) {
/* The raw input driver handles more than 4 controllers, so prefer that when available */
return;
}
#endif
/* iterate in reverse, so these are in the final list in ascending numeric order. */
for (iuserid = XUSER_MAX_COUNT - 1; iuserid >= 0; iuserid--) {
const Uint8 userid = (Uint8)iuserid;
+1 -1
View File
@@ -103,7 +103,7 @@ int console_wmain(int argc, wchar_t *wargv[], wchar_t *wenvp)
#endif
/* This is where execution begins [windowed apps] */
int WINAPI
int WINAPI MINGW32_FORCEALIGN
WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) /* NOLINT(readability-inconsistent-declaration-parameter-name) */
{
return main_getcmdline();
+4 -4
View File
@@ -9,8 +9,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 2,28,0,0
PRODUCTVERSION 2,28,0,0
FILEVERSION 2,28,4,0
PRODUCTVERSION 2,28,4,0
FILEFLAGSMASK 0x3fL
FILEFLAGS 0x0L
FILEOS 0x40004L
@@ -23,12 +23,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "\0"
VALUE "FileDescription", "SDL\0"
VALUE "FileVersion", "2, 28, 0, 0\0"
VALUE "FileVersion", "2, 28, 4, 0\0"
VALUE "InternalName", "SDL\0"
VALUE "LegalCopyright", "Copyright (C) 2023 Sam Lantinga\0"
VALUE "OriginalFilename", "SDL2.dll\0"
VALUE "ProductName", "Simple DirectMedia Layer\0"
VALUE "ProductVersion", "2, 28, 0, 0\0"
VALUE "ProductVersion", "2, 28, 4, 0\0"
END
END
BLOCK "VarFileInfo"
+3 -5
View File
@@ -23,13 +23,11 @@
#include <emscripten/emscripten.h>
EM_JS_DEPS(sdlsysurl, "$UTF8ToString");
int SDL_SYS_OpenURL(const char *url)
{
EM_ASM({
window.open(UTF8ToString($0), "_blank");
},
url);
EM_ASM(window.open(UTF8ToString($0), "_blank"), url);
return 0;
}
+13
View File
@@ -32,6 +32,18 @@ int SDL_SYS_OpenURL(const char *url)
{
const pid_t pid1 = fork();
if (pid1 == 0) { /* child process */
#ifdef USE_POSIX_SPAWN
pid_t pid2;
const char *args[] = { "xdg-open", url, NULL };
/* Clear LD_PRELOAD so Chrome opens correctly when this application is launched by Steam */
unsetenv("LD_PRELOAD");
if (posix_spawnp(&pid2, args[0], NULL, NULL, (char **)args, environ) == 0) {
/* Child process doesn't wait for possibly-blocking grandchild. */
_exit(EXIT_SUCCESS);
} else {
_exit(EXIT_FAILURE);
}
#else
pid_t pid2;
/* Clear LD_PRELOAD so Chrome opens correctly when this application is launched by Steam */
unsetenv("LD_PRELOAD");
@@ -46,6 +58,7 @@ int SDL_SYS_OpenURL(const char *url)
/* Child process doesn't wait for possibly-blocking grandchild. */
_exit(EXIT_SUCCESS);
}
#endif /* USE_POSIX_SPAWN */
} else if (pid1 < 0) {
return SDL_SetError("fork() failed: %s", strerror(errno));
} else {
+1 -1
View File
@@ -2481,7 +2481,7 @@ int SDL_RenderSetClipRect(SDL_Renderer *renderer, const SDL_Rect *rect)
int retval;
CHECK_RENDERER_MAGIC(renderer, -1)
if (rect && rect->w > 0 && rect->h > 0) {
if (rect && rect->w >= 0 && rect->h >= 0) {
renderer->clipping_enabled = SDL_TRUE;
renderer->clip_rect.x = (double)rect->x * renderer->scale.x;
renderer->clip_rect.y = (double)rect->y * renderer->scale.y;
+1 -1
View File
@@ -2143,7 +2143,7 @@ static int D3D11_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect,
D3D11_BOX srcBox;
D3D11_MAPPED_SUBRESOURCE textureMemory;
ID3D11DeviceContext_OMGetRenderTargets(data->d3dContext, 1, &renderTargetView, NULL);
renderTargetView = D3D11_GetCurrentRenderTargetView(renderer);
if (renderTargetView == NULL) {
SDL_SetError("%s, ID3D11DeviceContext::OMGetRenderTargets failed", __FUNCTION__);
goto done;
+6 -1
View File
@@ -2609,6 +2609,7 @@ static int D3D12_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
case SDL_RENDERCMD_SETCLIPRECT:
{
const SDL_Rect *rect = &cmd->data.cliprect.rect;
SDL_Rect viewport_cliprect;
if (rendererData->currentCliprectEnabled != cmd->data.cliprect.enabled) {
rendererData->currentCliprectEnabled = cmd->data.cliprect.enabled;
rendererData->cliprectDirty = SDL_TRUE;
@@ -2616,7 +2617,11 @@ static int D3D12_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
if (!rendererData->currentCliprectEnabled) {
/* If the clip rect is disabled, then the scissor rect should be the whole viewport,
since direct3d12 doesn't allow disabling the scissor rectangle */
rect = &rendererData->currentViewport;
viewport_cliprect.x = 0;
viewport_cliprect.y = 0;
viewport_cliprect.w = rendererData->currentViewport.w;
viewport_cliprect.h = rendererData->currentViewport.h;
rect = &viewport_cliprect;
}
if (SDL_memcmp(&rendererData->currentCliprect, rect, sizeof(*rect)) != 0) {
SDL_copyp(&rendererData->currentCliprect, rect);
+16 -2
View File
@@ -1654,8 +1654,22 @@ static SDL_Renderer *METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
return NULL;
}
// !!! FIXME: MTLCopyAllDevices() can find other GPUs on macOS...
mtldevice = MTLCreateSystemDefaultDevice();
#ifdef __MACOSX__
if (SDL_GetHintBoolean(SDL_HINT_RENDER_METAL_PREFER_LOW_POWER_DEVICE, SDL_TRUE)) {
NSArray<id<MTLDevice>> *devices = MTLCopyAllDevices();
for (id<MTLDevice> device in devices) {
if (device.isLowPower) {
mtldevice = device;
break;
}
}
}
#endif
if (mtldevice == nil) {
mtldevice = MTLCreateSystemDefaultDevice();
}
if (mtldevice == nil) {
SDL_free(renderer);
+6 -10
View File
@@ -795,17 +795,13 @@ char *SDL_iconv_string(const char *tocode, const char *fromcode, const char *inb
size_t outbytesleft;
size_t retCode = 0;
cd = SDL_iconv_open(tocode, fromcode);
if (cd == (SDL_iconv_t)-1) {
/* See if we can recover here (fixes iconv on Solaris 11) */
if (tocode == NULL || !*tocode) {
tocode = "UTF-8";
}
if (fromcode == NULL || !*fromcode) {
fromcode = "UTF-8";
}
cd = SDL_iconv_open(tocode, fromcode);
if (tocode == NULL || !*tocode) {
tocode = "UTF-8";
}
if (fromcode == NULL || !*fromcode) {
fromcode = "UTF-8";
}
cd = SDL_iconv_open(tocode, fromcode);
if (cd == (SDL_iconv_t)-1) {
return NULL;
}
+3 -1
View File
@@ -1190,7 +1190,9 @@ int SDL_vsscanf(const char *text, const char *fmt, va_list ap)
suppress = SDL_TRUE;
break;
case 'h':
if (inttype > DO_SHORT) {
if (inttype == DO_INT) {
inttype = DO_SHORT;
} else if (inttype > DO_SHORT) {
++inttype;
}
break;
+24 -2
View File
@@ -36,6 +36,25 @@
/* Counter for _CompareSurface calls; used for filename creation when comparisons fail */
static int _CompareSurfaceCount = 0;
static Uint32
GetPixel(Uint8 *p, size_t bytes_per_pixel)
{
Uint32 ret = 0;
SDL_assert(bytes_per_pixel <= sizeof(ret));
/* Fill the appropriate number of least-significant bytes of ret,
* leaving the most-significant bytes set to zero, so that ret can
* be decoded with SDL_GetRGBA afterwards. */
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
SDL_memcpy(((Uint8 *) &ret) + (sizeof(ret) - bytes_per_pixel), p, bytes_per_pixel);
#else
SDL_memcpy(&ret, p, bytes_per_pixel);
#endif
return ret;
}
/* Compare surfaces */
int SDLTest_CompareSurfaces(SDL_Surface *surface, SDL_Surface *referenceSurface, int allowable_error)
{
@@ -74,11 +93,14 @@ int SDLTest_CompareSurfaces(SDL_Surface *surface, SDL_Surface *referenceSurface,
/* Compare image - should be same format. */
for (j = 0; j < surface->h; j++) {
for (i = 0; i < surface->w; i++) {
Uint32 pixel;
p = (Uint8 *)surface->pixels + j * surface->pitch + i * bpp;
p_reference = (Uint8 *)referenceSurface->pixels + j * referenceSurface->pitch + i * bpp_reference;
SDL_GetRGBA(*(Uint32 *)p, surface->format, &R, &G, &B, &A);
SDL_GetRGBA(*(Uint32 *)p_reference, referenceSurface->format, &Rd, &Gd, &Bd, &Ad);
pixel = GetPixel(p, bpp);
SDL_GetRGBA(pixel, surface->format, &R, &G, &B, &A);
pixel = GetPixel(p_reference, bpp_reference);
SDL_GetRGBA(pixel, referenceSurface->format, &Rd, &Gd, &Bd, &Ad);
dist = 0;
dist += (R - Rd) * (R - Rd);
+20 -30
View File
@@ -71,10 +71,8 @@ static SDL_mutex *SDL_CreateMutex_srw(void)
static void SDL_DestroyMutex_srw(SDL_mutex *mutex)
{
if (mutex != NULL) {
/* There are no kernel allocated resources */
SDL_free(mutex);
}
/* There are no kernel allocated resources */
SDL_free(mutex);
}
static int SDL_LockMutex_srw(SDL_mutex *_mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
@@ -82,10 +80,6 @@ static int SDL_LockMutex_srw(SDL_mutex *_mutex) SDL_NO_THREAD_SAFETY_ANALYSIS /*
SDL_mutex_srw *mutex = (SDL_mutex_srw *)_mutex;
DWORD this_thread;
if (mutex == NULL) {
return 0;
}
this_thread = GetCurrentThreadId();
if (mutex->owner == this_thread) {
++mutex->count;
@@ -108,10 +102,6 @@ static int SDL_TryLockMutex_srw(SDL_mutex *_mutex)
DWORD this_thread;
int retval = 0;
if (mutex == NULL) {
return 0;
}
this_thread = GetCurrentThreadId();
if (mutex->owner == this_thread) {
++mutex->count;
@@ -131,10 +121,6 @@ static int SDL_UnlockMutex_srw(SDL_mutex *_mutex) SDL_NO_THREAD_SAFETY_ANALYSIS
{
SDL_mutex_srw *mutex = (SDL_mutex_srw *)_mutex;
if (mutex == NULL) {
return 0;
}
if (mutex->owner == GetCurrentThreadId()) {
if (--mutex->count == 0) {
mutex->owner = 0;
@@ -185,19 +171,15 @@ static SDL_mutex *SDL_CreateMutex_cs(void)
static void SDL_DestroyMutex_cs(SDL_mutex *mutex_)
{
SDL_mutex_cs *mutex = (SDL_mutex_cs *)mutex_;
if (mutex != NULL) {
DeleteCriticalSection(&mutex->cs);
SDL_free(mutex);
}
DeleteCriticalSection(&mutex->cs);
SDL_free(mutex);
}
/* Lock the mutex */
static int SDL_LockMutex_cs(SDL_mutex *mutex_) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
{
SDL_mutex_cs *mutex = (SDL_mutex_cs *)mutex_;
if (mutex == NULL) {
return 0;
}
EnterCriticalSection(&mutex->cs);
return 0;
@@ -208,9 +190,6 @@ static int SDL_TryLockMutex_cs(SDL_mutex *mutex_)
{
SDL_mutex_cs *mutex = (SDL_mutex_cs *)mutex_;
int retval = 0;
if (mutex == NULL) {
return 0;
}
if (TryEnterCriticalSection(&mutex->cs) == 0) {
retval = SDL_MUTEX_TIMEDOUT;
@@ -222,9 +201,6 @@ static int SDL_TryLockMutex_cs(SDL_mutex *mutex_)
static int SDL_UnlockMutex_cs(SDL_mutex *mutex_) SDL_NO_THREAD_SAFETY_ANALYSIS /* clang doesn't know about NULL mutexes */
{
SDL_mutex_cs *mutex = (SDL_mutex_cs *)mutex_;
if (mutex == NULL) {
return 0;
}
LeaveCriticalSection(&mutex->cs);
return 0;
@@ -277,21 +253,35 @@ SDL_mutex *SDL_CreateMutex(void)
void SDL_DestroyMutex(SDL_mutex *mutex)
{
SDL_mutex_impl_active.Destroy(mutex);
if (mutex) {
SDL_mutex_impl_active.Destroy(mutex);
}
}
int SDL_LockMutex(SDL_mutex *mutex)
{
if (mutex == NULL) {
return 0;
}
return SDL_mutex_impl_active.Lock(mutex);
}
int SDL_TryLockMutex(SDL_mutex *mutex)
{
if (mutex == NULL) {
return 0;
}
return SDL_mutex_impl_active.TryLock(mutex);
}
int SDL_UnlockMutex(SDL_mutex *mutex)
{
if (mutex == NULL) {
return 0;
}
return SDL_mutex_impl_active.Unlock(mutex);
}
+2 -2
View File
@@ -55,12 +55,12 @@ static DWORD RunThread(void *data)
return 0;
}
static DWORD WINAPI RunThreadViaCreateThread(LPVOID data)
static DWORD WINAPI MINGW32_FORCEALIGN RunThreadViaCreateThread(LPVOID data)
{
return RunThread(data);
}
static unsigned __stdcall RunThreadViaBeginThreadEx(void *data)
static unsigned __stdcall MINGW32_FORCEALIGN RunThreadViaBeginThreadEx(void *data)
{
return (unsigned)RunThread(data);
}
+8
View File
@@ -852,6 +852,10 @@ void SDL_DetectPalette(SDL_Palette *pal, SDL_bool *is_opaque, SDL_bool *has_alph
/* Find the opaque pixel value corresponding to an RGB triple */
Uint32 SDL_MapRGB(const SDL_PixelFormat *format, Uint8 r, Uint8 g, Uint8 b)
{
if (!format) {
SDL_InvalidParamError("format");
return 0;
}
if (format->palette == NULL) {
return (r >> format->Rloss) << format->Rshift | (g >> format->Gloss) << format->Gshift | (b >> format->Bloss) << format->Bshift | format->Amask;
} else {
@@ -862,6 +866,10 @@ Uint32 SDL_MapRGB(const SDL_PixelFormat *format, Uint8 r, Uint8 g, Uint8 b)
/* Find the pixel value corresponding to an RGBA quadruple */
Uint32 SDL_MapRGBA(const SDL_PixelFormat *format, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
if (!format) {
SDL_InvalidParamError("format");
return 0;
}
if (format->palette == NULL) {
return (r >> format->Rloss) << format->Rshift | (g >> format->Gloss) << format->Gshift | (b >> format->Bloss) << format->Bshift | ((Uint32)(a >> format->Aloss) << format->Ashift & format->Amask);
} else {
+9 -5
View File
@@ -18,6 +18,7 @@
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../SDL_internal.h"
/* The high-level video driver subsystem */
@@ -127,15 +128,15 @@ static VideoBootStrap *bootstrap[] = {
#if SDL_VIDEO_DRIVER_QNX
&QNX_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_OFFSCREEN
&OFFSCREEN_bootstrap,
#if SDL_VIDEO_DRIVER_OS2
&OS2DIVE_bootstrap,
&OS2VMAN_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_NGAGE
&NGAGE_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_OS2
&OS2DIVE_bootstrap,
&OS2VMAN_bootstrap,
#if SDL_VIDEO_DRIVER_OFFSCREEN
&OFFSCREEN_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_DUMMY
&DUMMY_bootstrap,
@@ -1398,6 +1399,9 @@ static int SDL_UpdateFullscreenMode(SDL_Window *window, SDL_bool fullscreen)
#endif
display = SDL_GetDisplayForWindow(window);
if (display == NULL) { /* No display connected, nothing to do. */
return 0;
}
if (fullscreen) {
/* Hide any other fullscreen windows */
+2
View File
@@ -40,6 +40,8 @@ typedef struct {
/* What location we last saw the cursor move to. */
CGFloat lastMoveX;
CGFloat lastMoveY;
/* If we just turned on relative mode, and should skip a single mouse motion event. */
SDL_bool justEnabledRelative;
} SDL_MouseData;
@interface NSCursor (InvisibleCursor)
+9 -1
View File
@@ -293,8 +293,11 @@ static int Cocoa_SetRelativeMouseMode(SDL_bool enabled)
if (enabled) {
if (window) {
/* make sure the mouse isn't at the corner of the window, as this can confuse things if macOS thinks a window resize is happening on the first click. */
SDL_MouseData *mousedriverdata = (SDL_MouseData*)SDL_GetMouse()->driverdata;
const CGPoint point = CGPointMake((float)(window->x + (window->w / 2)), (float)(window->y + (window->h / 2)));
Cocoa_HandleMouseWarp(point.x, point.y);
if (mousedriverdata) {
mousedriverdata->justEnabledRelative = SDL_TRUE;
}
CGWarpMouseCursorPosition(point);
}
DLog("Turning on.");
@@ -465,6 +468,11 @@ void Cocoa_HandleMouseEvent(_THIS, NSEvent *event)
seenWarp = driverdata->seenWarp;
driverdata->seenWarp = NO;
if (driverdata->justEnabledRelative) {
driverdata->justEnabledRelative = SDL_FALSE;
return; // dump the first event back.
}
location = [NSEvent mouseLocation];
lastMoveX = driverdata->lastMoveX;
lastMoveY = driverdata->lastMoveY;
+12 -1
View File
@@ -31,6 +31,15 @@
#include "../../events/SDL_mouse_c.h"
/* older Emscriptens don't have this, but we need to for wasm64 compatibility. */
#ifndef MAIN_THREAD_EM_ASM_PTR
#ifdef __wasm64__
#error You need to upgrade your Emscripten compiler to support wasm64
#else
#define MAIN_THREAD_EM_ASM_PTR MAIN_THREAD_EM_ASM_INT
#endif
#endif
static SDL_Cursor *Emscripten_CreateCursorFromString(const char *cursor_str, SDL_bool is_custom)
{
SDL_Cursor *cursor;
@@ -60,6 +69,8 @@ static SDL_Cursor *Emscripten_CreateDefaultCursor()
return Emscripten_CreateCursorFromString("default", SDL_FALSE);
}
EM_JS_DEPS(sdlmouse, "$stringToUTF8,$UTF8ToString");
static SDL_Cursor *Emscripten_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
{
const char *cursor_url = NULL;
@@ -72,7 +83,7 @@ static SDL_Cursor *Emscripten_CreateCursor(SDL_Surface *surface, int hot_x, int
}
/* *INDENT-OFF* */ /* clang-format off */
cursor_url = (const char *)MAIN_THREAD_EM_ASM_INT({
cursor_url = (const char *)MAIN_THREAD_EM_ASM_PTR({
var w = $0;
var h = $1;
var hot_x = $2;
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+12
View File
@@ -412,6 +412,9 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
SDL_SendKeyboardKey(SDL_PRESSED, scancode);
}
}
if (SDL_IsTextInputActive()) {
[super pressesBegan:presses withEvent:event];
}
}
- (void)pressesEnded:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
@@ -422,6 +425,9 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
SDL_SendKeyboardKey(SDL_RELEASED, scancode);
}
}
if (SDL_IsTextInputActive()) {
[super pressesEnded:presses withEvent:event];
}
}
- (void)pressesCancelled:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
@@ -432,11 +438,17 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
SDL_SendKeyboardKey(SDL_RELEASED, scancode);
}
}
if (SDL_IsTextInputActive()) {
[super pressesCancelled:presses withEvent:event];
}
}
- (void)pressesChanged:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
{
/* This is only called when the force of a press changes. */
if (SDL_IsTextInputActive()) {
[super pressesChanged:presses withEvent:event];
}
}
#endif /* TARGET_OS_TV || defined(__IPHONE_9_1) */
+75 -10
View File
@@ -74,6 +74,7 @@ SDL_HideHomeIndicatorHintChanged(void *userdata, const char *name, const char *o
UITextField *textField;
BOOL hardwareKeyboard;
BOOL showingKeyboard;
BOOL hidingKeyboard;
BOOL rotatingOrientation;
NSString *committedText;
NSString *obligateForBackspace;
@@ -91,6 +92,7 @@ SDL_HideHomeIndicatorHintChanged(void *userdata, const char *name, const char *o
[self initKeyboard];
hardwareKeyboard = NO;
showingKeyboard = NO;
hidingKeyboard = NO;
rotatingOrientation = NO;
#endif
@@ -277,8 +279,22 @@ SDL_HideHomeIndicatorHintChanged(void *userdata, const char *name, const char *o
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
#if !TARGET_OS_TV
[center addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[center addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
[center addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[center addObserver:self
selector:@selector(keyboardDidShow:)
name:UIKeyboardDidShowNotification
object:nil];
[center addObserver:self
selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
[center addObserver:self
selector:@selector(keyboardDidHide:)
name:UIKeyboardDidHideNotification
object:nil];
#endif
[center addObserver:self selector:@selector(textFieldTextDidChange:) name:UITextFieldTextDidChangeNotification object:nil];
}
@@ -341,8 +357,18 @@ SDL_HideHomeIndicatorHintChanged(void *userdata, const char *name, const char *o
{
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
#if !TARGET_OS_TV
[center removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[center removeObserver:self name:UIKeyboardWillHideNotification object:nil];
[center removeObserver:self
name:UIKeyboardWillShowNotification
object:nil];
[center removeObserver:self
name:UIKeyboardDidShowNotification
object:nil];
[center removeObserver:self
name:UIKeyboardWillHideNotification
object:nil];
[center removeObserver:self
name:UIKeyboardDidHideNotification
object:nil];
#endif
[center removeObserver:self name:UITextFieldTextDidChangeNotification object:nil];
}
@@ -350,23 +376,40 @@ SDL_HideHomeIndicatorHintChanged(void *userdata, const char *name, const char *o
/* reveal onscreen virtual keyboard */
- (void)showKeyboard
{
if (keyboardVisible) {
return;
}
keyboardVisible = YES;
if (textField.window) {
showingKeyboard = YES;
[textField becomeFirstResponder];
showingKeyboard = NO;
}
}
/* hide onscreen virtual keyboard */
- (void)hideKeyboard
{
if (!keyboardVisible) {
return;
}
keyboardVisible = NO;
[textField resignFirstResponder];
if (textField.window) {
hidingKeyboard = YES;
[textField resignFirstResponder];
}
}
- (void)keyboardWillShow:(NSNotification *)notification
{
BOOL shouldStartTextInput = NO;
if (!SDL_IsTextInputActive() && !hidingKeyboard && !rotatingOrientation) {
shouldStartTextInput = YES;
}
showingKeyboard = YES;
#if !TARGET_OS_TV
CGRect kbrect = [[notification userInfo][UIKeyboardFrameEndUserInfoKey] CGRectValue];
@@ -376,14 +419,36 @@ SDL_HideHomeIndicatorHintChanged(void *userdata, const char *name, const char *o
[self setKeyboardHeight:(int)kbrect.size.height];
#endif
if (shouldStartTextInput) {
SDL_StartTextInput();
}
}
- (void)keyboardDidShow:(NSNotification *)notification
{
showingKeyboard = NO;
}
- (void)keyboardWillHide:(NSNotification *)notification
{
if (!showingKeyboard && !rotatingOrientation) {
BOOL shouldStopTextInput = NO;
if (SDL_IsTextInputActive() && !showingKeyboard && !rotatingOrientation) {
shouldStopTextInput = YES;
}
hidingKeyboard = YES;
[self setKeyboardHeight:0];
if (shouldStopTextInput) {
SDL_StopTextInput();
}
[self setKeyboardHeight:0];
}
- (void)keyboardDidHide:(NSNotification *)notification
{
hidingKeyboard = NO;
}
- (void)textFieldTextDidChange:(NSNotification *)notification
@@ -402,8 +467,8 @@ SDL_HideHomeIndicatorHintChanged(void *userdata, const char *name, const char *o
size_t deleteLength = SDL_utf8strlen([[committedText substringFromIndex:matchLength] UTF8String]);
while (deleteLength > 0) {
/* Send distinct down and up events for each backspace action */
SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_BACKSPACE);
SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_BACKSPACE);
SDL_SendVirtualKeyboardKey(SDL_PRESSED, SDL_SCANCODE_BACKSPACE);
SDL_SendVirtualKeyboardKey(SDL_RELEASED, SDL_SCANCODE_BACKSPACE);
--deleteLength;
}
}
+18 -21
View File
@@ -37,34 +37,30 @@ typedef struct
const char *libname;
} waylanddynlib;
#ifndef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL
#define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL NULL
#endif
#ifndef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR
#define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR NULL
#endif
#ifndef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON
#define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON NULL
#endif
#ifndef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR
#define SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR NULL
#endif
static waylanddynlib waylandlibs[] = {
{ NULL, SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC },
#ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL
{ NULL, SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL },
#endif
#ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR
{ NULL, SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR },
#endif
#ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON
{ NULL, SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON },
{ NULL, SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR }
#endif
#ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR
{ NULL, SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR },
#endif
{ NULL, NULL }
};
static void *WAYLAND_GetSym(const char *fnname, int *pHasModule, SDL_bool required)
{
int i;
void *fn = NULL;
for (i = 0; i < SDL_TABLESIZE(waylandlibs); i++) {
if (waylandlibs[i].lib != NULL) {
fn = SDL_LoadFunction(waylandlibs[i].lib, fnname);
waylanddynlib *dynlib;
for (dynlib = waylandlibs; dynlib->libname; dynlib++) {
if (dynlib->lib != NULL) {
fn = SDL_LoadFunction(dynlib->lib, fnname);
if (fn != NULL) {
break;
}
@@ -72,10 +68,11 @@ static void *WAYLAND_GetSym(const char *fnname, int *pHasModule, SDL_bool requir
}
#if DEBUG_DYNAMIC_WAYLAND
if (fn != NULL)
SDL_Log("WAYLAND: Found '%s' in %s (%p)\n", fnname, waylandlibs[i].libname, fn);
else
if (fn != NULL) {
SDL_Log("WAYLAND: Found '%s' in %s (%p)\n", fnname, dynlib->libname, fn);
} else {
SDL_Log("WAYLAND: Symbol '%s' NOT FOUND!\n", fnname);
}
#endif
if (fn == NULL && required) {
+192 -134
View File
@@ -33,162 +33,220 @@
#include "SDL_waylandmessagebox.h"
#define ZENITY_VERSION_LEN 32 /* Number of bytes to read from zenity --version (including NUL)*/
#define MAX_BUTTONS 8 /* Maximum number of buttons supported */
int Wayland_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
{
int fd_pipe[2]; /* fd_pipe[0]: read end of pipe, fd_pipe[1]: write end of pipe */
static int run_zenity(const char **args, int fd_pipe[2]) {
int status;
pid_t pid1;
if (messageboxdata->numbuttons > MAX_BUTTONS) {
return SDL_SetError("Too many buttons (%d max allowed)", MAX_BUTTONS);
}
if (pipe(fd_pipe) != 0) { /* create a pipe */
return SDL_SetError("pipe() failed: %s", strerror(errno));
}
pid1 = fork();
if (pid1 == 0) { /* child process */
int argc = 5, i;
const char *argv[5 + 2 /* icon name */ + 2 /* title */ + 2 /* message */ + 2 * MAX_BUTTONS + 1 /* NULL */] = {
"zenity", "--question", "--switch", "--no-wrap", "--no-markup"
};
close(fd_pipe[0]); /* no reading from pipe */
/* write stdout in pipe */
if (dup2(fd_pipe[1], STDOUT_FILENO) == -1) {
_exit(128);
}
argv[argc++] = "--icon-name";
switch (messageboxdata->flags) {
case SDL_MESSAGEBOX_ERROR:
argv[argc++] = "dialog-error";
break;
case SDL_MESSAGEBOX_WARNING:
argv[argc++] = "dialog-warning";
break;
case SDL_MESSAGEBOX_INFORMATION:
default:
argv[argc++] = "dialog-information";
break;
}
if (messageboxdata->title && messageboxdata->title[0]) {
argv[argc++] = "--title";
argv[argc++] = messageboxdata->title;
} else {
argv[argc++] = "--title=\"\"";
}
if (messageboxdata->message && messageboxdata->message[0]) {
argv[argc++] = "--text";
argv[argc++] = messageboxdata->message;
} else {
argv[argc++] = "--text=\"\"";
}
for (i = 0; i < messageboxdata->numbuttons; ++i) {
if (messageboxdata->buttons[i].text && messageboxdata->buttons[i].text[0]) {
argv[argc++] = "--extra-button";
argv[argc++] = messageboxdata->buttons[i].text;
} else {
argv[argc++] = "--extra-button=\"\"";
}
}
argv[argc] = NULL;
/* const casting argv is fine:
* https://pubs.opengroup.org/onlinepubs/9699919799/functions/fexecve.html -> rational
*/
execvp("zenity", (char **)argv);
execvp("zenity", (char **)args);
_exit(129);
} else if (pid1 < 0) {
close(fd_pipe[0]);
close(fd_pipe[1]);
} else if (pid1 < 0) { /* fork() failed */
return SDL_SetError("fork() failed: %s", strerror(errno));
} else {
int status;
if (waitpid(pid1, &status, 0) == pid1) {
if (WIFEXITED(status)) {
if (WEXITSTATUS(status) < 128) {
int i;
size_t output_len = 1;
char *output = NULL;
char *tmp = NULL;
FILE *outputfp = NULL;
close(fd_pipe[1]); /* no writing to pipe */
/* At this point, if no button ID is needed, we can just bail as soon as the
* process has completed.
*/
if (buttonid == NULL) {
close(fd_pipe[0]);
return 0;
}
*buttonid = -1;
/* find button with longest text */
for (i = 0; i < messageboxdata->numbuttons; ++i) {
if (messageboxdata->buttons[i].text != NULL) {
const size_t button_len = SDL_strlen(messageboxdata->buttons[i].text);
if (button_len > output_len) {
output_len = button_len;
}
}
}
output = SDL_malloc(output_len + 1);
if (output == NULL) {
close(fd_pipe[0]);
return SDL_OutOfMemory();
}
output[0] = '\0';
outputfp = fdopen(fd_pipe[0], "r");
if (outputfp == NULL) {
SDL_free(output);
close(fd_pipe[0]);
return SDL_SetError("Couldn't open pipe for reading: %s", strerror(errno));
}
tmp = fgets(output, output_len + 1, outputfp);
(void)fclose(outputfp);
if ((tmp == NULL) || (*tmp == '\0') || (*tmp == '\n')) {
SDL_free(output);
return 0; /* User simply closed the dialog */
}
/* It likes to add a newline... */
tmp = SDL_strrchr(output, '\n');
if (tmp != NULL) {
*tmp = '\0';
}
/* Check which button got pressed */
for (i = 0; i < messageboxdata->numbuttons; i += 1) {
if (messageboxdata->buttons[i].text != NULL) {
if (SDL_strcmp(output, messageboxdata->buttons[i].text) == 0) {
*buttonid = messageboxdata->buttons[i].buttonid;
break;
}
}
}
SDL_free(output);
return 0; /* success! */
} else {
return SDL_SetError("zenity reported error or failed to launch: %d", WEXITSTATUS(status));
}
} else {
return SDL_SetError("zenity failed for some reason");
}
} else {
} else { /* parent process */
close(fd_pipe[1]); /* no writing to the pipe */
if (waitpid(pid1, &status, 0) != pid1) {
return SDL_SetError("Waiting on zenity failed: %s", strerror(errno));
}
if (!WIFEXITED(status)) {
return SDL_SetError("zenity failed for some reason");
}
if (WEXITSTATUS(status) >= 128) {
return SDL_SetError("zenity reported error or failed to launch: %d", WEXITSTATUS(status));
}
return 0; /* success! */
}
}
static int get_zenity_version(int *major, int *minor) {
int fd_pipe[2]; /* fd_pipe[0]: read end of pipe, fd_pipe[1]: write end of pipe */
const char *argv[] = { "zenity", "--version", NULL };
if (pipe(fd_pipe) != 0) { /* create a pipe */
return SDL_SetError("pipe() failed: %s", strerror(errno));
}
if (run_zenity(argv, fd_pipe) == 0) {
FILE *outputfp = NULL;
char version_str[ZENITY_VERSION_LEN];
char *version_ptr = NULL, *end_ptr = NULL;
int tmp;
outputfp = fdopen(fd_pipe[0], "r");
if (outputfp == NULL) {
close(fd_pipe[0]);
return SDL_SetError("failed to open pipe for reading: %s", strerror(errno));
}
version_ptr = fgets(version_str, ZENITY_VERSION_LEN, outputfp);
(void)fclose(outputfp); /* will close underlying fd */
/* we expect the version string is in the form of MAJOR.MINOR.MICRO
* as described in meson.build. We'll ignore everything after that.
*/
tmp = (int) SDL_strtol(version_ptr, &end_ptr, 10);
if (tmp == 0 && end_ptr == version_ptr) {
return SDL_SetError("failed to get zenity major version number");
}
*major = tmp;
version_ptr = end_ptr + 1; /* skip the dot */
tmp = (int) SDL_strtol(version_ptr, &end_ptr, 10);
if (tmp == 0 && end_ptr == version_ptr) {
return SDL_SetError("failed to get zenity minor version number");
}
*minor = tmp;
return 0; /* success */
}
close(fd_pipe[0]);
close(fd_pipe[1]);
return -1; /* run_zenity should've called SDL_SetError() */
}
int Wayland_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) {
int fd_pipe[2]; /* fd_pipe[0]: read end of pipe, fd_pipe[1]: write end of pipe */
int zenity_major = 0, zenity_minor = 0, output_len = 0;
int argc = 5, i;
const char *argv[5 + 2 /* icon name */ + 2 /* title */ + 2 /* message */ + 2 * MAX_BUTTONS + 1 /* NULL */] = {
"zenity", "--question", "--switch", "--no-wrap", "--no-markup"
};
if (messageboxdata->numbuttons > MAX_BUTTONS) {
return SDL_SetError("Too many buttons (%d max allowed)", MAX_BUTTONS);
}
/* get zenity version so we know which arg to use */
if (get_zenity_version(&zenity_major, &zenity_minor) != 0) {
return -1; /* get_zenity_version() calls SDL_SetError(), so message is already set */
}
if (pipe(fd_pipe) != 0) { /* create a pipe */
return SDL_SetError("pipe() failed: %s", strerror(errno));
}
/* https://gitlab.gnome.org/GNOME/zenity/-/commit/c686bdb1b45e95acf010efd9ca0c75527fbb4dea
* This commit removed --icon-name without adding a deprecation notice.
* We need to handle it gracefully, otherwise no message box will be shown.
*/
argv[argc++] = zenity_major > 3 || (zenity_major == 3 && zenity_minor >= 90) ? "--icon" : "--icon-name";
switch (messageboxdata->flags) {
case SDL_MESSAGEBOX_ERROR:
argv[argc++] = "dialog-error";
break;
case SDL_MESSAGEBOX_WARNING:
argv[argc++] = "dialog-warning";
break;
case SDL_MESSAGEBOX_INFORMATION:
default:
argv[argc++] = "dialog-information";
break;
}
if (messageboxdata->title && messageboxdata->title[0]) {
argv[argc++] = "--title";
argv[argc++] = messageboxdata->title;
} else {
argv[argc++] = "--title=\"\"";
}
if (messageboxdata->message && messageboxdata->message[0]) {
argv[argc++] = "--text";
argv[argc++] = messageboxdata->message;
} else {
argv[argc++] = "--text=\"\"";
}
for (i = 0; i < messageboxdata->numbuttons; ++i) {
if (messageboxdata->buttons[i].text && messageboxdata->buttons[i].text[0]) {
int len = SDL_strlen(messageboxdata->buttons[i].text);
if (len > output_len) {
output_len = len;
}
argv[argc++] = "--extra-button";
argv[argc++] = messageboxdata->buttons[i].text;
} else {
argv[argc++] = "--extra-button=\"\"";
}
}
argv[argc] = NULL;
if (run_zenity(argv, fd_pipe) == 0) {
FILE *outputfp = NULL;
char *output = NULL;
char *tmp = NULL;
if (buttonid == NULL) {
/* if we don't need buttonid, we can return immediately */
close(fd_pipe[0]);
return 0; /* success */
}
*buttonid = -1;
output = SDL_malloc(output_len + 1);
if (output == NULL) {
close(fd_pipe[0]);
return SDL_OutOfMemory();
}
output[0] = '\0';
outputfp = fdopen(fd_pipe[0], "r");
if (outputfp == NULL) {
SDL_free(output);
close(fd_pipe[0]);
return SDL_SetError("Couldn't open pipe for reading: %s", strerror(errno));
}
tmp = fgets(output, output_len + 1, outputfp);
(void)fclose(outputfp);
if ((tmp == NULL) || (*tmp == '\0') || (*tmp == '\n')) {
SDL_free(output);
return 0; /* User simply closed the dialog */
}
/* It likes to add a newline... */
tmp = SDL_strrchr(output, '\n');
if (tmp != NULL) {
*tmp = '\0';
}
/* Check which button got pressed */
for (i = 0; i < messageboxdata->numbuttons; i += 1) {
if (messageboxdata->buttons[i].text != NULL) {
if (SDL_strcmp(output, messageboxdata->buttons[i].text) == 0) {
*buttonid = messageboxdata->buttons[i].buttonid;
break;
}
}
}
SDL_free(output);
return 0; /* success! */
}
close(fd_pipe[0]);
close(fd_pipe[1]);
return -1; /* run_zenity() calls SDL_SetError(), so message is already set */
}
#endif /* SDL_VIDEO_DRIVER_WAYLAND */
/* vi: set ts=4 sw=4 expandtab: */
+3
View File
@@ -217,6 +217,7 @@ SDL_WAYLAND_SYM(bool, libdecor_configuration_get_window_state, (struct libdecor_
enum libdecor_window_state *))
SDL_WAYLAND_SYM(int, libdecor_dispatch, (struct libdecor *, int))
#if defined(SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_LIBDECOR) || defined(SDL_HAVE_LIBDECOR_GET_MIN_MAX)
/* Only found in libdecor 0.1.1 or higher, so failure to load them is not fatal. */
SDL_WAYLAND_SYM_OPT(void, libdecor_frame_get_min_content_size, (struct libdecor_frame *,\
int *,\
@@ -226,6 +227,8 @@ SDL_WAYLAND_SYM_OPT(void, libdecor_frame_get_max_content_size, (struct libdecor_
int *))
#endif
#endif
#undef SDL_WAYLAND_MODULE
#undef SDL_WAYLAND_SYM
#undef SDL_WAYLAND_SYM_OPT
+25 -34
View File
@@ -59,12 +59,13 @@ SDL_FORCE_INLINE SDL_bool FloatEqual(float a, float b)
static void GetFullScreenDimensions(SDL_Window *window, int *width, int *height, int *drawable_width, int *drawable_height)
{
SDL_WindowData *wind = (SDL_WindowData *)window->driverdata;
SDL_WaylandOutputData *output = (SDL_WaylandOutputData *)SDL_GetDisplayForWindow(window)->driverdata;
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
SDL_WaylandOutputData *output = display ? (SDL_WaylandOutputData *)display->driverdata : NULL;
int fs_width, fs_height;
int buf_width, buf_height;
const int output_width = wind->fs_output_width ? wind->fs_output_width : output->width;
const int output_height = wind->fs_output_height ? wind->fs_output_height : output->height;
const int output_width = wind->fs_output_width ? wind->fs_output_width : (output ? output->width : wind->window_width);
const int output_height = wind->fs_output_height ? wind->fs_output_height : (output ? output->height : wind->window_height);
/*
* Fullscreen desktop mandates a desktop sized window, so that's what applications will get.
@@ -133,7 +134,10 @@ static SDL_bool NeedViewport(SDL_Window *window)
{
SDL_WindowData *wind = window->driverdata;
SDL_VideoData *video = wind->waylandData;
SDL_WaylandOutputData *output = ((SDL_WaylandOutputData *)SDL_GetDisplayForWindow(window)->driverdata);
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
SDL_WaylandOutputData *output = display ? ((SDL_WaylandOutputData *)display->driverdata) : NULL;
const int output_width = wind->fs_output_width ? wind->fs_output_width : (output ? output->width : wind->window_width);
const int output_height = wind->fs_output_height ? wind->fs_output_height : (output ? output->height : wind->window_height);
int fs_width, fs_height;
/*
@@ -144,7 +148,7 @@ static SDL_bool NeedViewport(SDL_Window *window)
if (video->viewporter != NULL) {
if (FullscreenModeEmulation(window)) {
GetFullScreenDimensions(window, &fs_width, &fs_height, NULL, NULL);
if (fs_width != output->width || fs_height != output->height) {
if (fs_width != output_width || fs_height != output_height) {
return SDL_TRUE;
}
} else if (SurfaceScaleIsFractional(window) && (window->flags & SDL_WINDOW_ALLOW_HIGHDPI)) {
@@ -217,7 +221,8 @@ static void ConfigureWindowGeometry(SDL_Window *window)
{
SDL_WindowData *data = window->driverdata;
SDL_VideoData *viddata = data->waylandData;
SDL_WaylandOutputData *output = (SDL_WaylandOutputData *)SDL_GetDisplayForWindow(window)->driverdata;
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
SDL_WaylandOutputData *output = display ? (SDL_WaylandOutputData *)display->driverdata : NULL;
struct wl_region *region;
const int old_dw = data->drawable_width;
const int old_dh = data->drawable_height;
@@ -237,8 +242,8 @@ static void ConfigureWindowGeometry(SDL_Window *window)
if (FullscreenModeEmulation(window) && NeedViewport(window)) {
int fs_width, fs_height;
const int output_width = data->fs_output_width ? data->fs_output_width : output->width;
const int output_height = data->fs_output_height ? data->fs_output_height : output->height;
const int output_width = data->fs_output_width ? data->fs_output_width : (output ? output->width : data->window_width);
const int output_height = data->fs_output_height ? data->fs_output_height : (output ? output->height : data->window_height);
window_size_changed = data->window_width != output_width || data->window_height != output_height;
@@ -559,7 +564,6 @@ static void handle_configure_xdg_toplevel(void *data,
{
SDL_WindowData *wind = (SDL_WindowData *)data;
SDL_Window *window = wind->sdlwindow;
SDL_WaylandOutputData *driverdata;
enum xdg_toplevel_state *state;
SDL_bool fullscreen = SDL_FALSE;
@@ -586,8 +590,6 @@ static void handle_configure_xdg_toplevel(void *data,
}
}
driverdata = (SDL_WaylandOutputData *)SDL_GetDisplayForWindow(window)->driverdata;
UpdateWindowFullscreen(window, fullscreen);
if (!fullscreen) {
@@ -664,12 +666,6 @@ static void handle_configure_xdg_toplevel(void *data,
window->h = height;
wind->needs_resize_event = SDL_TRUE;
}
/* This part is good though. */
if ((window->flags & SDL_WINDOW_ALLOW_HIGHDPI) && !FloatEqual(wind->scale_factor, driverdata->scale_factor)) {
wind->scale_factor = driverdata->scale_factor;
wind->needs_resize_event = SDL_TRUE;
}
}
}
@@ -819,12 +815,10 @@ static void decoration_frame_configure(struct libdecor_frame *frame,
{
SDL_WindowData *wind = (SDL_WindowData *)user_data;
SDL_Window *window = wind->sdlwindow;
SDL_WaylandOutputData *driverdata;
struct libdecor_state *state;
enum libdecor_window_state window_state;
int width, height;
float scale_factor = wind->scale_factor;
SDL_bool focused = SDL_FALSE;
SDL_bool fullscreen = SDL_FALSE;
@@ -844,8 +838,6 @@ static void decoration_frame_configure(struct libdecor_frame *frame,
}
floating = !(fullscreen || maximized || tiled);
driverdata = (SDL_WaylandOutputData *)SDL_GetDisplayForWindow(window)->driverdata;
UpdateWindowFullscreen(window, fullscreen);
if (!fullscreen) {
@@ -887,11 +879,6 @@ static void decoration_frame_configure(struct libdecor_frame *frame,
if (FullscreenModeEmulation(window)) {
GetFullScreenDimensions(window, &width, &height, NULL, NULL);
}
/* This part is good though. */
if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
scale_factor = driverdata->scale_factor;
}
} else if (!(window->flags & SDL_WINDOW_RESIZABLE) || (floating && wind->floating_resize_pending)) {
width = window->windowed.w;
height = window->windowed.h;
@@ -936,7 +923,7 @@ static void decoration_frame_configure(struct libdecor_frame *frame,
wind->was_floating = floating;
/* Do the resize on the SDL side (this will set window->w/h)... */
Wayland_HandleResize(window, width, height, scale_factor);
Wayland_HandleResize(window, width, height, wind->scale_factor);
/* ... then commit the changes on the libdecor side. */
state = libdecor_state_new(wind->window_width, wind->window_height);
@@ -1003,7 +990,7 @@ static const struct qt_extended_surface_listener extended_surface_listener = {
static void update_scale_factor(SDL_WindowData *window)
{
float old_factor = window->scale_factor;
const float old_factor = window->scale_factor;
float new_factor;
int i;
@@ -1012,14 +999,18 @@ static void update_scale_factor(SDL_WindowData *window)
return;
}
if (FULLSCREEN_VISIBLE(window->sdlwindow)) {
if (window->num_outputs == 0) {
/* No display connected, just fall back. */
new_factor = old_factor;
} else if (FULLSCREEN_VISIBLE(window->sdlwindow)) {
/* For fullscreen, use the active display's scale factor */
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window->sdlwindow);
SDL_WaylandOutputData *driverdata = display->driverdata;
new_factor = driverdata->scale_factor;
} else if (window->num_outputs == 0) {
/* No monitor (somehow)? Just fall back. */
new_factor = old_factor;
if (display) {
SDL_WaylandOutputData *driverdata = display->driverdata;
new_factor = driverdata->scale_factor;
} else {
new_factor = old_factor;
}
} else {
/* Check every display's factor, use the highest */
new_factor = 0.0f;
+23 -14
View File
@@ -24,6 +24,7 @@
#include "SDL_windowsvideo.h"
#include "SDL_windowswindow.h"
#include "SDL_timer.h"
#include "../../events/SDL_clipboardevents_c.h"
#ifdef UNICODE
@@ -102,23 +103,31 @@ int WIN_SetClipboardText(_THIS, const char *text)
char *WIN_GetClipboardText(_THIS)
{
char *text;
char *text = NULL;
text = NULL;
if (IsClipboardFormatAvailable(TEXT_FORMAT) &&
OpenClipboard(GetWindowHandle(_this))) {
HANDLE hMem;
LPTSTR tstr;
if (IsClipboardFormatAvailable(TEXT_FORMAT)) {
/* Retry to open the clipboard in case another application has it open */
const int MAX_ATTEMPTS = 3;
int attempt;
hMem = GetClipboardData(TEXT_FORMAT);
if (hMem) {
tstr = (LPTSTR)GlobalLock(hMem);
text = WIN_StringToUTF8(tstr);
GlobalUnlock(hMem);
} else {
WIN_SetError("Couldn't get clipboard data");
for (attempt = 0; attempt < MAX_ATTEMPTS; ++attempt) {
if (OpenClipboard(GetWindowHandle(_this))) {
HANDLE hMem;
LPTSTR tstr;
hMem = GetClipboardData(TEXT_FORMAT);
if (hMem) {
tstr = (LPTSTR)GlobalLock(hMem);
text = WIN_StringToUTF8(tstr);
GlobalUnlock(hMem);
} else {
WIN_SetError("Couldn't get clipboard data");
}
CloseClipboard();
break;
}
SDL_Delay(10);
}
CloseClipboard();
}
if (text == NULL) {
text = SDL_strdup("");
+4 -1
View File
@@ -318,10 +318,13 @@ static void WIN_AddDisplay(_THIS, HMONITOR hMonitor, const MONITORINFOEXW *info,
if (SDL_wcscmp(driverdata->DeviceName, info->szDevice) == 0) {
SDL_bool moved = (index != i);
if (index >= _this->num_displays) {
return;
}
if (moved) {
SDL_VideoDisplay tmp;
SDL_assert(index < _this->num_displays);
SDL_memcpy(&tmp, &_this->displays[index], sizeof(tmp));
SDL_memcpy(&_this->displays[index], &_this->displays[i], sizeof(tmp));
SDL_memcpy(&_this->displays[i], &tmp, sizeof(tmp));
+1
View File
@@ -288,6 +288,7 @@ static void WIN_WarpMouse(SDL_Window *window, int x, int y)
return;
}
WIN_ClientPointFromSDL(window, &x, &y);
pt.x = x;
pt.y = y;
ClientToScreen(hwnd, &pt);
+1 -4
View File
@@ -132,10 +132,7 @@ static int SetSelectionText(_THIS, const char *text, Atom selection_type)
X11_GetSDLCutBufferClipboardInternalFormat(display, SDL_X11_CLIPBOARD_MIME_TYPE_STRING), 8, PropModeReplace,
(const unsigned char *)text, SDL_strlen(text));
if (X11_XGetSelectionOwner(display, selection_type) != window) {
X11_XSetSelectionOwner(display, selection_type, window, CurrentTime);
}
X11_XSetSelectionOwner(display, selection_type, window, CurrentTime);
return 0;
}
+3 -2
View File
@@ -643,8 +643,9 @@ int X11_InitModes(_THIS)
int xrandr_major, xrandr_minor;
/* require at least XRandR v1.3 */
if (CheckXRandR(data->display, &xrandr_major, &xrandr_minor) &&
(xrandr_major >= 2 || (xrandr_major == 1 && xrandr_minor >= 3))) {
return X11_InitModes_XRandR(_this);
(xrandr_major >= 2 || (xrandr_major == 1 && xrandr_minor >= 3)) &&
X11_InitModes_XRandR(_this) == 0) {
return 0;
}
}
#endif /* SDL_VIDEO_DRIVER_X11_XRANDR */
+1 -28
View File
@@ -1180,33 +1180,6 @@ void X11_ShowWindow(_THIS, SDL_Window *window)
if (data->border_left == 0 && data->border_right == 0 && data->border_top == 0 && data->border_bottom == 0) {
X11_GetBorderValues(data);
}
/* Check if the window manager moved us somewhere unexpected, just in case. */
{
int (*prev_handler)(Display *, XErrorEvent *) = NULL;
Window childReturn, root, parent;
Window *children;
unsigned int childCount;
XWindowAttributes attrs;
int x, y;
X11_XSync(display, False);
prev_handler = X11_XSetErrorHandler(X11_CatchAnyError);
caught_x11_error = SDL_FALSE;
X11_XQueryTree(display, data->xwindow, &root, &parent, &children, &childCount);
X11_XGetWindowAttributes(display, data->xwindow, &attrs);
X11_XTranslateCoordinates(display, parent, DefaultRootWindow(display),
attrs.x, attrs.y, &x, &y, &childReturn);
if (!caught_x11_error) {
/* if these values haven't changed from our current beliefs, these don't actually generate events. */
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, x, y);
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, attrs.width, attrs.height);
}
X11_XSetErrorHandler(prev_handler);
caught_x11_error = SDL_FALSE;
}
}
void X11_HideWindow(_THIS, SDL_Window *window)
@@ -1328,7 +1301,7 @@ static void SetWindowMaximized(_THIS, SDL_Window *window, SDL_bool maximized)
X11_XSync(display, False);
prev_handler = X11_XSetErrorHandler(X11_CatchAnyError);
timeout = SDL_GetTicks64() + 1000;
timeout = SDL_GetTicks64() + 100;
while (SDL_TRUE) {
caught_x11_error = SDL_FALSE;
X11_XSync(display, False);
+10 -1
View File
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.0)
cmake_minimum_required(VERSION 3.0...3.5)
project(SDL2_test)
include(CheckCCompilerFlag)
@@ -160,12 +160,17 @@ elseif(WINDOWS)
elseif(HAVE_X11)
add_sdl_test_executable(testnative NEEDS_RESOURCES testnative.c testnativex11.c testutils.c)
target_link_libraries(testnative X11)
elseif(OS2)
add_sdl_test_executable(testnative NEEDS_RESOURCES testnative.c testnativeos2.c testutils.c)
endif()
add_sdl_test_executable(testoverlay2 NEEDS_RESOURCES testoverlay2.c testyuv_cvt.c testutils.c)
add_sdl_test_executable(testplatform NONINTERACTIVE testplatform.c)
add_sdl_test_executable(testpower NONINTERACTIVE testpower.c)
add_sdl_test_executable(testfilesystem NONINTERACTIVE testfilesystem.c)
if(WIN32 AND CMAKE_SIZEOF_VOID_P EQUAL 4)
add_sdl_test_executable(testfilesystem_pre NONINTERACTIVE testfilesystem_pre.c)
endif()
add_sdl_test_executable(testrendertarget NEEDS_RESOURCES testrendertarget.c testutils.c)
add_sdl_test_executable(testscale NEEDS_RESOURCES testscale.c testutils.c)
add_sdl_test_executable(testsem testsem.c)
@@ -424,6 +429,10 @@ endforeach()
set_tests_properties(testthread PROPERTIES TIMEOUT 40)
set_tests_properties(testtimer PROPERTIES TIMEOUT 60)
if(TARGET testfilesystem_pre)
set_property(TEST testfilesystem_pre PROPERTY TIMEOUT 60)
set_property(TEST testfilesystem APPEND PROPERTY DEPENDS testfilesystem_pre)
endif()
if(SDL_INSTALL_TESTS)
if(RISCOS)
Loaded 100 of 105 files, more files were not shown because too many files have changed in this diff. Show more