Compare commits

..

57 Commits

Author SHA1 Message Date
Sam Lantinga
981e1e3c44 Fixed logical size synchronization issue on macOS
https://discourse.libsdl.org/t/sdl-2-0-22-prerelease/35306/6
2022-04-23 10:35:05 -07:00
Ozkan Sezer
7a5743031d hidapi, libusb: import mainstream commit 536bad201e 2022-04-23 20:01:40 +03:00
Sam Lantinga
fa073ed01a Revert "Fix relative mouse input for Unvanquished (unvanquished.net)"
This reverts commit 3318590796.

Fixes https://github.com/libsdl-org/SDL/issues/5569
2022-04-22 22:31:04 -07:00
Sam Lantinga
8986efd643 Added support for the Backbone One controller on iOS 2022-04-22 14:21:46 -07:00
Sam Lantinga
2ca0837888 SDL: sometimes the PS5 controller doesn't report having to power even when connected over USB. Possibly related to being completely charged? Either way we already know that it's USB or BT so let's use the driver's knowledge instead. 2022-04-22 14:21:41 -07:00
Sam Lantinga
04bf7c9434 Fixed build 2022-04-22 09:36:39 -07:00
Sam Lantinga
d9b5805ba5 Return a correlation error when trigger rumble is attempted without correlation 2022-04-22 09:13:40 -07:00
Eddy Jansson
0288de8529 SDL_Rect: Add \sa documentation block to SDL_FRect 2022-04-22 12:09:13 -04:00
Sam Lantinga
ba62ead5ec Handle potential out of memory condition when working with hints 2022-04-21 08:47:41 -07:00
Cameron Gutman
145824f6ab WGI: Only call RoUninitialize() if RoInitialize() succeeded 2022-04-21 08:47:22 -07:00
Cameron Gutman
00b2e10a7a WGI: Keep a reference to the MTA to avoid crashing on COM teardown
Fixes #5552
Fixes #5270
2022-04-21 08:47:22 -07:00
Cameron Gutman
8982d9f403 windows: Fix RoInitialize() failure after a CoInitializeEx() call using apartment threading
This mirrors the same codepath in WIN_CoInitialize() which handles STA and MTA.
2022-04-21 08:47:22 -07:00
Cameron Gutman
923cb4463e windows: Fix calling convention for RoInitialize/RoUninitialize
Fixes #5563
2022-04-20 21:02:40 -05:00
Ryan C. Gordon
d4a01bfef0 os2: SDL_DestroyMutex should ignore NULL mutexes.
Every other backend does this, so this should match, now.
It's possible this was harmless, but we can avoid the system call
and the (likely?) debug message when it fails, though!
2022-04-20 14:08:09 -04:00
Eddy Jansson
a40405d724 hidapi: Wrap CopyHIDDeviceInfo in define checks.
The purpose of this is to silence a 'defined but not used'
warning.
2022-04-20 09:33:40 -07:00
Eddy Jansson
5bc2933425 test: Basic tests for SDL_FRectEquals
Based on the integer version. These tests mostly check that input
isn't mangled and that invalid input gives the expected negative
result.
2022-04-20 08:38:53 -07:00
Eddy Jansson
fc944859d1 SDL_Rect: Use a default epsilon in SDL_FRectEquals()
Add SDL_FRectEqualsEpsilon() for when more control over
equality test is required.
2022-04-20 08:38:53 -07:00
Eddy Jansson
00feca27b0 Add SDL_FLT_EPSILON. 2022-04-20 08:38:53 -07:00
Eddy Jansson
5d4a1f8356 WhatsNew.txt: Add SDL_FRectEqualsEpsilon() 2022-04-20 08:38:53 -07:00
Frank Praznik
aeadbdd788 Remove an unused function prototype 2022-04-20 09:39:34 -04:00
Frank Praznik
c8c59a2139 Fix a -Wshadow warning 2022-04-20 09:39:34 -04:00
Jaylon Gowie
d9009388c8 SceKernelMemBlockType to unsigned int 2022-04-19 14:17:27 -07:00
Jaylon Gowie
3753a7b1c3 Fix recent changes in VitaSDK 2022-04-19 14:17:27 -07:00
Sam Lantinga
02225aa738 Fixed build 2022-04-18 22:57:03 -07:00
Ryan C. Gordon
49a2e4b0ea x11: Revert "Fix keymap updating for X11 backend"
This reverts commit de6d290266.

This patch had multiple issues, discussed in #5520.
2022-04-19 00:37:39 -04:00
Sam Lantinga
b9fe6ba0e7 Fixed compile warnings 2022-04-18 13:09:08 -07:00
Sam Lantinga
57927a2458 Don't call scandir() inside of scandir()
This works around a crash in address sanitizer
2022-04-18 12:57:28 -07:00
Sylvain
1ede941f5c SDL_render.c: internally change viewport/cliprect type from SDL_FRect to SDL_DRect (double precision). (see bug #5547) 2022-04-18 12:26:32 -07:00
Sam Lantinga
9919d1a7a5 Remove HWND_TOPMOST for fullscreen windows
Fixes https://github.com/libsdl-org/SDL/issues/5509
2022-04-18 11:51:54 -07:00
pionere
009a0ff95f use explicit GetModuleFileNameW 2022-04-18 14:12:22 -04:00
pionere
de711e1685 simplify SDL_GetBasePath on windows
- use GetModuleFileName directly (as recommended)
2022-04-18 14:12:22 -04:00
Jan Beich
7c140429a8 Enable evdev-based gamecontrollerdb on FreeBSD 2022-04-18 09:57:49 -07:00
Sam Lantinga
e7b01ee745 Added controller mapping for the Thrustmaster Dual Analog 3.2 on Linux 2022-04-18 09:55:52 -07:00
Frank Praznik
2b52946143 video: Don't minimize fullscreen windows on focus loss by default when mode switching is disabled
When mode switching is disabled in a video backend, fullscreen windows are basically just fullscreen desktop windows with different internal scaling.  As no mode switching occurs, there's no need to minimize them on focus loss by default.  This can still be overridden by explicitly setting the internal hint for minimizing on focus loss.

This has the side effect of fixing a bug on GNOME, where, when a fullscreen Wayland window has it's focus lost and restored via alt+tab followed by switching back to windowed mode, the top portion of the window won't end up being obstructed by GNOME's top bar.
2022-04-18 09:39:25 -07:00
Ethan Lee
c37090f9a4 wayland: Add support for TOOLTIP/POPUP_MENU 2022-04-18 12:31:02 -04:00
Sam Lantinga
9e264b921b Certain audio drivers, like the RME "Pro" Audio driver, have resampling quality issues when using WASAPI.
We'll use SDL's resampling algorithm so we have consistent quality between platforms and drivers.

Fixes https://github.com/libsdl-org/SDL/issues/5538
2022-04-18 09:20:47 -07:00
Sam Lantinga
254fcc90eb Revert "video: Prefer Wayland over X11"
This reverts commit 8ceba27d62.

SDL Wayland support is stable, but there are a number of issues with third-party software (NVIDIA drivers, libwayland event overflow, libdecor not handling plugin load failures, Steam overlay not working with Wayland, etc.) that make it better to default to X11 at this time.

Games which would like to prefer wayland when available can use the following code before SDL_Init():
	SDL_SetHint(SDL_HINT_VIDEODRIVER, "wayland,x11");

Fixes https://github.com/libsdl-org/SDL/issues/5527
2022-04-18 09:03:14 -07:00
Ryan C. Gordon
c1336b21ed hints: Make SDL_VIDEODRIVER and SDL_AUDIODRIVER formal hints.
They were just environment variables before.

Fixes #5528.
2022-04-17 11:31:55 -07:00
Ryan C. Gordon
634b9edc7f cmake: Fixed indenting and some oldschool endif(TEXT) things. 2022-04-15 20:50:55 -04:00
Semphris
dc5bc5237c Added CMake option to disable the installer 2022-04-15 20:48:40 -04:00
Ryan C. Gordon
67e0f546c5 x11: Update the display when the WM changes a window's fullscreen state.
Fixes #5390.
2022-04-15 18:25:53 -04:00
Frank Praznik
edb473cf46 video: Wayland: Always round scaled pointer coordinates down
Rounding up can cause the pointer coordinates to exceed the window boundaries at the right and bottom edges.
2022-04-15 16:24:20 -04:00
Frank Praznik
13393a1c4b video: Wayland: Clamp fullscreen window dimensions to desktop
A scaled fullscreen window may exceed the bounds of the desktop.  Clamp the window size to the desktop dimensions in fullscreen mode.
2022-04-15 16:24:20 -04:00
pionere
0adb67017b avoid NullPointer in SDL_GetRenderTarget 2022-04-15 15:47:35 -04:00
pionere
01b14e14e6 avoid NullPointer in SDL_GL_MakeCurrent 2022-04-15 08:30:33 -04:00
Ozkan Sezer
55a4e1d336 CI: update os2.yml to use open-watcom/setup-watcom
also remove os2-buildbot.sh -- not needed anymore.
2022-04-14 10:10:02 +03:00
Simon McVittie
c36bd78474 WhatsNew.txt: Document new dependency on libwayland-client 1.18.0
Signed-off-by: Simon McVittie <smcv@collabora.com>
2022-04-13 10:14:29 -04:00
Ethan Lee
46616af722 WhatsNew.txt: Added SDL_HINT_VIDEO_WAYLAND_PREFER_LIBDECOR 2022-04-12 11:53:40 -04:00
David Gow
9c2f46b0d5 Wayland: Add SDL_HINT_VIDEO_WAYLAND_PREFER_LIBDECOR
This hint allows libdecor to be used even when xdg-decoration is
available. It's mostly useful for debugging libdecor, but could in
theory be used by applications which want to (for example) bundle their
own libdecor plugins.
2022-04-12 11:52:41 -04:00
Mathieu Eyraud
99ae6395b1 Initialise scandir argument
'scandir' does not initialise 'entries' on error
2022-04-12 11:14:07 -04:00
Simon McVittie
68b6fff245 test: Copy utf8.txt to build directory
testiconv wants this.

Signed-off-by: Simon McVittie <smcv@collabora.com>
2022-04-12 11:01:20 -04:00
Simon McVittie
b4256d03e9 testevdev: Adapt to a broader definition of keyboards
At the time I contributed this unit test, SDL had a relatively narrow
definition of what is a keyboard, approximately matching udev
ID_INPUT_KEYBOARD. Now it uses the equivalent of udev ID_INPUT_KEY,
which matches anything with keyboard keys, and not just reasonably
complete alphanumeric keyboards.

Fixes: 040bd7a9 "Fix udev not detecting ID_INPUT_KEY devices when udev is not running"
Signed-off-by: Simon McVittie <smcv@collabora.com>
2022-04-12 10:59:53 -04:00
Simon McVittie
c2946902fa testevdev: Recognise touchpads as such
At the time I contributed this unit test, SDL didn't understand Linux
touchpads, but now it does.

Fixes: 373216ae "Added support for touchpads in the Linux evdev code"
Signed-off-by: Simon McVittie <smcv@collabora.com>
2022-04-12 10:59:53 -04:00
pionere
f708cebe10 fix os2 timer in fallback mode 2022-04-12 17:01:20 +03:00
Ivan Epifanov
b75996138a Vita: fix VIDEO_VITA_PVR flag 2022-04-11 17:16:22 -04:00
Ethan Lee
b1831715a2 UWP: Require Windows 10 16299 or newer.
This is required to build with WGI support. Thanks for @FrozenChameleon for the fix!

Fixes #5504
2022-04-11 12:09:40 -04:00
Ryan C. Gordon
727eef7064 audio: SDL_ConvertStereoToMono_SSE3 missed an unaligned load. 2022-04-09 10:13:37 -04:00
45 changed files with 867 additions and 360 deletions

View File

@@ -7,20 +7,16 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Cache OpenWatcom
uses: actions/cache@v2
env:
cache-name: cache-openwatcom
with:
path: ~/openwatcom
key: ${{ runner.os }}-build-${{ env.cache-name }}
- name: Download OpenWatcom if not cached
run: if [ ! -d ~/openwatcom/binl64 ]; then wget --no-verbose 'https://github.com/open-watcom/open-watcom-v2/releases/download/Current-build/open-watcom-2_0-c-linux-x64' -O ~/ow.zip && mkdir -p ~/openwatcom && cd ~/openwatcom && unzip ~/ow.zip && chmod -R a+rx ~/openwatcom ; fi
shell: bash
- name: Build
run: WATCOM="$HOME/openwatcom" build-scripts/os2-buildbot.sh
shell: bash
- uses: open-watcom/setup-watcom@v0
- name: Build SDL2
run: |
wmake -f Makefile.os2
- name: Build tests
run: |
cd test && wmake -f Makefile.os2
cd ..
- name: distclean
run: |
wmake -f Makefile.os2 distclean
cd test && wmake -f Makefile.os2 distclean
cd ..

View File

@@ -372,6 +372,7 @@ endforeach()
# Allow some projects to be built conditionally.
set_option(SDL2_DISABLE_SDL2MAIN "Disable building/installation of SDL2main" OFF)
set_option(SDL2_DISABLE_INSTALL "Disable installation of SDL2" OFF)
set_option(SDL2_DISABLE_UNINSTALL "Disable uninstallation of SDL2" OFF)
option_string(SDL_ASSERTIONS "Enable internal sanity checks (auto/disabled/release/enabled/paranoid)" "auto")
@@ -2311,10 +2312,10 @@ elseif(VITA)
list(APPEND EXTRA_LIBS
pib
)
set(HAVE_VITA_PIB ON)
set(HAVE_VIDEO_VITA_PIB ON)
set(SDL_VIDEO_VITA_PIB 1)
else()
set(HAVE_VITA_PIB OFF)
set(HAVE_VIDEO_VITA_PIB OFF)
endif()
endif()
@@ -2335,7 +2336,7 @@ elseif(VITA)
libIMGEGL_stub_weak
)
set(HAVE_VITA_PVR ON)
set(HAVE_VIDEO_VITA_PVR ON)
set(SDL_VIDEO_VITA_PVR 1)
if(HAVE_GL4ES_H)
@@ -2347,7 +2348,7 @@ elseif(VITA)
endif()
else()
set(HAVE_VITA_PVR OFF)
set(HAVE_VIDEO_VITA_PVR OFF)
endif()
endif()
@@ -2968,122 +2969,125 @@ if(SDL_TEST)
endif()
##### Installation targets #####
if(SDL_SHARED)
install(TARGETS SDL2 EXPORT SDL2Targets
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
endif()
if(NOT WINDOWS_STORE AND NOT SDL2_DISABLE_SDL2MAIN)
install(TARGETS SDL2main EXPORT SDL2mainTargets
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
endif()
if(SDL_STATIC)
install(TARGETS SDL2-static EXPORT SDL2staticTargets
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
endif()
##### Export files #####
if (WINDOWS AND NOT MINGW)
set(PKG_PREFIX "cmake")
else ()
set(PKG_PREFIX "${CMAKE_INSTALL_LIBDIR}/cmake/SDL2")
endif ()
include(CMakePackageConfigHelpers)
write_basic_package_version_file("${CMAKE_BINARY_DIR}/SDL2ConfigVersion.cmake"
VERSION ${SDL_VERSION}
COMPATIBILITY AnyNewerVersion
)
if(SDL_SHARED)
install(EXPORT SDL2Targets
FILE SDL2Targets.cmake
NAMESPACE SDL2::
DESTINATION ${PKG_PREFIX}
)
endif()
if(NOT WINDOWS_STORE AND NOT SDL2_DISABLE_SDL2MAIN)
install(EXPORT SDL2mainTargets
FILE SDL2mainTargets.cmake
NAMESPACE SDL2::
DESTINATION ${PKG_PREFIX}
)
endif()
if(SDL_STATIC)
install(EXPORT SDL2staticTargets
FILE SDL2staticTargets.cmake
NAMESPACE SDL2::
DESTINATION ${PKG_PREFIX}
)
endif()
install(
FILES
${CMAKE_CURRENT_SOURCE_DIR}/SDL2Config.cmake
${CMAKE_BINARY_DIR}/SDL2ConfigVersion.cmake
DESTINATION ${PKG_PREFIX}
COMPONENT Devel
)
file(GLOB INCLUDE_FILES ${SDL2_SOURCE_DIR}/include/*.h)
file(GLOB BIN_INCLUDE_FILES ${SDL2_BINARY_DIR}/include/*.h)
foreach(_FNAME ${BIN_INCLUDE_FILES})
get_filename_component(_INCNAME ${_FNAME} NAME)
list(REMOVE_ITEM INCLUDE_FILES ${SDL2_SOURCE_DIR}/include/${_INCNAME})
endforeach()
list(APPEND INCLUDE_FILES ${BIN_INCLUDE_FILES})
install(FILES ${INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/SDL2)
string(TOUPPER "${CMAKE_BUILD_TYPE}" UPPER_BUILD_TYPE)
if (UPPER_BUILD_TYPE MATCHES DEBUG)
set(SOPOSTFIX "${SDL_CMAKE_DEBUG_POSTFIX}")
else()
set(SOPOSTFIX "")
endif()
if(NOT (WINDOWS OR CYGWIN) OR MINGW)
if(NOT SDL2_DISABLE_INSTALL)
if(SDL_SHARED)
set(SOEXT ${CMAKE_SHARED_LIBRARY_SUFFIX}) # ".so", ".dylib", etc.
get_target_property(SONAME SDL2 OUTPUT_NAME)
if(NOT ANDROID AND NOT MINGW AND NOT OS2)
install(CODE "
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink
\"lib${SONAME}${SOPOSTFIX}${SOEXT}\" \"libSDL2${SOPOSTFIX}${SOEXT}\"
WORKING_DIRECTORY \"${SDL2_BINARY_DIR}\")")
install(FILES ${SDL2_BINARY_DIR}/libSDL2${SOPOSTFIX}${SOEXT} DESTINATION "${CMAKE_INSTALL_LIBDIR}")
endif()
install(TARGETS SDL2 EXPORT SDL2Targets
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
endif()
if(FREEBSD)
# FreeBSD uses ${PREFIX}/libdata/pkgconfig
install(FILES ${SDL2_BINARY_DIR}/sdl2.pc DESTINATION "libdata/pkgconfig")
if(NOT WINDOWS_STORE AND NOT SDL2_DISABLE_SDL2MAIN)
install(TARGETS SDL2main EXPORT SDL2mainTargets
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
endif()
if(SDL_STATIC)
install(TARGETS SDL2-static EXPORT SDL2staticTargets
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
endif()
##### Export files #####
if (WINDOWS AND NOT MINGW)
set(PKG_PREFIX "cmake")
else ()
set(PKG_PREFIX "${CMAKE_INSTALL_LIBDIR}/cmake/SDL2")
endif ()
include(CMakePackageConfigHelpers)
write_basic_package_version_file("${CMAKE_BINARY_DIR}/SDL2ConfigVersion.cmake"
VERSION ${SDL_VERSION}
COMPATIBILITY AnyNewerVersion
)
if(SDL_SHARED)
install(EXPORT SDL2Targets
FILE SDL2Targets.cmake
NAMESPACE SDL2::
DESTINATION ${PKG_PREFIX}
)
endif()
if(NOT WINDOWS_STORE AND NOT SDL2_DISABLE_SDL2MAIN)
install(EXPORT SDL2mainTargets
FILE SDL2mainTargets.cmake
NAMESPACE SDL2::
DESTINATION ${PKG_PREFIX}
)
endif()
if(SDL_STATIC)
install(EXPORT SDL2staticTargets
FILE SDL2staticTargets.cmake
NAMESPACE SDL2::
DESTINATION ${PKG_PREFIX}
)
endif()
install(
FILES
${CMAKE_CURRENT_SOURCE_DIR}/SDL2Config.cmake
${CMAKE_BINARY_DIR}/SDL2ConfigVersion.cmake
DESTINATION ${PKG_PREFIX}
COMPONENT Devel
)
file(GLOB INCLUDE_FILES ${SDL2_SOURCE_DIR}/include/*.h)
file(GLOB BIN_INCLUDE_FILES ${SDL2_BINARY_DIR}/include/*.h)
foreach(_FNAME ${BIN_INCLUDE_FILES})
get_filename_component(_INCNAME ${_FNAME} NAME)
list(REMOVE_ITEM INCLUDE_FILES ${SDL2_SOURCE_DIR}/include/${_INCNAME})
endforeach()
list(APPEND INCLUDE_FILES ${BIN_INCLUDE_FILES})
install(FILES ${INCLUDE_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/SDL2)
string(TOUPPER "${CMAKE_BUILD_TYPE}" UPPER_BUILD_TYPE)
if (UPPER_BUILD_TYPE MATCHES DEBUG)
set(SOPOSTFIX "${SDL_CMAKE_DEBUG_POSTFIX}")
else()
install(FILES ${SDL2_BINARY_DIR}/sdl2.pc
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
set(SOPOSTFIX "")
endif()
if(NOT (WINDOWS OR CYGWIN) OR MINGW)
if(SDL_SHARED)
set(SOEXT ${CMAKE_SHARED_LIBRARY_SUFFIX}) # ".so", ".dylib", etc.
get_target_property(SONAME SDL2 OUTPUT_NAME)
if(NOT ANDROID AND NOT MINGW AND NOT OS2)
install(CODE "
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink
\"lib${SONAME}${SOPOSTFIX}${SOEXT}\" \"libSDL2${SOPOSTFIX}${SOEXT}\"
WORKING_DIRECTORY \"${SDL2_BINARY_DIR}\")")
install(FILES ${SDL2_BINARY_DIR}/libSDL2${SOPOSTFIX}${SOEXT} DESTINATION "${CMAKE_INSTALL_LIBDIR}")
endif()
endif()
if(FREEBSD)
# FreeBSD uses ${PREFIX}/libdata/pkgconfig
install(FILES ${SDL2_BINARY_DIR}/sdl2.pc DESTINATION "libdata/pkgconfig")
else()
install(FILES ${SDL2_BINARY_DIR}/sdl2.pc
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
endif()
install(PROGRAMS ${SDL2_BINARY_DIR}/sdl2-config DESTINATION "${CMAKE_INSTALL_BINDIR}")
# TODO: what about the .spec file? Is it only needed for RPM creation?
install(FILES "${SDL2_SOURCE_DIR}/sdl2.m4" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/aclocal")
endif()
install(PROGRAMS ${SDL2_BINARY_DIR}/sdl2-config DESTINATION "${CMAKE_INSTALL_BINDIR}")
# TODO: what about the .spec file? Is it only needed for RPM creation?
install(FILES "${SDL2_SOURCE_DIR}/sdl2.m4" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/aclocal")
endif()
##### Uninstall target #####
if(NOT SDL2_DISABLE_UNINSTALL)
if(NOT TARGET uninstall)
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
IMMEDIATE @ONLY)
if(NOT TARGET uninstall)
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
IMMEDIATE @ONLY)
add_custom_target(uninstall
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
add_custom_target(uninstall
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
endif()
endif()
endif(NOT SDL2_DISABLE_UNINSTALL)

View File

@@ -416,10 +416,10 @@
<AppContainerApplication>true</AppContainerApplication>
<ApplicationType>Windows Store</ApplicationType>
<ApplicationTypeRevision>8.2</ApplicationTypeRevision>
<TargetPlatformVersion>10.0.10069.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.10069.0</TargetPlatformMinVersion>
<WindowsTargetPlatformVersion>10.0.10240.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformMinVersion>10.0.10240.0</WindowsTargetPlatformMinVersion>
<TargetPlatformVersion>10.0.16299.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.16299.0</TargetPlatformMinVersion>
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformMinVersion>10.0.16299.0</WindowsTargetPlatformMinVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

View File

@@ -11,6 +11,7 @@ General:
* SDL_PointInFRect()
* SDL_FRectEmpty()
* SDL_FRectEquals()
* SDL_FRectEqualsEpsilon()
* SDL_HasIntersectionF()
* SDL_IntersectFRect()
* SDL_UnionFRect()
@@ -30,7 +31,9 @@ Windows:
* Added support for SDL_BLENDOPERATION_MINIMUM and SDL_BLENDOPERATION_MAXIMUM to the D3D9 renderer
Linux:
* Compiling with Wayland support requires libwayland-client version 1.18.0 or later
* Added the hint SDL_HINT_X11_WINDOW_TYPE to specify the _NET_WM_WINDOW_TYPE of SDL windows
* Added the hint SDL_HINT_VIDEO_WAYLAND_PREFER_LIBDECOR to allow using libdecor with compositors that support xdg-decoration
Android:
* Added SDL_AndroidSendMessage() to send a custom command to the SDL java activity

View File

@@ -1,41 +0,0 @@
#!/bin/bash
# This is the script buildbot.libsdl.org uses to cross-compile SDL2 from
# x86 Linux to OS/2, using OpenWatcom.
# The final zipfile can be unpacked on any machine that supports OpenWatcom
# (Windows, Linux, OS/2, etc). Point the compiler at the include directory
# and link against the SDL2.lib file. Ship the SDL2.dll with your app.
if [ -z "$WATCOM" ]; then
echo "This script expects \$WATCOM to be set to the OpenWatcom install dir." 1>&2
echo "This is often something like '/usr/local/share/watcom'" 1>&2
exit 1
fi
export PATH="$WATCOM/binl64:$PATH"
ZIPFILE="$1"
if [ -z $1 ]; then
ZIPFILE=sdl-os2.zip
fi
ZIPDIR=buildbot/SDL
set -e
set -x
cd `dirname "$0"`
cd ..
rm -f $ZIPFILE
wmake -f Makefile.os2
rm -rf $ZIPDIR
mkdir -p $ZIPDIR
chmod 644 SDL2.dll SDL2.lib SDL2test.lib
mv SDL2.dll SDL2.lib SDL2test.lib $ZIPDIR/
cp -R include $ZIPDIR/
zip -9r "buildbot/$ZIPFILE" $ZIPDIR
wmake -f Makefile.os2 distclean
set +x
echo "All done. Final installable is in $ZIPFILE ...";

View File

@@ -1475,6 +1475,20 @@ extern "C" {
*/
#define SDL_HINT_VIDEO_WAYLAND_ALLOW_LIBDECOR "SDL_VIDEO_WAYLAND_ALLOW_LIBDECOR"
/**
* \brief A variable controlling whether the libdecor Wayland backend is preferred over native decrations.
*
* When this hint is set, libdecor will be used to provide window decorations, even if xdg-decoration is
* available. (Note that, by default, libdecor will use xdg-decoration itself if available).
*
* This variable can be set to the following values:
* "0" - libdecor is enabled only if server-side decorations are unavailable.
* "1" - libdecor is always enabled if available.
*
* libdecor is used over xdg-shell when xdg-decoration protocol is unavailable.
*/
#define SDL_HINT_VIDEO_WAYLAND_PREFER_LIBDECOR "SDL_VIDEO_WAYLAND_PREFER_LIBDECOR"
/**
* \brief A variable that is the address of another SDL_Window* (as a hex string formatted with "%p").
*
@@ -1979,6 +1993,53 @@ extern "C" {
#define SDL_HINT_QUIT_ON_LAST_WINDOW_CLOSE "SDL_QUIT_ON_LAST_WINDOW_CLOSE"
/**
* \brief A variable that decides what video backend to use.
*
* By default, SDL will try all available video backends in a reasonable
* order until it finds one that can work, but this hint allows the app
* or user to force a specific target, such as "x11" if, say, you are
* on Wayland but want to try talking to the X server instead.
*
* This functionality has existed since SDL 2.0.0 (indeed, before that)
* but before 2.0.22 this was an environment variable only. In 2.0.22,
* it was upgraded to a full SDL hint, so you can set the environment
* variable as usual or programatically set the hint with SDL_SetHint,
* which won't propagate to child processes.
*
* The default value is unset, in which case SDL will try to figure out
* the best video backend on your behalf. This hint needs to be set
* before SDL_Init() is called to be useful.
*
* This hint is available since SDL 2.0.22. Before then, you could set
* the environment variable to get the same effect.
*/
#define SDL_HINT_VIDEODRIVER "SDL_VIDEODRIVER"
/**
* \brief A variable that decides what audio backend to use.
*
* By default, SDL will try all available audio backends in a reasonable
* order until it finds one that can work, but this hint allows the app
* or user to force a specific target, such as "alsa" if, say, you are
* on PulseAudio but want to try talking to the lower level instead.
*
* This functionality has existed since SDL 2.0.0 (indeed, before that)
* but before 2.0.22 this was an environment variable only. In 2.0.22,
* it was upgraded to a full SDL hint, so you can set the environment
* variable as usual or programatically set the hint with SDL_SetHint,
* which won't propagate to child processes.
*
* The default value is unset, in which case SDL will try to figure out
* the best audio backend on your behalf. This hint needs to be set
* before SDL_Init() is called to be useful.
*
* This hint is available since SDL 2.0.22. Before then, you could set
* the environment variable to get the same effect.
*/
#define SDL_HINT_AUDIODRIVER "SDL_AUDIODRIVER"
/**
* \brief An enumeration of hint priorities
*/

View File

@@ -54,11 +54,6 @@ typedef struct SDL_Point
/**
* The structure that defines a point (floating point)
*
* \sa SDL_FRectEmpty
* \sa SDL_FRectEquals
* \sa SDL_HasIntersectionF
* \sa SDL_IntersectFRect
* \sa SDL_UnionFRect
* \sa SDL_EncloseFPoints
* \sa SDL_PointInFRect
*/
@@ -76,6 +71,7 @@ typedef struct SDL_FPoint
* \sa SDL_RectEquals
* \sa SDL_HasIntersection
* \sa SDL_IntersectRect
* \sa SDL_IntersectRectAndLine
* \sa SDL_UnionRect
* \sa SDL_EnclosePoints
*/
@@ -88,6 +84,16 @@ typedef struct SDL_Rect
/**
* A rectangle, with the origin at the upper left (floating point).
*
* \sa SDL_FRectEmpty
* \sa SDL_FRectEquals
* \sa SDL_FRectEqualsEpsilon
* \sa SDL_HasIntersectionF
* \sa SDL_IntersectFRect
* \sa SDL_IntersectFRectAndLine
* \sa SDL_UnionFRect
* \sa SDL_EncloseFPoints
* \sa SDL_PointInFRect
*/
typedef struct SDL_FRect
{
@@ -239,12 +245,28 @@ SDL_FORCE_INLINE SDL_bool SDL_FRectEmpty(const SDL_FRect *r)
}
/**
* Returns true if the two rectangles are equal.
* Returns true if the two rectangles are equal, within some given epsilon.
*
* \since This function is available since SDL 2.0.22.
*/
SDL_FORCE_INLINE SDL_bool SDL_FRectEqualsEpsilon(const SDL_FRect *a, const SDL_FRect *b, const float epsilon)
{
return (a && b && ((a == b) ||
((SDL_fabs(a->x - b->x) <= epsilon) &&
(SDL_fabs(a->y - b->y) <= epsilon) &&
(SDL_fabs(a->w - b->w) <= epsilon) &&
(SDL_fabs(a->h - b->h) <= epsilon))))
? SDL_TRUE : SDL_FALSE;
}
/**
* Returns true if the two rectangles are equal, using a default epsilon.
*
* \since This function is available since SDL 2.0.22.
*/
SDL_FORCE_INLINE SDL_bool SDL_FRectEquals(const SDL_FRect *a, const SDL_FRect *b)
{
return (a && b && (a->x == b->x) && (a->y == b->y) &&
(a->w == b->w) && (a->h == b->h)) ? SDL_TRUE : SDL_FALSE;
return SDL_FRectEqualsEpsilon(a, b, SDL_FLT_EPSILON);
}
/**

View File

@@ -234,6 +234,19 @@ typedef uint64_t Uint64;
/* @} *//* Basic data types */
/**
* \name Floating-point constants
*/
/* @{ */
#ifdef FLT_EPSILON
#define SDL_FLT_EPSILON FLT_EPSILON
#else
#define SDL_FLT_EPSILON 1.1920928955078125e-07F /* 0x0.000002p0 */
#endif
/* @} *//* Floating-point constants */
/* Make sure we have macros for printing width-based integers.
* <stdint.h> should define these but this is not true all platforms.
* (for example win32) */

View File

@@ -298,6 +298,8 @@ struct SDL_SysWMinfo
struct wl_egl_window *egl_window; /**< Wayland EGL window (native window) */
struct xdg_surface *xdg_surface; /**< Wayland xdg surface (window manager handle) */
struct xdg_toplevel *xdg_toplevel; /**< Wayland xdg toplevel role */
struct xdg_popup *xdg_popup; /**< Wayland xdg popup role */
struct xdg_positioner *xdg_positioner; /**< Wayland xdg positioner, for popup */
} wl;
#endif
#if defined(SDL_VIDEO_DRIVER_MIR) /* no longer available, left for API/ABI compatibility. Remove in 2.1! */

View File

@@ -178,6 +178,11 @@ SDL_AddHintCallback(const char *name, SDL_HintCallback callback, void *userdata)
return;
}
hint->name = SDL_strdup(name);
if (!hint->name) {
SDL_free(hint);
SDL_OutOfMemory();
return;
}
hint->value = NULL;
hint->priority = SDL_HINT_DEFAULT;
hint->callbacks = NULL;

View File

@@ -936,7 +936,7 @@ SDL_AudioInit(const char *driver_name)
/* Select the proper audio driver */
if (driver_name == NULL) {
driver_name = SDL_getenv("SDL_AUDIODRIVER");
driver_name = SDL_GetHint(SDL_HINT_AUDIODRIVER);
}
if (driver_name != NULL && *driver_name != 0) {

View File

@@ -80,7 +80,7 @@ SDL_ConvertStereoToMono_SSE3(SDL_AudioCVT * cvt, SDL_AudioFormat format)
Just use unaligned load/stores, if the memory at runtime is
aligned it'll be just as fast on modern processors */
while (i >= 4) { /* 4 * float32 */
_mm_storeu_ps(dst, _mm_mul_ps(_mm_hadd_ps(_mm_load_ps(src), _mm_loadu_ps(src+4)), divby2));
_mm_storeu_ps(dst, _mm_mul_ps(_mm_hadd_ps(_mm_loadu_ps(src), _mm_loadu_ps(src+4)), divby2));
i -= 4; src += 8; dst += 4;
}

View File

@@ -558,12 +558,16 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream)
return WIN_SetErrorFromHRESULT("WASAPI can't determine minimum device period", ret);
}
#if 1 /* we're getting reports that WASAPI's resampler introduces distortions, so it's disabled for now. --ryan. */
this->spec.freq = waveformat->nSamplesPerSec; /* force sampling rate so our resampler kicks in, if necessary. */
#else
/* favor WASAPI's resampler over our own */
if (this->spec.freq != waveformat->nSamplesPerSec) {
streamflags |= (AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM | AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY);
waveformat->nSamplesPerSec = this->spec.freq;
waveformat->nAvgBytesPerSec = waveformat->nSamplesPerSec * waveformat->nChannels * (waveformat->wBitsPerSample / 8);
}
#endif
streamflags |= AUDCLNT_STREAMFLAGS_EVENTCALLBACK;
ret = IAudioClient_Initialize(client, sharemode, streamflags, 0, 0, waveformat, NULL);

View File

@@ -145,10 +145,22 @@ WIN_RoInitialize(void)
#ifdef __WINRT__
return S_OK;
#else
typedef HRESULT (*RoInitialize_t)(RO_INIT_TYPE initType);
typedef HRESULT (WINAPI *RoInitialize_t)(RO_INIT_TYPE initType);
RoInitialize_t RoInitializeFunc = (RoInitialize_t)WIN_LoadComBaseFunction("RoInitialize");
if (RoInitializeFunc) {
return RoInitializeFunc(RO_INIT_MULTITHREADED);
/* RO_INIT_SINGLETHREADED is equivalent to COINIT_APARTMENTTHREADED */
HRESULT hr = RoInitializeFunc(RO_INIT_SINGLETHREADED);
if (hr == RPC_E_CHANGED_MODE) {
hr = RoInitializeFunc(RO_INIT_MULTITHREADED);
}
/* S_FALSE means success, but someone else already initialized. */
/* You still need to call RoUninitialize in this case! */
if (hr == S_FALSE) {
return S_OK;
}
return hr;
} else {
return E_NOINTERFACE;
}
@@ -159,7 +171,7 @@ void
WIN_RoUninitialize(void)
{
#ifndef __WINRT__
typedef void (*RoUninitialize_t)(void);
typedef void (WINAPI *RoUninitialize_t)(void);
RoUninitialize_t RoUninitializeFunc = (RoUninitialize_t)WIN_LoadComBaseFunction("RoUninitialize");
if (RoUninitializeFunc) {
RoUninitializeFunc();

View File

@@ -410,7 +410,6 @@ SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relativ
mouse->x = x;
mouse->y = y;
mouse->has_position = SDL_TRUE;
return 0;
} else if (!xrel && !yrel) { /* Drop events that don't change state */
#ifdef DEBUG_MOUSE
SDL_Log("Mouse event didn't change state - dropped!\n");

View File

@@ -35,39 +35,23 @@
char *
SDL_GetBasePath(void)
{
typedef DWORD (WINAPI *GetModuleFileNameExW_t)(HANDLE, HMODULE, LPWSTR, DWORD);
GetModuleFileNameExW_t pGetModuleFileNameExW;
DWORD buflen = 128;
WCHAR *path = NULL;
HANDLE psapi = LoadLibrary(TEXT("psapi.dll"));
char *retval = NULL;
DWORD len = 0;
int i;
if (!psapi) {
WIN_SetError("Couldn't load psapi.dll");
return NULL;
}
pGetModuleFileNameExW = (GetModuleFileNameExW_t)GetProcAddress(psapi, "GetModuleFileNameExW");
if (!pGetModuleFileNameExW) {
WIN_SetError("Couldn't find GetModuleFileNameExW");
FreeLibrary(psapi);
return NULL;
}
while (SDL_TRUE) {
void *ptr = SDL_realloc(path, buflen * sizeof (WCHAR));
if (!ptr) {
SDL_free(path);
FreeLibrary(psapi);
SDL_OutOfMemory();
return NULL;
}
path = (WCHAR *) ptr;
len = pGetModuleFileNameExW(GetCurrentProcess(), NULL, path, buflen);
len = GetModuleFileNameW(NULL, path, buflen);
/* if it truncated, then len >= buflen - 1 */
/* if there was enough room (or failure), len < buflen - 1 */
if (len < buflen - 1) {
@@ -78,8 +62,6 @@ SDL_GetBasePath(void)
buflen *= 2;
}
FreeLibrary(psapi);
if (len == 0) {
SDL_free(path);
WIN_SetError("Couldn't locate our .exe");

View File

@@ -951,6 +951,7 @@ DeleteHIDDeviceWrapper(SDL_hid_device *device)
}
#if !SDL_HIDAPI_DISABLED
#if HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || defined(SDL_LIBUSB_DYNAMIC)
#define COPY_IF_EXISTS(var) \
if (pSrc->var != NULL) { \
@@ -987,6 +988,7 @@ CopyHIDDeviceInfo(struct SDL_hid_device_info *pSrc, struct SDL_hid_device_info *
#undef COPY_IF_EXISTS
#undef WCOPY_IF_EXISTS
#endif /* HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND || SDL_LIBUSB_DYNAMIC */
#endif /* !SDL_HIDAPI_DISABLED */
static int SDL_hidapi_refcount = 0;

View File

@@ -1497,6 +1497,7 @@ void HID_API_EXPORT hid_close(hid_device *dev)
/* Clean up the Transfer objects allocated in read_thread(). */
free(dev->transfer->buffer);
dev->transfer->buffer = NULL;
libusb_free_transfer(dev->transfer);
/* release the interface */

View File

@@ -501,7 +501,7 @@ static const char *s_ControllerMappings [] =
"03000000830500006020000000010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"03000000830500006020000000000000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,",
#endif
#if defined(__LINUX__)
#ifdef SDL_JOYSTICK_LINUX
"xinput,*,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,",
"03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"03000000c82d00000090000011010000,8BitDo FC30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
@@ -762,6 +762,7 @@ static const char *s_ControllerMappings [] =
"0300000000f00000f100000000010000,Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,",
"030000004f0400000ed0000011010000,ThrustMaster eSwap PRO 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,",
"030000004f04000020b3000010010000,Thrustmaster 2 in 1 DT,a:b0,b:b2,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:a2,righty:a3,start:b9,x:b1,y:b3,",
"030000004f04000015b3000001010000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,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:a2,righty:a3,start:b9,x:b1,y:b3,",
"030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,a:b0,b:b2,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:a2,righty:a3,start:b9,x:b1,y:b3,",
"030000004f04000023b3000000010000,Thrustmaster Dual Trigger 3-in-1,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:a5,start:b9,x:b0,y:b3,",
"030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,",

View File

@@ -961,7 +961,10 @@ HIDAPI_DriverPS5_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev,
axis = ((int)packet->ucRightJoystickY * 257) - 32768;
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis);
if (packet->ucBatteryLevel & 0x10) {
/* A check of packet->ucBatteryLevel & 0x10 should work as a check for BT vs USB but doesn't
* seem to always work. Possibly related to being 100% charged?
*/
if (!ctx->is_bluetooth) {
/* 0x20 set means fully charged */
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_WIRED);
} else {

View File

@@ -330,6 +330,19 @@ IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controlle
subtype = 1;
}
if (SDL_strcmp(name, "Backbone One") == 0) {
/* The Backbone app uses the guide and share buttons */
if ((device->button_mask & (1 << SDL_CONTROLLER_BUTTON_GUIDE)) != 0) {
device->button_mask &= ~(1 << SDL_CONTROLLER_BUTTON_GUIDE);
--nbuttons;
}
if ((device->button_mask & (1 << SDL_CONTROLLER_BUTTON_MISC1)) != 0) {
device->button_mask &= ~(1 << SDL_CONTROLLER_BUTTON_MISC1);
--nbuttons;
device->has_xbox_share_button = SDL_FALSE;
}
}
device->naxes = 6; /* 2 thumbsticks and 2 triggers */
device->nhats = 1; /* d-pad */
device->nbuttons = nbuttons;

View File

@@ -610,7 +610,7 @@ static int get_event_joystick_index(int event)
{
int joystick_index = -1;
int i, count;
struct dirent **entries;
struct dirent **entries = NULL;
char path[PATH_MAX];
SDL_snprintf(path, SDL_arraysize(path), "/sys/class/input/event%d/device", event);
@@ -636,8 +636,10 @@ filter_entries(const struct dirent *entry)
return IsJoystickDeviceNode(entry->d_name);
}
static int
sort_entries(const struct dirent **a, const struct dirent **b)
sort_entries(const void *_a, const void *_b)
{
const struct dirent **a = (const struct dirent **)_a;
const struct dirent **b = (const struct dirent **)_b;
int numA, numB;
int offset;
@@ -679,10 +681,13 @@ LINUX_FallbackJoystickDetect(void)
/* Opening input devices can generate synchronous device I/O, so avoid it if we can */
if (stat("/dev/input", &sb) == 0 && sb.st_mtime != last_input_dir_mtime) {
int i, count;
struct dirent **entries;
struct dirent **entries = NULL;
char path[PATH_MAX];
count = scandir("/dev/input", &entries, filter_entries, sort_entries);
count = scandir("/dev/input", &entries, filter_entries, NULL);
if (count > 1) {
qsort(entries, count, sizeof(*entries), sort_entries);
}
for (i = 0; i < count; ++i) {
SDL_snprintf(path, SDL_arraysize(path), "/dev/input/%s", entries[i]->d_name);
MaybeAddDevice(path);

View File

@@ -1322,8 +1322,10 @@ RAWINPUT_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint
if (!SUCCEEDED(hr)) {
return SDL_SetError("Setting vibration failed: 0x%lx\n", hr);
}
return 0;
} else {
return SDL_SetError("Controller isn't correlated yet, try hitting a button first");
}
return 0;
#else
return SDL_Unsupported();
#endif

View File

@@ -68,6 +68,7 @@ static struct {
EventRegistrationToken controller_added_token;
EventRegistrationToken controller_removed_token;
int controller_count;
SDL_bool ro_initialized;
WindowsGamingInputControllerState *controllers;
} wgi;
@@ -443,6 +444,30 @@ WGI_JoystickInit(void)
if (FAILED(WIN_RoInitialize())) {
return SDL_SetError("RoInitialize() failed");
}
wgi.ro_initialized = SDL_TRUE;
#ifndef __WINRT__
{
/* There seems to be a bug in Windows where a dependency of WGI can be unloaded from memory prior to WGI itself.
* This results in Windows_Gaming_Input!GameController::~GameController() invoking an unloaded DLL and crashing.
* As a workaround, we will keep a reference to the MTA to prevent COM from unloading DLLs later.
* See https://github.com/libsdl-org/SDL/issues/5552 for more details.
*/
static PVOID cookie = NULL;
if (!cookie) {
typedef HRESULT (WINAPI *CoIncrementMTAUsage_t)(PVOID* pCookie);
CoIncrementMTAUsage_t CoIncrementMTAUsageFunc = (CoIncrementMTAUsage_t)WIN_LoadComBaseFunction("CoIncrementMTAUsage");
if (CoIncrementMTAUsageFunc) {
if (FAILED(CoIncrementMTAUsageFunc(&cookie))) {
return SDL_SetError("CoIncrementMTAUsage() failed");
}
} else {
/* CoIncrementMTAUsage() is present since Win8, so we should never make it here. */
return SDL_SetError("CoIncrementMTAUsage() not found");
}
}
}
#endif
#ifdef __WINRT__
WindowsCreateStringReferenceFunc = WindowsCreateStringReference;
@@ -848,9 +873,12 @@ WGI_JoystickQuit(void)
__x_ABI_CWindows_CGaming_CInput_CIRawGameControllerStatics_remove_RawGameControllerRemoved(wgi.statics, wgi.controller_removed_token);
__x_ABI_CWindows_CGaming_CInput_CIRawGameControllerStatics_Release(wgi.statics);
}
SDL_zero(wgi);
WIN_RoUninitialize();
if (wgi.ro_initialized) {
WIN_RoUninitialize();
}
SDL_zero(wgi);
}
static SDL_bool

View File

@@ -356,7 +356,7 @@ QueueCmdSetViewport(SDL_Renderer *renderer)
if (cmd != NULL) {
cmd->command = SDL_RENDERCMD_SETVIEWPORT;
cmd->data.viewport.first = 0; /* render backend will fill this in. */
/* Convert SDL_FRect to SDL_Rect */
/* Convert SDL_DRect to SDL_Rect */
cmd->data.viewport.rect.x = (int)SDL_floor(renderer->viewport.x);
cmd->data.viewport.rect.y = (int)SDL_floor(renderer->viewport.y);
cmd->data.viewport.rect.w = (int)SDL_floor(renderer->viewport.w);
@@ -386,7 +386,7 @@ QueueCmdSetClipRect(SDL_Renderer *renderer)
} else {
cmd->command = SDL_RENDERCMD_SETCLIPRECT;
cmd->data.cliprect.enabled = renderer->clipping_enabled;
/* Convert SDL_FRect to SDL_Rect */
/* Convert SDL_DRect to SDL_Rect */
cmd->data.cliprect.rect.x = (int)SDL_floor(renderer->clip_rect.x);
cmd->data.cliprect.rect.y = (int)SDL_floor(renderer->clip_rect.y);
cmd->data.cliprect.rect.w = (int)SDL_floor(renderer->clip_rect.w);
@@ -676,7 +676,7 @@ SDL_GetRenderDriverInfo(int index, SDL_RendererInfo * info)
#endif
}
static void GetWindowViewportValues(SDL_Renderer *renderer, int *logical_w, int *logical_h, SDL_FRect *viewport, SDL_FPoint *scale)
static void GetWindowViewportValues(SDL_Renderer *renderer, int *logical_w, int *logical_h, SDL_DRect *viewport, SDL_FPoint *scale)
{
SDL_LockMutex(renderer->target_mutex);
*logical_w = renderer->target ? renderer->logical_w_backup : renderer->logical_w;
@@ -738,10 +738,10 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event)
SDL_GetWindowSize(renderer->window, &w, &h);
}
renderer->viewport.x = 0;
renderer->viewport.y = 0;
renderer->viewport.w = (float) w;
renderer->viewport.h = (float) h;
renderer->viewport.x = (double)0;
renderer->viewport.y = (double)0;
renderer->viewport.w = (double)w;
renderer->viewport.h = (double)h;
QueueCmdSetViewport(renderer);
FlushRenderCommandsIfNotBatching(renderer);
}
@@ -768,7 +768,7 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event)
SDL_Window *window = SDL_GetWindowFromID(event->motion.windowID);
if (window == renderer->window) {
int logical_w, logical_h;
SDL_FRect viewport;
SDL_DRect viewport;
SDL_FPoint scale;
GetWindowViewportValues(renderer, &logical_w, &logical_h, &viewport, &scale);
if (logical_w) {
@@ -795,7 +795,7 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event)
SDL_Window *window = SDL_GetWindowFromID(event->button.windowID);
if (window == renderer->window) {
int logical_w, logical_h;
SDL_FRect viewport;
SDL_DRect viewport;
SDL_FPoint scale;
GetWindowViewportValues(renderer, &logical_w, &logical_h, &viewport, &scale);
if (logical_w) {
@@ -810,7 +810,7 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event)
event->type == SDL_FINGERMOTION) {
int logical_w, logical_h;
float physical_w, physical_h;
SDL_FRect viewport;
SDL_DRect viewport;
SDL_FPoint scale;
GetWindowViewportValues(renderer, &logical_w, &logical_h, &viewport, &scale);
@@ -2228,10 +2228,10 @@ SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture)
}
if (texture) {
renderer->viewport.x = 0.0f;
renderer->viewport.y = 0.0f;
renderer->viewport.w = (float) texture->w;
renderer->viewport.h = (float) texture->h;
renderer->viewport.x = (double)0;
renderer->viewport.y = (double)0;
renderer->viewport.w = (double)texture->w;
renderer->viewport.h = (double)texture->h;
SDL_zero(renderer->clip_rect);
renderer->clipping_enabled = SDL_FALSE;
renderer->scale.x = 1.0f;
@@ -2263,6 +2263,8 @@ SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture)
SDL_Texture *
SDL_GetRenderTarget(SDL_Renderer *renderer)
{
CHECK_RENDERER_MAGIC(renderer, NULL);
return renderer->target;
}
@@ -2438,19 +2440,19 @@ SDL_RenderSetViewport(SDL_Renderer * renderer, const SDL_Rect * rect)
CHECK_RENDERER_MAGIC(renderer, -1);
if (rect) {
renderer->viewport.x = rect->x * renderer->scale.x;
renderer->viewport.y = rect->y * renderer->scale.y;
renderer->viewport.w = rect->w * renderer->scale.x;
renderer->viewport.h = rect->h * renderer->scale.y;
renderer->viewport.x = (double)rect->x * renderer->scale.x;
renderer->viewport.y = (double)rect->y * renderer->scale.y;
renderer->viewport.w = (double)rect->w * renderer->scale.x;
renderer->viewport.h = (double)rect->h * renderer->scale.y;
} else {
int w, h;
if (SDL_GetRendererOutputSize(renderer, &w, &h) < 0) {
return -1;
}
renderer->viewport.x = 0.0f;
renderer->viewport.y = 0.0f;
renderer->viewport.w = (float) w;
renderer->viewport.h = (float) h;
renderer->viewport.x = (double)0;
renderer->viewport.y = (double)0;
renderer->viewport.w = (double)w;
renderer->viewport.h = (double)h;
}
retval = QueueCmdSetViewport(renderer);
return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer);
@@ -2474,8 +2476,8 @@ RenderGetViewportSize(SDL_Renderer * renderer, SDL_FRect * rect)
{
rect->x = 0.0f;
rect->y = 0.0f;
rect->w = renderer->viewport.w / renderer->scale.x;
rect->h = renderer->viewport.h / renderer->scale.y;
rect->w = (float)(renderer->viewport.w / renderer->scale.x);
rect->h = (float)(renderer->viewport.h / renderer->scale.y);
}
int
@@ -2486,10 +2488,10 @@ SDL_RenderSetClipRect(SDL_Renderer * renderer, const SDL_Rect * rect)
if (rect) {
renderer->clipping_enabled = SDL_TRUE;
renderer->clip_rect.x = rect->x * renderer->scale.x;
renderer->clip_rect.y = rect->y * renderer->scale.y;
renderer->clip_rect.w = rect->w * renderer->scale.x;
renderer->clip_rect.h = rect->h * renderer->scale.y;
renderer->clip_rect.x = (double)rect->x * renderer->scale.x;
renderer->clip_rect.y = (double)rect->y * renderer->scale.y;
renderer->clip_rect.w = (double)rect->w * renderer->scale.x;
renderer->clip_rect.h = (double)rect->h * renderer->scale.y;
} else {
renderer->clipping_enabled = SDL_FALSE;
SDL_zero(renderer->clip_rect);
@@ -2553,10 +2555,10 @@ SDL_RenderWindowToLogical(SDL_Renderer * renderer, int windowX, int windowY, flo
window_physical_y = ((float) windowY) / renderer->dpi_scale.y;
if (logicalX) {
*logicalX = (window_physical_x - renderer->viewport.x) / renderer->scale.x;
*logicalX = (float)((window_physical_x - renderer->viewport.x) / renderer->scale.x);
}
if (logicalY) {
*logicalY = (window_physical_y - renderer->viewport.y) / renderer->scale.y;
*logicalY = (float)((window_physical_y - renderer->viewport.y) / renderer->scale.y);
}
}
@@ -2567,8 +2569,8 @@ SDL_RenderLogicalToWindow(SDL_Renderer * renderer, float logicalX, float logical
CHECK_RENDERER_MAGIC(renderer, );
window_physical_x = (logicalX * renderer->scale.x) + renderer->viewport.x;
window_physical_y = (logicalY * renderer->scale.y) + renderer->viewport.y;
window_physical_x = (float)((logicalX * renderer->scale.x) + renderer->viewport.x);
window_physical_y = (float)((logicalY * renderer->scale.y) + renderer->viewport.y);
if (windowX) {
*windowX = (int)(window_physical_x * renderer->dpi_scale.x);

View File

@@ -28,6 +28,19 @@
#include "SDL_mutex.h"
#include "SDL_yuv_sw_c.h"
/**
* A rectangle, with the origin at the upper left (double precision).
*/
typedef struct SDL_DRect
{
double x;
double y;
double w;
double h;
} SDL_DRect;
/* The SDL 2D rendering system */
typedef struct SDL_RenderDriver SDL_RenderDriver;
@@ -201,12 +214,12 @@ struct SDL_Renderer
SDL_bool integer_scale;
/* The drawable area within the window */
SDL_FRect viewport;
SDL_FRect viewport_backup;
SDL_DRect viewport;
SDL_DRect viewport_backup;
/* The clip rectangle within the window */
SDL_FRect clip_rect;
SDL_FRect clip_rect_backup;
SDL_DRect clip_rect;
SDL_DRect clip_rect_backup;
/* Wether or not the clipping rectangle is used. */
SDL_bool clipping_enabled;
@@ -244,8 +257,8 @@ struct SDL_Renderer
SDL_RenderCommand *render_commands_pool;
Uint32 render_command_generation;
Uint32 last_queued_color;
SDL_FRect last_queued_viewport;
SDL_FRect last_queued_cliprect;
SDL_DRect last_queued_viewport;
SDL_DRect last_queued_cliprect;
SDL_bool last_queued_cliprect_enabled;
SDL_bool color_queued;
SDL_bool viewport_queued;

View File

@@ -1230,6 +1230,13 @@ GL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic
}
}
#ifdef __MACOSX__
// On macOS on older systems, the OpenGL view change and resize events aren't
// necessarily synchronized, so just always reset it.
// Workaround for: https://discourse.libsdl.org/t/sdl-2-0-22-prerelease/35306/6
data->drawstate.viewport_dirty = SDL_TRUE;
#endif
while (cmd) {
switch (cmd->command) {
case SDL_RENDERCMD_SETDRAWCOLOR: {

View File

@@ -26,7 +26,7 @@
#include "SDL_render_vita_gxm_memory.h"
void *
vita_mem_alloc(SceKernelMemBlockType type, unsigned int size, unsigned int alignment, unsigned int attribs, SceUID *uid)
vita_mem_alloc(unsigned int type, unsigned int size, unsigned int alignment, unsigned int attribs, SceUID *uid)
{
void *mem;

View File

@@ -29,7 +29,7 @@
#define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1))
void *vita_mem_alloc(SceKernelMemBlockType type, unsigned int size, unsigned int alignment, unsigned int attribs, SceUID *uid);
void *vita_mem_alloc(unsigned int type, unsigned int size, unsigned int alignment, unsigned int attribs, SceUID *uid);
void vita_mem_free(SceUID uid);
void *vita_gpu_mem_alloc(VITA_GXM_RenderData *data, unsigned int size);
void vita_gpu_mem_free(VITA_GXM_RenderData *data, void* ptr);

View File

@@ -56,12 +56,12 @@ SDL_CreateMutex(void)
void
SDL_DestroyMutex(SDL_mutex * mutex)
{
ULONG ulRC;
HMTX hMtx = (HMTX)mutex;
ulRC = DosCloseMutexSem(hMtx);
if (ulRC != NO_ERROR) {
debug_os2("DosCloseMutexSem(), rc = %u", ulRC);
if (hMtx != NULLHANDLE) {
const ULONG ulRC = DosCloseMutexSem(hMtx);
if (ulRC != NO_ERROR) {
debug_os2("DosCloseMutexSem(), rc = %u", ulRC);
}
}
}

View File

@@ -39,6 +39,7 @@
typedef unsigned long long ULLONG;
static SDL_bool ticks_started = SDL_FALSE;
static ULONG ulTmrFreq = 0;
static ULLONG ullTmrStart = 0;
@@ -46,7 +47,14 @@ void
SDL_TicksInit(void)
{
ULONG ulTmrStart; /* for 32-bit fallback. */
ULONG ulRC = DosTmrQueryFreq(&ulTmrFreq);
ULONG ulRC;
if (ticks_started) {
return;
}
ticks_started = SDL_TRUE;
ulRC = DosTmrQueryFreq(&ulTmrFreq);
if (ulRC != NO_ERROR) {
debug_os2("DosTmrQueryFreq() failed, rc = %u", ulRC);
} else {
@@ -65,6 +73,7 @@ SDL_TicksInit(void)
void
SDL_TicksQuit(void)
{
ticks_started = SDL_FALSE;
}
Uint64
@@ -73,7 +82,7 @@ SDL_GetTicks64(void)
Uint64 ui64Result;
ULLONG ullTmrNow;
if (ulTmrFreq == 0) { /* Was not initialized. */
if (!ticks_started) {
SDL_TicksInit();
}

View File

@@ -61,12 +61,12 @@ static VideoBootStrap *bootstrap[] = {
#if SDL_VIDEO_DRIVER_COCOA
&COCOA_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_WAYLAND
&Wayland_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_X11
&X11_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_WAYLAND
&Wayland_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_VIVANTE
&VIVANTE_bootstrap,
#endif
@@ -425,7 +425,7 @@ SDL_VideoInit(const char *driver_name)
i = index = 0;
video = NULL;
if (driver_name == NULL) {
driver_name = SDL_getenv("SDL_VIDEODRIVER");
driver_name = SDL_GetHint(SDL_HINT_VIDEODRIVER);
}
if (driver_name != NULL && *driver_name != 0) {
const char *driver_attempt = driver_name;
@@ -3060,7 +3060,8 @@ ShouldMinimizeOnFocusLoss(SDL_Window * window)
/* Real fullscreen windows should minimize on focus loss so the desktop video mode is restored */
hint = SDL_GetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS);
if (!hint || !*hint || SDL_strcasecmp(hint, "auto") == 0) {
if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) {
if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP ||
_this->disable_display_mode_switching == SDL_TRUE) {
return SDL_FALSE;
} else {
return SDL_TRUE;
@@ -3924,6 +3925,10 @@ SDL_GL_MakeCurrent(SDL_Window * window, SDL_GLContext ctx)
{
int retval;
if (!_this) {
return SDL_UninitializedVideo();
}
if (window == SDL_GL_GetCurrentWindow() &&
ctx == SDL_GL_GetCurrentContext()) {
/* We're already current. */
@@ -4267,12 +4272,12 @@ SDL_IsScreenKeyboardShown(SDL_Window *window)
#if SDL_VIDEO_DRIVER_UIKIT
#include "uikit/SDL_uikitmessagebox.h"
#endif
#if SDL_VIDEO_DRIVER_WAYLAND
#include "wayland/SDL_waylandmessagebox.h"
#endif
#if SDL_VIDEO_DRIVER_X11
#include "x11/SDL_x11messagebox.h"
#endif
#if SDL_VIDEO_DRIVER_WAYLAND
#include "wayland/SDL_waylandmessagebox.h"
#endif
#if SDL_VIDEO_DRIVER_HAIKU
#include "haiku/SDL_bmessagebox.h"
#endif
@@ -4380,13 +4385,6 @@ SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
retval = 0;
}
#endif
#if SDL_VIDEO_DRIVER_WAYLAND
if (retval == -1 &&
SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_WAYLAND) &&
Wayland_ShowMessageBox(messageboxdata, buttonid) == 0) {
retval = 0;
}
#endif
#if SDL_VIDEO_DRIVER_X11
if (retval == -1 &&
SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_X11) &&
@@ -4394,6 +4392,13 @@ SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
retval = 0;
}
#endif
#if SDL_VIDEO_DRIVER_WAYLAND
if (retval == -1 &&
SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_WAYLAND) &&
Wayland_ShowMessageBox(messageboxdata, buttonid) == 0) {
retval = 0;
}
#endif
#if SDL_VIDEO_DRIVER_HAIKU
if (retval == -1 &&
SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_HAIKU) &&

View File

@@ -46,6 +46,7 @@
#include "SDL_nullvideo.h"
#include "SDL_nullevents_c.h"
#include "SDL_nullframebuffer_c.h"
#include "SDL_hints.h"
#define DUMMYVID_DRIVER_NAME "dummy"
@@ -59,7 +60,7 @@ static void DUMMY_VideoQuit(_THIS);
static int
DUMMY_Available(void)
{
const char *envr = SDL_getenv("SDL_VIDEODRIVER");
const char *envr = SDL_GetHint(SDL_HINT_VIDEODRIVER);
if ((envr) && (SDL_strcmp(envr, DUMMYVID_DRIVER_NAME) == 0)) {
return (1);
}

View File

@@ -31,7 +31,7 @@
#define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1))
#define DISPLAY_PIXEL_FORMAT SCE_DISPLAY_PIXELFORMAT_A8B8G8R8
void *vita_gpu_alloc(SceKernelMemBlockType type, unsigned int size, SceUID *uid)
void *vita_gpu_alloc(unsigned int type, unsigned int size, SceUID *uid)
{
void *mem;

View File

@@ -391,8 +391,8 @@ pointer_handle_motion(void *data, struct wl_pointer *pointer,
if (input->pointer_focus) {
const float sx_f = (float)wl_fixed_to_double(sx_w);
const float sy_f = (float)wl_fixed_to_double(sy_w);
const int sx = (int)SDL_lroundf(sx_f * window->pointer_scale_x);
const int sy = (int)SDL_lroundf(sy_f * window->pointer_scale_y);
const int sx = (int)SDL_floorf(sx_f * window->pointer_scale_x);
const int sy = (int)SDL_floorf(sy_f * window->pointer_scale_y);
SDL_SendMouseMotion(window->sdlwindow, 0, 0, sx, sy);
}
}
@@ -476,6 +476,9 @@ ProcessHitTest(struct SDL_WaylandInput *input, uint32_t serial)
const uint32_t *directions_libdecor = directions;
#endif
/* Hit tests shouldn't apply to xdg_popups, right? */
SDL_assert(!WINDOW_IS_XDG_POPUP(window));
switch (rc) {
case SDL_HITTEST_DRAGGABLE:
#ifdef HAVE_LIBDECOR_H
@@ -1826,8 +1829,8 @@ tablet_tool_handle_motion(void* data, struct zwp_tablet_tool_v2* tool, wl_fixed_
if (input->tool_focus) {
const float sx_f = (float)wl_fixed_to_double(sx_w);
const float sy_f = (float)wl_fixed_to_double(sy_w);
const int sx = (int)SDL_lroundf(sx_f * window->pointer_scale_x);
const int sy = (int)SDL_lroundf(sy_f * window->pointer_scale_y);
const int sx = (int)SDL_floorf(sx_f * window->pointer_scale_x);
const int sy = (int)SDL_floorf(sy_f * window->pointer_scale_y);
SDL_SendMouseMotion(window->sdlwindow, 0, 0, sx, sy);
}
}

View File

@@ -819,7 +819,7 @@ display_handle_global(void *data, struct wl_registry *registry, uint32_t id,
} else if (SDL_strcmp(interface, "wl_seat") == 0) {
Wayland_display_add_input(d, id, version);
} else if (SDL_strcmp(interface, "xdg_wm_base") == 0) {
d->shell.xdg = wl_registry_bind(d->registry, id, &xdg_wm_base_interface, 1);
d->shell.xdg = wl_registry_bind(d->registry, id, &xdg_wm_base_interface, SDL_min(version, 3));
xdg_wm_base_add_listener(d->shell.xdg, &shell_listener_xdg, NULL);
} else if (SDL_strcmp(interface, "wl_shm") == 0) {
d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
@@ -876,6 +876,29 @@ static const struct wl_registry_listener registry_listener = {
display_handle_global,
display_remove_global
};
#ifdef HAVE_LIBDECOR_H
static SDL_bool should_use_libdecor(SDL_VideoData *data)
{
if (!SDL_WAYLAND_HAVE_WAYLAND_LIBDECOR) {
return SDL_FALSE;
}
if (!SDL_GetHintBoolean(SDL_HINT_VIDEO_WAYLAND_ALLOW_LIBDECOR, SDL_TRUE)) {
return SDL_FALSE;
}
if (SDL_GetHintBoolean(SDL_HINT_VIDEO_WAYLAND_PREFER_LIBDECOR, SDL_FALSE)) {
return SDL_TRUE;
}
if (data->decoration_manager) {
return SDL_FALSE;
}
return SDL_TRUE;
}
#endif
int
Wayland_VideoInit(_THIS)
@@ -899,14 +922,8 @@ Wayland_VideoInit(_THIS)
#ifdef HAVE_LIBDECOR_H
/* Don't have server-side decorations? Try client-side instead. */
if (!data->decoration_manager && SDL_WAYLAND_HAVE_WAYLAND_LIBDECOR && SDL_GetHintBoolean(SDL_HINT_VIDEO_WAYLAND_ALLOW_LIBDECOR, SDL_TRUE)) {
if (should_use_libdecor(data)) {
data->shell.libdecor = libdecor_new(data->display, &libdecor_interface);
/* If libdecor works, we don't need xdg-shell anymore. */
if (data->shell.libdecor && data->shell.xdg) {
xdg_wm_base_destroy(data->shell.xdg);
data->shell.xdg = NULL;
}
}
#endif

View File

@@ -25,12 +25,14 @@
#include "../SDL_sysvideo.h"
#include "../../events/SDL_windowevents_c.h"
#include "../../events/SDL_mouse_c.h"
#include "../SDL_egl_c.h"
#include "SDL_waylandevents_c.h"
#include "SDL_waylandwindow.h"
#include "SDL_waylandvideo.h"
#include "SDL_waylandtouch.h"
#include "SDL_hints.h"
#include "SDL_events.h"
#include "xdg-shell-client-protocol.h"
#include "xdg-decoration-unstable-v1-client-protocol.h"
@@ -173,6 +175,19 @@ NeedWindowedViewport(SDL_Window *window)
DesktopIsFractionalScaled(window) && (window->flags & SDL_WINDOW_ALLOW_HIGHDPI);
}
/* Never set a fullscreen window size larger than the desktop. */
SDL_FORCE_INLINE int
GetWindowWidth(SDL_Window *window)
{
return NeedFullscreenViewport(window) ? ((SDL_WaylandOutputData *)SDL_GetDisplayForWindow(window)->driverdata)->width : window->w;
}
SDL_FORCE_INLINE int
GetWindowHeight(SDL_Window *window)
{
return NeedFullscreenViewport(window) ? ((SDL_WaylandOutputData *)SDL_GetDisplayForWindow(window)->driverdata)->height : window->h;
}
static void
GetWindowBufferSize(SDL_Window *window, int *width, int *height)
{
@@ -305,6 +320,15 @@ SetMinMaxDimensions(SDL_Window *window, SDL_bool commit)
SDL_VideoData *viddata = wind->waylandData;
int min_width, min_height, max_width, max_height;
/* Pop-ups don't get to change size */
if (WINDOW_IS_XDG_POPUP(window)) {
/* ... but we still want to commit, particularly for ShowWindow */
if (commit) {
wl_surface_commit(wind->surface);
}
return;
}
if (window->flags & SDL_WINDOW_FULLSCREEN) {
min_width = 0;
min_height = 0;
@@ -323,7 +347,7 @@ SetMinMaxDimensions(SDL_Window *window, SDL_bool commit)
}
#ifdef HAVE_LIBDECOR_H
if (viddata->shell.libdecor) {
if (WINDOW_IS_LIBDECOR(viddata, window)) {
if (wind->shell_surface.libdecor.frame == NULL) {
return; /* Can't do anything yet, wait for ShowWindow */
}
@@ -357,13 +381,22 @@ SetFullscreen(SDL_Window *window, struct wl_output *output, SDL_bool commit)
SDL_WindowData *wind = window->driverdata;
SDL_VideoData *viddata = wind->waylandData;
/* Pop-ups don't get to be fullscreened */
if (WINDOW_IS_XDG_POPUP(window)) {
/* ... but we still want to commit, particularly for ShowWindow */
if (commit) {
wl_surface_commit(wind->surface);
}
return;
}
/* The desktop may try to enforce min/max sizes here, so turn them off for
* fullscreen and on (if applicable) for windowed
*/
SetMinMaxDimensions(window, SDL_FALSE);
#ifdef HAVE_LIBDECOR_H
if (viddata->shell.libdecor) {
if (WINDOW_IS_LIBDECOR(viddata, window)) {
if (wind->shell_surface.libdecor.frame == NULL) {
return; /* Can't do anything yet, wait for ShowWindow */
}
@@ -596,6 +629,60 @@ static const struct xdg_toplevel_listener toplevel_listener_xdg = {
handle_close_xdg_toplevel
};
static void
handle_configure_xdg_popup(void *data,
struct xdg_popup *xdg_popup,
int32_t x,
int32_t y,
int32_t width,
int32_t height)
{
/* No-op, we don't use x/y and width/height are fixed-size */
}
static void
handle_done_xdg_popup(void *data, struct xdg_popup *xdg_popup)
{
SDL_WindowData *window = (SDL_WindowData *)data;
SDL_SendWindowEvent(window->sdlwindow, SDL_WINDOWEVENT_CLOSE, 0, 0);
}
static void
handle_repositioned_xdg_popup(void *data,
struct xdg_popup *xdg_popup,
uint32_t token)
{
/* No-op, configure does all the work we care about */
}
static const struct xdg_popup_listener popup_listener_xdg = {
handle_configure_xdg_popup,
handle_done_xdg_popup,
handle_repositioned_xdg_popup
};
#define TOOLTIP_CURSOR_OFFSET 8 /* FIXME: Arbitrary, eyeballed from X tooltip */
static int
Wayland_PopupWatch(void *data, SDL_Event *event)
{
if (event->type == SDL_MOUSEMOTION) {
SDL_Window *window = (SDL_Window *) data;
SDL_WindowData *wind = window->driverdata;
/* Coordinates might be relative to the popup, which we don't want */
if (event->motion.windowID == wind->shell_surface.xdg.roleobj.popup.parentID) {
xdg_positioner_set_offset(wind->shell_surface.xdg.roleobj.popup.positioner,
event->motion.x + TOOLTIP_CURSOR_OFFSET,
event->motion.y + TOOLTIP_CURSOR_OFFSET);
xdg_popup_reposition(wind->shell_surface.xdg.roleobj.popup.popup,
wind->shell_surface.xdg.roleobj.popup.positioner,
0);
}
}
return 1;
}
#ifdef HAVE_LIBDECOR_H
static void
decoration_frame_configure(struct libdecor_frame *frame,
@@ -718,7 +805,7 @@ decoration_frame_configure(struct libdecor_frame *frame,
wind->shell_surface.libdecor.initial_configure_seen = SDL_TRUE;
/* ... then commit the changes on the libdecor side. */
state = libdecor_state_new(width, height);
state = libdecor_state_new(GetWindowWidth(window), GetWindowHeight(window));
libdecor_frame_commit(frame, state, configuration);
libdecor_state_free(state);
@@ -916,6 +1003,19 @@ static const struct wl_surface_listener surface_listener = {
handle_surface_leave
};
static void
Wayland_FillEmptyShellInfo(SDL_SysWMinfo * info, const Uint32 version)
{
info->info.wl.xdg_surface = NULL;
if (version >= SDL_VERSIONNUM(2, 0, 17)) {
info->info.wl.xdg_toplevel = NULL;
if (version >= SDL_VERSIONNUM(2, 0, 22)) {
info->info.wl.xdg_popup = NULL;
info->info.wl.xdg_positioner = NULL;
}
}
}
SDL_bool
Wayland_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
{
@@ -948,23 +1048,40 @@ Wayland_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
info->info.wl.egl_window = data->egl_window;
#ifdef HAVE_LIBDECOR_H
if (viddata->shell.libdecor && data->shell_surface.libdecor.frame != NULL) {
info->info.wl.xdg_surface = libdecor_frame_get_xdg_surface(data->shell_surface.libdecor.frame);
if (version >= SDL_VERSIONNUM(2, 0, 17)) {
info->info.wl.xdg_toplevel = libdecor_frame_get_xdg_toplevel(data->shell_surface.libdecor.frame);
if (WINDOW_IS_LIBDECOR(viddata, window)) {
if (data->shell_surface.libdecor.frame != NULL) {
info->info.wl.xdg_surface = libdecor_frame_get_xdg_surface(data->shell_surface.libdecor.frame);
if (version >= SDL_VERSIONNUM(2, 0, 17)) {
info->info.wl.xdg_toplevel = libdecor_frame_get_xdg_toplevel(data->shell_surface.libdecor.frame);
if (version >= SDL_VERSIONNUM(2, 0, 22)) {
info->info.wl.xdg_popup = NULL;
info->info.wl.xdg_positioner = NULL;
}
}
} else {
/* Not mapped yet */
Wayland_FillEmptyShellInfo(info, version);
}
} else
#endif
if (viddata->shell.xdg && data->shell_surface.xdg.surface != NULL) {
info->info.wl.xdg_surface = data->shell_surface.xdg.surface;
if (version >= SDL_VERSIONNUM(2, 0, 17)) {
info->info.wl.xdg_toplevel = data->shell_surface.xdg.roleobj.toplevel;
SDL_bool popup = WINDOW_IS_XDG_POPUP(window);
info->info.wl.xdg_toplevel = popup ? NULL : data->shell_surface.xdg.roleobj.toplevel;
if (version >= SDL_VERSIONNUM(2, 0, 22)) {
if (popup) {
info->info.wl.xdg_popup = data->shell_surface.xdg.roleobj.popup.popup;
info->info.wl.xdg_positioner = data->shell_surface.xdg.roleobj.popup.positioner;
} else {
info->info.wl.xdg_popup = NULL;
info->info.wl.xdg_positioner = NULL;
}
}
}
} else {
info->info.wl.xdg_surface = NULL;
if (version >= SDL_VERSIONNUM(2, 0, 17)) {
info->info.wl.xdg_toplevel = NULL;
}
/* Either it's not mapped yet or we don't have a shell protocol */
Wayland_FillEmptyShellInfo(info, version);
}
}
@@ -989,6 +1106,10 @@ Wayland_SetWindowModalFor(_THIS, SDL_Window *modal_window, SDL_Window *parent_wi
SDL_WindowData *modal_data = modal_window->driverdata;
SDL_WindowData *parent_data = parent_window->driverdata;
if (WINDOW_IS_XDG_POPUP(modal_window) || WINDOW_IS_XDG_POPUP(parent_window)) {
return SDL_SetError("Modal/Parent was a popup, not a toplevel");
}
#ifdef HAVE_LIBDECOR_H
if (viddata->shell.libdecor) {
if (modal_data->shell_surface.libdecor.frame == NULL) {
@@ -1040,9 +1161,9 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
wl_surface_attach(data->surface, NULL, 0, 0);
wl_surface_commit(data->surface);
/* Create the shell surface and map the toplevel */
/* Create the shell surface and map the toplevel/popup */
#ifdef HAVE_LIBDECOR_H
if (c->shell.libdecor) {
if (WINDOW_IS_LIBDECOR(c, window)) {
data->shell_surface.libdecor.frame = libdecor_decorate(c->shell.libdecor,
data->surface,
&libdecor_frame_interface,
@@ -1060,10 +1181,42 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
xdg_surface_set_user_data(data->shell_surface.xdg.surface, data);
xdg_surface_add_listener(data->shell_surface.xdg.surface, &shell_surface_listener_xdg, data);
/* !!! FIXME: add popup role */
data->shell_surface.xdg.roleobj.toplevel = xdg_surface_get_toplevel(data->shell_surface.xdg.surface);
xdg_toplevel_set_app_id(data->shell_surface.xdg.roleobj.toplevel, c->classname);
xdg_toplevel_add_listener(data->shell_surface.xdg.roleobj.toplevel, &toplevel_listener_xdg, data);
if (WINDOW_IS_XDG_POPUP(window)) {
SDL_Mouse *mouse = SDL_GetMouse();
SDL_Window *focused = SDL_GetMouseFocus();
SDL_WindowData *focuseddata = focused->driverdata;
/* This popup may be a child of another popup! */
data->shell_surface.xdg.roleobj.popup.parentID = SDL_GetWindowID(focused);
data->shell_surface.xdg.roleobj.popup.child = NULL;
if (WINDOW_IS_XDG_POPUP(focused)) {
SDL_assert(focuseddata->shell_surface.xdg.roleobj.popup.child == NULL);
focuseddata->shell_surface.xdg.roleobj.popup.child = window;
}
/* Set up the positioner for the popup */
data->shell_surface.xdg.roleobj.popup.positioner = xdg_wm_base_create_positioner(c->shell.xdg);
xdg_positioner_set_offset(data->shell_surface.xdg.roleobj.popup.positioner,
mouse->x + TOOLTIP_CURSOR_OFFSET,
mouse->y + TOOLTIP_CURSOR_OFFSET);
/* Assign the popup role */
data->shell_surface.xdg.roleobj.popup.popup = xdg_surface_get_popup(data->shell_surface.xdg.surface,
focuseddata->shell_surface.xdg.surface,
data->shell_surface.xdg.roleobj.popup.positioner);
xdg_popup_add_listener(data->shell_surface.xdg.roleobj.popup.popup, &popup_listener_xdg, data);
/* For tooltips, track mouse motion so it follows the cursor */
if (window->flags & SDL_WINDOW_TOOLTIP) {
if (xdg_popup_get_version(data->shell_surface.xdg.roleobj.popup.popup) >= 3) {
SDL_AddEventWatch(Wayland_PopupWatch, window);
}
}
} else {
data->shell_surface.xdg.roleobj.toplevel = xdg_surface_get_toplevel(data->shell_surface.xdg.surface);
xdg_toplevel_set_app_id(data->shell_surface.xdg.roleobj.toplevel, c->classname);
xdg_toplevel_add_listener(data->shell_surface.xdg.roleobj.toplevel, &toplevel_listener_xdg, data);
}
}
/* Restore state that was set prior to this call */
@@ -1079,7 +1232,7 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
* this surface will fail. This is a new rule for xdg_shell.
*/
#ifdef HAVE_LIBDECOR_H
if (c->shell.libdecor) {
if (WINDOW_IS_LIBDECOR(c, window)) {
if (data->shell_surface.libdecor.frame) {
while (!data->shell_surface.libdecor.initial_configure_seen) {
WAYLAND_wl_display_flush(c->display);
@@ -1103,7 +1256,7 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
}
/* Create the window decorations */
if (data->shell_surface.xdg.roleobj.toplevel && c->decoration_manager) {
if (!WINDOW_IS_XDG_POPUP(window) && data->shell_surface.xdg.roleobj.toplevel && c->decoration_manager) {
data->server_decoration = zxdg_decoration_manager_v1_get_toplevel_decoration(c->decoration_manager, data->shell_surface.xdg.roleobj.toplevel);
}
} else {
@@ -1116,11 +1269,11 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
* them immediately afterward.
*/
#ifdef HAVE_LIBDECOR_H
if (c->shell.libdecor) {
if (WINDOW_IS_LIBDECOR(c, window)) {
/* ... but don't call it redundantly for libdecor, the decorator
* may not interpret a redundant call nicely and cause weird stuff to happen
*/
if (window->flags & SDL_WINDOW_BORDERLESS) {
if (data->shell_surface.libdecor.frame && window->flags & SDL_WINDOW_BORDERLESS) {
Wayland_SetWindowBordered(_this, window, SDL_FALSE);
}
} else
@@ -1146,6 +1299,42 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
}
}
static void
Wayland_ReleasePopup(_THIS, SDL_Window *popup)
{
SDL_WindowData *popupdata;
/* Basic sanity checks to weed out the weird popup closures */
if (popup == NULL || popup->magic != &_this->window_magic) {
return;
}
popupdata = popup->driverdata;
if (popupdata == NULL) {
return;
}
/* This may already be freed by a parent popup! */
if (popupdata->shell_surface.xdg.roleobj.popup.popup == NULL) {
return;
}
/* Release the child _first_, otherwise a protocol error triggers */
if (popupdata->shell_surface.xdg.roleobj.popup.child != NULL) {
Wayland_ReleasePopup(_this, popupdata->shell_surface.xdg.roleobj.popup.child);
popupdata->shell_surface.xdg.roleobj.popup.child = NULL;
}
if (popup->flags & SDL_WINDOW_TOOLTIP) {
if (xdg_popup_get_version(popupdata->shell_surface.xdg.roleobj.popup.popup) >= 3) {
SDL_DelEventWatch(Wayland_PopupWatch, popup);
}
}
xdg_popup_destroy(popupdata->shell_surface.xdg.roleobj.popup.popup);
xdg_positioner_destroy(popupdata->shell_surface.xdg.roleobj.popup.positioner);
popupdata->shell_surface.xdg.roleobj.popup.popup = NULL;
popupdata->shell_surface.xdg.roleobj.popup.positioner = NULL;
}
void Wayland_HideWindow(_THIS, SDL_Window *window)
{
SDL_VideoData *data = _this->driverdata;
@@ -1157,7 +1346,7 @@ void Wayland_HideWindow(_THIS, SDL_Window *window)
}
#ifdef HAVE_LIBDECOR_H
if (data->shell.libdecor) {
if (WINDOW_IS_LIBDECOR(data, window)) {
if (wind->shell_surface.libdecor.frame) {
libdecor_frame_unref(wind->shell_surface.libdecor.frame);
wind->shell_surface.libdecor.frame = NULL;
@@ -1165,7 +1354,9 @@ void Wayland_HideWindow(_THIS, SDL_Window *window)
} else
#endif
if (data->shell.xdg) {
if (wind->shell_surface.xdg.roleobj.toplevel) {
if (WINDOW_IS_XDG_POPUP(window)) {
Wayland_ReleasePopup(_this, window);
} else if (wind->shell_surface.xdg.roleobj.toplevel) {
xdg_toplevel_destroy(wind->shell_surface.xdg.roleobj.toplevel);
wind->shell_surface.xdg.roleobj.toplevel = NULL;
}
@@ -1382,13 +1573,17 @@ Wayland_RestoreWindow(_THIS, SDL_Window * window)
SDL_WindowData *wind = window->driverdata;
SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata;
if (WINDOW_IS_XDG_POPUP(window)) {
return;
}
/* Set this flag now even if we never actually maximized, eventually
* ShowWindow will take care of it along with the other window state.
*/
window->flags &= ~SDL_WINDOW_MAXIMIZED;
#ifdef HAVE_LIBDECOR_H
if (viddata->shell.libdecor) {
if (WINDOW_IS_LIBDECOR(viddata, window)) {
if (wind->shell_surface.libdecor.frame == NULL) {
return; /* Can't do anything yet, wait for ShowWindow */
}
@@ -1411,8 +1606,13 @@ Wayland_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
{
SDL_WindowData *wind = window->driverdata;
const SDL_VideoData *viddata = (const SDL_VideoData *) _this->driverdata;
if (WINDOW_IS_XDG_POPUP(window)) {
return;
}
#ifdef HAVE_LIBDECOR_H
if (viddata->shell.libdecor) {
if (WINDOW_IS_LIBDECOR(viddata, window)) {
if (wind->shell_surface.libdecor.frame) {
libdecor_frame_set_visibility(wind->shell_surface.libdecor.frame, bordered);
}
@@ -1431,7 +1631,7 @@ Wayland_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable)
SDL_VideoData *data = _this->driverdata;
const SDL_WindowData *wind = window->driverdata;
if (data->shell.libdecor) {
if (WINDOW_IS_LIBDECOR(data, window)) {
if (wind->shell_surface.libdecor.frame == NULL) {
return; /* Can't do anything yet, wait for ShowWindow */
}
@@ -1453,6 +1653,10 @@ Wayland_MaximizeWindow(_THIS, SDL_Window * window)
SDL_WindowData *wind = window->driverdata;
SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata;
if (WINDOW_IS_XDG_POPUP(window)) {
return;
}
if (!(window->flags & SDL_WINDOW_RESIZABLE)) {
return;
}
@@ -1463,7 +1667,7 @@ Wayland_MaximizeWindow(_THIS, SDL_Window * window)
window->flags |= SDL_WINDOW_MAXIMIZED;
#ifdef HAVE_LIBDECOR_H
if (viddata->shell.libdecor) {
if (WINDOW_IS_LIBDECOR(viddata, window)) {
if (wind->shell_surface.libdecor.frame == NULL) {
return; /* Can't do anything yet, wait for ShowWindow */
}
@@ -1486,8 +1690,12 @@ Wayland_MinimizeWindow(_THIS, SDL_Window * window)
SDL_WindowData *wind = window->driverdata;
SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata;
if (WINDOW_IS_XDG_POPUP(window)) {
return;
}
#ifdef HAVE_LIBDECOR_H
if (viddata->shell.libdecor) {
if (WINDOW_IS_LIBDECOR(viddata, window)) {
if (wind->shell_surface.libdecor.frame == NULL) {
return; /* Can't do anything yet, wait for ShowWindow */
}
@@ -1708,8 +1916,14 @@ Wayland_HandleResize(SDL_Window *window, int width, int height, float scale)
* It doesn't fix the first frames after resize being glitched visually,
* but at least lets us not be terminated by the compositor.
* Can be removed once SDL's resize logic becomes compliant. */
if (viddata->shell.xdg && data->shell_surface.xdg.surface) {
xdg_surface_set_window_geometry(data->shell_surface.xdg.surface, 0, 0, window->w, window->h);
if (
#ifdef HAVE_LIBDECOR_H
!WINDOW_IS_LIBDECOR(viddata, window) &&
#endif
viddata->shell.xdg &&
data->shell_surface.xdg.surface) {
xdg_surface_set_window_geometry(data->shell_surface.xdg.surface, 0, 0,
GetWindowWidth(window), GetWindowHeight(window));
}
/* Update the viewport */
@@ -1739,7 +1953,7 @@ void Wayland_SetWindowSize(_THIS, SDL_Window * window)
#ifdef HAVE_LIBDECOR_H
/* we must not resize the window while we have a static (non-floating) size */
if (data->shell.libdecor &&
if (WINDOW_IS_LIBDECOR(data, window) &&
wind->shell_surface.libdecor.frame &&
!libdecor_frame_is_floating(wind->shell_surface.libdecor.frame)) {
/* Commit the resize when we re-enter floating state */
@@ -1758,8 +1972,8 @@ void Wayland_SetWindowSize(_THIS, SDL_Window * window)
}
#ifdef HAVE_LIBDECOR_H
if (data->shell.libdecor && wind->shell_surface.libdecor.frame) {
state = libdecor_state_new(window->w, window->h);
if (WINDOW_IS_LIBDECOR(data, window) && wind->shell_surface.libdecor.frame) {
state = libdecor_state_new(GetWindowWidth(window), GetWindowHeight(window));
libdecor_frame_commit(wind->shell_surface.libdecor.frame, state, NULL);
libdecor_state_free(state);
}
@@ -1775,8 +1989,14 @@ void Wayland_SetWindowSize(_THIS, SDL_Window * window)
wl_region_destroy(region);
/* Update the geometry which may have been set by a hack in Wayland_HandleResize */
if (data->shell.xdg && wind->shell_surface.xdg.surface) {
xdg_surface_set_window_geometry(wind->shell_surface.xdg.surface, 0, 0, window->w, window->h);
if (
#ifdef HAVE_LIBDECOR_H
!WINDOW_IS_LIBDECOR(data, window) &&
#endif
data->shell.xdg &&
wind->shell_surface.xdg.surface) {
xdg_surface_set_window_geometry(wind->shell_surface.xdg.surface, 0, 0,
GetWindowWidth(window), GetWindowHeight(window));
}
}
@@ -1785,9 +2005,13 @@ void Wayland_SetWindowTitle(_THIS, SDL_Window * window)
SDL_WindowData *wind = window->driverdata;
SDL_VideoData *viddata = _this->driverdata;
if (WINDOW_IS_XDG_POPUP(window)) {
return;
}
if (window->title != NULL) {
#ifdef HAVE_LIBDECOR_H
if (viddata->shell.libdecor) {
if (WINDOW_IS_LIBDECOR(viddata, window)) {
if (wind->shell_surface.libdecor.frame == NULL) {
return; /* Can't do anything yet, wait for ShowWindow */
}

View File

@@ -36,16 +36,27 @@ typedef struct {
struct xdg_surface *surface;
union {
struct xdg_toplevel *toplevel;
struct xdg_popup *popup;
struct {
struct xdg_popup *popup;
struct xdg_positioner *positioner;
Uint32 parentID;
SDL_Window *child;
} popup;
} roleobj;
SDL_bool initial_configure_seen;
} SDL_xdg_shell_surface;
#define WINDOW_IS_XDG_POPUP(window) \
(window->flags & (SDL_WINDOW_TOOLTIP | SDL_WINDOW_POPUP_MENU))
#ifdef HAVE_LIBDECOR_H
typedef struct {
struct libdecor_frame *frame;
SDL_bool initial_configure_seen;
} SDL_libdecor_surface;
#define WINDOW_IS_LIBDECOR(viddata, window) \
(viddata->shell.libdecor && !WINDOW_IS_XDG_POPUP(window))
#endif
typedef struct {
@@ -117,7 +128,6 @@ extern int Wayland_SetWindowModalFor(_THIS, SDL_Window * modal_window, SDL_Windo
extern void Wayland_SetWindowTitle(_THIS, SDL_Window * window);
extern void Wayland_DestroyWindow(_THIS, SDL_Window *window);
extern void Wayland_SuspendScreenSaver(_THIS);
extern int Wayland_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
extern SDL_bool
Wayland_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info);

View File

@@ -158,7 +158,7 @@ WIN_SetWindowPositionInternal(_THIS, SDL_Window * window, UINT flags)
int w, h;
/* Figure out what the window area will be */
if (SDL_ShouldAllowTopmost() && ((window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS)) == (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS) || (window->flags & SDL_WINDOW_ALWAYS_ON_TOP))) {
if (SDL_ShouldAllowTopmost() && (window->flags & SDL_WINDOW_ALWAYS_ON_TOP)) {
top = HWND_TOPMOST;
} else {
top = HWND_NOTOPMOST;
@@ -741,7 +741,7 @@ WIN_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display,
return;
}
if (SDL_ShouldAllowTopmost() && ((window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS)) == (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS) || window->flags & SDL_WINDOW_ALWAYS_ON_TOP)) {
if (SDL_ShouldAllowTopmost() && (window->flags & SDL_WINDOW_ALWAYS_ON_TOP)) {
top = HWND_TOPMOST;
} else {
top = HWND_NOTOPMOST;

View File

@@ -733,7 +733,6 @@ static void
X11_DispatchEvent(_THIS, XEvent *xevent)
{
SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
XkbEvent* xkbEvent = (XkbEvent*) xevent;
Display *display;
SDL_WindowData *data;
int orig_event_type;
@@ -820,11 +819,13 @@ X11_DispatchEvent(_THIS, XEvent *xevent)
if (!data) {
/* The window for KeymapNotify, etc events is 0 */
if (xevent->type == KeymapNotify) {
#ifdef DEBUG_XEVENTS
printf("window %p: KeymapNotify!\n", data);
#endif
if (SDL_GetKeyboardFocus() != NULL) {
X11_ReconcileKeyboardState(_this);
}
} else if (xevent->type == MappingNotify ||
(xevent->type == videodata->xkb_event && xkbEvent->any.xkb_type == XkbStateNotify)) {
} else if (xevent->type == MappingNotify) {
/* Has the keyboard layout changed? */
const int request = xevent->xmapping.request;
@@ -1021,7 +1022,7 @@ X11_DispatchEvent(_THIS, XEvent *xevent)
SDL_bool handled_by_ime = SDL_FALSE;
#ifdef DEBUG_XEVENTS
printf("window %p: %s (X11 keycode = 0x%X)\n" data, (xevent->type == KeyPress ? "KeyPress" : "KeyRelease"), xevent->xkey.keycode);
printf("window %p: %s (X11 keycode = 0x%X)\n", data, (xevent->type == KeyPress ? "KeyPress" : "KeyRelease"), xevent->xkey.keycode);
#endif
#if 1
if (videodata->key_layout[keycode] == SDL_SCANCODE_UNKNOWN && keycode) {
@@ -1449,11 +1450,15 @@ X11_DispatchEvent(_THIS, XEvent *xevent)
}
}
/* FULLSCREEN_DESKTOP encompasses two bits: SDL_WINDOW_FULLSCREEN, plus a bit to note it's FULLSCREEN_DESKTOP */
if (changed & SDL_WINDOW_FULLSCREEN_DESKTOP) {
/* FULLSCREEN_DESKTOP encompasses two bits: SDL_WINDOW_FULLSCREEN, plus a bit to note it's FULLSCREEN_DESKTOP */
SDL_VideoDisplay *viddisplay = SDL_GetDisplayForWindow(data->window);
const Uint32 fsmasked = flags & SDL_WINDOW_FULLSCREEN_DESKTOP;
data->window->flags &= ~SDL_WINDOW_FULLSCREEN_DESKTOP;
data->window->flags |= fsmasked;
if (viddisplay) {
viddisplay->fullscreen_window = fsmasked ? data->window : NULL;
}
}
if (changed & SDL_WINDOW_MAXIMIZED) {

View File

@@ -185,7 +185,6 @@ SDL_X11_SYM(XkbDescPtr,XkbGetMap,(Display* a,unsigned int b,unsigned int c),(a,b
SDL_X11_SYM(void,XkbFreeClientMap,(XkbDescPtr a,unsigned int b, Bool c),(a,b,c),)
SDL_X11_SYM(void,XkbFreeKeyboard,(XkbDescPtr a,unsigned int b, Bool c),(a,b,c),)
SDL_X11_SYM(Bool,XkbSetDetectableAutoRepeat,(Display* a, Bool b, Bool* c),(a,b,c),return)
SDL_X11_SYM(Bool,XkbSelectEvents,(Display* a, unsigned int b, unsigned int c, unsigned int d),(a,b,c,d),return)
#endif
#if NeedWidePrototypes

View File

@@ -678,8 +678,6 @@ X11_CreateWindow(_THIS, SDL_Window * window)
/* For _ICC_PROFILE. */
X11_XSelectInput(display, RootWindow(display, screen), PropertyChangeMask);
X11_XkbSelectEvents(display, XkbUseCoreKbd, XkbStateNotifyMask, XkbStateNotifyMask);
X11_XFlush(display);
return 0;

View File

@@ -364,6 +364,7 @@ DATA = \
testgles2_sdf_img_sdf.bmp \
testyuv.bmp \
unifont-13.0.06.hex \
utf8.txt \
$(NULL)
ifneq ($(srcdir), .)

View File

@@ -408,6 +408,32 @@ void _validateRectEqualsResults(
refRectB->x, refRectB->y, refRectB->w, refRectB->h);
}
/* !
* \brief Private helper to check SDL_FRectEquals results
*/
void _validateFRectEqualsResults(
SDL_bool equals, SDL_bool expectedEquals,
SDL_FRect *rectA, SDL_FRect *rectB, SDL_FRect *refRectA, SDL_FRect *refRectB)
{
int cmpRes;
SDLTest_AssertCheck(equals == expectedEquals,
"Check for correct equals result: expected %s, got %s testing (%f,%f,%f,%f) and (%f,%f,%f,%f)",
(expectedEquals == SDL_TRUE) ? "SDL_TRUE" : "SDL_FALSE",
(equals == SDL_TRUE) ? "SDL_TRUE" : "SDL_FALSE",
rectA->x, rectA->y, rectA->w, rectA->h,
rectB->x, rectB->y, rectB->w, rectB->h);
cmpRes = SDL_memcmp(rectA, refRectA, sizeof(*rectA));
SDLTest_AssertCheck(cmpRes == 0,
"Check that source rectangle A was not modified: got (%f,%f,%f,%f) expected (%f,%f,%f,%f)",
rectA->x, rectA->y, rectA->w, rectA->h,
refRectA->x, refRectA->y, refRectA->w, refRectA->h);
cmpRes = SDL_memcmp(rectB, refRectB, sizeof(*rectB));
SDLTest_AssertCheck(cmpRes == 0,
"Check that source rectangle B was not modified: got (%f,%f,%f,%f) expected (%f,%f,%f,%f)",
rectB->x, rectB->y, rectB->w, rectB->h,
refRectB->x, refRectB->y, refRectB->w, refRectB->h);
}
/* !
* \brief Tests SDL_IntersectRect() with B fully inside A
*
@@ -1574,6 +1600,69 @@ int rect_testRectEqualsParam(void *arg)
return TEST_COMPLETED;
}
/* !
* \brief Tests SDL_FRectEquals() with various inputs
*
* \sa
* http://wiki.libsdl.org/SDL_FRectEquals
*/
int rect_testFRectEquals(void *arg)
{
SDL_FRect refRectA;
SDL_FRect refRectB;
SDL_FRect rectA;
SDL_FRect rectB;
SDL_bool expectedResult;
SDL_bool result;
/* Equals */
refRectA.x=(float)SDLTest_RandomIntegerInRange(-1024, 1024);
refRectA.y=(float)SDLTest_RandomIntegerInRange(-1024, 1024);
refRectA.w=(float)SDLTest_RandomIntegerInRange(1, 1024);
refRectA.h=(float)SDLTest_RandomIntegerInRange(1, 1024);
refRectB = refRectA;
expectedResult = SDL_TRUE;
rectA = refRectA;
rectB = refRectB;
result = (SDL_bool)SDL_FRectEquals((const SDL_FRect *)&rectA, (const SDL_FRect *)&rectB);
_validateFRectEqualsResults(result, expectedResult, &rectA, &rectB, &refRectA, &refRectB);
return TEST_COMPLETED;
}
/* !
* \brief Negative tests against SDL_FRectEquals() with invalid parameters
*
* \sa
* http://wiki.libsdl.org/SDL_FRectEquals
*/
int rect_testFRectEqualsParam(void *arg)
{
SDL_FRect rectA;
SDL_FRect rectB;
SDL_bool result;
/* data setup -- For the purpose of this test, the values don't matter. */
rectA.x=SDLTest_RandomFloat();
rectA.y=SDLTest_RandomFloat();
rectA.w=SDLTest_RandomFloat();
rectA.h=SDLTest_RandomFloat();
rectB.x=SDLTest_RandomFloat();
rectB.y=SDLTest_RandomFloat();
rectB.w=SDLTest_RandomFloat();
rectB.h=SDLTest_RandomFloat();
/* invalid parameter combinations */
result = (SDL_bool)SDL_FRectEquals((const SDL_FRect *)NULL, (const SDL_FRect *)&rectB);
SDLTest_AssertCheck(result == SDL_FALSE, "Check that function returns SDL_FALSE when 1st parameter is NULL");
result = (SDL_bool)SDL_FRectEquals((const SDL_FRect *)&rectA, (const SDL_FRect *)NULL);
SDLTest_AssertCheck(result == SDL_FALSE, "Check that function returns SDL_FALSE when 2nd parameter is NULL");
result = (SDL_bool)SDL_FRectEquals((const SDL_FRect *)NULL, (const SDL_FRect *)NULL);
SDLTest_AssertCheck(result == SDL_FALSE, "Check that function returns SDL_FALSE when 1st and 2nd parameter are NULL");
return TEST_COMPLETED;
}
/* ================= Test References ================== */
/* Rect test cases */
@@ -1673,6 +1762,13 @@ static const SDLTest_TestCaseReference rectTest28 =
static const SDLTest_TestCaseReference rectTest29 =
{ (SDLTest_TestCaseFp)rect_testRectEqualsParam, "rect_testRectEqualsParam", "Negative tests against SDL_RectEquals with invalid parameters", TEST_ENABLED };
/* SDL_FRectEquals */
static const SDLTest_TestCaseReference rectTest30 =
{ (SDLTest_TestCaseFp)rect_testFRectEquals, "rect_testFRectEquals", "Tests SDL_FRectEquals with various inputs", TEST_ENABLED };
static const SDLTest_TestCaseReference rectTest31 =
{ (SDLTest_TestCaseFp)rect_testFRectEqualsParam, "rect_testFRectEqualsParam", "Negative tests against SDL_FRectEquals with invalid parameters", TEST_ENABLED };
/* !
* \brief Sequence of Rect test cases; functions that handle simple rectangles including overlaps and merges.
@@ -1683,7 +1779,7 @@ static const SDLTest_TestCaseReference rectTest29 =
static const SDLTest_TestCaseReference *rectTests[] = {
&rectTest1, &rectTest2, &rectTest3, &rectTest4, &rectTest5, &rectTest6, &rectTest7, &rectTest8, &rectTest9, &rectTest10, &rectTest11, &rectTest12, &rectTest13, &rectTest14,
&rectTest15, &rectTest16, &rectTest17, &rectTest18, &rectTest19, &rectTest20, &rectTest21, &rectTest22, &rectTest23, &rectTest24, &rectTest25, &rectTest26, &rectTest27,
&rectTest28, &rectTest29, NULL
&rectTest28, &rectTest29, &rectTest30, &rectTest31, NULL
};

View File

@@ -41,6 +41,7 @@ static const struct
CLS(SOUND),
CLS(TOUCHSCREEN),
CLS(ACCELEROMETER),
CLS(TOUCHPAD),
#undef CLS
{ 0, NULL }
};
@@ -185,9 +186,7 @@ static const GuessTest guess_tests[] =
.bus_type = 0x0003,
.vendor_id = 0x054c,
.product_id = 0x09cc,
/* TODO: Should this be MOUSE? That's what it most closely
* resembles */
.expected = SDL_UDEV_DEVICE_UNKNOWN,
.expected = SDL_UDEV_DEVICE_TOUCHPAD,
/* SYN, KEY, ABS */
.ev = { 0x0b },
/* X, Y, multitouch */
@@ -596,7 +595,7 @@ static const GuessTest guess_tests[] =
* to the arrow, page up and page down keys, so it's a joystick
* with a subset of a keyboard attached. */
/* TODO: Should this be JOYSTICK, or even JOYSTICK|KEYBOARD? */
.expected = SDL_UDEV_DEVICE_UNKNOWN,
.expected = SDL_UDEV_DEVICE_KEYBOARD,
/* SYN, KEY */
.ev = { 0x03 },
.keys = {
@@ -608,7 +607,7 @@ static const GuessTest guess_tests[] =
/* BTN_1, BTN_2, BTN_A, BTN_B, BTN_MODE */
/* 0x100 */ 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x10,
/* 0x140 */ ZEROx8,
/* next, previous */
/* next (keyboard page down), previous (keyboard page up) */
/* 0x180 */ 0x00, 0x00, 0x80, 0x10, ZEROx4,
},
},
@@ -659,7 +658,7 @@ static const GuessTest guess_tests[] =
.name = "Wiimote - Classic Controller",
/* TODO: Should this be JOYSTICK, or maybe JOYSTICK|KEYBOARD?
* It's unusual in the same ways as the Wiimote */
.expected = SDL_UDEV_DEVICE_UNKNOWN,
.expected = SDL_UDEV_DEVICE_KEYBOARD,
/* SYN, KEY, ABS */
.ev = { 0x0b },
/* Hat 1-3 */
@@ -673,7 +672,7 @@ static const GuessTest guess_tests[] =
/* A, B, X, Y, MODE, TL, TL2, TR, TR2 */
/* 0x100 */ ZEROx4, 0x00, 0x13, 0xdb, 0x10,
/* 0x140 */ ZEROx8,
/* next, previous */
/* next (keyboard page down), previous (keyboard page up) */
/* 0x180 */ 0x00, 0x00, 0x80, 0x10, ZEROx4,
},
},
@@ -718,9 +717,7 @@ static const GuessTest guess_tests[] =
.vendor_id = 0x06cb,
.product_id = 0x0000,
.version = 0x0000,
/* TODO: Should this be MOUSE? That's what it most closely
* resembles */
.expected = SDL_UDEV_DEVICE_UNKNOWN,
.expected = SDL_UDEV_DEVICE_TOUCHPAD,
/* SYN, KEY, ABS */
.ev = { 0x0b },
/* X, Y, pressure, multitouch */
@@ -756,7 +753,8 @@ static const GuessTest guess_tests[] =
},
{
.name = "Thinkpad ACPI buttons",
.expected = SDL_UDEV_DEVICE_UNKNOWN,
/* SDL treats this as a keyboard because it has a power button */
.expected = SDL_UDEV_DEVICE_KEYBOARD,
/* SYN, KEY, MSC, SW */
.ev = { 0x33 },
.keys = {
@@ -815,7 +813,8 @@ static const GuessTest guess_tests[] =
.vendor_id = 0x0000,
.product_id = 0x0003,
.version = 0x0000,
.expected = SDL_UDEV_DEVICE_UNKNOWN,
/* SDL treats KEY_SLEEP as indicating a keyboard */
.expected = SDL_UDEV_DEVICE_KEYBOARD,
/* SYN, KEY */
.ev = { 0x03 },
.keys = {
@@ -841,7 +840,8 @@ static const GuessTest guess_tests[] =
.vendor_id = 0x0000,
.product_id = 0x0001,
.version = 0x0000,
.expected = SDL_UDEV_DEVICE_UNKNOWN,
/* SDL treats KEY_POWER as indicating a keyboard */
.expected = SDL_UDEV_DEVICE_KEYBOARD,
/* SYN, KEY */
.ev = { 0x03 },
.keys = {
@@ -856,7 +856,8 @@ static const GuessTest guess_tests[] =
.vendor_id = 0x0000,
.product_id = 0x0006,
.version = 0x0000,
.expected = SDL_UDEV_DEVICE_UNKNOWN,
/* SDL treats brightness control, etc. as keyboard keys */
.expected = SDL_UDEV_DEVICE_KEYBOARD,
/* SYN, KEY */
.ev = { 0x03 },
.keys = {
@@ -873,7 +874,7 @@ static const GuessTest guess_tests[] =
.vendor_id = 0x17aa,
.product_id = 0x5054,
.version = 0x4101,
.expected = SDL_UDEV_DEVICE_UNKNOWN,
.expected = SDL_UDEV_DEVICE_KEYBOARD,
/* SYN, KEY */
.ev = { 0x03 },
.keys = {
@@ -911,9 +912,8 @@ static const GuessTest guess_tests[] =
.product_id = 0x6009,
/* For some reason the special keys like mute and wlan toggle
* show up here instead of, or in addition to, as part of
* the keyboard - so udev reports this as having keys too.
* SDL currently doesn't. */
.expected = SDL_UDEV_DEVICE_MOUSE,
* the keyboard - so both udev and SDL report this as having keys too. */
.expected = SDL_UDEV_DEVICE_MOUSE | SDL_UDEV_DEVICE_KEYBOARD,
/* SYN, KEY, REL, MSC, LED */
.ev = { 0x17, 0x00, 0x02 },
/* X, Y */