From d11cea7aed252d4edc9fad5781591c72f9cd49a3 Mon Sep 17 00:00:00 2001 From: lhdjply Date: Tue, 14 Jan 2025 15:11:48 +0800 Subject: [PATCH] feat: update libsdl2 to 2.30.11+dfsg Signed-off-by: lhdjply --- .clang-format | 90 + .editorconfig | 79 + .git-hash | 1 + .wikiheaders-options | 17 + CMakeLists.txt | 75 +- LICENSE.txt | 2 +- Makefile.in | 2 +- Makefile.os2 | 2 +- Makefile.w32 | 2 +- REVISION.txt | 1 + SDL2.spec | 119 - VERSION.txt | 1 - android-project-ant/AndroidManifest.xml | 1 + android-project-ant/ant.properties | 17 + android-project-ant/build.properties | 17 + android-project-ant/build.xml | 93 + android-project-ant/default.properties | 11 + android-project-ant/jni/Android.mk | 1 + android-project-ant/jni/Application.mk | 10 + android-project-ant/jni/src/Android.mk | 18 + android-project-ant/jni/src/Android_static.mk | 12 + android-project-ant/proguard-project.txt | 20 + android-project-ant/project.properties | 14 + .../res/drawable-hdpi/ic_launcher.png | Bin 0 -> 2683 bytes .../res/drawable-mdpi/ic_launcher.png | Bin 0 -> 1698 bytes .../res/drawable-xhdpi/ic_launcher.png | Bin 0 -> 3872 bytes .../res/drawable-xxhdpi/ic_launcher.png | Bin 0 -> 6874 bytes android-project-ant/res/layout/main.xml | 13 + android-project-ant/res/values/strings.xml | 4 + android-project-ant/src | 1 + build-scripts/build-release.py | 1470 ++++++ .../cmake-toolchain-mingw64-i686.cmake | 18 + .../cmake-toolchain-mingw64-x86_64.cmake | 18 + build-scripts/create-release.py | 43 + build-scripts/gen_audio_channel_conversion.c | 4 +- build-scripts/gen_audio_resampler_filter.c | 4 +- build-scripts/release-info.json | 108 + build-scripts/setup-gdk-desktop.py | 303 ++ cmake/sdlchecks.cmake | 5 +- cmake/test/CMakeLists.txt | 26 + cmake/test/jni/Android.mk | 11 + cmake/test/sdltest.c | 9 + configure | 149 +- configure.ac | 101 +- debian/changelog | 263 + debian/control | 13 +- debian/copyright | 3 +- debian/gbp.conf | 15 - debian/libsdl2-doc.doc-base | 3 - debian/rules | 8 + debian/salsa-ci.yml | 3 +- debian/tests/build | 8 +- debian/tests/control | 4 +- docs/README-macos.md | 8 +- include/SDL.h | 2 +- include/SDL_assert.h | 2 +- include/SDL_atomic.h | 2 +- include/SDL_audio.h | 4 +- include/SDL_bits.h | 2 +- include/SDL_blendmode.h | 2 +- include/SDL_clipboard.h | 2 +- include/SDL_config.h | 2 +- include/SDL_config.h.cmake | 4 +- include/SDL_config.h.in | 4 +- include/SDL_config_android.h | 2 +- include/SDL_config_emscripten.h | 2 +- include/SDL_config_iphoneos.h | 2 +- include/SDL_config_macosx.h | 2 +- include/SDL_config_minimal.h | 2 +- include/SDL_config_ngage.h | 2 +- include/SDL_config_os2.h | 5 +- include/SDL_config_pandora.h | 2 +- include/SDL_config_windows.h | 6 +- include/SDL_config_wingdk.h | 2 +- include/SDL_config_winrt.h | 2 +- include/SDL_config_xbox.h | 2 +- include/SDL_copying.h | 2 +- include/SDL_cpuinfo.h | 4 +- include/SDL_egl.h | 2 +- include/SDL_endian.h | 2 +- include/SDL_error.h | 2 +- include/SDL_events.h | 2 +- include/SDL_filesystem.h | 2 +- include/SDL_gamecontroller.h | 2 +- include/SDL_gesture.h | 2 +- include/SDL_guid.h | 2 +- include/SDL_haptic.h | 2 +- include/SDL_hidapi.h | 2 +- include/SDL_hints.h | 17 +- include/SDL_joystick.h | 17 +- include/SDL_keyboard.h | 2 +- include/SDL_keycode.h | 2 +- include/SDL_loadso.h | 2 +- include/SDL_locale.h | 2 +- include/SDL_log.h | 2 +- include/SDL_main.h | 2 +- include/SDL_messagebox.h | 2 +- include/SDL_metal.h | 2 +- include/SDL_misc.h | 2 +- include/SDL_mouse.h | 2 +- include/SDL_mutex.h | 2 +- include/SDL_name.h | 2 +- include/SDL_opengl.h | 2 +- include/SDL_opengles.h | 2 +- include/SDL_opengles2.h | 2 +- include/SDL_pixels.h | 2 +- include/SDL_platform.h | 12 +- include/SDL_power.h | 2 +- include/SDL_quit.h | 2 +- include/SDL_rect.h | 2 +- include/SDL_render.h | 2 +- include/SDL_revision.h | 5 +- include/SDL_rwops.h | 2 +- include/SDL_scancode.h | 2 +- include/SDL_sensor.h | 2 +- include/SDL_shape.h | 2 +- include/SDL_stdinc.h | 33 +- include/SDL_surface.h | 2 +- include/SDL_system.h | 2 +- include/SDL_syswm.h | 2 +- include/SDL_test.h | 2 +- include/SDL_test_assert.h | 2 +- include/SDL_test_common.h | 2 +- include/SDL_test_compare.h | 2 +- include/SDL_test_crc32.h | 2 +- include/SDL_test_font.h | 2 +- include/SDL_test_fuzzer.h | 2 +- include/SDL_test_harness.h | 2 +- include/SDL_test_images.h | 2 +- include/SDL_test_log.h | 2 +- include/SDL_test_md5.h | 2 +- include/SDL_test_memory.h | 2 +- include/SDL_test_random.h | 2 +- include/SDL_thread.h | 2 +- include/SDL_timer.h | 2 +- include/SDL_touch.h | 2 +- include/SDL_types.h | 2 +- include/SDL_version.h | 4 +- include/SDL_video.h | 2 +- include/SDL_vulkan.h | 4 + include/begin_code.h | 2 +- include/close_code.h | 2 +- mingw/pkg-support/INSTALL.txt | 18 + mingw/pkg-support/Makefile | 37 + src/SDL.c | 58 +- src/SDL_assert.c | 6 +- src/SDL_assert_c.h | 2 +- src/SDL_dataqueue.c | 2 +- src/SDL_dataqueue.h | 2 +- src/SDL_error.c | 2 +- src/SDL_error_c.h | 2 +- src/SDL_guid.c | 2 +- src/SDL_hints.c | 6 +- src/SDL_hints_c.h | 2 +- src/SDL_internal.h | 84 +- src/SDL_list.c | 2 +- src/SDL_list.h | 2 +- src/SDL_log.c | 2 +- src/SDL_log_c.h | 2 +- src/SDL_utils.c | 2 +- src/SDL_utils_c.h | 2 +- src/atomic/SDL_atomic.c | 2 +- src/atomic/SDL_spinlock.c | 2 +- src/audio/SDL_audio.c | 12 +- src/audio/SDL_audio_c.h | 2 +- src/audio/SDL_audio_channel_converters.h | 2 +- src/audio/SDL_audio_resampler_filter.h | 2 +- src/audio/SDL_audiocvt.c | 2 +- src/audio/SDL_audiodev.c | 2 +- src/audio/SDL_audiodev_c.h | 2 +- src/audio/SDL_audiotypecvt.c | 6 +- src/audio/SDL_mixer.c | 2 +- src/audio/SDL_sysaudio.h | 2 +- src/audio/SDL_wave.c | 2 +- src/audio/SDL_wave.h | 2 +- src/audio/aaudio/SDL_aaudio.c | 4 +- src/audio/aaudio/SDL_aaudio.h | 2 +- src/audio/aaudio/SDL_aaudiofuncs.h | 4 +- src/audio/alsa/SDL_alsa_audio.c | 2 +- src/audio/alsa/SDL_alsa_audio.h | 2 +- src/audio/android/SDL_androidaudio.c | 2 +- src/audio/android/SDL_androidaudio.h | 2 +- src/audio/arts/SDL_artsaudio.c | 6 +- src/audio/arts/SDL_artsaudio.h | 2 +- src/audio/coreaudio/SDL_coreaudio.h | 2 +- src/audio/coreaudio/SDL_coreaudio.m | 24 +- src/audio/directsound/SDL_directsound.c | 2 +- src/audio/directsound/SDL_directsound.h | 2 +- src/audio/disk/SDL_diskaudio.c | 2 +- src/audio/disk/SDL_diskaudio.h | 2 +- src/audio/dsp/SDL_dspaudio.c | 2 +- src/audio/dsp/SDL_dspaudio.h | 2 +- src/audio/dummy/SDL_dummyaudio.c | 2 +- src/audio/dummy/SDL_dummyaudio.h | 2 +- src/audio/emscripten/SDL_emscriptenaudio.c | 14 +- src/audio/emscripten/SDL_emscriptenaudio.h | 2 +- src/audio/esd/SDL_esdaudio.c | 6 +- src/audio/esd/SDL_esdaudio.h | 2 +- src/audio/fusionsound/SDL_fsaudio.c | 6 +- src/audio/fusionsound/SDL_fsaudio.h | 2 +- src/audio/haiku/SDL_haikuaudio.cc | 2 +- src/audio/haiku/SDL_haikuaudio.h | 2 +- src/audio/jack/SDL_jackaudio.c | 2 +- src/audio/jack/SDL_jackaudio.h | 2 +- src/audio/n3ds/SDL_n3dsaudio.c | 2 +- src/audio/n3ds/SDL_n3dsaudio.h | 2 +- src/audio/nacl/SDL_naclaudio.c | 2 +- src/audio/nacl/SDL_naclaudio.h | 2 +- src/audio/nas/SDL_nasaudio.c | 2 +- src/audio/nas/SDL_nasaudio.h | 2 +- src/audio/netbsd/SDL_netbsdaudio.c | 2 +- src/audio/netbsd/SDL_netbsdaudio.h | 2 +- src/audio/openslES/SDL_openslES.c | 2 +- src/audio/openslES/SDL_openslES.h | 2 +- src/audio/os2/SDL_os2audio.c | 2 +- src/audio/os2/SDL_os2audio.h | 2 +- src/audio/paudio/SDL_paudio.c | 2 +- src/audio/paudio/SDL_paudio.h | 2 +- src/audio/pipewire/SDL_pipewire.c | 30 +- src/audio/pipewire/SDL_pipewire.h | 2 +- src/audio/ps2/SDL_ps2audio.c | 2 +- src/audio/ps2/SDL_ps2audio.h | 2 +- src/audio/psp/SDL_pspaudio.c | 2 +- src/audio/psp/SDL_pspaudio.h | 2 +- src/audio/pulseaudio/SDL_pulseaudio.c | 12 +- src/audio/pulseaudio/SDL_pulseaudio.h | 2 +- src/audio/qsa/SDL_qsa_audio.c | 2 +- src/audio/qsa/SDL_qsa_audio.h | 2 +- src/audio/sndio/SDL_sndioaudio.c | 2 +- src/audio/sndio/SDL_sndioaudio.h | 2 +- src/audio/sun/SDL_sunaudio.c | 2 +- src/audio/sun/SDL_sunaudio.h | 2 +- src/audio/vita/SDL_vitaaudio.c | 2 +- src/audio/vita/SDL_vitaaudio.h | 2 +- src/audio/wasapi/SDL_wasapi.c | 8 +- src/audio/wasapi/SDL_wasapi.h | 2 +- src/audio/wasapi/SDL_wasapi_win32.c | 2 +- src/audio/wasapi/SDL_wasapi_winrt.cpp | 2 +- src/audio/winmm/SDL_winmm.c | 2 +- src/audio/winmm/SDL_winmm.h | 2 +- src/core/android/SDL_android.c | 18 +- src/core/android/SDL_android.h | 2 +- src/core/freebsd/SDL_evdev_kbd_freebsd.c | 4 +- src/core/gdk/SDL_gdk.cpp | 23 +- src/core/gdk/SDL_gdk.h | 2 +- src/core/linux/SDL_dbus.c | 2 +- src/core/linux/SDL_dbus.h | 2 +- src/core/linux/SDL_evdev.c | 2 +- src/core/linux/SDL_evdev.h | 2 +- src/core/linux/SDL_evdev_capabilities.c | 2 +- src/core/linux/SDL_evdev_capabilities.h | 2 +- src/core/linux/SDL_evdev_kbd.c | 4 +- src/core/linux/SDL_evdev_kbd.h | 2 +- .../linux/SDL_evdev_kbd_default_accents.h | 2 +- src/core/linux/SDL_evdev_kbd_default_keymap.h | 2 +- src/core/linux/SDL_fcitx.c | 9 +- src/core/linux/SDL_fcitx.h | 2 +- src/core/linux/SDL_ibus.c | 2 +- src/core/linux/SDL_ibus.h | 2 +- src/core/linux/SDL_ime.c | 6 +- src/core/linux/SDL_ime.h | 2 +- src/core/linux/SDL_sandbox.c | 2 +- src/core/linux/SDL_sandbox.h | 2 +- src/core/linux/SDL_threadprio.c | 8 +- src/core/linux/SDL_udev.c | 81 +- src/core/linux/SDL_udev.h | 2 +- src/core/openbsd/SDL_wscons.h | 2 +- src/core/openbsd/SDL_wscons_kbd.c | 8 +- src/core/openbsd/SDL_wscons_mouse.c | 2 +- src/core/os2/SDL_os2.c | 2 +- src/core/os2/SDL_os2.h | 2 +- src/core/os2/geniconv/geniconv.c | 2 +- src/core/os2/geniconv/geniconv.h | 2 +- src/core/os2/geniconv/os2cp.c | 2 +- src/core/os2/geniconv/os2cp.h | 2 +- src/core/os2/geniconv/os2iconv.c | 2 +- src/core/os2/geniconv/sys2utf8.c | 2 +- src/core/os2/geniconv/test.c | 2 +- src/core/unix/SDL_poll.c | 2 +- src/core/unix/SDL_poll.h | 2 +- src/core/windows/SDL_directx.h | 2 +- src/core/windows/SDL_hid.c | 2 +- src/core/windows/SDL_hid.h | 2 +- src/core/windows/SDL_immdevice.c | 2 +- src/core/windows/SDL_immdevice.h | 2 +- src/core/windows/SDL_windows.c | 2 +- src/core/windows/SDL_windows.h | 14 +- src/core/windows/SDL_xinput.c | 2 +- src/core/windows/SDL_xinput.h | 8 +- src/core/winrt/SDL_winrtapp_common.cpp | 2 +- src/core/winrt/SDL_winrtapp_common.h | 2 +- src/core/winrt/SDL_winrtapp_direct3d.cpp | 6 +- src/core/winrt/SDL_winrtapp_direct3d.h | 2 +- src/core/winrt/SDL_winrtapp_xaml.cpp | 2 +- src/core/winrt/SDL_winrtapp_xaml.h | 2 +- src/cpuinfo/SDL_cpuinfo.c | 4 +- src/dynapi/SDL_dynapi.c | 2 +- src/dynapi/SDL_dynapi.h | 2 +- src/dynapi/SDL_dynapi_overrides.h | 2 +- src/dynapi/SDL_dynapi_procs.h | 2 +- src/dynapi/gendynapi.pl | 11 +- src/events/SDL_clipboardevents.c | 2 +- src/events/SDL_clipboardevents_c.h | 2 +- src/events/SDL_displayevents.c | 2 +- src/events/SDL_displayevents_c.h | 2 +- src/events/SDL_dropevents.c | 2 +- src/events/SDL_dropevents_c.h | 2 +- src/events/SDL_events.c | 19 +- src/events/SDL_events_c.h | 2 +- src/events/SDL_gesture.c | 2 +- src/events/SDL_gesture_c.h | 2 +- src/events/SDL_keyboard.c | 2 +- src/events/SDL_keyboard_c.h | 2 +- src/events/SDL_keysym_to_scancode.c | 2 +- src/events/SDL_keysym_to_scancode_c.h | 2 +- src/events/SDL_mouse.c | 17 +- src/events/SDL_mouse_c.h | 3 +- src/events/SDL_quit.c | 2 +- src/events/SDL_scancode_tables.c | 2 +- src/events/SDL_scancode_tables_c.h | 2 +- src/events/SDL_touch.c | 2 +- src/events/SDL_touch_c.h | 2 +- src/events/SDL_windowevents.c | 2 +- src/events/SDL_windowevents_c.h | 2 +- src/events/blank_cursor.h | 2 +- src/events/default_cursor.h | 2 +- src/events/scancodes_ascii.h | 2 +- src/events/scancodes_darwin.h | 2 +- src/events/scancodes_linux.h | 2 +- src/events/scancodes_windows.h | 2 +- src/events/scancodes_xfree86.h | 2 +- src/file/SDL_rwops.c | 25 +- src/file/cocoa/SDL_rwopsbundlesupport.h | 2 +- src/file/cocoa/SDL_rwopsbundlesupport.m | 2 +- src/file/n3ds/SDL_rwopsromfs.c | 2 +- src/file/n3ds/SDL_rwopsromfs.h | 2 +- src/filesystem/android/SDL_sysfilesystem.c | 2 +- src/filesystem/cocoa/SDL_sysfilesystem.m | 2 +- src/filesystem/dummy/SDL_sysfilesystem.c | 2 +- src/filesystem/emscripten/SDL_sysfilesystem.c | 2 +- src/filesystem/gdk/SDL_sysfilesystem.cpp | 4 +- src/filesystem/haiku/SDL_sysfilesystem.cc | 2 +- src/filesystem/n3ds/SDL_sysfilesystem.c | 2 +- src/filesystem/nacl/SDL_sysfilesystem.c | 2 +- src/filesystem/os2/SDL_sysfilesystem.c | 2 +- src/filesystem/ps2/SDL_sysfilesystem.c | 2 +- src/filesystem/psp/SDL_sysfilesystem.c | 2 +- src/filesystem/riscos/SDL_sysfilesystem.c | 2 +- src/filesystem/unix/SDL_sysfilesystem.c | 2 +- src/filesystem/vita/SDL_sysfilesystem.c | 2 +- src/filesystem/windows/SDL_sysfilesystem.c | 2 +- src/filesystem/winrt/SDL_sysfilesystem.cpp | 2 +- src/haptic/SDL_haptic.c | 2 +- src/haptic/SDL_haptic_c.h | 2 +- src/haptic/SDL_syshaptic.h | 2 +- src/haptic/android/SDL_syshaptic.c | 2 +- src/haptic/darwin/SDL_syshaptic.c | 2 +- src/haptic/darwin/SDL_syshaptic_c.h | 2 +- src/haptic/dummy/SDL_syshaptic.c | 2 +- src/haptic/linux/SDL_syshaptic.c | 2 +- src/haptic/windows/SDL_dinputhaptic.c | 2 +- src/haptic/windows/SDL_dinputhaptic_c.h | 2 +- src/haptic/windows/SDL_windowshaptic.c | 2 +- src/haptic/windows/SDL_windowshaptic_c.h | 2 +- src/haptic/windows/SDL_xinputhaptic.c | 2 +- src/haptic/windows/SDL_xinputhaptic_c.h | 2 +- src/hidapi/SDL_hidapi.c | 49 +- src/hidapi/SDL_hidapi_c.h | 2 +- src/hidapi/android/jni/Android.mk | 16 + src/hidapi/ios/hid.m | 24 +- src/hidapi/libusb/hid.c | 5 +- src/hidapi/mac/hid.c | 2 +- src/hidapi/windows/hid.c | 2 +- src/joystick/SDL_gamecontroller.c | 111 +- src/joystick/SDL_gamecontrollerdb.h | 11 +- src/joystick/SDL_joystick.c | 107 +- src/joystick/SDL_joystick_c.h | 5 +- src/joystick/SDL_steam_virtual_gamepad.c | 3 +- src/joystick/SDL_steam_virtual_gamepad.h | 2 +- src/joystick/SDL_sysjoystick.h | 2 +- src/joystick/android/SDL_sysjoystick.c | 2 +- src/joystick/android/SDL_sysjoystick_c.h | 2 +- src/joystick/bsd/SDL_bsdjoystick.c | 2 +- src/joystick/controller_list.h | 6 +- src/joystick/darwin/SDL_iokitjoystick.c | 7 +- src/joystick/darwin/SDL_iokitjoystick_c.h | 2 +- src/joystick/dummy/SDL_sysjoystick.c | 2 +- src/joystick/emscripten/SDL_sysjoystick.c | 2 +- src/joystick/emscripten/SDL_sysjoystick_c.h | 2 +- src/joystick/haiku/SDL_haikujoystick.cc | 2 +- src/joystick/hidapi/SDL_hidapi_combined.c | 2 +- src/joystick/hidapi/SDL_hidapi_gamecube.c | 2 +- src/joystick/hidapi/SDL_hidapi_luna.c | 2 +- src/joystick/hidapi/SDL_hidapi_nintendo.h | 2 +- src/joystick/hidapi/SDL_hidapi_ps3.c | 145 +- src/joystick/hidapi/SDL_hidapi_ps4.c | 3 +- src/joystick/hidapi/SDL_hidapi_ps5.c | 9 +- src/joystick/hidapi/SDL_hidapi_rumble.c | 2 +- src/joystick/hidapi/SDL_hidapi_rumble.h | 2 +- src/joystick/hidapi/SDL_hidapi_shield.c | 2 +- src/joystick/hidapi/SDL_hidapi_stadia.c | 2 +- src/joystick/hidapi/SDL_hidapi_steam.c | 2 +- src/joystick/hidapi/SDL_hidapi_steamdeck.c | 188 +- src/joystick/hidapi/SDL_hidapi_switch.c | 68 +- src/joystick/hidapi/SDL_hidapi_wii.c | 2 +- src/joystick/hidapi/SDL_hidapi_xbox360.c | 55 +- src/joystick/hidapi/SDL_hidapi_xbox360w.c | 2 +- src/joystick/hidapi/SDL_hidapi_xboxone.c | 9 +- src/joystick/hidapi/SDL_hidapijoystick.c | 38 +- src/joystick/hidapi/SDL_hidapijoystick_c.h | 10 +- src/joystick/iphoneos/SDL_mfijoystick.m | 49 +- src/joystick/iphoneos/SDL_mfijoystick_c.h | 9 +- src/joystick/linux/SDL_sysjoystick.c | 110 +- src/joystick/linux/SDL_sysjoystick_c.h | 2 +- src/joystick/n3ds/SDL_sysjoystick.c | 2 +- src/joystick/os2/SDL_os2joystick.c | 2 +- src/joystick/ps2/SDL_sysjoystick.c | 6 +- src/joystick/psp/SDL_sysjoystick.c | 9 +- src/joystick/sort_controllers.py | 13 +- src/joystick/steam/SDL_steamcontroller.c | 2 +- src/joystick/steam/SDL_steamcontroller.h | 2 +- src/joystick/usb_ids.h | 10 +- src/joystick/virtual/SDL_virtualjoystick.c | 2 +- src/joystick/virtual/SDL_virtualjoystick_c.h | 2 +- src/joystick/vita/SDL_sysjoystick.c | 6 +- src/joystick/windows/SDL_dinputjoystick.c | 12 +- src/joystick/windows/SDL_dinputjoystick_c.h | 2 +- src/joystick/windows/SDL_rawinputjoystick.c | 23 +- src/joystick/windows/SDL_rawinputjoystick_c.h | 2 +- .../windows/SDL_windows_gaming_input.c | 6 +- src/joystick/windows/SDL_windowsjoystick.c | 8 +- src/joystick/windows/SDL_windowsjoystick_c.h | 3 +- src/joystick/windows/SDL_xinputjoystick.c | 19 +- src/joystick/windows/SDL_xinputjoystick_c.h | 2 +- src/libm/math_libm.h | 2 +- src/loadso/dlopen/SDL_sysloadso.c | 2 +- src/loadso/dummy/SDL_sysloadso.c | 2 +- src/loadso/os2/SDL_sysloadso.c | 2 +- src/loadso/windows/SDL_sysloadso.c | 2 +- src/locale/SDL_locale.c | 2 +- src/locale/SDL_syslocale.h | 2 +- src/locale/android/SDL_syslocale.c | 2 +- src/locale/dummy/SDL_syslocale.c | 2 +- src/locale/emscripten/SDL_syslocale.c | 2 +- src/locale/haiku/SDL_syslocale.cc | 2 +- src/locale/macosx/SDL_syslocale.m | 2 +- src/locale/n3ds/SDL_syslocale.c | 11 +- src/locale/psp/SDL_syslocale.c | 77 + src/locale/unix/SDL_syslocale.c | 2 +- src/locale/vita/SDL_syslocale.c | 2 +- src/locale/windows/SDL_syslocale.c | 2 +- src/locale/winrt/SDL_syslocale.c | 2 +- src/main/gdk/SDL_gdk_main.c | 2 +- src/main/haiku/SDL_BApp.h | 2 +- src/main/haiku/SDL_BeApp.cc | 2 +- src/main/haiku/SDL_BeApp.h | 2 +- src/main/n3ds/SDL_n3ds_main.c | 2 +- src/main/nacl/SDL_nacl_main.c | 2 +- src/main/ps2/SDL_ps2_main.c | 8 +- src/main/windows/version.rc | 10 +- src/misc/SDL_sysurl.h | 2 +- src/misc/SDL_url.c | 2 +- src/misc/android/SDL_sysurl.c | 2 +- src/misc/dummy/SDL_sysurl.c | 2 +- src/misc/emscripten/SDL_sysurl.c | 2 +- src/misc/haiku/SDL_sysurl.cc | 2 +- src/misc/ios/SDL_sysurl.m | 15 +- src/misc/macosx/SDL_sysurl.m | 2 +- src/misc/riscos/SDL_sysurl.c | 2 +- src/misc/unix/SDL_sysurl.c | 2 +- src/misc/vita/SDL_sysurl.c | 2 +- src/misc/windows/SDL_sysurl.c | 2 +- src/misc/winrt/SDL_sysurl.cpp | 2 +- src/power/SDL_power.c | 2 +- src/power/SDL_syspower.h | 2 +- src/power/android/SDL_syspower.c | 2 +- src/power/emscripten/SDL_syspower.c | 2 +- src/power/haiku/SDL_syspower.c | 2 +- src/power/linux/SDL_syspower.c | 2 +- src/power/macosx/SDL_syspower.c | 2 +- src/power/n3ds/SDL_syspower.c | 2 +- src/power/psp/SDL_syspower.c | 2 +- src/power/uikit/SDL_syspower.h | 2 +- src/power/uikit/SDL_syspower.m | 4 +- src/power/vita/SDL_syspower.c | 2 +- src/power/windows/SDL_syspower.c | 2 +- src/power/winrt/SDL_syspower.cpp | 2 +- src/render/SDL_d3dmath.c | 6 +- src/render/SDL_d3dmath.h | 6 +- src/render/SDL_render.c | 44 +- src/render/SDL_sysrender.h | 2 +- src/render/SDL_yuv_sw.c | 2 +- src/render/SDL_yuv_sw_c.h | 2 +- src/render/direct3d/SDL_render_d3d.c | 20 +- src/render/direct3d/SDL_shaders_d3d.c | 6 +- src/render/direct3d/SDL_shaders_d3d.h | 2 +- src/render/direct3d11/SDL_render_d3d11.c | 18 +- src/render/direct3d11/SDL_render_winrt.cpp | 6 +- src/render/direct3d11/SDL_render_winrt.h | 6 +- src/render/direct3d11/SDL_shaders_d3d11.c | 6 +- src/render/direct3d11/SDL_shaders_d3d11.h | 2 +- src/render/direct3d12/SDL_render_d3d12.c | 93 +- .../direct3d12/SDL_render_d3d12_xbox.cpp | 4 +- src/render/direct3d12/SDL_render_d3d12_xbox.h | 2 +- src/render/direct3d12/SDL_shaders_d3d12.c | 6 +- src/render/direct3d12/SDL_shaders_d3d12.h | 2 +- .../direct3d12/SDL_shaders_d3d12_xboxone.cpp | 6 +- .../SDL_shaders_d3d12_xboxseries.cpp | 6 +- src/render/metal/SDL_render_metal.m | 6 +- src/render/opengl/SDL_glfuncs.h | 2 +- src/render/opengl/SDL_render_gl.c | 7 +- src/render/opengl/SDL_shaders_gl.c | 6 +- src/render/opengl/SDL_shaders_gl.h | 2 +- src/render/opengles/SDL_glesfuncs.h | 2 +- src/render/opengles/SDL_render_gles.c | 6 +- src/render/opengles2/SDL_gles2funcs.h | 2 +- src/render/opengles2/SDL_render_gles2.c | 7 +- src/render/opengles2/SDL_shaders_gles2.c | 6 +- src/render/opengles2/SDL_shaders_gles2.h | 4 +- src/render/ps2/SDL_render_ps2.c | 7 +- src/render/psp/SDL_render_psp.c | 5 +- src/render/software/SDL_blendfillrect.c | 6 +- src/render/software/SDL_blendfillrect.h | 2 +- src/render/software/SDL_blendline.c | 6 +- src/render/software/SDL_blendline.h | 2 +- src/render/software/SDL_blendpoint.c | 6 +- src/render/software/SDL_blendpoint.h | 2 +- src/render/software/SDL_draw.h | 2 +- src/render/software/SDL_drawline.c | 6 +- src/render/software/SDL_drawline.h | 2 +- src/render/software/SDL_drawpoint.c | 6 +- src/render/software/SDL_drawpoint.h | 2 +- src/render/software/SDL_render_sw.c | 6 +- src/render/software/SDL_render_sw_c.h | 2 +- src/render/software/SDL_rotate.c | 4 +- src/render/software/SDL_rotate.h | 2 +- src/render/software/SDL_triangle.c | 6 +- src/render/software/SDL_triangle.h | 2 +- src/render/vitagxm/SDL_render_vita_gxm.c | 7 +- .../vitagxm/SDL_render_vita_gxm_memory.c | 6 +- .../vitagxm/SDL_render_vita_gxm_memory.h | 2 +- .../vitagxm/SDL_render_vita_gxm_shaders.h | 2 +- .../vitagxm/SDL_render_vita_gxm_tools.c | 6 +- .../vitagxm/SDL_render_vita_gxm_tools.h | 2 +- .../vitagxm/SDL_render_vita_gxm_types.h | 2 +- src/sensor/SDL_sensor.c | 2 +- src/sensor/SDL_sensor_c.h | 2 +- src/sensor/SDL_syssensor.h | 2 +- src/sensor/android/SDL_androidsensor.c | 4 +- src/sensor/android/SDL_androidsensor.h | 2 +- src/sensor/coremotion/SDL_coremotionsensor.h | 2 +- src/sensor/coremotion/SDL_coremotionsensor.m | 2 +- src/sensor/dummy/SDL_dummysensor.c | 2 +- src/sensor/dummy/SDL_dummysensor.h | 2 +- src/sensor/n3ds/SDL_n3dssensor.c | 2 +- src/sensor/vita/SDL_vitasensor.c | 2 +- src/sensor/vita/SDL_vitasensor.h | 2 +- src/sensor/windows/SDL_windowssensor.c | 2 +- src/sensor/windows/SDL_windowssensor.h | 2 +- src/stdlib/SDL_crc16.c | 2 +- src/stdlib/SDL_crc32.c | 2 +- src/stdlib/SDL_getenv.c | 2 +- src/stdlib/SDL_iconv.c | 7 +- src/stdlib/SDL_malloc.c | 4 +- src/stdlib/SDL_mslibc.c | 2 +- src/stdlib/SDL_qsort.c | 49 +- src/stdlib/SDL_stdlib.c | 2 +- src/stdlib/SDL_string.c | 28 +- src/stdlib/SDL_strtokr.c | 2 +- src/stdlib/SDL_vacopy.h | 2 +- src/test/SDL_test_assert.c | 8 +- src/test/SDL_test_common.c | 2 +- src/test/SDL_test_compare.c | 2 +- src/test/SDL_test_crc32.c | 2 +- src/test/SDL_test_font.c | 2 +- src/test/SDL_test_fuzzer.c | 30 +- src/test/SDL_test_harness.c | 4 +- src/test/SDL_test_imageBlit.c | 8 +- src/test/SDL_test_imageBlitBlend.c | 12 +- src/test/SDL_test_imageFace.c | 4 +- src/test/SDL_test_imagePrimitives.c | 4 +- src/test/SDL_test_imagePrimitivesBlend.c | 4 +- src/test/SDL_test_log.c | 2 +- src/test/SDL_test_md5.c | 2 +- src/test/SDL_test_memory.c | 6 +- src/test/SDL_test_random.c | 2 +- src/thread/SDL_systhread.h | 8 +- src/thread/SDL_thread.c | 95 +- src/thread/SDL_thread_c.h | 14 +- src/thread/generic/SDL_syscond.c | 2 +- src/thread/generic/SDL_syscond_c.h | 2 +- src/thread/generic/SDL_sysmutex.c | 2 +- src/thread/generic/SDL_sysmutex_c.h | 2 +- src/thread/generic/SDL_syssem.c | 2 +- src/thread/generic/SDL_systhread.c | 2 +- src/thread/generic/SDL_systhread_c.h | 2 +- src/thread/generic/SDL_systls.c | 12 +- src/thread/n3ds/SDL_syscond.c | 2 +- src/thread/n3ds/SDL_sysmutex.c | 2 +- src/thread/n3ds/SDL_sysmutex_c.h | 2 +- src/thread/n3ds/SDL_syssem.c | 2 +- src/thread/n3ds/SDL_systhread.c | 2 +- src/thread/n3ds/SDL_systhread_c.h | 2 +- src/thread/ngage/SDL_sysmutex.cpp | 2 +- src/thread/ngage/SDL_syssem.cpp | 2 +- src/thread/ngage/SDL_systhread.cpp | 2 +- src/thread/ngage/SDL_systhread_c.h | 2 +- src/thread/os2/SDL_sysmutex.c | 2 +- src/thread/os2/SDL_syssem.c | 2 +- src/thread/os2/SDL_systhread.c | 2 +- src/thread/os2/SDL_systhread_c.h | 2 +- src/thread/os2/SDL_systls.c | 48 +- src/thread/os2/SDL_systls_c.h | 10 +- src/thread/ps2/SDL_syssem.c | 2 +- src/thread/ps2/SDL_systhread.c | 2 +- src/thread/ps2/SDL_systhread_c.h | 2 +- src/thread/psp/SDL_sysmutex.c | 2 +- src/thread/psp/SDL_sysmutex_c.h | 2 +- src/thread/psp/SDL_syssem.c | 2 +- src/thread/psp/SDL_systhread.c | 2 +- src/thread/psp/SDL_systhread_c.h | 2 +- src/thread/pthread/SDL_syscond.c | 4 +- src/thread/pthread/SDL_sysmutex.c | 2 +- src/thread/pthread/SDL_sysmutex_c.h | 2 +- src/thread/pthread/SDL_syssem.c | 4 +- src/thread/pthread/SDL_systhread.c | 18 +- src/thread/pthread/SDL_systhread_c.h | 2 +- src/thread/pthread/SDL_systls.c | 44 +- src/thread/stdcpp/SDL_syscond.cpp | 2 +- src/thread/stdcpp/SDL_sysmutex.cpp | 2 +- src/thread/stdcpp/SDL_sysmutex_c.h | 2 +- src/thread/stdcpp/SDL_systhread.cpp | 43 +- src/thread/stdcpp/SDL_systhread_c.h | 2 +- src/thread/vita/SDL_sysmutex.c | 2 +- src/thread/vita/SDL_sysmutex_c.h | 2 +- src/thread/vita/SDL_syssem.c | 2 +- src/thread/vita/SDL_systhread.c | 2 +- src/thread/vita/SDL_systhread_c.h | 2 +- src/thread/windows/SDL_syscond_cv.c | 2 +- src/thread/windows/SDL_sysmutex.c | 2 +- src/thread/windows/SDL_sysmutex_c.h | 2 +- src/thread/windows/SDL_syssem.c | 2 +- src/thread/windows/SDL_systhread.c | 2 +- src/thread/windows/SDL_systhread_c.h | 2 +- src/thread/windows/SDL_systls.c | 46 +- src/timer/SDL_timer.c | 2 +- src/timer/SDL_timer_c.h | 2 +- src/timer/dummy/SDL_systimer.c | 2 +- src/timer/haiku/SDL_systimer.c | 2 +- src/timer/n3ds/SDL_systimer.c | 2 +- src/timer/ngage/SDL_systimer.cpp | 2 +- src/timer/os2/SDL_systimer.c | 2 +- src/timer/ps2/SDL_systimer.c | 2 +- src/timer/psp/SDL_systimer.c | 2 +- src/timer/unix/SDL_systimer.c | 2 +- src/timer/vita/SDL_systimer.c | 2 +- src/timer/windows/SDL_systimer.c | 2 +- src/video/SDL_RLEaccel.c | 2 +- src/video/SDL_RLEaccel_c.h | 2 +- src/video/SDL_blit.c | 4 +- src/video/SDL_blit.h | 2 +- src/video/SDL_blit_0.c | 69 +- src/video/SDL_blit_1.c | 2 +- src/video/SDL_blit_A.c | 22 +- src/video/SDL_blit_N.c | 2 +- src/video/SDL_blit_auto.c | 2 +- src/video/SDL_blit_auto.h | 2 +- src/video/SDL_blit_copy.c | 2 +- src/video/SDL_blit_copy.h | 2 +- src/video/SDL_blit_slow.c | 2 +- src/video/SDL_blit_slow.h | 2 +- src/video/SDL_bmp.c | 2 +- src/video/SDL_clipboard.c | 2 +- src/video/SDL_egl.c | 2 +- src/video/SDL_egl_c.h | 2 +- src/video/SDL_fillrect.c | 9 +- src/video/SDL_pixels.c | 2 +- src/video/SDL_pixels_c.h | 2 +- src/video/SDL_rect.c | 2 +- src/video/SDL_rect_c.h | 2 +- src/video/SDL_rect_impl.h | 2 +- src/video/SDL_shape.c | 2 +- src/video/SDL_shape_internals.h | 2 +- src/video/SDL_stretch.c | 4 +- src/video/SDL_surface.c | 2 +- src/video/SDL_sysvideo.h | 8 +- src/video/SDL_video.c | 288 +- src/video/SDL_vulkan_internal.h | 2 +- src/video/SDL_vulkan_utils.c | 2 +- src/video/SDL_yuv.c | 2 +- src/video/SDL_yuv_c.h | 2 +- src/video/android/SDL_androidclipboard.c | 2 +- src/video/android/SDL_androidclipboard.h | 2 +- src/video/android/SDL_androidevents.c | 12 +- src/video/android/SDL_androidevents.h | 2 +- src/video/android/SDL_androidgl.c | 2 +- src/video/android/SDL_androidgl.h | 2 +- src/video/android/SDL_androidkeyboard.c | 13 +- src/video/android/SDL_androidkeyboard.h | 3 +- src/video/android/SDL_androidmessagebox.c | 2 +- src/video/android/SDL_androidmessagebox.h | 2 +- src/video/android/SDL_androidmouse.c | 8 +- src/video/android/SDL_androidmouse.h | 2 +- src/video/android/SDL_androidtouch.c | 2 +- src/video/android/SDL_androidtouch.h | 2 +- src/video/android/SDL_androidvideo.c | 2 +- src/video/android/SDL_androidvideo.h | 2 +- src/video/android/SDL_androidvulkan.c | 2 +- src/video/android/SDL_androidvulkan.h | 2 +- src/video/android/SDL_androidwindow.c | 2 +- src/video/android/SDL_androidwindow.h | 2 +- src/video/cocoa/SDL_cocoaclipboard.h | 2 +- src/video/cocoa/SDL_cocoaclipboard.m | 2 +- src/video/cocoa/SDL_cocoaevents.h | 2 +- src/video/cocoa/SDL_cocoaevents.m | 2 +- src/video/cocoa/SDL_cocoakeyboard.h | 2 +- src/video/cocoa/SDL_cocoakeyboard.m | 2 +- src/video/cocoa/SDL_cocoamessagebox.h | 2 +- src/video/cocoa/SDL_cocoamessagebox.m | 2 +- src/video/cocoa/SDL_cocoametalview.h | 2 +- src/video/cocoa/SDL_cocoametalview.m | 2 +- src/video/cocoa/SDL_cocoamodes.h | 2 +- src/video/cocoa/SDL_cocoamodes.m | 2 +- src/video/cocoa/SDL_cocoamouse.h | 2 +- src/video/cocoa/SDL_cocoamouse.m | 2 +- src/video/cocoa/SDL_cocoaopengl.h | 2 +- src/video/cocoa/SDL_cocoaopengl.m | 30 +- src/video/cocoa/SDL_cocoaopengles.h | 2 +- src/video/cocoa/SDL_cocoaopengles.m | 2 +- src/video/cocoa/SDL_cocoashape.h | 2 +- src/video/cocoa/SDL_cocoashape.m | 2 +- src/video/cocoa/SDL_cocoavideo.h | 2 +- src/video/cocoa/SDL_cocoavideo.m | 2 +- src/video/cocoa/SDL_cocoavulkan.h | 2 +- src/video/cocoa/SDL_cocoavulkan.m | 2 +- src/video/cocoa/SDL_cocoawindow.h | 5 +- src/video/cocoa/SDL_cocoawindow.m | 74 +- src/video/directfb/SDL_DirectFB_WM.c | 2 +- src/video/directfb/SDL_DirectFB_WM.h | 2 +- src/video/directfb/SDL_DirectFB_dyn.c | 2 +- src/video/directfb/SDL_DirectFB_dyn.h | 2 +- src/video/directfb/SDL_DirectFB_events.c | 2 +- src/video/directfb/SDL_DirectFB_events.h | 2 +- src/video/directfb/SDL_DirectFB_modes.c | 2 +- src/video/directfb/SDL_DirectFB_modes.h | 2 +- src/video/directfb/SDL_DirectFB_mouse.c | 2 +- src/video/directfb/SDL_DirectFB_mouse.h | 2 +- src/video/directfb/SDL_DirectFB_opengl.c | 2 +- src/video/directfb/SDL_DirectFB_opengl.h | 2 +- src/video/directfb/SDL_DirectFB_render.c | 4 +- src/video/directfb/SDL_DirectFB_render.h | 2 +- src/video/directfb/SDL_DirectFB_shape.c | 2 +- src/video/directfb/SDL_DirectFB_shape.h | 2 +- src/video/directfb/SDL_DirectFB_video.c | 2 +- src/video/directfb/SDL_DirectFB_video.h | 2 +- src/video/directfb/SDL_DirectFB_vulkan.c | 2 +- src/video/directfb/SDL_DirectFB_vulkan.h | 2 +- src/video/directfb/SDL_DirectFB_window.c | 2 +- src/video/directfb/SDL_DirectFB_window.h | 2 +- src/video/dummy/SDL_nullevents.c | 2 +- src/video/dummy/SDL_nullevents_c.h | 2 +- src/video/dummy/SDL_nullframebuffer.c | 2 +- src/video/dummy/SDL_nullframebuffer_c.h | 2 +- src/video/dummy/SDL_nullvideo.c | 4 +- src/video/dummy/SDL_nullvideo.h | 2 +- src/video/emscripten/SDL_emscriptenevents.c | 8 +- src/video/emscripten/SDL_emscriptenevents.h | 2 +- .../emscripten/SDL_emscriptenframebuffer.c | 4 +- .../emscripten/SDL_emscriptenframebuffer.h | 2 +- src/video/emscripten/SDL_emscriptenmouse.c | 52 +- src/video/emscripten/SDL_emscriptenmouse.h | 2 +- src/video/emscripten/SDL_emscriptenopengles.c | 2 +- src/video/emscripten/SDL_emscriptenopengles.h | 2 +- src/video/emscripten/SDL_emscriptenvideo.c | 3 +- src/video/emscripten/SDL_emscriptenvideo.h | 2 +- src/video/haiku/SDL_BApp.h | 2 +- src/video/haiku/SDL_BWin.h | 2 +- src/video/haiku/SDL_bclipboard.cc | 2 +- src/video/haiku/SDL_bclipboard.h | 2 +- src/video/haiku/SDL_bevents.cc | 2 +- src/video/haiku/SDL_bevents.h | 2 +- src/video/haiku/SDL_bframebuffer.cc | 2 +- src/video/haiku/SDL_bframebuffer.h | 2 +- src/video/haiku/SDL_bkeyboard.cc | 2 +- src/video/haiku/SDL_bkeyboard.h | 2 +- src/video/haiku/SDL_bmessagebox.cc | 2 +- src/video/haiku/SDL_bmessagebox.h | 2 +- src/video/haiku/SDL_bmodes.cc | 2 +- src/video/haiku/SDL_bmodes.h | 2 +- src/video/haiku/SDL_bopengl.cc | 2 +- src/video/haiku/SDL_bopengl.h | 2 +- src/video/haiku/SDL_bvideo.cc | 2 +- src/video/haiku/SDL_bvideo.h | 2 +- src/video/haiku/SDL_bwindow.cc | 2 +- src/video/haiku/SDL_bwindow.h | 2 +- src/video/khronos/vulkan/vulkan_metal.h | 26 +- src/video/kmsdrm/SDL_kmsdrmdyn.c | 16 +- src/video/kmsdrm/SDL_kmsdrmdyn.h | 5 +- src/video/kmsdrm/SDL_kmsdrmevents.c | 2 +- src/video/kmsdrm/SDL_kmsdrmevents.h | 2 +- src/video/kmsdrm/SDL_kmsdrmmouse.c | 2 +- src/video/kmsdrm/SDL_kmsdrmmouse.h | 2 +- src/video/kmsdrm/SDL_kmsdrmopengles.c | 4 +- src/video/kmsdrm/SDL_kmsdrmopengles.h | 2 +- src/video/kmsdrm/SDL_kmsdrmsym.h | 19 +- src/video/kmsdrm/SDL_kmsdrmvideo.c | 139 +- src/video/kmsdrm/SDL_kmsdrmvideo.h | 41 +- src/video/kmsdrm/SDL_kmsdrmvulkan.c | 2 +- src/video/kmsdrm/SDL_kmsdrmvulkan.h | 2 +- src/video/n3ds/SDL_n3dsevents.c | 2 +- src/video/n3ds/SDL_n3dsevents_c.h | 2 +- src/video/n3ds/SDL_n3dsframebuffer.c | 2 +- src/video/n3ds/SDL_n3dsframebuffer_c.h | 2 +- src/video/n3ds/SDL_n3dsswkb.c | 8 +- src/video/n3ds/SDL_n3dsswkb.h | 2 +- src/video/n3ds/SDL_n3dstouch.c | 4 +- src/video/n3ds/SDL_n3dstouch.h | 2 +- src/video/n3ds/SDL_n3dsvideo.c | 2 +- src/video/n3ds/SDL_n3dsvideo.h | 2 +- src/video/nacl/SDL_naclevents.c | 2 +- src/video/nacl/SDL_naclevents_c.h | 2 +- src/video/nacl/SDL_naclglue.c | 2 +- src/video/nacl/SDL_naclopengles.c | 2 +- src/video/nacl/SDL_naclopengles.h | 2 +- src/video/nacl/SDL_naclvideo.c | 2 +- src/video/nacl/SDL_naclvideo.h | 2 +- src/video/nacl/SDL_naclwindow.c | 2 +- src/video/nacl/SDL_naclwindow.h | 2 +- src/video/ngage/SDL_ngageevents.cpp | 2 +- src/video/ngage/SDL_ngageevents_c.h | 2 +- src/video/ngage/SDL_ngageframebuffer.cpp | 2 +- src/video/ngage/SDL_ngageframebuffer_c.h | 2 +- src/video/ngage/SDL_ngagevideo.cpp | 2 +- src/video/ngage/SDL_ngagevideo.h | 2 +- src/video/ngage/SDL_ngagewindow.cpp | 2 +- src/video/ngage/SDL_ngagewindow.h | 2 +- src/video/offscreen/SDL_offscreenevents.c | 2 +- src/video/offscreen/SDL_offscreenevents_c.h | 2 +- .../offscreen/SDL_offscreenframebuffer.c | 2 +- .../offscreen/SDL_offscreenframebuffer_c.h | 2 +- src/video/offscreen/SDL_offscreenopengles.c | 2 +- src/video/offscreen/SDL_offscreenopengles.h | 2 +- src/video/offscreen/SDL_offscreenvideo.c | 2 +- src/video/offscreen/SDL_offscreenvideo.h | 2 +- src/video/offscreen/SDL_offscreenwindow.c | 2 +- src/video/offscreen/SDL_offscreenwindow.h | 2 +- src/video/os2/SDL_os2dive.c | 2 +- src/video/os2/SDL_os2messagebox.c | 2 +- src/video/os2/SDL_os2messagebox.h | 2 +- src/video/os2/SDL_os2mouse.c | 2 +- src/video/os2/SDL_os2mouse.h | 2 +- src/video/os2/SDL_os2output.h | 2 +- src/video/os2/SDL_os2util.c | 2 +- src/video/os2/SDL_os2util.h | 2 +- src/video/os2/SDL_os2video.c | 2 +- src/video/os2/SDL_os2video.h | 2 +- src/video/os2/SDL_os2vman.c | 2 +- src/video/pandora/SDL_pandora.c | 2 +- src/video/pandora/SDL_pandora.h | 2 +- src/video/pandora/SDL_pandora_events.c | 2 +- src/video/pandora/SDL_pandora_events.h | 2 +- src/video/ps2/SDL_ps2video.c | 2 +- src/video/ps2/SDL_ps2video.h | 2 +- src/video/psp/SDL_pspevents.c | 2 +- src/video/psp/SDL_pspevents_c.h | 2 +- src/video/psp/SDL_pspgl.c | 2 +- src/video/psp/SDL_pspgl_c.h | 2 +- src/video/psp/SDL_pspmouse.c | 2 +- src/video/psp/SDL_pspmouse_c.h | 2 +- src/video/psp/SDL_pspvideo.c | 2 +- src/video/psp/SDL_pspvideo.h | 2 +- src/video/raspberry/SDL_rpievents.c | 2 +- src/video/raspberry/SDL_rpievents_c.h | 2 +- src/video/raspberry/SDL_rpimouse.c | 2 +- src/video/raspberry/SDL_rpimouse.h | 2 +- src/video/raspberry/SDL_rpiopengles.c | 2 +- src/video/raspberry/SDL_rpiopengles.h | 2 +- src/video/raspberry/SDL_rpivideo.c | 4 +- src/video/raspberry/SDL_rpivideo.h | 2 +- src/video/riscos/SDL_riscosdefs.h | 2 +- src/video/riscos/SDL_riscosevents.c | 2 +- src/video/riscos/SDL_riscosevents_c.h | 2 +- src/video/riscos/SDL_riscosframebuffer.c | 2 +- src/video/riscos/SDL_riscosframebuffer_c.h | 2 +- src/video/riscos/SDL_riscosmessagebox.c | 2 +- src/video/riscos/SDL_riscosmessagebox.h | 2 +- src/video/riscos/SDL_riscosmodes.c | 2 +- src/video/riscos/SDL_riscosmodes.h | 2 +- src/video/riscos/SDL_riscosmouse.c | 2 +- src/video/riscos/SDL_riscosmouse.h | 2 +- src/video/riscos/SDL_riscosvideo.c | 2 +- src/video/riscos/SDL_riscosvideo.h | 2 +- src/video/riscos/SDL_riscoswindow.c | 2 +- src/video/riscos/SDL_riscoswindow.h | 2 +- src/video/riscos/scancodes_riscos.h | 2 +- src/video/sdlgenblit.pl | 2 +- src/video/uikit/SDL_uikitappdelegate.h | 2 +- src/video/uikit/SDL_uikitappdelegate.m | 16 +- src/video/uikit/SDL_uikitclipboard.h | 2 +- src/video/uikit/SDL_uikitclipboard.m | 2 +- src/video/uikit/SDL_uikitevents.h | 2 +- src/video/uikit/SDL_uikitevents.m | 27 +- src/video/uikit/SDL_uikitmessagebox.h | 2 +- src/video/uikit/SDL_uikitmessagebox.m | 4 +- src/video/uikit/SDL_uikitmetalview.h | 2 +- src/video/uikit/SDL_uikitmetalview.m | 2 +- src/video/uikit/SDL_uikitmodes.h | 2 +- src/video/uikit/SDL_uikitmodes.m | 19 +- src/video/uikit/SDL_uikitopengles.h | 2 +- src/video/uikit/SDL_uikitopengles.m | 2 +- src/video/uikit/SDL_uikitopenglview.h | 2 +- src/video/uikit/SDL_uikitopenglview.m | 12 +- src/video/uikit/SDL_uikitvideo.h | 2 +- src/video/uikit/SDL_uikitvideo.m | 13 +- src/video/uikit/SDL_uikitview.h | 2 +- src/video/uikit/SDL_uikitview.m | 24 +- src/video/uikit/SDL_uikitviewcontroller.h | 2 +- src/video/uikit/SDL_uikitviewcontroller.m | 38 +- src/video/uikit/SDL_uikitvulkan.h | 2 +- src/video/uikit/SDL_uikitvulkan.m | 2 +- src/video/uikit/SDL_uikitwindow.h | 2 +- src/video/uikit/SDL_uikitwindow.m | 19 +- src/video/vita/SDL_vitaframebuffer.c | 2 +- src/video/vita/SDL_vitaframebuffer.h | 2 +- src/video/vita/SDL_vitagl_pvr.c | 2 +- src/video/vita/SDL_vitagl_pvr_c.h | 2 +- src/video/vita/SDL_vitagles.c | 2 +- src/video/vita/SDL_vitagles_c.h | 2 +- src/video/vita/SDL_vitagles_pvr.c | 2 +- src/video/vita/SDL_vitagles_pvr_c.h | 2 +- src/video/vita/SDL_vitakeyboard.c | 2 +- src/video/vita/SDL_vitakeyboard.h | 2 +- src/video/vita/SDL_vitamessagebox.c | 6 +- src/video/vita/SDL_vitamessagebox.h | 2 +- src/video/vita/SDL_vitamouse.c | 18 +- src/video/vita/SDL_vitamouse_c.h | 2 +- src/video/vita/SDL_vitatouch.c | 12 +- src/video/vita/SDL_vitatouch.h | 2 +- src/video/vita/SDL_vitavideo.c | 2 +- src/video/vita/SDL_vitavideo.h | 2 +- src/video/vivante/SDL_vivanteopengles.c | 2 +- src/video/vivante/SDL_vivanteopengles.h | 2 +- src/video/vivante/SDL_vivanteplatform.c | 2 +- src/video/vivante/SDL_vivanteplatform.h | 2 +- src/video/vivante/SDL_vivantevideo.c | 2 +- src/video/vivante/SDL_vivantevideo.h | 2 +- src/video/vivante/SDL_vivantevulkan.c | 2 +- src/video/vivante/SDL_vivantevulkan.h | 2 +- src/video/wayland/SDL_waylandclipboard.c | 2 +- src/video/wayland/SDL_waylandclipboard.h | 2 +- src/video/wayland/SDL_waylanddatamanager.c | 2 +- src/video/wayland/SDL_waylanddatamanager.h | 2 +- src/video/wayland/SDL_waylanddyn.c | 2 +- src/video/wayland/SDL_waylanddyn.h | 2 +- src/video/wayland/SDL_waylandevents.c | 56 +- src/video/wayland/SDL_waylandevents_c.h | 2 +- src/video/wayland/SDL_waylandkeyboard.c | 2 +- src/video/wayland/SDL_waylandkeyboard.h | 2 +- src/video/wayland/SDL_waylandmessagebox.c | 2 +- src/video/wayland/SDL_waylandmessagebox.h | 2 +- src/video/wayland/SDL_waylandmouse.c | 194 +- src/video/wayland/SDL_waylandmouse.h | 2 +- src/video/wayland/SDL_waylandopengles.c | 30 +- src/video/wayland/SDL_waylandopengles.h | 2 +- src/video/wayland/SDL_waylandsym.h | 2 +- src/video/wayland/SDL_waylandtouch.c | 2 +- src/video/wayland/SDL_waylandtouch.h | 2 +- src/video/wayland/SDL_waylandvideo.c | 32 +- src/video/wayland/SDL_waylandvideo.h | 2 +- src/video/wayland/SDL_waylandvulkan.c | 2 +- src/video/wayland/SDL_waylandvulkan.h | 2 +- src/video/wayland/SDL_waylandwindow.c | 108 +- src/video/wayland/SDL_waylandwindow.h | 3 +- src/video/windows/SDL_msctf.h | 2 +- src/video/windows/SDL_vkeys.h | 2 +- src/video/windows/SDL_windowsclipboard.c | 2 +- src/video/windows/SDL_windowsclipboard.h | 2 +- src/video/windows/SDL_windowsevents.c | 124 +- src/video/windows/SDL_windowsevents.h | 2 +- src/video/windows/SDL_windowsframebuffer.c | 2 +- src/video/windows/SDL_windowsframebuffer.h | 2 +- src/video/windows/SDL_windowskeyboard.c | 10 +- src/video/windows/SDL_windowskeyboard.h | 2 +- src/video/windows/SDL_windowsmessagebox.c | 2 +- src/video/windows/SDL_windowsmessagebox.h | 2 +- src/video/windows/SDL_windowsmodes.c | 5 +- src/video/windows/SDL_windowsmodes.h | 2 +- src/video/windows/SDL_windowsmouse.c | 4 +- src/video/windows/SDL_windowsmouse.h | 2 +- src/video/windows/SDL_windowsopengl.c | 11 +- src/video/windows/SDL_windowsopengl.h | 2 +- src/video/windows/SDL_windowsopengles.c | 2 +- src/video/windows/SDL_windowsopengles.h | 2 +- src/video/windows/SDL_windowsshape.c | 2 +- src/video/windows/SDL_windowsshape.h | 2 +- src/video/windows/SDL_windowsvideo.c | 2 +- src/video/windows/SDL_windowsvideo.h | 2 +- src/video/windows/SDL_windowsvulkan.c | 2 +- src/video/windows/SDL_windowsvulkan.h | 2 +- src/video/windows/SDL_windowswindow.c | 2 +- src/video/windows/SDL_windowswindow.h | 2 +- src/video/windows/wmmsg.h | 2 +- src/video/winrt/SDL_winrtevents.cpp | 2 +- src/video/winrt/SDL_winrtevents_c.h | 2 +- src/video/winrt/SDL_winrtgamebar.cpp | 2 +- src/video/winrt/SDL_winrtgamebar_cpp.h | 2 +- src/video/winrt/SDL_winrtkeyboard.cpp | 2 +- src/video/winrt/SDL_winrtmessagebox.cpp | 2 +- src/video/winrt/SDL_winrtmessagebox.h | 2 +- src/video/winrt/SDL_winrtmouse.cpp | 2 +- src/video/winrt/SDL_winrtmouse_c.h | 2 +- src/video/winrt/SDL_winrtopengles.cpp | 2 +- src/video/winrt/SDL_winrtopengles.h | 2 +- src/video/winrt/SDL_winrtpointerinput.cpp | 2 +- src/video/winrt/SDL_winrtvideo.cpp | 2 +- src/video/winrt/SDL_winrtvideo_cpp.h | 2 +- src/video/x11/SDL_x11clipboard.c | 2 +- src/video/x11/SDL_x11clipboard.h | 2 +- src/video/x11/SDL_x11dyn.c | 2 +- src/video/x11/SDL_x11dyn.h | 2 +- src/video/x11/SDL_x11events.c | 5 +- src/video/x11/SDL_x11events.h | 2 +- src/video/x11/SDL_x11framebuffer.c | 2 +- src/video/x11/SDL_x11framebuffer.h | 2 +- src/video/x11/SDL_x11keyboard.c | 2 +- src/video/x11/SDL_x11keyboard.h | 2 +- src/video/x11/SDL_x11messagebox.c | 2 +- src/video/x11/SDL_x11messagebox.h | 2 +- src/video/x11/SDL_x11modes.c | 2 +- src/video/x11/SDL_x11modes.h | 2 +- src/video/x11/SDL_x11mouse.c | 116 +- src/video/x11/SDL_x11mouse.h | 2 +- src/video/x11/SDL_x11opengl.c | 3 +- src/video/x11/SDL_x11opengl.h | 2 +- src/video/x11/SDL_x11opengles.c | 2 +- src/video/x11/SDL_x11opengles.h | 2 +- src/video/x11/SDL_x11shape.c | 2 +- src/video/x11/SDL_x11shape.h | 2 +- src/video/x11/SDL_x11sym.h | 3 +- src/video/x11/SDL_x11touch.c | 2 +- src/video/x11/SDL_x11touch.h | 2 +- src/video/x11/SDL_x11video.c | 12 +- src/video/x11/SDL_x11video.h | 4 +- src/video/x11/SDL_x11vulkan.c | 6 +- src/video/x11/SDL_x11vulkan.h | 2 +- src/video/x11/SDL_x11window.c | 2 +- src/video/x11/SDL_x11window.h | 2 +- src/video/x11/SDL_x11xfixes.c | 6 +- src/video/x11/SDL_x11xfixes.h | 2 +- src/video/x11/SDL_x11xinput2.c | 6 +- src/video/x11/SDL_x11xinput2.h | 2 +- test/CMakeLists.txt | 13 +- test/checkkeys.c | 6 +- test/checkkeysthreads.c | 6 +- test/controllermap.c | 2 +- test/loopwave.c | 10 +- test/loopwavequeue.c | 4 +- test/testatomic.c | 6 +- test/testaudiocapture.c | 4 +- test/testaudiohotplug.c | 6 +- test/testaudioinfo.c | 2 +- test/testautomation.c | 2 +- test/testautomation_audio.c | 32 +- test/testautomation_keyboard.c | 4 +- test/testautomation_log.c | 2 +- test/testautomation_math.c | 16 +- test/testautomation_stdlib.c | 12 + test/testautomation_subsystems.c | 8 +- test/testautomation_surface.c | 4 +- test/testautomation_video.c | 80 +- test/testbounds.c | 2 +- test/testcustomcursor.c | 4 +- test/testdisplayinfo.c | 2 +- test/testdraw2.c | 4 +- test/testdrawchessboard.c | 35 +- test/testdropfile.c | 2 +- test/testerror.c | 2 +- test/testevdev.c | 2 +- test/testfile.c | 2 +- test/testfilesystem.c | 2 +- test/testfilesystem_pre.c | 2 +- test/testgamecontroller.c | 12 +- test/testgeometry.c | 4 +- test/testgesture.c | 2 +- test/testgl2.c | 4 +- test/testgles.c | 4 +- test/testgles2.c | 6 +- test/testgles2_sdf.c | 4 +- test/testhotplug.c | 2 +- test/testiconv.c | 2 +- test/testime.c | 12 +- test/testintersections.c | 4 +- test/testjoystick.c | 2 +- test/testkeys.c | 2 +- test/testloadso.c | 2 +- test/testlocale.c | 2 +- test/testlock.c | 2 +- test/testmessage.c | 2 +- test/testmouse.c | 2 +- test/testmultiaudio.c | 4 +- test/testnative.c | 2 +- test/testnative.h | 2 +- test/testnativeos2.c | 2 +- test/testnativew32.c | 2 +- test/testnativex11.c | 2 +- test/testoffscreen.c | 8 +- test/testoverlay2.c | 4 +- test/testplatform.c | 2 +- test/testpower.c | 2 +- test/testqsort.c | 2 +- test/testrelative.c | 4 +- test/testrendercopyex.c | 4 +- test/testrendertarget.c | 4 +- test/testresample.c | 2 +- test/testrumble.c | 2 +- test/testscale.c | 4 +- test/testsem.c | 2 +- test/testsensor.c | 2 +- test/testshader.c | 7 +- test/testshape.c | 2 +- test/testsprite2.c | 6 +- test/testspriteminimal.c | 6 +- test/teststreaming.c | 4 +- test/testsurround.c | 2 +- test/testthread.c | 17 +- test/testtimer.c | 2 +- test/testurl.c | 2 +- test/testutils.c | 2 +- test/testutils.h | 2 +- test/testver.c | 2 +- test/testviewport.c | 4 +- test/testvulkan.c | 2 +- test/testwm2.c | 4 +- test/testyuv.c | 2 +- test/testyuv_cvt.c | 2 +- test/testyuv_cvt.h | 2 +- test/torturethread.c | 13 +- test/watcom.mif | 4 +- visualtest/COPYING.txt | 18 + visualtest/Makefile.in | 44 + visualtest/README.txt | 214 + visualtest/acinclude.m4 | 337 ++ visualtest/autogen.sh | 11 + .../testsprite2_blendmodes.actions | 3 + .../testsprite2_blendmodes.config | 5 + .../testsprite2_blendmodes.parameters | 5 + .../testsprite2_crashtest.actions | 1 + .../testsprite2_crashtest.config | 5 + .../testsprite2_crashtest.parameters | 24 + .../testsprite2_fullscreen.actions | 3 + .../testsprite2_fullscreen.config | 5 + .../testsprite2_fullscreen.parameters | 5 + .../testsprite2_geometry.actions | 3 + .../testsprite2_geometry.config | 5 + .../testsprite2_geometry.parameters | 5 + visualtest/configure | 4442 +++++++++++++++++ visualtest/configure.ac | 41 + visualtest/docs/Doxyfile | 1936 +++++++ .../SDL_visualtest_action_configparser.h | 149 + .../SDL_visualtest_exhaustive_variator.h | 64 + .../SDL_visualtest_harness_argparser.h | 75 + .../include/SDL_visualtest_mischelper.h | 28 + .../include/SDL_visualtest_parsehelper.h | 46 + visualtest/include/SDL_visualtest_process.h | 112 + .../include/SDL_visualtest_random_variator.h | 61 + visualtest/include/SDL_visualtest_rwhelper.h | 87 + .../include/SDL_visualtest_screenshot.h | 52 + .../include/SDL_visualtest_sut_configparser.h | 105 + .../include/SDL_visualtest_variator_common.h | 122 + visualtest/include/SDL_visualtest_variators.h | 66 + visualtest/launch_harness.cmd | 2 + visualtest/launch_harness.sh | 6 + visualtest/src/action_configparser.c | 399 ++ visualtest/src/harness_argparser.c | 358 ++ visualtest/src/linux/linux_process.c | 208 + visualtest/src/mischelper.c | 28 + visualtest/src/parsehelper.c | 231 + visualtest/src/rwhelper.c | 131 + visualtest/src/screenshot.c | 136 + visualtest/src/sut_configparser.c | 232 + visualtest/src/testharness.c | 532 ++ visualtest/src/variator_common.c | 225 + visualtest/src/variator_exhaustive.c | 133 + visualtest/src/variator_random.c | 113 + visualtest/src/variators.c | 95 + visualtest/src/windows/windows_process.c | 283 ++ visualtest/src/windows/windows_screenshot.c | 349 ++ visualtest/testsprite2_sample.actions | 3 + visualtest/testsprite2_sample.config | 6 + visualtest/testsprite2_sample.parameters | 29 + visualtest/unittest/testquit.actions | 1 + visualtest/unittest/testquit.c | 102 + visualtest/unittest/testquit.config | 5 + visualtest/unittest/testquit.parameters | 3 + 1194 files changed, 18651 insertions(+), 3034 deletions(-) create mode 100644 .clang-format create mode 100644 .editorconfig create mode 100644 .git-hash create mode 100644 .wikiheaders-options create mode 100644 REVISION.txt delete mode 100644 SDL2.spec delete mode 100644 VERSION.txt create mode 120000 android-project-ant/AndroidManifest.xml create mode 100644 android-project-ant/ant.properties create mode 100644 android-project-ant/build.properties create mode 100644 android-project-ant/build.xml create mode 100644 android-project-ant/default.properties create mode 100644 android-project-ant/jni/Android.mk create mode 100644 android-project-ant/jni/Application.mk create mode 100644 android-project-ant/jni/src/Android.mk create mode 100644 android-project-ant/jni/src/Android_static.mk create mode 100644 android-project-ant/proguard-project.txt create mode 100644 android-project-ant/project.properties create mode 100644 android-project-ant/res/drawable-hdpi/ic_launcher.png create mode 100644 android-project-ant/res/drawable-mdpi/ic_launcher.png create mode 100644 android-project-ant/res/drawable-xhdpi/ic_launcher.png create mode 100644 android-project-ant/res/drawable-xxhdpi/ic_launcher.png create mode 100644 android-project-ant/res/layout/main.xml create mode 100644 android-project-ant/res/values/strings.xml create mode 120000 android-project-ant/src create mode 100755 build-scripts/build-release.py create mode 100644 build-scripts/cmake-toolchain-mingw64-i686.cmake create mode 100644 build-scripts/cmake-toolchain-mingw64-x86_64.cmake create mode 100755 build-scripts/create-release.py create mode 100644 build-scripts/release-info.json create mode 100755 build-scripts/setup-gdk-desktop.py create mode 100644 cmake/test/jni/Android.mk create mode 100644 cmake/test/sdltest.c create mode 100644 mingw/pkg-support/INSTALL.txt create mode 100644 mingw/pkg-support/Makefile create mode 100644 src/hidapi/android/jni/Android.mk create mode 100644 src/locale/psp/SDL_syslocale.c create mode 100644 visualtest/COPYING.txt create mode 100644 visualtest/Makefile.in create mode 100644 visualtest/README.txt create mode 100644 visualtest/acinclude.m4 create mode 100755 visualtest/autogen.sh create mode 100644 visualtest/configs/testsprite2_blendmodes/testsprite2_blendmodes.actions create mode 100644 visualtest/configs/testsprite2_blendmodes/testsprite2_blendmodes.config create mode 100644 visualtest/configs/testsprite2_blendmodes/testsprite2_blendmodes.parameters create mode 100644 visualtest/configs/testsprite2_crashtest/testsprite2_crashtest.actions create mode 100644 visualtest/configs/testsprite2_crashtest/testsprite2_crashtest.config create mode 100644 visualtest/configs/testsprite2_crashtest/testsprite2_crashtest.parameters create mode 100644 visualtest/configs/testsprite2_fullscreen/testsprite2_fullscreen.actions create mode 100644 visualtest/configs/testsprite2_fullscreen/testsprite2_fullscreen.config create mode 100644 visualtest/configs/testsprite2_fullscreen/testsprite2_fullscreen.parameters create mode 100644 visualtest/configs/testsprite2_geometry/testsprite2_geometry.actions create mode 100644 visualtest/configs/testsprite2_geometry/testsprite2_geometry.config create mode 100644 visualtest/configs/testsprite2_geometry/testsprite2_geometry.parameters create mode 100755 visualtest/configure create mode 100644 visualtest/configure.ac create mode 100644 visualtest/docs/Doxyfile create mode 100644 visualtest/include/SDL_visualtest_action_configparser.h create mode 100644 visualtest/include/SDL_visualtest_exhaustive_variator.h create mode 100644 visualtest/include/SDL_visualtest_harness_argparser.h create mode 100644 visualtest/include/SDL_visualtest_mischelper.h create mode 100644 visualtest/include/SDL_visualtest_parsehelper.h create mode 100644 visualtest/include/SDL_visualtest_process.h create mode 100644 visualtest/include/SDL_visualtest_random_variator.h create mode 100644 visualtest/include/SDL_visualtest_rwhelper.h create mode 100644 visualtest/include/SDL_visualtest_screenshot.h create mode 100644 visualtest/include/SDL_visualtest_sut_configparser.h create mode 100644 visualtest/include/SDL_visualtest_variator_common.h create mode 100644 visualtest/include/SDL_visualtest_variators.h create mode 100644 visualtest/launch_harness.cmd create mode 100755 visualtest/launch_harness.sh create mode 100644 visualtest/src/action_configparser.c create mode 100644 visualtest/src/harness_argparser.c create mode 100644 visualtest/src/linux/linux_process.c create mode 100644 visualtest/src/mischelper.c create mode 100644 visualtest/src/parsehelper.c create mode 100644 visualtest/src/rwhelper.c create mode 100644 visualtest/src/screenshot.c create mode 100644 visualtest/src/sut_configparser.c create mode 100644 visualtest/src/testharness.c create mode 100644 visualtest/src/variator_common.c create mode 100644 visualtest/src/variator_exhaustive.c create mode 100644 visualtest/src/variator_random.c create mode 100644 visualtest/src/variators.c create mode 100644 visualtest/src/windows/windows_process.c create mode 100644 visualtest/src/windows/windows_screenshot.c create mode 100644 visualtest/testsprite2_sample.actions create mode 100644 visualtest/testsprite2_sample.config create mode 100644 visualtest/testsprite2_sample.parameters create mode 100644 visualtest/unittest/testquit.actions create mode 100644 visualtest/unittest/testquit.c create mode 100644 visualtest/unittest/testquit.config create mode 100644 visualtest/unittest/testquit.parameters diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..e98e5cd --- /dev/null +++ b/.clang-format @@ -0,0 +1,90 @@ +--- +AlignConsecutiveMacros: Consecutive +AlignConsecutiveAssignments: None +AlignConsecutiveBitFields: None +AlignConsecutiveDeclarations: None +AlignEscapedNewlines: Right +AlignOperands: Align +AlignTrailingComments: true + +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortEnumsOnASingleLine: true +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: Never +AllowShortLoopsOnASingleLine: false + +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: MultiLine + +# Custom brace breaking +BreakBeforeBraces: Custom +BraceWrapping: + AfterCaseLabel: true + AfterClass: true + AfterControlStatement: Never + AfterEnum: true + AfterFunction: true + AfterNamespace: true + AfterObjCDeclaration: true + AfterStruct: true + AfterUnion: true + AfterExternBlock: false + BeforeElse: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + +# Make the closing brace of container literals go to a new line +Cpp11BracedListStyle: false + +# Never format includes +IncludeBlocks: Preserve +# clang-format version 4.0 through 12.0: +#SortIncludes: false +# clang-format version 13.0+: +#SortIncludes: Never + +# No length limit, in case it breaks macros, you can +# disable it with /* clang-format off/on */ comments +ColumnLimit: 0 + +IndentWidth: 4 +ContinuationIndentWidth: 4 +IndentCaseLabels: false +IndentCaseBlocks: false +IndentGotoLabels: true +IndentPPDirectives: None +IndentExternBlock: NoIndent + +PointerAlignment: Right +SpaceAfterCStyleCast: false +SpacesInCStyleCastParentheses: false +SpacesInConditionalStatement: false +SpacesInContainerLiterals: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeParens: ControlStatements +SpaceAroundPointerQualifiers: Default +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false + +UseCRLF: false +UseTab: Never + +ForEachMacros: + [ + "spa_list_for_each", + "spa_list_for_each_safe", + "wl_list_for_each", + "wl_array_for_each", + "udev_list_entry_foreach", + ] + +--- + diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..cdd3c4e --- /dev/null +++ b/.editorconfig @@ -0,0 +1,79 @@ +# For format see editorconfig.org +# Copyright 2022 Collabora Ltd. +# SPDX-License-Identifier: Zlib + +root = true + +[*.{c,cg,cpp,gradle,h,java,m,metal,pl,py,S,sh,txt}] +indent_size = 4 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[*.{html,js,json,m4,yml,yaml,vcxproj,vcxproj.filters}] +indent_size = 2 +indent_style = space + +[*.xml] +indent_size = 4 +indent_style = space + +[{CMakeLists.txt,sdl2-config*.cmake.in,cmake/*.cmake}] +indent_size = 2 +indent_style = space + +[{cmake_uninstall.cmake.in,test/CMakeLists.txt}] +indent_size = 4 +indent_style = space + +[configure.ac] +# Inconsistently 2-, 4- or occasionally 3-space indented, but mostly 4, +# so let's use 4 for new code +indent_size = 4 +indent_style = space + +[{Makefile.*,*.mk,*.sln,*.pbxproj,*.plist}] +indent_size = 8 +indent_style = tab +tab_width = 8 + +[Makefile.os2] +indent_size = 4 +indent_style = space + +[test/Makefile.os2] +indent_size = 2 +indent_style = space + +[{src/core/os2/geniconv/makefile,src/core/os2/geniconv/os2cp.c}] +indent_size = 2 +indent_style = space + +[src/joystick/controller_type.*] +indent_style = tab + +[src/joystick/hidapi/steam/*.h] +indent_style = tab + +[src/libm/*.c] +indent_style = tab + +[src/test/SDL_test_{crc32,md5,random}.c] +indent_size = 2 +indent_style = space + +[src/video/yuv2rgb/*.{c,h}] +indent_style = tab + +[wayland-protocols/*.xml] +indent_size = 2 +indent_style = space + +[*.{markdown,md}] +indent_size = 4 +indent_style = space +# Markdown syntax treats tabs as 4 spaces +tab_width = 4 + +[{*.bat,*.rc}] +end_of_line = crlf diff --git a/.git-hash b/.git-hash new file mode 100644 index 0000000..1bd4cec --- /dev/null +++ b/.git-hash @@ -0,0 +1 @@ +fa24d868ac2f8fd558e4e914c9863411245db8fd diff --git a/.wikiheaders-options b/.wikiheaders-options new file mode 100644 index 0000000..634840e --- /dev/null +++ b/.wikiheaders-options @@ -0,0 +1,17 @@ +projectfullname = SDL2 +projectshortname = SDL2 +incsubdir = include +wikisubdir = SDL2 +readmesubdir = docs +apiprefixregex = (SDL_|SDLK_|KMOD_|AUDIO_) +mainincludefname = SDL.h +versionfname = include/SDL_version.h +versionmajorregex = \A\#define\s+SDL_MAJOR_VERSION\s+(\d+)\Z +versionminorregex = \A\#define\s+SDL_MINOR_VERSION\s+(\d+)\Z +versionpatchregex = \A\#define\s+SDL_PATCHLEVEL\s+(\d+)\Z +selectheaderregex = \ASDL.*?\.h\Z +projecturl = https://libsdl.org/ +wikiurl = https://wiki.libsdl.org/SDL2 +bugreporturl = https://github.com/libsdl-org/sdlwiki/issues/new +warn_about_missing = 0 +wikipreamble = (This is the legacy documentation for stable SDL2, the current stable version; [SDL3](https://wiki.libsdl.org/SDL3/) is the current development version.) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7f146a5..4bbf9d1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ 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) +cmake_minimum_required(VERSION 3.0.0...3.10) project(SDL2 C CXX) if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR) @@ -33,8 +33,8 @@ set(PKGCONFIG_DEPENDS) add_library(sdl-build-options INTERFACE) if(WINDOWS_STORE) - target_compile_definitions(sdl-build-options INTERFACE "-DSDL_BUILDING_WINRT=1") - target_compile_options(sdl-build-options INTERFACE "-ZW") + target_compile_definitions(sdl-build-options INTERFACE "-DSDL_BUILDING_WINRT=1" "WINAPI_FAMILY=WINAPI_FAMILY_APP") + target_compile_options(sdl-build-options INTERFACE "$<$:-ZW>" "$<$:-EHsc>") endif() # CMake 3.0 expands the "if(${A})" in "set(OFF 1);set(A OFF);if(${A})" to "if(1)" @@ -87,7 +87,7 @@ endif() # See docs/release_checklist.md set(SDL_MAJOR_VERSION 2) set(SDL_MINOR_VERSION 30) -set(SDL_MICRO_VERSION 0) +set(SDL_MICRO_VERSION 11) set(SDL_VERSION "${SDL_MAJOR_VERSION}.${SDL_MINOR_VERSION}.${SDL_MICRO_VERSION}") # Set defaults preventing destination file conflicts @@ -241,7 +241,7 @@ endif() if(UNIX OR MINGW OR MSYS OR (USE_CLANG AND NOT WINDOWS) OR VITA OR PSP OR PS2 OR N3DS) set(OPT_DEF_LIBC ON) endif() -if(WINDOWS OR IOS OR TVOS) +if(WINDOWS OR DARWIN OR MACOSX OR IOS OR TVOS) set(SDL_SYSTEM_ICONV_DEFAULT OFF) else() set(SDL_SYSTEM_ICONV_DEFAULT ON) @@ -409,7 +409,7 @@ dep_option(SDL_SSE "Use SSE assembly routines" ON "SDL_ASSEMBLY; dep_option(SDL_SSE2 "Use SSE2 assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_X86 OR SDL_CPU_X64" OFF) dep_option(SDL_SSE3 "Use SSE3 assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_X86 OR SDL_CPU_X64" OFF) dep_option(SDL_MMX "Use MMX assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_X86 OR SDL_CPU_X64" OFF) -dep_option(SDL_3DNOW "Use 3Dnow! MMX assembly routines" ON "SDL_ASSEMBLY;SDL_CPU_X86 OR SDL_CPU_X64" OFF) +dep_option(SDL_3DNOW "Use 3Dnow! MMX assembly routines" OFF "SDL_ASSEMBLY;SDL_CPU_X86 OR SDL_CPU_X64" OFF) dep_option(SDL_ALTIVEC "Use Altivec assembly routines" ON "SDL_ASSEMBLY" OFF) dep_option(SDL_ARMSIMD "Use SIMD assembly blitters on ARM" OFF "SDL_ASSEMBLY;SDL_CPU_ARM32" OFF) dep_option(SDL_ARMNEON "Use NEON assembly blitters on ARM" OFF "SDL_ASSEMBLY;SDL_CPU_ARM32" OFF) @@ -926,22 +926,6 @@ if(SDL_ASSEMBLY) endif() endif() - if(SDL_LASX) - cmake_push_check_state() - set(CMAKE_REQUIRED_FLAGS "-mlasx") - check_c_source_compiles(" - #ifndef __loongarch_asx - #error Assembler CPP flag not enabled - #endif - int main(int argc, char **argv) { return 0; }" CPU_SUPPORTS_LASX) - check_include_file("lasxintrin.h" HAVE_LASXINTRIN_H) - cmake_pop_check_state() - if(CPU_SUPPORTS_LASX AND HAVE_LASXINTRIN_H) - list(APPEND EXTRA_CFLAGS "-mlasx") - set(HAVE_LASX TRUE) - endif() - endif() - if(SDL_ARMSIMD) set(ORIG_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}") set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -x assembler-with-cpp") @@ -1107,6 +1091,8 @@ if(SDL_LIBC) check_symbol_exists(getauxval "sys/auxv.h" HAVE_GETAUXVAL) check_symbol_exists(elf_aux_info "sys/auxv.h" HAVE_ELF_AUX_INFO) check_symbol_exists(poll "poll.h" HAVE_POLL) + check_symbol_exists(memfd_create "sys/mman.h" HAVE_MEMFD_CREATE) + check_symbol_exists(posix_fallocate "fcntl.h" HAVE_POSIX_FALLOCATE) check_library_exists(m pow "" HAVE_LIBM) if(HAVE_LIBM) @@ -1688,7 +1674,7 @@ elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU) if(FREEBSD OR NETBSD OR OPENBSD OR BSDI) CheckUSBHID() endif() - if(LINUX AND HAVE_LINUX_INPUT_H AND NOT ANDROID) + if((LINUX OR FREEBSD) AND HAVE_LINUX_INPUT_H AND NOT ANDROID) set(SDL_JOYSTICK_LINUX 1) file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/linux/*.c ${SDL2_SOURCE_DIR}/src/joystick/steam/*.c) list(APPEND SOURCE_FILES ${JOYSTICK_SOURCES}) @@ -1791,14 +1777,6 @@ elseif(WINDOWS) list(APPEND SOURCE_FILES ${WINRT_SOURCE_FILES}) endif() - if(MSVC AND NOT SDL_LIBC) - # Prevent codegen that would use the VC runtime libraries. - set_property(DIRECTORY . APPEND PROPERTY COMPILE_OPTIONS "/GS-;/Gs1048576") - if(NOT ARCH_64 AND NOT CMAKE_GENERATOR_PLATFORM STREQUAL "ARM") - set_property(DIRECTORY . APPEND PROPERTY COMPILE_OPTIONS "/arch:SSE") - endif() - endif() - if(SDL_MISC) if(WINDOWS_STORE) file(GLOB MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/winrt/*.cpp) @@ -1824,13 +1802,11 @@ elseif(WINDOWS) check_include_file(d3d9.h HAVE_D3D_H) check_include_file(d3d11_1.h HAVE_D3D11_H) check_c_source_compiles(" - #include - #include #include + #include ID3D12Device1 *device; - #if WDK_NTDDI_VERSION > 0x0A000008 - int main(int argc, char **argv) { return 0; } - #endif" HAVE_D3D12_H) + int main(int argc, char **argv) {return 0; } + " HAVE_D3D12_H) check_include_file(ddraw.h HAVE_DDRAW_H) check_include_file(dsound.h HAVE_DSOUND_H) check_include_file(dinput.h HAVE_DINPUT_H) @@ -2689,6 +2665,11 @@ elseif(PSP) list(APPEND SOURCE_FILES ${PSP_THREAD_SOURCES}) set(HAVE_SDL_THREADS TRUE) endif() + if(SDL_LOCALE) + file(GLOB PSP_LOCALE_SOURCES ${SDL2_SOURCE_DIR}/src/locale/psp/*.c) + list(APPEND SOURCE_FILES ${PSP_LOCALE_SOURCES}) + set(HAVE_SDL_LOCALE TRUE) + endif() if(SDL_TIMERS) set(SDL_TIMER_PSP 1) file(GLOB PSP_TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/psp/*.c) @@ -2721,7 +2702,6 @@ elseif(PSP) endif() elseif(PS2) - list(APPEND EXTRA_CFLAGS "-DPS2" "-D__PS2__" "-I$ENV{PS2SDK}/ports/include" "-I$ENV{PS2DEV}/gsKit/include") file(GLOB PS2_MAIN_SOURCES ${SDL2_SOURCE_DIR}/src/main/ps2/*.c) set(SDLMAIN_SOURCES ${SDLMAIN_SOURCES} ${PS2_MAIN_SOURCES}) @@ -3077,8 +3057,8 @@ endif() # Compat helpers for the configuration files -if(EXISTS "${PROJECT_SOURCE_DIR}/VERSION.txt") - file(READ "${PROJECT_SOURCE_DIR}/VERSION.txt" SDL_SOURCE_VERSION) +if(EXISTS "${PROJECT_SOURCE_DIR}/REVISION.txt") + file(READ "${PROJECT_SOURCE_DIR}/REVISION.txt" SDL_SOURCE_VERSION) string(STRIP "${SDL_SOURCE_VERSION}" SDL_SOURCE_VERSION) endif() @@ -3543,6 +3523,23 @@ if(SDL_TEST) set_property(TARGET SDL2_test PROPERTY INTERFACE_SDL_VERSION "SDL2") endif() +if(MSVC AND NOT SDL_LIBC) + set(targets ) + if(TARGET SDL2) + list(APPEND targets SDL2) + endif() + if(TARGET SDL2-static) + list(APPEND targets SDL2-static) + endif() + if(TARGET SDL2_test) + list(APPEND targets SDL2_test) + endif() + set_property(TARGET ${targets} APPEND PROPERTY COMPILE_OPTIONS "/GS-;/Gs1048576") + if(NOT ARCH_64 AND NOT CMAKE_GENERATOR_PLATFORM STREQUAL "ARM") + set_property(TARGET ${targets} APPEND PROPERTY COMPILE_OPTIONS "/arch:SSE") + endif() +endif() + ##### Installation targets ##### if(NOT SDL2_DISABLE_INSTALL) if(SDL_SHARED) diff --git a/LICENSE.txt b/LICENSE.txt index 74bb56c..23abb73 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (C) 1997-2024 Sam Lantinga +Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/Makefile.in b/Makefile.in index eb4c4bc..27e0bbb 100644 --- a/Makefile.in +++ b/Makefile.in @@ -52,7 +52,7 @@ WAYLAND_SCANNER_CODE_MODE = @WAYLAND_SCANNER_CODE_MODE@ INSTALL_SDL2_CONFIG = @INSTALL_SDL2_CONFIG@ -SRC_DIST = *.md *.txt acinclude Android.mk autogen.sh android-project build-scripts cmake cmake_uninstall.cmake.in configure configure.ac docs include Makefile.* mingw sdl2-config.cmake.in sdl2-config-version.cmake.in sdl2-config.in sdl2.m4 sdl2.pc.in SDL2.spec.in SDL2Config.cmake.in src test VisualC VisualC-WinRT Xcode Xcode-iOS wayland-protocols +SRC_DIST = *.md *.txt acinclude Android.mk autogen.sh android-project build-scripts cmake cmake_uninstall.cmake.in configure configure.ac docs include Makefile.* mingw sdl2-config.cmake.in sdl2-config-version.cmake.in sdl2-config.in sdl2.m4 sdl2.pc.in SDL2.spec.in SDL2Config.cmake.in src test VisualC VisualC-GDK VisualC-WinRT Xcode Xcode-iOS wayland-protocols GEN_DIST = SDL2.spec ifneq ($V,1) diff --git a/Makefile.os2 b/Makefile.os2 index afd5f44..3647a38 100644 --- a/Makefile.os2 +++ b/Makefile.os2 @@ -15,7 +15,7 @@ LIBNAME = SDL2 MAJOR_VERSION = 2 MINOR_VERSION = 30 -MICRO_VERSION = 0 +MICRO_VERSION = 11 VERSION = $(MAJOR_VERSION).$(MINOR_VERSION).$(MICRO_VERSION) DESCRIPTION = Simple DirectMedia Layer 2 diff --git a/Makefile.w32 b/Makefile.w32 index bd28c07..4680b59 100644 --- a/Makefile.w32 +++ b/Makefile.w32 @@ -6,7 +6,7 @@ LIBNAME = SDL2 MAJOR_VERSION = 2 MINOR_VERSION = 30 -MICRO_VERSION = 0 +MICRO_VERSION = 11 VERSION = $(MAJOR_VERSION).$(MINOR_VERSION).$(MICRO_VERSION) LIBHOME = . diff --git a/REVISION.txt b/REVISION.txt new file mode 100644 index 0000000..1776500 --- /dev/null +++ b/REVISION.txt @@ -0,0 +1 @@ +release-2.30.11-0-gfa24d868a diff --git a/SDL2.spec b/SDL2.spec deleted file mode 100644 index e7be9d6..0000000 --- a/SDL2.spec +++ /dev/null @@ -1,119 +0,0 @@ -Summary: Simple DirectMedia Layer -Name: SDL2 -Version: 2.30.0 -Release: 2 -Source: http://www.libsdl.org/release/%{name}-%{version}.tar.gz -URL: http://www.libsdl.org/ -License: zlib -Group: System Environment/Libraries -BuildRoot: %{_tmppath}/%{name}-%{version}-buildroot -Prefix: %{_prefix} -%ifos linux -Provides: libSDL2-2.0.so.0 -%endif - -%define __defattr %defattr(-,root,root) -%define __soext so - -%description -This is the Simple DirectMedia Layer, a generic API that provides low -level access to audio, keyboard, mouse, and display framebuffer across -multiple platforms. - -%package devel -Summary: Libraries, includes and more to develop SDL applications. -Group: Development/Libraries -Requires: %{name} = %{version} - -%description devel -This is the Simple DirectMedia Layer, a generic API that provides low -level access to audio, keyboard, mouse, and display framebuffer across -multiple platforms. - -This is the libraries, include files and other resources you can use -to develop SDL applications. - - -%prep -%setup -q - -%build -%ifos linux -CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{prefix} --disable-video-directfb -%else -%configure -%endif -make - -%install -rm -rf $RPM_BUILD_ROOT -%ifos linux -make install prefix=$RPM_BUILD_ROOT%{prefix} \ - bindir=$RPM_BUILD_ROOT%{_bindir} \ - libdir=$RPM_BUILD_ROOT%{_libdir} \ - includedir=$RPM_BUILD_ROOT%{_includedir} \ - datadir=$RPM_BUILD_ROOT%{_datadir} \ - mandir=$RPM_BUILD_ROOT%{_mandir} -%else -%makeinstall -%endif - -%clean -rm -rf $RPM_BUILD_ROOT - -%files -%{__defattr} -%doc README*.txt LICENSE.txt CREDITS.txt BUGS.txt -%{_libdir}/lib*.%{__soext}.* - -%files devel -%{__defattr} -%doc docs/README*.md -%{_bindir}/*-config -%{_libdir}/lib*.a -%{_libdir}/lib*.la -%{_libdir}/lib*.%{__soext} -%{_includedir}/*/*.h -%{_libdir}/cmake/* -%{_libdir}/pkgconfig/SDL2/* -%{_datadir}/aclocal/* - -%changelog -* Thu Jun 04 2015 Ryan C. Gordon -- Fixed README paths. - -* Sun Dec 07 2014 Simone Contini -- Fixed changelog date issue and docs filenames - -* Sun Jan 22 2012 Sam Lantinga -- Updated for SDL 2.0 - -* Tue May 16 2006 Sam Lantinga -- Removed support for Darwin, due to build problems on ps2linux - -* Sat Jan 03 2004 Anders Bjorklund -- Added support for Darwin, updated spec file - -* Wed Jan 19 2000 Sam Lantinga -- Re-integrated spec file into SDL distribution -- 'name' and 'version' come from configure -- Some of the documentation is devel specific -- Removed SMP support from %build - it doesn't work with libtool anyway - -* Tue Jan 18 2000 Hakan Tandogan -- Hacked Mandrake sdl spec to build 1.1 - -* Sun Dec 19 1999 John Buswell -- Build Release - -* Sat Dec 18 1999 John Buswell -- Add symlink for libSDL-1.0.so.0 required by sdlbomber -- Added docs - -* Thu Dec 09 1999 Lenny Cartier -- v 1.0.0 - -* Mon Nov 1 1999 Chmouel Boudjnah -- First spec file for Mandrake distribution. - -# end of file diff --git a/VERSION.txt b/VERSION.txt deleted file mode 100644 index 4426dd6..0000000 --- a/VERSION.txt +++ /dev/null @@ -1 +0,0 @@ -release-2.30.0-0-g859844eae diff --git a/android-project-ant/AndroidManifest.xml b/android-project-ant/AndroidManifest.xml new file mode 120000 index 0000000..94bcaef --- /dev/null +++ b/android-project-ant/AndroidManifest.xml @@ -0,0 +1 @@ +../android-project/app/src/main/AndroidManifest.xml \ No newline at end of file diff --git a/android-project-ant/ant.properties b/android-project-ant/ant.properties new file mode 100644 index 0000000..b0971e8 --- /dev/null +++ b/android-project-ant/ant.properties @@ -0,0 +1,17 @@ +# This file is used to override default values used by the Ant build system. +# +# This file must be checked into Version Control Systems, as it is +# integral to the build system of your project. + +# This file is only used by the Ant script. + +# You can use this to override default values such as +# 'source.dir' for the location of your java source folder and +# 'out.dir' for the location of your output folder. + +# You can also use it define how the release builds are signed by declaring +# the following properties: +# 'key.store' for the location of your keystore and +# 'key.alias' for the name of the key to use. +# The password will be asked during the build when you use the 'release' target. + diff --git a/android-project-ant/build.properties b/android-project-ant/build.properties new file mode 100644 index 0000000..edc7f23 --- /dev/null +++ b/android-project-ant/build.properties @@ -0,0 +1,17 @@ +# This file is used to override default values used by the Ant build system. +# +# This file must be checked in Version Control Systems, as it is +# integral to the build system of your project. + +# This file is only used by the Ant script. + +# You can use this to override default values such as +# 'source.dir' for the location of your java source folder and +# 'out.dir' for the location of your output folder. + +# You can also use it define how the release builds are signed by declaring +# the following properties: +# 'key.store' for the location of your keystore and +# 'key.alias' for the name of the key to use. +# The password will be asked during the build when you use the 'release' target. + diff --git a/android-project-ant/build.xml b/android-project-ant/build.xml new file mode 100644 index 0000000..9f19a07 --- /dev/null +++ b/android-project-ant/build.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-project-ant/default.properties b/android-project-ant/default.properties new file mode 100644 index 0000000..0a69b77 --- /dev/null +++ b/android-project-ant/default.properties @@ -0,0 +1,11 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "build.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=android-16 diff --git a/android-project-ant/jni/Android.mk b/android-project-ant/jni/Android.mk new file mode 100644 index 0000000..5053e7d --- /dev/null +++ b/android-project-ant/jni/Android.mk @@ -0,0 +1 @@ +include $(call all-subdir-makefiles) diff --git a/android-project-ant/jni/Application.mk b/android-project-ant/jni/Application.mk new file mode 100644 index 0000000..5ea0fb4 --- /dev/null +++ b/android-project-ant/jni/Application.mk @@ -0,0 +1,10 @@ + +# Uncomment this if you're using STL in your project +# See CPLUSPLUS-SUPPORT.html in the NDK documentation for more information +# APP_STL := stlport_static + +APP_ABI := armeabi armeabi-v7a x86 + +# Min SDK level +APP_PLATFORM=android-10 + diff --git a/android-project-ant/jni/src/Android.mk b/android-project-ant/jni/src/Android.mk new file mode 100644 index 0000000..1adcb6e --- /dev/null +++ b/android-project-ant/jni/src/Android.mk @@ -0,0 +1,18 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := main + +SDL_PATH := ../SDL + +LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/include + +# Add your application source files here... +LOCAL_SRC_FILES := YourSourceHere.c + +LOCAL_SHARED_LIBRARIES := SDL2 + +LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -llog + +include $(BUILD_SHARED_LIBRARY) diff --git a/android-project-ant/jni/src/Android_static.mk b/android-project-ant/jni/src/Android_static.mk new file mode 100644 index 0000000..faed669 --- /dev/null +++ b/android-project-ant/jni/src/Android_static.mk @@ -0,0 +1,12 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := main + +LOCAL_SRC_FILES := YourSourceHere.c + +LOCAL_STATIC_LIBRARIES := SDL2_static + +include $(BUILD_SHARED_LIBRARY) +$(call import-module,SDL)LOCAL_PATH := $(call my-dir) diff --git a/android-project-ant/proguard-project.txt b/android-project-ant/proguard-project.txt new file mode 100644 index 0000000..f2fe155 --- /dev/null +++ b/android-project-ant/proguard-project.txt @@ -0,0 +1,20 @@ +# To enable ProGuard in your project, edit project.properties +# to define the proguard.config property as described in that file. +# +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in ${sdk.dir}/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the ProGuard +# include property in project.properties. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/android-project-ant/project.properties b/android-project-ant/project.properties new file mode 100644 index 0000000..9b84a6b --- /dev/null +++ b/android-project-ant/project.properties @@ -0,0 +1,14 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system edit +# "ant.properties", and override values to adapt the script to your +# project structure. +# +# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): +#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt + +# Project target. +target=android-16 diff --git a/android-project-ant/res/drawable-hdpi/ic_launcher.png b/android-project-ant/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..d50bdaae06ee5a8d3f39911f81715abd3bf7b24d GIT binary patch literal 2683 zcmV->3WW8EP)f5ia)v7o~R{NBhA5U9TS|y z#6;hys3;x?J}MJ`{(hg4#z_5C&8JGE%`?(Dh&7ZR;5Edpc?St%xW6qA@|?(P(S$9MfVM(#w*vFZ~ne7nXF-+jLy z3pO0UA{`?v-E_!bpo?j?Gb?HuKfY?*Y6jAmgpYBGQGoCzQqLE+m2$@j^psT86g0Dzxxz6?lr@v zAI>O+wDU;6_MNgvMsCp%K-&)W_v8M0`z(e*RJXOYci>rk5?WeXCkK$Nn;&K_*T<}t z2KZ+6UM${d1kW4cNJ`5^dR8Hx{G0@bD*;%$>!h$E?|^-0}z!=BRu5?hkP6@Ogv z4u+$90J*3OE&QwiAi**?dI2S+6$5};vE|@dY$Y+&O%nhl1@2!Gl2KRRpm{)AdPndd z0`#@Efv}=mcVnQ;(l{1*`G=#00IemfV=H1vEGa%o7aW(E27PifhQLW$2|q_UN6D*F%>lA;xrTo&-7&<9I2LiRp0{ovfjB1mq-N$10i;ct zje|BrT20xlvU+4dUIBLn2uT+9o&pfNrOw`d_hiU5bqx~+R7p3<_>40mA4ZR8MdJcg zN9k3vBE?uFWi%=6FVs1Rb51_!qWXgYE#G21nAtdZD+3fv^^qcs!{*LtYHl6ko(#FB zcH)2}Hwy>~K^3Kc&DB9<-lpfT2tYGOfyAlbiLw*}QcV9`Cn*EuAM$Vz1k2d+q5#CD z1!qQ)9mz^H1*oB+0Y29Qkdm6N`AWLFwq8`jW_DLamg0Cchaj=5ac#tqxOl9pt`{{D zTb|ZtV`z~zRVV?(>0biDvUc$$KrO=R*frS#8F00R0A2J9#BmFIM8`ax{JmJo>k6^$ zkRY)oF{t0DMq0G-pn%1ew3Jj)RXc2aJ5{*4hGzr>NgVte36NBsvjs9_O#tG!vx?@_ z*?kNV527XxsIjR9C(mCNE~Bh*`kqaJd(MEnF(?k$42p|NwxmULd>;^Btdqx00fHg0 z*n;XCngt-XI(AWpvqbkWsz)dj#?#WXa^QIB3hq&$o-iOzt$+S@qgc2*kAC-4(6ylZ{WpdHEg7&r z76Yy#7wsdcBWWz{PDCVZom>&0_(C&){xn+$f1S4pfB#MoUoF`#Dqdcksja&x@@8<* z9!UQjxLv)1#a?ReTEjt?V^9o^EsC?9WLfNjk{ceix`dvd-a*S;DU?;xa4w*pm=dCUbG||3d|jyT|-=ZzCz!A82iOMJRi@? z*2-4P)~gO6Bf2(T$NF8yaP#oiOdZ5`^rzrRQJ*lNzs=Jd28qQ%`1-8}gH<&Hnz=$> zSd>%_NF@PlAuV`=fho>8`ywr?V0bESY#9vv(imwDX-+ORX3|ZWp|w+NZB#Y?kVwo~ ztq(&JGo)u`YyN>*BW*_G5>mwjEUtcePZs_#j^ar%dVBkZJ%=f;sClQ#cj92nR;KDX z&Kv40Npbv;c`2@OZ0qYAJr1=|?6h@pqx5bKuj~FF|B-8NZ!bK53dY^Y7$m1=B0IN` z?piLT))-`D<eGMlqZD8Z*BCPwP1LACT^t3Hb zSUBLcwKMFTufpoWCG0(94r4mc53uYndf~LC1Kh6OfU)TXy2Dq+IX6##m|Hp0f*fIB zWClAY51Q)&-TB+1ue(nmtbV)<6Pm~9_&FNmDJ*WJrbD4&#ONnaCSdFrle(wV<(;G0Lec~;&WXDm0eFd*VFUvcLv@+SFhOX@$VT~`C^!f@uJqTv3Ewmtx&YLx2rW?eW>h6iOjLeVwUW_kFyo2iQ{wPrD>YIcsX6NSPW^gDjIQGIS#NHx3;!Y4bwd7VEFr<#61_=Am1B-@bL?Pf8cFAPx=jQYP!=$i$M*IO;j^A z(Xo+$wJCknI#x^d35=k$o-H7R-+O?dkTCcK1moxUM7%C7R~oFR^sDF2&Q824eS_-i z8dO$Rp|YwPk7++tU*ACWNQAD9BT%MP7UMMCL9wBUs`6^8Nh%0hX=xeKsdy|XdWnLG$1hoqF4ULrYyC&Ur^73*_XQ>2KTwII~rIL~omHLp^!%_(-FE0<%Stac7NPn23 p`a;b$d_J(|Pvw8BB{$8s{{bZLi_t)ny#xRN002ovPDHLkV1mMH1%3bk literal 0 HcmV?d00001 diff --git a/android-project-ant/res/drawable-mdpi/ic_launcher.png b/android-project-ant/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..0a299eb3cc0273ad1fc260cf0b4a2c35f5d373f5 GIT binary patch literal 1698 zcmV;T23`4yP)f} zu>|cMov+-ZzrP>60ufVbMfI5GD8S3sHU={Wz|3(0Iuu=S@d?FG>uvDs20IvRa=`Mf zj#y>tjJ0O2%(P!fEH>}&wob%R&H}5 zCGc-u(!|no5r`_`6U@PeT^`tAbpUc=l=XIx5}}*~W|%4>j>`bH?(t?i92~9nn5b`P z0>7Y$mEeQ`zFlE~MQf~ZG9n(urD7;YrS#B=Xsowzhmqy}5da!J%3kbpKFSQ6?LES3 zdZV=$HtqI=cTl8G16xp14uP;#cL2|TbNJ?WbCv}PLC1o@ra$3vG#sKQRjdsy89E-; znY%&Wrg-Hc0ikisFjZMa4gT2a!LsFbJVGacax#gWk55EjU*EU@vs5pnGl{G3Su9*> z!N$T5Ypq5G^s>zk;1`v_^H>BcvDMq12|&jy4-O2w$V^iek#aL6kcJj+tOIn78@KP` zS-n&hVAi+*!y%P5Bk6V~t9LpJEg6Dv^9^HW=&|J{j%XbP;NW?ZWriBBlQv?_b{7Wf z?jNR;`Laq0%pJT@Bot{6Kx_D6R>6O6CaG({;-O4fxdg!7FN{sE1|%b@0J(*wY`Ud# zI&>PHo!wYrvX5kIA6$-v>I9%5)46v*2=WER+5@z;cjB`jH^as)5b4Y=@KwIY|49kMQ$Jq^Dh2W~kwk@+x$8bu&m>dOMx`k@;AF zOr8K4IfY0k8eSOHMN@M#{DV%Rsz#yu)%WM&qwuw)N1vUEpCDpjN&f6V0!P?RG^g3&|W3X}!VA~OOk&(lPv85w2vT{aGqiO+W zYf57uSx8hDv*9QfJwZunB_z+Jkkm>cDyt-0fLi3{6{B7%LtVWLLei#2QU@6+!TiD! zl#~5aZJiXd#%46Pyg>bP8Oyk8^pf6|Hpt);7>u(~G3pkw+3Eo1=sLZnrDub4ArZ+b z_Yo2ni^%f{c*H9}V)8v)O}c|CM3)n8BIWKwa4ud)++{A##l(Y`E5KFmU4(Pu+2747 z*`g5=8ISd54mcALP0FuJ-Bx1G8vz)-chNQaRj#2MI5{az9zPF9gF_IX$VE?2kEYGs z!~iB@Qrq`{%xpdkcQ_(EDwdRD`FQUG69b?RqFdY^GAOBDH)`vilR+PWYe_e7@oFLp zi%XzX_GHnL8)uWgCx#|Gs=@G!ZNq|X!w*jD3DxnY32q2fsp%2msAeBm? z57GqikytE-K8Si%3m_B sCR#xB$vdJ2L!RajdHnFb`QMJe0XP&@60ho4VgLXD07*qoM6N<$f_SqK!TqaTn3XQ!tHPYHM zMO4&iY%%-veV@PJ`Ebs;u5&(|^Yz4;8tYtU;%5Q?;If{srukoW{y#9#{pID1*S7(H zg`}scZW%bcmF;ecvElDaT^OFJJjTv^$*;Ti;LFT#R`-WEepkZ;IVrQq7ItO*iUJ1n z;v!CUby^xpb51h`qadDQ-PB|$St=>r?<;Lb4MWPUi?XtJsq0AuzYBM|z>U2olP2<@ zbY(0U#rx>LB-a_6l%)ETOlA%3$Ky?iN2EJR#c{3NMpv?b^-vfY8B1X>n4E))iwl2S z>P?6Gf`DMp!mZxME!+2la*CeNvoPF3lf&aC9{Dh1@Ix;eH7=DwOo}Ny>LL$M;oty}0eDbZ3rlmO^PR@k-%G$Q?KH@6) z9|0;yPmkngLkG2L$N7NnZyRg?4FFOD{#Q{7JNb2unfcyoeyVVLsz`WuSDsG&6kOzM z(oKItI3iCc^y~mQ%fIT}MWRD4P!~LTcO~ zN?TPi3p;+XM*V8p)v%U_ghb!zTn0po4v++=>+FzbNFtDyx>rKvc|WUyw^e!K&>v{J zFVJx*yZmmkVV|aUu}$=!Tfv4r^$yc=Iibkpcdz%N)%_R3W0yyz&L}w?`ecAVd#-9> zp38#AqZ3zYC`;TJrUdSA56RE=g4vjnviLx#>cc95J)6+C5F7H6_Iq`0#aVy0A0G03 z)npczW4DqUF)qyq4A!z4(sd79CRkon5a66I4C!l5~s#Hn!OH;U$oxX z(m5UTx#^_${S6eoBaoGq>3%=U7U=Pq#6O`63%@{t0abe(twOp-k4KR@B%>)ubd#T| zy|W`-geXsqeN0qmaVd-I5v8G9ocok!53X2v5;=S-n4Dv_ZRk<5UH3d@f{pmMptof0 zhB!M-z8|}(6xoOwc+wX-hi>1J$FEua#%~SEi^Uda2cHlNPMxp}bf3#m{{k{98D&N&$q3t`7+q99srgYBV zPtIYYyqOuq$7-BNyLncIH(kH>(!KkaF#J)1C>rr5?4~53bSHuD-oUmv6~E6NJMzHs zKF=ql{{FwKfwj5i%)^QyvI^EvZUu3QU18Tp6$}np6v2dR`r zXy_jl2L>$%9OPA_Yp@0=kXq4UEtTYyg0|665VdS>PcS25g%%U#x;z#*CO^sUcSGpX z;E!6J|@D3c#F~W7GnIyu9+65Rx&X ziqH2FUaQM7Ay)RO0!Gs`?>{seSp}{q=%Gk1iEwN0$ITs}l~tb3`=Y#z1CqohUY&RJ z6Ekks*RY7;NAT+@u!4XqNVOMQl6=vz%_(1}-W302LaM20Q?m(jRVrcUza0-rGq$If zdutbpo8$#t6uN-spVbeZa6)e9Zma8R7WdLN`M`zMo?L$yk8!RO_Fe^U!Knh8aBA8c zS|;F(U2;6i?GtISz=|#nmjPE-9yHow2BPKUPn>lXh z0B3LiS|r%hG=h%KG-yM~`eh9wI#Izm|FXOwq9pB=;X`L+!u+zFBkutfh6fc>L@e#1 zoFrg)iYF|XOvFG1{NX|y^%BJL9_E}ZyZ$;b1g$Y^k$FY*ti0o6fyL0aabL@#2(L#y zo95C_RuP$w2MTFb)uTdIH3zdz3l#r=M`@zyBY)*xt17(~KE4AK;5H+)XP&db|^wJ&9U zx%0pXDI9#*01|h^x0})P2nP87oItCC&VILOQTA}}pEF=WE)I9<40|c0O|E8xu;9aQ z#&#^~_WUKZ)z7+oBL$;YxXkm=zR}|4-o9_X=6n7#(~A3qg9z!|y(*MH0wWde8C$@` zjWFax<#mt1pmLqJkEX~t#QR*1q-kZoT6Qs@Ew`E>JnMNeYCD~8@J>`4{+63?mBwXt zf}{c4J-p_JshFps+D;M!>Q9ki(7*Tzv4Xh zaW8pmgS7N+bDR51m#TpP4OV-oz<_;UJXSa@6)euMLYpPptP(5{vptey)of@uAj9ul zafunRFRLSunipGJtp5Wf6ozcGUAT}Y=8 zZqMzgm05wus~hy<0XK_4A1PCoub{b_MK!|g>{vz-hPwskLkruDMsftF(O2&pe6Q?q zh7P`68p`^7mtgqUn6D$^y2h}}2p=0@~ld?{6DBnwI z9&uWUZ_Fy^K(tj=_?$ZacK>9~tAtHqWPP z!y4`}{gNdZ`f$481iK|vQi9zxr^;ZC6jtC)pIE$zjEObS z?Ub|OzLGm{SMR4~`jqDMoI3ZdB(Nqsg6iE>gcKe8=-R305uCqgTebKGS-4CJvkILD zncC?GWzro$-*eS1u5QH~_bPjTn~jSWez-~-7uepsq}3Z02uuuGHd#1K_1(X-7VNLG zhAIuGDfgNZYs2!A>;iXol2kSh;=jrV1IW78b$VHH+=%rzW(!F1g9TZiLi z$Vus?wmmZn(NfIA{mI%)0UL#uMojc}f|Yf{n&5k>pl5!7`qSqPZ(jXWVTtbKg!iRh zL!Fvr^{y&8G^UO4OGCKH!9&`Z(ndE zInYzqS{md4uZ)E2K*?c}A&N>h&zK$0#m;_kw^-@mF_N1B{{DrnRqRi=-g&F=A?yrl zMei!H$W_@iEOVqLKQxUBvNk?EI1rd8UJd2aRCqgSG0TVUEpZ!{{EbZ^%a@nGI6i7r zJ}@1J%0?=-cM=3L8=}v8rpwp)EiJA8Eygh){tmuSxprV35uhjli2Wao6L_~mEKWP8EA)Gxio?JWcsReW8pf5C)m6f_plSIH5dw%#L z!CG{Ft&1%b0f+(&02Km|o!lvx%_M-Dr2s=2ME)W5`B}pm`5$-zTP^?q literal 0 HcmV?d00001 diff --git a/android-project-ant/res/drawable-xxhdpi/ic_launcher.png b/android-project-ant/res/drawable-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..d423dac2624cf0b5dc90821a15362bc29e5a1e6b GIT binary patch literal 6874 zcmZWuXHXMNw@yOuq4y#nO^P5TQloT`4$_N&G^I%=ln8>M1&}I8?;>E}r6yn@fPxe; z^dbb1-XuZkm+yXm-aB{Z+1)ccyU#hZGkebNIZ39*x^&cB)Bpg0PG3*U{CdpzPopHi z?$>qj9RL7VnZDLN%kbIVB5zAe{oDcclj<6nIx(ssC^DDf$B%^{Y70ML);W&St+tcp zRk>?D`*zaV9r4M@lGNpbDF~2YsTd_?2OQo}Dp?MH8Yd_qSWg)zXm{1A^eRuiS?-2K zmT*GH`nidRI^Ut7^Z8;LObFk7{)wSdKTE`@K;C=&{|F83k|H9%pe`-~l2vdx+)v|A z{~-&pX1~g0K9?Tp{c1^R{#F}?cKAC3^3uJ(QU+#nfo{Ot}SnVw?Wx8NRxT2 z#puhP-L24#J)8Mzw&$XE@7@)Vkf46IvEfA^IF&@6o^2bnOD9Jj2t?T1+4iN?*Jneb2FWLP4#Dg@}0kR zu)4NJR#R1V?|aTI>le8F3G@B>GmX<@Sr7ZL$J{U;%`>89b={TcQ{D$BjSIea)-c;` zg?pFtlO72*m6gK6qM{V<=I0&6_Cqvo?VnhMeX!2-n_0-I_lKFB6&fz&_&-pii`ED# z(hNa!%pvE0d5}vq+3kA-g11Vs8cYQE>Ue8%@sc*3PhsWcXq|*apywGEzoJlkDGOtu_yK(? zmc9wxu|tSH!%?rAdie>?Np`$Y3^g5Iv!!xcOa3 zH3}CuIVl=U3|;CAYnoyW=-t#n>V(i4g-?D*r=8*ZXyoO8|A`h`{9_MqK1xQ-TnO|O zp!xWb&dCftPRZ#alDz}Wz6W20xl{AcrPPa>K_x~L8!4Ohw>?JezS(caNfBZ_Uo}w! za1Sk}5S&A8F2~8f`EJ`UI@?C_(c_#)4?A5heXJ#IR+1B*w7Gqs<-MOW)%oakH^oEW znG_?x%Yb85(vng=tcb(?M_(O-gM;%4MQ@*Mp@O?ra%cBh>|ECyCzQ4q-e+u?+J%k^ zE^Y*yb0r)2F~8@%peYsf$zS6RUGA1)ciouo<2asB0`VmxfLx6frK2?sEP%8(C~D^s zyZG-dQ?Bye$f6ed5m?+o?FmZk?4B=4|8Prhr8aj$b<~Q0e8{FpnK$Va;jz7}+sVUk z{{*rW5O)yjutl(I8;3{;Rs-4>^zeddmAQ&-JGOy zJAtD#iAE_Hh(Keh{@D$=F;3=9@B6b&1x%zfS^&uhbyhfq+gRj2)j=fyU2jQC4Y+Rg zrz9JGV{)AS4&xqWbHtF?IlI-P_Mw+w8j(3k%za&@O*7I9FkTY$DegFDo?p+Bm}Z zzmM}xfX(aA-5^ot^7l>NXdj>~4h~cdWV0xGiv4ToswbTE*aeU&{W9;Twi9pyMs67p zMZ3>U_O+RG@s%_w^m^T$p zzmYlA&>qYJ|}XuHmhMF|J`AX7HzCE2rE*!tr_#G1P5-DGHyaa5>KYBj`P1{LpMQ ziGxi6TH)yp7^h&29l3?^g)9l1GRwGAXW;m>q!cXkYWaN7VILj>D#>-9zeF38cQgSd z>O0a$#pI{AdKfxS$eQFIx|_ju%=0P$m7_E>=sj2!^Cw3{?1p}7h4i*lh&3F-Y$4zZ zXF>EhxlBnxlNVx5)2;0PP=i@E ziYGus!~4H%Bf`SV=Lth1Re#vXyl|-#e}@n=3z21IZXX!w0;OsYUDcD;d{BL&ZA%kS=|8$^S^J-nN#}98qKfdlDg^%&^4wBJkfE4ypN1<7X7@14Lx?gP-J*Zb-S& zvqdYj#`36J0B}X@@a4uR`0DIP9*you=CI_aY{C7mazg^7zFh6NWmf5`7)+I|z25mGU>^c0fLC<{Fm!28}60bw~`b7+f* z5t4we{&m1wop5C`E;1gr_&(y2ZOju{zA(d{?4*xlD+olgcJRD+MSr3sb%uxcC)V>M zjAUkp&HN`&6PiZ(^MBLowpNUl+Li7(L%X5K<%kdf1FjLqiS+v z=n3xx2)mFCN(0dw2A5f~KLP0_9YMHNxEK>E1}aRQ%)FxkhXsxdAA~+TzU|H^`|j-~ zz-8RjlB<&JXGjMgExNYcV^4S3;jtWacsRXJnU5I$sxfS4FT{oh3{zH+Pv($p)LoX^ z1|g(`j=1jk3W3@9l7_6u8yE!0$~&-zptujI`8NSub+@?RdbT-*^%t*?@~Qhw0<;!} z5npB2hj3uj-#Zk)L?TLcrLw*6J}Dbpcbvy)wgSX0#C-y?Ia0S>(f|t*-D#R-%arO& zNM_kXHRHBpD(KdyHpkVpYhQ%;kfF5IcnOB|SP{|(C1goP!>fNZQ?kbb?H-=c^qEI#ltqB;gAQqMOxe3OijU%Ab5L~lAd1;sXIJ8 zNt5Ad! zs2!sf!g!6bHHhe2dlO!|pINS&IeBtFNu6ebKrC2f2%X>F!G1iYS0Cn*l zB3mNAQ-;8tv3&MwAgq3D*eXa?5yz}GUla|U^S4MI1)y}zC(X9wuyYT{5L3G8RsGhm zEa~C|fWgqWA0RAyJSbHVMVf~tigj3dSOKJL*Asuns`AEGk$MgxyQjl$>jit~0yg*~ z{Xg%kSek}`!{w2x13t@XUGW>5r*EP*3-mfQir+izKeJ);N5>rH>W83$jxYGYK8H3L z%^r3DdAA%kj$Ec#6hw2CrqAwO#me2qG6>;H{Y~OkbgV>=Z7ZwO8N)F|V%XPz0uZuU zLM7}Z@^+M2T$Zu-`pO6b@SO_edVd<}$&=b&gG{|`*M_vu$^UtD7PGtL(brA!_r3ys zpE+J;?|!HHBq`W_EE9s#xyVW~T<#j;E)dbda4Uyq za%f?k8-TUj@D)QuI4qO_u+V^!*{UO5^x6EJU68x57CUr{pVE}o#cA+iIJD6s<~wga zXycxdROq$Ogkex_?d+=27isz{QWRq{myN)Uc9u#Md2A=;v2={9NC!H}tZ!T{sPF5P z(pW7VyZsDu-~s>J;+IAC@BFU{+vY@7X?(&rMb1&nd}?-pT5|tR*oU{H7_k%Z4r`}f8WMcMMi)L); zdrBASbRyI|%zq1R&l_G}1^tv&lQ>Dpwto2JB_qxpS*9*MrKv*u-B#Dv97>FxQIqNa zxv8R2tH2Mny{m1rzmq~Itv>zUSEbGG4}1k#G`+KhZ2nEX4chpy$SVqP{ZFho?H#y7 z3RQJ$dhQvTN7TFy9`923l~$&8WqZ)^`<>Pl(+khtDMg~8hix;8b7DGg_e5gevMoMv zL`ut7!z+S+oIBPJlY)DX2GVPu%(;$zxjVgz(fru*(mdR)%g_%-1GKCLdVQ&sc0%+4 zIB7EXcGRAH2EnoyH@gUMAimzpxw=~Z)t*2lmxyC2j&778&@{J^i?p`fE;V@@RFS9y z)OF<7TnhN}%_*0eG6?vO1|)gb^_3TiU;5AJ+hp~M%8#;sggVH(iY%4`)XE{x_i143 zM-hKnAG@7)$z4C9=r~(AkbFQd?~}{lhUAE*hauI~H0EJW`gAP*>mBZDkKOx?V{bzT zZ^!w)KE^M6@;7Vva`>t$g!IrrdVc=eTk$;c-aq4lKtT$60U zka>a}rL*wh+Mjs@kAsOVCaLtW4>c`3-vcutE$FwiJ&C4WZe4Jenl#|iyh%o@?I07P z*16~qJ2~h4t?#FLi4gwN)@4+~YL*qf7(r@g0A#(JX|k6=zVGQBCg zxnjYUNZ@%~1?pK#O*kd4qjUREoUFDan7k=Ubb!`i*jI6v?a$!Ru7a;g@v)7fhUo41 z@xuoO6V7i<#SG1m2A$fgj($m{9muX4f>DcF?;o%r)Dkyb!=KXgG(yrynN;9eBhh=`+H2fxg5y4pm@ zx0TCyJM35+&XBXV;mOCt+8+y-v1yD827XRA@Fq1&4_tlnc3E?*#Ka^~(-EDHq3rf; z`@--y2^6m3lgbc5l_^4@@-W$0`a3$lW7m>&XLwMZb-)f*T&wSNRY{}-7FcWzQhJT*DGH11*49DPM@fth&t7>C_eBY zfYgs|{xjd{*{PHY>hlO$*??Q%Z3u`_)^oX4gY+?r(g|6DknEbAuSz`Y_M7)}DwMjl zd@;|LDXZloSk8r?cjXOwS4bCK{nYpiDK{==1(#H=1V(q$zrg$aq6&is5^24vT?dJgk+uQeDIQmB&kX7~VpT7@NwB*e^ zYBvGjM;2iP3)5^ow&6q8EwZ75Oy6oonb&7Oe+rR#B~!@^-8>-BmFL&eTKt;+9J;G0 zY10E-UQPNNGF;8ep%B5iH{YNYV8ar3-`Hiie-~01MRm*TXM;3MHhP(>BZ3#}PHnm_ z**btiK%UMmr?nn8Qc@;iab)%4kS6fr=#Y#SlwWV{o0E?&k$7`-2{~i9b339~DuPn! zTg?i2qLwKw&TqUE0_KW$W++BDXZC;l=aY`XkKOi8>KR7p_rn_J6Ys|tY^D7#)4$w; zxDgX~ZF>3{k$XKh?r6?4l61je!E(9dXAwBlda4)1>)z`_1P z|2QSt2y6HIwuABa2DxvJ&3wgY484ianN3!B!(4aYS;WvzW^N2`C~n%1FUC~`rYIVz zQOt!*Uw+{7pqMDd))?@SM`GPL;wHYbxEHLk>H*|e_3lyW|F zH2ot5V5IUg=IeSKzx&{8X@(+NwDQ2?kInv zFZRRI4RODd3UFG1%1CWrfEH) z5F9BP*EQ@IFu(jlywr0MXiwAus5Tvm|BEOee(%i~P}!vL-gA zFWJz)aMy;ZG{)u4*PCxf!6xTT{$7>uj)dn`yHRd=><(eOtlO|RRHYde17`Nt{*!Ko z@YCnM0mR-b)5N|YyL!d0&%IChBl!6{b`L)x7Z#^iw$tl5ZM&N}h8+MG7XHNom-uJ$ zvjG{Za~|~`IV9eF~PnmFG4gsjcuS=Hb&Q3DlqFW3UaffQ> zm@eqochXKh5`Y-xqi<&D=$*d+DFP< z+PS4b*>4tA(pAkF@aOJ}%4|z)f5|<|r>f<~{VUk7kT@~6feKeJV+a$KzBq{MxNR~! z^Vkp`OtRnBrih!ENYS=by&I8N+GTB(MsDDLS73dou_8!%$H2ocoenquyTg98Kgjzl zdrL;}4QAifo8bm=`=_fR5T$4S$+`nKMQT1SM#wDkw{yUb$%HPS3c8wzF0IzxLDWnI zky=g?x$%?uHqpt#+XNUq_>rrroxMGoDn_xIaLjwS^5oqcOq8Uk;+Ocv1zoG>D{oQTiUY@QS~e{O22Qrjz3Gy@8DsVcD}b& zC12^#A^fZ4m4!_5&nmqK#;i_jmY?sQ&S_UV4uefn)|FeqrTzx4w@U$Aex2^oIo>&`u-R=<#xnqg|M`(tNakI4{s_s2qN+gyzv9#l7- zJ0#(q1)1Vlh9*pLRto0)K1*IUr70w3bs4e9SDy(W-mnq;SoI*iMX+Z(r<=qR#$$0v z>F*e=79o-rhQG;9mzL&LE?r+$m2m9en^j}dcNH2ey|Cf$Aq|g_97v?74xBUm|Jm;U zT-q%TtZr0udxk9P%QM9xKALYmD{iBwy1BI2{Qp9JpWqHy2R2 zk6AMSJZrc)iHQeEZCxGJe}%F#;D3ecYVr&1*4EbU>dW9_n_r-flKQuA1r!djzW!`* z2?>b&Oe#ePfSu{1nf{ zSC_$^Q|KKPg`vSJT#L*|W>*@abvb)PF$Uc-JS@jFoQ}R?A0O3^6{HjFo=PLnO0==j zR8dGJ^yECrf7_F*ZW0gkLfoM{}HAD literal 0 HcmV?d00001 diff --git a/android-project-ant/res/layout/main.xml b/android-project-ant/res/layout/main.xml new file mode 100644 index 0000000..123c4b6 --- /dev/null +++ b/android-project-ant/res/layout/main.xml @@ -0,0 +1,13 @@ + + + + + diff --git a/android-project-ant/res/values/strings.xml b/android-project-ant/res/values/strings.xml new file mode 100644 index 0000000..9bce51c --- /dev/null +++ b/android-project-ant/res/values/strings.xml @@ -0,0 +1,4 @@ + + + SDL App + diff --git a/android-project-ant/src b/android-project-ant/src new file mode 120000 index 0000000..d5b63ee --- /dev/null +++ b/android-project-ant/src @@ -0,0 +1 @@ +../android-project/app/src/main/java \ No newline at end of file diff --git a/build-scripts/build-release.py b/build-scripts/build-release.py new file mode 100755 index 0000000..d3f44a3 --- /dev/null +++ b/build-scripts/build-release.py @@ -0,0 +1,1470 @@ +#!/usr/bin/env python3 + +""" +This script is shared between SDL2, SDL3, and all satellite libraries. +Don't specialize this script for doing project-specific modifications. +Rather, modify release-info.json. +""" + +import argparse +import collections +import dataclasses +from collections.abc import Callable +import contextlib +import datetime +import fnmatch +import glob +import io +import json +import logging +import multiprocessing +import os +from pathlib import Path +import platform +import re +import shlex +import shutil +import subprocess +import sys +import tarfile +import tempfile +import textwrap +import typing +import zipfile + + +logger = logging.getLogger(__name__) +GIT_HASH_FILENAME = ".git-hash" +REVISION_TXT = "REVISION.txt" + + +def safe_isotime_to_datetime(str_isotime: str) -> datetime.datetime: + try: + return datetime.datetime.fromisoformat(str_isotime) + except ValueError: + pass + logger.warning("Invalid iso time: %s", str_isotime) + if str_isotime[-6:-5] in ("+", "-"): + # Commits can have isotime with invalid timezone offset (e.g. "2021-07-04T20:01:40+32:00") + modified_str_isotime = str_isotime[:-6] + "+00:00" + try: + return datetime.datetime.fromisoformat(modified_str_isotime) + except ValueError: + pass + raise ValueError(f"Invalid isotime: {str_isotime}") + + +def arc_join(*parts: list[str]) -> str: + assert all(p[:1] != "/" and p[-1:] != "/" for p in parts), f"None of {parts} may start or end with '/'" + return "/".join(p for p in parts if p) + + +@dataclasses.dataclass(frozen=True) +class VsArchPlatformConfig: + arch: str + configuration: str + platform: str + + def extra_context(self): + return { + "ARCH": self.arch, + "CONFIGURATION": self.configuration, + "PLATFORM": self.platform, + } + + +@contextlib.contextmanager +def chdir(path): + original_cwd = os.getcwd() + try: + os.chdir(path) + yield + finally: + os.chdir(original_cwd) + + +class Executer: + def __init__(self, root: Path, dry: bool=False): + self.root = root + self.dry = dry + + def run(self, cmd, cwd=None, env=None): + logger.info("Executing args=%r", cmd) + sys.stdout.flush() + if not self.dry: + subprocess.check_call(cmd, cwd=cwd or self.root, env=env, text=True) + + def check_output(self, cmd, cwd=None, dry_out=None, env=None, text=True): + logger.info("Executing args=%r", cmd) + sys.stdout.flush() + if self.dry: + return dry_out + return subprocess.check_output(cmd, cwd=cwd or self.root, env=env, text=text) + + +class SectionPrinter: + @contextlib.contextmanager + def group(self, title: str): + print(f"{title}:") + yield + + +class GitHubSectionPrinter(SectionPrinter): + def __init__(self): + super().__init__() + self.in_group = False + + @contextlib.contextmanager + def group(self, title: str): + print(f"::group::{title}") + assert not self.in_group, "Can enter a group only once" + self.in_group = True + yield + self.in_group = False + print("::endgroup::") + + +class VisualStudio: + def __init__(self, executer: Executer, year: typing.Optional[str]=None): + self.executer = executer + self.vsdevcmd = self.find_vsdevcmd(year) + self.msbuild = self.find_msbuild() + + @property + def dry(self) -> bool: + return self.executer.dry + + VS_YEAR_TO_VERSION = { + "2022": 17, + "2019": 16, + "2017": 15, + "2015": 14, + "2013": 12, + } + + def find_vsdevcmd(self, year: typing.Optional[str]=None) -> typing.Optional[Path]: + vswhere_spec = ["-latest"] + if year is not None: + try: + version = self.VS_YEAR_TO_VERSION[year] + except KeyError: + logger.error("Invalid Visual Studio year") + return None + vswhere_spec.extend(["-version", f"[{version},{version+1})"]) + vswhere_cmd = ["vswhere"] + vswhere_spec + ["-property", "installationPath"] + vs_install_path = Path(self.executer.check_output(vswhere_cmd, dry_out="/tmp").strip()) + logger.info("VS install_path = %s", vs_install_path) + assert vs_install_path.is_dir(), "VS installation path does not exist" + vsdevcmd_path = vs_install_path / "Common7/Tools/vsdevcmd.bat" + logger.info("vsdevcmd path = %s", vsdevcmd_path) + if self.dry: + vsdevcmd_path.parent.mkdir(parents=True, exist_ok=True) + vsdevcmd_path.touch(exist_ok=True) + assert vsdevcmd_path.is_file(), "vsdevcmd.bat batch file does not exist" + return vsdevcmd_path + + def find_msbuild(self) -> typing.Optional[Path]: + vswhere_cmd = ["vswhere", "-latest", "-requires", "Microsoft.Component.MSBuild", "-find", r"MSBuild\**\Bin\MSBuild.exe"] + msbuild_path = Path(self.executer.check_output(vswhere_cmd, dry_out="/tmp/MSBuild.exe").strip()) + logger.info("MSBuild path = %s", msbuild_path) + if self.dry: + msbuild_path.parent.mkdir(parents=True, exist_ok=True) + msbuild_path.touch(exist_ok=True) + assert msbuild_path.is_file(), "MSBuild.exe does not exist" + return msbuild_path + + def build(self, arch_platform: VsArchPlatformConfig, projects: list[Path]): + assert projects, "Need at least one project to build" + + vsdev_cmd_str = f"\"{self.vsdevcmd}\" -arch={arch_platform.arch}" + msbuild_cmd_str = " && ".join([f"\"{self.msbuild}\" \"{project}\" /m /p:BuildInParallel=true /p:Platform={arch_platform.platform} /p:Configuration={arch_platform.configuration}" for project in projects]) + bat_contents = f"{vsdev_cmd_str} && {msbuild_cmd_str}\n" + bat_path = Path(tempfile.gettempdir()) / "cmd.bat" + with bat_path.open("w") as f: + f.write(bat_contents) + + logger.info("Running cmd.exe script (%s): %s", bat_path, bat_contents) + cmd = ["cmd.exe", "/D", "/E:ON", "/V:OFF", "/S", "/C", f"CALL {str(bat_path)}"] + self.executer.run(cmd) + + +class Archiver: + def __init__(self, zip_path: typing.Optional[Path]=None, tgz_path: typing.Optional[Path]=None, txz_path: typing.Optional[Path]=None): + self._zip_files = [] + self._tar_files = [] + self._added_files = set() + if zip_path: + self._zip_files.append(zipfile.ZipFile(zip_path, "w", compression=zipfile.ZIP_DEFLATED)) + if tgz_path: + self._tar_files.append(tarfile.open(tgz_path, "w:gz")) + if txz_path: + self._tar_files.append(tarfile.open(txz_path, "w:xz")) + + @property + def added_files(self) -> set[str]: + return self._added_files + + def add_file_data(self, arcpath: str, data: bytes, mode: int, time: datetime.datetime): + for zf in self._zip_files: + file_data_time = (time.year, time.month, time.day, time.hour, time.minute, time.second) + zip_info = zipfile.ZipInfo(filename=arcpath, date_time=file_data_time) + zip_info.external_attr = mode << 16 + zip_info.compress_type = zipfile.ZIP_DEFLATED + zf.writestr(zip_info, data=data) + for tf in self._tar_files: + tar_info = tarfile.TarInfo(arcpath) + tar_info.type = tarfile.REGTYPE + tar_info.mode = mode + tar_info.size = len(data) + tar_info.mtime = int(time.timestamp()) + tf.addfile(tar_info, fileobj=io.BytesIO(data)) + + self._added_files.add(arcpath) + + def add_symlink(self, arcpath: str, target: str, time: datetime.datetime, files_for_zip): + logger.debug("Adding symlink (target=%r) -> %s", target, arcpath) + for zf in self._zip_files: + file_data_time = (time.year, time.month, time.day, time.hour, time.minute, time.second) + for f in files_for_zip: + zip_info = zipfile.ZipInfo(filename=f["arcpath"], date_time=file_data_time) + zip_info.external_attr = f["mode"] << 16 + zip_info.compress_type = zipfile.ZIP_DEFLATED + zf.writestr(zip_info, data=f["data"]) + for tf in self._tar_files: + tar_info = tarfile.TarInfo(arcpath) + tar_info.type = tarfile.SYMTYPE + tar_info.mode = 0o777 + tar_info.mtime = int(time.timestamp()) + tar_info.linkname = target + tf.addfile(tar_info) + + self._added_files.update(f["arcpath"] for f in files_for_zip) + + def add_git_hash(self, arcdir: str, commit: str, time: datetime.datetime): + arcpath = arc_join(arcdir, GIT_HASH_FILENAME) + data = f"{commit}\n".encode() + self.add_file_data(arcpath=arcpath, data=data, mode=0o100644, time=time) + + def add_file_path(self, arcpath: str, path: Path): + assert path.is_file(), f"{path} should be a file" + logger.debug("Adding %s -> %s", path, arcpath) + for zf in self._zip_files: + zf.write(path, arcname=arcpath) + for tf in self._tar_files: + tf.add(path, arcname=arcpath) + + def add_file_directory(self, arcdirpath: str, dirpath: Path): + assert dirpath.is_dir() + if arcdirpath and arcdirpath[-1:] != "/": + arcdirpath += "/" + for f in dirpath.iterdir(): + if f.is_file(): + arcpath = f"{arcdirpath}{f.name}" + logger.debug("Adding %s to %s", f, arcpath) + self.add_file_path(arcpath=arcpath, path=f) + + def close(self): + # Archiver is intentionally made invalid after this function + del self._zip_files + self._zip_files = None + del self._tar_files + self._tar_files = None + + def __enter__(self): + return self + + def __exit__(self, type, value, traceback): + self.close() + + +class NodeInArchive: + def __init__(self, arcpath: str, path: typing.Optional[Path]=None, data: typing.Optional[bytes]=None, mode: typing.Optional[int]=None, symtarget: typing.Optional[str]=None, time: typing.Optional[datetime.datetime]=None, directory: bool=False): + self.arcpath = arcpath + self.path = path + self.data = data + self.mode = mode + self.symtarget = symtarget + self.time = time + self.directory = directory + + @classmethod + def from_fs(cls, arcpath: str, path: Path, mode: int=0o100644, time: typing.Optional[datetime.datetime]=None) -> "NodeInArchive": + if time is None: + time = datetime.datetime.fromtimestamp(os.stat(path).st_mtime) + return cls(arcpath=arcpath, path=path, mode=mode) + + @classmethod + def from_data(cls, arcpath: str, data: bytes, time: datetime.datetime) -> "NodeInArchive": + return cls(arcpath=arcpath, data=data, time=time, mode=0o100644) + + @classmethod + def from_text(cls, arcpath: str, text: str, time: datetime.datetime) -> "NodeInArchive": + return cls.from_data(arcpath=arcpath, data=text.encode(), time=time) + + @classmethod + def from_symlink(cls, arcpath: str, symtarget: str) -> "NodeInArchive": + return cls(arcpath=arcpath, symtarget=symtarget) + + @classmethod + def from_directory(cls, arcpath: str) -> "NodeInArchive": + return cls(arcpath=arcpath, directory=True) + + def __repr__(self) -> str: + return f"<{type(self).__name__}:arcpath={self.arcpath},path='{str(self.path)}',len(data)={len(self.data) if self.data else 'n/a'},directory={self.directory},symtarget={self.symtarget}>" + + +def configure_file(path: Path, context: dict[str, str]) -> bytes: + text = path.read_text() + return configure_text(text, context=context).encode() + + +def configure_text(text: str, context: dict[str, str]) -> str: + original_text = text + for txt, repl in context.items(): + text = text.replace(f"@<@{txt}@>@", repl) + success = all(thing not in text for thing in ("@<@", "@>@")) + if not success: + raise ValueError(f"Failed to configure {repr(original_text)}") + return text + + +def configure_text_list(text_list: list[str], context: dict[str, str]) -> list[str]: + return [configure_text(text=e, context=context) for e in text_list] + + +class ArchiveFileTree: + def __init__(self): + self._tree: dict[str, NodeInArchive] = {} + + def add_file(self, file: NodeInArchive): + self._tree[file.arcpath] = file + + def get_latest_mod_time(self) -> datetime.datetime: + return max(item.time for item in self._tree.values() if item.time) + + def add_to_archiver(self, archive_base: str, archiver: Archiver): + remaining_symlinks = set() + added_files = dict() + + def calculate_symlink_target(s: NodeInArchive) -> str: + dest_dir = os.path.dirname(s.arcpath) + if dest_dir: + dest_dir += "/" + target = dest_dir + s.symtarget + while True: + new_target, n = re.subn(r"([^/]+/+[.]{2}/)", "", target) + target = new_target + if not n: + break + return target + + # Add files in first pass + for arcpath, node in self._tree.items(): + assert node is not None, f"{arcpath} -> node" + if node.data is not None: + archiver.add_file_data(arcpath=arc_join(archive_base, arcpath), data=node.data, time=node.time, mode=node.mode) + assert node.arcpath is not None, f"{node=}" + added_files[node.arcpath] = node + elif node.path is not None: + archiver.add_file_path(arcpath=arc_join(archive_base, arcpath), path=node.path) + assert node.arcpath is not None, f"{node=}" + added_files[node.arcpath] = node + elif node.symtarget is not None: + remaining_symlinks.add(node) + elif node.directory: + pass + else: + raise ValueError(f"Invalid Archive Node: {repr(node)}") + + assert None not in added_files + + # Resolve symlinks in second pass: zipfile does not support symlinks, so add files to zip archive + while True: + if not remaining_symlinks: + break + symlinks_this_time = set() + extra_added_files = {} + for symlink in remaining_symlinks: + symlink_files_for_zip = {} + symlink_target_path = calculate_symlink_target(symlink) + if symlink_target_path in added_files: + symlink_files_for_zip[symlink.arcpath] = added_files[symlink_target_path] + else: + symlink_target_path_slash = symlink_target_path + "/" + for added_file in added_files: + if added_file.startswith(symlink_target_path_slash): + path_in_symlink = symlink.arcpath + "/" + added_file.removeprefix(symlink_target_path_slash) + symlink_files_for_zip[path_in_symlink] = added_files[added_file] + if symlink_files_for_zip: + symlinks_this_time.add(symlink) + extra_added_files.update(symlink_files_for_zip) + files_for_zip = [{"arcpath": f"{archive_base}/{sym_path}", "data": sym_info.data, "mode": sym_info.mode} for sym_path, sym_info in symlink_files_for_zip.items()] + archiver.add_symlink(arcpath=f"{archive_base}/{symlink.arcpath}", target=symlink.symtarget, time=symlink.time, files_for_zip=files_for_zip) + # if not symlinks_this_time: + # logger.info("files added: %r", set(path for path in added_files.keys())) + assert symlinks_this_time, f"No targets found for symlinks: {remaining_symlinks}" + remaining_symlinks.difference_update(symlinks_this_time) + added_files.update(extra_added_files) + + def add_directory_tree(self, arc_dir: str, path: Path, time: datetime.datetime): + assert path.is_dir() + for files_dir, _, filenames in os.walk(path): + files_dir_path = Path(files_dir) + rel_files_path = files_dir_path.relative_to(path) + for filename in filenames: + self.add_file(NodeInArchive.from_fs(arcpath=arc_join(arc_dir, str(rel_files_path), filename), path=files_dir_path / filename, time=time)) + + def _add_files_recursively(self, arc_dir: str, paths: list[Path], time: datetime.datetime): + logger.debug(f"_add_files_recursively({arc_dir=} {paths=})") + for path in paths: + arcpath = arc_join(arc_dir, path.name) + if path.is_file(): + logger.debug("Adding %s as %s", path, arcpath) + self.add_file(NodeInArchive.from_fs(arcpath=arcpath, path=path, time=time)) + elif path.is_dir(): + self._add_files_recursively(arc_dir=arc_join(arc_dir, path.name), paths=list(path.iterdir()), time=time) + else: + raise ValueError(f"Unsupported file type to add recursively: {path}") + + def add_file_mapping(self, arc_dir: str, file_mapping: dict[str, list[str]], file_mapping_root: Path, context: dict[str, str], time: datetime.datetime): + for meta_rel_destdir, meta_file_globs in file_mapping.items(): + rel_destdir = configure_text(meta_rel_destdir, context=context) + assert "@" not in rel_destdir, f"archive destination should not contain an @ after configuration ({repr(meta_rel_destdir)}->{repr(rel_destdir)})" + for meta_file_glob in meta_file_globs: + file_glob = configure_text(meta_file_glob, context=context) + assert "@" not in rel_destdir, f"archive glob should not contain an @ after configuration ({repr(meta_file_glob)}->{repr(file_glob)})" + if ":" in file_glob: + original_path, new_filename = file_glob.rsplit(":", 1) + assert ":" not in original_path, f"Too many ':' in {repr(file_glob)}" + assert "/" not in new_filename, f"New filename cannot contain a '/' in {repr(file_glob)}" + path = file_mapping_root / original_path + arcpath = arc_join(arc_dir, rel_destdir, new_filename) + if path.suffix == ".in": + data = configure_file(path, context=context) + logger.debug("Adding processed %s -> %s", path, arcpath) + self.add_file(NodeInArchive.from_data(arcpath=arcpath, data=data, time=time)) + else: + logger.debug("Adding %s -> %s", path, arcpath) + self.add_file(NodeInArchive.from_fs(arcpath=arcpath, path=path, time=time)) + else: + relative_file_paths = glob.glob(file_glob, root_dir=file_mapping_root) + assert relative_file_paths, f"Glob '{file_glob}' does not match any file" + self._add_files_recursively(arc_dir=arc_join(arc_dir, rel_destdir), paths=[file_mapping_root / p for p in relative_file_paths], time=time) + + +class SourceCollector: + # TreeItem = collections.namedtuple("TreeItem", ("path", "mode", "data", "symtarget", "directory", "time")) + def __init__(self, root: Path, commit: str, filter: typing.Optional[Callable[[str], bool]], executer: Executer): + self.root = root + self.commit = commit + self.filter = filter + self.executer = executer + + def get_archive_file_tree(self) -> ArchiveFileTree: + git_archive_args = ["git", "archive", "--format=tar.gz", self.commit, "-o", "/dev/stdout"] + logger.info("Executing args=%r", git_archive_args) + contents_tgz = subprocess.check_output(git_archive_args, cwd=self.root, text=False) + tar_archive = tarfile.open(fileobj=io.BytesIO(contents_tgz), mode="r:gz") + filenames = tuple(m.name for m in tar_archive if (m.isfile() or m.issym())) + + file_times = self._get_file_times(paths=filenames) + git_contents = ArchiveFileTree() + for ti in tar_archive: + if self.filter and not self.filter(ti.name): + continue + data = None + symtarget = None + directory = False + file_time = None + if ti.isfile(): + contents_file = tar_archive.extractfile(ti.name) + data = contents_file.read() + file_time = file_times[ti.name] + elif ti.issym(): + symtarget = ti.linkname + file_time = file_times[ti.name] + elif ti.isdir(): + directory = True + else: + raise ValueError(f"{ti.name}: unknown type") + node = NodeInArchive(arcpath=ti.name, data=data, mode=ti.mode, symtarget=symtarget, time=file_time, directory=directory) + git_contents.add_file(node) + return git_contents + + def _get_file_times(self, paths: tuple[str, ...]) -> dict[str, datetime.datetime]: + dry_out = textwrap.dedent("""\ + time=2024-03-14T15:40:25-07:00 + + M\tCMakeLists.txt + """) + git_log_out = self.executer.check_output(["git", "log", "--name-status", '--pretty=time=%cI', self.commit], dry_out=dry_out, cwd=self.root).splitlines(keepends=False) + current_time = None + set_paths = set(paths) + path_times: dict[str, datetime.datetime] = {} + for line in git_log_out: + if not line: + continue + if line.startswith("time="): + current_time = safe_isotime_to_datetime(line.removeprefix("time=")) + continue + mod_type, file_paths = line.split(maxsplit=1) + assert current_time is not None + for file_path in file_paths.split("\t"): + if file_path in set_paths and file_path not in path_times: + path_times[file_path] = current_time + + # FIXME: find out why some files are not shown in "git log" + # assert set(path_times.keys()) == set_paths + if set(path_times.keys()) != set_paths: + found_times = set(path_times.keys()) + paths_without_times = set_paths.difference(found_times) + logger.warning("No times found for these paths: %s", paths_without_times) + max_time = max(time for time in path_times.values()) + for path in paths_without_times: + path_times[path] = max_time + + return path_times + + +class Releaser: + def __init__(self, release_info: dict, commit: str, revision: str, root: Path, dist_path: Path, section_printer: SectionPrinter, executer: Executer, cmake_generator: str, deps_path: Path, overwrite: bool, github: bool, fast: bool): + self.release_info = release_info + self.project = release_info["name"] + self.version = self.extract_sdl_version(root=root, release_info=release_info) + self.root = root + self.commit = commit + self.revision = revision + self.dist_path = dist_path + self.section_printer = section_printer + self.executer = executer + self.cmake_generator = cmake_generator + self.cpu_count = multiprocessing.cpu_count() + self.deps_path = deps_path + self.overwrite = overwrite + self.github = github + self.fast = fast + self.arc_time = datetime.datetime.now() + + self.artifacts: dict[str, Path] = {} + + def get_context(self, extra_context: typing.Optional[dict[str, str]]=None) -> dict[str, str]: + ctx = { + "PROJECT_NAME": self.project, + "PROJECT_VERSION": self.version, + "PROJECT_COMMIT": self.commit, + "PROJECT_REVISION": self.revision, + "PROJECT_ROOT": str(self.root), + } + if extra_context: + ctx.update(extra_context) + return ctx + + @property + def dry(self) -> bool: + return self.executer.dry + + def prepare(self): + logger.debug("Creating dist folder") + self.dist_path.mkdir(parents=True, exist_ok=True) + + @classmethod + def _path_filter(cls, path: str) -> bool: + if ".gitmodules" in path: + return True + if path.startswith(".git"): + return False + return True + + @classmethod + def _external_repo_path_filter(cls, path: str) -> bool: + if not cls._path_filter(path): + return False + if path.startswith("test/") or path.startswith("tests/"): + return False + return True + + def create_source_archives(self) -> None: + source_collector = SourceCollector(root=self.root, commit=self.commit, executer=self.executer, filter=self._path_filter) + print(f"Collecting sources of {self.project}...") + archive_tree = source_collector.get_archive_file_tree() + latest_mod_time = archive_tree.get_latest_mod_time() + archive_tree.add_file(NodeInArchive.from_text(arcpath=REVISION_TXT, text=f"{self.revision}\n", time=latest_mod_time)) + archive_tree.add_file(NodeInArchive.from_text(arcpath=f"{GIT_HASH_FILENAME}", text=f"{self.commit}\n", time=latest_mod_time)) + archive_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["source"].get("files", {}), file_mapping_root=self.root, context=self.get_context(), time=latest_mod_time) + + archive_base = f"{self.project}-{self.version}" + zip_path = self.dist_path / f"{archive_base}.zip" + tgz_path = self.dist_path / f"{archive_base}.tar.gz" + txz_path = self.dist_path / f"{archive_base}.tar.xz" + + logger.info("Creating zip/tgz/txz source archives ...") + if self.dry: + zip_path.touch() + tgz_path.touch() + txz_path.touch() + else: + with Archiver(zip_path=zip_path, tgz_path=tgz_path, txz_path=txz_path) as archiver: + print(f"Adding source files of {self.project}...") + archive_tree.add_to_archiver(archive_base=archive_base, archiver=archiver) + + for extra_repo in self.release_info["source"].get("extra-repos", []): + extra_repo_root = self.root / extra_repo + assert (extra_repo_root / ".git").exists(), f"{extra_repo_root} must be a git repo" + extra_repo_commit = self.executer.check_output(["git", "rev-parse", "HEAD"], dry_out=f"gitsha-extra-repo-{extra_repo}", cwd=extra_repo_root).strip() + extra_repo_source_collector = SourceCollector(root=extra_repo_root, commit=extra_repo_commit, executer=self.executer, filter=self._external_repo_path_filter) + print(f"Collecting sources of {extra_repo} ...") + extra_repo_archive_tree = extra_repo_source_collector.get_archive_file_tree() + print(f"Adding source files of {extra_repo} ...") + extra_repo_archive_tree.add_to_archiver(archive_base=f"{archive_base}/{extra_repo}", archiver=archiver) + + for file in self.release_info["source"]["checks"]: + assert f"{archive_base}/{file}" in archiver.added_files, f"'{archive_base}/{file}' must exist" + + logger.info("... done") + + self.artifacts["src-zip"] = zip_path + self.artifacts["src-tar-gz"] = tgz_path + self.artifacts["src-tar-xz"] = txz_path + + if not self.dry: + with tgz_path.open("r+b") as f: + # Zero the embedded timestamp in the gzip'ed tarball + f.seek(4, 0) + f.write(b"\x00\x00\x00\x00") + + def create_dmg(self, configuration: str="Release") -> None: + dmg_in = self.root / self.release_info["dmg"]["path"] + xcode_project = self.root / self.release_info["dmg"]["project"] + assert xcode_project.is_dir(), f"{xcode_project} must be a directory" + assert (xcode_project / "project.pbxproj").is_file, f"{xcode_project} must contain project.pbxproj" + if not self.fast: + dmg_in.unlink(missing_ok=True) + build_xcconfig = self.release_info["dmg"].get("build-xcconfig") + if build_xcconfig: + shutil.copy(self.root / build_xcconfig, xcode_project.parent / "build.xcconfig") + + xcode_scheme = self.release_info["dmg"].get("scheme") + xcode_target = self.release_info["dmg"].get("target") + assert xcode_scheme or xcode_target, "dmg needs scheme or target" + assert not (xcode_scheme and xcode_target), "dmg cannot have both scheme and target set" + if xcode_scheme: + scheme_or_target = "-scheme" + target_like = xcode_scheme + else: + scheme_or_target = "-target" + target_like = xcode_target + self.executer.run(["xcodebuild", "ONLY_ACTIVE_ARCH=NO", "-project", xcode_project, scheme_or_target, target_like, "-configuration", configuration]) + if self.dry: + dmg_in.parent.mkdir(parents=True, exist_ok=True) + dmg_in.touch() + + assert dmg_in.is_file(), f"{self.project}.dmg was not created by xcodebuild" + + dmg_out = self.dist_path / f"{self.project}-{self.version}.dmg" + shutil.copy(dmg_in, dmg_out) + self.artifacts["dmg"] = dmg_out + + @property + def git_hash_data(self) -> bytes: + return f"{self.commit}\n".encode() + + def create_mingw_archives(self) -> None: + build_type = "Release" + build_parent_dir = self.root / "build-mingw" + ARCH_TO_GNU_ARCH = { + # "arm64": "aarch64", + "x86": "i686", + "x64": "x86_64", + } + ARCH_TO_TRIPLET = { + # "arm64": "aarch64-w64-mingw32", + "x86": "i686-w64-mingw32", + "x64": "x86_64-w64-mingw32", + } + + new_env = dict(os.environ) + + cmake_prefix_paths = [] + mingw_deps_path = self.deps_path / "mingw-deps" + + if "dependencies" in self.release_info["mingw"]: + shutil.rmtree(mingw_deps_path, ignore_errors=True) + mingw_deps_path.mkdir() + + for triplet in ARCH_TO_TRIPLET.values(): + (mingw_deps_path / triplet).mkdir() + + def extract_filter(member: tarfile.TarInfo, path: str, /): + if member.name.startswith("SDL"): + member.name = "/".join(Path(member.name).parts[1:]) + return member + for dep in self.release_info.get("dependencies", {}): + extract_path = mingw_deps_path / f"extract-{dep}" + extract_path.mkdir() + with chdir(extract_path): + tar_path = self.deps_path / glob.glob(self.release_info["mingw"]["dependencies"][dep]["artifact"], root_dir=self.deps_path)[0] + logger.info("Extracting %s to %s", tar_path, mingw_deps_path) + assert tar_path.suffix in (".gz", ".xz") + with tarfile.open(tar_path, mode=f"r:{tar_path.suffix.strip('.')}") as tarf: + tarf.extractall(filter=extract_filter) + for arch, triplet in ARCH_TO_TRIPLET.items(): + install_cmd = self.release_info["mingw"]["dependencies"][dep]["install-command"] + extra_configure_data = { + "ARCH": ARCH_TO_GNU_ARCH[arch], + "TRIPLET": triplet, + "PREFIX": str(mingw_deps_path / triplet), + } + install_cmd = configure_text(install_cmd, context=self.get_context(extra_configure_data)) + self.executer.run(shlex.split(install_cmd), cwd=str(extract_path)) + + dep_binpath = mingw_deps_path / triplet / "bin" + assert dep_binpath.is_dir(), f"{dep_binpath} for PATH should exist" + dep_pkgconfig = mingw_deps_path / triplet / "lib/pkgconfig" + assert dep_pkgconfig.is_dir(), f"{dep_pkgconfig} for PKG_CONFIG_PATH should exist" + + new_env["PATH"] = os.pathsep.join([str(dep_binpath), new_env["PATH"]]) + new_env["PKG_CONFIG_PATH"] = str(dep_pkgconfig) + cmake_prefix_paths.append(mingw_deps_path) + + new_env["CFLAGS"] = f"-O2 -ffile-prefix-map={self.root}=/src/{self.project}" + new_env["CXXFLAGS"] = f"-O2 -ffile-prefix-map={self.root}=/src/{self.project}" + + assert any(system in self.release_info["mingw"] for system in ("autotools", "cmake")) + assert not all(system in self.release_info["mingw"] for system in ("autotools", "cmake")) + + mingw_archs = set() + arc_root = f"{self.project}-{self.version}" + archive_file_tree = ArchiveFileTree() + + if "autotools" in self.release_info["mingw"]: + for arch in self.release_info["mingw"]["autotools"]["archs"]: + triplet = ARCH_TO_TRIPLET[arch] + new_env["CC"] = f"{triplet}-gcc" + new_env["CXX"] = f"{triplet}-g++" + new_env["RC"] = f"{triplet}-windres" + + assert arch not in mingw_archs + mingw_archs.add(arch) + + build_path = build_parent_dir / f"build-{triplet}" + install_path = build_parent_dir / f"install-{triplet}" + shutil.rmtree(install_path, ignore_errors=True) + build_path.mkdir(parents=True, exist_ok=True) + context = self.get_context({ + "ARCH": arch, + "DEP_PREFIX": str(mingw_deps_path / triplet), + }) + extra_args = configure_text_list(text_list=self.release_info["mingw"]["autotools"]["args"], context=context) + + with self.section_printer.group(f"Configuring MinGW {triplet} (autotools)"): + assert "@" not in " ".join(extra_args), f"@ should not be present in extra arguments ({extra_args})" + self.executer.run([ + self.root / "configure", + f"--prefix={install_path}", + f"--includedir=${{prefix}}/include", + f"--libdir=${{prefix}}/lib", + f"--bindir=${{prefix}}/bin", + f"--exec-prefix=${{prefix}}/bin", + f"--host={triplet}", + f"--build=x86_64-none-linux-gnu", + "CFLAGS=-O2", + "CXXFLAGS=-O2", + "LDFLAGS=-Wl,-s", + ] + extra_args, cwd=build_path, env=new_env) + with self.section_printer.group(f"Build MinGW {triplet} (autotools)"): + self.executer.run(["make", "V=1", f"-j{self.cpu_count}"], cwd=build_path, env=new_env) + with self.section_printer.group(f"Install MinGW {triplet} (autotools)"): + self.executer.run(["make", "install"], cwd=build_path, env=new_env) + archive_file_tree.add_directory_tree(arc_dir=arc_join(arc_root, triplet), path=install_path, time=self.arc_time) + + print("Recording arch-dependent extra files for MinGW development archive ...") + extra_context = { + "TRIPLET": ARCH_TO_TRIPLET[arch], + } + archive_file_tree.add_file_mapping(arc_dir=arc_root, file_mapping=self.release_info["mingw"]["autotools"].get("files", {}), file_mapping_root=self.root, context=self.get_context(extra_context=extra_context), time=self.arc_time) + + if "cmake" in self.release_info["mingw"]: + assert self.release_info["mingw"]["cmake"]["shared-static"] in ("args", "both") + for arch in self.release_info["mingw"]["cmake"]["archs"]: + triplet = ARCH_TO_TRIPLET[arch] + new_env["CC"] = f"{triplet}-gcc" + new_env["CXX"] = f"{triplet}-g++" + new_env["RC"] = f"{triplet}-windres" + + assert arch not in mingw_archs + mingw_archs.add(arch) + + context = self.get_context({ + "ARCH": arch, + "DEP_PREFIX": str(mingw_deps_path / triplet), + }) + extra_args = configure_text_list(text_list=self.release_info["mingw"]["cmake"]["args"], context=context) + + build_path = build_parent_dir / f"build-{triplet}" + install_path = build_parent_dir / f"install-{triplet}" + shutil.rmtree(install_path, ignore_errors=True) + build_path.mkdir(parents=True, exist_ok=True) + if self.release_info["mingw"]["cmake"]["shared-static"] == "args": + args_for_shared_static = ([], ) + elif self.release_info["mingw"]["cmake"]["shared-static"] == "both": + args_for_shared_static = (["-DBUILD_SHARED_LIBS=ON"], ["-DBUILD_SHARED_LIBS=OFF"]) + for arg_for_shared_static in args_for_shared_static: + with self.section_printer.group(f"Configuring MinGW {triplet} (CMake)"): + assert "@" not in " ".join(extra_args), f"@ should not be present in extra arguments ({extra_args})" + self.executer.run([ + f"cmake", + f"-S", str(self.root), "-B", str(build_path), + f"-DCMAKE_BUILD_TYPE={build_type}", + f'''-DCMAKE_C_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''', + f'''-DCMAKE_CXX_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''', + f"-DCMAKE_PREFIX_PATH={mingw_deps_path / triplet}", + f"-DCMAKE_INSTALL_PREFIX={install_path}", + f"-DCMAKE_INSTALL_INCLUDEDIR=include", + f"-DCMAKE_INSTALL_LIBDIR=lib", + f"-DCMAKE_INSTALL_BINDIR=bin", + f"-DCMAKE_INSTALL_DATAROOTDIR=share", + f"-DCMAKE_TOOLCHAIN_FILE={self.root}/build-scripts/cmake-toolchain-mingw64-{ARCH_TO_GNU_ARCH[arch]}.cmake", + f"-G{self.cmake_generator}", + ] + extra_args + ([] if self.fast else ["--fresh"]) + arg_for_shared_static, cwd=build_path, env=new_env) + with self.section_printer.group(f"Build MinGW {triplet} (CMake)"): + self.executer.run(["cmake", "--build", str(build_path), "--verbose", "--config", build_type], cwd=build_path, env=new_env) + with self.section_printer.group(f"Install MinGW {triplet} (CMake)"): + self.executer.run(["cmake", "--install", str(build_path)], cwd=build_path, env=new_env) + archive_file_tree.add_directory_tree(arc_dir=arc_join(arc_root, triplet), path=install_path, time=self.arc_time) + + print("Recording arch-dependent extra files for MinGW development archive ...") + extra_context = { + "TRIPLET": ARCH_TO_TRIPLET[arch], + } + archive_file_tree.add_file_mapping(arc_dir=arc_root, file_mapping=self.release_info["mingw"]["cmake"].get("files", {}), file_mapping_root=self.root, context=self.get_context(extra_context=extra_context), time=self.arc_time) + print("... done") + + print("Recording extra files for MinGW development archive ...") + archive_file_tree.add_file_mapping(arc_dir=arc_root, file_mapping=self.release_info["mingw"].get("files", {}), file_mapping_root=self.root, context=self.get_context(), time=self.arc_time) + print("... done") + + print("Creating zip/tgz/txz development archives ...") + zip_path = self.dist_path / f"{self.project}-devel-{self.version}-mingw.zip" + tgz_path = self.dist_path / f"{self.project}-devel-{self.version}-mingw.tar.gz" + txz_path = self.dist_path / f"{self.project}-devel-{self.version}-mingw.tar.xz" + + with Archiver(zip_path=zip_path, tgz_path=tgz_path, txz_path=txz_path) as archiver: + archive_file_tree.add_to_archiver(archive_base="", archiver=archiver) + archiver.add_git_hash(arcdir=arc_root, commit=self.commit, time=self.arc_time) + print("... done") + + self.artifacts["mingw-devel-zip"] = zip_path + self.artifacts["mingw-devel-tar-gz"] = tgz_path + self.artifacts["mingw-devel-tar-xz"] = txz_path + + def _detect_android_api(self, android_home: str) -> typing.Optional[int]: + platform_dirs = list(Path(p) for p in glob.glob(f"{android_home}/platforms/android-*")) + re_platform = re.compile("android-([0-9]+)") + platform_versions = [] + for platform_dir in platform_dirs: + logger.debug("Found Android Platform SDK: %s", platform_dir) + if m:= re_platform.match(platform_dir.name): + platform_versions.append(int(m.group(1))) + platform_versions.sort() + logger.info("Available platform versions: %s", platform_versions) + platform_versions = list(filter(lambda v: v >= self._android_api_minimum, platform_versions)) + logger.info("Valid platform versions (>=%d): %s", self._android_api_minimum, platform_versions) + if not platform_versions: + return None + android_api = platform_versions[0] + logger.info("Selected API version %d", android_api) + return android_api + + def _get_prefab_json_text(self) -> str: + return textwrap.dedent(f"""\ + {{ + "schema_version": 2, + "name": "{self.project}", + "version": "{self.version}", + "dependencies": [] + }} + """) + + def _get_prefab_module_json_text(self, library_name: typing.Optional[str], export_libraries: list[str]) -> str: + for lib in export_libraries: + assert isinstance(lib, str), f"{lib} must be a string" + module_json_dict = { + "export_libraries": export_libraries, + } + if library_name: + module_json_dict["library_name"] = f"lib{library_name}" + return json.dumps(module_json_dict, indent=4) + + @property + def _android_api_minimum(self): + return self.release_info["android"]["api-minimum"] + + @property + def _android_api_target(self): + return self.release_info["android"]["api-target"] + + @property + def _android_ndk_minimum(self): + return self.release_info["android"]["ndk-minimum"] + + def _get_prefab_abi_json_text(self, abi: str, cpp: bool, shared: bool) -> str: + abi_json_dict = { + "abi": abi, + "api": self._android_api_minimum, + "ndk": self._android_ndk_minimum, + "stl": "c++_shared" if cpp else "none", + "static": not shared, + } + return json.dumps(abi_json_dict, indent=4) + + def _get_android_manifest_text(self) -> str: + return textwrap.dedent(f"""\ + + + + """) + + def create_android_archives(self, android_api: int, android_home: Path, android_ndk_home: Path) -> None: + cmake_toolchain_file = Path(android_ndk_home) / "build/cmake/android.toolchain.cmake" + if not cmake_toolchain_file.exists(): + logger.error("CMake toolchain file does not exist (%s)", cmake_toolchain_file) + raise SystemExit(1) + aar_path = self.dist_path / f"{self.project}-{self.version}.aar" + android_abis = self.release_info["android"]["abis"] + java_jars_added = False + module_data_added = False + android_deps_path = self.deps_path / "android-deps" + shutil.rmtree(android_deps_path, ignore_errors=True) + + for dep, depinfo in self.release_info["android"].get("dependencies", {}).items(): + android_aar = self.deps_path / glob.glob(depinfo["artifact"], root_dir=self.deps_path)[0] + with self.section_printer.group(f"Extracting Android dependency {dep} ({android_aar.name})"): + self.executer.run([sys.executable, str(android_aar), "-o", str(android_deps_path)]) + + for module_name, module_info in self.release_info["android"]["modules"].items(): + assert "type" in module_info and module_info["type"] in ("interface", "library"), f"module {module_name} must have a valid type" + + archive_file_tree = ArchiveFileTree() + + for android_abi in android_abis: + with self.section_printer.group(f"Building for Android {android_api} {android_abi}"): + build_dir = self.root / "build-android" / f"{android_abi}-build" + install_dir = self.root / "install-android" / f"{android_abi}-install" + shutil.rmtree(install_dir, ignore_errors=True) + assert not install_dir.is_dir(), f"{install_dir} should not exist prior to build" + build_type = "Release" + cmake_args = [ + "cmake", + "-S", str(self.root), + "-B", str(build_dir), + f'''-DCMAKE_C_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''', + f'''-DCMAKE_CXX_FLAGS="-ffile-prefix-map={self.root}=/src/{self.project}"''', + f"-DCMAKE_TOOLCHAIN_FILE={cmake_toolchain_file}", + f"-DCMAKE_PREFIX_PATH={str(android_deps_path)}", + f"-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=BOTH", + f"-DANDROID_HOME={android_home}", + f"-DANDROID_PLATFORM={android_api}", + f"-DANDROID_ABI={android_abi}", + "-DCMAKE_POSITION_INDEPENDENT_CODE=ON", + f"-DCMAKE_INSTALL_PREFIX={install_dir}", + "-DCMAKE_INSTALL_INCLUDEDIR=include ", + "-DCMAKE_INSTALL_LIBDIR=lib", + "-DCMAKE_INSTALL_DATAROOTDIR=share", + f"-DCMAKE_BUILD_TYPE={build_type}", + f"-G{self.cmake_generator}", + ] + self.release_info["android"]["cmake"]["args"] + ([] if self.fast else ["--fresh"]) + build_args = [ + "cmake", + "--build", str(build_dir), + "--verbose", + "--config", build_type, + ] + install_args = [ + "cmake", + "--install", str(build_dir), + "--config", build_type, + ] + self.executer.run(cmake_args) + self.executer.run(build_args) + self.executer.run(install_args) + + for module_name, module_info in self.release_info["android"]["modules"].items(): + arcdir_prefab_module = f"prefab/modules/{module_name}" + if module_info["type"] == "library": + library = install_dir / module_info["library"] + assert library.suffix in (".so", ".a") + assert library.is_file(), f"CMake should have built library '{library}' for module {module_name}" + arcdir_prefab_libs = f"{arcdir_prefab_module}/libs/android.{android_abi}" + archive_file_tree.add_file(NodeInArchive.from_fs(arcpath=f"{arcdir_prefab_libs}/{library.name}", path=library, time=self.arc_time)) + archive_file_tree.add_file(NodeInArchive.from_text(arcpath=f"{arcdir_prefab_libs}/abi.json", text=self._get_prefab_abi_json_text(abi=android_abi, cpp=False, shared=library.suffix == ".so"), time=self.arc_time)) + + if not module_data_added: + library_name = None + if module_info["type"] == "library": + library_name = Path(module_info["library"]).stem.removeprefix("lib") + export_libraries = module_info.get("export-libraries", []) + archive_file_tree.add_file(NodeInArchive.from_text(arcpath=arc_join(arcdir_prefab_module, "module.json"), text=self._get_prefab_module_json_text(library_name=library_name, export_libraries=export_libraries), time=self.arc_time)) + arcdir_prefab_include = f"prefab/modules/{module_name}/include" + if "includes" in module_info: + archive_file_tree.add_file_mapping(arc_dir=arcdir_prefab_include, file_mapping=module_info["includes"], file_mapping_root=install_dir, context=self.get_context(), time=self.arc_time) + else: + archive_file_tree.add_file(NodeInArchive.from_text(arcpath=arc_join(arcdir_prefab_include, ".keep"), text="\n", time=self.arc_time)) + module_data_added = True + + if not java_jars_added: + java_jars_added = True + if "jars" in self.release_info["android"]: + classes_jar_path = install_dir / configure_text(text=self.release_info["android"]["jars"]["classes"], context=self.get_context()) + sources_jar_path = install_dir / configure_text(text=self.release_info["android"]["jars"]["sources"], context=self.get_context()) + doc_jar_path = install_dir / configure_text(text=self.release_info["android"]["jars"]["doc"], context=self.get_context()) + assert classes_jar_path.is_file(), f"CMake should have compiled the java sources and archived them into a JAR ({classes_jar_path})" + assert sources_jar_path.is_file(), f"CMake should have archived the java sources into a JAR ({sources_jar_path})" + assert doc_jar_path.is_file(), f"CMake should have archived javadoc into a JAR ({doc_jar_path})" + + archive_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes.jar", path=classes_jar_path, time=self.arc_time)) + archive_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes-sources.jar", path=sources_jar_path, time=self.arc_time)) + archive_file_tree.add_file(NodeInArchive.from_fs(arcpath="classes-doc.jar", path=doc_jar_path, time=self.arc_time)) + + assert ("jars" in self.release_info["android"] and java_jars_added) or "jars" not in self.release_info["android"], "Must have archived java JAR archives" + + archive_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["android"].get("files", {}), file_mapping_root=self.root, context=self.get_context(), time=self.arc_time) + + archive_file_tree.add_file(NodeInArchive.from_text(arcpath="prefab/prefab.json", text=self._get_prefab_json_text(), time=self.arc_time)) + archive_file_tree.add_file(NodeInArchive.from_text(arcpath="AndroidManifest.xml", text=self._get_android_manifest_text(), time=self.arc_time)) + + with Archiver(zip_path=aar_path) as archiver: + archive_file_tree.add_to_archiver(archive_base="", archiver=archiver) + archiver.add_git_hash(arcdir="", commit=self.commit, time=self.arc_time) + self.artifacts[f"android-aar"] = aar_path + + def download_dependencies(self): + shutil.rmtree(self.deps_path, ignore_errors=True) + self.deps_path.mkdir(parents=True) + + if self.github: + with open(os.environ["GITHUB_OUTPUT"], "a") as f: + f.write(f"dep-path={self.deps_path.absolute()}\n") + + for dep, depinfo in self.release_info.get("dependencies", {}).items(): + startswith = depinfo["startswith"] + dep_repo = depinfo["repo"] + # FIXME: dropped "--exclude-pre-releases" + dep_string_data = self.executer.check_output(["gh", "-R", dep_repo, "release", "list", "--exclude-drafts", "--json", "name,createdAt,tagName", "--jq", f'[.[]|select(.name|startswith("{startswith}"))]|max_by(.createdAt)']).strip() + dep_data = json.loads(dep_string_data) + dep_tag = dep_data["tagName"] + dep_version = dep_data["name"] + logger.info("Download dependency %s version %s (tag=%s) ", dep, dep_version, dep_tag) + self.executer.run(["gh", "-R", dep_repo, "release", "download", dep_tag], cwd=self.deps_path) + if self.github: + with open(os.environ["GITHUB_OUTPUT"], "a") as f: + f.write(f"dep-{dep.lower()}-version={dep_version}\n") + + def verify_dependencies(self): + for dep, depinfo in self.release_info.get("dependencies", {}).items(): + if "mingw" in self.release_info: + mingw_matches = glob.glob(self.release_info["mingw"]["dependencies"][dep]["artifact"], root_dir=self.deps_path) + assert len(mingw_matches) == 1, f"Exactly one archive matches mingw {dep} dependency: {mingw_matches}" + if "dmg" in self.release_info: + dmg_matches = glob.glob(self.release_info["dmg"]["dependencies"][dep]["artifact"], root_dir=self.deps_path) + assert len(dmg_matches) == 1, f"Exactly one archive matches dmg {dep} dependency: {dmg_matches}" + if "msvc" in self.release_info: + msvc_matches = glob.glob(self.release_info["msvc"]["dependencies"][dep]["artifact"], root_dir=self.deps_path) + assert len(msvc_matches) == 1, f"Exactly one archive matches msvc {dep} dependency: {msvc_matches}" + if "android" in self.release_info: + android_matches = glob.glob(self.release_info["android"]["dependencies"][dep]["artifact"], root_dir=self.deps_path) + assert len(android_matches) == 1, f"Exactly one archive matches msvc {dep} dependency: {msvc_matches}" + + @staticmethod + def _arch_to_vs_platform(arch: str, configuration: str="Release") -> VsArchPlatformConfig: + ARCH_TO_VS_PLATFORM = { + "x86": VsArchPlatformConfig(arch="x86", platform="Win32", configuration=configuration), + "x64": VsArchPlatformConfig(arch="x64", platform="x64", configuration=configuration), + "arm64": VsArchPlatformConfig(arch="arm64", platform="ARM64", configuration=configuration), + } + return ARCH_TO_VS_PLATFORM[arch] + + def build_msvc(self): + with self.section_printer.group("Find Visual Studio"): + vs = VisualStudio(executer=self.executer) + for arch in self.release_info["msvc"].get("msbuild", {}).get("archs", []): + self._build_msvc_msbuild(arch_platform=self._arch_to_vs_platform(arch=arch), vs=vs) + if "cmake" in self.release_info["msvc"]: + deps_path = self.root / "msvc-deps" + shutil.rmtree(deps_path, ignore_errors=True) + dep_roots = [] + for dep, depinfo in self.release_info["msvc"].get("dependencies", {}).items(): + dep_extract_path = deps_path / f"extract-{dep}" + msvc_zip = self.deps_path / glob.glob(depinfo["artifact"], root_dir=self.deps_path)[0] + with zipfile.ZipFile(msvc_zip, "r") as zf: + zf.extractall(dep_extract_path) + contents_msvc_zip = glob.glob(str(dep_extract_path / "*")) + assert len(contents_msvc_zip) == 1, f"There must be exactly one root item in the root directory of {dep}" + dep_roots.append(contents_msvc_zip[0]) + + for arch in self.release_info["msvc"].get("cmake", {}).get("archs", []): + self._build_msvc_cmake(arch_platform=self._arch_to_vs_platform(arch=arch), dep_roots=dep_roots) + with self.section_printer.group("Create SDL VC development zip"): + self._build_msvc_devel() + + def _build_msvc_msbuild(self, arch_platform: VsArchPlatformConfig, vs: VisualStudio): + platform_context = self.get_context(arch_platform.extra_context()) + for dep, depinfo in self.release_info["msvc"].get("dependencies", {}).items(): + msvc_zip = self.deps_path / glob.glob(depinfo["artifact"], root_dir=self.deps_path)[0] + + src_globs = [configure_text(instr["src"], context=platform_context) for instr in depinfo["copy"]] + with zipfile.ZipFile(msvc_zip, "r") as zf: + for member in zf.namelist(): + member_path = "/".join(Path(member).parts[1:]) + for src_i, src_glob in enumerate(src_globs): + if fnmatch.fnmatch(member_path, src_glob): + dst = (self.root / configure_text(depinfo["copy"][src_i]["dst"], context=platform_context)).resolve() / Path(member_path).name + zip_data = zf.read(member) + if dst.exists(): + identical = False + if dst.is_file(): + orig_bytes = dst.read_bytes() + if orig_bytes == zip_data: + identical = True + if not identical: + logger.warning("Extracting dependency %s, will cause %s to be overwritten", dep, dst) + if not self.overwrite: + raise RuntimeError("Run with --overwrite to allow overwriting") + logger.debug("Extracting %s -> %s", member, dst) + + dst.parent.mkdir(exist_ok=True, parents=True) + dst.write_bytes(zip_data) + + prebuilt_paths = set(self.root / full_prebuilt_path for prebuilt_path in self.release_info["msvc"]["msbuild"].get("prebuilt", []) for full_prebuilt_path in glob.glob(configure_text(prebuilt_path, context=platform_context), root_dir=self.root)) + msbuild_paths = set(self.root / configure_text(f, context=platform_context) for file_mapping in (self.release_info["msvc"]["msbuild"]["files-lib"], self.release_info["msvc"]["msbuild"]["files-devel"]) for files_list in file_mapping.values() for f in files_list) + assert prebuilt_paths.issubset(msbuild_paths), f"msvc.msbuild.prebuilt must be a subset of (msvc.msbuild.files-lib, msvc.msbuild.files-devel)" + built_paths = msbuild_paths.difference(prebuilt_paths) + logger.info("MSbuild builds these files, to be included in the package: %s", built_paths) + if not self.fast: + for b in built_paths: + b.unlink(missing_ok=True) + + rel_projects: list[str] = self.release_info["msvc"]["msbuild"]["projects"] + projects = list(self.root / p for p in rel_projects) + + directory_build_props_src_relpath = self.release_info["msvc"]["msbuild"].get("directory-build-props") + for project in projects: + dir_b_props = project.parent / "Directory.Build.props" + dir_b_props.unlink(missing_ok = True) + if directory_build_props_src_relpath: + src = self.root / directory_build_props_src_relpath + logger.debug("Copying %s -> %s", src, dir_b_props) + shutil.copy(src=src, dst=dir_b_props) + + with self.section_printer.group(f"Build {arch_platform.arch} VS binary"): + vs.build(arch_platform=arch_platform, projects=projects) + + if self.dry: + for b in built_paths: + b.parent.mkdir(parents=True, exist_ok=True) + b.touch() + + for b in built_paths: + assert b.is_file(), f"{b} has not been created" + b.parent.mkdir(parents=True, exist_ok=True) + b.touch() + + zip_path = self.dist_path / f"{self.project}-{self.version}-win32-{arch_platform.arch}.zip" + zip_path.unlink(missing_ok=True) + + logger.info("Collecting files...") + archive_file_tree = ArchiveFileTree() + archive_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["msvc"]["msbuild"]["files-lib"], file_mapping_root=self.root, context=platform_context, time=self.arc_time) + archive_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["msvc"]["files-lib"], file_mapping_root=self.root, context=platform_context, time=self.arc_time) + + logger.info("Writing to %s", zip_path) + with Archiver(zip_path=zip_path) as archiver: + arc_root = f"" + archive_file_tree.add_to_archiver(archive_base=arc_root, archiver=archiver) + archiver.add_git_hash(arcdir=arc_root, commit=self.commit, time=self.arc_time) + self.artifacts[f"VC-{arch_platform.arch}"] = zip_path + + for p in built_paths: + assert p.is_file(), f"{p} should exist" + + def _arch_platform_to_build_path(self, arch_platform: VsArchPlatformConfig) -> Path: + return self.root / f"build-vs-{arch_platform.arch}" + + def _arch_platform_to_install_path(self, arch_platform: VsArchPlatformConfig) -> Path: + return self._arch_platform_to_build_path(arch_platform) / "prefix" + + def _build_msvc_cmake(self, arch_platform: VsArchPlatformConfig, dep_roots: list[Path]): + build_path = self._arch_platform_to_build_path(arch_platform) + install_path = self._arch_platform_to_install_path(arch_platform) + platform_context = self.get_context(extra_context=arch_platform.extra_context()) + + build_type = "Release" + + built_paths = set(install_path / configure_text(f, context=platform_context) for file_mapping in (self.release_info["msvc"]["cmake"]["files-lib"], self.release_info["msvc"]["cmake"]["files-devel"]) for files_list in file_mapping.values() for f in files_list) + logger.info("CMake builds these files, to be included in the package: %s", built_paths) + if not self.fast: + for b in built_paths: + b.unlink(missing_ok=True) + + shutil.rmtree(install_path, ignore_errors=True) + build_path.mkdir(parents=True, exist_ok=True) + with self.section_printer.group(f"Configure VC CMake project for {arch_platform.arch}"): + self.executer.run([ + "cmake", "-S", str(self.root), "-B", str(build_path), + "-A", arch_platform.platform, + "-DCMAKE_INSTALL_BINDIR=bin", + "-DCMAKE_INSTALL_DATAROOTDIR=share", + "-DCMAKE_INSTALL_INCLUDEDIR=include", + "-DCMAKE_INSTALL_LIBDIR=lib", + f"-DCMAKE_BUILD_TYPE={build_type}", + f"-DCMAKE_INSTALL_PREFIX={install_path}", + # MSVC debug information format flags are selected by an abstraction + "-DCMAKE_POLICY_DEFAULT_CMP0141=NEW", + # MSVC debug information format + "-DCMAKE_MSVC_DEBUG_INFORMATION_FORMAT=ProgramDatabase", + # Linker flags for executables + "-DCMAKE_EXE_LINKER_FLAGS=-INCREMENTAL:NO -DEBUG -OPT:REF -OPT:ICF", + # Linker flag for shared libraries + "-DCMAKE_SHARED_LINKER_FLAGS=-INCREMENTAL:NO -DEBUG -OPT:REF -OPT:ICF", + # MSVC runtime library flags are selected by an abstraction + "-DCMAKE_POLICY_DEFAULT_CMP0091=NEW", + # Use statically linked runtime (-MT) (ideally, should be "MultiThreaded$<$:Debug>") + "-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded", + f"-DCMAKE_PREFIX_PATH={';'.join(str(s) for s in dep_roots)}", + ] + self.release_info["msvc"]["cmake"]["args"] + ([] if self.fast else ["--fresh"])) + + with self.section_printer.group(f"Build VC CMake project for {arch_platform.arch}"): + self.executer.run(["cmake", "--build", str(build_path), "--verbose", "--config", build_type]) + with self.section_printer.group(f"Install VC CMake project for {arch_platform.arch}"): + self.executer.run(["cmake", "--install", str(build_path), "--config", build_type]) + + if self.dry: + for b in built_paths: + b.parent.mkdir(parents=True, exist_ok=True) + b.touch() + + zip_path = self.dist_path / f"{self.project}-{self.version}-win32-{arch_platform.arch}.zip" + zip_path.unlink(missing_ok=True) + + logger.info("Collecting files...") + archive_file_tree = ArchiveFileTree() + archive_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["msvc"]["cmake"]["files-lib"], file_mapping_root=install_path, context=platform_context, time=self.arc_time) + archive_file_tree.add_file_mapping(arc_dir="", file_mapping=self.release_info["msvc"]["files-lib"], file_mapping_root=self.root, context=self.get_context(), time=self.arc_time) + + logger.info("Creating %s", zip_path) + with Archiver(zip_path=zip_path) as archiver: + arc_root = f"" + archive_file_tree.add_to_archiver(archive_base=arc_root, archiver=archiver) + archiver.add_git_hash(arcdir=arc_root, commit=self.commit, time=self.arc_time) + + for p in built_paths: + assert p.is_file(), f"{p} should exist" + + def _build_msvc_devel(self) -> None: + zip_path = self.dist_path / f"{self.project}-devel-{self.version}-VC.zip" + arc_root = f"{self.project}-{self.version}" + + def copy_files_devel(ctx): + archive_file_tree.add_file_mapping(arc_dir=arc_root, file_mapping=self.release_info["msvc"]["files-devel"], file_mapping_root=self.root, context=ctx, time=self.arc_time) + + + logger.info("Collecting files...") + archive_file_tree = ArchiveFileTree() + if "msbuild" in self.release_info["msvc"]: + for arch in self.release_info["msvc"]["msbuild"]["archs"]: + arch_platform = self._arch_to_vs_platform(arch=arch) + platform_context = self.get_context(arch_platform.extra_context()) + archive_file_tree.add_file_mapping(arc_dir=arc_root, file_mapping=self.release_info["msvc"]["msbuild"]["files-devel"], file_mapping_root=self.root, context=platform_context, time=self.arc_time) + copy_files_devel(ctx=platform_context) + if "cmake" in self.release_info["msvc"]: + for arch in self.release_info["msvc"]["cmake"]["archs"]: + arch_platform = self._arch_to_vs_platform(arch=arch) + platform_context = self.get_context(arch_platform.extra_context()) + archive_file_tree.add_file_mapping(arc_dir=arc_root, file_mapping=self.release_info["msvc"]["cmake"]["files-devel"], file_mapping_root=self._arch_platform_to_install_path(arch_platform), context=platform_context, time=self.arc_time) + copy_files_devel(ctx=platform_context) + + with Archiver(zip_path=zip_path) as archiver: + archive_file_tree.add_to_archiver(archive_base="", archiver=archiver) + archiver.add_git_hash(arcdir=arc_root, commit=self.commit, time=self.arc_time) + self.artifacts["VC-devel"] = zip_path + + @classmethod + def extract_sdl_version(cls, root: Path, release_info: dict) -> str: + with open(root / release_info["version"]["file"], "r") as f: + text = f.read() + major = next(re.finditer(release_info["version"]["re_major"], text, flags=re.M)).group(1) + minor = next(re.finditer(release_info["version"]["re_minor"], text, flags=re.M)).group(1) + micro = next(re.finditer(release_info["version"]["re_micro"], text, flags=re.M)).group(1) + return f"{major}.{minor}.{micro}" + + +def main(argv=None) -> int: + if sys.version_info < (3, 11): + logger.error("This script needs at least python 3.11") + return 1 + + parser = argparse.ArgumentParser(allow_abbrev=False, description="Create SDL release artifacts") + parser.add_argument("--root", metavar="DIR", type=Path, default=Path(__file__).absolute().parents[1], help="Root of project") + parser.add_argument("--release-info", metavar="JSON", dest="path_release_info", type=Path, default=Path(__file__).absolute().parent / "release-info.json", help="Path of release-info.json") + parser.add_argument("--dependency-folder", metavar="FOLDER", dest="deps_path", type=Path, default="deps", help="Directory containing pre-built archives of dependencies (will be removed when downloading archives)") + parser.add_argument("--out", "-o", metavar="DIR", dest="dist_path", type=Path, default="dist", help="Output directory") + parser.add_argument("--github", action="store_true", help="Script is running on a GitHub runner") + parser.add_argument("--commit", default="HEAD", help="Git commit/tag of which a release should be created") + parser.add_argument("--actions", choices=["download", "source", "android", "mingw", "msvc", "dmg"], required=True, nargs="+", dest="actions", help="What to do?") + parser.set_defaults(loglevel=logging.INFO) + parser.add_argument('--vs-year', dest="vs_year", help="Visual Studio year") + parser.add_argument('--android-api', type=int, dest="android_api", help="Android API version") + parser.add_argument('--android-home', dest="android_home", default=os.environ.get("ANDROID_HOME"), help="Android Home folder") + parser.add_argument('--android-ndk-home', dest="android_ndk_home", default=os.environ.get("ANDROID_NDK_HOME"), help="Android NDK Home folder") + parser.add_argument('--cmake-generator', dest="cmake_generator", default="Ninja", help="CMake Generator") + parser.add_argument('--debug', action='store_const', const=logging.DEBUG, dest="loglevel", help="Print script debug information") + parser.add_argument('--dry-run', action='store_true', dest="dry", help="Don't execute anything") + parser.add_argument('--force', action='store_true', dest="force", help="Ignore a non-clean git tree") + parser.add_argument('--overwrite', action='store_true', dest="overwrite", help="Allow potentially overwriting other projects") + parser.add_argument('--fast', action='store_true', dest="fast", help="Don't do a rebuild") + + args = parser.parse_args(argv) + logging.basicConfig(level=args.loglevel, format='[%(levelname)s] %(message)s') + args.deps_path = args.deps_path.absolute() + args.dist_path = args.dist_path.absolute() + args.root = args.root.absolute() + args.dist_path = args.dist_path.absolute() + if args.dry: + args.dist_path = args.dist_path / "dry" + + if args.github: + section_printer: SectionPrinter = GitHubSectionPrinter() + else: + section_printer = SectionPrinter() + + if args.github and "GITHUB_OUTPUT" not in os.environ: + os.environ["GITHUB_OUTPUT"] = "/tmp/github_output.txt" + + executer = Executer(root=args.root, dry=args.dry) + + root_git_hash_path = args.root / GIT_HASH_FILENAME + root_is_maybe_archive = root_git_hash_path.is_file() + if root_is_maybe_archive: + logger.warning("%s detected: Building from archive", GIT_HASH_FILENAME) + archive_commit = root_git_hash_path.read_text().strip() + if args.commit != archive_commit: + logger.warning("Commit argument is %s, but archive commit is %s. Using %s.", args.commit, archive_commit, archive_commit) + args.commit = archive_commit + revision = (args.root / REVISION_TXT).read_text().strip() + else: + args.commit = executer.check_output(["git", "rev-parse", args.commit], dry_out="e5812a9fd2cda317b503325a702ba3c1c37861d9").strip() + revision = executer.check_output(["git", "describe", "--always", "--tags", "--long", args.commit], dry_out="preview-3.1.3-96-g9512f2144").strip() + logger.info("Using commit %s", args.commit) + + try: + with args.path_release_info.open() as f: + release_info = json.load(f) + except FileNotFoundError: + logger.error(f"Could not find {args.path_release_info}") + + releaser = Releaser( + release_info=release_info, + commit=args.commit, + revision=revision, + root=args.root, + dist_path=args.dist_path, + executer=executer, + section_printer=section_printer, + cmake_generator=args.cmake_generator, + deps_path=args.deps_path, + overwrite=args.overwrite, + github=args.github, + fast=args.fast, + ) + + if root_is_maybe_archive: + logger.warning("Building from archive. Skipping clean git tree check.") + else: + porcelain_status = executer.check_output(["git", "status", "--ignored", "--porcelain"], dry_out="\n").strip() + if porcelain_status: + print(porcelain_status) + logger.warning("The tree is dirty! Do not publish any generated artifacts!") + if not args.force: + raise Exception("The git repo contains modified and/or non-committed files. Run with --force to ignore.") + + if args.fast: + logger.warning("Doing fast build! Do not publish generated artifacts!") + + with section_printer.group("Arguments"): + print(f"project = {releaser.project}") + print(f"version = {releaser.version}") + print(f"revision = {revision}") + print(f"commit = {args.commit}") + print(f"out = {args.dist_path}") + print(f"actions = {args.actions}") + print(f"dry = {args.dry}") + print(f"force = {args.force}") + print(f"overwrite = {args.overwrite}") + print(f"cmake_generator = {args.cmake_generator}") + + releaser.prepare() + + if "download" in args.actions: + releaser.download_dependencies() + + if set(args.actions).intersection({"msvc", "mingw", "android"}): + print("Verifying presence of dependencies (run 'download' action to download) ...") + releaser.verify_dependencies() + print("... done") + + if "source" in args.actions: + if root_is_maybe_archive: + raise Exception("Cannot build source archive from source archive") + with section_printer.group("Create source archives"): + releaser.create_source_archives() + + if "dmg" in args.actions: + if platform.system() != "Darwin" and not args.dry: + parser.error("framework artifact(s) can only be built on Darwin") + + releaser.create_dmg() + + if "msvc" in args.actions: + if platform.system() != "Windows" and not args.dry: + parser.error("msvc artifact(s) can only be built on Windows") + releaser.build_msvc() + + if "mingw" in args.actions: + releaser.create_mingw_archives() + + if "android" in args.actions: + if args.android_home is None or not Path(args.android_home).is_dir(): + parser.error("Invalid $ANDROID_HOME or --android-home: must be a directory containing the Android SDK") + if args.android_ndk_home is None or not Path(args.android_ndk_home).is_dir(): + parser.error("Invalid $ANDROID_NDK_HOME or --android_ndk_home: must be a directory containing the Android NDK") + if args.android_api is None: + with section_printer.group("Detect Android APIS"): + args.android_api = releaser._detect_android_api(android_home=args.android_home) + if args.android_api is None or not (Path(args.android_home) / f"platforms/android-{args.android_api}").is_dir(): + parser.error("Invalid --android-api, and/or could not be detected") + with section_printer.group("Android arguments"): + print(f"android_home = {args.android_home}") + print(f"android_ndk_home = {args.android_ndk_home}") + print(f"android_api = {args.android_api}") + releaser.create_android_archives( + android_api=args.android_api, + android_home=args.android_home, + android_ndk_home=args.android_ndk_home, + ) + with section_printer.group("Summary"): + print(f"artifacts = {releaser.artifacts}") + + if args.github: + with open(os.environ["GITHUB_OUTPUT"], "a") as f: + f.write(f"project={releaser.project}\n") + f.write(f"version={releaser.version}\n") + for k, v in releaser.artifacts.items(): + f.write(f"{k}={v.name}\n") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/build-scripts/cmake-toolchain-mingw64-i686.cmake b/build-scripts/cmake-toolchain-mingw64-i686.cmake new file mode 100644 index 0000000..8be7b3a --- /dev/null +++ b/build-scripts/cmake-toolchain-mingw64-i686.cmake @@ -0,0 +1,18 @@ +set(CMAKE_SYSTEM_NAME Windows) +set(CMAKE_SYSTEM_PROCESSOR x86) + +find_program(CMAKE_C_COMPILER NAMES i686-w64-mingw32-gcc) +find_program(CMAKE_CXX_COMPILER NAMES i686-w64-mingw32-g++) +find_program(CMAKE_RC_COMPILER NAMES i686-w64-mingw32-windres windres) + +if(NOT CMAKE_C_COMPILER) + message(FATAL_ERROR "Failed to find CMAKE_C_COMPILER.") +endif() + +if(NOT CMAKE_CXX_COMPILER) + message(FATAL_ERROR "Failed to find CMAKE_CXX_COMPILER.") +endif() + +if(NOT CMAKE_RC_COMPILER) + message(FATAL_ERROR "Failed to find CMAKE_RC_COMPILER.") +endif() diff --git a/build-scripts/cmake-toolchain-mingw64-x86_64.cmake b/build-scripts/cmake-toolchain-mingw64-x86_64.cmake new file mode 100644 index 0000000..8bf4366 --- /dev/null +++ b/build-scripts/cmake-toolchain-mingw64-x86_64.cmake @@ -0,0 +1,18 @@ +set(CMAKE_SYSTEM_NAME Windows) +set(CMAKE_SYSTEM_PROCESSOR x86_64) + +find_program(CMAKE_C_COMPILER NAMES x86_64-w64-mingw32-gcc) +find_program(CMAKE_CXX_COMPILER NAMES x86_64-w64-mingw32-g++) +find_program(CMAKE_RC_COMPILER NAMES x86_64-w64-mingw32-windres windres) + +if(NOT CMAKE_C_COMPILER) + message(FATAL_ERROR "Failed to find CMAKE_C_COMPILER.") +endif() + +if(NOT CMAKE_CXX_COMPILER) + message(FATAL_ERROR "Failed to find CMAKE_CXX_COMPILER.") +endif() + +if(NOT CMAKE_RC_COMPILER) + message(FATAL_ERROR "Failed to find CMAKE_RC_COMPILER.") +endif() diff --git a/build-scripts/create-release.py b/build-scripts/create-release.py new file mode 100755 index 0000000..2214449 --- /dev/null +++ b/build-scripts/create-release.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 + +import argparse +from pathlib import Path +import json +import logging +import re +import subprocess + +ROOT = Path(__file__).resolve().parents[1] + + +def determine_remote() -> str: + text = (ROOT / "build-scripts/release-info.json").read_text() + release_info = json.loads(text) + if "remote" in release_info: + return release_info["remote"] + project_with_version = release_info["name"] + project, _ = re.subn("([^a-zA-Z_])", "", project_with_version) + return f"libsdl-org/{project}" + + +def main(): + default_remote = determine_remote() + + current_commit = subprocess.check_output(["git", "rev-parse", "HEAD"], cwd=ROOT, text=True).strip() + + parser = argparse.ArgumentParser(allow_abbrev=False) + parser.add_argument("--ref", required=True, help=f"Name of branch or tag containing release.yml") + parser.add_argument("--remote", "-R", default=default_remote, help=f"Remote repo (default={default_remote})") + parser.add_argument("--commit", default=current_commit, help=f"Commit (default={current_commit})") + args = parser.parse_args() + + + print(f"Running release.yml workflow:") + print(f" commit = {args.commit}") + print(f" remote = {args.remote}") + + subprocess.check_call(["gh", "-R", args.remote, "workflow", "run", "release.yml", "--ref", args.ref, "-f", f"commit={args.commit}"], cwd=ROOT) + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/build-scripts/gen_audio_channel_conversion.c b/build-scripts/gen_audio_channel_conversion.c index 5d5841d..38c3548 100644 --- a/build-scripts/gen_audio_channel_conversion.c +++ b/build-scripts/gen_audio_channel_conversion.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -395,7 +395,7 @@ int main(void) printf( "/*\n" " Simple DirectMedia Layer\n" - " Copyright (C) 1997-2024 Sam Lantinga \n" + " Copyright (C) 1997-2025 Sam Lantinga \n" "\n" " This software is provided 'as-is', without any express or implied\n" " warranty. In no event will the authors be held liable for any damages\n" diff --git a/build-scripts/gen_audio_resampler_filter.c b/build-scripts/gen_audio_resampler_filter.c index 22b7437..df0acca 100644 --- a/build-scripts/gen_audio_resampler_filter.c +++ b/build-scripts/gen_audio_resampler_filter.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -113,7 +113,7 @@ int main(void) printf( "/*\n" " Simple DirectMedia Layer\n" - " Copyright (C) 1997-2024 Sam Lantinga \n" + " Copyright (C) 1997-2025 Sam Lantinga \n" "\n" " This software is provided 'as-is', without any express or implied\n" " warranty. In no event will the authors be held liable for any damages\n" diff --git a/build-scripts/release-info.json b/build-scripts/release-info.json new file mode 100644 index 0000000..02a294e --- /dev/null +++ b/build-scripts/release-info.json @@ -0,0 +1,108 @@ +{ + "name": "SDL2", + "remote": "libsdl-org/SDL", + "version": { + "file": "include/SDL_version.h", + "re_major": "^#define SDL_MAJOR_VERSION\\s+([0-9]+)$", + "re_minor": "^#define SDL_MINOR_VERSION\\s+([0-9]+)$", + "re_micro": "^#define SDL_PATCHLEVEL\\s+([0-9]+)$" + }, + "source": { + "checks": [ + "src/SDL.c", + "include/SDL.h", + "test/testsprite2.c", + "android-project/app/src/main/java/org/libsdl/app/SDLActivity.java" + ] + }, + "dmg": { + "project": "Xcode/SDL/SDL.xcodeproj", + "path": "Xcode/SDL/build/SDL2.dmg", + "target": "Standard DMG" + }, + "mingw": { + "autotools": { + "archs": ["x86", "x64"], + "args": [ + ], + "files": { + "@<@TRIPLET@>@/include/SDL2": [ + "include/SDL_config*.h" + ] + } + }, + "files": { + "": [ + "mingw/pkg-support/INSTALL.txt", + "mingw/pkg-support/Makefile", + "BUGS.txt", + "CREDITS.txt", + "README-SDL.txt", + "WhatsNew.txt", + "LICENSE.txt", + "README.md" + ], + "cmake": [ + "mingw/pkg-support/cmake/sdl2-config.cmake", + "mingw/pkg-support/cmake/sdl2-config-version.cmake" + ], + "docs": [ + "docs/*" + ], + "test": [ + "test/*" + ] + } + }, + "msvc": { + "msbuild": { + "archs": [ + "x86", + "x64" + ], + "projects": [ + "VisualC/SDL/SDL.vcxproj", + "VisualC/SDLmain/SDLmain.vcxproj", + "VisualC/SDLtest/SDLtest.vcxproj" + ], + "files-lib": { + "": [ + "VisualC/SDL/@<@PLATFORM@>@/@<@CONFIGURATION@>@/SDL2.dll" + ] + }, + "files-devel": { + "lib/@<@ARCH@>@": [ + "VisualC/SDL/@<@PLATFORM@>@/@<@CONFIGURATION@>@/SDL2.dll", + "VisualC/SDL/@<@PLATFORM@>@/@<@CONFIGURATION@>@/SDL2.lib", + "VisualC/SDL/@<@PLATFORM@>@/@<@CONFIGURATION@>@/SDL2.pdb", + "VisualC/SDLmain/@<@PLATFORM@>@/@<@CONFIGURATION@>@/SDL2main.lib", + "VisualC/SDLtest/@<@PLATFORM@>@/@<@CONFIGURATION@>@/SDL2test.lib" + ] + } + }, + "files-lib": { + "": [ + "README-SDL.txt" + ] + }, + "files-devel": { + "": [ + "README-SDL.txt", + "BUGS.txt", + "LICENSE.txt", + "README.md", + "WhatsNew.txt" + ], + "cmake": [ + "VisualC/pkg-support/cmake/sdl2-config.cmake", + "VisualC/pkg-support/cmake/sdl2-config-version.cmake" + ], + "docs": [ + "docs/*" + ], + "include": [ + "include/*.h" + ] + } + } +} diff --git a/build-scripts/setup-gdk-desktop.py b/build-scripts/setup-gdk-desktop.py new file mode 100755 index 0000000..d2309a0 --- /dev/null +++ b/build-scripts/setup-gdk-desktop.py @@ -0,0 +1,303 @@ +#!/usr/bin/env python + +import argparse +import functools +import logging +import os +from pathlib import Path +import re +import shutil +import subprocess +import tempfile +import textwrap +import urllib.request +import zipfile + +# Update both variables when updating the GDK +GIT_REF = "June_2024_Update_1" +GDK_EDITION = "240601" # YYMMUU + +logger = logging.getLogger(__name__) + +class GdDesktopConfigurator: + def __init__(self, gdk_path, arch, vs_folder, vs_version=None, vs_toolset=None, temp_folder=None, git_ref=None, gdk_edition=None): + self.git_ref = git_ref or GIT_REF + self.gdk_edition = gdk_edition or GDK_EDITION + self.gdk_path = gdk_path + self.temp_folder = temp_folder or Path(tempfile.gettempdir()) + self.dl_archive_path = Path(self.temp_folder) / f"{ self.git_ref }.zip" + self.gdk_extract_path = Path(self.temp_folder) / f"GDK-{ self.git_ref }" + self.arch = arch + self.vs_folder = vs_folder + self._vs_version = vs_version + self._vs_toolset = vs_toolset + + def download_archive(self) -> None: + gdk_url = f"https://github.com/microsoft/GDK/archive/refs/tags/{ GIT_REF }.zip" + logger.info("Downloading %s to %s", gdk_url, self.dl_archive_path) + urllib.request.urlretrieve(gdk_url, self.dl_archive_path) + assert self.dl_archive_path.is_file() + + def extract_zip_archive(self) -> None: + extract_path = self.gdk_extract_path.parent + assert self.dl_archive_path.is_file() + logger.info("Extracting %s to %s", self.dl_archive_path, extract_path) + with zipfile.ZipFile(self.dl_archive_path) as zf: + zf.extractall(extract_path) + assert self.gdk_extract_path.is_dir(), f"{self.gdk_extract_path} must exist" + + def extract_development_kit(self) -> None: + extract_dks_cmd = self.gdk_extract_path / "SetupScripts/ExtractXboxOneDKs.cmd" + assert extract_dks_cmd.is_file() + logger.info("Extracting GDK Development Kit: running %s", extract_dks_cmd) + cmd = ["cmd.exe", "/C", str(extract_dks_cmd), str(self.gdk_extract_path), str(self.gdk_path)] + logger.debug("Running %r", cmd) + subprocess.check_call(cmd) + + def detect_vs_version(self) -> str: + vs_regex = re.compile("VS([0-9]{4})") + supported_vs_versions = [] + for p in self.gaming_grdk_build_path.iterdir(): + if not p.is_dir(): + continue + if m := vs_regex.match(p.name): + supported_vs_versions.append(m.group(1)) + logger.info(f"Supported Visual Studio versions: {supported_vs_versions}") + vs_versions = set(self.vs_folder.parts).intersection(set(supported_vs_versions)) + if not vs_versions: + raise RuntimeError("Visual Studio version is incompatible") + if len(vs_versions) > 1: + raise RuntimeError(f"Too many compatible VS versions found ({vs_versions})") + vs_version = vs_versions.pop() + logger.info(f"Used Visual Studio version: {vs_version}") + return vs_version + + def detect_vs_toolset(self) -> str: + toolset_paths = [] + for ts_path in self.gdk_toolset_parent_path.iterdir(): + if not ts_path.is_dir(): + continue + ms_props = ts_path / "Microsoft.Cpp.props" + if not ms_props.is_file(): + continue + toolset_paths.append(ts_path.name) + logger.info("Detected Visual Studio toolsets: %s", toolset_paths) + assert toolset_paths, "Have we detected at least one toolset?" + + def toolset_number(toolset: str) -> int: + if m:= re.match("[^0-9]*([0-9]+).*", toolset): + return int(m.group(1)) + return -9 + + return max(toolset_paths, key=toolset_number) + + @property + def vs_version(self) -> str: + if self._vs_version is None: + self._vs_version = self.detect_vs_version() + return self._vs_version + + @property + def vs_toolset(self) -> str: + if self._vs_toolset is None: + self._vs_toolset = self.detect_vs_toolset() + return self._vs_toolset + + @staticmethod + def copy_files_and_merge_into(srcdir: Path, dstdir: Path) -> None: + logger.info(f"Copy {srcdir} to {dstdir}") + for root, _, files in os.walk(srcdir): + dest_root = dstdir / Path(root).relative_to(srcdir) + if not dest_root.is_dir(): + dest_root.mkdir() + for file in files: + srcfile = Path(root) / file + dstfile = dest_root / file + shutil.copy(srcfile, dstfile) + + def copy_msbuild(self) -> None: + vc_toolset_parent_path = self.vs_folder / "MSBuild/Microsoft/VC" + if 1: + logger.info(f"Detected compatible Visual Studio version: {self.vs_version}") + srcdir = vc_toolset_parent_path + dstdir = self.gdk_toolset_parent_path + assert srcdir.is_dir(), "Source directory must exist" + assert dstdir.is_dir(), "Destination directory must exist" + + self.copy_files_and_merge_into(srcdir=srcdir, dstdir=dstdir) + + @property + def game_dk_path(self) -> Path: + return self.gdk_path / "Microsoft GDK" + + @property + def game_dk_latest_path(self) -> Path: + return self.game_dk_path / self.gdk_edition + + @property + def windows_sdk_path(self) -> Path: + return self.gdk_path / "Windows Kits/10" + + @property + def gaming_grdk_build_path(self) -> Path: + return self.game_dk_latest_path / "GRDK" + + @property + def gdk_toolset_parent_path(self) -> Path: + return self.gaming_grdk_build_path / f"VS{self.vs_version}/flatDeployment/MSBuild/Microsoft/VC" + + @property + def env(self) -> dict[str, str]: + game_dk = self.game_dk_path + game_dk_latest = self.game_dk_latest_path + windows_sdk_dir = self.windows_sdk_path + gaming_grdk_build = self.gaming_grdk_build_path + + return { + "GRDKEDITION": f"{self.gdk_edition}", + "GameDK": f"{game_dk}\\", + "GameDKLatest": f"{ game_dk_latest }\\", + "WindowsSdkDir": f"{ windows_sdk_dir }\\", + "GamingGRDKBuild": f"{ gaming_grdk_build }\\", + "VSInstallDir": f"{ self.vs_folder }\\", + } + + def create_user_props(self, path: Path) -> None: + vc_targets_path = self.gaming_grdk_build_path / f"VS{ self.vs_version }/flatDeployment/MSBuild/Microsoft/VC/{ self.vs_toolset }" + vc_targets_path16 = self.gaming_grdk_build_path / f"VS2019/flatDeployment/MSBuild/Microsoft/VC/{ self.vs_toolset }" + vc_targets_path17 = self.gaming_grdk_build_path / f"VS2022/flatDeployment/MSBuild/Microsoft/VC/{ self.vs_toolset }" + additional_include_directories = ";".join(str(p) for p in self.gdk_include_paths) + additional_library_directories = ";".join(str(p) for p in self.gdk_library_paths) + durango_xdk_install_path = self.gdk_path / "Microsoft GDK" + with path.open("w") as f: + f.write(textwrap.dedent(f"""\ + + + + { vc_targets_path }\\ + { vc_targets_path16 }\\ + { vc_targets_path17 }\\ + { self.gaming_grdk_build_path }\\ + Gaming.Desktop.x64 + Debug + { self.gdk_edition } + { durango_xdk_install_path } + + $(DurangoXdkInstallPath)\\{self.gdk_edition}\\GRDK\\VS2019\\flatDeployment\\MSBuild\\Microsoft\\VC\\{self.vs_toolset}\\Platforms\\$(Platform)\\ + $(DurangoXdkInstallPath)\\{self.gdk_edition}\\GRDK\\VS2019\\flatDeployment\\MSBuild\\Microsoft\\VC\\{self.vs_toolset}\\Platforms\\$(Platform)\\ + $(DurangoXdkInstallPath)\\{self.gdk_edition}\\GRDK\\VS2022\\flatDeployment\\MSBuild\\Microsoft\\VC\\{self.vs_toolset}\\Platforms\\$(Platform)\\ + $(DurangoXdkInstallPath)\\{self.gdk_edition}\\GRDK\\VS2022\\flatDeployment\\MSBuild\\Microsoft\\VC\\{self.vs_toolset}\\Platforms\\$(Platform)\\ + + true + true + true + + + + { additional_include_directories };%(AdditionalIncludeDirectories) + + + { additional_library_directories };%(AdditionalLibraryDirectories) + + + + """)) + + @property + def gdk_include_paths(self) -> list[Path]: + return [ + self.gaming_grdk_build_path / "gamekit/include", + ] + + @property + def gdk_library_paths(self) -> list[Path]: + return [ + self.gaming_grdk_build_path / f"gamekit/lib/{self.arch}", + ] + + @property + def gdk_binary_path(self) -> list[Path]: + return [ + self.gaming_grdk_build_path / "bin", + self.game_dk_path / "bin", + ] + + @property + def build_env(self) -> dict[str, str]: + gdk_include = ";".join(str(p) for p in self.gdk_include_paths) + gdk_lib = ";".join(str(p) for p in self.gdk_library_paths) + gdk_path = ";".join(str(p) for p in self.gdk_binary_path) + return { + "GDK_INCLUDE": gdk_include, + "GDK_LIB": gdk_lib, + "GDK_PATH": gdk_path, + } + + def print_env(self) -> None: + for k, v in self.env.items(): + print(f"set \"{k}={v}\"") + print() + for k, v in self.build_env.items(): + print(f"set \"{k}={v}\"") + print() + print(f"set \"PATH=%GDK_PATH%;%PATH%\"") + print(f"set \"LIB=%GDK_LIB%;%LIB%\"") + print(f"set \"INCLUDE=%GDK_INCLUDE%;%INCLUDE%\"") + + +def main(): + logging.basicConfig(level=logging.INFO) + parser = argparse.ArgumentParser(allow_abbrev=False) + parser.add_argument("--arch", choices=["amd64"], default="amd64", help="Architecture") + parser.add_argument("--download", action="store_true", help="Download GDK") + parser.add_argument("--extract", action="store_true", help="Extract downloaded GDK") + parser.add_argument("--copy-msbuild", action="store_true", help="Copy MSBuild files") + parser.add_argument("--temp-folder", help="Temporary folder where to download and extract GDK") + parser.add_argument("--gdk-path", required=True, type=Path, help="Folder where to store the GDK") + parser.add_argument("--ref-edition", type=str, help="Git ref and GDK edition separated by comma") + parser.add_argument("--vs-folder", required=True, type=Path, help="Installation folder of Visual Studio") + parser.add_argument("--vs-version", required=False, type=int, help="Visual Studio version") + parser.add_argument("--vs-toolset", required=False, help="Visual Studio toolset (e.g. v150)") + parser.add_argument("--props-folder", required=False, type=Path, default=Path(), help="Visual Studio toolset (e.g. v150)") + parser.add_argument("--no-user-props", required=False, dest="user_props", action="store_false", help="Don't ") + args = parser.parse_args() + + logging.basicConfig(level=logging.INFO) + + git_ref = None + gdk_edition = None + if args.ref_edition is not None: + git_ref, gdk_edition = args.ref_edition.split(",", 1) + try: + int(gdk_edition) + except ValueError: + parser.error("Edition should be an integer (YYMMUU) (Y=year M=month U=update)") + + configurator = GdDesktopConfigurator( + arch=args.arch, + git_ref=git_ref, + gdk_edition=gdk_edition, + vs_folder=args.vs_folder, + vs_version=args.vs_version, + vs_toolset=args.vs_toolset, + gdk_path=args.gdk_path, + temp_folder=args.temp_folder, + ) + + if args.download: + configurator.download_archive() + + if args.extract: + configurator.extract_zip_archive() + + configurator.extract_development_kit() + + if args.copy_msbuild: + configurator.copy_msbuild() + + if args.user_props: + configurator.print_env() + configurator.create_user_props(args.props_folder / "Directory.Build.props") + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/cmake/sdlchecks.cmake b/cmake/sdlchecks.cmake index 8156653..a23b2ef 100644 --- a/cmake/sdlchecks.cmake +++ b/cmake/sdlchecks.cmake @@ -1352,12 +1352,13 @@ endmacro() macro(CheckLibUDev) if(SDL_LIBUDEV) - check_include_file("libudev.h" have_libudev_header) - if(have_libudev_header) + check_include_file("libudev.h" HAVE_LIBUDEV_HEADER) + if(HAVE_LIBUDEV_HEADER) set(HAVE_LIBUDEV_H TRUE) FindLibraryAndSONAME(udev) if(UDEV_LIB_SONAME) set(SDL_UDEV_DYNAMIC "\"${UDEV_LIB_SONAME}\"") + set(HAVE_LIBUDEV TRUE) endif() endif() endif() diff --git a/cmake/test/CMakeLists.txt b/cmake/test/CMakeLists.txt index 388e86c..a9c0c49 100644 --- a/cmake/test/CMakeLists.txt +++ b/cmake/test/CMakeLists.txt @@ -27,6 +27,12 @@ add_feature_info("TEST_SHARED" TEST_SHARED "Test linking with shared library") option(TEST_STATIC "Test linking to static SDL2 library" ON) add_feature_info("TEST_STATIC" TEST_STATIC "Test linking with static library") +option(TEST_TEST "Test linking to SDL3_test library" ON) +add_feature_info("TEST_TEST" TEST_STATIC "Test linking to SDL test library") + +option(TEST_FULL "Run complete SDL test suite" OFF) +add_feature_info("TEST_FULL" TEST_FULL "Build full SDL testsuite") + if(TEST_SHARED) find_package(SDL2 REQUIRED CONFIG COMPONENTS SDL2) if(EMSCRIPTEN OR (WIN32 AND NOT WINDOWS_STORE)) @@ -75,6 +81,11 @@ if(TEST_SHARED) generate_export_header(sharedlib-shared-vars EXPORT_MACRO_NAME MYLIBRARY_EXPORT) target_compile_definitions(sharedlib-shared-vars PRIVATE "EXPORT_HEADER=\"${CMAKE_CURRENT_BINARY_DIR}/sharedlib-shared-vars_export.h\"") set_target_properties(sharedlib-shared-vars PROPERTIES C_VISIBILITY_PRESET "hidden") + + if(TEST_TEST) + add_executable(sdltest-shared sdltest.c) + target_link_libraries(sdltest-shared PRIVATE SDL2::SDL2main SDL2::SDL2test SDL2::SDL2) + endif() endif() if(TEST_STATIC) @@ -111,6 +122,21 @@ if(TEST_STATIC) target_link_libraries(cli-static-vars PRIVATE ${SDL2_STATIC_LIBRARIES}) target_include_directories(cli-static-vars PRIVATE ${SDL2_INCLUDE_DIRS}) endif() + + if(CMAKE_Swift_COMPILER) + add_executable(swift-static main.swift) + target_include_directories(swift-static PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/swift") + target_link_libraries(swift-static PRIVATE SDL2::SDL2-static) + endif() +endif() + +if(TEST_FULL) + enable_testing() + set(SDL_TESTS_TIMEOUT_MULTIPLIER "1" CACHE STRING "Test timeout multiplier") + set(SDL_TESTS_LINK_SHARED ${TEST_SHARED}) + + add_definitions(-DNO_BUILD_CONFIG) + add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/../../test" SDL_test) endif() message(STATUS "SDL2_PREFIX: ${SDL2_PREFIX}") diff --git a/cmake/test/jni/Android.mk b/cmake/test/jni/Android.mk new file mode 100644 index 0000000..c4956d6 --- /dev/null +++ b/cmake/test/jni/Android.mk @@ -0,0 +1,11 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := main_gui_androidmk +LOCAL_SRC_FILES := ../main_gui.c +LOCAL_SHARED_LIBRARIES += SDL2 +include $(BUILD_SHARED_LIBRARY) + +$(call import-module,SDL2main) +$(call import-module,SDL2) diff --git a/cmake/test/sdltest.c b/cmake/test/sdltest.c new file mode 100644 index 0000000..5c6d697 --- /dev/null +++ b/cmake/test/sdltest.c @@ -0,0 +1,9 @@ +#include "SDL.h" +#include "SDL_test.h" + + +int main(int argc, char *argv[]) { + SDLTest_CommonState state; + SDLTest_CommonDefaultArgs(&state, argc, argv); + return 0; +} diff --git a/configure b/configure index 61b6711..0b41e13 100755 --- a/configure +++ b/configure @@ -873,7 +873,6 @@ enable_sse2 enable_sse3 enable_altivec enable_lsx -enable_lasx enable_oss enable_alsa with_alsa_prefix @@ -1669,13 +1668,12 @@ Optional Features: --enable-ssemath Allow GCC to use SSE floating point math [default=maybe] --enable-mmx use MMX assembly routines [default=yes] - --enable-3dnow use 3DNow! assembly routines [default=yes] + --enable-3dnow use 3DNow! assembly routines [default=no] --enable-sse use SSE assembly routines [default=yes] --enable-sse2 use SSE2 assembly routines [default=maybe] --enable-sse3 use SSE3 assembly routines [default=maybe] --enable-altivec use Altivec assembly routines [default=yes] --enable-lsx use LSX assembly routines [default=yes] - --enable-lasx use LASX assembly routines [default=yes] --enable-oss support the OSS audio API [default=maybe] --enable-alsa support the ALSA audio API [default=yes] --disable-alsatest Do not try to compile and run a test Alsa program @@ -3510,7 +3508,7 @@ orig_CFLAGS="$CFLAGS" # See docs/release_checklist.md SDL_MAJOR_VERSION=2 SDL_MINOR_VERSION=30 -SDL_MICRO_VERSION=0 +SDL_MICRO_VERSION=11 SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION SDL_BINARY_AGE=`expr $SDL_MINOR_VERSION \* 100 + $SDL_MICRO_VERSION` @@ -18818,7 +18816,7 @@ fi enable_system_iconv_default=yes case "$host" in - *-*-cygwin*|*-*-mingw*) + *-*-cygwin*|*-*-mingw*|*-*-darwin*|*-ios-*) enable_system_iconv_default=no ;; esac @@ -19749,6 +19747,18 @@ if test "x$ac_cv_func_poll" = xyes then : printf "%s\n" "#define HAVE_POLL 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "memfd_create" "ac_cv_func_memfd_create" +if test "x$ac_cv_func_memfd_create" = xyes +then : + printf "%s\n" "#define HAVE_MEMFD_CREATE 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "posix_fallocate" "ac_cv_func_posix_fallocate" +if test "x$ac_cv_func_posix_fallocate" = xyes +then : + printf "%s\n" "#define HAVE_POSIX_FALLOCATE 1" >>confdefs.h + fi ac_fn_c_check_func "$LINENO" "_Exit" "ac_cv_func__Exit" if test "x$ac_cv_func__Exit" = xyes @@ -20637,7 +20647,7 @@ if test ${enable_3dnow+y} then : enableval=$enable_3dnow; else $as_nop - enable_3dnow=yes + enable_3dnow=no fi if test x$enable_3dnow = xyes; then @@ -21026,7 +21036,7 @@ printf "%s\n" "#define HAVE_ALTIVEC_H 1" >>confdefs.h fi fi - # Check whether --enable-lsx was given. +# Check whether --enable-lsx was given. if test ${enable_lsx+y} then : enableval=$enable_lsx; @@ -21034,20 +21044,20 @@ else $as_nop enable_lsx=yes fi - if test x$enable_lsx = xyes; then - save_CFLAGS="$CFLAGS" - have_gcc_lsx=no - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GCC -mlsx option" >&5 +if test x$enable_lsx = xyes; then + save_CFLAGS="$CFLAGS" + have_gcc_lsx=no + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GCC -mlsx option" >&5 printf %s "checking for GCC -mlsx option... " >&6; } - lsx_CFLAGS="-mlsx" - CFLAGS="$save_CFLAGS $lsx_CFLAGS" + lsx_CFLAGS="-mlsx" + CFLAGS="$save_CFLAGS $lsx_CFLAGS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - #ifndef __loongarch_sx - #error Assembler CPP flag not enabled - #endif + #ifndef __loongarch_sx + #error Assembler CPP flag not enabled + #endif int main (void) @@ -21062,19 +21072,19 @@ then : have_gcc_lsx=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_lsx" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_gcc_lsx" >&5 printf "%s\n" "$have_gcc_lsx" >&6; } - CFLAGS="$save_CFLAGS" + CFLAGS="$save_CFLAGS" - if test x$have_gcc_lsx = xyes; then - EXTRA_CFLAGS="$EXTRA_CFLAGS $lsx_CFLAGS" - SUMMARY_math="${SUMMARY_math} lsx" - fi + if test x$have_gcc_lsx = xyes; then + EXTRA_CFLAGS="$EXTRA_CFLAGS $lsx_CFLAGS" + SUMMARY_math="${SUMMARY_math} lsx" fi +fi - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for lsxintrin.h" >&5 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for lsxintrin.h" >&5 printf %s "checking for lsxintrin.h... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int @@ -21092,88 +21102,14 @@ else $as_nop have_lsxintrin_h_hdr=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_lsxintrin_h_hdr" >&5 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_lsxintrin_h_hdr" >&5 printf "%s\n" "$have_lsxintrin_h_hdr" >&6; } - if test x$have_lsxintrin_h_hdr = xyes; then +if test x$have_lsxintrin_h_hdr = xyes; then printf "%s\n" "#define HAVE_LSXINTRIN_H 1" >>confdefs.h - fi - - # Check whether --enable-lasx was given. -if test ${enable_lasx+y} -then : - enableval=$enable_lasx; -else $as_nop - enable_LASX=yes fi - if test x$enable_LASX = xyes; then - save_CFLAGS="$CFLAGS" - have_gcc_lasx=no - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GCC -mlasx option" >&5 -printf %s "checking for GCC -mlasx option... " >&6; } - lasx_CFLAGS="-mlasx" - CFLAGS="$save_CFLAGS $lasx_CFLAGS" - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - #ifndef __loongarch_asx - #error Assembler CPP flag not enabled - #endif - -int -main (void) -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - have_gcc_lasx=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_lasx" >&5 -printf "%s\n" "$have_gcc_lasx" >&6; } - CFLAGS="$save_CFLAGS" - - if test x$have_gcc_lasx = xyes; then - EXTRA_CFLAGS="$EXTRA_CFLAGS $lasx_CFLAGS" - SUMMARY_math="${SUMMARY_math} lasx" - fi - fi - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for lasxintrin.h" >&5 -printf %s "checking for lasxintrin.h... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main (void) -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - have_lasxintrin_h_hdr=yes -else $as_nop - have_lasxintrin_h_hdr=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_lasxintrin_h_hdr" >&5 -printf "%s\n" "$have_lasxintrin_h_hdr" >&6; } - if test x$have_lasxintrin_h_hdr = xyes; then - -printf "%s\n" "#define HAVE_LASXINTRIN_H 1" >>confdefs.h - - fi - CheckOSS() { # Check whether --enable-oss was given. @@ -27577,18 +27513,14 @@ then : have_d3d11=yes fi - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for d3d12 Windows SDK version" >&5 -printf %s "checking for d3d12 Windows SDK version... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for compatible d3d12 headers" >&5 +printf %s "checking for compatible d3d12 headers... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include -#include #include +#include ID3D12Device1 *device; -#if WDK_NTDDI_VERSION <= 0x0A000008 -asdf -#endif int main (void) @@ -27607,6 +27539,7 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_d3d12" >&5 printf "%s\n" "$have_d3d12" >&6; } + ac_fn_c_check_header_compile "$LINENO" "ddraw.h" "ac_cv_header_ddraw_h" "$ac_includes_default" if test "x$ac_cv_header_ddraw_h" = xyes then : diff --git a/configure.ac b/configure.ac index 56087fb..be32efa 100644 --- a/configure.ac +++ b/configure.ac @@ -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=30 -SDL_MICRO_VERSION=0 +SDL_MICRO_VERSION=11 SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION SDL_BINARY_AGE=`expr $SDL_MINOR_VERSION \* 100 + $SDL_MICRO_VERSION` @@ -322,7 +322,7 @@ AC_ARG_ENABLE(libc, dnl See whether we are allowed to use system iconv enable_system_iconv_default=yes case "$host" in - *-*-cygwin*|*-*-mingw*) + *-*-cygwin*|*-*-mingw*|*-*-darwin*|*-ios-*) enable_system_iconv_default=no ;; esac @@ -359,7 +359,7 @@ dnl Checks for library functions. AC_DEFINE(HAVE_MPROTECT, 1, [ ]) ],[]), ) - AC_CHECK_FUNCS(malloc calloc realloc free getenv setenv putenv unsetenv bsearch qsort abs bcopy memset memcmp memcpy memmove wcslen wcslcpy wcslcat _wcsdup wcsdup wcsstr wcscmp wcsncmp wcscasecmp _wcsicmp wcsncasecmp _wcsnicmp strlen strlcpy strlcat _strrev _strupr _strlwr index rindex strchr strrchr strstr strtok_r itoa _ltoa _uitoa _ultoa strtod strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp strcasestr vsscanf vsnprintf fopen64 fseeko fseeko64 sigaction setjmp nanosleep sysconf sysctlbyname getauxval elf_aux_info poll _Exit) + AC_CHECK_FUNCS(malloc calloc realloc free getenv setenv putenv unsetenv bsearch qsort abs bcopy memset memcmp memcpy memmove wcslen wcslcpy wcslcat _wcsdup wcsdup wcsstr wcscmp wcsncmp wcscasecmp _wcsicmp wcsncasecmp _wcsnicmp strlen strlcpy strlcat _strrev _strupr _strlwr index rindex strchr strrchr strstr strtok_r itoa _ltoa _uitoa _ultoa strtod strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp strcasestr vsscanf vsnprintf fopen64 fseeko fseeko64 sigaction setjmp nanosleep sysconf sysctlbyname getauxval elf_aux_info poll memfd_create posix_fallocate _Exit) AC_CHECK_LIB(m, pow, [LIBS="$LIBS -lm"; EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lm"]) AC_CHECK_FUNCS(acos acosf asin asinf atan atanf atan2 atan2f ceil ceilf copysign copysignf cos cosf exp expf fabs fabsf floor floorf trunc truncf fmod fmodf log logf log10 log10f lround lroundf pow powf round roundf scalbn scalbnf sin sinf sqrt sqrtf tan tanf) @@ -698,8 +698,8 @@ dnl Check for various instruction support fi AC_ARG_ENABLE(3dnow, -[AS_HELP_STRING([--enable-3dnow], [use 3DNow! assembly routines [default=yes]])], - , enable_3dnow=yes) +[AS_HELP_STRING([--enable-3dnow], [use 3DNow! assembly routines [default=no]])], + , enable_3dnow=no) if test x$enable_3dnow = xyes; then save_CFLAGS="$CFLAGS" have_gcc_3dnow=no @@ -906,69 +906,37 @@ dnl Check for various instruction support fi fi - AC_ARG_ENABLE(lsx, +AC_ARG_ENABLE(lsx, [AS_HELP_STRING([--enable-lsx], [use LSX assembly routines [default=yes]])], , enable_lsx=yes) - if test x$enable_lsx = xyes; then - save_CFLAGS="$CFLAGS" - have_gcc_lsx=no - AC_MSG_CHECKING(for GCC -mlsx option) - lsx_CFLAGS="-mlsx" - CFLAGS="$save_CFLAGS $lsx_CFLAGS" - - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #ifndef __loongarch_sx - #error Assembler CPP flag not enabled - #endif - ]], [])], [have_gcc_lsx=yes], []) - AC_MSG_RESULT($have_gcc_lsx) - CFLAGS="$save_CFLAGS" - - if test x$have_gcc_lsx = xyes; then - EXTRA_CFLAGS="$EXTRA_CFLAGS $lsx_CFLAGS" - SUMMARY_math="${SUMMARY_math} lsx" - fi - fi - - AC_MSG_CHECKING(for lsxintrin.h) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]])], - [have_lsxintrin_h_hdr=yes],[have_lsxintrin_h_hdr=no]) - AC_MSG_RESULT($have_lsxintrin_h_hdr) - if test x$have_lsxintrin_h_hdr = xyes; then - AC_DEFINE(HAVE_LSXINTRIN_H, 1, [ ]) - fi - - AC_ARG_ENABLE(lasx, -[AS_HELP_STRING([--enable-lasx], [use LASX assembly routines [default=yes]])], - , enable_LASX=yes) - if test x$enable_LASX = xyes; then - save_CFLAGS="$CFLAGS" - have_gcc_lasx=no - AC_MSG_CHECKING(for GCC -mlasx option) - lasx_CFLAGS="-mlasx" - CFLAGS="$save_CFLAGS $lasx_CFLAGS" +if test x$enable_lsx = xyes; then + save_CFLAGS="$CFLAGS" + have_gcc_lsx=no + AC_MSG_CHECKING(for GCC -mlsx option) + lsx_CFLAGS="-mlsx" + CFLAGS="$save_CFLAGS $lsx_CFLAGS" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #ifndef __loongarch_asx - #error Assembler CPP flag not enabled - #endif - ]], [])], [have_gcc_lasx=yes], []) - AC_MSG_RESULT($have_gcc_lasx) - CFLAGS="$save_CFLAGS" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #ifndef __loongarch_sx + #error Assembler CPP flag not enabled + #endif + ]], [])], [have_gcc_lsx=yes], []) + AC_MSG_RESULT($have_gcc_lsx) + CFLAGS="$save_CFLAGS" - if test x$have_gcc_lasx = xyes; then - EXTRA_CFLAGS="$EXTRA_CFLAGS $lasx_CFLAGS" - SUMMARY_math="${SUMMARY_math} lasx" - fi + if test x$have_gcc_lsx = xyes; then + EXTRA_CFLAGS="$EXTRA_CFLAGS $lsx_CFLAGS" + SUMMARY_math="${SUMMARY_math} lsx" fi +fi - AC_MSG_CHECKING(for lasxintrin.h) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]])], - [have_lasxintrin_h_hdr=yes],[have_lasxintrin_h_hdr=no]) - AC_MSG_RESULT($have_lasxintrin_h_hdr) - if test x$have_lasxintrin_h_hdr = xyes; then - AC_DEFINE(HAVE_LASXINTRIN_H, 1, [ ]) - fi +AC_MSG_CHECKING(for lsxintrin.h) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]])], + [have_lsxintrin_h_hdr=yes],[have_lsxintrin_h_hdr=no]) +AC_MSG_RESULT($have_lsxintrin_h_hdr) +if test x$have_lsxintrin_h_hdr = xyes; then + AC_DEFINE(HAVE_LSXINTRIN_H, 1, [ ]) +fi dnl See if the OSS audio interface is supported CheckOSS() @@ -3375,17 +3343,14 @@ CheckDIRECTX() if test x$enable_directx = xyes; then AC_CHECK_HEADER(d3d9.h, have_d3d=yes) AC_CHECK_HEADER(d3d11_1.h, have_d3d11=yes) - AC_MSG_CHECKING(for d3d12 Windows SDK version) + AC_MSG_CHECKING(for compatible d3d12 headers) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ -#include -#include #include +#include ID3D12Device1 *device; -#if WDK_NTDDI_VERSION <= 0x0A000008 -asdf -#endif ]])], [have_d3d12=yes],[have_d3d12=no]) AC_MSG_RESULT($have_d3d12) + AC_CHECK_HEADER(ddraw.h, have_ddraw=yes) AC_CHECK_HEADER(dsound.h, have_dsound=yes) AC_CHECK_HEADER(dinput.h, have_dinput=yes) diff --git a/debian/changelog b/debian/changelog index 530fd19..ea1158f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,266 @@ +libsdl2 (2.30.11+dfsg-1) unstable; urgency=medium + + * New upstream stable release + - Fix a crash if a game controller's product name is NULL + - Treat gamepad mappings with a specified CRC as more important than + mappings without a CRC, fixing PS3 (DualShock 3) gamepads + - 3DS-, Android-, emscripten-, iOS-, macOS-, PS2-, PSP-specific + changes not relevant to Debian + * d/copyright: Update + * d/control: Only depend on libpipewire-0.3-dev on Linux + + -- Simon McVittie Thu, 02 Jan 2025 20:57:00 +0000 + +libsdl2 (2.30.10+dfsg-1) unstable; urgency=medium + + * New upstream stable release + - Support multiple joystick buttons outputting the same gamepad button + - Improve portability of printing 64-bit integers + - Improve the performance of whole-surface fill operations if there + is no padding between rows + - Fix order of events in case audio buffer size changes + - Improve reproducibility of dynapi build + - Fix a buffer overflow that caused a rare crash on KMSDRM + - Disable AMD 3dNow extensions by default, avoiding miscompilation on + some x86 CPUs when using -march=native -mtune=native + - Android-, macOS-, Vita- and Windows-specific fixes not relevant + to Debian + * d/salsa-ci.yml: Use recommended recipe + + -- Simon McVittie Mon, 09 Dec 2024 11:23:13 +0000 + +libsdl2 (2.30.9+dfsg-1) unstable; urgency=medium + + * New upstream stable release + - Only use Steam virtual gamepad if actually running from Steam + (which sets a hint telling us to use it) + - Reduce size of blitting code + - Fix build issues for dependent code if it uses vulkan.hpp + - When using X11, set the correct clipboard target type + - When using native Wayland, always create a viewport if available, + fixing display issues under GNOME + - When using native Wayland, don't initialize OpenGL if not requested, + which can cause protocol violations now that the explicit sync + protocol is in use + - In testdrawchessboard, make it easier to switch to the accelerated + render API for comparison + - 3DS-, Android-, emscripten-, macOS-, Vita- and Windows-specific + fixes not relevant to Debian + * d/p/Reapply-wayland-Don-t-initialize-OpenGL-when-the-window-f.patch: + Drop patch, applied upstream + + -- Simon McVittie Mon, 04 Nov 2024 17:12:21 +0000 + +libsdl2 (2.30.8+dfsg-1) unstable; urgency=medium + + * New upstream stable release + - Use a better stack size for PulseAudio hotplugging + - Fix a hang if PulseAudio hotplugging fails to initialize + - Treat Thrustmaster TMX as a steering wheel + - Avoid sending excessive packets to PS4, PS5 controllers when + using raw HID + - Don't use incorrect optimized blit for SDL_PIXELFORMAT_ARGB1555 + - Add double-buffering support to Wayland video backend + - Use correct SONAME when dynamically loading libX11-xcb.so.1 + for use with Vulkan + - Send SDL_WINDOWEVENT_EXPOSED for Wayland windows when required + - Fix memory leaks in Vulkan video driver + - Add fallbacks so KMSDRM can work with older libdrm and libgbm + - Keep KMSDRM fd open after drmDropMaster() if possible + - Fix thread-safety and memory leaks in unit tests + - Android- and Windows-specific fixes not relevant to Debian + * d/p/Reapply-wayland-Don-t-initialize-OpenGL-when-the-window-f.patch: + Add a post-release bugfix from upstream + + -- Simon McVittie Fri, 04 Oct 2024 17:12:21 +0100 + +libsdl2 (2.30.7+dfsg-1) unstable; urgency=medium + + * New upstream stable release + - Fix XWayland cursor becoming visible when using relative mouse capture + - Fix a crash when the current mouse capture window is destroyed + - Treat Cammus C12 Wheelbase as a steering wheel + - Add support for PS3 controller clones that do not have + pressure-sensitive buttons, such as Retro-Bit Controller + - Fix KMSDRM initialization failure on some Linux systems + - Implement left-justification in SDL_snprintf on all platforms + - Android-, Vita- and Windows-specific fixes not relevant to Debian + + -- Simon McVittie Mon, 02 Sep 2024 13:53:14 +0100 + +libsdl2 (2.30.6+dfsg-1) unstable; urgency=medium + + * New upstream stable release + - Add gamepad mapping for SplitFish Game Controller + - Fix a crash if joystick rumble starts immediately before the + joystick is disconnected + - On Wayland, get a cursor successfully even if no window is focused + - Implement SDL_COMPILE_TIME_ASSERT with C23 static_assert in + preference to C11 _Static_assert if compiling in C23 mode + - CMake fixes, not relevant to how we compile SDL 2 in Debian + - Windows-, macOS- and OS/2 specific fixes, not relevant to Debian + * d/patches: Drop patches that were included in 2.30.6 + + -- Simon McVittie Fri, 02 Aug 2024 11:43:06 +0100 + +libsdl2 (2.30.5+dfsg-1) unstable; urgency=medium + + * New upstream stable release + - Treat ROG RAIKIRI as an Xbox Series-compatible gamepad + - Respect SDL_RENDER_DRIVER, SDL_FRAMEBUFFER_ACCELERATION hints when + creating an accelerated window surface + - Add SDL_MOUSE_RELATIVE_CURSOR_VISIBLE hint allowing the hardware + cursor to be kept visible in relative mode + - In the KMSDRM driver, use GBM modifiers if necessary + - Various platform-specific changes not relevant to Debian + * d/patches: Apply post-release bug fixes up to + release-2.30.5-18-ge7a47e783, excluding platform-specific changes not + relevant to Debian + - Try to create an accelerated renderer for the window surface, even + if SDL_HINT_RENDER_DRIVER is "software" + - Improve latency of Steam Deck controller via HIDAPI + - Improve detection of Nintendo Switch Pro controller report mode + - Fix attribute list for SDL_GL_FLOATBUFFERS + - Fix unsupported KMSDRM modifiers + - Fix a race condition in multi-threaded applications + - Fix an off-by-one that led to rare sem_timedwait() failures + - Ensure that all functions have proper prototypes + + -- Simon McVittie Fri, 19 Jul 2024 11:23:48 +0100 + +libsdl2 (2.30.4+dfsg-1) unstable; urgency=medium + + * New upstream stable release + - Pass through the original name of the Steam Virtual Gamepad, fixing + a regression for XInput slot mapping in Proton + (ValveSoftware/steam-for-linux#9571, steamrt/tasks#469) + - Try to use a platform HIDAPI backend in preference to libusb + - Add mappings for Qanba Drone 2 Arcade Joystick + - Treat some steering wheel controllers as such: + + VRS DirectForce Pro Wheel Base + + Simucube 1 Wheelbase + + Simucube 2 Ultimate Wheelbase + + Simucube 2 Pro Wheelbase + + Simucube 2 Sport Wheelbase + + Cammus C5 Wheelbase + - Don't treat Logitech HID devices as Playstation-compatible unless + included in an allowlist, avoiding various issues with + non-game-related Logitech HID devices + - Treat Logitech Chillstream as a PS3 controller + - Add support for Saitek Cyborg V.3 Rumble Pad in PS3 mode + - Fix mapping for R1 on third party PS3 controllers + - Treat Razer Kitsune arcade stick as a PS5 controller, and work around + lack of support for the feature-detection protocol + - Improve handling of Nintendo Switch controllers + - Don't crash if SDL_GetHint(NULL) is called + - Avoid undefined behaviour if SDL_iconv_string needs to resize + the buffer + - In Wayland, set the initial min/max limits when showing a window + without libdecor loaded + - Various Windows-, macOS- and OS/2-specific changes not listed here + * d/copyright: Exclude VisualC-GDK from orig tarball + + -- Simon McVittie Tue, 18 Jun 2024 12:57:02 +0100 + +libsdl2 (2.30.3+dfsg-1) unstable; urgency=medium + + * New upstream stable release + - Fix compilation in C89 mode + - Treat Thrustmaster TS-XW as a steering wheel + - Fix pointer warp on XWayland + - Speed up input device enumeration by trying not to open irrelevant + devices + - Don't use -mlasx to avoid baseline violation on loong64 + - Various Windows-specific changes + + -- Simon McVittie Wed, 29 May 2024 16:48:47 +0100 + +libsdl2 (2.30.2+dfsg-1) unstable; urgency=medium + + * New upstream stable release + - Fix a udev device enumeration performance regression + - Don't fail joystick initialization if udev isn't available + - Treat Sega Genesis/Mega Drive controller as having 6 buttons + - Add gamepad mapping for Defender Joystick Cobra R4 + - Remove generic mapping for HORI product ID 0d00, which has been + reused for several incompatible controllers + - Treat Yawman Arrow as a flight stick + - Don't treat MadCatz Saitek Side Panel Control Deck as + Playstation-compatible + - Try to use memfd_create() for Wayland cursors + - Avoid a crash under Wayland when all displays are disconnected + - Avoid protocol errors under Wayland if the viewport source is resized + under fractional scaling + * d/patches: Drop patches that were applied upstream + * Standards-Version: 4.7.0 (no changes required) + + -- Simon McVittie Tue, 16 Apr 2024 15:43:48 +0100 + +libsdl2 (2.30.1+dfsg-4) unstable; urgency=medium + + * d/control, d/rules: Re-enable native pipewire audio backend. + Convert it into a pkg.libsdl2.nopipewire build-profile, so that it's + convenient to break cycles in any future transitions that affect it. + This is a "non-reproducible" build profile, which makes functional + changes to the package, so breaking this cycle by building pipewire + with noinsttest is likely to be preferable. + * d/control, d/rules: Also add a pkg.libsdl2.nosndio build-profile + to disable sndio audio output, similar to the one for Pipewire + * d/control: Stop listing the audio drivers in the libsdl2-2.0-0 + Description. + This list was out of date (Pipewire was missing), and is not + particularly interesting information anyway. It seems to have been + left over from early libsdl1.2 packaging, where there were multiple + binary builds from the same source with different features enabled. + + -- Simon McVittie Mon, 25 Mar 2024 11:23:34 +0000 + +libsdl2 (2.30.1+dfsg-3) unstable; urgency=medium + + * Temporarily disable native Pipewire output on 32-bit non-x86. + libsdl2 is involved in a cyclic build-dependency with pipewire and + libcamera. This change can be reverted after it has been rebuilt. + + -- Simon McVittie Fri, 22 Mar 2024 11:05:04 +0000 + +libsdl2 (2.30.1+dfsg-2) unstable; urgency=medium + + * d/control, d/tests: Prefer pkgconf over pkg-config + * d/p/Fixed-crash-if-joystick-functions-are-passed-a-NULL-joyst.patch: + Add proposed patch to fix crash during doomsday startup + (Closes: #1062969) + + -- Simon McVittie Sat, 09 Mar 2024 11:49:07 +0000 + +libsdl2 (2.30.1+dfsg-1) unstable; urgency=medium + + * New upstream stable release + - Fix conversion of signed 16-bit audio to floating point 32-bit + - Improve gamepad mapping for Sanwa Supply JY-P76USV (also known as + GameShark GS-GP702) + - Treat OpenFFBoard as a steering wheel + - Fix a memory leak in Steam virtual gamepad handling + - Fix memory leaks in Wayland keyboard map handling + - Update viewport clipping rectangle when required + - Use CSS/freedesktop.org cursor names with traditional X11 names as + a fallback, fixing use of non-default cursors with updated + adwaita-icon-theme + - Convert mouse wheel coordinates to renderer view + - Fix a regression in 2.30.0 for the Vanilla-Conquer game engine + - Improve robustness of unit test for mathematical functions + * d/patches: Add post-release fixes from upstream release-2.30.x branch, + up to commit release-2.30.1-3-g3f0d7a293, excluding a Windows-specific + change + - d/p/SDL_RWFromFile-stdio-allow-named-pipes-along-with-regular.patch: + Allow opening fifos with SDL's I/O abstraction + - d/p/Fixed-mapping-for-the-Sanwa-Supply-JY-P76USV-controller.patch: + Improve gamepad mapping for Sanwa Supply JY-P76USV, again + * d/gbp.conf: Stop filtering imported tarballs. + Please use uscan instead, which will automatically produce a filtered + +dfsg tarball based on debian/copyright. + + -- Simon McVittie Thu, 07 Mar 2024 10:37:41 +0000 + libsdl2 (2.30.0+dfsg-1) unstable; urgency=medium * New upstream stable release diff --git a/debian/control b/debian/control index f8e6202..5241d60 100644 --- a/debian/control +++ b/debian/control @@ -6,7 +6,7 @@ Uploaders: Manuel A. Fernandez Montecelo , Felix Geyer , Simon McVittie -Standards-Version: 4.6.2 +Standards-Version: 4.7.0 Build-Depends: debhelper-compat (= 13), fcitx-libs-dev, @@ -19,10 +19,10 @@ Build-Depends: libgl-dev, libgles-dev [!hurd-any], libibus-1.0-dev, - libpipewire-0.3-dev (>= 0.3.20) [linux-any], + libpipewire-0.3-dev (>= 0.3.20) [linux-any] , libpulse-dev, libsamplerate0-dev, - libsndio-dev, + libsndio-dev , libudev-dev [linux-any], libusb2-dev [kfreebsd-any], libusbhid-dev [kfreebsd-any], @@ -40,7 +40,7 @@ Build-Depends: libxt-dev, libxv-dev, libxxf86vm-dev, - pkg-config, + pkgconf, wayland-protocols Build-Depends-Indep: graphviz , @@ -68,8 +68,7 @@ Description: Simple DirectMedia Layer SDL is a library that allows programs portable low level access to a video framebuffer, audio output, mouse, and keyboard. . - This version of SDL is compiled with X11 and Wayland graphics drivers and OSS, - ALSA, sndio and PulseAudio sound drivers. + This package contains the shared library. Package: libsdl2-dev Section: libdevel @@ -88,7 +87,7 @@ Depends: libpulse-dev, libsamplerate0-dev, libsdl2-2.0-0 (= ${binary:Version}), - libsndio-dev, + libsndio-dev , libudev-dev [linux-any], libusb2-dev [kfreebsd-any], libusbhid-dev [kfreebsd-any], diff --git a/debian/copyright b/debian/copyright index 02678a6..18d4abb 100644 --- a/debian/copyright +++ b/debian/copyright @@ -9,13 +9,14 @@ Files-Excluded: Android.mk src/video/os2/SDL_gradd.h test/unifont-* VisualC + VisualC-GDK VisualC-WinRT Xcode Xcode-iOS Files: * Copyright: - 1997-2024 Sam Lantinga + 1997-2025 Sam Lantinga 2012 Raspberry Pi Foundation 2012-2018 RISC OS Open Ltd 2018-2019 EXL diff --git a/debian/gbp.conf b/debian/gbp.conf index 75a0407..9a7c6d1 100644 --- a/debian/gbp.conf +++ b/debian/gbp.conf @@ -5,18 +5,3 @@ upstream-branch = upstream/latest [tag] sign-tags = True - -[import-orig] -filter = [ - 'Android.mk', - 'android-project', - 'src/hidapi/windows/ddk_build', - 'src/render/metal/SDL_shaders_metal_*.h', - 'src/video/os2/SDL_gradd.h', - 'test/unifont-*', - 'VisualC', - 'VisualC-WinRT', - 'Xcode', - 'Xcode-iOS', - ] -filter-pristine-tar = True diff --git a/debian/libsdl2-doc.doc-base b/debian/libsdl2-doc.doc-base index f9782aa..67aebe0 100644 --- a/debian/libsdl2-doc.doc-base +++ b/debian/libsdl2-doc.doc-base @@ -4,9 +4,6 @@ Author: Sam Lantinga Abstract: SDL is a library that allows programs portable low level access to a video framebuffer, audio output, mouse, and keyboard. - . - This version of SDL is compiled with X11 and Wayland graphics drivers and OSS, - ALSA, NAS, sndio and PulseAudio sound drivers. Section: Programming/C++ Format: HTML diff --git a/debian/rules b/debian/rules index a868f50..9a27626 100755 --- a/debian/rules +++ b/debian/rules @@ -75,6 +75,14 @@ else confflags += --disable-video-wayland endif +ifneq ($(filter pkg.libsdl2.nopipewire,$(DEB_BUILD_PROFILES)),) + confflags += --disable-pipewire +endif + +ifneq ($(filter pkg.libsdl2.nosndio,$(DEB_BUILD_PROFILES)),) + confflags += --disable-sndio +endif + # don't use libunwind even if it happens to be installed confflags += ac_cv_header_libunwind_h=no diff --git a/debian/salsa-ci.yml b/debian/salsa-ci.yml index 33c3a64..8424db4 100644 --- a/debian/salsa-ci.yml +++ b/debian/salsa-ci.yml @@ -1,4 +1,3 @@ --- include: - - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/salsa-ci.yml - - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/pipeline-jobs.yml + - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/recipes/debian.yml diff --git a/debian/tests/build b/debian/tests/build index f9717fe..6301f83 100755 --- a/debian/tests/build +++ b/debian/tests/build @@ -45,7 +45,7 @@ int main(void) } EOF -for tool in pkg-config sdl2-config; do +for tool in pkgconf sdl2-config; do for cc in "${CROSS_COMPILE}gcc" clang; do cflags= pcflags= @@ -68,14 +68,14 @@ for tool in pkg-config sdl2-config; do exe="use-${tool}-${cc}-${mode}" case "$tool" in - (pkg-config) + (pkgconf) # Deliberately word-splitting cflags, pcflags, pkg-config output # shellcheck disable=SC2046,SC2086 - "$cc" $cflags -o "${exe}" use-sdl.c $("${CROSS_COMPILE}pkg-config" $pcflags --cflags --libs sdl2) + "$cc" $cflags -o "${exe}" use-sdl.c $("${CROSS_COMPILE}pkgconf" $pcflags --cflags --libs sdl2) ;; (sdl2-config) # shellcheck disable=SC2046,SC2086 - "$cc" $cflags -o "${exe}" use-sdl.c $(PKG_CONFIG="${CROSS_COMPILE}pkg-config" sdl2-config --cflags $scflags) + "$cc" $cflags -o "${exe}" use-sdl.c $(PKG_CONFIG="${CROSS_COMPILE}pkgconf" sdl2-config --cflags $scflags) ;; (*) exit 1 diff --git a/debian/tests/control b/debian/tests/control index ab90dd1..d8f44ea 100644 --- a/debian/tests/control +++ b/debian/tests/control @@ -1,9 +1,9 @@ Tests: build -Depends: build-essential, clang:native, libsdl2-dev +Depends: build-essential, clang:native, libsdl2-dev, pkgconf Restrictions: allow-stderr, superficial Tests: deprecated-use -Depends: build-essential, clang:native, libsdl2-dev, libsdl2-ttf-dev +Depends: build-essential, clang:native, libsdl2-dev, libsdl2-ttf-dev, pkgconf Restrictions: allow-stderr, superficial Tests: cmake diff --git a/docs/README-macos.md b/docs/README-macos.md index 634d456..bcf6956 100644 --- a/docs/README-macos.md +++ b/docs/README-macos.md @@ -261,10 +261,10 @@ Some things that may be of interest about how it all works... ## Working directory In SDL 1.2, the working directory of your SDL app is by default set to its -parent, but this is no longer the case in SDL 2.0. SDL2 does change the -working directory, which means it'll be whatever the command line prompt -that launched the program was using, or if launched by double-clicking in -the finger, it will be "/", the _root of the filesystem_. Plan accordingly! +parent, but this is no longer the case in SDL 2.0 and later. SDL2 does not +change the working directory, which means it'll be whatever the command line +prompt that launched the program was using, or if launched by double-clicking +in the Finder, it will be "/", the _root of the filesystem_. Plan accordingly! You can use SDL_GetBasePath() to find where the program is running from and chdir() there directly. diff --git a/include/SDL.h b/include/SDL.h index 20c903b..fd58ac3 100644 --- a/include/SDL.h +++ b/include/SDL.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_assert.h b/include/SDL_assert.h index a396d4e..a19c9f2 100644 --- a/include/SDL_assert.h +++ b/include/SDL_assert.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_atomic.h b/include/SDL_atomic.h index 1fa18f4..3559ce9 100644 --- a/include/SDL_atomic.h +++ b/include/SDL_atomic.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_audio.h b/include/SDL_audio.h index bd8e7ab..f65deb9 100644 --- a/include/SDL_audio.h +++ b/include/SDL_audio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -594,7 +594,7 @@ extern DECLSPEC int SDLCALL SDL_GetDefaultAudioInfo(char **name, * frames_ (with stereo output, two samples--left and right--would make a * single sample frame). This number should be a power of two, and may be * adjusted by the audio driver to a value more suitable for the hardware. - * Good values seem to range between 512 and 8096 inclusive, depending on + * Good values seem to range between 512 and 4096 inclusive, depending on * the application and CPU speed. Smaller values reduce latency, but can * lead to underflow if the application is doing heavy processing and cannot * fill the audio buffer in time. Note that the number of sample frames is diff --git a/include/SDL_bits.h b/include/SDL_bits.h index 83e8a78..508351e 100644 --- a/include/SDL_bits.h +++ b/include/SDL_bits.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_blendmode.h b/include/SDL_blendmode.h index 09d0147..351b43d 100644 --- a/include/SDL_blendmode.h +++ b/include/SDL_blendmode.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_clipboard.h b/include/SDL_clipboard.h index bd4b044..2b31245 100644 --- a/include/SDL_clipboard.h +++ b/include/SDL_clipboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_config.h b/include/SDL_config.h index 49605b1..87ea1c0 100644 --- a/include/SDL_config.h +++ b/include/SDL_config.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_config.h.cmake b/include/SDL_config.h.cmake index e1da0c6..ef014e7 100644 --- a/include/SDL_config.h.cmake +++ b/include/SDL_config.h.cmake @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -190,6 +190,8 @@ #cmakedefine HAVE_FOPEN64 1 #cmakedefine HAVE_FSEEKO 1 #cmakedefine HAVE_FSEEKO64 1 +#cmakedefine HAVE_MEMFD_CREATE 1 +#cmakedefine HAVE_POSIX_FALLOCATE 1 #cmakedefine HAVE_SIGACTION 1 #cmakedefine HAVE_SA_SIGACTION 1 #cmakedefine HAVE_SETJMP 1 diff --git a/include/SDL_config.h.in b/include/SDL_config.h.in index 35b849d..0d9fa14 100644 --- a/include/SDL_config.h.in +++ b/include/SDL_config.h.in @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -211,6 +211,8 @@ #undef HAVE_GETAUXVAL #undef HAVE_ELF_AUX_INFO #undef HAVE_POLL +#undef HAVE_MEMFD_CREATE +#undef HAVE_POSIX_FALLOCATE #undef HAVE__EXIT #else diff --git a/include/SDL_config_android.h b/include/SDL_config_android.h index 00ffef8..0609995 100644 --- a/include/SDL_config_android.h +++ b/include/SDL_config_android.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_config_emscripten.h b/include/SDL_config_emscripten.h index 637cdae..3f06490 100644 --- a/include/SDL_config_emscripten.h +++ b/include/SDL_config_emscripten.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_config_iphoneos.h b/include/SDL_config_iphoneos.h index 2743901..fed314e 100644 --- a/include/SDL_config_iphoneos.h +++ b/include/SDL_config_iphoneos.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_config_macosx.h b/include/SDL_config_macosx.h index 2db760a..e9e6b6d 100644 --- a/include/SDL_config_macosx.h +++ b/include/SDL_config_macosx.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_config_minimal.h b/include/SDL_config_minimal.h index ceedda2..5695871 100644 --- a/include/SDL_config_minimal.h +++ b/include/SDL_config_minimal.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_config_ngage.h b/include/SDL_config_ngage.h index 61c26c2..b6042cd 100644 --- a/include/SDL_config_ngage.h +++ b/include/SDL_config_ngage.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_config_os2.h b/include/SDL_config_os2.h index 9be6b2d..22fafb1 100644 --- a/include/SDL_config_os2.h +++ b/include/SDL_config_os2.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -114,9 +114,6 @@ #define HAVE_MEMCPY 1 #define HAVE_MEMMOVE 1 #define HAVE_MEMCMP 1 -#define HAVE_WCSLEN 1 -#define HAVE_WCSLCPY 1 -#define HAVE_WCSLCAT 1 #define HAVE_WCSCMP 1 #define HAVE__WCSICMP 1 #define HAVE__WCSNICMP 1 diff --git a/include/SDL_config_pandora.h b/include/SDL_config_pandora.h index 27b858d..96375c1 100644 --- a/include/SDL_config_pandora.h +++ b/include/SDL_config_pandora.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_config_windows.h b/include/SDL_config_windows.h index dba7808..77d2d74 100644 --- a/include/SDL_config_windows.h +++ b/include/SDL_config_windows.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -99,9 +99,11 @@ typedef unsigned int uintptr_t; #define HAVE_D3D11_H 1 #define HAVE_ROAPI_H 1 #endif -#if defined(WDK_NTDDI_VERSION) && WDK_NTDDI_VERSION > 0x0A000008 /* 10.0.19041.0 */ +#if defined(__has_include) +#if __has_include() && __has_include() #define HAVE_D3D12_H 1 #endif +#endif #if defined(_WIN32_MAXVER) && _WIN32_MAXVER >= 0x0603 /* Windows 8.1 SDK */ #define HAVE_SHELLSCALINGAPI_H 1 #endif diff --git a/include/SDL_config_wingdk.h b/include/SDL_config_wingdk.h index c2a63b5..2e32927 100644 --- a/include/SDL_config_wingdk.h +++ b/include/SDL_config_wingdk.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_config_winrt.h b/include/SDL_config_winrt.h index 3a11456..8fe0b66 100644 --- a/include/SDL_config_winrt.h +++ b/include/SDL_config_winrt.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_config_xbox.h b/include/SDL_config_xbox.h index a2ea8cb..a06f52e 100644 --- a/include/SDL_config_xbox.h +++ b/include/SDL_config_xbox.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_copying.h b/include/SDL_copying.h index da90893..bde7431 100644 --- a/include/SDL_copying.h +++ b/include/SDL_copying.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_cpuinfo.h b/include/SDL_cpuinfo.h index 2a9dd38..58021b0 100644 --- a/include/SDL_cpuinfo.h +++ b/include/SDL_cpuinfo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -53,9 +53,11 @@ _m_prefetch(void *__P) #ifndef __MMX__ #define __MMX__ #endif +/* #ifndef __3dNOW__ #define __3dNOW__ #endif +*/ #endif #ifndef __SSE__ #define __SSE__ diff --git a/include/SDL_egl.h b/include/SDL_egl.h index a4276e6..60b1606 100644 --- a/include/SDL_egl.h +++ b/include/SDL_egl.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_endian.h b/include/SDL_endian.h index 591ccac..942248c 100644 --- a/include/SDL_endian.h +++ b/include/SDL_endian.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_error.h b/include/SDL_error.h index 2df6463..16dfd88 100644 --- a/include/SDL_error.h +++ b/include/SDL_error.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_events.h b/include/SDL_events.h index eccbba2..a39f1df 100644 --- a/include/SDL_events.h +++ b/include/SDL_events.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_filesystem.h b/include/SDL_filesystem.h index 0749889..8873995 100644 --- a/include/SDL_filesystem.h +++ b/include/SDL_filesystem.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_gamecontroller.h b/include/SDL_gamecontroller.h index 281fa35..fa23a51 100644 --- a/include/SDL_gamecontroller.h +++ b/include/SDL_gamecontroller.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_gesture.h b/include/SDL_gesture.h index 4fffa5f..81ec380 100644 --- a/include/SDL_gesture.h +++ b/include/SDL_gesture.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_guid.h b/include/SDL_guid.h index 7daa5f1..25e1732 100644 --- a/include/SDL_guid.h +++ b/include/SDL_guid.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_haptic.h b/include/SDL_haptic.h index c9ed847..270940f 100644 --- a/include/SDL_haptic.h +++ b/include/SDL_haptic.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_hidapi.h b/include/SDL_hidapi.h index b9d8ffa..c51cc91 100644 --- a/include/SDL_hidapi.h +++ b/include/SDL_hidapi.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_hints.h b/include/SDL_hints.h index e775a65..febb249 100644 --- a/include/SDL_hints.h +++ b/include/SDL_hints.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -1424,7 +1424,19 @@ extern "C" { #define SDL_HINT_MOUSE_RELATIVE_WARP_MOTION "SDL_MOUSE_RELATIVE_WARP_MOTION" /** - * \brief A variable controlling whether mouse events should generate synthetic touch events + * \brief A variable controlling whether the hardware cursor stays visible when relative mode is active. + * + * This variable can be set to the following values: + * "0" - The cursor will be hidden while relative mode is active (default) + * "1" - The cursor will remain visible while relative mode is active + * + * Note that for systems without raw hardware inputs, relative mode is implemented using warping, so the hardware cursor will visibly warp between frames if this is enabled on those systems. + */ +#define SDL_HINT_MOUSE_RELATIVE_CURSOR_VISIBLE "SDL_MOUSE_RELATIVE_CURSOR_VISIBLE" + +/** + * A variable controlling whether mouse events should generate synthetic touch + * events * * This variable can be set to the following values: * "0" - Mouse events will not generate touch events (default for desktop platforms) @@ -1900,6 +1912,7 @@ extern "C" { * Since it's driver-specific, it's only supported where possible and * implemented. Currently supported the following drivers: * + * - Wayland (wayland) * - KMSDRM (kmsdrm) * - Raspberry Pi (raspberrypi) */ diff --git a/include/SDL_joystick.h b/include/SDL_joystick.h index 561e010..3907d6e 100644 --- a/include/SDL_joystick.h +++ b/include/SDL_joystick.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -790,12 +790,17 @@ extern DECLSPEC void SDLCALL SDL_JoystickUpdate(void); * **WARNING**: Calling this function may delete all events currently in SDL's * event queue. * - * \param state can be one of `SDL_QUERY`, `SDL_IGNORE`, or `SDL_ENABLE` - * \returns 1 if enabled, 0 if disabled, or a negative error code on failure; - * call SDL_GetError() for more information. + * While `param` is meant to be one of `SDL_QUERY`, `SDL_IGNORE`, or + * `SDL_ENABLE`, this function accepts any value, with any non-zero value that + * isn't `SDL_QUERY` being treated as `SDL_ENABLE`. * - * If `state` is `SDL_QUERY` then the current state is returned, - * otherwise the new processing state is returned. + * If SDL was built with events disabled (extremely uncommon!), this will + * do nothing and always return `SDL_IGNORE`. + * + * \param state can be one of `SDL_QUERY`, `SDL_IGNORE`, or `SDL_ENABLE` + * \returns If `state` is `SDL_QUERY` then the current state is returned, + * otherwise `state` is returned (even if it was not one of the + * allowed values). * * \since This function is available since SDL 2.0.0. * diff --git a/include/SDL_keyboard.h b/include/SDL_keyboard.h index 03c7b5a..c6cdec9 100644 --- a/include/SDL_keyboard.h +++ b/include/SDL_keyboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_keycode.h b/include/SDL_keycode.h index 57a71bd..8ee0301 100644 --- a/include/SDL_keycode.h +++ b/include/SDL_keycode.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_loadso.h b/include/SDL_loadso.h index 4edc22e..20d22ed 100644 --- a/include/SDL_loadso.h +++ b/include/SDL_loadso.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_locale.h b/include/SDL_locale.h index 0b6118f..27a7110 100644 --- a/include/SDL_locale.h +++ b/include/SDL_locale.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_log.h b/include/SDL_log.h index bd030c6..46e3af8 100644 --- a/include/SDL_log.h +++ b/include/SDL_log.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_main.h b/include/SDL_main.h index a66c84b..8f27c02 100644 --- a/include/SDL_main.h +++ b/include/SDL_main.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_messagebox.h b/include/SDL_messagebox.h index 5ace6f2..1a4bff3 100644 --- a/include/SDL_messagebox.h +++ b/include/SDL_messagebox.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_metal.h b/include/SDL_metal.h index 50f7b2a..b02a294 100644 --- a/include/SDL_metal.h +++ b/include/SDL_metal.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_misc.h b/include/SDL_misc.h index 113ba7a..ab11a99 100644 --- a/include/SDL_misc.h +++ b/include/SDL_misc.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_mouse.h b/include/SDL_mouse.h index 687ff12..36e2d2d 100644 --- a/include/SDL_mouse.h +++ b/include/SDL_mouse.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_mutex.h b/include/SDL_mutex.h index eaa21f2..2a6d716 100644 --- a/include/SDL_mutex.h +++ b/include/SDL_mutex.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_name.h b/include/SDL_name.h index 71e9354..0c48bcf 100644 --- a/include/SDL_name.h +++ b/include/SDL_name.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_opengl.h b/include/SDL_opengl.h index 2bb38c5..ffcff60 100644 --- a/include/SDL_opengl.h +++ b/include/SDL_opengl.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_opengles.h b/include/SDL_opengles.h index 7e9a1ab..b9ab4bb 100644 --- a/include/SDL_opengles.h +++ b/include/SDL_opengles.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_opengles2.h b/include/SDL_opengles2.h index 9697134..c450901 100644 --- a/include/SDL_opengles2.h +++ b/include/SDL_opengles2.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_pixels.h b/include/SDL_pixels.h index 44757cd..cea1c1b 100644 --- a/include/SDL_pixels.h +++ b/include/SDL_pixels.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_platform.h b/include/SDL_platform.h index 6e67b45..a2bcb42 100644 --- a/include/SDL_platform.h +++ b/include/SDL_platform.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -73,7 +73,13 @@ #if defined(__APPLE__) /* lets us know what version of Mac OS X we're compiling on */ #include +#ifndef __has_extension /* Older compilers don't support this */ +#define __has_extension(x) 0 #include +#undef __has_extension +#else +#include +#endif /* Fix building with older SDKs that don't define these See this for more information: @@ -199,8 +205,10 @@ #undef __GDK__ #define __GDK__ 1 #endif -#if defined(__PSP__) +#if defined(__PSP__) || defined(__psp__) +#ifdef __PSP__ #undef __PSP__ +#endif #define __PSP__ 1 #endif #if defined(PS2) diff --git a/include/SDL_power.h b/include/SDL_power.h index 0520065..ce33d66 100644 --- a/include/SDL_power.h +++ b/include/SDL_power.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_quit.h b/include/SDL_quit.h index 3f69dc9..d396546 100644 --- a/include/SDL_quit.h +++ b/include/SDL_quit.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_rect.h b/include/SDL_rect.h index 5ce1f0b..273b8c1 100644 --- a/include/SDL_rect.h +++ b/include/SDL_rect.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_render.h b/include/SDL_render.h index b7135bb..d7722c4 100644 --- a/include/SDL_render.h +++ b/include/SDL_render.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_revision.h b/include/SDL_revision.h index ee42f84..36691f5 100644 --- a/include/SDL_revision.h +++ b/include/SDL_revision.h @@ -1,7 +1,6 @@ -/* Generated by updaterev.sh, do not edit */ #ifdef SDL_VENDOR_INFO -#define SDL_REVISION "SDL-release-2.30.0-0-g859844eae (" SDL_VENDOR_INFO ")" +#define SDL_REVISION SDL_VENDOR_INFO #else -#define SDL_REVISION "SDL-release-2.30.0-0-g859844eae" +#define SDL_REVISION "" #endif #define SDL_REVISION_NUMBER 0 diff --git a/include/SDL_rwops.h b/include/SDL_rwops.h index 9dd99f9..28065bd 100644 --- a/include/SDL_rwops.h +++ b/include/SDL_rwops.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_scancode.h b/include/SDL_scancode.h index fe13d5b..3f15c3a 100644 --- a/include/SDL_scancode.h +++ b/include/SDL_scancode.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_sensor.h b/include/SDL_sensor.h index 8b89ef6..17b8c7a 100644 --- a/include/SDL_sensor.h +++ b/include/SDL_sensor.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_shape.h b/include/SDL_shape.h index 4783cf2..4d3f7bf 100644 --- a/include/SDL_shape.h +++ b/include/SDL_shape.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_stdinc.h b/include/SDL_stdinc.h index 0035a35..430202a 100644 --- a/include/SDL_stdinc.h +++ b/include/SDL_stdinc.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -107,7 +107,7 @@ # elif defined(__MRC__) void *alloca(unsigned); # else -char *alloca(); +void *alloca(size_t); # endif #endif @@ -253,21 +253,21 @@ typedef uint64_t Uint64; * should define these but this is not true all platforms. * (for example win32) */ #ifndef SDL_PRIs64 -#ifdef PRIs64 -#define SDL_PRIs64 PRIs64 -#elif defined(__WIN32__) || defined(__GDK__) +#if defined(__WIN32__) || defined(__GDK__) #define SDL_PRIs64 "I64d" -#elif defined(__LP64__) && !defined(__APPLE__) +#elif defined(PRId64) +#define SDL_PRIs64 PRId64 +#elif defined(__LP64__) && !defined(__APPLE__) && !defined(__EMSCRIPTEN__) #define SDL_PRIs64 "ld" #else #define SDL_PRIs64 "lld" #endif #endif #ifndef SDL_PRIu64 -#ifdef PRIu64 -#define SDL_PRIu64 PRIu64 -#elif defined(__WIN32__) || defined(__GDK__) +#if defined(__WIN32__) || defined(__GDK__) #define SDL_PRIu64 "I64u" +#elif defined(PRIu64) +#define SDL_PRIu64 PRIu64 #elif defined(__LP64__) && !defined(__APPLE__) #define SDL_PRIu64 "lu" #else @@ -275,10 +275,10 @@ typedef uint64_t Uint64; #endif #endif #ifndef SDL_PRIx64 -#ifdef PRIx64 -#define SDL_PRIx64 PRIx64 -#elif defined(__WIN32__) || defined(__GDK__) +#if defined(__WIN32__) || defined(__GDK__) #define SDL_PRIx64 "I64x" +#elif defined(PRIx64) +#define SDL_PRIx64 PRIx64 #elif defined(__LP64__) && !defined(__APPLE__) #define SDL_PRIx64 "lx" #else @@ -286,10 +286,10 @@ typedef uint64_t Uint64; #endif #endif #ifndef SDL_PRIX64 -#ifdef PRIX64 -#define SDL_PRIX64 PRIX64 -#elif defined(__WIN32__) || defined(__GDK__) +#if defined(__WIN32__) || defined(__GDK__) #define SDL_PRIX64 "I64X" +#elif defined(PRIX64) +#define SDL_PRIX64 PRIX64 #elif defined(__LP64__) && !defined(__APPLE__) #define SDL_PRIX64 "lX" #else @@ -377,9 +377,12 @@ typedef uint64_t Uint64; #ifndef SDL_COMPILE_TIME_ASSERT #if defined(__cplusplus) +/* Keep C++ case alone: Some versions of gcc will define __STDC_VERSION__ even when compiling in C++ mode. */ #if (__cplusplus >= 201103L) #define SDL_COMPILE_TIME_ASSERT(name, x) static_assert(x, #x) #endif +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 202311L) +#define SDL_COMPILE_TIME_ASSERT(name, x) static_assert(x, #x) #elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) #define SDL_COMPILE_TIME_ASSERT(name, x) _Static_assert(x, #x) #endif diff --git a/include/SDL_surface.h b/include/SDL_surface.h index ceeb86b..ddb5b73 100644 --- a/include/SDL_surface.h +++ b/include/SDL_surface.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_system.h b/include/SDL_system.h index ddae4f8..01d5c6c 100644 --- a/include/SDL_system.h +++ b/include/SDL_system.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_syswm.h b/include/SDL_syswm.h index 7b8bd6e..7acf43d 100644 --- a/include/SDL_syswm.h +++ b/include/SDL_syswm.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_test.h b/include/SDL_test.h index e5acbee..630c904 100644 --- a/include/SDL_test.h +++ b/include/SDL_test.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_test_assert.h b/include/SDL_test_assert.h index 4f98335..9408b4f 100644 --- a/include/SDL_test_assert.h +++ b/include/SDL_test_assert.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_test_common.h b/include/SDL_test_common.h index d977e46..8e7622d 100644 --- a/include/SDL_test_common.h +++ b/include/SDL_test_common.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_test_compare.h b/include/SDL_test_compare.h index 61a38d0..a116634 100644 --- a/include/SDL_test_compare.h +++ b/include/SDL_test_compare.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_test_crc32.h b/include/SDL_test_crc32.h index e347831..32a4740 100644 --- a/include/SDL_test_crc32.h +++ b/include/SDL_test_crc32.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_test_font.h b/include/SDL_test_font.h index 620c821..ec41b46 100644 --- a/include/SDL_test_font.h +++ b/include/SDL_test_font.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_test_fuzzer.h b/include/SDL_test_fuzzer.h index a847ccb..351ab99 100644 --- a/include/SDL_test_fuzzer.h +++ b/include/SDL_test_fuzzer.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_test_harness.h b/include/SDL_test_harness.h index bd9e4f8..02bbb70 100644 --- a/include/SDL_test_harness.h +++ b/include/SDL_test_harness.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_test_images.h b/include/SDL_test_images.h index b5bcb0a..4229d26 100644 --- a/include/SDL_test_images.h +++ b/include/SDL_test_images.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_test_log.h b/include/SDL_test_log.h index ea9ae5e..04e03e6 100644 --- a/include/SDL_test_log.h +++ b/include/SDL_test_log.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_test_md5.h b/include/SDL_test_md5.h index 3764b04..5770603 100644 --- a/include/SDL_test_md5.h +++ b/include/SDL_test_md5.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_test_memory.h b/include/SDL_test_memory.h index 9bd1432..128c1ab 100644 --- a/include/SDL_test_memory.h +++ b/include/SDL_test_memory.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_test_random.h b/include/SDL_test_random.h index 344646a..e846857 100644 --- a/include/SDL_test_random.h +++ b/include/SDL_test_random.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_thread.h b/include/SDL_thread.h index dc7f536..d6ae47d 100644 --- a/include/SDL_thread.h +++ b/include/SDL_thread.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_timer.h b/include/SDL_timer.h index 8123e43..e187a79 100644 --- a/include/SDL_timer.h +++ b/include/SDL_timer.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_touch.h b/include/SDL_touch.h index f6a5db4..a4633c8 100644 --- a/include/SDL_touch.h +++ b/include/SDL_touch.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_types.h b/include/SDL_types.h index e8d33c6..12b5f75 100644 --- a/include/SDL_types.h +++ b/include/SDL_types.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_version.h b/include/SDL_version.h index 02143ff..a508776 100644 --- a/include/SDL_version.h +++ b/include/SDL_version.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -59,7 +59,7 @@ typedef struct SDL_version */ #define SDL_MAJOR_VERSION 2 #define SDL_MINOR_VERSION 30 -#define SDL_PATCHLEVEL 0 +#define SDL_PATCHLEVEL 11 /** * Macro to determine SDL version program was compiled against. diff --git a/include/SDL_video.h b/include/SDL_video.h index fa47d30..4b69a99 100644 --- a/include/SDL_video.h +++ b/include/SDL_video.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/SDL_vulkan.h b/include/SDL_vulkan.h index ab86a0b..a506ef4 100644 --- a/include/SDL_vulkan.h +++ b/include/SDL_vulkan.h @@ -52,6 +52,10 @@ extern "C" { VK_DEFINE_HANDLE(VkInstance) VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR) +/* Make sure to undef to avoid issues in case of later vulkan include */ +#undef VK_DEFINE_HANDLE +#undef VK_DEFINE_NON_DISPATCHABLE_HANDLE + #endif /* !NO_SDL_VULKAN_TYPEDEFS */ typedef VkInstance SDL_vulkanInstance; diff --git a/include/begin_code.h b/include/begin_code.h index a47a7d2..6ab655c 100644 --- a/include/begin_code.h +++ b/include/begin_code.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/include/close_code.h b/include/close_code.h index 50a0e6f..f991f45 100644 --- a/include/close_code.h +++ b/include/close_code.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/mingw/pkg-support/INSTALL.txt b/mingw/pkg-support/INSTALL.txt new file mode 100644 index 0000000..607dafd --- /dev/null +++ b/mingw/pkg-support/INSTALL.txt @@ -0,0 +1,18 @@ + +The 32-bit files are in i686-w64-mingw32 +The 64-bit files are in x86_64-w64-mingw32 + +To install SDL for native development: + make native + +To install SDL for cross-compiling development: + make cross + +Look at the example programs in ./test, and check out online documentation: + http://wiki.libsdl.org/ + +Join the SDL developer mailing list if you want to join the community: + http://www.libsdl.org/mailing-list.php + +That's it! +Sam Lantinga diff --git a/mingw/pkg-support/Makefile b/mingw/pkg-support/Makefile new file mode 100644 index 0000000..ae85b3e --- /dev/null +++ b/mingw/pkg-support/Makefile @@ -0,0 +1,37 @@ +# +# Makefile for installing the mingw32 version of the SDL library + +CROSS_PATH := /usr/local +ARCHITECTURES := i686-w64-mingw32 x86_64-w64-mingw32 + +all install: + @echo "Type \"make native\" to install 32-bit to /usr" + @echo "Type \"make cross\" to install 32-bit and 64-bit to $(CROSS_PATH)" + +native: + make install-package arch=i686-w64-mingw32 prefix=/usr + +cross: + mkdir -p $(CROSS_PATH)/cmake + cp -rv cmake/* $(CROSS_PATH)/cmake + for arch in $(ARCHITECTURES); do \ + mkdir -p $(CROSS_PATH)/$$arch; \ + make install-package arch=$$arch prefix=$(CROSS_PATH)/$$arch; \ + done + +install-package: + @if test -d $(arch) && test -d $(prefix); then \ + (cd $(arch) && cp -rv bin include lib share $(prefix)/); \ + sed "s|^prefix=.*|prefix=$(prefix)|" <$(arch)/bin/sdl2-config >$(prefix)/bin/sdl2-config; \ + chmod 755 $(prefix)/bin/sdl2-config; \ + sed "s|^libdir=.*|libdir=\'$(prefix)/lib\'|" <$(arch)/lib/libSDL2.la >$(prefix)/lib/libSDL2.la; \ + sed -e "s|^set[(]bindir \".*|set(bindir \"$(prefix)/bin\")|" \ + -e "s|^set[(]includedir \".*|set(includedir \"$(prefix)/include\")|" \ + -e "s|^set[(]libdir \".*|set(libdir \"$(prefix)/lib\")|" <$(arch)/lib/cmake/SDL2/sdl2-config.cmake >$(prefix)/lib/cmake/SDL2/sdl2-config.cmake; \ + sed -e "s|^prefix=.*|prefix=$(prefix)|" \ + -e "s|^includedir=.*|includedir=$(prefix)/include|" \ + -e "s|^libdir=.*|prefix=$(prefix)/lib|" <$(arch)/lib/pkgconfig/sdl2.pc >$(prefix)/lib/pkgconfig/sdl2.pc; \ + else \ + echo "*** ERROR: $(arch) or $(prefix) does not exist!"; \ + exit 1; \ + fi diff --git a/src/SDL.c b/src/SDL.c index 7065fe7..e21b500 100644 --- a/src/SDL.c +++ b/src/SDL.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -29,9 +29,6 @@ #endif #if defined(__OS2__) #include "core/os2/SDL_os2.h" -#ifdef SDL_THREAD_OS2 -#include "thread/os2/SDL_systls_c.h" -#endif #endif /* this checks for HAVE_DBUS_DBUS_H internally. */ @@ -52,6 +49,7 @@ #include "haptic/SDL_haptic_c.h" #include "joystick/SDL_joystick_c.h" #include "sensor/SDL_sensor_c.h" +#include "thread/SDL_thread_c.h" /* Initialization/Cleanup routines */ #ifndef SDL_TIMERS_DISABLED @@ -116,6 +114,7 @@ static SDL_bool SDL_MainIsReady = SDL_FALSE; #else static SDL_bool SDL_MainIsReady = SDL_TRUE; #endif +static SDL_bool SDL_main_thread_initialized = SDL_FALSE; static SDL_bool SDL_bInMainQuit = SDL_FALSE; static Uint8 SDL_SubsystemRefCount[32]; @@ -181,6 +180,36 @@ void SDL_SetMainReady(void) SDL_MainIsReady = SDL_TRUE; } +void SDL_InitMainThread(void) +{ + if (SDL_main_thread_initialized) { + return; + } + + SDL_InitTLSData(); +#ifndef SDL_TIMERS_DISABLED + SDL_TicksInit(); +#endif + SDL_LogInit(); + + SDL_main_thread_initialized = SDL_TRUE; +} + +static void SDL_QuitMainThread(void) +{ + if (!SDL_main_thread_initialized) { + return; + } + + SDL_LogQuit(); +#ifndef SDL_TIMERS_DISABLED + SDL_TicksQuit(); +#endif + SDL_QuitTLSData(); + + SDL_main_thread_initialized = SDL_FALSE; +} + int SDL_InitSubSystem(Uint32 flags) { Uint32 flags_initialized = 0; @@ -189,8 +218,6 @@ int SDL_InitSubSystem(Uint32 flags) return SDL_SetError("Application didn't initialize properly, did you include SDL_main.h in the file containing your main() function?"); } - SDL_LogInit(); - /* Clear the error message */ SDL_ClearError(); @@ -198,10 +225,6 @@ int SDL_InitSubSystem(Uint32 flags) SDL_DBus_Init(); #endif -#ifdef SDL_THREAD_OS2 - SDL_OS2TLSAlloc(); /* thread/os2/SDL_systls.c */ -#endif - #ifdef SDL_VIDEO_DRIVER_WINDOWS if (flags & (SDL_INIT_HAPTIC | SDL_INIT_JOYSTICK)) { if (SDL_HelperWindowCreate() < 0) { @@ -210,10 +233,6 @@ int SDL_InitSubSystem(Uint32 flags) } #endif -#ifndef SDL_TIMERS_DISABLED - SDL_TicksInit(); -#endif - /* Initialize the event subsystem */ if (flags & SDL_INIT_EVENTS) { #ifndef SDL_EVENTS_DISABLED @@ -378,9 +397,6 @@ int SDL_Init(Uint32 flags) void SDL_QuitSubSystem(Uint32 flags) { #if defined(__OS2__) -#ifdef SDL_THREAD_OS2 - SDL_OS2TLSFree(); /* thread/os2/SDL_systls.c */ -#endif SDL_OS2Quit(); #endif @@ -504,10 +520,6 @@ void SDL_Quit(void) #endif SDL_QuitSubSystem(SDL_INIT_EVERYTHING); -#ifndef SDL_TIMERS_DISABLED - SDL_TicksQuit(); -#endif - #ifdef SDL_USE_LIBDBUS SDL_DBus_Quit(); #endif @@ -515,14 +527,12 @@ void SDL_Quit(void) SDL_ClearHints(); SDL_AssertionsQuit(); - SDL_LogQuit(); - /* Now that every subsystem has been quit, we reset the subsystem refcount * and the list of initialized subsystems. */ SDL_memset(SDL_SubsystemRefCount, 0x0, sizeof(SDL_SubsystemRefCount)); - SDL_TLSCleanup(); + SDL_QuitMainThread(); SDL_bInMainQuit = SDL_FALSE; } diff --git a/src/SDL_assert.c b/src/SDL_assert.c index 1ca41e7..76c7491 100644 --- a/src/SDL_assert.c +++ b/src/SDL_assert.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -292,7 +292,7 @@ static SDL_assert_state SDLCALL SDL_PromptAssertion(const SDL_assert_data *data, break; } } -#elif defined(HAVE_STDIO_H) +#elif defined(HAVE_STDIO_H) && !defined(__3DS__) /* this is a little hacky. */ for (;;) { char buf[32]; @@ -319,6 +319,8 @@ static SDL_assert_state SDLCALL SDL_PromptAssertion(const SDL_assert_data *data, break; } } +#else + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_WARNING, "Assertion Failed", message, window); #endif /* HAVE_STDIO_H */ } diff --git a/src/SDL_assert_c.h b/src/SDL_assert_c.h index 330acb8..69cd9c3 100644 --- a/src/SDL_assert_c.h +++ b/src/SDL_assert_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/SDL_dataqueue.c b/src/SDL_dataqueue.c index e32ba31..0498e12 100644 --- a/src/SDL_dataqueue.c +++ b/src/SDL_dataqueue.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/SDL_dataqueue.h b/src/SDL_dataqueue.h index 972a521..6c671ad 100644 --- a/src/SDL_dataqueue.h +++ b/src/SDL_dataqueue.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/SDL_error.c b/src/SDL_error.c index d5c45fb..db24b3b 100644 --- a/src/SDL_error.c +++ b/src/SDL_error.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/SDL_error_c.h b/src/SDL_error_c.h index 1aae3be..ae9f5df 100644 --- a/src/SDL_error_c.h +++ b/src/SDL_error_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/SDL_guid.c b/src/SDL_guid.c index 2f91edb..0e4c34b 100644 --- a/src/SDL_guid.c +++ b/src/SDL_guid.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/SDL_hints.c b/src/SDL_hints.c index ae4055d..f8e9ba4 100644 --- a/src/SDL_hints.c +++ b/src/SDL_hints.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -161,6 +161,10 @@ const char *SDL_GetHint(const char *name) const char *env; SDL_Hint *hint; + if (!name) { + return NULL; + } + env = SDL_getenv(name); for (hint = SDL_hints; hint; hint = hint->next) { if (SDL_strcmp(name, hint->name) == 0) { diff --git a/src/SDL_hints_c.h b/src/SDL_hints_c.h index 8af9fc5..097a0d9 100644 --- a/src/SDL_hints_c.h +++ b/src/SDL_hints_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/SDL_internal.h b/src/SDL_internal.h index c2f8b80..aa63914 100644 --- a/src/SDL_internal.h +++ b/src/SDL_internal.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -125,9 +125,91 @@ #define SDL_HAVE_YUV !SDL_LEAN_AND_MEAN #endif +#ifndef SDL_RENDER_DISABLED +/* define the not defined ones as 0 */ +#ifndef SDL_VIDEO_RENDER_D3D +#define SDL_VIDEO_RENDER_D3D 0 +#endif +#ifndef SDL_VIDEO_RENDER_D3D11 +#define SDL_VIDEO_RENDER_D3D11 0 +#endif +#ifndef SDL_VIDEO_RENDER_D3D12 +#define SDL_VIDEO_RENDER_D3D12 0 +#endif +#ifndef SDL_VIDEO_RENDER_METAL +#define SDL_VIDEO_RENDER_METAL 0 +#endif +#ifndef SDL_VIDEO_RENDER_OGL +#define SDL_VIDEO_RENDER_OGL 0 +#endif +#ifndef SDL_VIDEO_RENDER_OGL_ES +#define SDL_VIDEO_RENDER_OGL_ES 0 +#endif +#ifndef SDL_VIDEO_RENDER_OGL_ES2 +#define SDL_VIDEO_RENDER_OGL_ES2 0 +#endif +#ifndef SDL_VIDEO_RENDER_DIRECTFB +#define SDL_VIDEO_RENDER_DIRECTFB 0 +#endif +#ifndef SDL_VIDEO_RENDER_PS2 +#define SDL_VIDEO_RENDER_PS2 0 +#endif +#ifndef SDL_VIDEO_RENDER_PSP +#define SDL_VIDEO_RENDER_PSP 0 +#endif +#ifndef SDL_VIDEO_RENDER_VITA_GXM +#define SDL_VIDEO_RENDER_VITA_GXM 0 +#endif +#else /* define all as 0 */ +#undef SDL_VIDEO_RENDER_SW +#define SDL_VIDEO_RENDER_SW 0 +#undef SDL_VIDEO_RENDER_D3D +#define SDL_VIDEO_RENDER_D3D 0 +#undef SDL_VIDEO_RENDER_D3D11 +#define SDL_VIDEO_RENDER_D3D11 0 +#undef SDL_VIDEO_RENDER_D3D12 +#define SDL_VIDEO_RENDER_D3D12 0 +#undef SDL_VIDEO_RENDER_METAL +#define SDL_VIDEO_RENDER_METAL 0 +#undef SDL_VIDEO_RENDER_OGL +#define SDL_VIDEO_RENDER_OGL 0 +#undef SDL_VIDEO_RENDER_OGL_ES +#define SDL_VIDEO_RENDER_OGL_ES 0 +#undef SDL_VIDEO_RENDER_OGL_ES2 +#define SDL_VIDEO_RENDER_OGL_ES2 0 +#undef SDL_VIDEO_RENDER_DIRECTFB +#define SDL_VIDEO_RENDER_DIRECTFB 0 +#undef SDL_VIDEO_RENDER_PS2 +#define SDL_VIDEO_RENDER_PS2 0 +#undef SDL_VIDEO_RENDER_PSP +#define SDL_VIDEO_RENDER_PSP 0 +#undef SDL_VIDEO_RENDER_VITA_GXM +#define SDL_VIDEO_RENDER_VITA_GXM 0 +#endif /* SDL_RENDER_DISABLED */ + +#define SDL_HAS_RENDER_DRIVER \ + (SDL_VIDEO_RENDER_SW | \ + SDL_VIDEO_RENDER_D3D | \ + SDL_VIDEO_RENDER_D3D11 | \ + SDL_VIDEO_RENDER_D3D12 | \ + SDL_VIDEO_RENDER_METAL | \ + SDL_VIDEO_RENDER_OGL | \ + SDL_VIDEO_RENDER_OGL_ES | \ + SDL_VIDEO_RENDER_OGL_ES2 | \ + SDL_VIDEO_RENDER_DIRECTFB | \ + SDL_VIDEO_RENDER_PS2 | \ + SDL_VIDEO_RENDER_PSP | \ + SDL_VIDEO_RENDER_VITA_GXM) + +#if !defined(SDL_RENDER_DISABLED) && !SDL_HAS_RENDER_DRIVER +#error SDL_RENDER enabled without any backend drivers. +#endif + #include "SDL_assert.h" #include "SDL_log.h" +extern void SDL_InitMainThread(void); + #endif /* SDL_internal_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/SDL_list.c b/src/SDL_list.c index b7f45de..8873002 100644 --- a/src/SDL_list.c +++ b/src/SDL_list.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/SDL_list.h b/src/SDL_list.h index f855e9b..16079b8 100644 --- a/src/SDL_list.h +++ b/src/SDL_list.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/SDL_log.c b/src/SDL_log.c index 9e324e3..47f5b72 100644 --- a/src/SDL_log.c +++ b/src/SDL_log.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/SDL_log_c.h b/src/SDL_log_c.h index 4d6676d..7fdd514 100644 --- a/src/SDL_log_c.h +++ b/src/SDL_log_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/SDL_utils.c b/src/SDL_utils.c index 10a3083..f4ebcf9 100644 --- a/src/SDL_utils.c +++ b/src/SDL_utils.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/SDL_utils_c.h b/src/SDL_utils_c.h index 4c00d8b..eb870c7 100644 --- a/src/SDL_utils_c.h +++ b/src/SDL_utils_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/atomic/SDL_atomic.c b/src/atomic/SDL_atomic.c index e843c8d..755ae57 100644 --- a/src/atomic/SDL_atomic.c +++ b/src/atomic/SDL_atomic.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/atomic/SDL_spinlock.c b/src/atomic/SDL_spinlock.c index a2d1d3f..bdfa082 100644 --- a/src/atomic/SDL_spinlock.c +++ b/src/atomic/SDL_spinlock.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c index 96586fe..1ab847a 100644 --- a/src/audio/SDL_audio.c +++ b/src/audio/SDL_audio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -93,12 +93,12 @@ static const AudioBootStrap *const bootstrap[] = { #ifdef SDL_AUDIO_DRIVER_FUSIONSOUND &FUSIONSOUND_bootstrap, #endif -#ifdef SDL_AUDIO_DRIVER_AAUDIO - &aaudio_bootstrap, -#endif #ifdef SDL_AUDIO_DRIVER_OPENSLES &openslES_bootstrap, #endif +#ifdef SDL_AUDIO_DRIVER_AAUDIO + &aaudio_bootstrap, +#endif #ifdef SDL_AUDIO_DRIVER_ANDROID &ANDROIDAUDIO_bootstrap, #endif @@ -700,8 +700,6 @@ static int SDLCALL SDL_RunAudio(void *userdata) /* Loop, filling the audio buffers */ while (!SDL_AtomicGet(&device->shutdown)) { - data_len = device->callbackspec.size; - /* Fill the current buffer with sound */ if (!device->stream && SDL_AtomicGet(&device->enabled)) { data = current_audio.impl.GetDeviceBuf(device); @@ -728,6 +726,8 @@ static int SDLCALL SDL_RunAudio(void *userdata) data = device->work_buffer; } + data_len = device->callbackspec.size; + /* !!! FIXME: this should be LockDevice. */ SDL_LockMutex(device->mixer_lock); if (SDL_AtomicGet(&device->paused)) { diff --git a/src/audio/SDL_audio_c.h b/src/audio/SDL_audio_c.h index 5bc2b41..49019e1 100644 --- a/src/audio/SDL_audio_c.h +++ b/src/audio/SDL_audio_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/SDL_audio_channel_converters.h b/src/audio/SDL_audio_channel_converters.h index 95e22b1..1e6fd6e 100644 --- a/src/audio/SDL_audio_channel_converters.h +++ b/src/audio/SDL_audio_channel_converters.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/SDL_audio_resampler_filter.h b/src/audio/SDL_audio_resampler_filter.h index a6dff39..be728ea 100644 --- a/src/audio/SDL_audio_resampler_filter.h +++ b/src/audio/SDL_audio_resampler_filter.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/SDL_audiocvt.c b/src/audio/SDL_audiocvt.c index 9087317..348ce6b 100644 --- a/src/audio/SDL_audiocvt.c +++ b/src/audio/SDL_audiocvt.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/SDL_audiodev.c b/src/audio/SDL_audiodev.c index 903ba9e..3ecaa05 100644 --- a/src/audio/SDL_audiodev.c +++ b/src/audio/SDL_audiodev.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/SDL_audiodev_c.h b/src/audio/SDL_audiodev_c.h index 1235ea4..7aefc0d 100644 --- a/src/audio/SDL_audiodev_c.h +++ b/src/audio/SDL_audiodev_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/SDL_audiotypecvt.c b/src/audio/SDL_audiotypecvt.c index 53c8ffe..516be82 100644 --- a/src/audio/SDL_audiotypecvt.c +++ b/src/audio/SDL_audiotypecvt.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -125,7 +125,7 @@ static void SDLCALL SDL_Convert_U8_to_F32_Scalar(SDL_AudioCVT *cvt, SDL_AudioFor static void SDLCALL SDL_Convert_S16_to_F32_Scalar(SDL_AudioCVT *cvt, SDL_AudioFormat format) { - const int num_samples = cvt->len_cvt; + const int num_samples = cvt->len_cvt / sizeof(Sint16); const Sint16 *src = (const Sint16 *)cvt->buf; float *dst = (float *)cvt->buf; int i; @@ -350,7 +350,7 @@ static void SDLCALL SDL_Convert_S8_to_F32_SSE2(SDL_AudioCVT *cvt, SDL_AudioForma i -= 16; { - const __m128i bytes = _mm_xor_si128(_mm_loadu_si128((const __m128i *)&src[i-16]), flipper); + const __m128i bytes = _mm_xor_si128(_mm_loadu_si128((const __m128i *)&src[i]), flipper); const __m128i shorts1 = _mm_unpacklo_epi8(bytes, zero); const __m128i shorts2 = _mm_unpackhi_epi8(bytes, zero); diff --git a/src/audio/SDL_mixer.c b/src/audio/SDL_mixer.c index 9cf96a6..bb42fe7 100644 --- a/src/audio/SDL_mixer.c +++ b/src/audio/SDL_mixer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/SDL_sysaudio.h b/src/audio/SDL_sysaudio.h index d569ba7..6e8de52 100644 --- a/src/audio/SDL_sysaudio.h +++ b/src/audio/SDL_sysaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/SDL_wave.c b/src/audio/SDL_wave.c index 1ecce9b..e71235e 100644 --- a/src/audio/SDL_wave.c +++ b/src/audio/SDL_wave.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/SDL_wave.h b/src/audio/SDL_wave.h index 6d71e47..b0e0e68 100644 --- a/src/audio/SDL_wave.h +++ b/src/audio/SDL_wave.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/aaudio/SDL_aaudio.c b/src/audio/aaudio/SDL_aaudio.c index 401fef6..93bcaf3 100644 --- a/src/audio/aaudio/SDL_aaudio.c +++ b/src/audio/aaudio/SDL_aaudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -116,7 +116,6 @@ static int aaudio_OpenDevice(_THIS, const char *devname) } ctx.AAudioStreamBuilder_setErrorCallback(ctx.builder, aaudio_errorCallback, private); - ctx.AAudioStreamBuilder_setPerformanceMode(ctx.builder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY); LOGI("AAudio Try to open %u hz %u bit chan %u %s samples %u", this->spec.freq, SDL_AUDIO_BITSIZE(this->spec.format), @@ -239,7 +238,6 @@ static int RebuildAAudioStream(SDL_AudioDevice *device) } ctx.AAudioStreamBuilder_setErrorCallback(ctx.builder, aaudio_errorCallback, hidden); - ctx.AAudioStreamBuilder_setPerformanceMode(ctx.builder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY); LOGI("AAudio Try to reopen %u hz %u bit chan %u %s samples %u", device->spec.freq, SDL_AUDIO_BITSIZE(device->spec.format), diff --git a/src/audio/aaudio/SDL_aaudio.h b/src/audio/aaudio/SDL_aaudio.h index d61d1b0..b988a5c 100644 --- a/src/audio/aaudio/SDL_aaudio.h +++ b/src/audio/aaudio/SDL_aaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/aaudio/SDL_aaudiofuncs.h b/src/audio/aaudio/SDL_aaudiofuncs.h index 2bc674c..c2fff18 100644 --- a/src/audio/aaudio/SDL_aaudiofuncs.h +++ b/src/audio/aaudio/SDL_aaudiofuncs.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright , (C) 1997-2024 Sam Lantinga + Copyright , (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -32,7 +32,7 @@ SDL_PROC(void, AAudioStreamBuilder_setFormat, (AAudioStreamBuilder * builder, aa SDL_PROC_UNUSED(void, AAudioStreamBuilder_setSharingMode, (AAudioStreamBuilder * builder, aaudio_sharing_mode_t sharingMode)) SDL_PROC(void, AAudioStreamBuilder_setDirection, (AAudioStreamBuilder * builder, aaudio_direction_t direction)) SDL_PROC_UNUSED(void, AAudioStreamBuilder_setBufferCapacityInFrames, (AAudioStreamBuilder * builder, int32_t numFrames)) -SDL_PROC(void, AAudioStreamBuilder_setPerformanceMode, (AAudioStreamBuilder * builder, aaudio_performance_mode_t mode)) +SDL_PROC_UNUSED(void, AAudioStreamBuilder_setPerformanceMode, (AAudioStreamBuilder * builder, aaudio_performance_mode_t mode)) SDL_PROC_UNUSED(void, AAudioStreamBuilder_setUsage, (AAudioStreamBuilder * builder, aaudio_usage_t usage)) /* API 28 */ SDL_PROC_UNUSED(void, AAudioStreamBuilder_setContentType, (AAudioStreamBuilder * builder, aaudio_content_type_t contentType)) /* API 28 */ SDL_PROC_UNUSED(void, AAudioStreamBuilder_setInputPreset, (AAudioStreamBuilder * builder, aaudio_input_preset_t inputPreset)) /* API 28 */ diff --git a/src/audio/alsa/SDL_alsa_audio.c b/src/audio/alsa/SDL_alsa_audio.c index 3ed66f2..3e0e7ac 100644 --- a/src/audio/alsa/SDL_alsa_audio.c +++ b/src/audio/alsa/SDL_alsa_audio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/alsa/SDL_alsa_audio.h b/src/audio/alsa/SDL_alsa_audio.h index fb3f154..200e8e7 100644 --- a/src/audio/alsa/SDL_alsa_audio.h +++ b/src/audio/alsa/SDL_alsa_audio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/android/SDL_androidaudio.c b/src/audio/android/SDL_androidaudio.c index 8173686..c45e031 100644 --- a/src/audio/android/SDL_androidaudio.c +++ b/src/audio/android/SDL_androidaudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/android/SDL_androidaudio.h b/src/audio/android/SDL_androidaudio.h index 4e9df10..e9c2ef6 100644 --- a/src/audio/android/SDL_androidaudio.h +++ b/src/audio/android/SDL_androidaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/arts/SDL_artsaudio.c b/src/audio/arts/SDL_artsaudio.c index da91997..420588b 100644 --- a/src/audio/arts/SDL_artsaudio.c +++ b/src/audio/arts/SDL_artsaudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -86,7 +86,7 @@ static struct #undef SDL_ARTS_SYM -static void UnloadARTSLibrary() +static void UnloadARTSLibrary(void) { if (arts_handle) { SDL_UnloadObject(arts_handle); @@ -119,7 +119,7 @@ static int LoadARTSLibrary(void) #else -static void UnloadARTSLibrary() +static void UnloadARTSLibrary(void) { return; } diff --git a/src/audio/arts/SDL_artsaudio.h b/src/audio/arts/SDL_artsaudio.h index fe55bcd..e7f4fc1 100644 --- a/src/audio/arts/SDL_artsaudio.h +++ b/src/audio/arts/SDL_artsaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/coreaudio/SDL_coreaudio.h b/src/audio/coreaudio/SDL_coreaudio.h index d5d11ca..2a9fac2 100644 --- a/src/audio/coreaudio/SDL_coreaudio.h +++ b/src/audio/coreaudio/SDL_coreaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/coreaudio/SDL_coreaudio.m b/src/audio/coreaudio/SDL_coreaudio.m index 26da64d..6f751d3 100644 --- a/src/audio/coreaudio/SDL_coreaudio.m +++ b/src/audio/coreaudio/SDL_coreaudio.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -455,12 +455,13 @@ static BOOL update_audio_session(_THIS, SDL_bool open, SDL_bool allow_playandrec if ((open_playback_devices || open_capture_devices) && !session_active) { if (![session setActive:YES error:&err]) { + NSString *desc; if ([err code] == AVAudioSessionErrorCodeResourceNotAvailable && category == AVAudioSessionCategoryPlayAndRecord) { return update_audio_session(this, open, SDL_FALSE); } - NSString *desc = err.description; + desc = err.description; SDL_SetError("Could not activate Audio Session: %s", desc.UTF8String); return NO; } @@ -856,30 +857,39 @@ static int prepare_audioqueue(_THIS) SDL_zero(layout); switch (this->spec.channels) { case 1: + // a standard mono stream layout.mChannelLayoutTag = kAudioChannelLayoutTag_Mono; break; case 2: + // a standard stereo stream (L R) - implied playback layout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo; break; case 3: + // L R LFE layout.mChannelLayoutTag = kAudioChannelLayoutTag_DVD_4; break; case 4: + // front left, front right, back left, back right layout.mChannelLayoutTag = kAudioChannelLayoutTag_Quadraphonic; break; case 5: - layout.mChannelLayoutTag = kAudioChannelLayoutTag_MPEG_5_0_A; + // L R LFE Ls Rs + layout.mChannelLayoutTag = kAudioChannelLayoutTag_DVD_6; break; case 6: - layout.mChannelLayoutTag = kAudioChannelLayoutTag_MPEG_5_1_A; + // L R C LFE Ls Rs + layout.mChannelLayoutTag = kAudioChannelLayoutTag_DVD_12; break; case 7: - /* FIXME: Need to move channel[4] (BC) to channel[6] */ - layout.mChannelLayoutTag = kAudioChannelLayoutTag_MPEG_6_1_A; + // L R C LFE Cs Ls Rs + layout.mChannelLayoutTag = kAudioChannelLayoutTag_WAVE_6_1; break; case 8: - layout.mChannelLayoutTag = kAudioChannelLayoutTag_MPEG_7_1_A; + // L R C LFE Rls Rrs Ls Rs + layout.mChannelLayoutTag = kAudioChannelLayoutTag_WAVE_7_1; break; + default: + return SDL_SetError("Unsupported audio channels"); } if (layout.mChannelLayoutTag != 0) { result = AudioQueueSetProperty(this->hidden->audioQueue, kAudioQueueProperty_ChannelLayout, &layout, sizeof(layout)); diff --git a/src/audio/directsound/SDL_directsound.c b/src/audio/directsound/SDL_directsound.c index a98a164..9d52c38 100644 --- a/src/audio/directsound/SDL_directsound.c +++ b/src/audio/directsound/SDL_directsound.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/directsound/SDL_directsound.h b/src/audio/directsound/SDL_directsound.h index 051b9d7..6de044a 100644 --- a/src/audio/directsound/SDL_directsound.h +++ b/src/audio/directsound/SDL_directsound.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/disk/SDL_diskaudio.c b/src/audio/disk/SDL_diskaudio.c index d9d4aae..49a39f7 100644 --- a/src/audio/disk/SDL_diskaudio.c +++ b/src/audio/disk/SDL_diskaudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/disk/SDL_diskaudio.h b/src/audio/disk/SDL_diskaudio.h index 8ae237f..a7e7e01 100644 --- a/src/audio/disk/SDL_diskaudio.h +++ b/src/audio/disk/SDL_diskaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/dsp/SDL_dspaudio.c b/src/audio/dsp/SDL_dspaudio.c index fdbad8f..ffba531 100644 --- a/src/audio/dsp/SDL_dspaudio.c +++ b/src/audio/dsp/SDL_dspaudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/dsp/SDL_dspaudio.h b/src/audio/dsp/SDL_dspaudio.h index 11214a5..c710a7e 100644 --- a/src/audio/dsp/SDL_dspaudio.h +++ b/src/audio/dsp/SDL_dspaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/dummy/SDL_dummyaudio.c b/src/audio/dummy/SDL_dummyaudio.c index b17cd44..a9bdd84 100644 --- a/src/audio/dummy/SDL_dummyaudio.c +++ b/src/audio/dummy/SDL_dummyaudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/dummy/SDL_dummyaudio.h b/src/audio/dummy/SDL_dummyaudio.h index 500f5d9..e0e77e5 100644 --- a/src/audio/dummy/SDL_dummyaudio.h +++ b/src/audio/dummy/SDL_dummyaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/emscripten/SDL_emscriptenaudio.c b/src/audio/emscripten/SDL_emscriptenaudio.c index 8d21dab..3600fb5 100644 --- a/src/audio/emscripten/SDL_emscriptenaudio.c +++ b/src/audio/emscripten/SDL_emscriptenaudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -39,6 +39,12 @@ static void FeedAudioDevice(_THIS, const void *buf, const int buflen) /* *INDENT-OFF* */ /* clang-format off */ MAIN_THREAD_EM_ASM({ var SDL2 = Module['SDL2']; + /* Convert incoming buf pointer to a HEAPF32 offset. */ +#ifdef __wasm64__ + var buf = $0 / 4; +#else + var buf = $0 >>> 2; +#endif var numChannels = SDL2.audio.currentOutputBuffer['numberOfChannels']; for (var c = 0; c < numChannels; ++c) { var channelData = SDL2.audio.currentOutputBuffer['getChannelData'](c); @@ -47,7 +53,7 @@ static void FeedAudioDevice(_THIS, const void *buf, const int buflen) } for (var j = 0; j < $1; ++j) { - channelData[j] = HEAPF32[$0 + ((j*numChannels + c) << 2) >> 2]; /* !!! FIXME: why are these shifts here? */ + channelData[j] = HEAPF32[buf + (j*numChannels + c)]; } } }, buf, buflen / framelen); @@ -223,7 +229,7 @@ static int EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname) SDL2.audioContext = new webkitAudioContext(); } if (SDL2.audioContext) { - if ((typeof navigator.userActivation) === 'undefined') { // Firefox doesn't have this (as of August 2023), use autoResumeAudioContext instead. + if ((typeof navigator.userActivation) === 'undefined') { autoResumeAudioContext(SDL2.audioContext); } } @@ -354,7 +360,7 @@ static int EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname) SDL2.audio.silenceBuffer = SDL2.audioContext.createBuffer($0, $1, SDL2.audioContext.sampleRate); SDL2.audio.silenceBuffer.getChannelData(0).fill(0.0); var silence_callback = function() { - if ((typeof navigator.userActivation) !== 'undefined') { // Almost everything modern except Firefox (as of August 2023) + if ((typeof navigator.userActivation) !== 'undefined') { if (navigator.userActivation.hasBeenActive) { SDL2.audioContext.resume(); } diff --git a/src/audio/emscripten/SDL_emscriptenaudio.h b/src/audio/emscripten/SDL_emscriptenaudio.h index 54f6057..62631cf 100644 --- a/src/audio/emscripten/SDL_emscriptenaudio.h +++ b/src/audio/emscripten/SDL_emscriptenaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/esd/SDL_esdaudio.c b/src/audio/esd/SDL_esdaudio.c index 596f51a..70cdfa2 100644 --- a/src/audio/esd/SDL_esdaudio.c +++ b/src/audio/esd/SDL_esdaudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -64,7 +64,7 @@ static struct #undef SDL_ESD_SYM -static void UnloadESDLibrary() +static void UnloadESDLibrary(void) { if (esd_handle) { SDL_UnloadObject(esd_handle); @@ -96,7 +96,7 @@ static int LoadESDLibrary(void) #else -static void UnloadESDLibrary() +static void UnloadESDLibrary(void) { return; } diff --git a/src/audio/esd/SDL_esdaudio.h b/src/audio/esd/SDL_esdaudio.h index 15e3d4e..0ec50b0 100644 --- a/src/audio/esd/SDL_esdaudio.h +++ b/src/audio/esd/SDL_esdaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/fusionsound/SDL_fsaudio.c b/src/audio/fusionsound/SDL_fsaudio.c index 5abab2e..30a429f 100644 --- a/src/audio/fusionsound/SDL_fsaudio.c +++ b/src/audio/fusionsound/SDL_fsaudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -77,7 +77,7 @@ static struct #undef SDL_FS_SYM -static void UnloadFusionSoundLibrary() +static void UnloadFusionSoundLibrary(void) { if (fs_handle) { SDL_UnloadObject(fs_handle); @@ -110,7 +110,7 @@ static int LoadFusionSoundLibrary(void) #else -static void UnloadFusionSoundLibrary() +static void UnloadFusionSoundLibrary(void) { return; } diff --git a/src/audio/fusionsound/SDL_fsaudio.h b/src/audio/fusionsound/SDL_fsaudio.h index 556ea54..49c2f53 100644 --- a/src/audio/fusionsound/SDL_fsaudio.h +++ b/src/audio/fusionsound/SDL_fsaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/haiku/SDL_haikuaudio.cc b/src/audio/haiku/SDL_haikuaudio.cc index 39b8d8c..729c0b0 100644 --- a/src/audio/haiku/SDL_haikuaudio.cc +++ b/src/audio/haiku/SDL_haikuaudio.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/haiku/SDL_haikuaudio.h b/src/audio/haiku/SDL_haikuaudio.h index 9acb6e1..50008de 100644 --- a/src/audio/haiku/SDL_haikuaudio.h +++ b/src/audio/haiku/SDL_haikuaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/jack/SDL_jackaudio.c b/src/audio/jack/SDL_jackaudio.c index 9be8799..697cc0a 100644 --- a/src/audio/jack/SDL_jackaudio.c +++ b/src/audio/jack/SDL_jackaudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/jack/SDL_jackaudio.h b/src/audio/jack/SDL_jackaudio.h index e0ac2e9..5fbac2b 100644 --- a/src/audio/jack/SDL_jackaudio.h +++ b/src/audio/jack/SDL_jackaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/n3ds/SDL_n3dsaudio.c b/src/audio/n3ds/SDL_n3dsaudio.c index ea20a7c..c577436 100644 --- a/src/audio/n3ds/SDL_n3dsaudio.c +++ b/src/audio/n3ds/SDL_n3dsaudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/n3ds/SDL_n3dsaudio.h b/src/audio/n3ds/SDL_n3dsaudio.h index 274e9f3..dbd9d61 100644 --- a/src/audio/n3ds/SDL_n3dsaudio.h +++ b/src/audio/n3ds/SDL_n3dsaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/nacl/SDL_naclaudio.c b/src/audio/nacl/SDL_naclaudio.c index f189256..c592aaa 100644 --- a/src/audio/nacl/SDL_naclaudio.c +++ b/src/audio/nacl/SDL_naclaudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/nacl/SDL_naclaudio.h b/src/audio/nacl/SDL_naclaudio.h index c08702b..c47f544 100644 --- a/src/audio/nacl/SDL_naclaudio.h +++ b/src/audio/nacl/SDL_naclaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/nas/SDL_nasaudio.c b/src/audio/nas/SDL_nasaudio.c index f3eb68f..22301e5 100644 --- a/src/audio/nas/SDL_nasaudio.c +++ b/src/audio/nas/SDL_nasaudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/nas/SDL_nasaudio.h b/src/audio/nas/SDL_nasaudio.h index 0275c06..eaa3b37 100644 --- a/src/audio/nas/SDL_nasaudio.h +++ b/src/audio/nas/SDL_nasaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/netbsd/SDL_netbsdaudio.c b/src/audio/netbsd/SDL_netbsdaudio.c index cc51599..0704e32 100644 --- a/src/audio/netbsd/SDL_netbsdaudio.c +++ b/src/audio/netbsd/SDL_netbsdaudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/netbsd/SDL_netbsdaudio.h b/src/audio/netbsd/SDL_netbsdaudio.h index 81fd4e6..416f9cd 100644 --- a/src/audio/netbsd/SDL_netbsdaudio.h +++ b/src/audio/netbsd/SDL_netbsdaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/openslES/SDL_openslES.c b/src/audio/openslES/SDL_openslES.c index d93fb5a..278e891 100644 --- a/src/audio/openslES/SDL_openslES.c +++ b/src/audio/openslES/SDL_openslES.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/openslES/SDL_openslES.h b/src/audio/openslES/SDL_openslES.h index b9943d8..1f84b84 100644 --- a/src/audio/openslES/SDL_openslES.h +++ b/src/audio/openslES/SDL_openslES.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/os2/SDL_os2audio.c b/src/audio/os2/SDL_os2audio.c index c61c641..3657e53 100644 --- a/src/audio/os2/SDL_os2audio.c +++ b/src/audio/os2/SDL_os2audio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/os2/SDL_os2audio.h b/src/audio/os2/SDL_os2audio.h index 41f091f..7aa8efb 100644 --- a/src/audio/os2/SDL_os2audio.h +++ b/src/audio/os2/SDL_os2audio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/paudio/SDL_paudio.c b/src/audio/paudio/SDL_paudio.c index b82ec8e..1d954dd 100644 --- a/src/audio/paudio/SDL_paudio.c +++ b/src/audio/paudio/SDL_paudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/paudio/SDL_paudio.h b/src/audio/paudio/SDL_paudio.h index 7c870ca..d1f8928 100644 --- a/src/audio/paudio/SDL_paudio.h +++ b/src/audio/paudio/SDL_paudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/pipewire/SDL_pipewire.c b/src/audio/pipewire/SDL_pipewire.c index 4fbe9af..889e05d 100644 --- a/src/audio/pipewire/SDL_pipewire.c +++ b/src/audio/pipewire/SDL_pipewire.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -142,13 +142,13 @@ static int pipewire_dlsym(const char *fn, void **addr) return -1; \ } -static int load_pipewire_library() +static int load_pipewire_library(void) { pipewire_handle = SDL_LoadObject(pipewire_library); return pipewire_handle ? 0 : -1; } -static void unload_pipewire_library() +static void unload_pipewire_library(void) { if (pipewire_handle) { SDL_UnloadObject(pipewire_handle); @@ -160,18 +160,18 @@ static void unload_pipewire_library() #define SDL_PIPEWIRE_SYM(x) PIPEWIRE_##x = x -static int load_pipewire_library() +static int load_pipewire_library(void) { return 0; } -static void unload_pipewire_library() +static void unload_pipewire_library(void) { /* Nothing to do */ } #endif /* SDL_AUDIO_DRIVER_PIPEWIRE_DYNAMIC */ -static int load_pipewire_syms() +static int load_pipewire_syms(void) { SDL_PIPEWIRE_SYM(pw_get_library_version); SDL_PIPEWIRE_SYM(pw_init); @@ -212,7 +212,7 @@ SDL_FORCE_INLINE SDL_bool pipewire_version_at_least(int major, int minor, int pa (pipewire_version_major > major || pipewire_version_minor > minor || pipewire_version_patch >= patch); } -static int init_pipewire_library() +static int init_pipewire_library(void) { if (!load_pipewire_library()) { if (!load_pipewire_syms()) { @@ -234,7 +234,7 @@ static int init_pipewire_library() return -1; } -static void deinit_pipewire_library() +static void deinit_pipewire_library(void) { PIPEWIRE_pw_deinit(); unload_pipewire_library(); @@ -340,7 +340,7 @@ static void io_list_remove(Uint32 id) } } -static void io_list_sort() +static void io_list_sort(void) { struct io_node *default_sink = NULL, *default_source = NULL; struct io_node *n, *temp; @@ -365,7 +365,7 @@ static void io_list_sort() } } -static void io_list_clear() +static void io_list_clear(void) { struct io_node *n, *temp; @@ -426,7 +426,7 @@ static void pending_list_remove(Uint32 id) } } -static void pending_list_clear() +static void pending_list_clear(void) { struct node_object *node, *temp; @@ -751,7 +751,7 @@ static const struct pw_registry_events registry_events = { PW_VERSION_REGISTRY_E .global_remove = registry_event_remove_callback }; /* The hotplug thread */ -static int hotplug_loop_init() +static int hotplug_loop_init(void) { int res; @@ -794,7 +794,7 @@ static int hotplug_loop_init() return 0; } -static void hotplug_loop_destroy() +static void hotplug_loop_destroy(void) { if (hotplug_loop) { PIPEWIRE_pw_thread_loop_stop(hotplug_loop); @@ -836,7 +836,7 @@ static void hotplug_loop_destroy() } } -static void PIPEWIRE_DetectDevices() +static void PIPEWIRE_DetectDevices(void) { struct io_node *io; @@ -1342,7 +1342,7 @@ static int PIPEWIRE_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int is return ret; } -static void PIPEWIRE_Deinitialize() +static void PIPEWIRE_Deinitialize(void) { if (pipewire_initialized) { hotplug_loop_destroy(); diff --git a/src/audio/pipewire/SDL_pipewire.h b/src/audio/pipewire/SDL_pipewire.h index cf5817b..079821d 100644 --- a/src/audio/pipewire/SDL_pipewire.h +++ b/src/audio/pipewire/SDL_pipewire.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/ps2/SDL_ps2audio.c b/src/audio/ps2/SDL_ps2audio.c index da5c5d3..0de2372 100644 --- a/src/audio/ps2/SDL_ps2audio.c +++ b/src/audio/ps2/SDL_ps2audio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/ps2/SDL_ps2audio.h b/src/audio/ps2/SDL_ps2audio.h index 5f5989d..3c76544 100644 --- a/src/audio/ps2/SDL_ps2audio.h +++ b/src/audio/ps2/SDL_ps2audio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/psp/SDL_pspaudio.c b/src/audio/psp/SDL_pspaudio.c index 30e1c23..e949a7a 100644 --- a/src/audio/psp/SDL_pspaudio.c +++ b/src/audio/psp/SDL_pspaudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/psp/SDL_pspaudio.h b/src/audio/psp/SDL_pspaudio.h index ba35102..7baa93f 100644 --- a/src/audio/psp/SDL_pspaudio.h +++ b/src/audio/psp/SDL_pspaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/pulseaudio/SDL_pulseaudio.c b/src/audio/pulseaudio/SDL_pulseaudio.c index 5e2bb6f..2fb2f31 100644 --- a/src/audio/pulseaudio/SDL_pulseaudio.c +++ b/src/audio/pulseaudio/SDL_pulseaudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -885,7 +885,7 @@ static int SDLCALL HotplugThread(void *data) return 0; } -static void PULSEAUDIO_DetectDevices() +static void PULSEAUDIO_DetectDevices(void) { SDL_sem *ready_sem = SDL_CreateSemaphore(0); @@ -897,8 +897,12 @@ static void PULSEAUDIO_DetectDevices() /* ok, we have a sane list, let's set up hotplug notifications now... */ SDL_AtomicSet(&pulseaudio_hotplug_thread_active, 1); - pulseaudio_hotplug_thread = SDL_CreateThreadInternal(HotplugThread, "PulseHotplug", 256 * 1024, ready_sem); /* !!! FIXME: this can probably survive in significantly less stack space. */ - SDL_SemWait(ready_sem); + pulseaudio_hotplug_thread = SDL_CreateThreadInternal(HotplugThread, "PulseHotplug", 0, ready_sem); + if (pulseaudio_hotplug_thread) { + SDL_SemWait(ready_sem); + } else { + SDL_AtomicSet(&pulseaudio_hotplug_thread_active, 0); // thread failed to start, we'll go on without hotplug. + } SDL_DestroySemaphore(ready_sem); } diff --git a/src/audio/pulseaudio/SDL_pulseaudio.h b/src/audio/pulseaudio/SDL_pulseaudio.h index b4ad382..f58d9c0 100644 --- a/src/audio/pulseaudio/SDL_pulseaudio.h +++ b/src/audio/pulseaudio/SDL_pulseaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/qsa/SDL_qsa_audio.c b/src/audio/qsa/SDL_qsa_audio.c index be0532c..c9cc616 100644 --- a/src/audio/qsa/SDL_qsa_audio.c +++ b/src/audio/qsa/SDL_qsa_audio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/qsa/SDL_qsa_audio.h b/src/audio/qsa/SDL_qsa_audio.h index 1e69f26..5140e6d 100644 --- a/src/audio/qsa/SDL_qsa_audio.h +++ b/src/audio/qsa/SDL_qsa_audio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/sndio/SDL_sndioaudio.c b/src/audio/sndio/SDL_sndioaudio.c index 499b847..480afd9 100644 --- a/src/audio/sndio/SDL_sndioaudio.c +++ b/src/audio/sndio/SDL_sndioaudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/sndio/SDL_sndioaudio.h b/src/audio/sndio/SDL_sndioaudio.h index ffd4df8..ecd5c39 100644 --- a/src/audio/sndio/SDL_sndioaudio.h +++ b/src/audio/sndio/SDL_sndioaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/sun/SDL_sunaudio.c b/src/audio/sun/SDL_sunaudio.c index 442cf2b..b596bec 100644 --- a/src/audio/sun/SDL_sunaudio.c +++ b/src/audio/sun/SDL_sunaudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/sun/SDL_sunaudio.h b/src/audio/sun/SDL_sunaudio.h index 0952543..976f0fc 100644 --- a/src/audio/sun/SDL_sunaudio.h +++ b/src/audio/sun/SDL_sunaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/vita/SDL_vitaaudio.c b/src/audio/vita/SDL_vitaaudio.c index bd87323..88ce007 100644 --- a/src/audio/vita/SDL_vitaaudio.c +++ b/src/audio/vita/SDL_vitaaudio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/vita/SDL_vitaaudio.h b/src/audio/vita/SDL_vitaaudio.h index cb0aba8..4cde8d8 100644 --- a/src/audio/vita/SDL_vitaaudio.h +++ b/src/audio/vita/SDL_vitaaudio.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/wasapi/SDL_wasapi.c b/src/audio/wasapi/SDL_wasapi.c index cf90efc..f516b1e 100644 --- a/src/audio/wasapi/SDL_wasapi.c +++ b/src/audio/wasapi/SDL_wasapi.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -111,6 +111,12 @@ static int UpdateAudioStream(_THIS, const SDL_AudioSpec *oldspec) } } + /* if the device sample size changed, make sure we're asking for enough data. */ + if (this->callbackspec.samples != this->spec.samples) { + this->callbackspec.samples = this->spec.samples; + SDL_CalculateAudioSpec(&this->callbackspec); + } + /* make sure our scratch buffer can cover the new device spec. */ if (this->spec.size > this->work_buffer_len) { Uint8 *ptr = (Uint8 *)SDL_realloc(this->work_buffer, this->spec.size); diff --git a/src/audio/wasapi/SDL_wasapi.h b/src/audio/wasapi/SDL_wasapi.h index 804e0b7..9786598 100644 --- a/src/audio/wasapi/SDL_wasapi.h +++ b/src/audio/wasapi/SDL_wasapi.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/wasapi/SDL_wasapi_win32.c b/src/audio/wasapi/SDL_wasapi_win32.c index 88823c5..0c1e8bd 100644 --- a/src/audio/wasapi/SDL_wasapi_win32.c +++ b/src/audio/wasapi/SDL_wasapi_win32.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/wasapi/SDL_wasapi_winrt.cpp b/src/audio/wasapi/SDL_wasapi_winrt.cpp index 26f4838..a44058b 100644 --- a/src/audio/wasapi/SDL_wasapi_winrt.cpp +++ b/src/audio/wasapi/SDL_wasapi_winrt.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/winmm/SDL_winmm.c b/src/audio/winmm/SDL_winmm.c index 47cb4ba..77e1773 100644 --- a/src/audio/winmm/SDL_winmm.c +++ b/src/audio/winmm/SDL_winmm.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/audio/winmm/SDL_winmm.h b/src/audio/winmm/SDL_winmm.h index 8d0744a..cebc747 100644 --- a/src/audio/winmm/SDL_winmm.h +++ b/src/audio/winmm/SDL_winmm.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c index 60620d8..86f272e 100644 --- a/src/core/android/SDL_android.c +++ b/src/core/android/SDL_android.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -842,18 +842,18 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeDropFile)( } /* Lock / Unlock Mutex */ -void Android_ActivityMutex_Lock() +void Android_ActivityMutex_Lock(void) { SDL_LockMutex(Android_ActivityMutex); } -void Android_ActivityMutex_Unlock() +void Android_ActivityMutex_Unlock(void) { SDL_UnlockMutex(Android_ActivityMutex); } /* Lock the Mutex when the Activity is in its 'Running' state */ -void Android_ActivityMutex_Lock_Running() +void Android_ActivityMutex_Lock_Running(void) { int pauseSignaled = 0; int resumeSignaled = 0; @@ -1439,13 +1439,13 @@ void Android_JNI_SetOrientation(int w, int h, int resizable, const char *hint) (*env)->DeleteLocalRef(env, jhint); } -void Android_JNI_MinizeWindow() +void Android_JNI_MinizeWindow(void) { JNIEnv *env = Android_JNI_GetEnv(); (*env)->CallStaticVoidMethod(env, mActivityClass, midMinimizeWindow); } -SDL_bool Android_JNI_ShouldMinimizeOnFocusLoss() +SDL_bool Android_JNI_ShouldMinimizeOnFocusLoss(void) { JNIEnv *env = Android_JNI_GetEnv(); return (*env)->CallStaticBooleanMethod(env, mActivityClass, midShouldMinimizeOnFocusLoss); @@ -1879,7 +1879,7 @@ static SDL_bool Android_JNI_ExceptionOccurred(SDL_bool silent) return SDL_FALSE; } -static void Internal_Android_Create_AssetManager() +static void Internal_Android_Create_AssetManager(void) { struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); @@ -1918,7 +1918,7 @@ static void Internal_Android_Create_AssetManager() LocalReferenceHolder_Cleanup(&refs); } -static void Internal_Android_Destroy_AssetManager() +static void Internal_Android_Destroy_AssetManager(void) { JNIEnv *env = Android_JNI_GetEnv(); @@ -2153,7 +2153,7 @@ int Android_JNI_GetPowerInfo(int *plugged, int *charged, int *battery, int *seco } /* Add all touch devices */ -void Android_JNI_InitTouch() +void Android_JNI_InitTouch(void) { JNIEnv *env = Android_JNI_GetEnv(); (*env)->CallStaticVoidMethod(env, mActivityClass, midInitTouch); diff --git a/src/core/android/SDL_android.h b/src/core/android/SDL_android.h index 20d1fc5..650b794 100644 --- a/src/core/android/SDL_android.h +++ b/src/core/android/SDL_android.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/freebsd/SDL_evdev_kbd_freebsd.c b/src/core/freebsd/SDL_evdev_kbd_freebsd.c index a3c3456..47e25b5 100644 --- a/src/core/freebsd/SDL_evdev_kbd_freebsd.c +++ b/src/core/freebsd/SDL_evdev_kbd_freebsd.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -134,7 +134,7 @@ static void kbd_cleanup_signal_action(int signum, siginfo_t *info, void *ucontex SDL_EVDEV_kbd_reraise_signal(signum); } -static void kbd_unregister_emerg_cleanup() +static void kbd_unregister_emerg_cleanup(void) { int tabidx, signum; diff --git a/src/core/gdk/SDL_gdk.cpp b/src/core/gdk/SDL_gdk.cpp index c5bac8a..238375e 100644 --- a/src/core/gdk/SDL_gdk.cpp +++ b/src/core/gdk/SDL_gdk.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -36,6 +36,7 @@ extern "C" { static XTaskQueueHandle GDK_GlobalTaskQueue; PAPPSTATE_REGISTRATION hPLM = {}; +PAPPCONSTRAIN_REGISTRATION hCPLM = {}; HANDLE plmSuspendComplete = nullptr; extern "C" DECLSPEC int @@ -177,6 +178,23 @@ SDL_GDKRunApp(SDL_main_func mainFunction, void *reserved) return -1; } + /* Register constrain/unconstrain handling */ + auto raccn = [](BOOLEAN constrained, PVOID context) { + SDL_LogDebug(SDL_LOG_CATEGORY_APPLICATION, "[GDK] in RegisterAppConstrainedChangeNotification handler"); + SDL_VideoDevice *_this = SDL_GetVideoDevice(); + if (_this) { + if (constrained) { + SDL_SetKeyboardFocus(NULL); + } else { + SDL_SetKeyboardFocus(_this->windows); + } + } + }; + if (RegisterAppConstrainedChangeNotification(raccn, NULL, &hCPLM)) { + SDL_SetError("[GDK] Unable to call RegisterAppConstrainedChangeNotification"); + return -1; + } + /* Run the application main() code */ result = mainFunction(argc, argv); @@ -184,6 +202,9 @@ SDL_GDKRunApp(SDL_main_func mainFunction, void *reserved) UnregisterAppStateChangeNotification(hPLM); CloseHandle(plmSuspendComplete); + /* Unregister constrain/unconstrain handling */ + UnregisterAppConstrainedChangeNotification(hCPLM); + /* !!! FIXME: This follows the docs exactly, but for some reason still leaks handles on exit? */ /* Terminate the task queue and dispatch any pending tasks */ XTaskQueueTerminate(taskQueue, false, nullptr, nullptr); diff --git a/src/core/gdk/SDL_gdk.h b/src/core/gdk/SDL_gdk.h index 75f13ab..1757c2f 100644 --- a/src/core/gdk/SDL_gdk.h +++ b/src/core/gdk/SDL_gdk.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/linux/SDL_dbus.c b/src/core/linux/SDL_dbus.c index 7d706c2..969c04d 100644 --- a/src/core/linux/SDL_dbus.c +++ b/src/core/linux/SDL_dbus.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/linux/SDL_dbus.h b/src/core/linux/SDL_dbus.h index 572ea47..5fc118f 100644 --- a/src/core/linux/SDL_dbus.h +++ b/src/core/linux/SDL_dbus.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/linux/SDL_evdev.c b/src/core/linux/SDL_evdev.c index e3b836c..de1b758 100644 --- a/src/core/linux/SDL_evdev.c +++ b/src/core/linux/SDL_evdev.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/linux/SDL_evdev.h b/src/core/linux/SDL_evdev.h index c3e9c53..6c4b14f 100644 --- a/src/core/linux/SDL_evdev.h +++ b/src/core/linux/SDL_evdev.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/linux/SDL_evdev_capabilities.c b/src/core/linux/SDL_evdev_capabilities.c index e1b5d74..472cc2f 100644 --- a/src/core/linux/SDL_evdev_capabilities.c +++ b/src/core/linux/SDL_evdev_capabilities.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga Copyright (C) 2020 Collabora Ltd. This software is provided 'as-is', without any express or implied diff --git a/src/core/linux/SDL_evdev_capabilities.h b/src/core/linux/SDL_evdev_capabilities.h index 8d3830a..37f9d06 100644 --- a/src/core/linux/SDL_evdev_capabilities.h +++ b/src/core/linux/SDL_evdev_capabilities.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga Copyright (C) 2020 Collabora Ltd. This software is provided 'as-is', without any express or implied diff --git a/src/core/linux/SDL_evdev_kbd.c b/src/core/linux/SDL_evdev_kbd.c index 0aaefa0..22a70c3 100644 --- a/src/core/linux/SDL_evdev_kbd.c +++ b/src/core/linux/SDL_evdev_kbd.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -214,7 +214,7 @@ static void kbd_cleanup_signal_action(int signum, siginfo_t *info, void *ucontex SDL_EVDEV_kbd_reraise_signal(signum); } -static void kbd_unregister_emerg_cleanup() +static void kbd_unregister_emerg_cleanup(void) { int tabidx, signum; diff --git a/src/core/linux/SDL_evdev_kbd.h b/src/core/linux/SDL_evdev_kbd.h index 52a4778..ffc7a3d 100644 --- a/src/core/linux/SDL_evdev_kbd.h +++ b/src/core/linux/SDL_evdev_kbd.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/linux/SDL_evdev_kbd_default_accents.h b/src/core/linux/SDL_evdev_kbd_default_accents.h index d0d5234..fd1fe6f 100644 --- a/src/core/linux/SDL_evdev_kbd_default_accents.h +++ b/src/core/linux/SDL_evdev_kbd_default_accents.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/linux/SDL_evdev_kbd_default_keymap.h b/src/core/linux/SDL_evdev_kbd_default_keymap.h index d744a54..35f7ebf 100644 --- a/src/core/linux/SDL_evdev_kbd_default_keymap.h +++ b/src/core/linux/SDL_evdev_kbd_default_keymap.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/linux/SDL_fcitx.c b/src/core/linux/SDL_fcitx.c index 88b6d06..23dcc28 100644 --- a/src/core/linux/SDL_fcitx.c +++ b/src/core/linux/SDL_fcitx.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -55,7 +55,7 @@ typedef struct _FcitxClient static FcitxClient fcitx_client; -static char *GetAppName() +static char *GetAppName(void) { #if defined(__LINUX__) || defined(__FREEBSD__) char *spot; @@ -368,7 +368,7 @@ static Uint32 Fcitx_ModState(void) return fcitx_mods; } -SDL_bool SDL_Fcitx_Init() +SDL_bool SDL_Fcitx_Init(void) { fcitx_client.dbus = SDL_DBus_GetContext(); @@ -380,7 +380,7 @@ SDL_bool SDL_Fcitx_Init() return FcitxClientCreateIC(&fcitx_client); } -void SDL_Fcitx_Quit() +void SDL_Fcitx_Quit(void) { FcitxClientICCallMethod(&fcitx_client, "DestroyIC"); if (fcitx_client.ic_path) { @@ -485,7 +485,6 @@ void SDL_Fcitx_PumpEvents(void) while (dbus->connection_dispatch(conn) == DBUS_DISPATCH_DATA_REMAINS) { /* Do nothing, actual work happens in DBus_MessageFilter */ - usleep(10); } } diff --git a/src/core/linux/SDL_fcitx.h b/src/core/linux/SDL_fcitx.h index 4a893f2..7aaf1f6 100644 --- a/src/core/linux/SDL_fcitx.h +++ b/src/core/linux/SDL_fcitx.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/linux/SDL_ibus.c b/src/core/linux/SDL_ibus.c index 31179d4..83e3227 100644 --- a/src/core/linux/SDL_ibus.c +++ b/src/core/linux/SDL_ibus.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/linux/SDL_ibus.h b/src/core/linux/SDL_ibus.h index a4ea140..f6ec1b2 100644 --- a/src/core/linux/SDL_ibus.h +++ b/src/core/linux/SDL_ibus.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/linux/SDL_ime.c b/src/core/linux/SDL_ime.c index 6c28e5f..4540621 100644 --- a/src/core/linux/SDL_ime.c +++ b/src/core/linux/SDL_ime.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -40,7 +40,7 @@ static _SDL_IME_ProcessKeyEvent SDL_IME_ProcessKeyEvent_Real = NULL; static _SDL_IME_UpdateTextRect SDL_IME_UpdateTextRect_Real = NULL; static _SDL_IME_PumpEvents SDL_IME_PumpEvents_Real = NULL; -static void InitIME() +static void InitIME(void) { static SDL_bool inited = SDL_FALSE; #ifdef HAVE_FCITX @@ -142,7 +142,7 @@ void SDL_IME_UpdateTextRect(const SDL_Rect *rect) } } -void SDL_IME_PumpEvents() +void SDL_IME_PumpEvents(void) { if (SDL_IME_PumpEvents_Real) { SDL_IME_PumpEvents_Real(); diff --git a/src/core/linux/SDL_ime.h b/src/core/linux/SDL_ime.h index 0c1e2d0..0995ce5 100644 --- a/src/core/linux/SDL_ime.h +++ b/src/core/linux/SDL_ime.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/linux/SDL_sandbox.c b/src/core/linux/SDL_sandbox.c index e93e183..d4e0360 100644 --- a/src/core/linux/SDL_sandbox.c +++ b/src/core/linux/SDL_sandbox.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga Copyright (C) 2022 Collabora Ltd. This software is provided 'as-is', without any express or implied diff --git a/src/core/linux/SDL_sandbox.h b/src/core/linux/SDL_sandbox.h index 4e66918..dc2fd47 100644 --- a/src/core/linux/SDL_sandbox.h +++ b/src/core/linux/SDL_sandbox.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga Copyright (C) 2022 Collabora Ltd. This software is provided 'as-is', without any express or implied diff --git a/src/core/linux/SDL_threadprio.c b/src/core/linux/SDL_threadprio.c index 80d448e..fca2033 100644 --- a/src/core/linux/SDL_threadprio.c +++ b/src/core/linux/SDL_threadprio.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -79,7 +79,7 @@ static SDL_bool realtime_portal_supported(DBusConnection *conn) "RTTimeUSecMax", DBUS_TYPE_INT64, &res); } -static void set_rtkit_interface() +static void set_rtkit_interface(void) { SDL_DBusContext *dbus = SDL_DBus_GetContext(); @@ -108,7 +108,7 @@ static DBusConnection *get_rtkit_dbus_connection() return NULL; } -static void rtkit_initialize() +static void rtkit_initialize(void) { DBusConnection *dbus_conn; @@ -134,7 +134,7 @@ static void rtkit_initialize() } } -static SDL_bool rtkit_initialize_realtime_thread() +static SDL_bool rtkit_initialize_realtime_thread(void) { // Following is an excerpt from rtkit README that outlines the requirements // a thread must meet before making rtkit requests: diff --git a/src/core/linux/SDL_udev.c b/src/core/linux/SDL_udev.c index 9cb5345..06eefa3 100644 --- a/src/core/linux/SDL_udev.c +++ b/src/core/linux/SDL_udev.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -31,6 +31,7 @@ #ifdef SDL_USE_LIBUDEV #include +#include #include "SDL_assert.h" #include "SDL_evdev_capabilities.h" @@ -227,61 +228,59 @@ void SDL_UDEV_Scan(void) SDL_bool SDL_UDEV_GetProductInfo(const char *device_path, Uint16 *vendor, Uint16 *product, Uint16 *version, int *class) { - struct udev_enumerate *enumerate = NULL; - struct udev_list_entry *devs = NULL; - struct udev_list_entry *item = NULL; - SDL_bool found = SDL_FALSE; + struct stat statbuf; + char type; + struct udev_device *dev; + const char* val; + int class_temp; if (!_this) { return SDL_FALSE; } - enumerate = _this->syms.udev_enumerate_new(_this->udev); - if (!enumerate) { - SDL_SetError("udev_enumerate_new() failed"); + if (stat(device_path, &statbuf) == -1) { return SDL_FALSE; } - _this->syms.udev_enumerate_scan_devices(enumerate); - devs = _this->syms.udev_enumerate_get_list_entry(enumerate); - for (item = devs; item && !found; item = _this->syms.udev_list_entry_get_next(item)) { - const char *path = _this->syms.udev_list_entry_get_name(item); - struct udev_device *dev = _this->syms.udev_device_new_from_syspath(_this->udev, path); - if (dev) { - const char *val = NULL; - const char *existing_path; + if (S_ISBLK(statbuf.st_mode)) { + type = 'b'; + } + else if (S_ISCHR(statbuf.st_mode)) { + type = 'c'; + } + else { + return SDL_FALSE; + } - existing_path = _this->syms.udev_device_get_devnode(dev); - if (existing_path && SDL_strcmp(device_path, existing_path) == 0) { - int class_temp; - found = SDL_TRUE; + dev = _this->syms.udev_device_new_from_devnum(_this->udev, type, statbuf.st_rdev); - val = _this->syms.udev_device_get_property_value(dev, "ID_VENDOR_ID"); - if (val) { - *vendor = (Uint16)SDL_strtol(val, NULL, 16); - } + if (!dev) { + return SDL_FALSE; + } - val = _this->syms.udev_device_get_property_value(dev, "ID_MODEL_ID"); - if (val) { - *product = (Uint16)SDL_strtol(val, NULL, 16); - } + val = _this->syms.udev_device_get_property_value(dev, "ID_VENDOR_ID"); + if (val) { + *vendor = (Uint16)SDL_strtol(val, NULL, 16); + } - val = _this->syms.udev_device_get_property_value(dev, "ID_REVISION"); - if (val) { - *version = (Uint16)SDL_strtol(val, NULL, 16); - } + val = _this->syms.udev_device_get_property_value(dev, "ID_MODEL_ID"); + if (val) { + *product = (Uint16)SDL_strtol(val, NULL, 16); + } - class_temp = device_class(dev); - if (class_temp) { - *class = class_temp; - } - } - _this->syms.udev_device_unref(dev); - } + val = _this->syms.udev_device_get_property_value(dev, "ID_REVISION"); + if (val) { + *version = (Uint16)SDL_strtol(val, NULL, 16); } - _this->syms.udev_enumerate_unref(enumerate); - return found; + class_temp = device_class(dev); + if (class_temp) { + *class = class_temp; + } + + _this->syms.udev_device_unref(dev); + + return SDL_TRUE; } void SDL_UDEV_UnloadLibrary(void) diff --git a/src/core/linux/SDL_udev.h b/src/core/linux/SDL_udev.h index 1489a85..85a563c 100644 --- a/src/core/linux/SDL_udev.h +++ b/src/core/linux/SDL_udev.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/openbsd/SDL_wscons.h b/src/core/openbsd/SDL_wscons.h index 40e102d..201aeca 100644 --- a/src/core/openbsd/SDL_wscons.h +++ b/src/core/openbsd/SDL_wscons.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/openbsd/SDL_wscons_kbd.c b/src/core/openbsd/SDL_wscons_kbd.c index 975ba82..1bee37e 100644 --- a/src/core/openbsd/SDL_wscons_kbd.c +++ b/src/core/openbsd/SDL_wscons_kbd.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -449,7 +449,7 @@ static SDL_WSCONS_input_data *SDL_WSCONS_Init_Keyboard(const char *dev) return input; } -void SDL_WSCONS_Init() +void SDL_WSCONS_Init(void) { inputs[0] = SDL_WSCONS_Init_Keyboard("/dev/wskbd0"); inputs[1] = SDL_WSCONS_Init_Keyboard("/dev/wskbd1"); @@ -460,7 +460,7 @@ void SDL_WSCONS_Init() return; } -void SDL_WSCONS_Quit() +void SDL_WSCONS_Quit(void) { int i = 0; SDL_WSCONS_input_data *input = NULL; @@ -921,7 +921,7 @@ static void updateKeyboard(SDL_WSCONS_input_data *input) } } -void SDL_WSCONS_PumpEvents() +void SDL_WSCONS_PumpEvents(void) { int i = 0; for (i = 0; i < 4; i++) { diff --git a/src/core/openbsd/SDL_wscons_mouse.c b/src/core/openbsd/SDL_wscons_mouse.c index 5a8664c..8b04634 100644 --- a/src/core/openbsd/SDL_wscons_mouse.c +++ b/src/core/openbsd/SDL_wscons_mouse.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/os2/SDL_os2.c b/src/core/os2/SDL_os2.c index 76ad59d..138652c 100644 --- a/src/core/os2/SDL_os2.c +++ b/src/core/os2/SDL_os2.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/os2/SDL_os2.h b/src/core/os2/SDL_os2.h index 9f88c70..4f90d7f 100644 --- a/src/core/os2/SDL_os2.h +++ b/src/core/os2/SDL_os2.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/os2/geniconv/geniconv.c b/src/core/os2/geniconv/geniconv.c index df9c7c7..81ceaec 100644 --- a/src/core/os2/geniconv/geniconv.c +++ b/src/core/os2/geniconv/geniconv.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/os2/geniconv/geniconv.h b/src/core/os2/geniconv/geniconv.h index 463255b..8483d0f 100644 --- a/src/core/os2/geniconv/geniconv.h +++ b/src/core/os2/geniconv/geniconv.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/os2/geniconv/os2cp.c b/src/core/os2/geniconv/os2cp.c index 36d808e..ee32110 100644 --- a/src/core/os2/geniconv/os2cp.c +++ b/src/core/os2/geniconv/os2cp.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/os2/geniconv/os2cp.h b/src/core/os2/geniconv/os2cp.h index 7024e9d..9ea8b99 100644 --- a/src/core/os2/geniconv/os2cp.h +++ b/src/core/os2/geniconv/os2cp.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/os2/geniconv/os2iconv.c b/src/core/os2/geniconv/os2iconv.c index 4c6a024..dd9fc5e 100644 --- a/src/core/os2/geniconv/os2iconv.c +++ b/src/core/os2/geniconv/os2iconv.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/os2/geniconv/sys2utf8.c b/src/core/os2/geniconv/sys2utf8.c index 75dd7dd..ec53d9f 100644 --- a/src/core/os2/geniconv/sys2utf8.c +++ b/src/core/os2/geniconv/sys2utf8.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/os2/geniconv/test.c b/src/core/os2/geniconv/test.c index 2fe19ac..251ca92 100644 --- a/src/core/os2/geniconv/test.c +++ b/src/core/os2/geniconv/test.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/unix/SDL_poll.c b/src/core/unix/SDL_poll.c index 1a34c57..9bcc8f0 100644 --- a/src/core/unix/SDL_poll.c +++ b/src/core/unix/SDL_poll.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/unix/SDL_poll.h b/src/core/unix/SDL_poll.h index 67e52ec..045068e 100644 --- a/src/core/unix/SDL_poll.h +++ b/src/core/unix/SDL_poll.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/windows/SDL_directx.h b/src/core/windows/SDL_directx.h index 98c63ec..128df87 100644 --- a/src/core/windows/SDL_directx.h +++ b/src/core/windows/SDL_directx.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/windows/SDL_hid.c b/src/core/windows/SDL_hid.c index 60b9d14..fddfba2 100644 --- a/src/core/windows/SDL_hid.c +++ b/src/core/windows/SDL_hid.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/windows/SDL_hid.h b/src/core/windows/SDL_hid.h index f75ea24..869190f 100644 --- a/src/core/windows/SDL_hid.h +++ b/src/core/windows/SDL_hid.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/windows/SDL_immdevice.c b/src/core/windows/SDL_immdevice.c index a8e8b45..d08e7b2 100644 --- a/src/core/windows/SDL_immdevice.c +++ b/src/core/windows/SDL_immdevice.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/windows/SDL_immdevice.h b/src/core/windows/SDL_immdevice.h index b15b903..fc7708d 100644 --- a/src/core/windows/SDL_immdevice.h +++ b/src/core/windows/SDL_immdevice.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/windows/SDL_windows.c b/src/core/windows/SDL_windows.c index 1da9418..3caca61 100644 --- a/src/core/windows/SDL_windows.c +++ b/src/core/windows/SDL_windows.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/windows/SDL_windows.h b/src/core/windows/SDL_windows.h index 852fdb0..33581a9 100644 --- a/src/core/windows/SDL_windows.h +++ b/src/core/windows/SDL_windows.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -36,7 +36,7 @@ #endif #undef WINVER #undef _WIN32_WINNT -#if defined(SDL_VIDEO_RENDER_D3D12) +#if SDL_VIDEO_RENDER_D3D12 #define _WIN32_WINNT 0xA00 /* For D3D12, 0xA00 is required */ #elif defined(HAVE_SHELLSCALINGAPI_H) #define _WIN32_WINNT 0x603 /* For DPI support */ @@ -92,16 +92,6 @@ #include #include /* for REFIID with broken mingw.org headers */ -/* Older Visual C++ headers don't have the Win64-compatible typedefs... */ -#if defined(_MSC_VER) && (_MSC_VER <= 1200) -#ifndef DWORD_PTR -#define DWORD_PTR DWORD -#endif -#ifndef LONG_PTR -#define LONG_PTR LONG -#endif -#endif - #include "SDL_rect.h" /* Routines to convert from UTF8 to native Windows text */ diff --git a/src/core/windows/SDL_xinput.c b/src/core/windows/SDL_xinput.c index 053473e..0e39ded 100644 --- a/src/core/windows/SDL_xinput.c +++ b/src/core/windows/SDL_xinput.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/windows/SDL_xinput.h b/src/core/windows/SDL_xinput.h index 396afcd..0f6ab1d 100644 --- a/src/core/windows/SDL_xinput.h +++ b/src/core/windows/SDL_xinput.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -212,7 +212,7 @@ typedef struct #endif /* HAVE_XINPUT_H */ /* This struct is not defined in XInput headers. */ -typedef struct _XINPUT_CAPABILITIES_EX +typedef struct { XINPUT_CAPABILITIES Capabilities; WORD VendorId; @@ -220,7 +220,7 @@ typedef struct _XINPUT_CAPABILITIES_EX WORD ProductVersion; WORD unk1; DWORD unk2; -} XINPUT_CAPABILITIES_EX, *PXINPUT_CAPABILITIES_EX; +} SDL_XINPUT_CAPABILITIES_EX; /* Forward decl's for XInput API's we load dynamically and use if available */ typedef DWORD(WINAPI *XInputGetState_t)( @@ -244,7 +244,7 @@ typedef DWORD(WINAPI *XInputGetCapabilitiesEx_t)( DWORD dwReserved, /* [in] Must be 1 */ DWORD dwUserIndex, /* [in] Index of the gamer associated with the device */ DWORD dwFlags, /* [in] Input flags that identify the device type */ - XINPUT_CAPABILITIES_EX *pCapabilitiesEx /* [out] Receives the capabilities */ + SDL_XINPUT_CAPABILITIES_EX *pCapabilitiesEx /* [out] Receives the capabilities */ ); typedef DWORD(WINAPI *XInputGetBatteryInformation_t)( diff --git a/src/core/winrt/SDL_winrtapp_common.cpp b/src/core/winrt/SDL_winrtapp_common.cpp index 9d16492..dfd1ac8 100644 --- a/src/core/winrt/SDL_winrtapp_common.cpp +++ b/src/core/winrt/SDL_winrtapp_common.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/winrt/SDL_winrtapp_common.h b/src/core/winrt/SDL_winrtapp_common.h index fdc8294..3789f07 100644 --- a/src/core/winrt/SDL_winrtapp_common.h +++ b/src/core/winrt/SDL_winrtapp_common.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/winrt/SDL_winrtapp_direct3d.cpp b/src/core/winrt/SDL_winrtapp_direct3d.cpp index 2cf7b40..04c655d 100644 --- a/src/core/winrt/SDL_winrtapp_direct3d.cpp +++ b/src/core/winrt/SDL_winrtapp_direct3d.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -58,7 +58,7 @@ extern "C" { #include "SDL_winrtapp_common.h" #include "SDL_winrtapp_direct3d.h" -#if defined(SDL_VIDEO_RENDER_D3D11) && !defined(SDL_RENDER_DISABLED) +#if SDL_VIDEO_RENDER_D3D11 /* Calling IDXGIDevice3::Trim on the active Direct3D 11.x device is necessary * when Windows 8.1 apps are about to get suspended. */ @@ -622,7 +622,7 @@ void SDL_WinRTApp::OnSuspending(Platform::Object ^ sender, SuspendingEventArgs ^ // Let the Direct3D 11 renderer prepare for the app to be backgrounded. // This is necessary for Windows 8.1, possibly elsewhere in the future. // More details at: http://msdn.microsoft.com/en-us/library/windows/apps/Hh994929.aspx -#if defined(SDL_VIDEO_RENDER_D3D11) && !defined(SDL_RENDER_DISABLED) +#if SDL_VIDEO_RENDER_D3D11 if (WINRT_GlobalSDLWindow) { SDL_Renderer *renderer = SDL_GetRenderer(WINRT_GlobalSDLWindow); if (renderer && (SDL_strcmp(renderer->info.name, "direct3d11") == 0)) { diff --git a/src/core/winrt/SDL_winrtapp_direct3d.h b/src/core/winrt/SDL_winrtapp_direct3d.h index fcd6ab7..c4bfd1d 100644 --- a/src/core/winrt/SDL_winrtapp_direct3d.h +++ b/src/core/winrt/SDL_winrtapp_direct3d.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/winrt/SDL_winrtapp_xaml.cpp b/src/core/winrt/SDL_winrtapp_xaml.cpp index 9174f0d..361c832 100644 --- a/src/core/winrt/SDL_winrtapp_xaml.cpp +++ b/src/core/winrt/SDL_winrtapp_xaml.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/core/winrt/SDL_winrtapp_xaml.h b/src/core/winrt/SDL_winrtapp_xaml.h index b414753..39e46c9 100644 --- a/src/core/winrt/SDL_winrtapp_xaml.h +++ b/src/core/winrt/SDL_winrtapp_xaml.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/cpuinfo/SDL_cpuinfo.c b/src/cpuinfo/SDL_cpuinfo.c index 34aa424..5e65b62 100644 --- a/src/cpuinfo/SDL_cpuinfo.c +++ b/src/cpuinfo/SDL_cpuinfo.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -1239,7 +1239,7 @@ void SDL_SIMDFree(void *ptr) #include -int main() +int main(void) { printf("CPU count: %d\n", SDL_GetCPUCount()); printf("CPU type: %s\n", SDL_GetCPUType()); diff --git a/src/dynapi/SDL_dynapi.c b/src/dynapi/SDL_dynapi.c index 861f88a..42dc8ed 100644 --- a/src/dynapi/SDL_dynapi.c +++ b/src/dynapi/SDL_dynapi.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/dynapi/SDL_dynapi.h b/src/dynapi/SDL_dynapi.h index 95b20aa..b5c9cbb 100644 --- a/src/dynapi/SDL_dynapi.h +++ b/src/dynapi/SDL_dynapi.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index f57c522..f26569b 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index 7f5d325..695ee83 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/dynapi/gendynapi.pl b/src/dynapi/gendynapi.pl index dad2bc4..14c206f 100755 --- a/src/dynapi/gendynapi.pl +++ b/src/dynapi/gendynapi.pl @@ -1,7 +1,7 @@ #!/usr/bin/perl -w # Simple DirectMedia Layer -# Copyright (C) 1997-2024 Sam Lantinga +# Copyright (C) 1997-2025 Sam Lantinga # # This software is provided 'as-is', without any express or implied # warranty. In no event will the authors be held liable for any damages @@ -50,8 +50,13 @@ open(SDL_DYNAPI_OVERRIDES_H, '>>', $sdl_dynapi_overrides_h) or die("Can't open $sdl_dynapi_overrides_h: $!\n"); open(SDL2_EXPORTS, '>>', $sdl2_exports) or die("Can't open $sdl2_exports: $!\n"); +# Ordered for reproducible builds opendir(HEADERS, 'include') or die("Can't open include dir: $!\n"); -while (my $d = readdir(HEADERS)) { +my @entries = readdir(HEADERS); +closedir(HEADERS); +# Sort the entries +@entries = sort @entries; +foreach my $d (@entries) { next if not $d =~ /\.h\Z/; my $header = "include/$d"; open(HEADER, '<', $header) or die("Can't open $header: $!\n"); @@ -143,8 +148,6 @@ close(HEADER); } -closedir(HEADERS); - close(SDL_DYNAPI_PROCS_H); close(SDL_DYNAPI_OVERRIDES_H); close(SDL2_EXPORTS); diff --git a/src/events/SDL_clipboardevents.c b/src/events/SDL_clipboardevents.c index 68b9a76..2789303 100644 --- a/src/events/SDL_clipboardevents.c +++ b/src/events/SDL_clipboardevents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/events/SDL_clipboardevents_c.h b/src/events/SDL_clipboardevents_c.h index 77e2e42..116ba99 100644 --- a/src/events/SDL_clipboardevents_c.h +++ b/src/events/SDL_clipboardevents_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/events/SDL_displayevents.c b/src/events/SDL_displayevents.c index 9777d5d..36bf19f 100644 --- a/src/events/SDL_displayevents.c +++ b/src/events/SDL_displayevents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/events/SDL_displayevents_c.h b/src/events/SDL_displayevents_c.h index d2e2b57..99058c2 100644 --- a/src/events/SDL_displayevents_c.h +++ b/src/events/SDL_displayevents_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/events/SDL_dropevents.c b/src/events/SDL_dropevents.c index 7c7cc56..a7a9a98 100644 --- a/src/events/SDL_dropevents.c +++ b/src/events/SDL_dropevents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/events/SDL_dropevents_c.h b/src/events/SDL_dropevents_c.h index 83177a8..5bdd32f 100644 --- a/src/events/SDL_dropevents_c.h +++ b/src/events/SDL_dropevents_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c index 47f5721..16916be 100644 --- a/src/events/SDL_events.c +++ b/src/events/SDL_events.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -34,13 +34,6 @@ #include "../video/SDL_sysvideo.h" #include "SDL_syswm.h" -#undef SDL_PRIs64 -#if (defined(__WIN32__) || defined(__GDK__)) && !defined(__CYGWIN__) -#define SDL_PRIs64 "I64d" -#else -#define SDL_PRIs64 "lld" -#endif - /* An arbitrary limit so we don't have unbounded growth */ #define SDL_MAX_QUEUED_EVENTS 65535 @@ -454,8 +447,8 @@ static void SDL_LogEvent(const SDL_Event *event) #define PRINT_FINGER_EVENT(event) \ (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u touchid=%" SDL_PRIs64 " fingerid=%" SDL_PRIs64 " x=%f y=%f dx=%f dy=%f pressure=%f)", \ - (uint)event->tfinger.timestamp, (long long)event->tfinger.touchId, \ - (long long)event->tfinger.fingerId, event->tfinger.x, event->tfinger.y, \ + (uint)event->tfinger.timestamp, event->tfinger.touchId, \ + event->tfinger.fingerId, event->tfinger.x, event->tfinger.y, \ event->tfinger.dx, event->tfinger.dy, event->tfinger.pressure) SDL_EVENT_CASE(SDL_FINGERDOWN) PRINT_FINGER_EVENT(event); @@ -470,8 +463,8 @@ static void SDL_LogEvent(const SDL_Event *event) #define PRINT_DOLLAR_EVENT(event) \ (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u touchid=%" SDL_PRIs64 " gestureid=%" SDL_PRIs64 " numfingers=%u error=%f x=%f y=%f)", \ - (uint)event->dgesture.timestamp, (long long)event->dgesture.touchId, \ - (long long)event->dgesture.gestureId, (uint)event->dgesture.numFingers, \ + (uint)event->dgesture.timestamp, event->dgesture.touchId, \ + event->dgesture.gestureId, (uint)event->dgesture.numFingers, \ event->dgesture.error, event->dgesture.x, event->dgesture.y) SDL_EVENT_CASE(SDL_DOLLARGESTURE) PRINT_DOLLAR_EVENT(event); @@ -483,7 +476,7 @@ static void SDL_LogEvent(const SDL_Event *event) SDL_EVENT_CASE(SDL_MULTIGESTURE) (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u touchid=%" SDL_PRIs64 " dtheta=%f ddist=%f x=%f y=%f numfingers=%u)", - (uint)event->mgesture.timestamp, (long long)event->mgesture.touchId, + (uint)event->mgesture.timestamp, event->mgesture.touchId, event->mgesture.dTheta, event->mgesture.dDist, event->mgesture.x, event->mgesture.y, (uint)event->mgesture.numFingers); break; diff --git a/src/events/SDL_events_c.h b/src/events/SDL_events_c.h index 6a9cf4c..572734e 100644 --- a/src/events/SDL_events_c.h +++ b/src/events/SDL_events_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/events/SDL_gesture.c b/src/events/SDL_gesture.c index 63362c0..6287431 100644 --- a/src/events/SDL_gesture.c +++ b/src/events/SDL_gesture.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/events/SDL_gesture_c.h b/src/events/SDL_gesture_c.h index 04320d5..b6f450b 100644 --- a/src/events/SDL_gesture_c.h +++ b/src/events/SDL_gesture_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/events/SDL_keyboard.c b/src/events/SDL_keyboard.c index 58a95c9..6b3e9de 100644 --- a/src/events/SDL_keyboard.c +++ b/src/events/SDL_keyboard.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/events/SDL_keyboard_c.h b/src/events/SDL_keyboard_c.h index 4c5cd2f..bbad086 100644 --- a/src/events/SDL_keyboard_c.h +++ b/src/events/SDL_keyboard_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/events/SDL_keysym_to_scancode.c b/src/events/SDL_keysym_to_scancode.c index ddf4ae3..7bd91c0 100644 --- a/src/events/SDL_keysym_to_scancode.c +++ b/src/events/SDL_keysym_to_scancode.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/events/SDL_keysym_to_scancode_c.h b/src/events/SDL_keysym_to_scancode_c.h index 11e2d37..e11dde0 100644 --- a/src/events/SDL_keysym_to_scancode_c.h +++ b/src/events/SDL_keysym_to_scancode_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/events/SDL_mouse.c b/src/events/SDL_mouse.c index 431354f..48b3dae 100644 --- a/src/events/SDL_mouse.c +++ b/src/events/SDL_mouse.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -170,6 +170,13 @@ static void SDLCALL SDL_MouseRelativeWarpMotionChanged(void *userdata, const cha mouse->relative_mode_warp_motion = SDL_GetStringBoolean(hint, SDL_FALSE); } +static void SDLCALL SDL_MouseRelativeCursorVisibleChanged(void *userdata, const char *name, const char *oldValue, const char *hint) +{ + SDL_Mouse *mouse = (SDL_Mouse *)userdata; + + mouse->relative_mode_cursor_visible = SDL_GetStringBoolean(hint, SDL_FALSE); +} + /* Public functions */ int SDL_MousePreInit(void) { @@ -209,6 +216,9 @@ int SDL_MousePreInit(void) SDL_AddHintCallback(SDL_HINT_MOUSE_RELATIVE_WARP_MOTION, SDL_MouseRelativeWarpMotionChanged, mouse); + SDL_AddHintCallback(SDL_HINT_MOUSE_RELATIVE_CURSOR_VISIBLE, + SDL_MouseRelativeCursorVisibleChanged, mouse); + mouse->was_touch_mouse_events = SDL_FALSE; /* no touch to mouse movement event pending */ mouse->cursor_shown = SDL_TRUE; @@ -992,6 +1002,9 @@ void SDL_MouseQuit(void) SDL_DelHintCallback(SDL_HINT_MOUSE_RELATIVE_WARP_MOTION, SDL_MouseRelativeWarpMotionChanged, mouse); + + SDL_DelHintCallback(SDL_HINT_MOUSE_RELATIVE_CURSOR_VISIBLE, + SDL_MouseRelativeCursorVisibleChanged, mouse); } Uint32 SDL_GetMouseState(int *x, int *y) @@ -1412,7 +1425,7 @@ void SDL_SetCursor(SDL_Cursor *cursor) } } - if (cursor && mouse->cursor_shown && !mouse->relative_mode) { + if (cursor && mouse->cursor_shown && (!mouse->relative_mode || mouse->relative_mode_cursor_visible)) { if (mouse->ShowCursor) { mouse->ShowCursor(cursor); } diff --git a/src/events/SDL_mouse_c.h b/src/events/SDL_mouse_c.h index 4204f62..e71fd8d 100644 --- a/src/events/SDL_mouse_c.h +++ b/src/events/SDL_mouse_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -92,6 +92,7 @@ typedef struct SDL_bool relative_mode; SDL_bool relative_mode_warp; SDL_bool relative_mode_warp_motion; + SDL_bool relative_mode_cursor_visible; SDL_bool enable_normal_speed_scale; float normal_speed_scale; SDL_bool enable_relative_speed_scale; diff --git a/src/events/SDL_quit.c b/src/events/SDL_quit.c index cd629a9..b4234fc 100644 --- a/src/events/SDL_quit.c +++ b/src/events/SDL_quit.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/events/SDL_scancode_tables.c b/src/events/SDL_scancode_tables.c index db6d861..71147a5 100644 --- a/src/events/SDL_scancode_tables.c +++ b/src/events/SDL_scancode_tables.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/events/SDL_scancode_tables_c.h b/src/events/SDL_scancode_tables_c.h index 481e7a5..153c3c7 100644 --- a/src/events/SDL_scancode_tables_c.h +++ b/src/events/SDL_scancode_tables_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/events/SDL_touch.c b/src/events/SDL_touch.c index b5ec77b..6824f75 100644 --- a/src/events/SDL_touch.c +++ b/src/events/SDL_touch.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/events/SDL_touch_c.h b/src/events/SDL_touch_c.h index 85f1f90..2902228 100644 --- a/src/events/SDL_touch_c.h +++ b/src/events/SDL_touch_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/events/SDL_windowevents.c b/src/events/SDL_windowevents.c index 2ef1e74..9e4f0f3 100644 --- a/src/events/SDL_windowevents.c +++ b/src/events/SDL_windowevents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/events/SDL_windowevents_c.h b/src/events/SDL_windowevents_c.h index cf7fc3a..3ae1d34 100644 --- a/src/events/SDL_windowevents_c.h +++ b/src/events/SDL_windowevents_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/events/blank_cursor.h b/src/events/blank_cursor.h index 1c317b7..597d78e 100644 --- a/src/events/blank_cursor.h +++ b/src/events/blank_cursor.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/events/default_cursor.h b/src/events/default_cursor.h index 3eecf6c..95ea8ec 100644 --- a/src/events/default_cursor.h +++ b/src/events/default_cursor.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/events/scancodes_ascii.h b/src/events/scancodes_ascii.h index a4a0ecc..0e28b54 100644 --- a/src/events/scancodes_ascii.h +++ b/src/events/scancodes_ascii.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/events/scancodes_darwin.h b/src/events/scancodes_darwin.h index de23de4..6564bc0 100644 --- a/src/events/scancodes_darwin.h +++ b/src/events/scancodes_darwin.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/events/scancodes_linux.h b/src/events/scancodes_linux.h index 03d84a9..f505db1 100644 --- a/src/events/scancodes_linux.h +++ b/src/events/scancodes_linux.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/events/scancodes_windows.h b/src/events/scancodes_windows.h index e902e76..84a3713 100644 --- a/src/events/scancodes_windows.h +++ b/src/events/scancodes_windows.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/events/scancodes_xfree86.h b/src/events/scancodes_xfree86.h index 20d02fe..e751cb4 100644 --- a/src/events/scancodes_xfree86.h +++ b/src/events/scancodes_xfree86.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/file/SDL_rwops.c b/src/file/SDL_rwops.c index 439f20a..0cf3bfa 100644 --- a/src/file/SDL_rwops.c +++ b/src/file/SDL_rwops.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -36,9 +36,9 @@ #ifdef HAVE_STDIO_H #include +#include #include #endif - #ifdef HAVE_LIMITS_H #include #endif @@ -525,16 +525,17 @@ static int SDLCALL mem_close(SDL_RWops *context) /* Functions to create SDL_RWops structures from various data sources */ #if defined(HAVE_STDIO_H) && !(defined(__WIN32__) || defined(__GDK__)) -static SDL_bool SDL_IsRegularFile(FILE *f) +static SDL_bool IsRegularFileOrPipe(FILE *f) { #ifdef __WINRT__ struct __stat64 st; - if (_fstat64(_fileno(f), &st) < 0 || (st.st_mode & _S_IFMT) != _S_IFREG) { + if (_fstat64(_fileno(f), &st) < 0 || + !((st.st_mode & _S_IFMT) == _S_IFREG || (st.st_mode & _S_IFMT) == _S_IFIFO)) { return SDL_FALSE; } #else struct stat st; - if (fstat(fileno(f), &st) < 0 || !S_ISREG(st.st_mode)) { + if (fstat(fileno(f), &st) < 0 || !(S_ISREG(st.st_mode) || S_ISFIFO(st.st_mode))) { return SDL_FALSE; } #endif @@ -555,9 +556,9 @@ SDL_RWops *SDL_RWFromFile(const char *file, const char *mode) if (*file == '/') { FILE *fp = fopen(file, mode); if (fp) { - if (!SDL_IsRegularFile(fp)) { + if (!IsRegularFileOrPipe(fp)) { fclose(fp); - SDL_SetError("%s is not a regular file", file); + SDL_SetError("%s is not a regular file or pipe", file); return NULL; } return SDL_RWFromFP(fp, 1); @@ -575,9 +576,9 @@ SDL_RWops *SDL_RWFromFile(const char *file, const char *mode) fp = fopen(path, mode); SDL_stack_free(path); if (fp) { - if (!SDL_IsRegularFile(fp)) { + if (!IsRegularFileOrPipe(fp)) { fclose(fp); - SDL_SetError("%s is not a regular file", path); + SDL_SetError("%s is not a regular file or pipe", path); return NULL; } return SDL_RWFromFP(fp, 1); @@ -632,11 +633,11 @@ SDL_RWops *SDL_RWFromFile(const char *file, const char *mode) FILE *fp = fopen(file, mode); #endif if (!fp) { - SDL_SetError("Couldn't open %s", file); - } else if (!SDL_IsRegularFile(fp)) { + SDL_SetError("Couldn't open %s: %s", file, strerror(errno)); + } else if (!IsRegularFileOrPipe(fp)) { fclose(fp); fp = NULL; - SDL_SetError("%s is not a regular file", file); + SDL_SetError("%s is not a regular file or pipe", file); } else { rwops = SDL_RWFromFP(fp, SDL_TRUE); } diff --git a/src/file/cocoa/SDL_rwopsbundlesupport.h b/src/file/cocoa/SDL_rwopsbundlesupport.h index c57ce45..2cb9331 100644 --- a/src/file/cocoa/SDL_rwopsbundlesupport.h +++ b/src/file/cocoa/SDL_rwopsbundlesupport.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/file/cocoa/SDL_rwopsbundlesupport.m b/src/file/cocoa/SDL_rwopsbundlesupport.m index 1fdce06..5920e60 100644 --- a/src/file/cocoa/SDL_rwopsbundlesupport.m +++ b/src/file/cocoa/SDL_rwopsbundlesupport.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/file/n3ds/SDL_rwopsromfs.c b/src/file/n3ds/SDL_rwopsromfs.c index 9ca81a1..72ab031 100644 --- a/src/file/n3ds/SDL_rwopsromfs.c +++ b/src/file/n3ds/SDL_rwopsromfs.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/file/n3ds/SDL_rwopsromfs.h b/src/file/n3ds/SDL_rwopsromfs.h index 1ec1567..7ff212f 100644 --- a/src/file/n3ds/SDL_rwopsromfs.h +++ b/src/file/n3ds/SDL_rwopsromfs.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/filesystem/android/SDL_sysfilesystem.c b/src/filesystem/android/SDL_sysfilesystem.c index 5e37298..a2296a4 100644 --- a/src/filesystem/android/SDL_sysfilesystem.c +++ b/src/filesystem/android/SDL_sysfilesystem.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/filesystem/cocoa/SDL_sysfilesystem.m b/src/filesystem/cocoa/SDL_sysfilesystem.m index 3d48ef6..f3fce9c 100644 --- a/src/filesystem/cocoa/SDL_sysfilesystem.m +++ b/src/filesystem/cocoa/SDL_sysfilesystem.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/filesystem/dummy/SDL_sysfilesystem.c b/src/filesystem/dummy/SDL_sysfilesystem.c index 0243cce..aa09063 100644 --- a/src/filesystem/dummy/SDL_sysfilesystem.c +++ b/src/filesystem/dummy/SDL_sysfilesystem.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/filesystem/emscripten/SDL_sysfilesystem.c b/src/filesystem/emscripten/SDL_sysfilesystem.c index 3163972..6d40e24 100644 --- a/src/filesystem/emscripten/SDL_sysfilesystem.c +++ b/src/filesystem/emscripten/SDL_sysfilesystem.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/filesystem/gdk/SDL_sysfilesystem.cpp b/src/filesystem/gdk/SDL_sysfilesystem.cpp index 601d352..202f02b 100644 --- a/src/filesystem/gdk/SDL_sysfilesystem.cpp +++ b/src/filesystem/gdk/SDL_sysfilesystem.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,6 @@ */ #include "../../SDL_internal.h" -#ifdef SDL_FILESYSTEM_XBOX /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* System dependent filesystem routines */ @@ -135,6 +134,5 @@ SDL_GetPrefPath(const char *org, const char *app) return folderPath; } -#endif /* SDL_FILESYSTEM_XBOX */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/filesystem/haiku/SDL_sysfilesystem.cc b/src/filesystem/haiku/SDL_sysfilesystem.cc index 5585c48..921b339 100644 --- a/src/filesystem/haiku/SDL_sysfilesystem.cc +++ b/src/filesystem/haiku/SDL_sysfilesystem.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/filesystem/n3ds/SDL_sysfilesystem.c b/src/filesystem/n3ds/SDL_sysfilesystem.c index fe46076..5fbbd51 100644 --- a/src/filesystem/n3ds/SDL_sysfilesystem.c +++ b/src/filesystem/n3ds/SDL_sysfilesystem.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/filesystem/nacl/SDL_sysfilesystem.c b/src/filesystem/nacl/SDL_sysfilesystem.c index 1ef34dd..8d5faa9 100644 --- a/src/filesystem/nacl/SDL_sysfilesystem.c +++ b/src/filesystem/nacl/SDL_sysfilesystem.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/filesystem/os2/SDL_sysfilesystem.c b/src/filesystem/os2/SDL_sysfilesystem.c index 4e9597f..99fda9e 100644 --- a/src/filesystem/os2/SDL_sysfilesystem.c +++ b/src/filesystem/os2/SDL_sysfilesystem.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/filesystem/ps2/SDL_sysfilesystem.c b/src/filesystem/ps2/SDL_sysfilesystem.c index 6b64466..d00edf9 100644 --- a/src/filesystem/ps2/SDL_sysfilesystem.c +++ b/src/filesystem/ps2/SDL_sysfilesystem.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/filesystem/psp/SDL_sysfilesystem.c b/src/filesystem/psp/SDL_sysfilesystem.c index 7ed87e0..392399e 100644 --- a/src/filesystem/psp/SDL_sysfilesystem.c +++ b/src/filesystem/psp/SDL_sysfilesystem.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/filesystem/riscos/SDL_sysfilesystem.c b/src/filesystem/riscos/SDL_sysfilesystem.c index 4617895..e0ac080 100644 --- a/src/filesystem/riscos/SDL_sysfilesystem.c +++ b/src/filesystem/riscos/SDL_sysfilesystem.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/filesystem/unix/SDL_sysfilesystem.c b/src/filesystem/unix/SDL_sysfilesystem.c index c69a991..3f7533c 100644 --- a/src/filesystem/unix/SDL_sysfilesystem.c +++ b/src/filesystem/unix/SDL_sysfilesystem.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/filesystem/vita/SDL_sysfilesystem.c b/src/filesystem/vita/SDL_sysfilesystem.c index eb7e159..0ae693f 100644 --- a/src/filesystem/vita/SDL_sysfilesystem.c +++ b/src/filesystem/vita/SDL_sysfilesystem.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/filesystem/windows/SDL_sysfilesystem.c b/src/filesystem/windows/SDL_sysfilesystem.c index a653291..c8aea90 100644 --- a/src/filesystem/windows/SDL_sysfilesystem.c +++ b/src/filesystem/windows/SDL_sysfilesystem.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/filesystem/winrt/SDL_sysfilesystem.cpp b/src/filesystem/winrt/SDL_sysfilesystem.cpp index 85cfd19..bdd7688 100644 --- a/src/filesystem/winrt/SDL_sysfilesystem.cpp +++ b/src/filesystem/winrt/SDL_sysfilesystem.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/haptic/SDL_haptic.c b/src/haptic/SDL_haptic.c index 256d667..349eb63 100644 --- a/src/haptic/SDL_haptic.c +++ b/src/haptic/SDL_haptic.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/haptic/SDL_haptic_c.h b/src/haptic/SDL_haptic_c.h index a1b1ed7..44107a6 100644 --- a/src/haptic/SDL_haptic_c.h +++ b/src/haptic/SDL_haptic_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/haptic/SDL_syshaptic.h b/src/haptic/SDL_syshaptic.h index 31f37dd..8f8abda 100644 --- a/src/haptic/SDL_syshaptic.h +++ b/src/haptic/SDL_syshaptic.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/haptic/android/SDL_syshaptic.c b/src/haptic/android/SDL_syshaptic.c index 15fbdd2..b3cbf01 100644 --- a/src/haptic/android/SDL_syshaptic.c +++ b/src/haptic/android/SDL_syshaptic.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/haptic/darwin/SDL_syshaptic.c b/src/haptic/darwin/SDL_syshaptic.c index d33e4d6..3ef5666 100644 --- a/src/haptic/darwin/SDL_syshaptic.c +++ b/src/haptic/darwin/SDL_syshaptic.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/haptic/darwin/SDL_syshaptic_c.h b/src/haptic/darwin/SDL_syshaptic_c.h index 49b54bb..dfa1f95 100644 --- a/src/haptic/darwin/SDL_syshaptic_c.h +++ b/src/haptic/darwin/SDL_syshaptic_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/haptic/dummy/SDL_syshaptic.c b/src/haptic/dummy/SDL_syshaptic.c index 861aa6e..d8cdb0e 100644 --- a/src/haptic/dummy/SDL_syshaptic.c +++ b/src/haptic/dummy/SDL_syshaptic.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/haptic/linux/SDL_syshaptic.c b/src/haptic/linux/SDL_syshaptic.c index a21c118..548bb2d 100644 --- a/src/haptic/linux/SDL_syshaptic.c +++ b/src/haptic/linux/SDL_syshaptic.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/haptic/windows/SDL_dinputhaptic.c b/src/haptic/windows/SDL_dinputhaptic.c index 2214915..04d91ce 100644 --- a/src/haptic/windows/SDL_dinputhaptic.c +++ b/src/haptic/windows/SDL_dinputhaptic.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/haptic/windows/SDL_dinputhaptic_c.h b/src/haptic/windows/SDL_dinputhaptic_c.h index b84fd71..bdf64f9 100644 --- a/src/haptic/windows/SDL_dinputhaptic_c.h +++ b/src/haptic/windows/SDL_dinputhaptic_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/haptic/windows/SDL_windowshaptic.c b/src/haptic/windows/SDL_windowshaptic.c index 1992a06..4d7e662 100644 --- a/src/haptic/windows/SDL_windowshaptic.c +++ b/src/haptic/windows/SDL_windowshaptic.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/haptic/windows/SDL_windowshaptic_c.h b/src/haptic/windows/SDL_windowshaptic_c.h index e5d45d5..5217c28 100644 --- a/src/haptic/windows/SDL_windowshaptic_c.h +++ b/src/haptic/windows/SDL_windowshaptic_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/haptic/windows/SDL_xinputhaptic.c b/src/haptic/windows/SDL_xinputhaptic.c index 0066412..0704a08 100644 --- a/src/haptic/windows/SDL_xinputhaptic.c +++ b/src/haptic/windows/SDL_xinputhaptic.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/haptic/windows/SDL_xinputhaptic_c.h b/src/haptic/windows/SDL_xinputhaptic_c.h index 071d3e4..a011b35 100644 --- a/src/haptic/windows/SDL_xinputhaptic_c.h +++ b/src/haptic/windows/SDL_xinputhaptic_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/hidapi/SDL_hidapi.c b/src/hidapi/SDL_hidapi.c index 6ed1eb6..61413c3 100644 --- a/src/hidapi/SDL_hidapi.c +++ b/src/hidapi/SDL_hidapi.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -877,6 +877,41 @@ static int SDL_libusb_get_string_descriptor(libusb_device_handle *dev, #undef make_path #undef read_thread +/* If the platform has any backend other than libusb, try to avoid using + * libusb as the main backend for devices, since it detaches drivers and + * therefore makes devices inaccessible to the rest of the OS. + * + * We do this by whitelisting devices we know to be accessible _exclusively_ + * via libusb; these are typically devices that look like HIDs but have a + * quirk that requires direct access to the hardware. + */ +static const struct { + Uint16 vendor; + Uint16 product; +} SDL_libusb_whitelist[] = { + { 0x057e, 0x0337 } /* Nintendo WUP-028, Wii U/Switch GameCube Adapter */ +}; + +static SDL_bool +IsInWhitelist(Uint16 vendor, Uint16 product) +{ + int i; + for (i = 0; i < SDL_arraysize(SDL_libusb_whitelist); i += 1) { + if (vendor == SDL_libusb_whitelist[i].vendor && + product == SDL_libusb_whitelist[i].product) { + return SDL_TRUE; + } + } + return SDL_FALSE; +} + +#if defined(HAVE_PLATFORM_BACKEND) || HAVE_DRIVER_BACKEND + #define use_libusb_whitelist_default SDL_TRUE +#else + #define use_libusb_whitelist_default SDL_FALSE +#endif /* HAVE_PLATFORM_BACKEND || HAVE_DRIVER_BACKEND */ +static SDL_bool use_libusb_whitelist = use_libusb_whitelist_default; + #endif /* HAVE_LIBUSB */ #endif /* !SDL_HIDAPI_DISABLED */ @@ -1062,6 +1097,8 @@ int SDL_hid_init(void) #endif #ifdef HAVE_LIBUSB + use_libusb_whitelist = SDL_GetHintBoolean("SDL_HIDAPI_LIBUSB_WHITELIST", + use_libusb_whitelist_default); if (SDL_getenv("SDL_HIDAPI_DISABLE_LIBUSB") != NULL) { SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, "libusb disabled by SDL_HIDAPI_DISABLE_LIBUSB"); @@ -1238,6 +1275,16 @@ struct SDL_hid_device_info *SDL_hid_enumerate(unsigned short vendor_id, unsigned SDL_Log("libusb devices found:"); #endif for (usb_dev = usb_devs; usb_dev; usb_dev = usb_dev->next) { + if (use_libusb_whitelist) { + if (!IsInWhitelist(usb_dev->vendor_id, usb_dev->product_id)) { +#ifdef DEBUG_HIDAPI + SDL_Log("Device was not in libusb whitelist: %ls %ls 0x%.4hx 0x%.4hx", + usb_dev->manufacturer_string, usb_dev->product_string, + usb_dev->vendor_id, usb_dev->product_id); +#endif /* DEBUG_HIDAPI */ + continue; + } + } new_dev = (struct SDL_hid_device_info *)SDL_malloc(sizeof(struct SDL_hid_device_info)); if (new_dev == NULL) { LIBUSB_hid_free_enumeration(usb_devs); diff --git a/src/hidapi/SDL_hidapi_c.h b/src/hidapi/SDL_hidapi_c.h index 51fe013..06a75d3 100644 --- a/src/hidapi/SDL_hidapi_c.h +++ b/src/hidapi/SDL_hidapi_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/hidapi/android/jni/Android.mk b/src/hidapi/android/jni/Android.mk new file mode 100644 index 0000000..4462e88 --- /dev/null +++ b/src/hidapi/android/jni/Android.mk @@ -0,0 +1,16 @@ +LOCAL_PATH:= $(call my-dir) + +HIDAPI_ROOT_REL:= ../.. +HIDAPI_ROOT_ABS:= $(LOCAL_PATH)/../.. + +include $(CLEAR_VARS) + +LOCAL_CPPFLAGS += -std=c++11 + +LOCAL_SRC_FILES := \ + $(HIDAPI_ROOT_REL)/android/hid.cpp + +LOCAL_MODULE := libhidapi +LOCAL_LDLIBS := -llog + +include $(BUILD_SHARED_LIBRARY) diff --git a/src/hidapi/ios/hid.m b/src/hidapi/ios/hid.m index 636d0f0..72879f2 100644 --- a/src/hidapi/ios/hid.m +++ b/src/hidapi/ios/hid.m @@ -290,6 +290,8 @@ - (int)updateConnectedSteamControllers:(BOOL) bForce { static uint64_t s_unLastUpdateTick = 0; static mach_timebase_info_data_t s_timebase_info; + uint64_t ticksNow; + NSArray *peripherals; if ( self.centralManager == nil ) { @@ -301,7 +303,7 @@ - (int)updateConnectedSteamControllers:(BOOL) bForce mach_timebase_info( &s_timebase_info ); } - uint64_t ticksNow = mach_approximate_time(); + ticksNow = mach_approximate_time(); if ( !bForce && ( ( (ticksNow - s_unLastUpdateTick) * s_timebase_info.numer ) / s_timebase_info.denom ) < (5ull * NSEC_PER_SEC) ) return (int)self.deviceMap.count; @@ -318,7 +320,7 @@ - (int)updateConnectedSteamControllers:(BOOL) bForce if ( self.nPendingPairs > 0 ) return (int)self.deviceMap.count; - NSArray *peripherals = [self.centralManager retrieveConnectedPeripheralsWithServices: @[ [CBUUID UUIDWithString:@"180A"]]]; + peripherals = [self.centralManager retrieveConnectedPeripheralsWithServices: @[ [CBUUID UUIDWithString:@"180A"]]]; for ( CBPeripheral *peripheral in peripherals ) { // we already know this peripheral @@ -328,8 +330,9 @@ - (int)updateConnectedSteamControllers:(BOOL) bForce NSLog( @"connected peripheral: %@", peripheral ); if ( [peripheral.name isEqualToString:@"SteamController"] ) { + HIDBLEDevice *steamController; self.nPendingPairs += 1; - HIDBLEDevice *steamController = [[HIDBLEDevice alloc] initWithPeripheral:peripheral]; + steamController = [[HIDBLEDevice alloc] initWithPeripheral:peripheral]; [self.deviceMap setObject:steamController forKey:peripheral]; [self.centralManager connectPeripheral:peripheral options:nil]; } @@ -452,9 +455,10 @@ - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeri if ( [localName isEqualToString:@"SteamController"] ) { + HIDBLEDevice *steamController; NSLog( @"%@ : %@ - %@", log, peripheral, advertisementData ); self.nPendingPairs += 1; - HIDBLEDevice *steamController = [[HIDBLEDevice alloc] initWithPeripheral:peripheral]; + steamController = [[HIDBLEDevice alloc] initWithPeripheral:peripheral]; [self.deviceMap setObject:steamController forKey:peripheral]; [self.centralManager connectPeripheral:peripheral options:nil]; } @@ -851,11 +855,13 @@ int HID_API_EXPORT hid_set_nonblocking(hid_device *dev, int nonblock) if ( ( vendor_id == 0 || vendor_id == VALVE_USB_VID ) && ( product_id == 0 || product_id == D0G_BLE2_PID ) ) { + NSEnumerator *devices; HIDBLEManager *bleManager = HIDBLEManager.sharedInstance; [bleManager updateConnectedSteamControllers:false]; - NSEnumerator *devices = [bleManager.deviceMap objectEnumerator]; + devices = [bleManager.deviceMap objectEnumerator]; for ( HIDBLEDevice *device in devices ) { + struct hid_device_info *device_info; // there are several brief windows in connecting to an already paired device and // one long window waiting for users to confirm pairing where we don't want // to consider a device ready - if we hand it back to SDL or another @@ -873,7 +879,7 @@ int HID_API_EXPORT hid_set_nonblocking(hid_device *dev, int nonblock) } continue; } - struct hid_device_info *device_info = (struct hid_device_info *)malloc( sizeof(struct hid_device_info) ); + device_info = (struct hid_device_info *)malloc( sizeof(struct hid_device_info) ); memset( device_info, 0, sizeof(struct hid_device_info) ); device_info->next = root; root = device_info; @@ -947,12 +953,13 @@ int HID_API_EXPORT hid_send_feature_report(hid_device *dev, const unsigned char int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length) { + size_t written; HIDBLEDevice *device_handle = (__bridge HIDBLEDevice *)dev->device_handle; if ( !device_handle.connected ) return -1; - size_t written = [device_handle get_feature_report:data[0] into:data]; + written = [device_handle get_feature_report:data[0] into:data]; return written == length-1 ? (int)length : (int)written; } @@ -969,6 +976,7 @@ int HID_API_EXPORT hid_read(hid_device *dev, unsigned char *data, size_t length) int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds) { + int result; HIDBLEDevice *device_handle = (__bridge HIDBLEDevice *)dev->device_handle; if ( !device_handle.connected ) @@ -978,7 +986,7 @@ int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t { NSLog( @"hid_read_timeout with non-zero wait" ); } - int result = (int)[device_handle read_input_report:data]; + result = (int)[device_handle read_input_report:data]; #if FEATURE_REPORT_LOGGING NSLog( @"HIDBLE:hid_read_timeout (%d) [%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x]", result, data[1], data[2], data[3], data[4], data[5], data[6], diff --git a/src/hidapi/libusb/hid.c b/src/hidapi/libusb/hid.c index 008131b..2485bbf 100644 --- a/src/hidapi/libusb/hid.c +++ b/src/hidapi/libusb/hid.c @@ -519,7 +519,7 @@ static struct usb_string_cache_entry *usb_string_cache = NULL; static size_t usb_string_cache_size = 0; static size_t usb_string_cache_insert_pos = 0; -static int usb_string_cache_grow() +static int usb_string_cache_grow(void) { struct usb_string_cache_entry *new_cache; size_t allocSize; @@ -537,7 +537,7 @@ static int usb_string_cache_grow() return 0; } -static void usb_string_cache_destroy() +static void usb_string_cache_destroy(void) { size_t i; for (i = 0; i < usb_string_cache_insert_pos; i++) { @@ -715,6 +715,7 @@ static int is_xboxone(unsigned short vendor_id, const struct libusb_interface_de 0x044f, /* Thrustmaster */ 0x045e, /* Microsoft */ 0x0738, /* Mad Catz */ + 0x0b05, /* ASUS */ 0x0e6f, /* PDP */ 0x0f0d, /* Hori */ 0x10f5, /* Turtle Beach */ diff --git a/src/hidapi/mac/hid.c b/src/hidapi/mac/hid.c index bbb5c62..0dbe422 100644 --- a/src/hidapi/mac/hid.c +++ b/src/hidapi/mac/hid.c @@ -504,7 +504,7 @@ int HID_API_EXPORT hid_exit(void) return 0; } -static void process_pending_events() { +static void process_pending_events(void) { SInt32 res; do { res = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.001, FALSE); diff --git a/src/hidapi/windows/hid.c b/src/hidapi/windows/hid.c index 3d8a230..54843d4 100644 --- a/src/hidapi/windows/hid.c +++ b/src/hidapi/windows/hid.c @@ -264,7 +264,7 @@ static void register_error(hid_device *device, const char *op) } #ifndef HIDAPI_USE_DDK -static int lookup_functions() +static int lookup_functions(void) { lib_handle = LoadLibrary(TEXT("hid.dll")); if (lib_handle) { diff --git a/src/joystick/SDL_gamecontroller.c b/src/joystick/SDL_gamecontroller.c index bce36ab..7a1eabf 100644 --- a/src/joystick/SDL_gamecontroller.c +++ b/src/joystick/SDL_gamecontroller.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -555,7 +555,7 @@ static ControllerMapping_t *SDL_CreateMappingForHIDAPIController(SDL_JoystickGUI SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,righttrigger:a5,start:b6,x:b2,y:b3,misc1:b15,", sizeof(mapping_string)); break; case k_eSwitchDeviceInfoControllerType_SEGA_Genesis: - SDL_strlcat(mapping_string, "a:b0,b:b1,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,rightshoulder:b10,righttrigger:a5,start:b6,misc1:b15,", sizeof(mapping_string)); + SDL_strlcat(mapping_string, "a:b0,b:b1,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,rightshoulder:b10,righttrigger:a5,start:b6,x:b2,y:b3,misc1:b15,", sizeof(mapping_string)); break; case k_eWiiExtensionControllerType_None: SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,start:b6,x:b2,y:b3,", sizeof(mapping_string)); @@ -688,16 +688,14 @@ static ControllerMapping_t *SDL_CreateMappingForWGIController(SDL_JoystickGUID g /* * Helper function to scan the mappings database for a controller with the specified GUID */ -static ControllerMapping_t *SDL_PrivateMatchControllerMappingForGUID(SDL_JoystickGUID guid, SDL_bool match_crc, SDL_bool match_version) +static ControllerMapping_t *SDL_PrivateMatchControllerMappingForGUID(SDL_JoystickGUID guid, SDL_bool match_version, SDL_bool exact_match_crc) { - ControllerMapping_t *mapping; + ControllerMapping_t *mapping, *best_match = NULL; Uint16 crc = 0; SDL_AssertJoysticksLocked(); - if (match_crc) { - SDL_GetJoystickGUIDInfo(guid, NULL, NULL, NULL, &crc); - } + SDL_GetJoystickGUIDInfo(guid, NULL, NULL, NULL, &crc); /* Clear the CRC from the GUID for matching, the mappings never include it in the GUID */ SDL_SetJoystickGUIDCRC(&guid, 0); @@ -719,20 +717,27 @@ static ControllerMapping_t *SDL_PrivateMatchControllerMappingForGUID(SDL_Joystic } if (SDL_memcmp(&guid, &mapping_guid, sizeof(guid)) == 0) { - Uint16 mapping_crc = 0; + const char *crc_string = SDL_strstr(mapping->mapping, SDL_CONTROLLER_CRC_FIELD); + if (crc_string) { + Uint16 mapping_crc = (Uint16)SDL_strtol(crc_string + SDL_CONTROLLER_CRC_FIELD_SIZE, NULL, 16); - if (match_crc) { - const char *crc_string = SDL_strstr(mapping->mapping, SDL_CONTROLLER_CRC_FIELD); - if (crc_string) { - mapping_crc = (Uint16)SDL_strtol(crc_string + SDL_CONTROLLER_CRC_FIELD_SIZE, NULL, 16); + if (mapping_crc != crc) { + /* This mapping specified a CRC and they don't match */ + continue; } - } - if (crc == mapping_crc) { + + /* An exact match, including CRC */ return mapping; + } else if (crc && exact_match_crc) { + return NULL; + } + + if (!best_match) { + best_match = mapping; } } } - return NULL; + return best_match; } /* @@ -741,19 +746,8 @@ static ControllerMapping_t *SDL_PrivateMatchControllerMappingForGUID(SDL_Joystic static ControllerMapping_t *SDL_PrivateGetControllerMappingForGUID(SDL_JoystickGUID guid, SDL_bool adding_mapping) { ControllerMapping_t *mapping; - Uint16 vendor, product, crc; - - SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL, &crc); - if (crc) { - /* First check for exact CRC matching */ - mapping = SDL_PrivateMatchControllerMappingForGUID(guid, SDL_TRUE, SDL_TRUE); - if (mapping) { - return mapping; - } - } - /* Now check for a mapping without CRC */ - mapping = SDL_PrivateMatchControllerMappingForGUID(guid, SDL_FALSE, SDL_TRUE); + mapping = SDL_PrivateMatchControllerMappingForGUID(guid, SDL_TRUE, adding_mapping); if (mapping) { return mapping; } @@ -767,13 +761,6 @@ static ControllerMapping_t *SDL_PrivateGetControllerMappingForGUID(SDL_JoystickG if (SDL_JoystickGUIDUsesVersion(guid)) { /* Try again, ignoring the version */ - if (crc) { - mapping = SDL_PrivateMatchControllerMappingForGUID(guid, SDL_TRUE, SDL_FALSE); - if (mapping) { - return mapping; - } - } - mapping = SDL_PrivateMatchControllerMappingForGUID(guid, SDL_FALSE, SDL_FALSE); if (mapping) { return mapping; @@ -1391,9 +1378,6 @@ static ControllerMapping_t *SDL_PrivateGetControllerMappingForNameAndGUID(const } #endif /* __LINUX__ */ - if (!mapping) { - mapping = s_pDefaultMapping; - } return mapping; } @@ -1506,6 +1490,9 @@ static ControllerMapping_t *SDL_PrivateGetControllerMapping(int device_index) } } + if (!mapping) { + mapping = s_pDefaultMapping; + } return mapping; } @@ -2059,7 +2046,7 @@ SDL_bool SDL_IsGameControllerNameAndGUID(const char *name, SDL_JoystickGUID guid SDL_LockJoysticks(); { - if (SDL_PrivateGetControllerMappingForNameAndGUID(name, guid) != NULL) { + if (s_pDefaultMapping || SDL_PrivateGetControllerMappingForNameAndGUID(name, guid) != NULL) { retval = SDL_TRUE; } else { retval = SDL_FALSE; @@ -2137,28 +2124,10 @@ SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid) return SDL_TRUE; } - if (SDL_allowed_controllers.num_included_entries == 0 && - SDL_ignored_controllers.num_included_entries == 0) { - return SDL_FALSE; - } - SDL_GetJoystickGUIDInfo(guid, &vendor, &product, &version, NULL); - if (SDL_GetHintBoolean("SDL_GAMECONTROLLER_ALLOW_STEAM_VIRTUAL_GAMEPAD", SDL_FALSE)) { - /* We shouldn't ignore Steam's virtual gamepad since it's using the hints to filter out the real controllers so it can remap input for the virtual controller */ - /* https://partner.steamgames.com/doc/features/steam_controller/steam_input_gamepad_emulation_bestpractices */ - SDL_bool bSteamVirtualGamepad = SDL_FALSE; -#if defined(__LINUX__) - bSteamVirtualGamepad = (vendor == USB_VENDOR_VALVE && product == USB_PRODUCT_STEAM_VIRTUAL_GAMEPAD); -#elif defined(__MACOSX__) - bSteamVirtualGamepad = (vendor == USB_VENDOR_MICROSOFT && product == USB_PRODUCT_XBOX360_WIRED_CONTROLLER && version == 1); -#elif defined(__WIN32__) - /* We can't tell on Windows, but Steam will block others in input hooks */ - bSteamVirtualGamepad = SDL_TRUE; -#endif - if (bSteamVirtualGamepad) { - return SDL_FALSE; - } + if (SDL_IsJoystickSteamVirtualGamepad(vendor, product, version)) { + return !SDL_GetHintBoolean("SDL_GAMECONTROLLER_ALLOW_STEAM_VIRTUAL_GAMEPAD", SDL_FALSE); } if (SDL_allowed_controllers.num_included_entries > 0) { @@ -2396,23 +2365,19 @@ Uint8 SDL_GameControllerGetButton(SDL_GameController *gamecontroller, SDL_GameCo if (binding->input.axis.axis_min < binding->input.axis.axis_max) { valid_input_range = (value >= binding->input.axis.axis_min && value <= binding->input.axis.axis_max); if (valid_input_range) { - retval = (value >= threshold) ? SDL_PRESSED : SDL_RELEASED; - break; + retval |= (value >= threshold) ? SDL_PRESSED : SDL_RELEASED; } } else { valid_input_range = (value >= binding->input.axis.axis_max && value <= binding->input.axis.axis_min); if (valid_input_range) { - retval = (value <= threshold) ? SDL_PRESSED : SDL_RELEASED; - break; + retval |= (value <= threshold) ? SDL_PRESSED : SDL_RELEASED; } } } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_BUTTON) { - retval = SDL_JoystickGetButton(gamecontroller->joystick, binding->input.button); - break; + retval |= SDL_JoystickGetButton(gamecontroller->joystick, binding->input.button); } else if (binding->inputType == SDL_CONTROLLER_BINDTYPE_HAT) { int hat_mask = SDL_JoystickGetHat(gamecontroller->joystick, binding->input.hat.hat); - retval = (hat_mask & binding->input.hat.hat_mask) ? SDL_PRESSED : SDL_RELEASED; - break; + retval |= (hat_mask & binding->input.hat.hat_mask) ? SDL_PRESSED : SDL_RELEASED; } } } @@ -3259,10 +3224,11 @@ const char *SDL_GameControllerGetAppleSFSymbolsNameForButton(SDL_GameController } SDL_UnlockJoysticks(); - return retval; -#else - return NULL; + if (retval && *retval) { + return retval; + } #endif + return NULL; } const char *SDL_GameControllerGetAppleSFSymbolsNameForAxis(SDL_GameController *gamecontroller, SDL_GameControllerAxis axis) @@ -3279,10 +3245,11 @@ const char *SDL_GameControllerGetAppleSFSymbolsNameForAxis(SDL_GameController *g } SDL_UnlockJoysticks(); - return retval; -#else - return NULL; + if (retval && *retval) { + return retval; + } #endif + return NULL; } /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/joystick/SDL_gamecontrollerdb.h b/src/joystick/SDL_gamecontrollerdb.h index 4f20d03..5f8a143 100644 --- a/src/joystick/SDL_gamecontrollerdb.h +++ b/src/joystick/SDL_gamecontrollerdb.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -125,6 +125,7 @@ static const char *s_ControllerMappings[] = { "03000000260900008888000000000000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a4,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,", "03000000a306000022f6000000000000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,", "03000000451300000830000000000000,Defender Game Racer X7,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,", + "03000000790000000600000000000000,Defender Joystick Cobra R4,crc:c77a,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,", "03000000791d00000103000000000000,Dual Box WII,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,", "03000000bd12000002e0000000000000,Dual USB Vibration Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a3,righty:a2,start:b11,x:b3,y:b0,", "030000006f0e00003001000000000000,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,", @@ -303,6 +304,7 @@ static const char *s_ControllerMappings[] = { "030000006f0e00002f01000000000000,Rock Candy 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,", "03000000341a00000208000000000000,SL-6555-SBK,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:-a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a3,righty:a2,start:b7,x:b2,y:b3,", "03000000341a00000908000000000000,SL-6566,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,", + "03000000790000000600000000000000,SPEEDLINK STRIKE Gamepad,crc:5811,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:a4,start:b9,x:b3,y:b0,", "03000000790000001c18000000000000,STK-7024X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,", "03000000ff1100003133000000000000,SVEN X-PAD,a:b2,b:b3,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a4,start:b5,x:b0,y:b1,", "03000000457500002211000000000000,SZMY-POWER PC 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:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", @@ -317,10 +319,12 @@ static const char *s_ControllerMappings[] = { "03000000a30600002106000000000000,Saitek PS1000,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:a4,start:b9,x:b0,y:b3,", "03000000a306000020f6000000000000,Saitek PS2700,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:a4,start:b9,x:b0,y:b3,", "03000000300f00001101000000000000,Saitek Rumble Pad,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,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,", + "03000000790000000600000000000000,Sanwa Supply JY-P76USV,crc:20f0,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,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b2,y:b3,", "0300000000050000289b000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,", "030000009b2800000500000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,", "030000008f0e00000800000000000000,SpeedLink Strike FX,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,", "03000000c01100000591000000000000,Speedlink Torid,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,", + "030000004c0500006802000000000000,SplitFish Game Controller,crc:5628,a:b0,b:b16,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,leftshoulder:b17,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b10,", "03000000de280000ff11000000000000,Steam Virtual Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:+a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:-a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "03000000110100003114000000000000,SteelSeries Stratus Duo,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,", "03000000381000001814000000000000,SteelSeries Stratus XL,a:b0,b:b1,back:b18,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b19,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b2,y:b3,", @@ -769,6 +773,8 @@ static const char *s_ControllerMappings[] = { "03000000300f00001211000011010000,QanBa Arcade JoyStick,a:b2,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b9,x:b1,y:b3,", "03000000222c00000225000011010000,Qanba Dragon Arcade Joystick (PS3),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,", "03000000222c00000025000011010000,Qanba Dragon Arcade Joystick (PS4),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,", + "03000000222c00001220000011010000,Qanba Drone 2 Arcade Joystick (PS4),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:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", + "03000000222c00001020000011010000,Qanba Drone 2 Arcade Joystick (PS5),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:a5,start:b9,x:b0,y:b3,", "03000000222c00000020000011010000,Qanba Drone Arcade Joystick (PS4),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,rightshoulder:b5,righttrigger:a4,start:b9,x:b0,y:b3,", "03000000222c00000223000011010000,Qanba Obsidian Arcade Joystick (PS3),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,", "03000000222c00000023000011010000,Qanba Obsidian Arcade Joystick (PS4),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,", @@ -858,7 +864,6 @@ static const char *s_ControllerMappings[] = { "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,", "03000000120c0000101e000011010000,ZEROPLUS P4 Wired 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,", "03000000666600006706000000010000,boom PSX to PC Converter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,", - "030000000d0f00000d00000000010000,hori,a:b0,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,leftx:b4,lefty:b5,rightshoulder:b7,start:b9,x:b1,y:b2,", "03000000830500006020000010010000,iBuffalo SNES Controller,a:b0,b:b1,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b2,y:b3,hint:SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,", "03000000830500006020000010010000,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,", "050000006964726f69643a636f6e0000,idroid:con,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,", @@ -920,7 +925,7 @@ static const char *s_ControllerMappings[] = { "050000004c050000c4050000ffff3f00,PS4 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", "050000004c050000cc090000fffe3f80,PS4 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:a3,rightx:a4,righty:a5,start:b16,x:b0,y:b2,", "050000004c050000cc090000ffff3f00,PS4 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", - "050000004c050000e60c0000fffe3f80,PS5 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:a3,rightx:a4,righty:a5,start:b16,x:b0,y:b2,", + "050000004c050000e60c0000fffe3f80,PS5 Controller,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:a3,rightx:a4,righty:a5,start:b16,x:b2,y:b17,", "050000004c050000e60c0000ffff3f00,PS5 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", "05000000f8270000bf0b0000ffff3f00,Razer Kishi,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", "050000003215000005070000ffff3f00,Razer Raiju Mobile,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index b0915af..e968288 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -293,6 +293,7 @@ static Uint32 initial_flightstick_devices[] = { MAKE_VIDPID(0x046d, 0xc215), /* Logitech Extreme 3D */ MAKE_VIDPID(0x231d, 0x0126), /* Gunfighter Mk.III ‘Space Combat Edition’ (right) */ MAKE_VIDPID(0x231d, 0x0127), /* Gunfighter Mk.III ‘Space Combat Edition’ (left) */ + MAKE_VIDPID(0x362c, 0x0001), /* Yawman Arrow */ }; static SDL_vidpid_list flightstick_devices = { SDL_HINT_JOYSTICK_FLIGHTSTICK_DEVICES, 0, 0, NULL, @@ -369,7 +370,11 @@ static Uint32 initial_wheel_devices[] = { MAKE_VIDPID(0x044f, 0xb65e), /* Thrustmaster T500RS */ MAKE_VIDPID(0x044f, 0xb664), /* Thrustmaster TX (initial mode) */ MAKE_VIDPID(0x044f, 0xb669), /* Thrustmaster TX (active mode) */ + MAKE_VIDPID(0x044f, 0xb67f), /* Thrustmaster TMX */ + MAKE_VIDPID(0x044f, 0xb691), /* Thrustmaster TS-XW (initial mode) */ + MAKE_VIDPID(0x044f, 0xb692), /* Thrustmaster TS-XW (active mode) */ MAKE_VIDPID(0x0483, 0x0522), /* Simagic Wheelbase (including M10, Alpha Mini, Alpha, Alpha U) */ + MAKE_VIDPID(0x0483, 0xa355), /* VRS DirectForce Pro Wheel Base */ 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) */ @@ -381,10 +386,22 @@ static Uint32 initial_wheel_devices[] = { 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) */ + MAKE_VIDPID(0x1209, 0xffb0), /* Generic FFBoard OpenFFBoard universal forcefeedback wheel */ + MAKE_VIDPID(0x16d0, 0x0d5a), /* Simucube 1 Wheelbase */ + MAKE_VIDPID(0x16d0, 0x0d5f), /* Simucube 2 Ultimate Wheelbase */ + MAKE_VIDPID(0x16d0, 0x0d60), /* Simucube 2 Pro Wheelbase */ + MAKE_VIDPID(0x16d0, 0x0d61), /* Simucube 2 Sport Wheelbase */ MAKE_VIDPID(0x2433, 0xf300), /* Asetek SimSports Invicta Wheelbase */ MAKE_VIDPID(0x2433, 0xf301), /* Asetek SimSports Forte Wheelbase */ MAKE_VIDPID(0x2433, 0xf303), /* Asetek SimSports La Prima Wheelbase */ MAKE_VIDPID(0x2433, 0xf306), /* Asetek SimSports Tony Kannan Wheelbase */ + MAKE_VIDPID(0x3416, 0x0301), /* Cammus C5 Wheelbase */ + MAKE_VIDPID(0x3416, 0x0302), /* Cammus C12 Wheelbase */ + MAKE_VIDPID(0x346e, 0x0000), /* Moza R16/R21 Wheelbase */ + MAKE_VIDPID(0x346e, 0x0002), /* Moza R9 Wheelbase */ + MAKE_VIDPID(0x346e, 0x0004), /* Moza R5 Wheelbase */ + MAKE_VIDPID(0x346e, 0x0005), /* Moza R3 Wheelbase */ + MAKE_VIDPID(0x346e, 0x0006), /* Moza R12 Wheelbase */ }; static SDL_vidpid_list wheel_devices = { SDL_HINT_JOYSTICK_WHEEL_DEVICES, 0, 0, NULL, @@ -1312,13 +1329,15 @@ const char *SDL_JoystickName(SDL_Joystick *joystick) const SDL_SteamVirtualGamepadInfo *info; SDL_LockJoysticks(); - info = SDL_GetJoystickInstanceVirtualGamepadInfo(joystick->instance_id); - if (info) { - retval = info->name; - } else { + { CHECK_JOYSTICK_MAGIC(joystick, NULL); - retval = joystick->name; + info = SDL_GetJoystickInstanceVirtualGamepadInfo(joystick->instance_id); + if (info) { + retval = info->name; + } else { + retval = joystick->name; + } } SDL_UnlockJoysticks(); @@ -1395,9 +1414,13 @@ int SDL_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint retval = 0; } else { retval = joystick->driver->Rumble(joystick, low_frequency_rumble, high_frequency_rumble); - joystick->rumble_resend = SDL_GetTicks() + SDL_RUMBLE_RESEND_MS; - if (!joystick->rumble_resend) { - joystick->rumble_resend = 1; + if (retval == 0) { + joystick->rumble_resend = SDL_GetTicks() + SDL_RUMBLE_RESEND_MS; + if (joystick->rumble_resend == 0) { + joystick->rumble_resend = 1; + } + } else { + joystick->rumble_resend = 0; } } @@ -2160,12 +2183,14 @@ void SDL_JoystickUpdate(void) #endif /* SDL_JOYSTICK_HIDAPI */ for (joystick = SDL_joysticks; joystick; joystick = joystick->next) { - if (joystick->attached) { - joystick->driver->Update(joystick); + if (!joystick->attached) { + continue; + } - if (joystick->delayed_guide_button) { - SDL_GameControllerHandleDelayedGuideButton(joystick); - } + joystick->driver->Update(joystick); + + if (joystick->delayed_guide_button) { + SDL_GameControllerHandleDelayedGuideButton(joystick); } now = SDL_GetTicks(); @@ -2203,7 +2228,7 @@ void SDL_JoystickUpdate(void) int SDL_JoystickEventState(int state) { #ifdef SDL_EVENTS_DISABLED - return SDL_DISABLE; + return SDL_IGNORE; #else const Uint32 event_list[] = { SDL_JOYAXISMOTION, SDL_JOYBALLMOTION, SDL_JOYHATMOTION, @@ -2470,7 +2495,7 @@ SDL_JoystickGUID SDL_CreateJoystickGUID(Uint16 bus, Uint16 vendor, Uint16 produc *guid16++ = SDL_SwapLE16(bus); *guid16++ = SDL_SwapLE16(crc); - if (vendor && product) { + if (vendor) { *guid16++ = SDL_SwapLE16(vendor); *guid16++ = 0; *guid16++ = SDL_SwapLE16(product); @@ -2486,7 +2511,9 @@ SDL_JoystickGUID SDL_CreateJoystickGUID(Uint16 bus, Uint16 vendor, Uint16 produc guid.data[14] = driver_signature; guid.data[15] = driver_data; } - SDL_strlcpy((char *)guid16, product_name, available_space); + if (product_name) { + SDL_strlcpy((char *)guid16, product_name, available_space); + } } return guid; } @@ -2731,6 +2758,11 @@ SDL_bool SDL_IsJoystickXboxSeriesX(Uint16 vendor_id, Uint16 product_id) return SDL_TRUE; } } + if (vendor_id == USB_VENDOR_ASUS) { + if (product_id == USB_PRODUCT_ROG_RAIKIRI) { + return SDL_TRUE; + } + } return SDL_FALSE; } @@ -2813,6 +2845,15 @@ SDL_bool SDL_IsJoystickNintendoSwitchJoyConPair(Uint16 vendor_id, Uint16 product return vendor_id == USB_VENDOR_NINTENDO && product_id == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_PAIR; } +SDL_bool SDL_IsJoystickSteamVirtualGamepad(Uint16 vendor_id, Uint16 product_id, Uint16 version) +{ +#ifdef __MACOSX__ + return (vendor_id == USB_VENDOR_MICROSOFT && product_id == USB_PRODUCT_XBOX360_WIRED_CONTROLLER && version == 0); +#else + return (vendor_id == USB_VENDOR_VALVE && product_id == USB_PRODUCT_STEAM_VIRTUAL_GAMEPAD); +#endif +} + SDL_bool SDL_IsJoystickSteamController(Uint16 vendor_id, Uint16 product_id) { EControllerType eType = GuessControllerType(vendor_id, product_id); @@ -3101,13 +3142,17 @@ Uint16 SDL_JoystickGetVendor(SDL_Joystick *joystick) const SDL_SteamVirtualGamepadInfo *info; SDL_LockJoysticks(); - info = SDL_GetJoystickInstanceVirtualGamepadInfo(joystick->instance_id); - if (info) { - vendor = info->vendor_id; - } else { - SDL_JoystickGUID guid = SDL_JoystickGetGUID(joystick); + { + CHECK_JOYSTICK_MAGIC(joystick, 0); - SDL_GetJoystickGUIDInfo(guid, &vendor, NULL, NULL, NULL); + info = SDL_GetJoystickInstanceVirtualGamepadInfo(joystick->instance_id); + if (info) { + vendor = info->vendor_id; + } else { + SDL_JoystickGUID guid = SDL_JoystickGetGUID(joystick); + + SDL_GetJoystickGUIDInfo(guid, &vendor, NULL, NULL, NULL); + } } SDL_UnlockJoysticks(); @@ -3120,13 +3165,17 @@ Uint16 SDL_JoystickGetProduct(SDL_Joystick *joystick) const SDL_SteamVirtualGamepadInfo *info; SDL_LockJoysticks(); - info = SDL_GetJoystickInstanceVirtualGamepadInfo(joystick->instance_id); - if (info) { - product = info->product_id; - } else { - SDL_JoystickGUID guid = SDL_JoystickGetGUID(joystick); + { + CHECK_JOYSTICK_MAGIC(joystick, 0); - SDL_GetJoystickGUIDInfo(guid, NULL, &product, NULL, NULL); + info = SDL_GetJoystickInstanceVirtualGamepadInfo(joystick->instance_id); + if (info) { + product = info->product_id; + } else { + SDL_JoystickGUID guid = SDL_JoystickGetGUID(joystick); + + SDL_GetJoystickGUIDInfo(guid, NULL, &product, NULL, NULL); + } } SDL_UnlockJoysticks(); diff --git a/src/joystick/SDL_joystick_c.h b/src/joystick/SDL_joystick_c.h index 44d8e8c..3107d3f 100644 --- a/src/joystick/SDL_joystick_c.h +++ b/src/joystick/SDL_joystick_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -123,6 +123,9 @@ extern SDL_bool SDL_IsJoystickNintendoSwitchJoyConRight(Uint16 vendor_id, Uint16 extern SDL_bool SDL_IsJoystickNintendoSwitchJoyConGrip(Uint16 vendor_id, Uint16 product_id); extern SDL_bool SDL_IsJoystickNintendoSwitchJoyConPair(Uint16 vendor_id, Uint16 product_id); +/* Function to return whether a joystick is a Steam Virtual Gamepad */ +extern SDL_bool SDL_IsJoystickSteamVirtualGamepad(Uint16 vendor_id, Uint16 product_id, Uint16 version); + /* Function to return whether a joystick is a Steam Controller */ extern SDL_bool SDL_IsJoystickSteamController(Uint16 vendor_id, Uint16 product_id); diff --git a/src/joystick/SDL_steam_virtual_gamepad.c b/src/joystick/SDL_steam_virtual_gamepad.c index c382b99..403f7e7 100644 --- a/src/joystick/SDL_steam_virtual_gamepad.c +++ b/src/joystick/SDL_steam_virtual_gamepad.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -221,6 +221,7 @@ SDL_bool SDL_UpdateSteamVirtualGamepadInfo(void) if (slot >= 0) { AddVirtualGamepadInfo(slot, &info); } + SDL_free(info.name); SDL_free(data); SDL_steam_virtual_gamepad_info_file_mtime = mtime; diff --git a/src/joystick/SDL_steam_virtual_gamepad.h b/src/joystick/SDL_steam_virtual_gamepad.h index 415643b..8bdbeff 100644 --- a/src/joystick/SDL_steam_virtual_gamepad.h +++ b/src/joystick/SDL_steam_virtual_gamepad.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/joystick/SDL_sysjoystick.h b/src/joystick/SDL_sysjoystick.h index 173650e..cabb69a 100644 --- a/src/joystick/SDL_sysjoystick.h +++ b/src/joystick/SDL_sysjoystick.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/joystick/android/SDL_sysjoystick.c b/src/joystick/android/SDL_sysjoystick.c index c29f738..e0c228a 100644 --- a/src/joystick/android/SDL_sysjoystick.c +++ b/src/joystick/android/SDL_sysjoystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/joystick/android/SDL_sysjoystick_c.h b/src/joystick/android/SDL_sysjoystick_c.h index 189bcf4..e1eceab 100644 --- a/src/joystick/android/SDL_sysjoystick_c.h +++ b/src/joystick/android/SDL_sysjoystick_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/joystick/bsd/SDL_bsdjoystick.c b/src/joystick/bsd/SDL_bsdjoystick.c index 3886fbf..8a87d76 100644 --- a/src/joystick/bsd/SDL_bsdjoystick.c +++ b/src/joystick/bsd/SDL_bsdjoystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/joystick/controller_list.h b/src/joystick/controller_list.h index 15d3902..79446c5 100644 --- a/src/joystick/controller_list.h +++ b/src/joystick/controller_list.h @@ -24,6 +24,7 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x0079, 0x1844 ), k_eControllerType_PS3Controller, NULL }, // From SDL { MAKE_CONTROLLER_ID( 0x044f, 0xb315 ), k_eControllerType_PS3Controller, NULL }, // Firestorm Dual Analog 3 { MAKE_CONTROLLER_ID( 0x044f, 0xd007 ), k_eControllerType_PS3Controller, NULL }, // Thrustmaster wireless 3-1 + { MAKE_CONTROLLER_ID( 0x046d, 0xcad1 ), k_eControllerType_PS3Controller, NULL }, // Logitech Chillstream //{ MAKE_CONTROLLER_ID( 0x046d, 0xc24f ), k_eControllerType_PS3Controller, NULL }, // Logitech G29 (PS3) { MAKE_CONTROLLER_ID( 0x054c, 0x0268 ), k_eControllerType_PS3Controller, NULL }, // Sony PS3 Controller { MAKE_CONTROLLER_ID( 0x056e, 0x200f ), k_eControllerType_PS3Controller, NULL }, // From SDL @@ -68,7 +69,7 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x20d6, 0x576d ), k_eControllerType_PS3Controller, NULL }, // Power A PS3 { MAKE_CONTROLLER_ID( 0x20d6, 0xca6d ), k_eControllerType_PS3Controller, NULL }, // From SDL { MAKE_CONTROLLER_ID( 0x2563, 0x0523 ), k_eControllerType_PS3Controller, NULL }, // Digiflip GP006 - { MAKE_CONTROLLER_ID( 0x2563, 0x0575 ), k_eControllerType_PS3Controller, NULL }, // From SDL + { MAKE_CONTROLLER_ID( 0x2563, 0x0575 ), k_eControllerType_PS3Controller, "Retro-bit Controller" }, // SWITCH CO., LTD. Retro-bit Controller { MAKE_CONTROLLER_ID( 0x25f0, 0x83c3 ), k_eControllerType_PS3Controller, NULL }, // gioteck vx2 { MAKE_CONTROLLER_ID( 0x25f0, 0xc121 ), k_eControllerType_PS3Controller, NULL }, // { MAKE_CONTROLLER_ID( 0x2c22, 0x2003 ), k_eControllerType_PS3Controller, NULL }, // Qanba Drone @@ -157,6 +158,7 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x0f0d, 0x0184 ), k_eControllerType_PS5Controller, NULL }, // Hori Fighting Stick α { MAKE_CONTROLLER_ID( 0x1532, 0x100b ), k_eControllerType_PS5Controller, NULL }, // Razer Wolverine V2 Pro (Wired) { MAKE_CONTROLLER_ID( 0x1532, 0x100c ), k_eControllerType_PS5Controller, NULL }, // Razer Wolverine V2 Pro (Wireless) + { MAKE_CONTROLLER_ID( 0x1532, 0x1012 ), k_eControllerType_PS5Controller, NULL }, // Razer Kitsune { MAKE_CONTROLLER_ID( 0x3285, 0x0d18 ), k_eControllerType_PS5Controller, NULL }, // NACON Revolution 5 Pro (PS5 mode with dongle) { MAKE_CONTROLLER_ID( 0x3285, 0x0d19 ), k_eControllerType_PS5Controller, NULL }, // NACON Revolution 5 Pro (PS5 mode wired) { MAKE_CONTROLLER_ID( 0x358a, 0x0104 ), k_eControllerType_PS5Controller, NULL }, // Backbone One PlayStation Edition for iOS @@ -593,7 +595,7 @@ static const ControllerDescription_t arrControllers[] = { { MAKE_CONTROLLER_ID( 0x28de, 0x1102 ), k_eControllerType_SteamController, NULL }, // Valve wired Steam Controller (D0G) { MAKE_CONTROLLER_ID( 0x28de, 0x1105 ), k_eControllerType_SteamController, NULL }, // Valve Bluetooth Steam Controller (D0G) { MAKE_CONTROLLER_ID( 0x28de, 0x1106 ), k_eControllerType_SteamController, NULL }, // Valve Bluetooth Steam Controller (D0G) - { MAKE_CONTROLLER_ID( 0x28de, 0x11ff ), k_eControllerType_UnknownNonSteamController, "Steam Virtual Gamepad" }, // Steam virtual gamepad + { MAKE_CONTROLLER_ID( 0x28de, 0x11ff ), k_eControllerType_UnknownNonSteamController, NULL }, // Steam Virtual Gamepad { MAKE_CONTROLLER_ID( 0x28de, 0x1142 ), k_eControllerType_SteamController, NULL }, // Valve wireless Steam Controller { MAKE_CONTROLLER_ID( 0x28de, 0x1201 ), k_eControllerType_SteamControllerV2, NULL }, // Valve wired Steam Controller (HEADCRAB) { MAKE_CONTROLLER_ID( 0x28de, 0x1202 ), k_eControllerType_SteamControllerV2, NULL }, // Valve Bluetooth Steam Controller (HEADCRAB) diff --git a/src/joystick/darwin/SDL_iokitjoystick.c b/src/joystick/darwin/SDL_iokitjoystick.c index 493f816..8bb8d00 100644 --- a/src/joystick/darwin/SDL_iokitjoystick.c +++ b/src/joystick/darwin/SDL_iokitjoystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -477,6 +477,11 @@ static SDL_bool GetDeviceInfo(IOHIDDeviceRef hidDevice, recDevice *pDevice) CFNumberGetValue(refCF, kCFNumberSInt32Type, &version); } + if (SDL_IsJoystickXboxOne(vendor, product)) { + /* We can't actually use this API for Xbox controllers */ + return false; + } + /* get device name */ refCF = IOHIDDeviceGetProperty(hidDevice, CFSTR(kIOHIDManufacturerKey)); if ((!refCF) || (!CFStringGetCString(refCF, manufacturer_string, sizeof(manufacturer_string), kCFStringEncodingUTF8))) { diff --git a/src/joystick/darwin/SDL_iokitjoystick_c.h b/src/joystick/darwin/SDL_iokitjoystick_c.h index 095c083..e7b42ae 100644 --- a/src/joystick/darwin/SDL_iokitjoystick_c.h +++ b/src/joystick/darwin/SDL_iokitjoystick_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/joystick/dummy/SDL_sysjoystick.c b/src/joystick/dummy/SDL_sysjoystick.c index 1ade8e1..f2e2fc0 100644 --- a/src/joystick/dummy/SDL_sysjoystick.c +++ b/src/joystick/dummy/SDL_sysjoystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/joystick/emscripten/SDL_sysjoystick.c b/src/joystick/emscripten/SDL_sysjoystick.c index a2db803..02c450a 100644 --- a/src/joystick/emscripten/SDL_sysjoystick.c +++ b/src/joystick/emscripten/SDL_sysjoystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/joystick/emscripten/SDL_sysjoystick_c.h b/src/joystick/emscripten/SDL_sysjoystick_c.h index 6e9b649..10814cf 100644 --- a/src/joystick/emscripten/SDL_sysjoystick_c.h +++ b/src/joystick/emscripten/SDL_sysjoystick_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/joystick/haiku/SDL_haikujoystick.cc b/src/joystick/haiku/SDL_haikujoystick.cc index 5c31363..013bff0 100644 --- a/src/joystick/haiku/SDL_haikujoystick.cc +++ b/src/joystick/haiku/SDL_haikujoystick.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/joystick/hidapi/SDL_hidapi_combined.c b/src/joystick/hidapi/SDL_hidapi_combined.c index 94ab75c..25000f6 100644 --- a/src/joystick/hidapi/SDL_hidapi_combined.c +++ b/src/joystick/hidapi/SDL_hidapi_combined.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/joystick/hidapi/SDL_hidapi_gamecube.c b/src/joystick/hidapi/SDL_hidapi_gamecube.c index 53d40b9..db64518 100644 --- a/src/joystick/hidapi/SDL_hidapi_gamecube.c +++ b/src/joystick/hidapi/SDL_hidapi_gamecube.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/joystick/hidapi/SDL_hidapi_luna.c b/src/joystick/hidapi/SDL_hidapi_luna.c index e5557c5..811b0a6 100644 --- a/src/joystick/hidapi/SDL_hidapi_luna.c +++ b/src/joystick/hidapi/SDL_hidapi_luna.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/joystick/hidapi/SDL_hidapi_nintendo.h b/src/joystick/hidapi/SDL_hidapi_nintendo.h index bd8459a..4247828 100644 --- a/src/joystick/hidapi/SDL_hidapi_nintendo.h +++ b/src/joystick/hidapi/SDL_hidapi_nintendo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/joystick/hidapi/SDL_hidapi_ps3.c b/src/joystick/hidapi/SDL_hidapi_ps3.c index e9baf7e..61a242f 100644 --- a/src/joystick/hidapi/SDL_hidapi_ps3.c +++ b/src/joystick/hidapi/SDL_hidapi_ps3.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -50,6 +50,7 @@ typedef struct SDL_HIDAPI_Device *device; SDL_Joystick *joystick; SDL_bool is_shanwan; + SDL_bool has_analog_buttons; SDL_bool report_sensors; SDL_bool effects_updated; int player_index; @@ -145,6 +146,7 @@ static SDL_bool HIDAPI_DriverPS3_InitDevice(SDL_HIDAPI_Device *device) } ctx->device = device; ctx->is_shanwan = is_shanwan; + ctx->has_analog_buttons = SDL_TRUE; device->context = ctx; @@ -247,7 +249,10 @@ static SDL_bool HIDAPI_DriverPS3_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joy /* Initialize the joystick capabilities */ joystick->nbuttons = 15; - joystick->naxes = 16; + joystick->naxes = 6; + if (ctx->has_analog_buttons) { + joystick->naxes += 10; + } joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED; SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 100.0f); @@ -432,7 +437,7 @@ static void HIDAPI_DriverPS3_HandleStatePacket(SDL_Joystick *joystick, SDL_Drive SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis); /* Buttons are mapped as axes in the order they appear in the button enumeration */ - { + if (ctx->has_analog_buttons) { static int button_axis_offsets[] = { 24, /* SDL_CONTROLLER_BUTTON_A */ 23, /* SDL_CONTROLLER_BUTTON_B */ @@ -584,7 +589,13 @@ static SDL_bool HIDAPI_DriverPS3ThirdParty_IsSupportedDevice(SDL_HIDAPI_Device * Uint8 data[USB_PACKET_LENGTH]; int size; - if (HIDAPI_SupportsPlaystationDetection(vendor_id, product_id)) { + if (vendor_id == USB_VENDOR_LOGITECH && + product_id == USB_PRODUCT_LOGITECH_CHILLSTREAM) { + return SDL_TRUE; + } + + if ((type == SDL_CONTROLLER_TYPE_PS3 && vendor_id != USB_VENDOR_SONY) || + HIDAPI_SupportsPlaystationDetection(vendor_id, product_id)) { if (device && device->dev) { size = ReadFeatureReport(device->dev, 0x03, data, sizeof(data)); if (size == 8 && data[2] == 0x26) { @@ -611,6 +622,11 @@ static SDL_bool HIDAPI_DriverPS3ThirdParty_InitDevice(SDL_HIDAPI_Device *device) return SDL_FALSE; } ctx->device = device; + if (device->vendor_id == USB_VENDOR_SWITCH && device->product_id == USB_PRODUCT_SWITCH_RETROBIT_CONTROLLER) { + ctx->has_analog_buttons = SDL_FALSE; + } else { + ctx->has_analog_buttons = SDL_TRUE; + } device->context = ctx; @@ -644,8 +660,17 @@ static SDL_bool HIDAPI_DriverPS3ThirdParty_OpenJoystick(SDL_HIDAPI_Device *devic /* Initialize the joystick capabilities */ joystick->nbuttons = 15; - joystick->naxes = 16; - joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED; + joystick->naxes = 6; + if (ctx->has_analog_buttons) { + joystick->naxes += 10; + } + + if (device->vendor_id == USB_VENDOR_SWITCH && device->product_id == USB_PRODUCT_SWITCH_RETROBIT_CONTROLLER) { + // This is a wireless controller using a USB dongle + joystick->epowerlevel = SDL_JOYSTICK_POWER_UNKNOWN; + } else { + joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED; + } return SDL_TRUE; } @@ -756,7 +781,7 @@ static void HIDAPI_DriverPS3ThirdParty_HandleStatePacket18(SDL_Joystick *joystic SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis); /* Buttons are mapped as axes in the order they appear in the button enumeration */ - { + if (ctx->has_analog_buttons) { static int button_axis_offsets[] = { 12, /* SDL_GAMEPAD_BUTTON_A */ 11, /* SDL_GAMEPAD_BUTTON_B */ @@ -768,7 +793,7 @@ static void HIDAPI_DriverPS3ThirdParty_HandleStatePacket18(SDL_Joystick *joystic 0, /* SDL_GAMEPAD_BUTTON_LEFT_STICK */ 0, /* SDL_GAMEPAD_BUTTON_RIGHT_STICK */ 14, /* SDL_GAMEPAD_BUTTON_LEFT_SHOULDER */ - 16, /* SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER */ + 15, /* SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER */ 8, /* SDL_GAMEPAD_BUTTON_DPAD_UP */ 9, /* SDL_GAMEPAD_BUTTON_DPAD_DOWN */ 7, /* SDL_GAMEPAD_BUTTON_DPAD_LEFT */ @@ -813,53 +838,69 @@ static void HIDAPI_DriverPS3ThirdParty_HandleStatePacket19(SDL_Joystick *joystic SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[1] & 0x10) ? SDL_PRESSED : SDL_RELEASED); } - if (ctx->last_state[2] != data[2]) { - SDL_bool dpad_up = SDL_FALSE; - SDL_bool dpad_down = SDL_FALSE; - SDL_bool dpad_left = SDL_FALSE; - SDL_bool dpad_right = SDL_FALSE; - - switch (data[2] & 0x0f) { - case 0: - dpad_up = SDL_TRUE; - break; - case 1: - dpad_up = SDL_TRUE; - dpad_right = SDL_TRUE; - break; - case 2: - dpad_right = SDL_TRUE; - break; - case 3: - dpad_right = SDL_TRUE; - dpad_down = SDL_TRUE; - break; - case 4: - dpad_down = SDL_TRUE; - break; - case 5: - dpad_left = SDL_TRUE; - dpad_down = SDL_TRUE; - break; - case 6: - dpad_left = SDL_TRUE; - break; - case 7: - dpad_up = SDL_TRUE; - dpad_left = SDL_TRUE; - break; - default: - break; + if (ctx->device->vendor_id == USB_VENDOR_SAITEK && ctx->device->product_id == USB_PRODUCT_SAITEK_CYBORG_V3) { + /* Cyborg V.3 Rumble Pad doesn't set the dpad bits as expected, so use the axes instead */ + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, data[10] ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, data[9] ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, data[7] ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, data[8] ? SDL_PRESSED : SDL_RELEASED); + } else { + if (ctx->last_state[2] != data[2]) { + SDL_bool dpad_up = SDL_FALSE; + SDL_bool dpad_down = SDL_FALSE; + SDL_bool dpad_left = SDL_FALSE; + SDL_bool dpad_right = SDL_FALSE; + + switch (data[2] & 0x0f) { + case 0: + dpad_up = SDL_TRUE; + break; + case 1: + dpad_up = SDL_TRUE; + dpad_right = SDL_TRUE; + break; + case 2: + dpad_right = SDL_TRUE; + break; + case 3: + dpad_right = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 4: + dpad_down = SDL_TRUE; + break; + case 5: + dpad_left = SDL_TRUE; + dpad_down = SDL_TRUE; + break; + case 6: + dpad_left = SDL_TRUE; + break; + case 7: + dpad_up = SDL_TRUE; + dpad_left = SDL_TRUE; + break; + default: + break; + } + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, dpad_down); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, dpad_up); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, dpad_right); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, dpad_left); } - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, dpad_down); - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, dpad_up); - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, dpad_right); - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, dpad_left); } - axis = ((int)data[17] * 257) - 32768; + if (data[0] & 0x40) { + axis = 32767; + } else { + axis = ((int)data[17] * 257) - 32768; + } SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis); - axis = ((int)data[18] * 257) - 32768; + if (data[0] & 0x80) { + axis = 32767; + } else { + axis = ((int)data[18] * 257) - 32768; + } SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis); axis = ((int)data[3] * 257) - 32768; SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis); @@ -871,7 +912,7 @@ static void HIDAPI_DriverPS3ThirdParty_HandleStatePacket19(SDL_Joystick *joystic SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis); /* Buttons are mapped as axes in the order they appear in the button enumeration */ - { + if (ctx->has_analog_buttons) { static int button_axis_offsets[] = { 13, /* SDL_CONTROLLER_BUTTON_A */ 12, /* SDL_CONTROLLER_BUTTON_B */ diff --git a/src/joystick/hidapi/SDL_hidapi_ps4.c b/src/joystick/hidapi/SDL_hidapi_ps4.c index 565431d..3016964 100644 --- a/src/joystick/hidapi/SDL_hidapi_ps4.c +++ b/src/joystick/hidapi/SDL_hidapi_ps4.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -1208,6 +1208,7 @@ static SDL_bool HIDAPI_DriverPS4_UpdateDevice(SDL_HIDAPI_Device *device) if (SDL_TICKS_PASSED(now, ctx->last_packet + BLUETOOTH_DISCONNECT_TIMEOUT_MS)) { /* Send an empty output report to tickle the Bluetooth stack */ HIDAPI_DriverPS4_TickleBluetooth(device); + ctx->last_packet = now; } } else { /* Reconnect the Bluetooth device once the USB device is gone */ diff --git a/src/joystick/hidapi/SDL_hidapi_ps5.c b/src/joystick/hidapi/SDL_hidapi_ps5.c index afefa3d..5065fc5 100644 --- a/src/joystick/hidapi/SDL_hidapi_ps5.c +++ b/src/joystick/hidapi/SDL_hidapi_ps5.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -499,6 +499,12 @@ static SDL_bool HIDAPI_DriverPS5_InitDevice(SDL_HIDAPI_Device *device) ctx->sensors_supported = SDL_TRUE; ctx->touchpad_supported = SDL_TRUE; ctx->use_alternate_report = SDL_TRUE; + } else if (device->vendor_id == USB_VENDOR_RAZER && + device->product_id == USB_PRODUCT_RAZER_KITSUNE) { + /* The Razer Kitsune doesn't respond to the detection protocol, but has a touchpad */ + joystick_type = SDL_JOYSTICK_TYPE_ARCADE_STICK; + ctx->touchpad_supported = SDL_TRUE; + ctx->use_alternate_report = SDL_TRUE; } } ctx->effects_supported = (ctx->lightbar_supported || ctx->vibration_supported || ctx->playerled_supported); @@ -1494,6 +1500,7 @@ static SDL_bool HIDAPI_DriverPS5_UpdateDevice(SDL_HIDAPI_Device *device) if (SDL_TICKS_PASSED(now, ctx->last_packet + BLUETOOTH_DISCONNECT_TIMEOUT_MS)) { /* Send an empty output report to tickle the Bluetooth stack */ HIDAPI_DriverPS5_TickleBluetooth(device); + ctx->last_packet = now; } } else { /* Reconnect the Bluetooth device once the USB device is gone */ diff --git a/src/joystick/hidapi/SDL_hidapi_rumble.c b/src/joystick/hidapi/SDL_hidapi_rumble.c index 2bb166e..8cacc33 100644 --- a/src/joystick/hidapi/SDL_hidapi_rumble.c +++ b/src/joystick/hidapi/SDL_hidapi_rumble.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/joystick/hidapi/SDL_hidapi_rumble.h b/src/joystick/hidapi/SDL_hidapi_rumble.h index 918e08c..fa5158a 100644 --- a/src/joystick/hidapi/SDL_hidapi_rumble.h +++ b/src/joystick/hidapi/SDL_hidapi_rumble.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/joystick/hidapi/SDL_hidapi_shield.c b/src/joystick/hidapi/SDL_hidapi_shield.c index 63540e6..0507ca1 100644 --- a/src/joystick/hidapi/SDL_hidapi_shield.c +++ b/src/joystick/hidapi/SDL_hidapi_shield.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/joystick/hidapi/SDL_hidapi_stadia.c b/src/joystick/hidapi/SDL_hidapi_stadia.c index 0fc6d14..9c0307e 100644 --- a/src/joystick/hidapi/SDL_hidapi_stadia.c +++ b/src/joystick/hidapi/SDL_hidapi_stadia.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/joystick/hidapi/SDL_hidapi_steam.c b/src/joystick/hidapi/SDL_hidapi_steam.c index 9f9e0e3..9a712b0 100644 --- a/src/joystick/hidapi/SDL_hidapi_steam.c +++ b/src/joystick/hidapi/SDL_hidapi_steam.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/joystick/hidapi/SDL_hidapi_steamdeck.c b/src/joystick/hidapi/SDL_hidapi_steamdeck.c index c26b3e6..20554ed 100644 --- a/src/joystick/hidapi/SDL_hidapi_steamdeck.c +++ b/src/joystick/hidapi/SDL_hidapi_steamdeck.c @@ -134,6 +134,89 @@ static SDL_bool FeedDeckLizardWatchdog(SDL_hid_device *dev) return SDL_TRUE; } +static void HIDAPI_DriverSteamDeck_HandleState(SDL_HIDAPI_Device *device, + SDL_Joystick *joystick, + ValveInReport_t *pInReport) +{ + float values[3]; + SDL_DriverSteamDeck_Context *ctx = (SDL_DriverSteamDeck_Context *)device->context; + + if (pInReport->payload.deckState.ulButtons != ctx->last_button_state) { + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, + (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_A) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, + (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_B) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, + (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_X) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, + (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_Y) ? SDL_PRESSED : SDL_RELEASED); + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, + (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_L) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, + (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_R) ? SDL_PRESSED : SDL_RELEASED); + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, + (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_VIEW) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, + (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_MENU) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, + (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_STEAM) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1, + (pInReport->payload.deckState.ulButtonsH & STEAMDECK_HBUTTON_QAM) ? SDL_PRESSED : SDL_RELEASED); + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, + (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_L3) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, + (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_R3) ? SDL_PRESSED : SDL_RELEASED); + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_PADDLE1, + (pInReport->payload.deckState.ulButtonsH & STEAMDECK_HBUTTON_R4) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_PADDLE2, + (pInReport->payload.deckState.ulButtonsH & STEAMDECK_HBUTTON_L4) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_PADDLE3, + (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_R5) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_PADDLE4, + (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_L5) ? SDL_PRESSED : SDL_RELEASED); + + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, + (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_DPAD_UP) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, + (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_DPAD_DOWN) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, + (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_DPAD_LEFT) ? SDL_PRESSED : SDL_RELEASED); + SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, + (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_DPAD_RIGHT) ? SDL_PRESSED : SDL_RELEASED); + ctx->last_button_state = pInReport->payload.deckState.ulButtons; + } + + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, + (int)pInReport->payload.deckState.sTriggerRawL * 2 - 32768); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, + (int)pInReport->payload.deckState.sTriggerRawR * 2 - 32768); + + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, + pInReport->payload.deckState.sLeftStickX); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, + -pInReport->payload.deckState.sLeftStickY); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, + pInReport->payload.deckState.sRightStickX); + SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, + -pInReport->payload.deckState.sRightStickY); + + ctx->sensor_timestamp_us += ctx->update_rate_us; + + values[0] = (pInReport->payload.deckState.sGyroX / 32768.0f) * (2000.0f * ((float)M_PI / 180.0f)); + values[1] = (pInReport->payload.deckState.sGyroZ / 32768.0f) * (2000.0f * ((float)M_PI / 180.0f)); + values[2] = (-pInReport->payload.deckState.sGyroY / 32768.0f) * (2000.0f * ((float)M_PI / 180.0f)); + SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_GYRO, ctx->sensor_timestamp_us, values, 3); + + values[0] = (pInReport->payload.deckState.sAccelX / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY; + values[1] = (pInReport->payload.deckState.sAccelZ / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY; + values[2] = (-pInReport->payload.deckState.sAccelY / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY; + SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_ACCEL, ctx->sensor_timestamp_us, values, 3); +} + /*****************************************************************************************************/ static void HIDAPI_DriverSteamDeck_RegisterHints(SDL_HintCallback callback, void *userdata) @@ -179,8 +262,8 @@ static SDL_bool HIDAPI_DriverSteamDeck_InitDevice(SDL_HIDAPI_Device *device) return SDL_FALSE; } - // Always 1kHz according to USB descriptor - ctx->update_rate_us = 1000; + // Always 1kHz according to USB descriptor, but actually about 4 ms. + ctx->update_rate_us = 4000; device->context = ctx; @@ -214,7 +297,6 @@ static SDL_bool HIDAPI_DriverSteamDeck_UpdateDevice(SDL_HIDAPI_Device *device) SDL_Joystick *joystick = NULL; int r; uint8_t data[64]; - float values[3]; ValveInReport_t *pInReport = (ValveInReport_t *)data; if (device->num_joysticks > 0) { @@ -233,95 +315,21 @@ static SDL_bool HIDAPI_DriverSteamDeck_UpdateDevice(SDL_HIDAPI_Device *device) } SDL_memset(data, 0, sizeof(data)); - r = SDL_hid_read(device->dev, data, sizeof(data)); - if (r == 0) { - return SDL_FALSE; - } else if (r <= 0) { - /* Failed to read from controller */ - HIDAPI_JoystickDisconnected(device, device->joysticks[0]); - return SDL_FALSE; - } - - if (!(r == 64 && pInReport->header.unReportVersion == k_ValveInReportMsgVersion && pInReport->header.ucType == ID_CONTROLLER_DECK_STATE && pInReport->header.ucLength == 64)) { - return SDL_FALSE; - } - // Uint64 timestamp = SDL_GetTicksNS(); + do { + r = SDL_hid_read(device->dev, data, sizeof(data)); - if (pInReport->payload.deckState.ulButtons != ctx->last_button_state) { - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_A, - (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_A) ? SDL_PRESSED : SDL_RELEASED); - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_B, - (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_B) ? SDL_PRESSED : SDL_RELEASED); - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_X, - (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_X) ? SDL_PRESSED : SDL_RELEASED); - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_Y, - (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_Y) ? SDL_PRESSED : SDL_RELEASED); - - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, - (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_L) ? SDL_PRESSED : SDL_RELEASED); - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, - (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_R) ? SDL_PRESSED : SDL_RELEASED); - - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, - (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_VIEW) ? SDL_PRESSED : SDL_RELEASED); - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, - (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_MENU) ? SDL_PRESSED : SDL_RELEASED); - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, - (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_STEAM) ? SDL_PRESSED : SDL_RELEASED); - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1, - (pInReport->payload.deckState.ulButtonsH & STEAMDECK_HBUTTON_QAM) ? SDL_PRESSED : SDL_RELEASED); - - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_LEFTSTICK, - (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_L3) ? SDL_PRESSED : SDL_RELEASED); - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, - (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_R3) ? SDL_PRESSED : SDL_RELEASED); - - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_PADDLE1, - (pInReport->payload.deckState.ulButtonsH & STEAMDECK_HBUTTON_R4) ? SDL_PRESSED : SDL_RELEASED); - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_PADDLE2, - (pInReport->payload.deckState.ulButtonsH & STEAMDECK_HBUTTON_L4) ? SDL_PRESSED : SDL_RELEASED); - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_PADDLE3, - (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_R5) ? SDL_PRESSED : SDL_RELEASED); - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_PADDLE4, - (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_L5) ? SDL_PRESSED : SDL_RELEASED); - - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_UP, - (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_DPAD_UP) ? SDL_PRESSED : SDL_RELEASED); - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_DOWN, - (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_DPAD_DOWN) ? SDL_PRESSED : SDL_RELEASED); - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_LEFT, - (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_DPAD_LEFT) ? SDL_PRESSED : SDL_RELEASED); - SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, - (pInReport->payload.deckState.ulButtonsL & STEAMDECK_LBUTTON_DPAD_RIGHT) ? SDL_PRESSED : SDL_RELEASED); - ctx->last_button_state = pInReport->payload.deckState.ulButtons; - } - - SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, - (int)pInReport->payload.deckState.sTriggerRawL * 2 - 32768); - SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, - (int)pInReport->payload.deckState.sTriggerRawR * 2 - 32768); - - SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, - pInReport->payload.deckState.sLeftStickX); - SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, - -pInReport->payload.deckState.sLeftStickY); - SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, - pInReport->payload.deckState.sRightStickX); - SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, - -pInReport->payload.deckState.sRightStickY); - - ctx->sensor_timestamp_us += ctx->update_rate_us; - - values[0] = (pInReport->payload.deckState.sGyroX / 32768.0f) * (2000.0f * ((float)M_PI / 180.0f)); - values[1] = (pInReport->payload.deckState.sGyroZ / 32768.0f) * (2000.0f * ((float)M_PI / 180.0f)); - values[2] = (-pInReport->payload.deckState.sGyroY / 32768.0f) * (2000.0f * ((float)M_PI / 180.0f)); - SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_GYRO, ctx->sensor_timestamp_us, values, 3); - - values[0] = (pInReport->payload.deckState.sAccelX / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY; - values[1] = (pInReport->payload.deckState.sAccelZ / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY; - values[2] = (-pInReport->payload.deckState.sAccelY / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY; - SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_ACCEL, ctx->sensor_timestamp_us, values, 3); + if (r < 0) { + /* Failed to read from controller */ + HIDAPI_JoystickDisconnected(device, device->joysticks[0]); + return SDL_FALSE; + } else if (r == 64 && + pInReport->header.unReportVersion == k_ValveInReportMsgVersion && + pInReport->header.ucType == ID_CONTROLLER_DECK_STATE && + pInReport->header.ucLength == 64) { + HIDAPI_DriverSteamDeck_HandleState(device, joystick, pInReport); + } + } while (r > 0); return SDL_TRUE; } diff --git a/src/joystick/hidapi/SDL_hidapi_switch.c b/src/joystick/hidapi/SDL_hidapi_switch.c index 0e2257f..54c6d96 100644 --- a/src/joystick/hidapi/SDL_hidapi_switch.c +++ b/src/joystick/hidapi/SDL_hidapi_switch.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -332,12 +332,28 @@ typedef struct static int ReadInput(SDL_DriverSwitch_Context *ctx) { + int result; + /* Make sure we don't try to read at the same time a write is happening */ if (SDL_AtomicGet(&ctx->device->rumble_pending) > 0) { return 0; } - return SDL_hid_read_timeout(ctx->device->dev, ctx->m_rgucReadBuffer, sizeof(ctx->m_rgucReadBuffer), 0); + result = SDL_hid_read_timeout(ctx->device->dev, ctx->m_rgucReadBuffer, sizeof(ctx->m_rgucReadBuffer), 0); + + /* See if we can guess the initial input mode */ + if (result > 0 && !ctx->m_bInputOnly && !ctx->m_nInitialInputMode) { + switch (ctx->m_rgucReadBuffer[0]) { + case k_eSwitchInputReportIDs_FullControllerState: + case k_eSwitchInputReportIDs_FullControllerAndMcuState: + case k_eSwitchInputReportIDs_SimpleControllerState: + ctx->m_nInitialInputMode = ctx->m_rgucReadBuffer[0]; + break; + default: + break; + } + } + return result; } static int WriteOutput(SDL_DriverSwitch_Context *ctx, const Uint8 *data, int size) @@ -727,14 +743,12 @@ static void SDLCALL SDL_PlayerLEDHintChanged(void *userdata, const char *name, c } } -static Uint8 GetInitialInputMode(SDL_DriverSwitch_Context *ctx) +static void GetInitialInputMode(SDL_DriverSwitch_Context *ctx) { - Uint8 input_mode = 0; - - if (ReadInput(ctx) > 0) { - input_mode = ctx->m_rgucReadBuffer[0]; + if (!ctx->m_nInitialInputMode) { + /* This will set the initial input mode if it can */ + ReadInput(ctx); } - return input_mode; } static Uint8 GetDefaultInputMode(SDL_DriverSwitch_Context *ctx) @@ -758,7 +772,18 @@ static Uint8 GetDefaultInputMode(SDL_DriverSwitch_Context *ctx) * battery level over Bluetooth anyway. */ if (ctx->device->vendor_id == USB_VENDOR_NINTENDO) { + /* However, switching to full controller state breaks DirectInput, so let's not do that */ + #if 0 input_mode = k_eSwitchInputReportIDs_FullControllerState; + #endif + + /* However, Joy-Con controllers switch their thumbsticks into D-pad mode in simple mode, + * so let's enable full controller state for them. + */ + if (ctx->device->product_id == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_LEFT || + ctx->device->product_id == USB_PRODUCT_NINTENDO_SWITCH_JOYCON_RIGHT) { + input_mode = k_eSwitchInputReportIDs_FullControllerState; + } } return input_mode; } @@ -1292,6 +1317,27 @@ static void UpdateDeviceIdentity(SDL_HIDAPI_Device *device) break; case k_eSwitchDeviceInfoControllerType_Unknown: /* We couldn't read the device info for this controller, might not be fully compliant */ + if (device->vendor_id == USB_VENDOR_NINTENDO) { + switch (device->product_id) { + case USB_PRODUCT_NINTENDO_SWITCH_JOYCON_LEFT: + ctx->m_eControllerType = k_eSwitchDeviceInfoControllerType_JoyConLeft; + HIDAPI_SetDeviceName(device, "Nintendo Switch Joy-Con (L)"); + device->type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT; + break; + case USB_PRODUCT_NINTENDO_SWITCH_JOYCON_RIGHT: + ctx->m_eControllerType = k_eSwitchDeviceInfoControllerType_JoyConRight; + HIDAPI_SetDeviceName(device, "Nintendo Switch Joy-Con (R)"); + device->type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT; + break; + case USB_PRODUCT_NINTENDO_SWITCH_PRO: + ctx->m_eControllerType = k_eSwitchDeviceInfoControllerType_ProController; + HIDAPI_SetDeviceName(device, "Nintendo Switch Pro Controller"); + device->type = SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO; + break; + default: + break; + } + } return; default: device->type = SDL_CONTROLLER_TYPE_UNKNOWN; @@ -1380,7 +1426,7 @@ static SDL_bool HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_ ctx->m_bSyncWrite = SDL_TRUE; if (!ctx->m_bInputOnly) { - ctx->m_nInitialInputMode = GetInitialInputMode(ctx); + GetInitialInputMode(ctx); ctx->m_nCurrentInputMode = ctx->m_nInitialInputMode; /* Initialize rumble data */ @@ -2211,6 +2257,10 @@ static SDL_bool HIDAPI_DriverSwitch_UpdateDevice(SDL_HIDAPI_Device *device) continue; } + if (ctx->m_rgucReadBuffer[0] == k_eSwitchInputReportIDs_SubcommandReply) { + continue; + } + if (ctx->m_bInputOnly) { HandleInputOnlyControllerState(joystick, ctx, (SwitchInputOnlyControllerStatePacket_t *)&ctx->m_rgucReadBuffer[0]); } else { diff --git a/src/joystick/hidapi/SDL_hidapi_wii.c b/src/joystick/hidapi/SDL_hidapi_wii.c index 3b3d994..f28f2ab 100644 --- a/src/joystick/hidapi/SDL_hidapi_wii.c +++ b/src/joystick/hidapi/SDL_hidapi_wii.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/joystick/hidapi/SDL_hidapi_xbox360.c b/src/joystick/hidapi/SDL_hidapi_xbox360.c index 2917fff..189115e 100644 --- a/src/joystick/hidapi/SDL_hidapi_xbox360.c +++ b/src/joystick/hidapi/SDL_hidapi_xbox360.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -84,21 +84,16 @@ static SDL_bool HIDAPI_DriverXbox360_IsSupportedDevice(SDL_HIDAPI_Device *device /* This is the chatpad or other input interface, not the Xbox 360 interface */ return SDL_FALSE; } -#ifdef __MACOSX__ - if (vendor_id == USB_VENDOR_MICROSOFT && product_id == USB_PRODUCT_XBOX360_WIRED_CONTROLLER && version == 1) { - /* This is the Steam Virtual Gamepad, which isn't supported by this driver */ - return SDL_FALSE; - } - /* Wired Xbox One controllers are handled by this driver, interfacing with - the 360Controller driver available from: - https://github.com/360Controller/360Controller/releases - - Bluetooth Xbox One controllers are handled by the SDL Xbox One driver - */ - if (SDL_IsJoystickBluetoothXboxOne(vendor_id, product_id)) { +#if defined(__MACOSX__) && defined(SDL_JOYSTICK_MFI) + if (SDL_IsJoystickSteamVirtualGamepad(vendor_id, product_id, version)) { + /* GCController support doesn't work with the Steam Virtual Gamepad */ + return SDL_TRUE; + } else { + /* On macOS you can't write output reports to wired XBox controllers, + so we'll just use the GCController support instead. + */ return SDL_FALSE; } - return (type == SDL_CONTROLLER_TYPE_XBOX360 || type == SDL_CONTROLLER_TYPE_XBOXONE) ? SDL_TRUE : SDL_FALSE; #else return (type == SDL_CONTROLLER_TYPE_XBOX360) ? SDL_TRUE : SDL_FALSE; #endif @@ -153,6 +148,13 @@ static SDL_bool HIDAPI_DriverXbox360_InitDevice(SDL_HIDAPI_Device *device) device->type = SDL_CONTROLLER_TYPE_XBOX360; + if (SDL_IsJoystickSteamVirtualGamepad(device->vendor_id, device->product_id, device->version) && + device->product_string && SDL_strncmp(device->product_string, "GamePad-", 8) == 0) { + int slot = 0; + SDL_sscanf(device->product_string, "GamePad-%d", &slot); + device->steam_virtual_gamepad_slot = (slot - 1); + } + return HIDAPI_JoystickConnected(device, NULL); } @@ -201,30 +203,6 @@ static SDL_bool HIDAPI_DriverXbox360_OpenJoystick(SDL_HIDAPI_Device *device, SDL static int HIDAPI_DriverXbox360_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) { -#ifdef __MACOSX__ - if (SDL_IsJoystickBluetoothXboxOne(device->vendor_id, device->product_id)) { - Uint8 rumble_packet[] = { 0x03, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00 }; - - rumble_packet[4] = (low_frequency_rumble >> 8); - rumble_packet[5] = (high_frequency_rumble >> 8); - - if (SDL_HIDAPI_SendRumble(device, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) { - return SDL_SetError("Couldn't send rumble packet"); - } - } else { - /* On Mac OS X the 360Controller driver uses this short report, - and we need to prefix it with a magic token so hidapi passes it through untouched - */ - Uint8 rumble_packet[] = { 'M', 'A', 'G', 'I', 'C', '0', 0x00, 0x04, 0x00, 0x00 }; - - rumble_packet[6 + 2] = (low_frequency_rumble >> 8); - rumble_packet[6 + 3] = (high_frequency_rumble >> 8); - - if (SDL_HIDAPI_SendRumble(device, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) { - return SDL_SetError("Couldn't send rumble packet"); - } - } -#else Uint8 rumble_packet[] = { 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; rumble_packet[3] = (low_frequency_rumble >> 8); @@ -233,7 +211,6 @@ static int HIDAPI_DriverXbox360_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Jo if (SDL_HIDAPI_SendRumble(device, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) { return SDL_SetError("Couldn't send rumble packet"); } -#endif return 0; } diff --git a/src/joystick/hidapi/SDL_hidapi_xbox360w.c b/src/joystick/hidapi/SDL_hidapi_xbox360w.c index 9c44085..19798ab 100644 --- a/src/joystick/hidapi/SDL_hidapi_xbox360w.c +++ b/src/joystick/hidapi/SDL_hidapi_xbox360w.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/joystick/hidapi/SDL_hidapi_xboxone.c b/src/joystick/hidapi/SDL_hidapi_xboxone.c index 497234a..9ca02bf 100644 --- a/src/joystick/hidapi/SDL_hidapi_xboxone.c +++ b/src/joystick/hidapi/SDL_hidapi_xboxone.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -354,9 +354,12 @@ static SDL_bool HIDAPI_DriverXboxOne_IsEnabled(void) static SDL_bool HIDAPI_DriverXboxOne_IsSupportedDevice(SDL_HIDAPI_Device *device, const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol) { -#ifdef __MACOSX__ - /* Wired Xbox One controllers are handled by the 360Controller driver */ +#if defined(__MACOSX__) && defined(SDL_JOYSTICK_MFI) if (!SDL_IsJoystickBluetoothXboxOne(vendor_id, product_id)) { + /* On macOS we get a shortened version of the real report and + you can't write output reports for wired controllers, so + we'll just use the GCController support instead. + */ return SDL_FALSE; } #endif diff --git a/src/joystick/hidapi/SDL_hidapijoystick.c b/src/joystick/hidapi/SDL_hidapijoystick.c index 81453ee..a1cb9c4 100644 --- a/src/joystick/hidapi/SDL_hidapijoystick.c +++ b/src/joystick/hidapi/SDL_hidapijoystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -157,18 +157,18 @@ SDL_bool HIDAPI_SupportsPlaystationDetection(Uint16 vendor, Uint16 product) case USB_VENDOR_HORI: return SDL_TRUE; case USB_VENDOR_LOGITECH: - /* Most Logitech devices are fine with this, but there are a few exceptions */ - if (product == USB_PRODUCT_LOGITECH_F310) { - /* The Logitech F310 gamepad will lock up */ - return SDL_FALSE; - } - if (product == 0xc33f) { - /* The Logitech G815 keyboard will reset the LEDs */ + /* Most Logitech devices are not PlayStation controllers, and some of them + * lock up or reset when we send them the Sony third-party query feature + * report, so don't include that vendor here. Instead add devices as + * appropriate to controller_list.h + */ + return SDL_FALSE; + case USB_VENDOR_MADCATZ: + if (product == USB_PRODUCT_MADCATZ_SAITEK_SIDE_PANEL_CONTROL_DECK) { + /* This is not a Playstation compatible device */ return SDL_FALSE; } return SDL_TRUE; - case USB_VENDOR_MADCATZ: - return SDL_TRUE; case USB_VENDOR_MAYFLASH: return SDL_TRUE; case USB_VENDOR_NACON: @@ -183,10 +183,10 @@ SDL_bool HIDAPI_SupportsPlaystationDetection(Uint16 vendor, Uint16 product) case USB_VENDOR_QANBA: return SDL_TRUE; case USB_VENDOR_RAZER: - /* Most Razer devices are not game controllers, and some of them lock up - * or reset when we send them the Sony third-party query feature report, - * so don't include that vendor here. Instead add devices as appropriate - * to controller_type.c + /* Most Razer devices are not PlayStation controllers, and some of them + * lock up or reset when we send them the Sony third-party query feature + * report, so don't include that vendor here. Instead add devices as + * appropriate to controller_list.h * * Reference: https://github.com/libsdl-org/SDL/issues/6733 * https://github.com/libsdl-org/SDL/issues/6799 @@ -280,6 +280,7 @@ static SDL_GameControllerType SDL_GetJoystickGameControllerProtocol(const char * 0x044f, /* Thrustmaster */ 0x045e, /* Microsoft */ 0x0738, /* Mad Catz */ + 0x0b05, /* ASUS */ 0x0e6f, /* PDP */ 0x0f0d, /* Hori */ 0x10f5, /* Turtle Beach */ @@ -928,6 +929,7 @@ static SDL_HIDAPI_Device *HIDAPI_AddDevice(const struct SDL_hid_device_info *inf device->guid = SDL_CreateJoystickGUID(SDL_HARDWARE_BUS_USB, device->vendor_id, device->product_id, device->version, device->manufacturer_string, device->product_string, 'h', 0); device->joystick_type = SDL_JOYSTICK_TYPE_GAMECONTROLLER; device->type = SDL_GetJoystickGameControllerProtocol(device->name, device->vendor_id, device->product_id, device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol); + device->steam_virtual_gamepad_slot = -1; if (num_children > 0) { int i; @@ -1007,7 +1009,7 @@ static void HIDAPI_DelDevice(SDL_HIDAPI_Device *device) } } -static SDL_bool HIDAPI_CreateCombinedJoyCons() +static SDL_bool HIDAPI_CreateCombinedJoyCons(void) { SDL_HIDAPI_Device *device, *combined; SDL_HIDAPI_Device *joycons[2] = { NULL, NULL }; @@ -1379,6 +1381,12 @@ static const char *HIDAPI_JoystickGetDevicePath(int device_index) static int HIDAPI_JoystickGetDeviceSteamVirtualGamepadSlot(int device_index) { + SDL_HIDAPI_Device *device; + + device = HIDAPI_GetDeviceByIndex(device_index, NULL); + if (device) { + return device->steam_virtual_gamepad_slot; + } return -1; } diff --git a/src/joystick/hidapi/SDL_hidapijoystick_c.h b/src/joystick/hidapi/SDL_hidapijoystick_c.h index cd18730..a461515 100644 --- a/src/joystick/hidapi/SDL_hidapijoystick_c.h +++ b/src/joystick/hidapi/SDL_hidapijoystick_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -47,7 +47,14 @@ #define SDL_JOYSTICK_HIDAPI_SHIELD /* Whether HIDAPI is enabled by default */ +#if defined(__ANDROID__) || \ + defined(__IPHONEOS__) || \ + defined(__TVOS__) +/* On Android, HIDAPI prompts for permissions and acquires exclusive access to the device, and on Apple mobile platforms it doesn't do anything except for handling Bluetooth Steam Controllers, so we'll leave it off by default. */ +#define SDL_HIDAPI_DEFAULT SDL_FALSE +#else #define SDL_HIDAPI_DEFAULT SDL_TRUE +#endif /* The maximum size of a USB packet for HID devices */ #define USB_PACKET_LENGTH 64 @@ -76,6 +83,7 @@ typedef struct _SDL_HIDAPI_Device SDL_bool is_bluetooth; SDL_JoystickType joystick_type; SDL_GameControllerType type; + int steam_virtual_gamepad_slot; struct _SDL_HIDAPI_DeviceDriver *driver; void *context; diff --git a/src/joystick/iphoneos/SDL_mfijoystick.m b/src/joystick/iphoneos/SDL_mfijoystick.m index 5fac495..6ff8e0e 100644 --- a/src/joystick/iphoneos/SDL_mfijoystick.m +++ b/src/joystick/iphoneos/SDL_mfijoystick.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -247,6 +247,7 @@ static void CheckControllerSiriRemote(GCController *controller, int *is_siri_rem *is_siri_remote = 0; } +#ifdef ENABLE_PHYSICAL_INPUT_PROFILE static BOOL ElementAlreadyHandled(SDL_JoystickDeviceItem *device, NSString *element, NSDictionary *elements) { if ([element isEqualToString:@"Left Thumbstick Left"] || @@ -345,6 +346,7 @@ static BOOL ElementAlreadyHandled(SDL_JoystickDeviceItem *device, NSString *elem } return FALSE; } +#endif /* ENABLE_PHYSICAL_INPUT_PROFILE */ static BOOL IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controller) { @@ -378,6 +380,7 @@ static BOOL IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCControlle NSLog(@"Product name: %@\n", controller.vendorName); NSLog(@"Product category: %@\n", controller.productCategory); NSLog(@"Elements available:\n"); +#ifdef ENABLE_PHYSICAL_INPUT_PROFILE if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { NSDictionary *elements = controller.physicalInputProfile.elements; for (id key in controller.physicalInputProfile.buttons) { @@ -390,6 +393,7 @@ static BOOL IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCControlle NSLog(@"\tHat: %@\n", key); } } +#endif #endif device->is_xbox = IsControllerXbox(controller); @@ -402,7 +406,8 @@ static BOOL IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCControlle device->is_switch_joyconL = IsControllerSwitchJoyConL(controller); device->is_switch_joyconR = IsControllerSwitchJoyConR(controller); #ifdef SDL_JOYSTICK_HIDAPI - if ((device->is_xbox && HIDAPI_IsDeviceTypePresent(SDL_CONTROLLER_TYPE_XBOXONE)) || + if ((device->is_xbox && (HIDAPI_IsDeviceTypePresent(SDL_CONTROLLER_TYPE_XBOXONE) || + HIDAPI_IsDeviceTypePresent(SDL_CONTROLLER_TYPE_XBOX360))) || (device->is_ps4 && HIDAPI_IsDeviceTypePresent(SDL_CONTROLLER_TYPE_PS4)) || (device->is_ps5 && HIDAPI_IsDeviceTypePresent(SDL_CONTROLLER_TYPE_PS5)) || (device->is_switch_pro && HIDAPI_IsDeviceTypePresent(SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO)) || @@ -414,6 +419,10 @@ static BOOL IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCControlle return FALSE; } #endif + if (device->is_xbox && SDL_strncmp(name, "GamePad-", 8) == 0) { + /* This is a Steam Virtual Gamepad, which isn't supported by GCController */ + return FALSE; + } CheckControllerSiriRemote(controller, &device->is_siri_remote); if (device->is_siri_remote && !SDL_GetHintBoolean(SDL_HINT_TV_REMOTE_AS_JOYSTICK, SDL_TRUE)) { @@ -433,7 +442,7 @@ static BOOL IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCControlle device->has_xbox_share_button = TRUE; } } -#endif // ENABLE_PHYSICAL_INPUT_PROFILE +#endif /* ENABLE_PHYSICAL_INPUT_PROFILE */ if (device->is_backbone_one) { vendor = USB_VENDOR_BACKBONE; @@ -506,7 +515,7 @@ static BOOL IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCControlle NSDictionary *elements = controller.physicalInputProfile.elements; /* Provide both axes and analog buttons as SDL axes */ - device->axes = [[[elements allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)] + NSArray *axes = [[[elements allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)] filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id object, NSDictionary *bindings) { GCControllerElement *element; @@ -523,8 +532,7 @@ static BOOL IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCControlle } return NO; }]]; - device->naxes = (int)device->axes.count; - device->buttons = [[[elements allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)] + NSArray *buttons = [[[elements allKeys] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)] filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id object, NSDictionary *bindings) { GCControllerElement *element; @@ -538,7 +546,12 @@ static BOOL IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCControlle } return NO; }]]; - device->nbuttons = (int)device->buttons.count; + /* Explicitly retain the arrays because SDL_JoystickDeviceItem is a + * struct, and ARC doesn't work with structs. */ + device->naxes = (int)axes.count; + device->axes = (__bridge NSArray *)CFBridgingRetain(axes); + device->nbuttons = (int)buttons.count; + device->buttons = (__bridge NSArray *)CFBridgingRetain(buttons); subtype = 4; #ifdef DEBUG_CONTROLLER_PROFILE @@ -775,13 +788,20 @@ static void IOS_AddJoystickDevice(GCController *controller, SDL_bool acceleromet #ifdef SDL_JOYSTICK_MFI @autoreleasepool { + /* These were explicitly retained in the struct, so they should be explicitly released before freeing the struct. */ if (device->controller) { - /* The controller was explicitly retained in the struct, so it - * should be explicitly released before freeing the struct. */ GCController *controller = CFBridgingRelease((__bridge CFTypeRef)(device->controller)); controller.controllerPausedHandler = nil; device->controller = nil; } + if (device->axes) { + CFRelease((__bridge CFTypeRef)device->axes); + device->axes = nil; + } + if (device->buttons) { + CFRelease((__bridge CFTypeRef)device->buttons); + device->buttons = nil; + } } #endif /* SDL_JOYSTICK_MFI */ @@ -1109,7 +1129,7 @@ static void IOS_MFIJoystickUpdate(SDL_Joystick *joystick) Uint8 hatstate = SDL_HAT_CENTERED; int i; -#ifdef DEBUG_CONTROLLER_STATE +#if defined(DEBUG_CONTROLLER_STATE) && defined(ENABLE_PHYSICAL_INPUT_PROFILE) if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { if (controller.physicalInputProfile) { for (id key in controller.physicalInputProfile.buttons) { @@ -1136,6 +1156,7 @@ static void IOS_MFIJoystickUpdate(SDL_Joystick *joystick) } #endif /* DEBUG_CONTROLLER_STATE */ +#ifdef ENABLE_PHYSICAL_INPUT_PROFILE if (@available(macOS 10.16, iOS 14.0, tvOS 14.0, *)) { NSDictionary *elements = controller.physicalInputProfile.elements; NSDictionary *buttons = controller.physicalInputProfile.buttons; @@ -1162,7 +1183,9 @@ static void IOS_MFIJoystickUpdate(SDL_Joystick *joystick) } SDL_PrivateJoystickButton(joystick, button++, value); } - } else if (controller.extendedGamepad) { + } else +#endif + if (controller.extendedGamepad) { SDL_bool isstack; GCExtendedGamepad *gamepad = controller.extendedGamepad; @@ -1260,6 +1283,8 @@ static void IOS_MFIJoystickUpdate(SDL_Joystick *joystick) } #if TARGET_OS_TV else if (controller.microGamepad) { + Uint8 buttons[joystick->nbuttons]; + int button_count = 0; GCMicroGamepad *gamepad = controller.microGamepad; Sint16 axes[] = { @@ -1271,8 +1296,6 @@ static void IOS_MFIJoystickUpdate(SDL_Joystick *joystick) SDL_PrivateJoystickAxis(joystick, i, axes[i]); } - Uint8 buttons[joystick->nbuttons]; - int button_count = 0; buttons[button_count++] = gamepad.buttonA.isPressed; buttons[button_count++] = gamepad.buttonX.isPressed; buttons[button_count++] = (device->pause_button_pressed > 0); diff --git a/src/joystick/iphoneos/SDL_mfijoystick_c.h b/src/joystick/iphoneos/SDL_mfijoystick_c.h index bfb108b..8eee5e8 100644 --- a/src/joystick/iphoneos/SDL_mfijoystick_c.h +++ b/src/joystick/iphoneos/SDL_mfijoystick_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,7 +26,8 @@ #include "SDL_stdinc.h" #include "../SDL_sysjoystick.h" -#include +#import +#import @class GCController; @@ -59,8 +60,8 @@ typedef struct joystick_hwdata SDL_bool is_backbone_one; int is_siri_remote; - NSArray *axes; - NSArray *buttons; + NSArray __unsafe_unretained *axes; + NSArray __unsafe_unretained *buttons; SDL_bool has_dualshock_touchpad; SDL_bool has_xbox_paddles; diff --git a/src/joystick/linux/SDL_sysjoystick.c b/src/joystick/linux/SDL_sysjoystick.c index 39ddb75..889d87c 100644 --- a/src/joystick/linux/SDL_sysjoystick.c +++ b/src/joystick/linux/SDL_sysjoystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -273,7 +273,7 @@ static int GuessIsSensor(int fd) return 0; } -static int IsJoystick(const char *path, int fd, char **name_return, Uint16 *vendor_return, Uint16 *product_return, SDL_JoystickGUID *guid) +static int IsJoystick(const char *path, int *fd, char **name_return, Uint16 *vendor_return, Uint16 *product_return, SDL_JoystickGUID *guid) { struct input_id inpid; char *name; @@ -282,21 +282,32 @@ static int IsJoystick(const char *path, int fd, char **name_return, Uint16 *vend SDL_zero(inpid); #ifdef SDL_USE_LIBUDEV - SDL_UDEV_GetProductInfo(path, &inpid.vendor, &inpid.product, &inpid.version, &class); + /* Opening input devices can generate synchronous device I/O, so avoid it if we can */ + if (SDL_UDEV_GetProductInfo(path, &inpid.vendor, &inpid.product, &inpid.version, &class) && + !(class & SDL_UDEV_DEVICE_JOYSTICK)) { + return 0; + } #endif - if (ioctl(fd, JSIOCGNAME(sizeof(product_string)), product_string) <= 0) { - /* When udev is enabled we only get joystick devices here, so there's no need to test them */ - if (enumeration_method != ENUMERATION_LIBUDEV && - !(class & SDL_UDEV_DEVICE_JOYSTICK) && ( class || !GuessIsJoystick(fd))) { + + if (fd && *fd < 0) { + *fd = open(path, O_RDONLY | O_CLOEXEC, 0); + } + if (!fd || *fd < 0) { + return 0; + } + + if (ioctl(*fd, JSIOCGNAME(sizeof(product_string)), product_string) <= 0) { + /* When udev enumeration or classification, we only got joysticks here, so no need to test */ + if (enumeration_method != ENUMERATION_LIBUDEV && !class && !GuessIsJoystick(*fd)) { return 0; } /* Could have vendor and product already from udev, but should agree with evdev */ - if (ioctl(fd, EVIOCGID, &inpid) < 0) { + if (ioctl(*fd, EVIOCGID, &inpid) < 0) { return 0; } - if (ioctl(fd, EVIOCGNAME(sizeof(product_string)), product_string) < 0) { + if (ioctl(*fd, EVIOCGNAME(sizeof(product_string)), product_string) < 0) { return 0; } } @@ -315,7 +326,7 @@ static int IsJoystick(const char *path, int fd, char **name_return, Uint16 *vend } #endif - FixupDeviceInfoForMapping(fd, &inpid); + FixupDeviceInfoForMapping(*fd, &inpid); #ifdef DEBUG_JOYSTICK SDL_Log("Joystick: %s, bustype = %d, vendor = 0x%.4x, product = 0x%.4x, version = %d\n", name, inpid.bustype, inpid.vendor, inpid.product, inpid.version); @@ -333,11 +344,32 @@ static int IsJoystick(const char *path, int fd, char **name_return, Uint16 *vend return 1; } -static int IsSensor(const char *path, int fd) +static int IsSensor(const char *path, int *fd) { struct input_id inpid; + int class = 0; - if (ioctl(fd, EVIOCGID, &inpid) < 0) { + SDL_zero(inpid); +#ifdef SDL_USE_LIBUDEV + /* Opening input devices can generate synchronous device I/O, so avoid it if we can */ + if (SDL_UDEV_GetProductInfo(path, &inpid.vendor, &inpid.product, &inpid.version, &class) && + !(class & SDL_UDEV_DEVICE_ACCELEROMETER)) { + return 0; + } +#endif + + if (fd && *fd < 0) { + *fd = open(path, O_RDONLY | O_CLOEXEC, 0); + } + if (!fd || *fd < 0) { + return 0; + } + + if (!class && !GuessIsSensor(*fd)) { + return 0; + } + + if (ioctl(*fd, EVIOCGID, &inpid) < 0) { return 0; } @@ -347,7 +379,7 @@ static int IsSensor(const char *path, int fd) return 0; } - return GuessIsSensor(fd); + return 1; } #ifdef SDL_USE_LIBUDEV @@ -434,16 +466,11 @@ static void MaybeAddDevice(const char *path) } } - fd = open(path, O_RDONLY | O_CLOEXEC, 0); - if (fd < 0) { - goto done; - } - #ifdef DEBUG_INPUT_EVENTS SDL_Log("Checking %s\n", path); #endif - if (IsJoystick(path, fd, &name, &vendor, &product, &guid)) { + if (IsJoystick(path, &fd, &name, &vendor, &product, &guid)) { #ifdef DEBUG_INPUT_EVENTS SDL_Log("found joystick: %s\n", path); #endif @@ -484,7 +511,7 @@ static void MaybeAddDevice(const char *path) goto done; } - if (IsSensor(path, fd)) { + if (IsSensor(path, &fd)) { #ifdef DEBUG_INPUT_EVENTS SDL_Log("found sensor: %s\n", path); #endif @@ -880,11 +907,24 @@ static void LINUX_ScanSteamVirtualGamepads(void) int num_virtual_gamepads = 0; int virtual_gamepad_slot; VirtualGamepadEntry *virtual_gamepads = NULL; +#ifdef SDL_USE_LIBUDEV + int class; +#endif count = scandir("/dev/input", &entries, filter_entries, NULL); for (i = 0; i < count; ++i) { (void)SDL_snprintf(path, SDL_arraysize(path), "/dev/input/%s", entries[i]->d_name); +#ifdef SDL_USE_LIBUDEV + /* Opening input devices can generate synchronous device I/O, so avoid it if we can */ + class = 0; + SDL_zero(inpid); + if (SDL_UDEV_GetProductInfo(path, &inpid.vendor, &inpid.product, &inpid.version, &class) && + (inpid.vendor != USB_VENDOR_VALVE || inpid.product != USB_PRODUCT_STEAM_VIRTUAL_GAMEPAD)) { + free(entries[i]); /* This should NOT be SDL_free() */ + continue; + } +#endif fd = open(path, O_RDONLY | O_CLOEXEC, 0); if (fd >= 0) { if (ioctl(fd, EVIOCGID, &inpid) == 0 && @@ -986,6 +1026,9 @@ static void LINUX_JoystickDetect(void) static int LINUX_JoystickInit(void) { const char *devices = SDL_GetHint(SDL_HINT_JOYSTICK_DEVICE); +#ifdef SDL_USE_LIBUDEV + int udev_status = SDL_UDEV_Init(); +#endif SDL_classic_joysticks = SDL_GetHintBoolean(SDL_HINT_LINUX_JOYSTICK_CLASSIC, SDL_FALSE); @@ -1036,21 +1079,24 @@ static int LINUX_JoystickInit(void) } if (enumeration_method == ENUMERATION_LIBUDEV) { - if (SDL_UDEV_Init() < 0) { - return SDL_SetError("Could not initialize UDEV"); - } + if (udev_status == 0) { + /* Set up the udev callback */ + if (SDL_UDEV_AddCallback(joystick_udev_callback) < 0) { + SDL_UDEV_Quit(); + return SDL_SetError("Could not set up joystick <-> udev callback"); + } - /* Set up the udev callback */ - if (SDL_UDEV_AddCallback(joystick_udev_callback) < 0) { - SDL_UDEV_Quit(); - return SDL_SetError("Could not set up joystick <-> udev callback"); + /* Force a scan to build the initial device list */ + SDL_UDEV_Scan(); + } else { + SDL_LogDebug(SDL_LOG_CATEGORY_INPUT, + "udev init failed, disabling udev integration"); + enumeration_method = ENUMERATION_FALLBACK; } - - /* Force a scan to build the initial device list */ - SDL_UDEV_Scan(); - } else + } #endif - { + + if (enumeration_method != ENUMERATION_LIBUDEV) { #if defined(HAVE_INOTIFY) inotify_fd = SDL_inotify_init1(); diff --git a/src/joystick/linux/SDL_sysjoystick_c.h b/src/joystick/linux/SDL_sysjoystick_c.h index 6d6ee69..8b5c927 100644 --- a/src/joystick/linux/SDL_sysjoystick_c.h +++ b/src/joystick/linux/SDL_sysjoystick_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/joystick/n3ds/SDL_sysjoystick.c b/src/joystick/n3ds/SDL_sysjoystick.c index bfb1a37..274f0c1 100644 --- a/src/joystick/n3ds/SDL_sysjoystick.c +++ b/src/joystick/n3ds/SDL_sysjoystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/joystick/os2/SDL_os2joystick.c b/src/joystick/os2/SDL_os2joystick.c index 8df26ff..66de5a2 100644 --- a/src/joystick/os2/SDL_os2joystick.c +++ b/src/joystick/os2/SDL_os2joystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/joystick/ps2/SDL_sysjoystick.c b/src/joystick/ps2/SDL_sysjoystick.c index 8c0edb7..adc73ca 100644 --- a/src/joystick/ps2/SDL_sysjoystick.c +++ b/src/joystick/ps2/SDL_sysjoystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -133,13 +133,13 @@ static int PS2_JoystickInit(void) } /* Function to return the number of joystick devices plugged in right now */ -static int PS2_JoystickGetCount() +static int PS2_JoystickGetCount(void) { return (int)enabled_pads; } /* Function to cause any queued joystick insertions to be processed */ -static void PS2_JoystickDetect() +static void PS2_JoystickDetect(void) { } diff --git a/src/joystick/psp/SDL_sysjoystick.c b/src/joystick/psp/SDL_sysjoystick.c index 11e6acc..160e3f2 100644 --- a/src/joystick/psp/SDL_sysjoystick.c +++ b/src/joystick/psp/SDL_sysjoystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -96,6 +96,9 @@ static int PSP_JoystickInit(void) analog_map[127 - i] = -1 * analog_map[i + 128]; } + /* Fire off a joystick add event */ + SDL_PrivateJoystickAdded(0); + return 1; } @@ -210,7 +213,9 @@ static void PSP_JoystickUpdate(SDL_Joystick *joystick) static enum PspCtrlButtons old_buttons = 0; static unsigned char old_x = 0, old_y = 0; - sceCtrlReadBufferPositive(&pad, 1); + if (sceCtrlPeekBufferPositive(&pad, 1) <= 0) { + return; + } buttons = pad.Buttons; x = pad.Lx; y = pad.Ly; diff --git a/src/joystick/sort_controllers.py b/src/joystick/sort_controllers.py index c354a22..c97559f 100755 --- a/src/joystick/sort_controllers.py +++ b/src/joystick/sort_controllers.py @@ -35,6 +35,15 @@ def find_element(prefix, bindings): return -1 +def get_crc_from_entry(entry): + crc = "" + line = "".join(entry) + bindings = line.split(",") + pos = find_element("crc:", bindings) + if pos >= 0: + crc = bindings[pos][4:] + return crc + def save_controller(line): global controllers match = split_pattern.match(line) @@ -85,7 +94,7 @@ def save_controller(line): entry.append(match.group(5)) controllers.append(entry) - entry_id = entry[1] + entry[3] + entry_id = entry[1] + get_crc_from_entry(entry) if ',sdk' in line or ',hint:' in line: conditionals.append(entry_id) @@ -94,7 +103,7 @@ def write_controllers(): global controller_guids # Check for duplicates for entry in controllers: - entry_id = entry[1] + entry[3] + entry_id = entry[1] + get_crc_from_entry(entry) if (entry_id in controller_guids and entry_id not in conditionals): current_name = entry[2] existing_name = controller_guids[entry_id][2] diff --git a/src/joystick/steam/SDL_steamcontroller.c b/src/joystick/steam/SDL_steamcontroller.c index 04327e3..b80dc86 100644 --- a/src/joystick/steam/SDL_steamcontroller.c +++ b/src/joystick/steam/SDL_steamcontroller.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/joystick/steam/SDL_steamcontroller.h b/src/joystick/steam/SDL_steamcontroller.h index 35a7222..81131f2 100644 --- a/src/joystick/steam/SDL_steamcontroller.h +++ b/src/joystick/steam/SDL_steamcontroller.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/joystick/usb_ids.h b/src/joystick/usb_ids.h index 1e218a4..9484ba5 100644 --- a/src/joystick/usb_ids.h +++ b/src/joystick/usb_ids.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,6 +28,7 @@ #define USB_VENDOR_AMAZON 0x1949 #define USB_VENDOR_APPLE 0x05ac #define USB_VENDOR_ASTRO 0x9886 +#define USB_VENDOR_ASUS 0x0b05 #define USB_VENDOR_BACKBONE 0x358a #define USB_VENDOR_GAMESIR 0x3537 #define USB_VENDOR_DRAGONRISE 0x0079 @@ -47,11 +48,13 @@ #define USB_VENDOR_POWERA_ALT 0x20d6 #define USB_VENDOR_QANBA 0x2c22 #define USB_VENDOR_RAZER 0x1532 +#define USB_VENDOR_SAITEK 0x06a3 #define USB_VENDOR_SHANWAN 0x2563 #define USB_VENDOR_SHANWAN_ALT 0x20bc #define USB_VENDOR_SONY 0x054c #define USB_VENDOR_THRUSTMASTER 0x044f #define USB_VENDOR_TURTLE_BEACH 0x10f5 +#define USB_VENDOR_SWITCH 0x2563 #define USB_VENDOR_VALVE 0x28de #define USB_VENDOR_ZEROPLUS 0x0c12 @@ -71,6 +74,7 @@ #define USB_PRODUCT_HORI_FIGHTING_STICK_ALPHA_PS5 0x0184 #define USB_PRODUCT_LOGITECH_F310 0xc216 #define USB_PRODUCT_LOGITECH_CHILLSTREAM 0xcad1 +#define USB_PRODUCT_MADCATZ_SAITEK_SIDE_PANEL_CONTROL_DECK 0x2218 #define USB_PRODUCT_NACON_REVOLUTION_5_PRO_PS4_WIRELESS 0x0d16 #define USB_PRODUCT_NACON_REVOLUTION_5_PRO_PS4_WIRED 0x0d17 #define USB_PRODUCT_NACON_REVOLUTION_5_PRO_PS5_WIRELESS 0x0d18 @@ -89,6 +93,7 @@ #define USB_PRODUCT_NVIDIA_SHIELD_CONTROLLER_V103 0x7210 #define USB_PRODUCT_NVIDIA_SHIELD_CONTROLLER_V104 0x7214 #define USB_PRODUCT_RAZER_ATROX 0x0a00 +#define USB_PRODUCT_RAZER_KITSUNE 0x1012 #define USB_PRODUCT_RAZER_PANTHERA 0x0401 #define USB_PRODUCT_RAZER_PANTHERA_EVO 0x1008 #define USB_PRODUCT_RAZER_RAIJU 0x1000 @@ -102,6 +107,8 @@ #define USB_PRODUCT_RAZER_WOLVERINE_V2_PRO_PS5_WIRELESS 0x100c #define USB_PRODUCT_RAZER_WOLVERINE_V2_PRO_XBOX_WIRED 0x1010 #define USB_PRODUCT_RAZER_WOLVERINE_V2_PRO_XBOX_WIRELESS 0x1011 +#define USB_PRODUCT_ROG_RAIKIRI 0x1a38 +#define USB_PRODUCT_SAITEK_CYBORG_V3 0xf622 #define USB_PRODUCT_SHANWAN_DS3 0x0523 #define USB_PRODUCT_SONY_DS3 0x0268 #define USB_PRODUCT_SONY_DS4 0x05c4 @@ -110,6 +117,7 @@ #define USB_PRODUCT_SONY_DS4_STRIKEPAD 0x05c5 #define USB_PRODUCT_SONY_DS5 0x0ce6 #define USB_PRODUCT_SONY_DS5_EDGE 0x0df2 +#define USB_PRODUCT_SWITCH_RETROBIT_CONTROLLER 0x0575 #define USB_PRODUCT_THRUSTMASTER_ESWAPX_PRO 0xd012 #define USB_PRODUCT_TURTLE_BEACH_SERIES_X_REACT_R 0x7013 #define USB_PRODUCT_TURTLE_BEACH_SERIES_X_RECON 0x7009 diff --git a/src/joystick/virtual/SDL_virtualjoystick.c b/src/joystick/virtual/SDL_virtualjoystick.c index e5e9b38..a8859c8 100644 --- a/src/joystick/virtual/SDL_virtualjoystick.c +++ b/src/joystick/virtual/SDL_virtualjoystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/joystick/virtual/SDL_virtualjoystick_c.h b/src/joystick/virtual/SDL_virtualjoystick_c.h index 10c5cff..62cc41e 100644 --- a/src/joystick/virtual/SDL_virtualjoystick_c.h +++ b/src/joystick/virtual/SDL_virtualjoystick_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/joystick/vita/SDL_sysjoystick.c b/src/joystick/vita/SDL_sysjoystick.c index 9da62c2..215a032 100644 --- a/src/joystick/vita/SDL_sysjoystick.c +++ b/src/joystick/vita/SDL_sysjoystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -145,12 +145,12 @@ int VITA_JoystickInit(void) return SDL_numjoysticks; } -int VITA_JoystickGetCount() +int VITA_JoystickGetCount(void) { return SDL_numjoysticks; } -void VITA_JoystickDetect() +void VITA_JoystickDetect(void) { } diff --git a/src/joystick/windows/SDL_dinputjoystick.c b/src/joystick/windows/SDL_dinputjoystick.c index 89daf04..73c2605 100644 --- a/src/joystick/windows/SDL_dinputjoystick.c +++ b/src/joystick/windows/SDL_dinputjoystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -855,6 +855,7 @@ int SDL_DINPUT_JoystickOpen(SDL_Joystick *joystick, JoyStick_DeviceData *joystic } else if (FAILED(result)) { return SetDIerror("IDirectInputDevice8::SetProperty", result); } + joystick->hwdata->first_update = SDL_TRUE; /* Poll and wait for initial device state to be populated */ result = IDirectInputDevice8_Poll(joystick->hwdata->InputDevice); @@ -1130,7 +1131,14 @@ void SDL_DINPUT_JoystickUpdate(SDL_Joystick *joystick) IDirectInputDevice8_Poll(joystick->hwdata->InputDevice); } - if (joystick->hwdata->buffered) { + if (joystick->hwdata->first_update) { + /* Poll to get the initial state of the joystick */ + UpdateDINPUTJoystickState_Polled(joystick); + joystick->hwdata->first_update = SDL_FALSE; + return; + } + + if (joystick->hwdata->buffered ) { UpdateDINPUTJoystickState_Buffered(joystick); } else { UpdateDINPUTJoystickState_Polled(joystick); diff --git a/src/joystick/windows/SDL_dinputjoystick_c.h b/src/joystick/windows/SDL_dinputjoystick_c.h index 8e6d233..79bbd22 100644 --- a/src/joystick/windows/SDL_dinputjoystick_c.h +++ b/src/joystick/windows/SDL_dinputjoystick_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/joystick/windows/SDL_rawinputjoystick.c b/src/joystick/windows/SDL_rawinputjoystick.c index c911efd..9728780 100644 --- a/src/joystick/windows/SDL_rawinputjoystick.c +++ b/src/joystick/windows/SDL_rawinputjoystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 2024 Sam Lantinga + Copyright (C) 2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -331,7 +331,7 @@ static struct static SDL_bool xinput_device_change = SDL_TRUE; static SDL_bool xinput_state_dirty = SDL_TRUE; -static void RAWINPUT_UpdateXInput() +static void RAWINPUT_UpdateXInput(void) { DWORD user_index; if (xinput_device_change) { @@ -371,7 +371,7 @@ static void RAWINPUT_MarkXInputSlotFree(Uint8 xinput_slot) xinput_state[xinput_slot].used = SDL_FALSE; } } -static SDL_bool RAWINPUT_MissingXInputSlot() +static SDL_bool RAWINPUT_MissingXInputSlot(void) { int ii; for (ii = 0; ii < SDL_arraysize(xinput_state); ii++) { @@ -556,7 +556,7 @@ static void RAWINPUT_MarkWindowsGamingInputSlotFree(WindowsGamingInputGamepadSta wgi_slot->correlated_context = NULL; } -static SDL_bool RAWINPUT_MissingWindowsGamingInputSlot() +static SDL_bool RAWINPUT_MissingWindowsGamingInputSlot(void) { int ii; for (ii = 0; ii < wgi_state.per_gamepad_count; ii++) { @@ -567,7 +567,7 @@ static SDL_bool RAWINPUT_MissingWindowsGamingInputSlot() return SDL_FALSE; } -static void RAWINPUT_UpdateWindowsGamingInput() +static void RAWINPUT_UpdateWindowsGamingInput(void) { int ii; if (!wgi_state.gamepad_statics) { @@ -1050,7 +1050,7 @@ static int RAWINPUT_JoystickGetCount(void) return SDL_RAWINPUT_numjoysticks; } -SDL_bool RAWINPUT_IsEnabled() +SDL_bool RAWINPUT_IsEnabled(void) { return SDL_RAWINPUT_inited && !SDL_RAWINPUT_remote_desktop; } @@ -1290,6 +1290,7 @@ static int RAWINPUT_JoystickOpen(SDL_Joystick *joystick, int device_index) value_caps = SDL_stack_alloc(HIDP_VALUE_CAPS, caps.NumberInputValueCaps); if (SDL_HidP_GetValueCaps(HidP_Input, value_caps, &caps.NumberInputValueCaps, ctx->preparsed_data) != HIDP_STATUS_SUCCESS) { RAWINPUT_JoystickClose(joystick); + SDL_stack_free(button_caps); return SDL_SetError("Couldn't get device value capabilities"); } @@ -1318,6 +1319,8 @@ static int RAWINPUT_JoystickOpen(SDL_Joystick *joystick, int device_index) ctx->button_indices = (USHORT *)SDL_malloc(joystick->nbuttons * sizeof(*ctx->button_indices)); if (!ctx->button_indices) { RAWINPUT_JoystickClose(joystick); + SDL_stack_free(value_caps); + SDL_stack_free(button_caps); return SDL_OutOfMemory(); } @@ -1342,6 +1345,8 @@ static int RAWINPUT_JoystickOpen(SDL_Joystick *joystick, int device_index) joystick->nbuttons += 1; } + SDL_stack_free(button_caps); + for (i = 0; i < caps.NumberInputValueCaps; ++i) { HIDP_VALUE_CAPS *cap = &value_caps[i]; @@ -1371,6 +1376,7 @@ static int RAWINPUT_JoystickOpen(SDL_Joystick *joystick, int device_index) ctx->axis_indices = (USHORT *)SDL_malloc(joystick->naxes * sizeof(*ctx->axis_indices)); if (!ctx->axis_indices) { RAWINPUT_JoystickClose(joystick); + SDL_stack_free(value_caps); return SDL_OutOfMemory(); } @@ -1404,6 +1410,7 @@ static int RAWINPUT_JoystickOpen(SDL_Joystick *joystick, int device_index) ctx->hat_indices = (USHORT *)SDL_malloc(joystick->nhats * sizeof(*ctx->hat_indices)); if (!ctx->hat_indices) { RAWINPUT_JoystickClose(joystick); + SDL_stack_free(value_caps); return SDL_OutOfMemory(); } @@ -1422,6 +1429,8 @@ static int RAWINPUT_JoystickOpen(SDL_Joystick *joystick, int device_index) } } + SDL_stack_free(value_caps); + joystick->epowerlevel = SDL_JOYSTICK_POWER_UNKNOWN; return 0; @@ -2087,7 +2096,7 @@ int RAWINPUT_RegisterNotifications(HWND hWnd) return 0; } -int RAWINPUT_UnregisterNotifications() +int RAWINPUT_UnregisterNotifications(void) { int i; RAWINPUTDEVICE rid[SDL_arraysize(subscribed_devices)]; diff --git a/src/joystick/windows/SDL_rawinputjoystick_c.h b/src/joystick/windows/SDL_rawinputjoystick_c.h index 598a22d..75bd5ff 100644 --- a/src/joystick/windows/SDL_rawinputjoystick_c.h +++ b/src/joystick/windows/SDL_rawinputjoystick_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/joystick/windows/SDL_windows_gaming_input.c b/src/joystick/windows/SDL_windows_gaming_input.c index 656f742..a7e42e7 100644 --- a/src/joystick/windows/SDL_windows_gaming_input.c +++ b/src/joystick/windows/SDL_windows_gaming_input.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -216,7 +216,7 @@ static SDL_bool SDL_IsXInputDevice(Uint16 vendor, Uint16 product) return SDL_FALSE; } -static void WGI_LoadRawGameControllerStatics() +static void WGI_LoadRawGameControllerStatics(void) { WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = NULL; RoGetActivationFactory_t RoGetActivationFactoryFunc = NULL; @@ -247,7 +247,7 @@ static void WGI_LoadRawGameControllerStatics() } } -static void WGI_LoadOtherControllerStatics() +static void WGI_LoadOtherControllerStatics(void) { WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = NULL; RoGetActivationFactory_t RoGetActivationFactoryFunc = NULL; diff --git a/src/joystick/windows/SDL_windowsjoystick.c b/src/joystick/windows/SDL_windowsjoystick.c index 49e4c59..d2ea36d 100644 --- a/src/joystick/windows/SDL_windowsjoystick.c +++ b/src/joystick/windows/SDL_windowsjoystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -377,7 +377,7 @@ static int SDLCALL SDL_JoystickThread(void *_data) #ifdef SDL_JOYSTICK_XINPUT /* WM_DEVICECHANGE not working, poll for new XINPUT controllers */ SDL_CondWaitTimeout(s_condJoystickThread, s_mutexJoyStickEnum, 1000); - if (SDL_XINPUT_Enabled() && XINPUTGETCAPABILITIES) { + if (SDL_XINPUT_Enabled()) { /* scan for any change in XInput devices */ Uint8 userId; for (userId = 0; userId < XUSER_MAX_COUNT; userId++) { @@ -473,12 +473,12 @@ void WINDOWS_JoystickQuit(void); */ static int WINDOWS_JoystickInit(void) { - if (SDL_DINPUT_JoystickInit() < 0) { + if (SDL_XINPUT_JoystickInit() < 0) { WINDOWS_JoystickQuit(); return -1; } - if (SDL_XINPUT_JoystickInit() < 0) { + if (SDL_DINPUT_JoystickInit() < 0) { WINDOWS_JoystickQuit(); return -1; } diff --git a/src/joystick/windows/SDL_windowsjoystick_c.h b/src/joystick/windows/SDL_windowsjoystick_c.h index c39481f..aeb534e 100644 --- a/src/joystick/windows/SDL_windowsjoystick_c.h +++ b/src/joystick/windows/SDL_windowsjoystick_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -77,6 +77,7 @@ struct joystick_hwdata LPDIRECTINPUTDEVICE8 InputDevice; DIDEVCAPS Capabilities; SDL_bool buffered; + SDL_bool first_update; input_t Inputs[MAX_INPUTS]; int NumInputs; int NumSliders; diff --git a/src/joystick/windows/SDL_xinputjoystick.c b/src/joystick/windows/SDL_xinputjoystick.c index 3a2e912..103eb12 100644 --- a/src/joystick/windows/SDL_xinputjoystick.c +++ b/src/joystick/windows/SDL_xinputjoystick.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -39,9 +39,9 @@ extern "C" { /* * Internal stuff. */ -static SDL_bool s_bXInputEnabled = SDL_TRUE; +static SDL_bool s_bXInputEnabled = SDL_FALSE; -static SDL_bool SDL_XInputUseOldJoystickMapping() +static SDL_bool SDL_XInputUseOldJoystickMapping(void) { #ifdef __WINRT__ /* TODO: remove this __WINRT__ block, but only after integrating with UWP/WinRT's HID API */ @@ -65,11 +65,13 @@ SDL_bool SDL_XINPUT_Enabled(void) int SDL_XINPUT_JoystickInit(void) { - s_bXInputEnabled = SDL_GetHintBoolean(SDL_HINT_XINPUT_ENABLED, SDL_TRUE); + SDL_bool enabled = SDL_GetHintBoolean(SDL_HINT_XINPUT_ENABLED, SDL_TRUE); - if (s_bXInputEnabled && WIN_LoadXInputDLL() < 0) { - s_bXInputEnabled = SDL_FALSE; /* oh well. */ + if (enabled && WIN_LoadXInputDLL() < 0) { + enabled = SDL_FALSE; /* oh well. */ } + s_bXInputEnabled = enabled; + return 0; } @@ -117,7 +119,7 @@ static const char *GetXInputName(const Uint8 userid, BYTE SubType) static SDL_bool GetXInputDeviceInfo(Uint8 userid, Uint16 *pVID, Uint16 *pPID, Uint16 *pVersion) { - XINPUT_CAPABILITIES_EX capabilities; + SDL_XINPUT_CAPABILITIES_EX capabilities; if (!XINPUTGETCAPABILITIESEX || XINPUTGETCAPABILITIESEX(1, userid, 0, &capabilities) != ERROR_SUCCESS) { return SDL_FALSE; @@ -143,7 +145,7 @@ static SDL_bool GetXInputDeviceInfo(Uint8 userid, Uint16 *pVID, Uint16 *pPID, Ui int SDL_XINPUT_GetSteamVirtualGamepadSlot(Uint8 userid) { - XINPUT_CAPABILITIES_EX capabilities; + SDL_XINPUT_CAPABILITIES_EX capabilities; if (XINPUTGETCAPABILITIESEX && XINPUTGETCAPABILITIESEX(1, userid, 0, &capabilities) == ERROR_SUCCESS && @@ -458,6 +460,7 @@ void SDL_XINPUT_JoystickClose(SDL_Joystick *joystick) void SDL_XINPUT_JoystickQuit(void) { if (s_bXInputEnabled) { + s_bXInputEnabled = SDL_FALSE; WIN_UnloadXInputDLL(); } } diff --git a/src/joystick/windows/SDL_xinputjoystick_c.h b/src/joystick/windows/SDL_xinputjoystick_c.h index 8eaa849..15094b9 100644 --- a/src/joystick/windows/SDL_xinputjoystick_c.h +++ b/src/joystick/windows/SDL_xinputjoystick_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/libm/math_libm.h b/src/libm/math_libm.h index 831a184..cf06850 100644 --- a/src/libm/math_libm.h +++ b/src/libm/math_libm.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/loadso/dlopen/SDL_sysloadso.c b/src/loadso/dlopen/SDL_sysloadso.c index f08209c..b7f341c 100644 --- a/src/loadso/dlopen/SDL_sysloadso.c +++ b/src/loadso/dlopen/SDL_sysloadso.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/loadso/dummy/SDL_sysloadso.c b/src/loadso/dummy/SDL_sysloadso.c index b03703b..a21b150 100644 --- a/src/loadso/dummy/SDL_sysloadso.c +++ b/src/loadso/dummy/SDL_sysloadso.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/loadso/os2/SDL_sysloadso.c b/src/loadso/os2/SDL_sysloadso.c index a48db99..f55631d 100644 --- a/src/loadso/os2/SDL_sysloadso.c +++ b/src/loadso/os2/SDL_sysloadso.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/loadso/windows/SDL_sysloadso.c b/src/loadso/windows/SDL_sysloadso.c index 1fcee3d..dd1568e 100644 --- a/src/loadso/windows/SDL_sysloadso.c +++ b/src/loadso/windows/SDL_sysloadso.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/locale/SDL_locale.c b/src/locale/SDL_locale.c index ea3e858..f80fd63 100644 --- a/src/locale/SDL_locale.c +++ b/src/locale/SDL_locale.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/locale/SDL_syslocale.h b/src/locale/SDL_syslocale.h index 3217160..fb163ee 100644 --- a/src/locale/SDL_syslocale.h +++ b/src/locale/SDL_syslocale.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/locale/android/SDL_syslocale.c b/src/locale/android/SDL_syslocale.c index 9a447d0..5724eb7 100644 --- a/src/locale/android/SDL_syslocale.c +++ b/src/locale/android/SDL_syslocale.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/locale/dummy/SDL_syslocale.c b/src/locale/dummy/SDL_syslocale.c index 89a7b1d..d852d82 100644 --- a/src/locale/dummy/SDL_syslocale.c +++ b/src/locale/dummy/SDL_syslocale.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/locale/emscripten/SDL_syslocale.c b/src/locale/emscripten/SDL_syslocale.c index 3b148ac..6972294 100644 --- a/src/locale/emscripten/SDL_syslocale.c +++ b/src/locale/emscripten/SDL_syslocale.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/locale/haiku/SDL_syslocale.cc b/src/locale/haiku/SDL_syslocale.cc index 016a17c..619a8fb 100644 --- a/src/locale/haiku/SDL_syslocale.cc +++ b/src/locale/haiku/SDL_syslocale.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/locale/macosx/SDL_syslocale.m b/src/locale/macosx/SDL_syslocale.m index 57f40fe..426599a 100644 --- a/src/locale/macosx/SDL_syslocale.m +++ b/src/locale/macosx/SDL_syslocale.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/locale/n3ds/SDL_syslocale.c b/src/locale/n3ds/SDL_syslocale.c index 0f6f037..3845344 100644 --- a/src/locale/n3ds/SDL_syslocale.c +++ b/src/locale/n3ds/SDL_syslocale.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -33,7 +33,7 @@ void SDL_SYS_GetPreferredLocales(char *buf, size_t buflen) { /* The 3DS only supports these 12 languages, only one can be active at a time */ static const char AVAILABLE_LOCALES[][6] = { "ja_JP", "en_US", "fr_FR", "de_DE", - "it_IT", "es_ES", "zn_CN", "ko_KR", + "it_IT", "es_ES", "zh_CN", "ko_KR", "nl_NL", "pt_PT", "ru_RU", "zh_TW" }; u8 current_locale = GetLocaleIndex(); if (current_locale != BAD_LOCALE) { @@ -45,14 +45,13 @@ SDL_FORCE_INLINE u8 GetLocaleIndex(void) { u8 current_locale; + Result result; if (R_FAILED(cfguInit())) { return BAD_LOCALE; } - if (R_FAILED(CFGU_GetSystemLanguage(¤t_locale))) { - return BAD_LOCALE; - } + result = CFGU_GetSystemLanguage(¤t_locale); cfguExit(); - return current_locale; + return R_SUCCEEDED(result) ? current_locale : BAD_LOCALE; } /* vi: set sts=4 ts=4 sw=4 expandtab: */ diff --git a/src/locale/psp/SDL_syslocale.c b/src/locale/psp/SDL_syslocale.c new file mode 100644 index 0000000..983df76 --- /dev/null +++ b/src/locale/psp/SDL_syslocale.c @@ -0,0 +1,77 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2025 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "../../SDL_internal.h" +#include "../SDL_syslocale.h" + +#include + +void SDL_SYS_GetPreferredLocales(char *buf, size_t buflen) +{ + int current_locale_int = PSP_SYSTEMPARAM_LANGUAGE_ENGLISH; + + SDL_assert(buflen > 0); + + sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_LANGUAGE, ¤t_locale_int); + switch(current_locale_int) { + case PSP_SYSTEMPARAM_LANGUAGE_JAPANESE: + SDL_strlcpy(buf, "ja_JP", buflen); + break; + case PSP_SYSTEMPARAM_LANGUAGE_ENGLISH: + SDL_strlcpy(buf, "en_US", buflen); + break; + case PSP_SYSTEMPARAM_LANGUAGE_FRENCH: + SDL_strlcpy(buf, "fr_FR", buflen); + break; + case PSP_SYSTEMPARAM_LANGUAGE_SPANISH: + SDL_strlcpy(buf, "es_ES", buflen); + break; + case PSP_SYSTEMPARAM_LANGUAGE_GERMAN: + SDL_strlcpy(buf, "de_DE", buflen); + break; + case PSP_SYSTEMPARAM_LANGUAGE_ITALIAN: + SDL_strlcpy(buf, "it_IT", buflen); + break; + case PSP_SYSTEMPARAM_LANGUAGE_DUTCH: + SDL_strlcpy(buf, "nl_NL", buflen); + break; + case PSP_SYSTEMPARAM_LANGUAGE_PORTUGUESE: + SDL_strlcpy(buf, "pt_PT", buflen); + break; + case PSP_SYSTEMPARAM_LANGUAGE_RUSSIAN: + SDL_strlcpy(buf, "ru_RU", buflen); + break; + case PSP_SYSTEMPARAM_LANGUAGE_KOREAN: + SDL_strlcpy(buf, "ko_KR", buflen); + break; + case PSP_SYSTEMPARAM_LANGUAGE_CHINESE_TRADITIONAL: + SDL_strlcpy(buf, "zh_TW", buflen); + break; + case PSP_SYSTEMPARAM_LANGUAGE_CHINESE_SIMPLIFIED: + SDL_strlcpy(buf, "zh_CN", buflen); + break; + default: + SDL_strlcpy(buf, "en_US", buflen); + break; + } +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/locale/unix/SDL_syslocale.c b/src/locale/unix/SDL_syslocale.c index f1e59cc..146381e 100644 --- a/src/locale/unix/SDL_syslocale.c +++ b/src/locale/unix/SDL_syslocale.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/locale/vita/SDL_syslocale.c b/src/locale/vita/SDL_syslocale.c index 780b9ad..76cba99 100644 --- a/src/locale/vita/SDL_syslocale.c +++ b/src/locale/vita/SDL_syslocale.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/locale/windows/SDL_syslocale.c b/src/locale/windows/SDL_syslocale.c index 2449b15..52766bd 100644 --- a/src/locale/windows/SDL_syslocale.c +++ b/src/locale/windows/SDL_syslocale.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/locale/winrt/SDL_syslocale.c b/src/locale/winrt/SDL_syslocale.c index 8fdeec7..3cd7420 100644 --- a/src/locale/winrt/SDL_syslocale.c +++ b/src/locale/winrt/SDL_syslocale.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/main/gdk/SDL_gdk_main.c b/src/main/gdk/SDL_gdk_main.c index 7bfd9cc..03383b2 100644 --- a/src/main/gdk/SDL_gdk_main.c +++ b/src/main/gdk/SDL_gdk_main.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/main/haiku/SDL_BApp.h b/src/main/haiku/SDL_BApp.h index 284445d..6027219 100644 --- a/src/main/haiku/SDL_BApp.h +++ b/src/main/haiku/SDL_BApp.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/main/haiku/SDL_BeApp.cc b/src/main/haiku/SDL_BeApp.cc index a736a9f..1449cc4 100644 --- a/src/main/haiku/SDL_BeApp.cc +++ b/src/main/haiku/SDL_BeApp.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/main/haiku/SDL_BeApp.h b/src/main/haiku/SDL_BeApp.h index 8b8cc0f..f35b22c 100644 --- a/src/main/haiku/SDL_BeApp.h +++ b/src/main/haiku/SDL_BeApp.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/main/n3ds/SDL_n3ds_main.c b/src/main/n3ds/SDL_n3ds_main.c index 844416f..82f7754 100644 --- a/src/main/n3ds/SDL_n3ds_main.c +++ b/src/main/n3ds/SDL_n3ds_main.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/main/nacl/SDL_nacl_main.c b/src/main/nacl/SDL_nacl_main.c index 174b85b..3e55c1a 100644 --- a/src/main/nacl/SDL_nacl_main.c +++ b/src/main/nacl/SDL_nacl_main.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/main/ps2/SDL_ps2_main.c b/src/main/ps2/SDL_ps2_main.c index b237eea..14fb0d7 100644 --- a/src/main/ps2/SDL_ps2_main.c +++ b/src/main/ps2/SDL_ps2_main.c @@ -23,7 +23,7 @@ #undef main #endif -__attribute__((weak)) void reset_IOP() +__attribute__((weak)) void reset_IOP(void) { SifInitRpc(0); while (!SifIopReset(NULL, 0)) { @@ -32,7 +32,7 @@ __attribute__((weak)) void reset_IOP() } } -static void prepare_IOP() +static void prepare_IOP(void) { reset_IOP(); SifInitRpc(0); @@ -41,12 +41,12 @@ static void prepare_IOP() sbv_patch_fileio(); } -static void init_drivers() +static void init_drivers(void) { init_ps2_filesystem_driver(); } -static void deinit_drivers() +static void deinit_drivers(void) { deinit_ps2_filesystem_driver(); } diff --git a/src/main/windows/version.rc b/src/main/windows/version.rc index 556048b..e5f4dc0 100644 --- a/src/main/windows/version.rc +++ b/src/main/windows/version.rc @@ -9,8 +9,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,30,0,0 - PRODUCTVERSION 2,30,0,0 + FILEVERSION 2,30,11,0 + PRODUCTVERSION 2,30,11,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0x0L FILEOS 0x40004L @@ -23,12 +23,12 @@ BEGIN BEGIN VALUE "CompanyName", "\0" VALUE "FileDescription", "SDL\0" - VALUE "FileVersion", "2, 30, 0, 0\0" + VALUE "FileVersion", "2, 30, 11, 0\0" VALUE "InternalName", "SDL\0" - VALUE "LegalCopyright", "Copyright (C) 2024 Sam Lantinga\0" + VALUE "LegalCopyright", "Copyright (C) 2025 Sam Lantinga\0" VALUE "OriginalFilename", "SDL2.dll\0" VALUE "ProductName", "Simple DirectMedia Layer\0" - VALUE "ProductVersion", "2, 30, 0, 0\0" + VALUE "ProductVersion", "2, 30, 11, 0\0" END END BLOCK "VarFileInfo" diff --git a/src/misc/SDL_sysurl.h b/src/misc/SDL_sysurl.h index f2a4f9b..bd28b4d 100644 --- a/src/misc/SDL_sysurl.h +++ b/src/misc/SDL_sysurl.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/misc/SDL_url.c b/src/misc/SDL_url.c index 9876bf2..458c6c1 100644 --- a/src/misc/SDL_url.c +++ b/src/misc/SDL_url.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/misc/android/SDL_sysurl.c b/src/misc/android/SDL_sysurl.c index e7e21d2..09f8d26 100644 --- a/src/misc/android/SDL_sysurl.c +++ b/src/misc/android/SDL_sysurl.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/misc/dummy/SDL_sysurl.c b/src/misc/dummy/SDL_sysurl.c index a5fa7cb..be5679d 100644 --- a/src/misc/dummy/SDL_sysurl.c +++ b/src/misc/dummy/SDL_sysurl.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/misc/emscripten/SDL_sysurl.c b/src/misc/emscripten/SDL_sysurl.c index 87c1a0c..8070d0e 100644 --- a/src/misc/emscripten/SDL_sysurl.c +++ b/src/misc/emscripten/SDL_sysurl.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/misc/haiku/SDL_sysurl.cc b/src/misc/haiku/SDL_sysurl.cc index 85fd622..5183234 100644 --- a/src/misc/haiku/SDL_sysurl.cc +++ b/src/misc/haiku/SDL_sysurl.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/misc/ios/SDL_sysurl.m b/src/misc/ios/SDL_sysurl.m index 76363b5..08722ba 100644 --- a/src/misc/ios/SDL_sysurl.m +++ b/src/misc/ios/SDL_sysurl.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,10 +26,19 @@ int SDL_SYS_OpenURL(const char *url) { @autoreleasepool { - NSString *nsstr = [NSString stringWithUTF8String:url]; NSURL *nsurl = [NSURL URLWithString:nsstr]; - return [[UIApplication sharedApplication] openURL:nsurl] ? 0 : -1; + if (![[UIApplication sharedApplication] canOpenURL:nsurl]) { + return SDL_SetError("No handler registered for this type of URL"); + } + if (@available(iOS 10.0, tvOS 10.0, *)) { + [[UIApplication sharedApplication] openURL:nsurl options:@{} completionHandler:^(BOOL success) {}]; + } else { + #ifndef SDL_PLATFORM_VISIONOS /* Fallback is never available in any version of VisionOS (but correct API always is). */ + [[UIApplication sharedApplication] openURL:nsurl]; + #endif + } + return 0; } } diff --git a/src/misc/macosx/SDL_sysurl.m b/src/misc/macosx/SDL_sysurl.m index d6088d1..f2d445d 100644 --- a/src/misc/macosx/SDL_sysurl.m +++ b/src/misc/macosx/SDL_sysurl.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/misc/riscos/SDL_sysurl.c b/src/misc/riscos/SDL_sysurl.c index bbb78c9..28ed491 100644 --- a/src/misc/riscos/SDL_sysurl.c +++ b/src/misc/riscos/SDL_sysurl.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/misc/unix/SDL_sysurl.c b/src/misc/unix/SDL_sysurl.c index 050446d..42218a7 100644 --- a/src/misc/unix/SDL_sysurl.c +++ b/src/misc/unix/SDL_sysurl.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/misc/vita/SDL_sysurl.c b/src/misc/vita/SDL_sysurl.c index fca6b2f..8530cde 100644 --- a/src/misc/vita/SDL_sysurl.c +++ b/src/misc/vita/SDL_sysurl.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/misc/windows/SDL_sysurl.c b/src/misc/windows/SDL_sysurl.c index 8462bab..04c3134 100644 --- a/src/misc/windows/SDL_sysurl.c +++ b/src/misc/windows/SDL_sysurl.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/misc/winrt/SDL_sysurl.cpp b/src/misc/winrt/SDL_sysurl.cpp index f435ab9..32c412d 100644 --- a/src/misc/winrt/SDL_sysurl.cpp +++ b/src/misc/winrt/SDL_sysurl.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/power/SDL_power.c b/src/power/SDL_power.c index a64cace..ab4e4c9 100644 --- a/src/power/SDL_power.c +++ b/src/power/SDL_power.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/power/SDL_syspower.h b/src/power/SDL_syspower.h index 25b22fc..480c39d 100644 --- a/src/power/SDL_syspower.h +++ b/src/power/SDL_syspower.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/power/android/SDL_syspower.c b/src/power/android/SDL_syspower.c index 3da49e5..9bdcdd4 100644 --- a/src/power/android/SDL_syspower.c +++ b/src/power/android/SDL_syspower.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/power/emscripten/SDL_syspower.c b/src/power/emscripten/SDL_syspower.c index aed93b0..18a2699 100644 --- a/src/power/emscripten/SDL_syspower.c +++ b/src/power/emscripten/SDL_syspower.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/power/haiku/SDL_syspower.c b/src/power/haiku/SDL_syspower.c index ec3d4b9..10b86d9 100644 --- a/src/power/haiku/SDL_syspower.c +++ b/src/power/haiku/SDL_syspower.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/power/linux/SDL_syspower.c b/src/power/linux/SDL_syspower.c index 7899e3d..8e4860b 100644 --- a/src/power/linux/SDL_syspower.c +++ b/src/power/linux/SDL_syspower.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/power/macosx/SDL_syspower.c b/src/power/macosx/SDL_syspower.c index a3881f3..c01de19 100644 --- a/src/power/macosx/SDL_syspower.c +++ b/src/power/macosx/SDL_syspower.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/power/n3ds/SDL_syspower.c b/src/power/n3ds/SDL_syspower.c index 9b5555e..4c369b2 100644 --- a/src/power/n3ds/SDL_syspower.c +++ b/src/power/n3ds/SDL_syspower.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/power/psp/SDL_syspower.c b/src/power/psp/SDL_syspower.c index 4b9d145..8b8204f 100644 --- a/src/power/psp/SDL_syspower.c +++ b/src/power/psp/SDL_syspower.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/power/uikit/SDL_syspower.h b/src/power/uikit/SDL_syspower.h index 9d5c6a8..02bd7b2 100644 --- a/src/power/uikit/SDL_syspower.h +++ b/src/power/uikit/SDL_syspower.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/power/uikit/SDL_syspower.m b/src/power/uikit/SDL_syspower.m index d366d65..26ddf03 100644 --- a/src/power/uikit/SDL_syspower.m +++ b/src/power/uikit/SDL_syspower.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -61,6 +61,7 @@ SDL_bool SDL_GetPowerInfo_UIKit(SDL_PowerState *state, int *seconds, int *percen #else /* TARGET_OS_TV */ @autoreleasepool { UIDevice *uidev = [UIDevice currentDevice]; + const float level = uidev.batteryLevel; if (!SDL_UIKitLastPowerInfoQuery) { SDL_assert(uidev.isBatteryMonitoringEnabled == NO); @@ -95,7 +96,6 @@ SDL_bool SDL_GetPowerInfo_UIKit(SDL_PowerState *state, int *seconds, int *percen break; } - const float level = uidev.batteryLevel; *percent = ((level < 0.0f) ? -1 : ((int)((level * 100) + 0.5f))); } #endif /* TARGET_OS_TV */ diff --git a/src/power/vita/SDL_syspower.c b/src/power/vita/SDL_syspower.c index 644b72a..7d870b2 100644 --- a/src/power/vita/SDL_syspower.c +++ b/src/power/vita/SDL_syspower.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/power/windows/SDL_syspower.c b/src/power/windows/SDL_syspower.c index 58fa9a8..c20e8e0 100644 --- a/src/power/windows/SDL_syspower.c +++ b/src/power/windows/SDL_syspower.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/power/winrt/SDL_syspower.cpp b/src/power/winrt/SDL_syspower.cpp index 1fc971f..3e1951c 100644 --- a/src/power/winrt/SDL_syspower.cpp +++ b/src/power/winrt/SDL_syspower.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/render/SDL_d3dmath.c b/src/render/SDL_d3dmath.c index ad3af1e..e348efe 100644 --- a/src/render/SDL_d3dmath.c +++ b/src/render/SDL_d3dmath.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../SDL_internal.h" -#if (defined(SDL_VIDEO_RENDER_D3D) || defined(SDL_VIDEO_RENDER_D3D11) || defined(SDL_VIDEO_RENDER_D3D12)) && !defined(SDL_RENDER_DISABLED) +#if (SDL_VIDEO_RENDER_D3D || SDL_VIDEO_RENDER_D3D11 || SDL_VIDEO_RENDER_D3D12) #include "SDL_stdinc.h" #include "SDL_d3dmath.h" @@ -130,6 +130,6 @@ Float4X4 MatrixRotationZ(float r) return m; } -#endif /* (SDL_VIDEO_RENDER_D3D || SDL_VIDEO_RENDER_D3D11 || SDL_VIDEO_RENDER_D3D12) && !SDL_RENDER_DISABLED */ +#endif /* (SDL_VIDEO_RENDER_D3D || SDL_VIDEO_RENDER_D3D11 || SDL_VIDEO_RENDER_D3D12) */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/render/SDL_d3dmath.h b/src/render/SDL_d3dmath.h index ba486f9..a0e04b2 100644 --- a/src/render/SDL_d3dmath.h +++ b/src/render/SDL_d3dmath.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../SDL_internal.h" -#if (defined(SDL_VIDEO_RENDER_D3D) || defined(SDL_VIDEO_RENDER_D3D11) || defined(SDL_VIDEO_RENDER_D3D12)) && !defined(SDL_RENDER_DISABLED) +#if (SDL_VIDEO_RENDER_D3D || SDL_VIDEO_RENDER_D3D11 || SDL_VIDEO_RENDER_D3D12) /* Set up for C function definitions, even when using C++ */ #ifdef __cplusplus @@ -78,6 +78,6 @@ Float4X4 MatrixRotationZ(float r); } #endif -#endif /* (SDL_VIDEO_RENDER_D3D || SDL_VIDEO_RENDER_D3D11 || SDL_VIDEO_RENDER_D3D12) && !SDL_RENDER_DISABLED */ +#endif /* (SDL_VIDEO_RENDER_D3D || SDL_VIDEO_RENDER_D3D11 || SDL_VIDEO_RENDER_D3D12) */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c index 39dcadb..a70d38e 100644 --- a/src/render/SDL_render.c +++ b/src/render/SDL_render.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -91,37 +91,37 @@ this should probably be removed at some point in the future. --ryan. */ #ifndef SDL_RENDER_DISABLED static const SDL_RenderDriver *render_drivers[] = { -#ifdef SDL_VIDEO_RENDER_D3D +#if SDL_VIDEO_RENDER_D3D &D3D_RenderDriver, #endif -#ifdef SDL_VIDEO_RENDER_D3D11 +#if SDL_VIDEO_RENDER_D3D11 &D3D11_RenderDriver, #endif -#ifdef SDL_VIDEO_RENDER_D3D12 +#if SDL_VIDEO_RENDER_D3D12 &D3D12_RenderDriver, #endif -#ifdef SDL_VIDEO_RENDER_METAL +#if SDL_VIDEO_RENDER_METAL &METAL_RenderDriver, #endif -#ifdef SDL_VIDEO_RENDER_OGL +#if SDL_VIDEO_RENDER_OGL &GL_RenderDriver, #endif -#ifdef SDL_VIDEO_RENDER_OGL_ES2 +#if SDL_VIDEO_RENDER_OGL_ES2 &GLES2_RenderDriver, #endif -#ifdef SDL_VIDEO_RENDER_OGL_ES +#if SDL_VIDEO_RENDER_OGL_ES &GLES_RenderDriver, #endif -#ifdef SDL_VIDEO_RENDER_DIRECTFB +#if SDL_VIDEO_RENDER_DIRECTFB &DirectFB_RenderDriver, #endif -#ifdef SDL_VIDEO_RENDER_PS2 +#if SDL_VIDEO_RENDER_PS2 &PS2_RenderDriver, #endif -#ifdef SDL_VIDEO_RENDER_PSP +#if SDL_VIDEO_RENDER_PSP &PSP_RenderDriver, #endif -#ifdef SDL_VIDEO_RENDER_VITA_GXM +#if SDL_VIDEO_RENDER_VITA_GXM &VITA_GXM_RenderDriver, #endif #if SDL_VIDEO_RENDER_SW @@ -799,6 +799,20 @@ static int SDLCALL SDL_RendererEventWatch(void *userdata, SDL_Event *event) event->button.y = (int)(event->button.y / (scale.y * renderer->dpi_scale.y)); } } + } else if (event->type == SDL_MOUSEWHEEL) { + SDL_Window *window = SDL_GetWindowFromID(event->wheel.windowID); + if (window == renderer->window) { + int logical_w, logical_h; + SDL_DRect viewport; + SDL_FPoint scale; + GetWindowViewportValues(renderer, &logical_w, &logical_h, &viewport, &scale); + if (logical_w) { + event->wheel.mouseX -= (int)(viewport.x * renderer->dpi_scale.x); + event->wheel.mouseY -= (int)(viewport.y * renderer->dpi_scale.y); + event->wheel.mouseX = (int)(event->wheel.mouseX / (scale.x * renderer->dpi_scale.x)); + event->wheel.mouseY = (int)(event->wheel.mouseY / (scale.y * renderer->dpi_scale.y)); + } + } } else if (event->type == SDL_FINGERDOWN || event->type == SDL_FINGERUP || event->type == SDL_FINGERMOTION) { @@ -1108,7 +1122,7 @@ SDL_Renderer *SDL_CreateRenderer(SDL_Window *window, int index, Uint32 flags) SDL_Renderer *SDL_CreateSoftwareRenderer(SDL_Surface *surface) { -#if !defined(SDL_RENDER_DISABLED) && SDL_VIDEO_RENDER_SW +#if SDL_VIDEO_RENDER_SW SDL_Renderer *renderer; renderer = SW_CreateRendererForSurface(surface); @@ -1451,7 +1465,7 @@ SDL_Texture *SDL_CreateTextureFromSurface(SDL_Renderer *renderer, SDL_Surface *s SDL_UpdateTexture(texture, NULL, surface->pixels, surface->pitch); } -#ifdef SDL_VIDEO_RENDER_DIRECTFB +#if SDL_VIDEO_RENDER_DIRECTFB /* DirectFB allows palette format for textures. * Copy SDL_Surface palette to the texture */ if (SDL_ISPIXELFORMAT_INDEXED(format)) { @@ -2284,7 +2298,7 @@ static int UpdateLogicalSize(SDL_Renderer *renderer, SDL_bool flush_viewport_cmd hint = SDL_GetHint(SDL_HINT_RENDER_LOGICAL_SIZE_MODE); if (hint && (*hint == '1' || SDL_strcasecmp(hint, "overscan") == 0)) { -#ifdef SDL_VIDEO_RENDER_D3D +#if SDL_VIDEO_RENDER_D3D SDL_bool overscan_supported = SDL_TRUE; /* Unfortunately, Direct3D 9 doesn't support negative viewport numbers which the overscan implementation relies on. diff --git a/src/render/SDL_sysrender.h b/src/render/SDL_sysrender.h index a4eef4d..88d7d57 100644 --- a/src/render/SDL_sysrender.h +++ b/src/render/SDL_sysrender.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/render/SDL_yuv_sw.c b/src/render/SDL_yuv_sw.c index 903279b..203306f 100644 --- a/src/render/SDL_yuv_sw.c +++ b/src/render/SDL_yuv_sw.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/render/SDL_yuv_sw_c.h b/src/render/SDL_yuv_sw_c.h index c123c51..0c35f9d 100644 --- a/src/render/SDL_yuv_sw_c.h +++ b/src/render/SDL_yuv_sw_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/render/direct3d/SDL_render_d3d.c b/src/render/direct3d/SDL_render_d3d.c index 07e854f..e14477f 100644 --- a/src/render/direct3d/SDL_render_d3d.c +++ b/src/render/direct3d/SDL_render_d3d.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,7 +23,7 @@ #include "SDL_render.h" #include "SDL_system.h" -#if defined(SDL_VIDEO_RENDER_D3D) && !defined(SDL_RENDER_DISABLED) +#if SDL_VIDEO_RENDER_D3D #include "../../core/windows/SDL_windows.h" @@ -34,7 +34,7 @@ #include "../SDL_d3dmath.h" #include "../../video/windows/SDL_windowsvideo.h" -#ifdef SDL_VIDEO_RENDER_D3D +#if SDL_VIDEO_RENDER_D3D #define D3D_DEBUG_INFO #include #endif @@ -1170,6 +1170,7 @@ static int D3D_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof(cmd->data.viewport.rect)) != 0) { SDL_copyp(viewport, &cmd->data.viewport.rect); data->drawstate.viewport_dirty = SDL_TRUE; + data->drawstate.cliprect_dirty = SDL_TRUE; } break; } @@ -1609,7 +1610,12 @@ SDL_Renderer *D3D_CreateRenderer(SDL_Window *window, Uint32 flags) renderer->driverdata = data; SDL_VERSION(&windowinfo.version); - SDL_GetWindowWMInfo(window, &windowinfo); + if (!SDL_GetWindowWMInfo(window, &windowinfo) || + windowinfo.subsystem != SDL_SYSWM_WINDOWS) { + SDL_free(data); + SDL_SetError("Couldn't get window handle"); + return NULL; + } window_flags = SDL_GetWindowFlags(window); SDL_GetWindowSizeInPixels(window, &w, &h); @@ -1731,7 +1737,7 @@ SDL_RenderDriver D3D_RenderDriver = { 0, 0 } }; -#endif /* SDL_VIDEO_RENDER_D3D && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_D3D */ #if defined(__WIN32__) || defined(__WINGDK__) /* This function needs to always exist on Windows, for the Dynamic API. */ @@ -1739,7 +1745,7 @@ IDirect3DDevice9 *SDL_RenderGetD3D9Device(SDL_Renderer *renderer) { IDirect3DDevice9 *device = NULL; -#if defined(SDL_VIDEO_RENDER_D3D) && !defined(SDL_RENDER_DISABLED) +#if SDL_VIDEO_RENDER_D3D D3D_RenderData *data = (D3D_RenderData *)renderer->driverdata; /* Make sure that this is a D3D renderer */ @@ -1752,7 +1758,7 @@ IDirect3DDevice9 *SDL_RenderGetD3D9Device(SDL_Renderer *renderer) if (device) { IDirect3DDevice9_AddRef(device); } -#endif /* SDL_VIDEO_RENDER_D3D && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_D3D */ return device; } diff --git a/src/render/direct3d/SDL_shaders_d3d.c b/src/render/direct3d/SDL_shaders_d3d.c index 1f3184f..9c5835a 100644 --- a/src/render/direct3d/SDL_shaders_d3d.c +++ b/src/render/direct3d/SDL_shaders_d3d.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,7 +23,7 @@ #include "SDL_render.h" #include "SDL_system.h" -#if defined(SDL_VIDEO_RENDER_D3D) && !defined(SDL_RENDER_DISABLED) +#if SDL_VIDEO_RENDER_D3D #include "../../core/windows/SDL_windows.h" @@ -268,6 +268,6 @@ HRESULT D3D9_CreatePixelShader(IDirect3DDevice9 *d3dDevice, D3D9_Shader shader, return IDirect3DDevice9_CreatePixelShader(d3dDevice, D3D9_shaders[shader], pixelShader); } -#endif /* SDL_VIDEO_RENDER_D3D && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_D3D */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/render/direct3d/SDL_shaders_d3d.h b/src/render/direct3d/SDL_shaders_d3d.h index 89cd1ea..389a122 100644 --- a/src/render/direct3d/SDL_shaders_d3d.h +++ b/src/render/direct3d/SDL_shaders_d3d.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/render/direct3d11/SDL_render_d3d11.c b/src/render/direct3d11/SDL_render_d3d11.c index 748a8c7..d3d8bc9 100644 --- a/src/render/direct3d11/SDL_render_d3d11.c +++ b/src/render/direct3d11/SDL_render_d3d11.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,7 +23,7 @@ #include "SDL_render.h" #include "SDL_system.h" -#if defined(SDL_VIDEO_RENDER_D3D11) && !defined(SDL_RENDER_DISABLED) +#if SDL_VIDEO_RENDER_D3D11 #define COBJMACROS #include "../../core/windows/SDL_windows.h" @@ -813,7 +813,12 @@ static HRESULT D3D11_CreateSwapChain(SDL_Renderer *renderer, int w, int h) #if defined(__WIN32__) || defined(__WINGDK__) SDL_SysWMinfo windowinfo; SDL_VERSION(&windowinfo.version); - SDL_GetWindowWMInfo(renderer->window, &windowinfo); + if (!SDL_GetWindowWMInfo(renderer->window, &windowinfo) || + windowinfo.subsystem != SDL_SYSWM_WINDOWS) { + SDL_SetError("Couldn't get window handle"); + result = E_FAIL; + goto done; + } result = IDXGIFactory2_CreateSwapChainForHwnd(data->dxgiFactory, (IUnknown *)data->d3dDevice, @@ -2047,6 +2052,7 @@ static int D3D11_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof(cmd->data.viewport.rect)) != 0) { SDL_copyp(viewport, &cmd->data.viewport.rect); rendererData->viewportDirty = SDL_TRUE; + rendererData->cliprectDirty = SDL_TRUE; } break; } @@ -2415,7 +2421,7 @@ SDL_RenderDriver D3D11_RenderDriver = { } }; -#endif /* SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_D3D11 */ #if defined(__WIN32__) || defined(__WINGDK__) /* This function needs to always exist on Windows, for the Dynamic API. */ @@ -2423,7 +2429,7 @@ ID3D11Device *SDL_RenderGetD3D11Device(SDL_Renderer *renderer) { ID3D11Device *device = NULL; -#if defined(SDL_VIDEO_RENDER_D3D11) && !defined(SDL_RENDER_DISABLED) +#if SDL_VIDEO_RENDER_D3D11 D3D11_RenderData *data = (D3D11_RenderData *)renderer->driverdata; /* Make sure that this is a D3D renderer */ @@ -2436,7 +2442,7 @@ ID3D11Device *SDL_RenderGetD3D11Device(SDL_Renderer *renderer) if (device) { ID3D11Device_AddRef(device); } -#endif /* SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_D3D11 */ return device; } diff --git a/src/render/direct3d11/SDL_render_winrt.cpp b/src/render/direct3d11/SDL_render_winrt.cpp index 8ab6a7a..6ff295c 100644 --- a/src/render/direct3d11/SDL_render_winrt.cpp +++ b/src/render/direct3d11/SDL_render_winrt.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if defined(SDL_VIDEO_RENDER_D3D11) && !defined(SDL_RENDER_DISABLED) +#if SDL_VIDEO_RENDER_D3D11 #include "SDL_syswm.h" #include "../../video/winrt/SDL_winrtvideo_cpp.h" @@ -109,6 +109,6 @@ D3D11_GetCurrentRotation() return DXGI_MODE_ROTATION_IDENTITY; } -#endif /* SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_D3D11 */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/render/direct3d11/SDL_render_winrt.h b/src/render/direct3d11/SDL_render_winrt.h index cf0c431..a19b9e6 100644 --- a/src/render/direct3d11/SDL_render_winrt.h +++ b/src/render/direct3d11/SDL_render_winrt.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if defined(SDL_VIDEO_RENDER_D3D11) && !defined(SDL_RENDER_DISABLED) +#if SDL_VIDEO_RENDER_D3D11 #include "SDL_render.h" @@ -35,6 +35,6 @@ DXGI_MODE_ROTATION D3D11_GetCurrentRotation(); } #endif -#endif /* SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_D3D11 */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/render/direct3d11/SDL_shaders_d3d11.c b/src/render/direct3d11/SDL_shaders_d3d11.c index 0bda02b..45c9be8 100644 --- a/src/render/direct3d11/SDL_shaders_d3d11.c +++ b/src/render/direct3d11/SDL_shaders_d3d11.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if defined(SDL_VIDEO_RENDER_D3D11) && !defined(SDL_RENDER_DISABLED) +#if SDL_VIDEO_RENDER_D3D11 #include "SDL_stdinc.h" @@ -1949,6 +1949,6 @@ int D3D11_CreatePixelShader(ID3D11Device1 *d3dDevice, D3D11_Shader shader, ID3D1 return 0; } -#endif /* SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_D3D11 */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/render/direct3d11/SDL_shaders_d3d11.h b/src/render/direct3d11/SDL_shaders_d3d11.h index 010cd93..597ff9b 100644 --- a/src/render/direct3d11/SDL_shaders_d3d11.h +++ b/src/render/direct3d11/SDL_shaders_d3d11.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/render/direct3d12/SDL_render_d3d12.c b/src/render/direct3d12/SDL_render_d3d12.c index 6cf34db..63a8410 100644 --- a/src/render/direct3d12/SDL_render_d3d12.c +++ b/src/render/direct3d12/SDL_render_d3d12.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,7 +23,7 @@ #include "SDL_render.h" #include "SDL_system.h" -#if defined(SDL_VIDEO_RENDER_D3D12) && !defined(SDL_RENDER_DISABLED) +#if SDL_VIDEO_RENDER_D3D12 #define SDL_D3D12_NUM_BUFFERS 2 #define SDL_D3D12_NUM_VERTEX_BUFFERS 256 @@ -48,6 +48,7 @@ #include #include #include +#include #endif #include "SDL_shaders_d3d12.h" @@ -58,6 +59,11 @@ #define SDL_COMPOSE_ERROR(str) SDL_STRINGIFY_ARG(__FUNCTION__) ", " str #endif +/* DXGI_PRESENT flags are removed on Xbox */ +#if defined(__XBOXONE__) || defined(__XBOXSERIES__) +#define DXGI_PRESENT_ALLOW_TEARING 0 +#endif + #ifdef __cplusplus #define SAFE_RELEASE(X) \ if (X) { \ @@ -78,6 +84,54 @@ #define D3D_GUID(X) &(X) #endif +/* + * Older MS Windows SDK headers declare some d3d12 functions with the wrong function prototype. + * - ID3D12Heap::GetDesc + * - ID3D12Resource::GetDesc + * - ID3D12DescriptorHeap::GetDesc + * (and 9 more)+ + * This is fixed in SDKs since WDK_NTDDI_VERSION >= NTDDI_WIN10_FE (0x0A00000A) + */ + +#if !(defined(__MINGW32__) || defined(__XBOXONE__) || defined(__XBOXSERIES__)) \ + && (WDK_NTDDI_VERSION < 0x0A00000A) + +#define D3D_CALL_RET_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(THIS, ...) do { \ + void (STDMETHODCALLTYPE * func)(ID3D12DescriptorHeap * This, D3D12_CPU_DESCRIPTOR_HANDLE * Handle) = \ + (void*)(THIS)->lpVtbl->GetCPUDescriptorHandleForHeapStart; \ + func((THIS), ##__VA_ARGS__); \ + } while (0) + +#define D3D_CALL_RET_ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(THIS, ...) do { \ + void (STDMETHODCALLTYPE * func)(ID3D12DescriptorHeap * This, D3D12_GPU_DESCRIPTOR_HANDLE * Handle) = \ + (void*)(THIS)->lpVtbl->GetGPUDescriptorHandleForHeapStart; \ + func((THIS), ##__VA_ARGS__); \ + } while (0) + +#define D3D_CALL_RET_ID3D12Resource_GetDesc(THIS, ...) do { \ + void (STDMETHODCALLTYPE * func)(ID3D12Resource * This, D3D12_RESOURCE_DESC * Desc) = \ + (void*)(THIS)->lpVtbl->GetDesc; \ + func((THIS), ##__VA_ARGS__); \ + } while (0) + +#else + +/* + * MinGW has correct function prototypes in the vtables, but defines wrong functions + * Xbox just needs these macros defined as used below (because CINTERFACE doesn't exist) + */ + +#define D3D_CALL_RET_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(THIS, ...) \ + D3D_CALL_RET(THIS, GetCPUDescriptorHandleForHeapStart, ##__VA_ARGS__); + +#define D3D_CALL_RET_ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(THIS, ...) \ + D3D_CALL_RET(THIS, GetGPUDescriptorHandleForHeapStart, ##__VA_ARGS__); + +#define D3D_CALL_RET_ID3D12Resource_GetDesc(THIS, ...) \ + D3D_CALL_RET(THIS, GetDesc, ##__VA_ARGS__); + +#endif + /* Set up for C function definitions, even when using C++ */ #ifdef __cplusplus extern "C" { @@ -393,10 +447,10 @@ static D3D12_GPU_DESCRIPTOR_HANDLE D3D12_CPUtoGPUHandle(ID3D12DescriptorHeap *he SIZE_T offset; /* Calculate the correct offset into the heap */ - D3D_CALL_RET(heap, GetCPUDescriptorHandleForHeapStart, &CPUHeapStart); + D3D_CALL_RET_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap, &CPUHeapStart); offset = CPUHandle.ptr - CPUHeapStart.ptr; - D3D_CALL_RET(heap, GetGPUDescriptorHandleForHeapStart, &GPUHandle); + D3D_CALL_RET_ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap, &GPUHandle); GPUHandle.ptr += offset; return GPUHandle; @@ -427,7 +481,7 @@ static D3D12_CPU_DESCRIPTOR_HANDLE D3D12_GetCurrentRenderTargetView(SDL_Renderer } SDL_zero(rtvDescriptor); - D3D_CALL_RET(data->rtvDescriptorHeap, GetCPUDescriptorHandleForHeapStart, &rtvDescriptor); + D3D_CALL_RET_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(data->rtvDescriptorHeap, &rtvDescriptor); rtvDescriptor.ptr += data->currentBackBufferIndex * data->rtvDescriptorSize; return rtvDescriptor; } @@ -1047,7 +1101,7 @@ static HRESULT D3D12_CreateDeviceResources(SDL_Renderer *renderer) samplerDesc.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS; samplerDesc.MinLOD = 0.0f; samplerDesc.MaxLOD = D3D12_FLOAT32_MAX; - D3D_CALL_RET(data->samplerDescriptorHeap, GetCPUDescriptorHandleForHeapStart, &data->nearestPixelSampler); + D3D_CALL_RET_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(data->samplerDescriptorHeap, &data->nearestPixelSampler); D3D_CALL(data->d3dDevice, CreateSampler, &samplerDesc, data->nearestPixelSampler); samplerDesc.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR; @@ -1336,7 +1390,7 @@ static HRESULT D3D12_CreateWindowSizeDependentResources(SDL_Renderer *renderer) rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; SDL_zero(rtvDescriptor); - D3D_CALL_RET(data->rtvDescriptorHeap, GetCPUDescriptorHandleForHeapStart, &rtvDescriptor); + D3D_CALL_RET_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(data->rtvDescriptorHeap, &rtvDescriptor); rtvDescriptor.ptr += i * data->rtvDescriptorSize; D3D_CALL(data->d3dDevice, CreateRenderTargetView, data->renderTargets[i], &rtvDesc, rtvDescriptor); } @@ -1550,7 +1604,7 @@ static int D3D12_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) resourceViewDesc.Texture2D.MipLevels = textureDesc.MipLevels; textureData->mainSRVIndex = D3D12_GetAvailableSRVIndex(renderer); - D3D_CALL_RET(rendererData->srvDescriptorHeap, GetCPUDescriptorHandleForHeapStart, &textureData->mainTextureResourceView); + D3D_CALL_RET_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(rendererData->srvDescriptorHeap, &textureData->mainTextureResourceView); textureData->mainTextureResourceView.ptr += textureData->mainSRVIndex * rendererData->srvDescriptorSize; D3D_CALL(rendererData->d3dDevice, CreateShaderResourceView, @@ -1559,7 +1613,7 @@ static int D3D12_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) textureData->mainTextureResourceView); #if SDL_HAVE_YUV if (textureData->yuv) { - D3D_CALL_RET(rendererData->srvDescriptorHeap, GetCPUDescriptorHandleForHeapStart, &textureData->mainTextureResourceViewU); + D3D_CALL_RET_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(rendererData->srvDescriptorHeap, &textureData->mainTextureResourceViewU); textureData->mainSRVIndexU = D3D12_GetAvailableSRVIndex(renderer); textureData->mainTextureResourceViewU.ptr += textureData->mainSRVIndexU * rendererData->srvDescriptorSize; D3D_CALL(rendererData->d3dDevice, CreateShaderResourceView, @@ -1567,7 +1621,7 @@ static int D3D12_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) &resourceViewDesc, textureData->mainTextureResourceViewU); - D3D_CALL_RET(rendererData->srvDescriptorHeap, GetCPUDescriptorHandleForHeapStart, &textureData->mainTextureResourceViewV); + D3D_CALL_RET_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(rendererData->srvDescriptorHeap, &textureData->mainTextureResourceViewV); textureData->mainSRVIndexV = D3D12_GetAvailableSRVIndex(renderer); textureData->mainTextureResourceViewV.ptr += textureData->mainSRVIndexV * rendererData->srvDescriptorSize; D3D_CALL(rendererData->d3dDevice, CreateShaderResourceView, @@ -1581,7 +1635,7 @@ static int D3D12_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) nvResourceViewDesc.Format = DXGI_FORMAT_R8G8_UNORM; - D3D_CALL_RET(rendererData->srvDescriptorHeap, GetCPUDescriptorHandleForHeapStart, &textureData->mainTextureResourceViewNV); + D3D_CALL_RET_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(rendererData->srvDescriptorHeap, &textureData->mainTextureResourceViewNV); textureData->mainSRVIndexNV = D3D12_GetAvailableSRVIndex(renderer); textureData->mainTextureResourceViewNV.ptr += textureData->mainSRVIndexNV * rendererData->srvDescriptorSize; D3D_CALL(rendererData->d3dDevice, CreateShaderResourceView, @@ -1598,7 +1652,7 @@ static int D3D12_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) renderTargetViewDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; renderTargetViewDesc.Texture2D.MipSlice = 0; - D3D_CALL_RET(rendererData->textureRTVDescriptorHeap, GetCPUDescriptorHandleForHeapStart, &textureData->mainTextureRenderTargetView); + D3D_CALL_RET_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(rendererData->textureRTVDescriptorHeap, &textureData->mainTextureRenderTargetView); textureData->mainTextureRenderTargetView.ptr += textureData->mainSRVIndex * rendererData->rtvDescriptorSize; D3D_CALL(rendererData->d3dDevice, CreateRenderTargetView, @@ -1663,7 +1717,7 @@ static int D3D12_UpdateTextureInternal(D3D12_RenderData *rendererData, ID3D12Res /* Create an upload buffer, which will be used to write to the main texture. */ SDL_zero(textureDesc); - D3D_CALL_RET(texture, GetDesc, &textureDesc); + D3D_CALL_RET_ID3D12Resource_GetDesc(texture, &textureDesc); textureDesc.Width = w; textureDesc.Height = h; @@ -1919,7 +1973,7 @@ static int D3D12_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, /* Create an upload buffer, which will be used to write to the main texture. */ SDL_zero(textureDesc); - D3D_CALL_RET(textureData->mainTexture, GetDesc, &textureDesc); + D3D_CALL_RET_ID3D12Resource_GetDesc(textureData->mainTexture, &textureDesc); textureDesc.Width = rect->w; textureDesc.Height = rect->h; @@ -2028,7 +2082,7 @@ static void D3D12_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture) D3D_CALL(textureData->stagingBuffer, Unmap, 0, NULL); SDL_zero(textureDesc); - D3D_CALL_RET(textureData->mainTexture, GetDesc, &textureDesc); + D3D_CALL_RET_ID3D12Resource_GetDesc(textureData->mainTexture, &textureDesc); textureDesc.Width = textureData->lockedRect.w; textureDesc.Height = textureData->lockedRect.h; @@ -2608,6 +2662,7 @@ static int D3D12_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof(cmd->data.viewport.rect)) != 0) { SDL_copyp(viewport, &cmd->data.viewport.rect); rendererData->viewportDirty = SDL_TRUE; + rendererData->cliprectDirty = SDL_TRUE; } break; } @@ -2738,7 +2793,7 @@ static int D3D12_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect, /* Create a staging texture to copy the screen's data to: */ SDL_zero(textureDesc); - D3D_CALL_RET(backBuffer, GetDesc, &textureDesc); + D3D_CALL_RET_ID3D12Resource_GetDesc(backBuffer, &textureDesc); textureDesc.Width = rect->w; textureDesc.Height = rect->h; @@ -3055,7 +3110,7 @@ SDL_RenderDriver D3D12_RenderDriver = { } #endif -#endif /* SDL_VIDEO_RENDER_D3D12 && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_D3D12 */ #if defined(__WIN32__) || defined(__GDK__) #ifdef __cplusplus @@ -3067,7 +3122,7 @@ extern "C" { ID3D12Device *device = NULL; -#if defined(SDL_VIDEO_RENDER_D3D12) && !defined(SDL_RENDER_DISABLED) +#if SDL_VIDEO_RENDER_D3D12 D3D12_RenderData *data = (D3D12_RenderData *)renderer->driverdata; /* Make sure that this is a D3D renderer */ @@ -3080,7 +3135,7 @@ extern "C" if (device) { D3D_CALL(device, AddRef); } -#endif /* SDL_VIDEO_RENDER_D3D12 && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_D3D12 */ return device; } diff --git a/src/render/direct3d12/SDL_render_d3d12_xbox.cpp b/src/render/direct3d12/SDL_render_d3d12_xbox.cpp index 0c46055..4abb1dc 100644 --- a/src/render/direct3d12/SDL_render_d3d12_xbox.cpp +++ b/src/render/direct3d12/SDL_render_d3d12_xbox.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_RENDER_D3D12 && !SDL_RENDER_DISABLED && (defined(__XBOXONE__) || defined(__XBOXSERIES__)) +#if SDL_VIDEO_RENDER_D3D12 && (defined(__XBOXONE__) || defined(__XBOXSERIES__)) #include "SDL_render_d3d12_xbox.h" #include "../../core/windows/SDL_windows.h" #include diff --git a/src/render/direct3d12/SDL_render_d3d12_xbox.h b/src/render/direct3d12/SDL_render_d3d12_xbox.h index 6db955a..16d22cd 100644 --- a/src/render/direct3d12/SDL_render_d3d12_xbox.h +++ b/src/render/direct3d12/SDL_render_d3d12_xbox.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/render/direct3d12/SDL_shaders_d3d12.c b/src/render/direct3d12/SDL_shaders_d3d12.c index 188f0e7..20c3167 100644 --- a/src/render/direct3d12/SDL_shaders_d3d12.c +++ b/src/render/direct3d12/SDL_shaders_d3d12.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if defined(SDL_VIDEO_RENDER_D3D12) && !defined(SDL_RENDER_DISABLED) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__) +#if SDL_VIDEO_RENDER_D3D12 && !defined(__XBOXONE__) && !defined(__XBOXSERIES__) #include "SDL_stdinc.h" @@ -6934,6 +6934,6 @@ void D3D12_GetRootSignatureData(D3D12_RootSignature rootSig, D3D12_SHADER_BYTECO outBytecode->BytecodeLength = D3D12_rootsigs[rootSig].rs_shader_size; } -#endif /* SDL_VIDEO_RENDER_D3D12 && !SDL_RENDER_DISABLED && !defined(__XBOXONE__) && !defined(__XBOXSERIES__) */ +#endif /* SDL_VIDEO_RENDER_D3D12 && !defined(__XBOXONE__) && !defined(__XBOXSERIES__) */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/render/direct3d12/SDL_shaders_d3d12.h b/src/render/direct3d12/SDL_shaders_d3d12.h index f0c528d..50920b1 100644 --- a/src/render/direct3d12/SDL_shaders_d3d12.h +++ b/src/render/direct3d12/SDL_shaders_d3d12.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/render/direct3d12/SDL_shaders_d3d12_xboxone.cpp b/src/render/direct3d12/SDL_shaders_d3d12_xboxone.cpp index 456c4db..ac90574 100644 --- a/src/render/direct3d12/SDL_shaders_d3d12_xboxone.cpp +++ b/src/render/direct3d12/SDL_shaders_d3d12_xboxone.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_RENDER_D3D12 && !SDL_RENDER_DISABLED && defined(__XBOXONE__) +#if SDL_VIDEO_RENDER_D3D12 && defined(__XBOXONE__) #include @@ -139,6 +139,6 @@ D3D12_GetRootSignatureData(D3D12_RootSignature rootSig, D3D12_SHADER_BYTECODE *o outBytecode->BytecodeLength = D3D12_rootsigs[rootSig].rs_shader_size; } -#endif /* SDL_VIDEO_RENDER_D3D12 && !SDL_RENDER_DISABLED && defined(__XBOXONE__) */ +#endif /* SDL_VIDEO_RENDER_D3D12 && defined(__XBOXONE__) */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/render/direct3d12/SDL_shaders_d3d12_xboxseries.cpp b/src/render/direct3d12/SDL_shaders_d3d12_xboxseries.cpp index 2fc8349..b48ae18 100644 --- a/src/render/direct3d12/SDL_shaders_d3d12_xboxseries.cpp +++ b/src/render/direct3d12/SDL_shaders_d3d12_xboxseries.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_RENDER_D3D12 && !SDL_RENDER_DISABLED && defined(__XBOXSERIES__) +#if SDL_VIDEO_RENDER_D3D12 && defined(__XBOXSERIES__) #include @@ -139,6 +139,6 @@ D3D12_GetRootSignatureData(D3D12_RootSignature rootSig, D3D12_SHADER_BYTECODE *o outBytecode->BytecodeLength = D3D12_rootsigs[rootSig].rs_shader_size; } -#endif /* SDL_VIDEO_RENDER_D3D12 && !SDL_RENDER_DISABLED && defined(__XBOXSERIES__) */ +#endif /* SDL_VIDEO_RENDER_D3D12 && defined(__XBOXSERIES__) */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/render/metal/SDL_render_metal.m b/src/render/metal/SDL_render_metal.m index be207e4..4108858 100644 --- a/src/render/metal/SDL_render_metal.m +++ b/src/render/metal/SDL_render_metal.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if defined(SDL_VIDEO_RENDER_METAL) && !defined(SDL_RENDER_DISABLED) +#if SDL_VIDEO_RENDER_METAL #include "SDL_hints.h" #include "SDL_syswm.h" @@ -1896,6 +1896,6 @@ in case we want to use it later (recreating the renderer) } }; -#endif /* SDL_VIDEO_RENDER_METAL && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_METAL */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/render/opengl/SDL_glfuncs.h b/src/render/opengl/SDL_glfuncs.h index 860b9c0..273d84d 100644 --- a/src/render/opengl/SDL_glfuncs.h +++ b/src/render/opengl/SDL_glfuncs.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/render/opengl/SDL_render_gl.c b/src/render/opengl/SDL_render_gl.c index c3bd0e6..31eddbd 100644 --- a/src/render/opengl/SDL_render_gl.c +++ b/src/render/opengl/SDL_render_gl.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if defined(SDL_VIDEO_RENDER_OGL) && !defined(SDL_RENDER_DISABLED) +#if SDL_VIDEO_RENDER_OGL #include "SDL_hints.h" #include "../../video/SDL_sysvideo.h" /* For SDL_GL_SwapWindowWithResult */ #include "SDL_opengl.h" @@ -1224,6 +1224,7 @@ static int GL_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, vo if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof(cmd->data.viewport.rect)) != 0) { SDL_copyp(viewport, &cmd->data.viewport.rect); data->drawstate.viewport_dirty = SDL_TRUE; + data->drawstate.cliprect_dirty = SDL_TRUE; } break; } @@ -1969,6 +1970,6 @@ SDL_RenderDriver GL_RenderDriver = { 0 } }; -#endif /* SDL_VIDEO_RENDER_OGL && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_OGL */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/render/opengl/SDL_shaders_gl.c b/src/render/opengl/SDL_shaders_gl.c index 10906a5..c7bb6b0 100644 --- a/src/render/opengl/SDL_shaders_gl.c +++ b/src/render/opengl/SDL_shaders_gl.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if defined(SDL_VIDEO_RENDER_OGL) && !defined(SDL_RENDER_DISABLED) +#if SDL_VIDEO_RENDER_OGL #include "SDL_stdinc.h" #include "SDL_opengl.h" @@ -577,6 +577,6 @@ void GL_DestroyShaderContext(GL_ShaderContext *ctx) SDL_free(ctx); } -#endif /* SDL_VIDEO_RENDER_OGL && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_OGL */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/render/opengl/SDL_shaders_gl.h b/src/render/opengl/SDL_shaders_gl.h index d237b3e..18fb84b 100644 --- a/src/render/opengl/SDL_shaders_gl.h +++ b/src/render/opengl/SDL_shaders_gl.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/render/opengles/SDL_glesfuncs.h b/src/render/opengles/SDL_glesfuncs.h index 971b445..6a59fc4 100644 --- a/src/render/opengles/SDL_glesfuncs.h +++ b/src/render/opengles/SDL_glesfuncs.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/render/opengles/SDL_render_gles.c b/src/render/opengles/SDL_render_gles.c index e0cb1f1..f065286 100644 --- a/src/render/opengles/SDL_render_gles.c +++ b/src/render/opengles/SDL_render_gles.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if defined(SDL_VIDEO_RENDER_OGL_ES) && !defined(SDL_RENDER_DISABLED) +#if SDL_VIDEO_RENDER_OGL_ES #include "SDL_hints.h" #include "../../video/SDL_sysvideo.h" /* For SDL_GL_SwapWindowWithResult */ @@ -1215,6 +1215,6 @@ SDL_RenderDriver GLES_RenderDriver = { 0 } }; -#endif /* SDL_VIDEO_RENDER_OGL_ES && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_OGL_ES */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/render/opengles2/SDL_gles2funcs.h b/src/render/opengles2/SDL_gles2funcs.h index b808b76..f6c8124 100644 --- a/src/render/opengles2/SDL_gles2funcs.h +++ b/src/render/opengles2/SDL_gles2funcs.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/render/opengles2/SDL_render_gles2.c b/src/render/opengles2/SDL_render_gles2.c index 81d91bc..bb9b4ad 100644 --- a/src/render/opengles2/SDL_render_gles2.c +++ b/src/render/opengles2/SDL_render_gles2.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if defined(SDL_VIDEO_RENDER_OGL_ES2) && !defined(SDL_RENDER_DISABLED) +#if SDL_VIDEO_RENDER_OGL_ES2 #include "SDL_hints.h" #include "../../video/SDL_sysvideo.h" /* For SDL_GL_SwapWindowWithResult */ @@ -1216,6 +1216,7 @@ static int GLES2_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof(cmd->data.viewport.rect)) != 0) { SDL_copyp(viewport, &cmd->data.viewport.rect); data->drawstate.viewport_dirty = SDL_TRUE; + data->drawstate.cliprect_dirty = SDL_TRUE; } break; } @@ -2244,6 +2245,6 @@ SDL_RenderDriver GLES2_RenderDriver = { 0 } }; -#endif /* SDL_VIDEO_RENDER_OGL_ES2 && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_OGL_ES2 */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/render/opengles2/SDL_shaders_gles2.c b/src/render/opengles2/SDL_shaders_gles2.c index cbb216b..ff45522 100644 --- a/src/render/opengles2/SDL_shaders_gles2.c +++ b/src/render/opengles2/SDL_shaders_gles2.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if defined(SDL_VIDEO_RENDER_OGL_ES2) && !defined(SDL_RENDER_DISABLED) +#if SDL_VIDEO_RENDER_OGL_ES2 #include "SDL_hints.h" #include "SDL_video.h" @@ -444,6 +444,6 @@ const char *GLES2_GetShader(GLES2_ShaderType type) } } -#endif /* SDL_VIDEO_RENDER_OGL_ES2 && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_OGL_ES2 */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/render/opengles2/SDL_shaders_gles2.h b/src/render/opengles2/SDL_shaders_gles2.h index f05d15a..f57e928 100644 --- a/src/render/opengles2/SDL_shaders_gles2.h +++ b/src/render/opengles2/SDL_shaders_gles2.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,7 +23,7 @@ #ifndef SDL_shaders_gles2_h_ #define SDL_shaders_gles2_h_ -#if defined(SDL_VIDEO_RENDER_OGL_ES2) +#if SDL_VIDEO_RENDER_OGL_ES2 typedef enum { diff --git a/src/render/ps2/SDL_render_ps2.c b/src/render/ps2/SDL_render_ps2.c index f45ea9e..7c381d7 100644 --- a/src/render/ps2/SDL_render_ps2.c +++ b/src/render/ps2/SDL_render_ps2.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#ifdef SDL_VIDEO_RENDER_PS2 +#if SDL_VIDEO_RENDER_PS2 #include "../SDL_sysrender.h" #include "SDL_hints.h" @@ -55,7 +55,7 @@ typedef struct static int vsync_sema_id = 0; /* PRIVATE METHODS */ -static int vsync_handler() +static int vsync_handler(void) { iSignalSema(vsync_sema_id); @@ -477,6 +477,7 @@ static int PS2_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v case SDL_RENDERCMD_SETVIEWPORT: { PS2_RenderSetViewPort(renderer, cmd); + /* FIXME: We need to update the clip rect too, see https://github.com/libsdl-org/SDL/issues/9094 */ break; } case SDL_RENDERCMD_SETCLIPRECT: diff --git a/src/render/psp/SDL_render_psp.c b/src/render/psp/SDL_render_psp.c index eaccb52..a53ea20 100644 --- a/src/render/psp/SDL_render_psp.c +++ b/src/render/psp/SDL_render_psp.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#ifdef SDL_VIDEO_RENDER_PSP +#if SDL_VIDEO_RENDER_PSP #include "SDL_hints.h" #include "../SDL_sysrender.h" @@ -1053,6 +1053,7 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v sceGuOffset(2048 - (viewport->w >> 1), 2048 - (viewport->h >> 1)); sceGuViewport(2048, 2048, viewport->w, viewport->h); sceGuScissor(viewport->x, viewport->y, viewport->w, viewport->h); + /* FIXME: We need to update the clip rect too, see https://github.com/libsdl-org/SDL/issues/9094 */ break; } diff --git a/src/render/software/SDL_blendfillrect.c b/src/render/software/SDL_blendfillrect.c index e0bd7fa..ac21366 100644 --- a/src/render/software/SDL_blendfillrect.c +++ b/src/render/software/SDL_blendfillrect.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_RENDER_SW && !defined(SDL_RENDER_DISABLED) +#if SDL_VIDEO_RENDER_SW #include "SDL_draw.h" #include "SDL_blendfillrect.h" @@ -343,6 +343,6 @@ int SDL_BlendFillRects(SDL_Surface *dst, const SDL_Rect *rects, int count, return status; } -#endif /* SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_SW */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/render/software/SDL_blendfillrect.h b/src/render/software/SDL_blendfillrect.h index eb9ba7d..df66e64 100644 --- a/src/render/software/SDL_blendfillrect.h +++ b/src/render/software/SDL_blendfillrect.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/render/software/SDL_blendline.c b/src/render/software/SDL_blendline.c index e505468..0844e7f 100644 --- a/src/render/software/SDL_blendline.c +++ b/src/render/software/SDL_blendline.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_RENDER_SW && !defined(SDL_RENDER_DISABLED) +#if SDL_VIDEO_RENDER_SW #include "SDL_draw.h" #include "SDL_blendline.h" @@ -859,6 +859,6 @@ int SDL_BlendLines(SDL_Surface *dst, const SDL_Point *points, int count, return 0; } -#endif /* SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_SW */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/render/software/SDL_blendline.h b/src/render/software/SDL_blendline.h index 993dd47..4612afd 100644 --- a/src/render/software/SDL_blendline.h +++ b/src/render/software/SDL_blendline.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/render/software/SDL_blendpoint.c b/src/render/software/SDL_blendpoint.c index 874a99a..ecdea30 100644 --- a/src/render/software/SDL_blendpoint.c +++ b/src/render/software/SDL_blendpoint.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_RENDER_SW && !defined(SDL_RENDER_DISABLED) +#if SDL_VIDEO_RENDER_SW #include "SDL_draw.h" #include "SDL_blendpoint.h" @@ -348,6 +348,6 @@ int SDL_BlendPoints(SDL_Surface *dst, const SDL_Point *points, int count, return status; } -#endif /* SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_SW */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/render/software/SDL_blendpoint.h b/src/render/software/SDL_blendpoint.h index 86ee766..23a67a3 100644 --- a/src/render/software/SDL_blendpoint.h +++ b/src/render/software/SDL_blendpoint.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/render/software/SDL_draw.h b/src/render/software/SDL_draw.h index ab80b87..f9e5ad3 100644 --- a/src/render/software/SDL_draw.h +++ b/src/render/software/SDL_draw.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/render/software/SDL_drawline.c b/src/render/software/SDL_drawline.c index 085b5db..8b6bc3d 100644 --- a/src/render/software/SDL_drawline.c +++ b/src/render/software/SDL_drawline.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_RENDER_SW && !defined(SDL_RENDER_DISABLED) +#if SDL_VIDEO_RENDER_SW #include "SDL_draw.h" #include "SDL_drawline.h" @@ -197,6 +197,6 @@ int SDL_DrawLines(SDL_Surface *dst, const SDL_Point *points, int count, return 0; } -#endif /* SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_SW */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/render/software/SDL_drawline.h b/src/render/software/SDL_drawline.h index 0d406c8..1472f74 100644 --- a/src/render/software/SDL_drawline.h +++ b/src/render/software/SDL_drawline.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/render/software/SDL_drawpoint.c b/src/render/software/SDL_drawpoint.c index dd4ef9f..9e095a3 100644 --- a/src/render/software/SDL_drawpoint.c +++ b/src/render/software/SDL_drawpoint.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_RENDER_SW && !defined(SDL_RENDER_DISABLED) +#if SDL_VIDEO_RENDER_SW #include "SDL_draw.h" #include "SDL_drawpoint.h" @@ -106,6 +106,6 @@ int SDL_DrawPoints(SDL_Surface *dst, const SDL_Point *points, int count, return 0; } -#endif /* SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_SW */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/render/software/SDL_drawpoint.h b/src/render/software/SDL_drawpoint.h index 1e74d59..994c529 100644 --- a/src/render/software/SDL_drawpoint.h +++ b/src/render/software/SDL_drawpoint.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/render/software/SDL_render_sw.c b/src/render/software/SDL_render_sw.c index 7aa4571..1eaf107 100644 --- a/src/render/software/SDL_render_sw.c +++ b/src/render/software/SDL_render_sw.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_RENDER_SW && !defined(SDL_RENDER_DISABLED) +#if SDL_VIDEO_RENDER_SW #include "../SDL_sysrender.h" #include "SDL_render_sw_c.h" @@ -1093,6 +1093,6 @@ SDL_RenderDriver SW_RenderDriver = { 0} }; -#endif /* SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_SW */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/render/software/SDL_render_sw_c.h b/src/render/software/SDL_render_sw_c.h index 1d7901f..351a937 100644 --- a/src/render/software/SDL_render_sw_c.h +++ b/src/render/software/SDL_render_sw_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/render/software/SDL_rotate.c b/src/render/software/SDL_rotate.c index d9faca4..d29b92d 100644 --- a/src/render/software/SDL_rotate.c +++ b/src/render/software/SDL_rotate.c @@ -30,7 +30,7 @@ Andreas Schiffler -- aschiffler at ferzkopp dot net */ #include "../../SDL_internal.h" -#if SDL_VIDEO_RENDER_SW && !defined(SDL_RENDER_DISABLED) +#if SDL_VIDEO_RENDER_SW #if defined(__WIN32__) || defined(__GDK__) #include "../../core/windows/SDL_windows.h" @@ -617,4 +617,4 @@ SDL_Surface *SDLgfx_rotateSurface(SDL_Surface *src, double angle, int smooth, in return rz_dst; } -#endif /* SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_SW */ diff --git a/src/render/software/SDL_rotate.h b/src/render/software/SDL_rotate.h index 9e08e53..2568531 100644 --- a/src/render/software/SDL_rotate.h +++ b/src/render/software/SDL_rotate.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/render/software/SDL_triangle.c b/src/render/software/SDL_triangle.c index 31588b9..db8aaf5 100644 --- a/src/render/software/SDL_triangle.c +++ b/src/render/software/SDL_triangle.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#if SDL_VIDEO_RENDER_SW && !defined(SDL_RENDER_DISABLED) +#if SDL_VIDEO_RENDER_SW #include @@ -935,6 +935,6 @@ static void SDL_BlitTriangle_Slow(SDL_BlitInfo *info, TRIANGLE_END_LOOP } -#endif /* SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED */ +#endif /* SDL_VIDEO_RENDER_SW */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/render/software/SDL_triangle.h b/src/render/software/SDL_triangle.h index 463cab6..05b1790 100644 --- a/src/render/software/SDL_triangle.h +++ b/src/render/software/SDL_triangle.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/render/vitagxm/SDL_render_vita_gxm.c b/src/render/vitagxm/SDL_render_vita_gxm.c index be85348..db61cf9 100644 --- a/src/render/vitagxm/SDL_render_vita_gxm.c +++ b/src/render/vitagxm/SDL_render_vita_gxm.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#ifdef SDL_VIDEO_RENDER_VITA_GXM +#if SDL_VIDEO_RENDER_VITA_GXM #include "SDL_hints.h" #include "../SDL_sysrender.h" @@ -366,6 +366,7 @@ static int VITA_GXM_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, length = rect->w * SDL_BYTESPERPIXEL(texture->format); if (length == pitch && length == dpitch) { SDL_memcpy(dst, pixels, length * rect->h); + pixels += pitch * rect->h; } else { for (row = 0; row < rect->h; ++row) { SDL_memcpy(dst, pixels, length); @@ -393,6 +394,7 @@ static int VITA_GXM_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, // U plane if (length == uv_src_pitch && length == uv_pitch) { SDL_memcpy(Udst, pixels, length * UVrect.h); + pixels += uv_src_pitch * UVrect.h; } else { for (row = 0; row < UVrect.h; ++row) { SDL_memcpy(Udst, pixels, length); @@ -956,6 +958,7 @@ static int VITA_GXM_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *c if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof(cmd->data.viewport.rect)) != 0) { SDL_copyp(viewport, &cmd->data.viewport.rect); data->drawstate.viewport_dirty = SDL_TRUE; + data->drawstate.cliprect_dirty = SDL_TRUE; } break; } diff --git a/src/render/vitagxm/SDL_render_vita_gxm_memory.c b/src/render/vitagxm/SDL_render_vita_gxm_memory.c index ac55b8d..b8e5ea7 100644 --- a/src/render/vitagxm/SDL_render_vita_gxm_memory.c +++ b/src/render/vitagxm/SDL_render_vita_gxm_memory.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -21,7 +21,7 @@ #include "../../SDL_internal.h" -#ifdef SDL_VIDEO_RENDER_VITA_GXM +#if SDL_VIDEO_RENDER_VITA_GXM #include "SDL_render_vita_gxm_memory.h" @@ -31,6 +31,8 @@ void *vita_mem_alloc(unsigned int type, unsigned int size, unsigned int alignmen if (type == SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW) { size = ALIGN(size, 256 * 1024); + } else if (type == SCE_KERNEL_MEMBLOCK_TYPE_USER_MAIN_PHYCONT_NC_RW) { + size = ALIGN(size, 1024 * 1024); } else { size = ALIGN(size, 4 * 1024); } diff --git a/src/render/vitagxm/SDL_render_vita_gxm_memory.h b/src/render/vitagxm/SDL_render_vita_gxm_memory.h index 1f3832e..1c10955 100644 --- a/src/render/vitagxm/SDL_render_vita_gxm_memory.h +++ b/src/render/vitagxm/SDL_render_vita_gxm_memory.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/render/vitagxm/SDL_render_vita_gxm_shaders.h b/src/render/vitagxm/SDL_render_vita_gxm_shaders.h index d383fd8..26ac57c 100644 --- a/src/render/vitagxm/SDL_render_vita_gxm_shaders.h +++ b/src/render/vitagxm/SDL_render_vita_gxm_shaders.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/render/vitagxm/SDL_render_vita_gxm_tools.c b/src/render/vitagxm/SDL_render_vita_gxm_tools.c index 2d22646..31a321a 100644 --- a/src/render/vitagxm/SDL_render_vita_gxm_tools.c +++ b/src/render/vitagxm/SDL_render_vita_gxm_tools.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -20,7 +20,7 @@ */ #include "../../SDL_internal.h" -#ifdef SDL_VIDEO_RENDER_VITA_GXM +#if SDL_VIDEO_RENDER_VITA_GXM #include "SDL_hints.h" #include "../SDL_sysrender.h" @@ -1162,7 +1162,7 @@ void gxm_init_for_common_dialog(void) for (int i = 0; i < VITA_GXM_BUFFERS; i += 1) { buffer_for_common_dialog[i].displayData.wait_vblank = SDL_TRUE; buffer_for_common_dialog[i].displayData.address = vita_mem_alloc( - SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, + SCE_KERNEL_MEMBLOCK_TYPE_USER_MAIN_PHYCONT_NC_RW, 4 * VITA_GXM_SCREEN_STRIDE * VITA_GXM_SCREEN_HEIGHT, SCE_GXM_COLOR_SURFACE_ALIGNMENT, SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE, diff --git a/src/render/vitagxm/SDL_render_vita_gxm_tools.h b/src/render/vitagxm/SDL_render_vita_gxm_tools.h index ca50e3f..6ee781e 100644 --- a/src/render/vitagxm/SDL_render_vita_gxm_tools.h +++ b/src/render/vitagxm/SDL_render_vita_gxm_tools.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/render/vitagxm/SDL_render_vita_gxm_types.h b/src/render/vitagxm/SDL_render_vita_gxm_types.h index 4255247..c72c5eb 100644 --- a/src/render/vitagxm/SDL_render_vita_gxm_types.h +++ b/src/render/vitagxm/SDL_render_vita_gxm_types.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/sensor/SDL_sensor.c b/src/sensor/SDL_sensor.c index 3179f73..ced1904 100644 --- a/src/sensor/SDL_sensor.c +++ b/src/sensor/SDL_sensor.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/sensor/SDL_sensor_c.h b/src/sensor/SDL_sensor_c.h index 0d2a483..8d049ef 100644 --- a/src/sensor/SDL_sensor_c.h +++ b/src/sensor/SDL_sensor_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/sensor/SDL_syssensor.h b/src/sensor/SDL_syssensor.h index 8f8196f..67012ab 100644 --- a/src/sensor/SDL_syssensor.h +++ b/src/sensor/SDL_syssensor.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/sensor/android/SDL_androidsensor.c b/src/sensor/android/SDL_androidsensor.c index 3f57253..ce69c11 100644 --- a/src/sensor/android/SDL_androidsensor.c +++ b/src/sensor/android/SDL_androidsensor.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -161,7 +161,7 @@ static void SDL_ANDROID_SensorUpdate(SDL_Sensor *sensor) ASensorEvent event; struct android_poll_source *source; - if (ALooper_pollAll(0, NULL, &events, (void **)&source) == LOOPER_ID_USER) { + if (ALooper_pollOnce(0, NULL, &events, (void **)&source) == LOOPER_ID_USER) { SDL_zero(event); while (ASensorEventQueue_getEvents(sensor->hwdata->eventqueue, &event, 1) > 0) { SDL_PrivateSensorUpdate(sensor, 0, event.data, SDL_arraysize(event.data)); diff --git a/src/sensor/android/SDL_androidsensor.h b/src/sensor/android/SDL_androidsensor.h index 5a119db..08eb077 100644 --- a/src/sensor/android/SDL_androidsensor.h +++ b/src/sensor/android/SDL_androidsensor.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/sensor/coremotion/SDL_coremotionsensor.h b/src/sensor/coremotion/SDL_coremotionsensor.h index ae48163..3cfad64 100644 --- a/src/sensor/coremotion/SDL_coremotionsensor.h +++ b/src/sensor/coremotion/SDL_coremotionsensor.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/sensor/coremotion/SDL_coremotionsensor.m b/src/sensor/coremotion/SDL_coremotionsensor.m index c653c9b..f4983b9 100644 --- a/src/sensor/coremotion/SDL_coremotionsensor.m +++ b/src/sensor/coremotion/SDL_coremotionsensor.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/sensor/dummy/SDL_dummysensor.c b/src/sensor/dummy/SDL_dummysensor.c index b8840d8..d4b13fd 100644 --- a/src/sensor/dummy/SDL_dummysensor.c +++ b/src/sensor/dummy/SDL_dummysensor.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/sensor/dummy/SDL_dummysensor.h b/src/sensor/dummy/SDL_dummysensor.h index e8bf8ef..a255a53 100644 --- a/src/sensor/dummy/SDL_dummysensor.h +++ b/src/sensor/dummy/SDL_dummysensor.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/sensor/n3ds/SDL_n3dssensor.c b/src/sensor/n3ds/SDL_n3dssensor.c index 236b648..08af044 100644 --- a/src/sensor/n3ds/SDL_n3dssensor.c +++ b/src/sensor/n3ds/SDL_n3dssensor.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/sensor/vita/SDL_vitasensor.c b/src/sensor/vita/SDL_vitasensor.c index 8ff68dd..a80c0c2 100644 --- a/src/sensor/vita/SDL_vitasensor.c +++ b/src/sensor/vita/SDL_vitasensor.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/sensor/vita/SDL_vitasensor.h b/src/sensor/vita/SDL_vitasensor.h index 183c35a..794cc0c 100644 --- a/src/sensor/vita/SDL_vitasensor.h +++ b/src/sensor/vita/SDL_vitasensor.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/sensor/windows/SDL_windowssensor.c b/src/sensor/windows/SDL_windowssensor.c index cba5b17..3c15dd3 100644 --- a/src/sensor/windows/SDL_windowssensor.c +++ b/src/sensor/windows/SDL_windowssensor.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/sensor/windows/SDL_windowssensor.h b/src/sensor/windows/SDL_windowssensor.h index e8bf8ef..a255a53 100644 --- a/src/sensor/windows/SDL_windowssensor.h +++ b/src/sensor/windows/SDL_windowssensor.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/stdlib/SDL_crc16.c b/src/stdlib/SDL_crc16.c index d1270f1..98fdb41 100644 --- a/src/stdlib/SDL_crc16.c +++ b/src/stdlib/SDL_crc16.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/stdlib/SDL_crc32.c b/src/stdlib/SDL_crc32.c index ad6eed3..9f2b567 100644 --- a/src/stdlib/SDL_crc32.c +++ b/src/stdlib/SDL_crc32.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/stdlib/SDL_getenv.c b/src/stdlib/SDL_getenv.c index 13cf5a3..2421f51 100644 --- a/src/stdlib/SDL_getenv.c +++ b/src/stdlib/SDL_getenv.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/stdlib/SDL_iconv.c b/src/stdlib/SDL_iconv.c index 2ab748c..3a54be0 100644 --- a/src/stdlib/SDL_iconv.c +++ b/src/stdlib/SDL_iconv.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -822,6 +822,7 @@ char *SDL_iconv_string(const char *tocode, const char *fromcode, const char *inb switch (retCode) { case SDL_ICONV_E2BIG: { + const ptrdiff_t diff = (ptrdiff_t) (outbuf - string); char *oldstring = string; stringsize *= 2; string = (char *)SDL_realloc(string, stringsize + sizeof(Uint32)); @@ -830,8 +831,8 @@ char *SDL_iconv_string(const char *tocode, const char *fromcode, const char *inb SDL_iconv_close(cd); return NULL; } - outbuf = string + (outbuf - oldstring); - outbytesleft = stringsize - (outbuf - string); + outbuf = string + diff; + outbytesleft = stringsize - diff; SDL_memset(outbuf, 0, sizeof(Uint32)); continue; } diff --git a/src/stdlib/SDL_malloc.c b/src/stdlib/SDL_malloc.c index 4c26661..a045a6a 100644 --- a/src/stdlib/SDL_malloc.c +++ b/src/stdlib/SDL_malloc.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -4472,7 +4472,7 @@ struct mallinfo dlmallinfo(void) { } #endif /* NO_MALLINFO */ -void dlmalloc_stats() { +void dlmalloc_stats(void) { internal_malloc_stats(gm); } diff --git a/src/stdlib/SDL_mslibc.c b/src/stdlib/SDL_mslibc.c index 3b3e7e2..c5661f8 100644 --- a/src/stdlib/SDL_mslibc.c +++ b/src/stdlib/SDL_mslibc.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/stdlib/SDL_qsort.c b/src/stdlib/SDL_qsort.c index 0e5728a..dfeee62 100644 --- a/src/stdlib/SDL_qsort.c +++ b/src/stdlib/SDL_qsort.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,7 +28,7 @@ #include "SDL_stdinc.h" #if defined(HAVE_QSORT) -void SDL_qsort(void *base, size_t nmemb, size_t size, int (*compare) (const void *, const void *)) +void SDL_qsort(void *base, size_t nmemb, size_t size, int (SDLCALL *compare) (const void *, const void *)) { if (!base) { return; @@ -65,7 +65,7 @@ void SDL_qsort(void *base, size_t nmemb, size_t size, int (*compare) (const void /* This code came from Gareth McCaughan, under the zlib license. -Specifically this: https://www.mccaughan.org.uk/software/qsort.c-1.15 +Specifically this: https://www.mccaughan.org.uk/software/qsort.c-1.16 Everything below this comment until the HAVE_QSORT #endif was from Gareth (any minor changes will be noted inline). @@ -112,7 +112,7 @@ benefit! * Gareth McCaughan */ -/* Copyright (c) 1998-2016 Gareth McCaughan +/* Copyright (c) 1998-2021 Gareth McCaughan * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any @@ -148,17 +148,23 @@ benefit! * (pre-insertion-sort messed up). * Disable DEBUG_QSORT by default. * Tweak comments very slightly. + * 2021-02-20 v1.16 Fix bug kindly reported by Ray Gardner + * (error in recursion leading to possible + * stack overflow). + * When checking alignment, avoid casting + * pointer to possibly-smaller integer. */ /* BEGIN SDL CHANGE ... commented this out with an #if 0 block. --ryan. */ #if 0 #include +#include #include #include #undef DEBUG_QSORT -static char _ID[]=""; +static char _ID[]=""; #endif /* END SDL CHANGE ... commented this out with an #if 0 block. --ryan. */ @@ -168,7 +174,8 @@ static char _ID[]=""; #define WORD_BYTES sizeof(int) /* How big does our stack need to be? Answer: one entry per - * bit in a |size_t|. + * bit in a |size_t|. (Actually, a bit less because we don't + * recurse all the way down to size-1 subarrays.) */ #define STACK_SIZE (8*sizeof(size_t)) @@ -207,11 +214,12 @@ typedef struct { char * first; char * last; } stack_entry; * on large datasets for locality-of-reference reasons, * but it makes the code much nastier and increases * bookkeeping overhead. - * 2. We always save the shorter and get to work on the - * longer. This guarantees that every time we push - * an item onto the stack its size is <= 1/2 of that - * of its parent; so the stack can't need more than - * log_2(max-array-size) entries. + * 2. We always save the longer and get to work on the + * shorter. This guarantees that whenever we push + * a k'th entry onto the stack we are about to get + * working on something of size <= N/2^k where N is + * the original array size; so the stack can't need + * more than log_2(max-array-size) entries. * 3. We choose a pivot by looking at the first, last * and middle elements. We arrange them into order * because it's easy to do that in conjunction with @@ -273,8 +281,8 @@ typedef struct { char * first; char * last; } stack_entry; if (r>=Trunc) doRight \ else pop \ } \ - else if (l<=r) { pushLeft; doRight } \ - else if (r>=Trunc) { pushRight; doLeft }\ + else if (l<=r) { pushRight; doLeft } \ + else if (r>=Trunc) { pushLeft; doRight }\ else doLeft \ } @@ -368,7 +376,7 @@ typedef struct { char * first; char * last; } stack_entry; /* ---------------------------------------------------------------------- */ static char * pivot_big(char *first, char *mid, char *last, size_t size, - int compare(const void *, const void *)) { + int (SDLCALL * compare)(const void *, const void *)) { size_t d=(((last-first)/size)>>3)*size; #ifdef DEBUG_QSORT fprintf(stderr, "pivot_big: first=%p last=%p size=%lu n=%lu\n", first, (unsigned long)last, size, (unsigned long)((last-first+1)/size)); @@ -409,7 +417,7 @@ fprintf(stderr,"-> %d %d %d @ %p %p %p\n",*(int*)m1,*(int*)m2,*(int*)m3, m1,m2,m /* ---------------------------------------------------------------------- */ static void qsort_nonaligned(void *base, size_t nmemb, size_t size, - int (*compare)(const void *, const void *)) { + int (SDLCALL * compare)(const void *, const void *)) { stack_entry stack[STACK_SIZE]; int stacktop=0; @@ -440,7 +448,7 @@ static void qsort_nonaligned(void *base, size_t nmemb, size_t size, } static void qsort_aligned(void *base, size_t nmemb, size_t size, - int (*compare)(const void *, const void *)) { + int (SDLCALL * compare)(const void *, const void *)) { stack_entry stack[STACK_SIZE]; int stacktop=0; @@ -471,7 +479,7 @@ static void qsort_aligned(void *base, size_t nmemb, size_t size, } static void qsort_words(void *base, size_t nmemb, - int (*compare)(const void *, const void *)) { + int (SDLCALL * compare)(const void *, const void *)) { stack_entry stack[STACK_SIZE]; int stacktop=0; @@ -523,10 +531,10 @@ fprintf(stderr, "after partitioning first=#%lu last=#%lu\n", (first-(char*)base) /* ---------------------------------------------------------------------- */ extern void qsortG(void *base, size_t nmemb, size_t size, - int (*compare)(const void *, const void *)) { + int (SDLCALL * compare)(const void *, const void *)) { if (nmemb<=1) return; - if (((size_t)base|size)&(WORD_BYTES-1)) + if (((uintptr_t)base|size)&(WORD_BYTES-1)) qsort_nonaligned(base,nmemb,size,compare); else if (size!=WORD_BYTES) qsort_aligned(base,nmemb,size,compare); @@ -536,7 +544,7 @@ extern void qsortG(void *base, size_t nmemb, size_t size, #endif /* HAVE_QSORT */ -void *SDL_bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compare)(const void *, const void *)) +void *SDL_bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (SDLCALL * compare)(const void *, const void *)) { #if defined(HAVE_BSEARCH) return bsearch(key, base, nmemb, size, compare); @@ -569,4 +577,3 @@ void *SDL_bsearch(const void *key, const void *base, size_t nmemb, size_t size, } /* vi: set ts=4 sw=4 expandtab: */ - diff --git a/src/stdlib/SDL_stdlib.c b/src/stdlib/SDL_stdlib.c index a90f09f..2a930da 100644 --- a/src/stdlib/SDL_stdlib.c +++ b/src/stdlib/SDL_stdlib.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/stdlib/SDL_string.c b/src/stdlib/SDL_string.c index b66163c..037f6d4 100644 --- a/src/stdlib/SDL_string.c +++ b/src/stdlib/SDL_string.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -1529,7 +1529,7 @@ typedef enum typedef struct { - SDL_bool left_justify; /* for now: ignored. */ + SDL_bool left_justify; SDL_bool force_sign; SDL_bool force_type; /* for now: used only by float printer, ignored otherwise. */ SDL_bool pad_zeroes; @@ -1541,6 +1541,9 @@ typedef struct static size_t SDL_PrintString(char *text, size_t maxlen, SDL_FormatInfo *info, const char *string) { + const char fill = (info && info->pad_zeroes) ? '0' : ' '; + size_t width = 0; + size_t filllen = 0; size_t length = 0; size_t slen, sz; @@ -1550,24 +1553,29 @@ static size_t SDL_PrintString(char *text, size_t maxlen, SDL_FormatInfo *info, c sz = SDL_strlen(string); if (info && info->width > 0 && (size_t)info->width > sz) { - const char fill = info->pad_zeroes ? '0' : ' '; - size_t width = info->width - sz; - size_t filllen; - + width = info->width - sz; if (info->precision >= 0 && (size_t)info->precision < sz) { width += sz - (size_t)info->precision; } filllen = SDL_min(width, maxlen); - SDL_memset(text, fill, filllen); - text += filllen; - maxlen -= filllen; - length += width; + if (!info->left_justify) { + SDL_memset(text, fill, filllen); + text += filllen; + maxlen -= filllen; + length += width; + filllen = 0; + } } SDL_strlcpy(text, string, maxlen); length += sz; + if (filllen > 0) { + SDL_memset(text + sz, fill, filllen); + length += width; + } + if (info) { if (info->precision >= 0 && (size_t)info->precision < sz) { slen = (size_t)info->precision; diff --git a/src/stdlib/SDL_strtokr.c b/src/stdlib/SDL_strtokr.c index 38dc830..7d8cd0d 100644 --- a/src/stdlib/SDL_strtokr.c +++ b/src/stdlib/SDL_strtokr.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/stdlib/SDL_vacopy.h b/src/stdlib/SDL_vacopy.h index ee45bf6..d8ae331 100644 --- a/src/stdlib/SDL_vacopy.h +++ b/src/stdlib/SDL_vacopy.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/test/SDL_test_assert.c b/src/test/SDL_test_assert.c index e8d0ff0..0082e37 100644 --- a/src/test/SDL_test_assert.c +++ b/src/test/SDL_test_assert.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -107,7 +107,7 @@ void SDLTest_AssertPass(SDL_PRINTF_FORMAT_STRING const char *assertDescription, /* * Resets the assert summary counters to zero. */ -void SDLTest_ResetAssertSummary() +void SDLTest_ResetAssertSummary(void) { SDLTest_AssertsPassed = 0; SDLTest_AssertsFailed = 0; @@ -117,7 +117,7 @@ void SDLTest_ResetAssertSummary() * Logs summary of all assertions (total, pass, fail) since last reset * as INFO (failed==0) or ERROR (failed > 0). */ -void SDLTest_LogAssertSummary() +void SDLTest_LogAssertSummary(void) { int totalAsserts = SDLTest_AssertsPassed + SDLTest_AssertsFailed; if (SDLTest_AssertsFailed == 0) { @@ -130,7 +130,7 @@ void SDLTest_LogAssertSummary() /* * Converts the current assert state into a test result */ -int SDLTest_AssertSummaryToTestResult() +int SDLTest_AssertSummaryToTestResult(void) { if (SDLTest_AssertsFailed > 0) { return TEST_RESULT_FAILED; diff --git a/src/test/SDL_test_common.c b/src/test/SDL_test_common.c index 04ad51f..8181ce3 100644 --- a/src/test/SDL_test_common.c +++ b/src/test/SDL_test_common.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/test/SDL_test_compare.c b/src/test/SDL_test_compare.c index ba532c7..de3e94c 100644 --- a/src/test/SDL_test_compare.c +++ b/src/test/SDL_test_compare.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/test/SDL_test_crc32.c b/src/test/SDL_test_crc32.c index b13839b..6de8714 100644 --- a/src/test/SDL_test_crc32.c +++ b/src/test/SDL_test_crc32.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/test/SDL_test_font.c b/src/test/SDL_test_font.c index ffa3dde..d7267b4 100644 --- a/src/test/SDL_test_font.c +++ b/src/test/SDL_test_font.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/test/SDL_test_fuzzer.c b/src/test/SDL_test_fuzzer.c index a04eee0..45468f3 100644 --- a/src/test/SDL_test_fuzzer.c +++ b/src/test/SDL_test_fuzzer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -68,54 +68,54 @@ void SDLTest_FuzzerInit(Uint64 execKey) fuzzerInvocationCounter = 0; } -int SDLTest_GetFuzzerInvocationCount() +int SDLTest_GetFuzzerInvocationCount(void) { return fuzzerInvocationCounter; } -Uint8 SDLTest_RandomUint8() +Uint8 SDLTest_RandomUint8(void) { fuzzerInvocationCounter++; return (Uint8)SDLTest_RandomInt(&rndContext) & 0x000000FF; } -Sint8 SDLTest_RandomSint8() +Sint8 SDLTest_RandomSint8(void) { fuzzerInvocationCounter++; return (Sint8)SDLTest_RandomInt(&rndContext) & 0x000000FF; } -Uint16 SDLTest_RandomUint16() +Uint16 SDLTest_RandomUint16(void) { fuzzerInvocationCounter++; return (Uint16)SDLTest_RandomInt(&rndContext) & 0x0000FFFF; } -Sint16 SDLTest_RandomSint16() +Sint16 SDLTest_RandomSint16(void) { fuzzerInvocationCounter++; return (Sint16)SDLTest_RandomInt(&rndContext) & 0x0000FFFF; } -Sint32 SDLTest_RandomSint32() +Sint32 SDLTest_RandomSint32(void) { fuzzerInvocationCounter++; return (Sint32)SDLTest_RandomInt(&rndContext); } -Uint32 SDLTest_RandomUint32() +Uint32 SDLTest_RandomUint32(void) { fuzzerInvocationCounter++; return (Uint32)SDLTest_RandomInt(&rndContext); } -Uint64 SDLTest_RandomUint64() +Uint64 SDLTest_RandomUint64(void) { union { @@ -132,7 +132,7 @@ Uint64 SDLTest_RandomUint64() return value.v64; } -Sint64 SDLTest_RandomSint64() +Sint64 SDLTest_RandomSint64(void) { union { @@ -425,24 +425,24 @@ Sint64 SDLTest_RandomSint64BoundaryValue(Sint64 boundary1, Sint64 boundary2, SDL validDomain); } -float SDLTest_RandomUnitFloat() +float SDLTest_RandomUnitFloat(void) { return SDLTest_RandomUint32() / (float)UINT_MAX; } -float SDLTest_RandomFloat() +float SDLTest_RandomFloat(void) { return (float)(SDLTest_RandomUnitDouble() * 2.0 * (double)FLT_MAX - (double)(FLT_MAX)); } double -SDLTest_RandomUnitDouble() +SDLTest_RandomUnitDouble(void) { return (double)(SDLTest_RandomUint64() >> 11) * (1.0 / 9007199254740992.0); } double -SDLTest_RandomDouble() +SDLTest_RandomDouble(void) { double r = 0.0; double s = 1.0; @@ -456,7 +456,7 @@ SDLTest_RandomDouble() return r; } -char *SDLTest_RandomAsciiString() +char *SDLTest_RandomAsciiString(void) { return SDLTest_RandomAsciiStringWithMaximumLength(255); } diff --git a/src/test/SDL_test_harness.c b/src/test/SDL_test_harness.c index 460e694..ae6d11c 100644 --- a/src/test/SDL_test_harness.c +++ b/src/test/SDL_test_harness.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -339,7 +339,7 @@ static void SDLTest_LogTestSuiteSummary(SDLTest_TestSuiteReference *testSuites) #endif /* Gets a timer value in seconds */ -static float GetClock() +static float GetClock(void) { float currentClock = SDL_GetPerformanceCounter() / (float)SDL_GetPerformanceFrequency(); return currentClock; diff --git a/src/test/SDL_test_imageBlit.c b/src/test/SDL_test_imageBlit.c index bf1cf2f..f084db5 100644 --- a/src/test/SDL_test_imageBlit.c +++ b/src/test/SDL_test_imageBlit.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -540,7 +540,7 @@ static const SDLTest_SurfaceImage_t SDLTest_imageBlit = { /** * \brief Returns the Blit test image as SDL_Surface. */ -SDL_Surface *SDLTest_ImageBlit() +SDL_Surface *SDLTest_ImageBlit(void) { SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormatFrom( (void *)SDLTest_imageBlit.pixel_data, @@ -1014,7 +1014,7 @@ static const SDLTest_SurfaceImage_t SDLTest_imageBlitColor = { /** * \brief Returns the BlitColor test image as SDL_Surface. */ -SDL_Surface *SDLTest_ImageBlitColor() +SDL_Surface *SDLTest_ImageBlitColor(void) { SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormatFrom( (void *)SDLTest_imageBlitColor.pixel_data, @@ -1651,7 +1651,7 @@ static const SDLTest_SurfaceImage_t SDLTest_imageBlitAlpha = { /** * \brief Returns the BlitAlpha test image as SDL_Surface. */ -SDL_Surface *SDLTest_ImageBlitAlpha() +SDL_Surface *SDLTest_ImageBlitAlpha(void) { SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormatFrom( (void *)SDLTest_imageBlitAlpha.pixel_data, diff --git a/src/test/SDL_test_imageBlitBlend.c b/src/test/SDL_test_imageBlitBlend.c index 520cfff..946bf58 100644 --- a/src/test/SDL_test_imageBlitBlend.c +++ b/src/test/SDL_test_imageBlitBlend.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -580,7 +580,7 @@ static const SDLTest_SurfaceImage_t SDLTest_imageBlitBlendAdd = { /** * \brief Returns the BlitBlendAdd test image as SDL_Surface. */ -SDL_Surface *SDLTest_ImageBlitBlendAdd() +SDL_Surface *SDLTest_ImageBlitBlendAdd(void) { SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormatFrom( (void *)SDLTest_imageBlitBlendAdd.pixel_data, @@ -1171,7 +1171,7 @@ static const SDLTest_SurfaceImage_t SDLTest_imageBlitBlend = { /** * \brief Returns the BlitBlend test image as SDL_Surface. */ -SDL_Surface *SDLTest_ImageBlitBlend() +SDL_Surface *SDLTest_ImageBlitBlend(void) { SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormatFrom( (void *)SDLTest_imageBlitBlend.pixel_data, @@ -1592,7 +1592,7 @@ static const SDLTest_SurfaceImage_t SDLTest_imageBlitBlendMod = { /** * \brief Returns the BlitBlendMod test image as SDL_Surface. */ -SDL_Surface *SDLTest_ImageBlitBlendMod() +SDL_Surface *SDLTest_ImageBlitBlendMod(void) { SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormatFrom( (void *)SDLTest_imageBlitBlendMod.pixel_data, @@ -2396,7 +2396,7 @@ static const SDLTest_SurfaceImage_t SDLTest_imageBlitBlendNone = { /** * \brief Returns the BlitBlendNone test image as SDL_Surface. */ -SDL_Surface *SDLTest_ImageBlitBlendNone() +SDL_Surface *SDLTest_ImageBlitBlendNone(void) { SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormatFrom( (void *)SDLTest_imageBlitBlendNone.pixel_data, @@ -2932,7 +2932,7 @@ static const SDLTest_SurfaceImage_t SDLTest_imageBlitBlendAll = { /** * \brief Returns the BlitBlendAll test image as SDL_Surface. */ -SDL_Surface *SDLTest_ImageBlitBlendAll() +SDL_Surface *SDLTest_ImageBlitBlendAll(void) { SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormatFrom( (void *)SDLTest_imageBlitBlendAll.pixel_data, diff --git a/src/test/SDL_test_imageFace.c b/src/test/SDL_test_imageFace.c index 255acad..a30b668 100644 --- a/src/test/SDL_test_imageFace.c +++ b/src/test/SDL_test_imageFace.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -223,7 +223,7 @@ static const SDLTest_SurfaceImage_t SDLTest_imageFace = { /** * \brief Returns the Face test image as SDL_Surface. */ -SDL_Surface *SDLTest_ImageFace() +SDL_Surface *SDLTest_ImageFace(void) { SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormatFrom( (void *)SDLTest_imageFace.pixel_data, diff --git a/src/test/SDL_test_imagePrimitives.c b/src/test/SDL_test_imagePrimitives.c index 6ef05c5..8e6585f 100644 --- a/src/test/SDL_test_imagePrimitives.c +++ b/src/test/SDL_test_imagePrimitives.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -504,7 +504,7 @@ static const SDLTest_SurfaceImage_t SDLTest_imagePrimitives = { /** * \brief Returns the Primitives test image as SDL_Surface. */ -SDL_Surface *SDLTest_ImagePrimitives() +SDL_Surface *SDLTest_ImagePrimitives(void) { SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormatFrom( (void *)SDLTest_imagePrimitives.pixel_data, diff --git a/src/test/SDL_test_imagePrimitivesBlend.c b/src/test/SDL_test_imagePrimitivesBlend.c index 8ee9f41..a6372f5 100644 --- a/src/test/SDL_test_imagePrimitivesBlend.c +++ b/src/test/SDL_test_imagePrimitivesBlend.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -677,7 +677,7 @@ static const SDLTest_SurfaceImage_t SDLTest_imagePrimitivesBlend = { /** * \brief Returns the PrimitivesBlend test image as SDL_Surface. */ -SDL_Surface *SDLTest_ImagePrimitivesBlend() +SDL_Surface *SDLTest_ImagePrimitivesBlend(void) { SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormatFrom( (void *)SDLTest_imagePrimitivesBlend.pixel_data, diff --git a/src/test/SDL_test_log.c b/src/test/SDL_test_log.c index 714d307..4e80595 100644 --- a/src/test/SDL_test_log.c +++ b/src/test/SDL_test_log.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/test/SDL_test_md5.c b/src/test/SDL_test_md5.c index 83f6f9c..fe9f938 100644 --- a/src/test/SDL_test_md5.c +++ b/src/test/SDL_test_md5.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/test/SDL_test_memory.c b/src/test/SDL_test_memory.c index ffd3eaa..723bd4b 100644 --- a/src/test/SDL_test_memory.c +++ b/src/test/SDL_test_memory.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -195,7 +195,7 @@ static void SDLCALL SDLTest_TrackedFree(void *ptr) SDL_free_orig(ptr); } -int SDLTest_TrackAllocations() +int SDLTest_TrackAllocations(void) { if (SDL_malloc_orig) { return 0; @@ -220,7 +220,7 @@ int SDLTest_TrackAllocations() return 0; } -void SDLTest_LogAllocations() +void SDLTest_LogAllocations(void) { char *message = NULL; size_t message_size = 0; diff --git a/src/test/SDL_test_random.c b/src/test/SDL_test_random.c index 0d7ef4e..4d87e5b 100644 --- a/src/test/SDL_test_random.c +++ b/src/test/SDL_test_random.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/SDL_systhread.h b/src/thread/SDL_systhread.h index b56eaf4..a58e14b 100644 --- a/src/thread/SDL_systhread.h +++ b/src/thread/SDL_systhread.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -59,12 +59,18 @@ extern void SDL_SYS_WaitThread(SDL_Thread *thread); /* Mark thread as cleaned up as soon as it exits, without joining. */ extern void SDL_SYS_DetachThread(SDL_Thread *thread); +/* Initialize the global TLS data */ +extern void SDL_SYS_InitTLSData(void); + /* Get the thread local storage for this thread */ extern SDL_TLSData *SDL_SYS_GetTLSData(void); /* Set the thread local storage for this thread */ extern int SDL_SYS_SetTLSData(SDL_TLSData *data); +/* Quit the global TLS data */ +extern void SDL_SYS_QuitTLSData(void); + /* This is for internal SDL use, so we don't need #ifdefs everywhere. */ extern SDL_Thread * SDL_CreateThreadInternal(int(SDLCALL *fn)(void *), const char *name, diff --git a/src/thread/SDL_thread.c b/src/thread/SDL_thread.c index 55c2902..3d11119 100644 --- a/src/thread/SDL_thread.c +++ b/src/thread/SDL_thread.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,6 +28,15 @@ #include "SDL_hints.h" #include "../SDL_error_c.h" +/* The storage is local to the thread, but the IDs are global for the process */ + +static SDL_atomic_t SDL_tls_allocated; + +void SDL_InitTLSData(void) +{ + SDL_SYS_InitTLSData(); +} + SDL_TLSID SDL_TLSCreate(void) { static SDL_atomic_t SDL_tls_id; @@ -53,6 +62,13 @@ int SDL_TLSSet(SDL_TLSID id, const void *value, void(SDLCALL *destructor)(void * return SDL_InvalidParamError("id"); } + /* Make sure TLS is initialized. + * There's a race condition here if you are calling this from non-SDL threads + * and haven't called SDL_Init() on your main thread, but such is life. + */ + SDL_InitTLSData(); + + /* Get the storage for the current thread */ storage = SDL_SYS_GetTLSData(); if (!storage || (id > storage->limit)) { unsigned int i, oldlimit, newlimit; @@ -69,8 +85,10 @@ int SDL_TLSSet(SDL_TLSID id, const void *value, void(SDLCALL *destructor)(void * storage->array[i].destructor = NULL; } if (SDL_SYS_SetTLSData(storage) != 0) { + SDL_free(storage); return -1; } + SDL_AtomicIncRef(&SDL_tls_allocated); } storage->array[id - 1].data = SDL_const_cast(void *, value); @@ -82,6 +100,7 @@ void SDL_TLSCleanup(void) { SDL_TLSData *storage; + /* Cleanup the storage for the current thread */ storage = SDL_SYS_GetTLSData(); if (storage) { unsigned int i; @@ -92,6 +111,18 @@ void SDL_TLSCleanup(void) } SDL_SYS_SetTLSData(NULL); SDL_free(storage); + (void)SDL_AtomicDecRef(&SDL_tls_allocated); + } +} + +void SDL_QuitTLSData(void) +{ + SDL_TLSCleanup(); + + if (SDL_AtomicGet(&SDL_tls_allocated) == 0) { + SDL_SYS_QuitTLSData(); + } else { + /* Some thread hasn't called SDL_CleanupTLS() */ } } @@ -113,40 +144,27 @@ typedef struct SDL_TLSEntry static SDL_mutex *SDL_generic_TLS_mutex; static SDL_TLSEntry *SDL_generic_TLS; +void SDL_Generic_InitTLSData(void) +{ + if (!SDL_generic_TLS_mutex) { + SDL_generic_TLS_mutex = SDL_CreateMutex(); + } +} + SDL_TLSData *SDL_Generic_GetTLSData(void) { SDL_threadID thread = SDL_ThreadID(); SDL_TLSEntry *entry; SDL_TLSData *storage = NULL; -#ifndef SDL_THREADS_DISABLED - if (!SDL_generic_TLS_mutex) { - static SDL_SpinLock tls_lock; - SDL_AtomicLock(&tls_lock); - if (!SDL_generic_TLS_mutex) { - SDL_mutex *mutex = SDL_CreateMutex(); - SDL_MemoryBarrierRelease(); - SDL_generic_TLS_mutex = mutex; - if (!SDL_generic_TLS_mutex) { - SDL_AtomicUnlock(&tls_lock); - return NULL; - } - } - SDL_AtomicUnlock(&tls_lock); - } - SDL_MemoryBarrierAcquire(); SDL_LockMutex(SDL_generic_TLS_mutex); -#endif /* SDL_THREADS_DISABLED */ - for (entry = SDL_generic_TLS; entry; entry = entry->next) { if (entry->thread == thread) { storage = entry->storage; break; } } -#ifndef SDL_THREADS_DISABLED SDL_UnlockMutex(SDL_generic_TLS_mutex); -#endif return storage; } @@ -155,8 +173,8 @@ int SDL_Generic_SetTLSData(SDL_TLSData *data) { SDL_threadID thread = SDL_ThreadID(); SDL_TLSEntry *prev, *entry; + int retval = 0; - /* SDL_Generic_GetTLSData() is always called first, so we can assume SDL_generic_TLS_mutex */ SDL_LockMutex(SDL_generic_TLS_mutex); prev = NULL; for (entry = SDL_generic_TLS; entry; entry = entry->next) { @@ -175,21 +193,44 @@ int SDL_Generic_SetTLSData(SDL_TLSData *data) } prev = entry; } - if (!entry) { + if (!entry && data) { entry = (SDL_TLSEntry *)SDL_malloc(sizeof(*entry)); if (entry) { entry->thread = thread; entry->storage = data; entry->next = SDL_generic_TLS; SDL_generic_TLS = entry; + } else { + retval = SDL_OutOfMemory(); } } SDL_UnlockMutex(SDL_generic_TLS_mutex); - if (!entry) { - return SDL_OutOfMemory(); + return retval; +} + +void SDL_Generic_QuitTLSData(void) +{ + SDL_TLSEntry *entry; + + /* This should have been cleaned up by the time we get here */ + SDL_assert(!SDL_generic_TLS); + if (SDL_generic_TLS) { + SDL_LockMutex(SDL_generic_TLS_mutex); + for (entry = SDL_generic_TLS; entry; ) { + SDL_TLSEntry *next = entry->next; + SDL_free(entry->storage); + SDL_free(entry); + entry = next; + } + SDL_generic_TLS = NULL; + SDL_UnlockMutex(SDL_generic_TLS_mutex); + } + + if (SDL_generic_TLS_mutex) { + SDL_DestroyMutex(SDL_generic_TLS_mutex); + SDL_generic_TLS_mutex = NULL; } - return 0; } /* Non-thread-safe global error variable */ @@ -328,6 +369,8 @@ SDL_Thread *SDL_CreateThreadWithStackSize(int(SDLCALL *fn)(void *), SDL_Thread *thread; int ret; + SDL_InitMainThread(); + /* Allocate memory for the thread info structure */ thread = (SDL_Thread *)SDL_calloc(1, sizeof(*thread)); if (!thread) { diff --git a/src/thread/SDL_thread_c.h b/src/thread/SDL_thread_c.h index 985a519..d173f1f 100644 --- a/src/thread/SDL_thread_c.h +++ b/src/thread/SDL_thread_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -93,17 +93,17 @@ typedef struct /* This is how many TLS entries we allocate at once */ #define TLS_ALLOC_CHUNKSIZE 4 -/* Get cross-platform, slow, thread local storage for this thread. - This is only intended as a fallback if getting real thread-local - storage fails or isn't supported on this platform. - */ -extern SDL_TLSData *SDL_Generic_GetTLSData(void); +extern void SDL_InitTLSData(void); +extern void SDL_QuitTLSData(void); -/* Set cross-platform, slow, thread local storage for this thread. +/* Generic TLS support. This is only intended as a fallback if getting real thread-local storage fails or isn't supported on this platform. */ +extern void SDL_Generic_InitTLSData(void); +extern SDL_TLSData *SDL_Generic_GetTLSData(void); extern int SDL_Generic_SetTLSData(SDL_TLSData *data); +extern void SDL_Generic_QuitTLSData(void); #endif /* SDL_thread_c_h_ */ diff --git a/src/thread/generic/SDL_syscond.c b/src/thread/generic/SDL_syscond.c index ebd0412..8345e4d 100644 --- a/src/thread/generic/SDL_syscond.c +++ b/src/thread/generic/SDL_syscond.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/generic/SDL_syscond_c.h b/src/thread/generic/SDL_syscond_c.h index 64aaf41..c054378 100644 --- a/src/thread/generic/SDL_syscond_c.h +++ b/src/thread/generic/SDL_syscond_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/generic/SDL_sysmutex.c b/src/thread/generic/SDL_sysmutex.c index f9fc4e4..385ed5e 100644 --- a/src/thread/generic/SDL_sysmutex.c +++ b/src/thread/generic/SDL_sysmutex.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/generic/SDL_sysmutex_c.h b/src/thread/generic/SDL_sysmutex_c.h index 886ce23..6d24bf7 100644 --- a/src/thread/generic/SDL_sysmutex_c.h +++ b/src/thread/generic/SDL_sysmutex_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/generic/SDL_syssem.c b/src/thread/generic/SDL_syssem.c index 8b835b0..0adc26c 100644 --- a/src/thread/generic/SDL_syssem.c +++ b/src/thread/generic/SDL_syssem.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/generic/SDL_systhread.c b/src/thread/generic/SDL_systhread.c index b3a33f7..61861cd 100644 --- a/src/thread/generic/SDL_systhread.c +++ b/src/thread/generic/SDL_systhread.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/generic/SDL_systhread_c.h b/src/thread/generic/SDL_systhread_c.h index 800b333..0795900 100644 --- a/src/thread/generic/SDL_systhread_c.h +++ b/src/thread/generic/SDL_systhread_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/generic/SDL_systls.c b/src/thread/generic/SDL_systls.c index 1d100e0..d5cf231 100644 --- a/src/thread/generic/SDL_systls.c +++ b/src/thread/generic/SDL_systls.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -22,6 +22,11 @@ #include "../../SDL_internal.h" #include "../SDL_thread_c.h" +void SDL_SYS_InitTLSData(void) +{ + SDL_Generic_InitTLSData(); +} + SDL_TLSData *SDL_SYS_GetTLSData(void) { return SDL_Generic_GetTLSData(); @@ -32,4 +37,9 @@ int SDL_SYS_SetTLSData(SDL_TLSData *data) return SDL_Generic_SetTLSData(data); } +void SDL_SYS_QuitTLSData(void) +{ + SDL_Generic_QuitTLSData(); +} + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/thread/n3ds/SDL_syscond.c b/src/thread/n3ds/SDL_syscond.c index c5eae40..808def3 100644 --- a/src/thread/n3ds/SDL_syscond.c +++ b/src/thread/n3ds/SDL_syscond.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/n3ds/SDL_sysmutex.c b/src/thread/n3ds/SDL_sysmutex.c index 71056c2..ce0c03c 100644 --- a/src/thread/n3ds/SDL_sysmutex.c +++ b/src/thread/n3ds/SDL_sysmutex.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/n3ds/SDL_sysmutex_c.h b/src/thread/n3ds/SDL_sysmutex_c.h index 4a3e7e9..192d4e1 100644 --- a/src/thread/n3ds/SDL_sysmutex_c.h +++ b/src/thread/n3ds/SDL_sysmutex_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/n3ds/SDL_syssem.c b/src/thread/n3ds/SDL_syssem.c index 45e5305..744eeb7 100644 --- a/src/thread/n3ds/SDL_syssem.c +++ b/src/thread/n3ds/SDL_syssem.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/n3ds/SDL_systhread.c b/src/thread/n3ds/SDL_systhread.c index c15c281..a202a7d 100644 --- a/src/thread/n3ds/SDL_systhread.c +++ b/src/thread/n3ds/SDL_systhread.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/n3ds/SDL_systhread_c.h b/src/thread/n3ds/SDL_systhread_c.h index ee8bf94..d7c4301 100644 --- a/src/thread/n3ds/SDL_systhread_c.h +++ b/src/thread/n3ds/SDL_systhread_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/ngage/SDL_sysmutex.cpp b/src/thread/ngage/SDL_sysmutex.cpp index 4aa2625..357dd3b 100644 --- a/src/thread/ngage/SDL_sysmutex.cpp +++ b/src/thread/ngage/SDL_sysmutex.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/ngage/SDL_syssem.cpp b/src/thread/ngage/SDL_syssem.cpp index f8e1198..6d2d5c2 100644 --- a/src/thread/ngage/SDL_syssem.cpp +++ b/src/thread/ngage/SDL_syssem.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/ngage/SDL_systhread.cpp b/src/thread/ngage/SDL_systhread.cpp index 8eb50b2..674b3bf 100644 --- a/src/thread/ngage/SDL_systhread.cpp +++ b/src/thread/ngage/SDL_systhread.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/ngage/SDL_systhread_c.h b/src/thread/ngage/SDL_systhread_c.h index ed6ce36..2e744d8 100644 --- a/src/thread/ngage/SDL_systhread_c.h +++ b/src/thread/ngage/SDL_systhread_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/os2/SDL_sysmutex.c b/src/thread/os2/SDL_sysmutex.c index e3a32e2..32354e1 100644 --- a/src/thread/os2/SDL_sysmutex.c +++ b/src/thread/os2/SDL_sysmutex.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/os2/SDL_syssem.c b/src/thread/os2/SDL_syssem.c index 44d6e91..aca5245 100644 --- a/src/thread/os2/SDL_syssem.c +++ b/src/thread/os2/SDL_syssem.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/os2/SDL_systhread.c b/src/thread/os2/SDL_systhread.c index f150de7..120ee89 100644 --- a/src/thread/os2/SDL_systhread.c +++ b/src/thread/os2/SDL_systhread.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/os2/SDL_systhread_c.h b/src/thread/os2/SDL_systhread_c.h index ed6ce36..2e744d8 100644 --- a/src/thread/os2/SDL_systhread_c.h +++ b/src/thread/os2/SDL_systhread_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/os2/SDL_systls.c b/src/thread/os2/SDL_systls.c index 5c380dd..e0a17b0 100644 --- a/src/thread/os2/SDL_systls.c +++ b/src/thread/os2/SDL_systls.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -34,45 +34,22 @@ SDL_TLSData **ppSDLTLSData = NULL; -static ULONG cTLSAlloc = 0; - -/* SDL_OS2TLSAlloc() called from SDL_InitSubSystem() */ -void SDL_OS2TLSAlloc(void) +void SDL_SYS_InitTLSData(void) { ULONG ulRC; - if (cTLSAlloc == 0 || !ppSDLTLSData) { - /* First call - allocate the thread local memory (1 DWORD) */ + if (!ppSDLTLSData) { + /* Allocate the thread local memory (1 DWORD) */ ulRC = DosAllocThreadLocalMemory(1, (PULONG *)&ppSDLTLSData); if (ulRC != NO_ERROR) { debug_os2("DosAllocThreadLocalMemory() failed, rc = %u", ulRC); } } - cTLSAlloc++; -} - -/* SDL_OS2TLSFree() called from SDL_QuitSubSystem() */ -void SDL_OS2TLSFree(void) -{ - ULONG ulRC; - - if (cTLSAlloc != 0) - cTLSAlloc--; - - if (cTLSAlloc == 0 && ppSDLTLSData) { - /* Last call - free the thread local memory */ - ulRC = DosFreeThreadLocalMemory((PULONG)ppSDLTLSData); - if (ulRC != NO_ERROR) { - debug_os2("DosFreeThreadLocalMemory() failed, rc = %u", ulRC); - } else { - ppSDLTLSData = NULL; - } - } } SDL_TLSData *SDL_SYS_GetTLSData(void) { - return (!ppSDLTLSData)? NULL : *ppSDLTLSData; + return ppSDLTLSData ? *ppSDLTLSData : NULL; } int SDL_SYS_SetTLSData(SDL_TLSData *data) @@ -84,6 +61,21 @@ int SDL_SYS_SetTLSData(SDL_TLSData *data) return 0; } +void SDL_SYS_QuitTLSData(void) +{ + ULONG ulRC; + + if (ppSDLTLSData) { + /* Free the thread local memory */ + ulRC = DosFreeThreadLocalMemory((PULONG)ppSDLTLSData); + if (ulRC != NO_ERROR) { + debug_os2("DosFreeThreadLocalMemory() failed, rc = %u", ulRC); + } else { + ppSDLTLSData = NULL; + } + } +} + #endif /* SDL_THREAD_OS2 */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/thread/os2/SDL_systls_c.h b/src/thread/os2/SDL_systls_c.h index bb39443..6070433 100644 --- a/src/thread/os2/SDL_systls_c.h +++ b/src/thread/os2/SDL_systls_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,12 +27,4 @@ extern SDL_TLSData **ppSDLTLSData; -/* SDL_OS2TLSAlloc() called from SDL_InitSubSystem() */ -void SDL_OS2TLSAlloc(void); - -/* SDL_OS2TLSFree() called from SDL_QuitSubSystem() */ -void SDL_OS2TLSFree(void); - #endif /* SDL_THREAD_OS2 */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/thread/ps2/SDL_syssem.c b/src/thread/ps2/SDL_syssem.c index c5f2cae..d1f97f2 100644 --- a/src/thread/ps2/SDL_syssem.c +++ b/src/thread/ps2/SDL_syssem.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/ps2/SDL_systhread.c b/src/thread/ps2/SDL_systhread.c index 15dcf0d..4a51aa4 100644 --- a/src/thread/ps2/SDL_systhread.c +++ b/src/thread/ps2/SDL_systhread.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/ps2/SDL_systhread_c.h b/src/thread/ps2/SDL_systhread_c.h index afab383..c6f30dd 100644 --- a/src/thread/ps2/SDL_systhread_c.h +++ b/src/thread/ps2/SDL_systhread_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/psp/SDL_sysmutex.c b/src/thread/psp/SDL_sysmutex.c index eafca9f..50c6991 100644 --- a/src/thread/psp/SDL_sysmutex.c +++ b/src/thread/psp/SDL_sysmutex.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/psp/SDL_sysmutex_c.h b/src/thread/psp/SDL_sysmutex_c.h index 886ce23..6d24bf7 100644 --- a/src/thread/psp/SDL_sysmutex_c.h +++ b/src/thread/psp/SDL_sysmutex_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/psp/SDL_syssem.c b/src/thread/psp/SDL_syssem.c index 9b8e7d1..a96193e 100644 --- a/src/thread/psp/SDL_syssem.c +++ b/src/thread/psp/SDL_syssem.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/psp/SDL_systhread.c b/src/thread/psp/SDL_systhread.c index c137799..d2aa03e 100644 --- a/src/thread/psp/SDL_systhread.c +++ b/src/thread/psp/SDL_systhread.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/psp/SDL_systhread_c.h b/src/thread/psp/SDL_systhread_c.h index ffa8449..9e951ec 100644 --- a/src/thread/psp/SDL_systhread_c.h +++ b/src/thread/psp/SDL_systhread_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/pthread/SDL_syscond.c b/src/thread/pthread/SDL_syscond.c index a1a2e63..485bdbc 100644 --- a/src/thread/pthread/SDL_syscond.c +++ b/src/thread/pthread/SDL_syscond.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -114,7 +114,7 @@ int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms) abstime.tv_sec = delta.tv_sec + (ms / 1000); abstime.tv_nsec = (long)(delta.tv_usec + (ms % 1000) * 1000) * 1000; #endif - if (abstime.tv_nsec > 1000000000) { + if (abstime.tv_nsec >= 1000000000) { abstime.tv_sec += 1; abstime.tv_nsec -= 1000000000; } diff --git a/src/thread/pthread/SDL_sysmutex.c b/src/thread/pthread/SDL_sysmutex.c index c66b5cc..ee356d9 100644 --- a/src/thread/pthread/SDL_sysmutex.c +++ b/src/thread/pthread/SDL_sysmutex.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/pthread/SDL_sysmutex_c.h b/src/thread/pthread/SDL_sysmutex_c.h index 0435a38..7839522 100644 --- a/src/thread/pthread/SDL_sysmutex_c.h +++ b/src/thread/pthread/SDL_sysmutex_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/pthread/SDL_syssem.c b/src/thread/pthread/SDL_syssem.c index 6d0cdd5..80fc5fa 100644 --- a/src/thread/pthread/SDL_syssem.c +++ b/src/thread/pthread/SDL_syssem.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -141,7 +141,7 @@ int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) #endif /* Wrap the second if needed */ - if (ts_timeout.tv_nsec > 1000000000) { + if (ts_timeout.tv_nsec >= 1000000000) { ts_timeout.tv_sec += 1; ts_timeout.tv_nsec -= 1000000000; } diff --git a/src/thread/pthread/SDL_systhread.c b/src/thread/pthread/SDL_systhread.c index ccc0987..2105673 100644 --- a/src/thread/pthread/SDL_systhread.c +++ b/src/thread/pthread/SDL_systhread.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -41,7 +41,7 @@ #include "../../core/linux/SDL_dbus.h" #endif /* __LINUX__ */ -#if (defined(__LINUX__) || defined(__MACOSX__) || defined(__IPHONEOS__)) && defined(HAVE_DLOPEN) +#if (defined(__LINUX__) || defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__ANDROID__)) && defined(HAVE_DLOPEN) #include #ifndef RTLD_DEFAULT #define RTLD_DEFAULT NULL @@ -80,7 +80,7 @@ static void *RunThread(void *data) #if (defined(__MACOSX__) || defined(__IPHONEOS__)) && defined(HAVE_DLOPEN) static SDL_bool checked_setname = SDL_FALSE; static int (*ppthread_setname_np)(const char *) = NULL; -#elif defined(__LINUX__) && defined(HAVE_DLOPEN) +#elif (defined(__LINUX__) || defined(__ANDROID__)) && defined(HAVE_DLOPEN) static SDL_bool checked_setname = SDL_FALSE; static int (*ppthread_setname_np)(pthread_t, const char *) = NULL; #endif @@ -89,17 +89,17 @@ int SDL_SYS_CreateThread(SDL_Thread *thread) pthread_attr_t type; /* do this here before any threads exist, so there's no race condition. */ - #if (defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__LINUX__)) && defined(HAVE_DLOPEN) + #if (defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__LINUX__) || defined(__ANDROID__)) && defined(HAVE_DLOPEN) if (!checked_setname) { void *fn = dlsym(RTLD_DEFAULT, "pthread_setname_np"); #if defined(__MACOSX__) || defined(__IPHONEOS__) ppthread_setname_np = (int(*)(const char*)) fn; - #elif defined(__LINUX__) + #elif defined(__LINUX__) || defined(__ANDROID__) ppthread_setname_np = (int(*)(pthread_t, const char*)) fn; #endif checked_setname = SDL_TRUE; } -#endif + #endif /* Set the thread attributes */ if (pthread_attr_init(&type) != 0) { @@ -128,12 +128,12 @@ void SDL_SYS_SetupThread(const char *name) #endif /* !__NACL__ */ if (name) { - #if (defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__LINUX__)) && defined(HAVE_DLOPEN) +#if (defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__LINUX__) || defined(__ANDROID__)) && defined(HAVE_DLOPEN) SDL_assert(checked_setname); if (ppthread_setname_np) { - #if defined(__MACOSX__) || defined(__IPHONEOS__) +#if defined(__MACOSX__) || defined(__IPHONEOS__) ppthread_setname_np(name); -#elif defined(__LINUX__) +#elif defined(__LINUX__) || defined(__ANDROID__) if (ppthread_setname_np(pthread_self(), name) == ERANGE) { char namebuf[16]; /* Limited to 16 char */ SDL_strlcpy(namebuf, name, sizeof(namebuf)); diff --git a/src/thread/pthread/SDL_systhread_c.h b/src/thread/pthread/SDL_systhread_c.h index 04dbb22..7a26f0f 100644 --- a/src/thread/pthread/SDL_systhread_c.h +++ b/src/thread/pthread/SDL_systhread_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/pthread/SDL_systls.c b/src/thread/pthread/SDL_systls.c index 0618cb3..e625a75 100644 --- a/src/thread/pthread/SDL_systls.c +++ b/src/thread/pthread/SDL_systls.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -30,27 +30,27 @@ static pthread_key_t thread_local_storage = INVALID_PTHREAD_KEY; static SDL_bool generic_local_storage = SDL_FALSE; -SDL_TLSData *SDL_SYS_GetTLSData(void) +void SDL_SYS_InitTLSData(void) { if (thread_local_storage == INVALID_PTHREAD_KEY && !generic_local_storage) { - static SDL_SpinLock lock; - SDL_AtomicLock(&lock); - if (thread_local_storage == INVALID_PTHREAD_KEY && !generic_local_storage) { - pthread_key_t storage; - if (pthread_key_create(&storage, NULL) == 0) { - SDL_MemoryBarrierRelease(); - thread_local_storage = storage; - } else { - generic_local_storage = SDL_TRUE; - } + if (pthread_key_create(&thread_local_storage, NULL) != 0) { + thread_local_storage = INVALID_PTHREAD_KEY; + SDL_Generic_InitTLSData(); + generic_local_storage = SDL_TRUE; } - SDL_AtomicUnlock(&lock); } +} + +SDL_TLSData *SDL_SYS_GetTLSData(void) +{ if (generic_local_storage) { return SDL_Generic_GetTLSData(); } - SDL_MemoryBarrierAcquire(); - return (SDL_TLSData *)pthread_getspecific(thread_local_storage); + + if (thread_local_storage != INVALID_PTHREAD_KEY) { + return (SDL_TLSData *)pthread_getspecific(thread_local_storage); + } + return NULL; } int SDL_SYS_SetTLSData(SDL_TLSData *data) @@ -58,10 +58,24 @@ int SDL_SYS_SetTLSData(SDL_TLSData *data) if (generic_local_storage) { return SDL_Generic_SetTLSData(data); } + if (pthread_setspecific(thread_local_storage, data) != 0) { return SDL_SetError("pthread_setspecific() failed"); } return 0; } +void SDL_SYS_QuitTLSData(void) +{ + if (generic_local_storage) { + SDL_Generic_QuitTLSData(); + generic_local_storage = SDL_FALSE; + } else { + if (thread_local_storage != INVALID_PTHREAD_KEY) { + pthread_key_delete(thread_local_storage); + thread_local_storage = INVALID_PTHREAD_KEY; + } + } +} + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/thread/stdcpp/SDL_syscond.cpp b/src/thread/stdcpp/SDL_syscond.cpp index 561d774..ea46973 100644 --- a/src/thread/stdcpp/SDL_syscond.cpp +++ b/src/thread/stdcpp/SDL_syscond.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/stdcpp/SDL_sysmutex.cpp b/src/thread/stdcpp/SDL_sysmutex.cpp index bc04bed..49f087f 100644 --- a/src/thread/stdcpp/SDL_sysmutex.cpp +++ b/src/thread/stdcpp/SDL_sysmutex.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/stdcpp/SDL_sysmutex_c.h b/src/thread/stdcpp/SDL_sysmutex_c.h index dd53ee8..759852f 100644 --- a/src/thread/stdcpp/SDL_sysmutex_c.h +++ b/src/thread/stdcpp/SDL_sysmutex_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/stdcpp/SDL_systhread.cpp b/src/thread/stdcpp/SDL_systhread.cpp index 3d93a01..0b360bd 100644 --- a/src/thread/stdcpp/SDL_systhread.cpp +++ b/src/thread/stdcpp/SDL_systhread.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -120,8 +120,12 @@ SDL_SYS_WaitThread(SDL_Thread *thread) try { std::thread *cpp_thread = (std::thread *)thread->handle; - if (cpp_thread->joinable()) { - cpp_thread->join(); + if (cpp_thread) { + if (cpp_thread->joinable()) { + cpp_thread->join(); + } + delete cpp_thread; + thread->handle = nullptr; } } catch (std::system_error &) { // An error occurred when joining the thread. SDL_WaitThread does not, @@ -139,8 +143,12 @@ SDL_SYS_DetachThread(SDL_Thread *thread) try { std::thread *cpp_thread = (std::thread *)thread->handle; - if (cpp_thread->joinable()) { - cpp_thread->detach(); + if (cpp_thread) { + if (cpp_thread->joinable()) { + cpp_thread->detach(); + } + delete cpp_thread; + thread->handle = nullptr; } } catch (std::system_error &) { // An error occurred when detaching the thread. SDL_DetachThread does not, @@ -149,16 +157,29 @@ SDL_SYS_DetachThread(SDL_Thread *thread) } } -extern "C" SDL_TLSData * -SDL_SYS_GetTLSData(void) +static thread_local SDL_TLSData *thread_local_storage; + +extern "C" +void SDL_SYS_InitTLSData(void) { - return SDL_Generic_GetTLSData(); } -extern "C" int -SDL_SYS_SetTLSData(SDL_TLSData *data) +extern "C" +SDL_TLSData * SDL_SYS_GetTLSData(void) +{ + return thread_local_storage; +} + +extern "C" +int SDL_SYS_SetTLSData(SDL_TLSData *data) +{ + thread_local_storage = data; + return 0; +} + +extern "C" +void SDL_SYS_QuitTLSData(void) { - return SDL_Generic_SetTLSData(data); } /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/thread/stdcpp/SDL_systhread_c.h b/src/thread/stdcpp/SDL_systhread_c.h index 5cf9d11..b479a5c 100644 --- a/src/thread/stdcpp/SDL_systhread_c.h +++ b/src/thread/stdcpp/SDL_systhread_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/vita/SDL_sysmutex.c b/src/thread/vita/SDL_sysmutex.c index b030145..7c3f21d 100644 --- a/src/thread/vita/SDL_sysmutex.c +++ b/src/thread/vita/SDL_sysmutex.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/vita/SDL_sysmutex_c.h b/src/thread/vita/SDL_sysmutex_c.h index 46b7996..075ded2 100644 --- a/src/thread/vita/SDL_sysmutex_c.h +++ b/src/thread/vita/SDL_sysmutex_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/vita/SDL_syssem.c b/src/thread/vita/SDL_syssem.c index 0149ec3..da1da65 100644 --- a/src/thread/vita/SDL_syssem.c +++ b/src/thread/vita/SDL_syssem.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/vita/SDL_systhread.c b/src/thread/vita/SDL_systhread.c index 5e531b6..d3cb1b5 100644 --- a/src/thread/vita/SDL_systhread.c +++ b/src/thread/vita/SDL_systhread.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/vita/SDL_systhread_c.h b/src/thread/vita/SDL_systhread_c.h index 7419b1e..646f43e 100644 --- a/src/thread/vita/SDL_systhread_c.h +++ b/src/thread/vita/SDL_systhread_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/windows/SDL_syscond_cv.c b/src/thread/windows/SDL_syscond_cv.c index b532231..cb1bed3 100644 --- a/src/thread/windows/SDL_syscond_cv.c +++ b/src/thread/windows/SDL_syscond_cv.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/windows/SDL_sysmutex.c b/src/thread/windows/SDL_sysmutex.c index 71cdac9..ab4734d 100644 --- a/src/thread/windows/SDL_sysmutex.c +++ b/src/thread/windows/SDL_sysmutex.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/windows/SDL_sysmutex_c.h b/src/thread/windows/SDL_sysmutex_c.h index 6a0f45f..e74497b 100644 --- a/src/thread/windows/SDL_sysmutex_c.h +++ b/src/thread/windows/SDL_sysmutex_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/windows/SDL_syssem.c b/src/thread/windows/SDL_syssem.c index 4c59fc1..4a96fef 100644 --- a/src/thread/windows/SDL_syssem.c +++ b/src/thread/windows/SDL_syssem.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/windows/SDL_systhread.c b/src/thread/windows/SDL_systhread.c index 974759b..fbeabd5 100644 --- a/src/thread/windows/SDL_systhread.c +++ b/src/thread/windows/SDL_systhread.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/windows/SDL_systhread_c.h b/src/thread/windows/SDL_systhread_c.h index ae6978b..80edc26 100644 --- a/src/thread/windows/SDL_systhread_c.h +++ b/src/thread/windows/SDL_systhread_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/thread/windows/SDL_systls.c b/src/thread/windows/SDL_systls.c index 9ae61b3..dd0a711 100644 --- a/src/thread/windows/SDL_systls.c +++ b/src/thread/windows/SDL_systls.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -43,27 +43,27 @@ static DWORD thread_local_storage = TLS_OUT_OF_INDEXES; static SDL_bool generic_local_storage = SDL_FALSE; -SDL_TLSData *SDL_SYS_GetTLSData(void) +void SDL_SYS_InitTLSData(void) { if (thread_local_storage == TLS_OUT_OF_INDEXES && !generic_local_storage) { - static SDL_SpinLock lock; - SDL_AtomicLock(&lock); - if (thread_local_storage == TLS_OUT_OF_INDEXES && !generic_local_storage) { - DWORD storage = TlsAlloc(); - if (storage != TLS_OUT_OF_INDEXES) { - SDL_MemoryBarrierRelease(); - thread_local_storage = storage; - } else { - generic_local_storage = SDL_TRUE; - } + thread_local_storage = TlsAlloc(); + if (thread_local_storage == TLS_OUT_OF_INDEXES) { + SDL_Generic_InitTLSData(); + generic_local_storage = SDL_TRUE; } - SDL_AtomicUnlock(&lock); } +} + +SDL_TLSData *SDL_SYS_GetTLSData(void) +{ if (generic_local_storage) { return SDL_Generic_GetTLSData(); } - SDL_MemoryBarrierAcquire(); - return (SDL_TLSData *)TlsGetValue(thread_local_storage); + + if (thread_local_storage != TLS_OUT_OF_INDEXES) { + return (SDL_TLSData *)TlsGetValue(thread_local_storage); + } + return NULL; } int SDL_SYS_SetTLSData(SDL_TLSData *data) @@ -71,12 +71,26 @@ int SDL_SYS_SetTLSData(SDL_TLSData *data) if (generic_local_storage) { return SDL_Generic_SetTLSData(data); } + if (!TlsSetValue(thread_local_storage, data)) { - return SDL_SetError("TlsSetValue() failed"); + return WIN_SetError("TlsSetValue()"); } return 0; } +void SDL_SYS_QuitTLSData(void) +{ + if (generic_local_storage) { + SDL_Generic_QuitTLSData(); + generic_local_storage = SDL_FALSE; + } else { + if (thread_local_storage != TLS_OUT_OF_INDEXES) { + TlsFree(thread_local_storage); + thread_local_storage = TLS_OUT_OF_INDEXES; + } + } +} + #endif /* SDL_THREAD_WINDOWS */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/timer/SDL_timer.c b/src/timer/SDL_timer.c index 8cba808..a050290 100644 --- a/src/timer/SDL_timer.c +++ b/src/timer/SDL_timer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/timer/SDL_timer_c.h b/src/timer/SDL_timer_c.h index f5c1e43..2f7de5f 100644 --- a/src/timer/SDL_timer_c.h +++ b/src/timer/SDL_timer_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/timer/dummy/SDL_systimer.c b/src/timer/dummy/SDL_systimer.c index ecc31ad..b9eb0ce 100644 --- a/src/timer/dummy/SDL_systimer.c +++ b/src/timer/dummy/SDL_systimer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/timer/haiku/SDL_systimer.c b/src/timer/haiku/SDL_systimer.c index 8b038b5..6e7d6be 100644 --- a/src/timer/haiku/SDL_systimer.c +++ b/src/timer/haiku/SDL_systimer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/timer/n3ds/SDL_systimer.c b/src/timer/n3ds/SDL_systimer.c index 047b004..bc31eb8 100644 --- a/src/timer/n3ds/SDL_systimer.c +++ b/src/timer/n3ds/SDL_systimer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/timer/ngage/SDL_systimer.cpp b/src/timer/ngage/SDL_systimer.cpp index 4ddf76f..85d3dc8 100644 --- a/src/timer/ngage/SDL_systimer.cpp +++ b/src/timer/ngage/SDL_systimer.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/timer/os2/SDL_systimer.c b/src/timer/os2/SDL_systimer.c index f558855..e268d59 100644 --- a/src/timer/os2/SDL_systimer.c +++ b/src/timer/os2/SDL_systimer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/timer/ps2/SDL_systimer.c b/src/timer/ps2/SDL_systimer.c index 720f696..cc8040d 100644 --- a/src/timer/ps2/SDL_systimer.c +++ b/src/timer/ps2/SDL_systimer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/timer/psp/SDL_systimer.c b/src/timer/psp/SDL_systimer.c index c69598e..cfed572 100644 --- a/src/timer/psp/SDL_systimer.c +++ b/src/timer/psp/SDL_systimer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/timer/unix/SDL_systimer.c b/src/timer/unix/SDL_systimer.c index a697b71..7cc5dee 100644 --- a/src/timer/unix/SDL_systimer.c +++ b/src/timer/unix/SDL_systimer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/timer/vita/SDL_systimer.c b/src/timer/vita/SDL_systimer.c index d5ccabc..8aa994d 100644 --- a/src/timer/vita/SDL_systimer.c +++ b/src/timer/vita/SDL_systimer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/timer/windows/SDL_systimer.c b/src/timer/windows/SDL_systimer.c index e7c2c78..b23390d 100644 --- a/src/timer/windows/SDL_systimer.c +++ b/src/timer/windows/SDL_systimer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/SDL_RLEaccel.c b/src/video/SDL_RLEaccel.c index a007984..ee7e8fc 100644 --- a/src/video/SDL_RLEaccel.c +++ b/src/video/SDL_RLEaccel.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/SDL_RLEaccel_c.h b/src/video/SDL_RLEaccel_c.h index 5968081..88e4bf5 100644 --- a/src/video/SDL_RLEaccel_c.h +++ b/src/video/SDL_RLEaccel_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/SDL_blit.c b/src/video/SDL_blit.c index 19d47a1..9575875 100644 --- a/src/video/SDL_blit.c +++ b/src/video/SDL_blit.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -103,7 +103,7 @@ static int SDLCALL SDL_SoftBlit(SDL_Surface *src, SDL_Rect *srcrect, #ifdef __MACOSX__ #include -static SDL_bool SDL_UseAltivecPrefetch() +static SDL_bool SDL_UseAltivecPrefetch(void) { const char key[] = "hw.l3cachesize"; u_int64_t result = 0; diff --git a/src/video/SDL_blit.h b/src/video/SDL_blit.h index 731ea63..2494403 100644 --- a/src/video/SDL_blit.h +++ b/src/video/SDL_blit.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/SDL_blit_0.c b/src/video/SDL_blit_0.c index e7750dd..4056200 100644 --- a/src/video/SDL_blit_0.c +++ b/src/video/SDL_blit_0.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -605,11 +605,8 @@ SDL_FORCE_INLINE void BlitBto4Key(SDL_BlitInfo *info, const Uint32 srcbpp) } } -SDL_FORCE_INLINE void BlitBtoNAlpha(SDL_BlitInfo *info, const Uint32 srcbpp) +static void BlitBtoNAlpha(SDL_BlitInfo *info) { - const Uint32 mask = (1 << srcbpp) - 1; - const Uint32 align = (8 / srcbpp) - 1; - int width = info->dst_w; int height = info->dst_h; Uint8 *src = info->src; @@ -617,15 +614,17 @@ SDL_FORCE_INLINE void BlitBtoNAlpha(SDL_BlitInfo *info, const Uint32 srcbpp) int srcskip = info->src_skip; int dstskip = info->dst_skip; const SDL_Color *srcpal = info->src_fmt->palette->colors; + SDL_PixelFormat *srcfmt = info->src_fmt; SDL_PixelFormat *dstfmt = info->dst_fmt; - int dstbpp; + int srcbpp, dstbpp; int c; - Uint32 pixel; + Uint32 pixel, mask, align; unsigned sR, sG, sB; unsigned dR, dG, dB, dA; const unsigned A = info->a; /* Set up some basic variables */ + srcbpp = srcfmt->BytesPerPixel; dstbpp = dstfmt->BytesPerPixel; if (srcbpp == 4) srcskip += width - (width + 1) / 2; @@ -633,6 +632,8 @@ SDL_FORCE_INLINE void BlitBtoNAlpha(SDL_BlitInfo *info, const Uint32 srcbpp) srcskip += width - (width + 3) / 4; else if (srcbpp == 1) srcskip += width - (width + 7) / 8; + mask = (1 << srcbpp) - 1; + align = (8 / srcbpp) - 1; if (SDL_PIXELORDER(info->src_fmt->format) == SDL_BITMAPORDER_4321) { while (height--) { @@ -681,11 +682,8 @@ SDL_FORCE_INLINE void BlitBtoNAlpha(SDL_BlitInfo *info, const Uint32 srcbpp) } } -SDL_FORCE_INLINE void BlitBtoNAlphaKey(SDL_BlitInfo *info, const Uint32 srcbpp) +static void BlitBtoNAlphaKey(SDL_BlitInfo *info) { - const Uint32 mask = (1 << srcbpp) - 1; - const Uint32 align = (8 / srcbpp) - 1; - int width = info->dst_w; int height = info->dst_h; Uint8 *src = info->src; @@ -695,15 +693,16 @@ SDL_FORCE_INLINE void BlitBtoNAlphaKey(SDL_BlitInfo *info, const Uint32 srcbpp) SDL_PixelFormat *srcfmt = info->src_fmt; SDL_PixelFormat *dstfmt = info->dst_fmt; const SDL_Color *srcpal = srcfmt->palette->colors; - int dstbpp; + int srcbpp, dstbpp; int c; - Uint32 pixel; + Uint32 pixel, mask, align; unsigned sR, sG, sB; unsigned dR, dG, dB, dA; const unsigned A = info->a; Uint32 ckey = info->colorkey; /* Set up some basic variables */ + srcbpp = srcfmt->BytesPerPixel; dstbpp = dstfmt->BytesPerPixel; if (srcbpp == 4) srcskip += width - (width + 1) / 2; @@ -711,6 +710,8 @@ SDL_FORCE_INLINE void BlitBtoNAlphaKey(SDL_BlitInfo *info, const Uint32 srcbpp) srcskip += width - (width + 3) / 4; else if (srcbpp == 1) srcskip += width - (width + 7) / 8; + mask = (1 << srcbpp) - 1; + align = (8 / srcbpp) - 1; if (SDL_PIXELORDER(info->src_fmt->format) == SDL_BITMAPORDER_4321) { while (height--) { @@ -801,16 +802,6 @@ static const SDL_BlitFunc colorkey_blit_1b[] = { (SDL_BlitFunc)NULL, Blit1bto1Key, Blit1bto2Key, Blit1bto3Key, Blit1bto4Key }; -static void Blit1btoNAlpha(SDL_BlitInfo *info) -{ - BlitBtoNAlpha(info, 1); -} - -static void Blit1btoNAlphaKey(SDL_BlitInfo *info) -{ - BlitBtoNAlphaKey(info, 1); -} - static void Blit2bto1(SDL_BlitInfo *info) { @@ -853,16 +844,6 @@ static const SDL_BlitFunc colorkey_blit_2b[] = { (SDL_BlitFunc)NULL, Blit2bto1Key, Blit2bto2Key, Blit2bto3Key, Blit2bto4Key }; -static void Blit2btoNAlpha(SDL_BlitInfo *info) -{ - BlitBtoNAlpha(info, 2); -} - -static void Blit2btoNAlphaKey(SDL_BlitInfo *info) -{ - BlitBtoNAlphaKey(info, 2); -} - static void Blit4bto1(SDL_BlitInfo *info) { @@ -905,16 +886,6 @@ static const SDL_BlitFunc colorkey_blit_4b[] = { (SDL_BlitFunc)NULL, Blit4bto1Key, Blit4bto2Key, Blit4bto3Key, Blit4bto4Key }; -static void Blit4btoNAlpha(SDL_BlitInfo *info) -{ - BlitBtoNAlpha(info, 4); -} - -static void Blit4btoNAlphaKey(SDL_BlitInfo *info) -{ - BlitBtoNAlphaKey(info, 4); -} - SDL_BlitFunc SDL_CalculateBlit0(SDL_Surface *surface) @@ -936,10 +907,10 @@ SDL_BlitFunc SDL_CalculateBlit0(SDL_Surface *surface) return colorkey_blit_1b[which]; case SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND: - return which >= 2 ? Blit1btoNAlpha : (SDL_BlitFunc)NULL; + return which >= 2 ? BlitBtoNAlpha : (SDL_BlitFunc)NULL; case SDL_COPY_COLORKEY | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND: - return which >= 2 ? Blit1btoNAlphaKey : (SDL_BlitFunc)NULL; + return which >= 2 ? BlitBtoNAlphaKey : (SDL_BlitFunc)NULL; } return NULL; } @@ -953,10 +924,10 @@ SDL_BlitFunc SDL_CalculateBlit0(SDL_Surface *surface) return colorkey_blit_2b[which]; case SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND: - return which >= 2 ? Blit2btoNAlpha : (SDL_BlitFunc)NULL; + return which >= 2 ? BlitBtoNAlpha : (SDL_BlitFunc)NULL; case SDL_COPY_COLORKEY | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND: - return which >= 2 ? Blit2btoNAlphaKey : (SDL_BlitFunc)NULL; + return which >= 2 ? BlitBtoNAlphaKey : (SDL_BlitFunc)NULL; } return NULL; } @@ -970,10 +941,10 @@ SDL_BlitFunc SDL_CalculateBlit0(SDL_Surface *surface) return colorkey_blit_4b[which]; case SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND: - return which >= 2 ? Blit4btoNAlpha : (SDL_BlitFunc)NULL; + return which >= 2 ? BlitBtoNAlpha : (SDL_BlitFunc)NULL; case SDL_COPY_COLORKEY | SDL_COPY_MODULATE_ALPHA | SDL_COPY_BLEND: - return which >= 2 ? Blit4btoNAlphaKey : (SDL_BlitFunc)NULL; + return which >= 2 ? BlitBtoNAlphaKey : (SDL_BlitFunc)NULL; } return NULL; } diff --git a/src/video/SDL_blit_1.c b/src/video/SDL_blit_1.c index 93fdb3e..000fae7 100644 --- a/src/video/SDL_blit_1.c +++ b/src/video/SDL_blit_1.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/SDL_blit_A.c b/src/video/SDL_blit_A.c index 2cf00e0..3c99078 100644 --- a/src/video/SDL_blit_A.c +++ b/src/video/SDL_blit_A.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -1222,10 +1222,9 @@ static void BlitARGBto565PixelAlpha(SDL_BlitInfo *info) DUFFS_LOOP4({ Uint32 s = *srcp; unsigned alpha = s >> 27; /* downscale alpha to 5 bits */ - /* FIXME: Here we special-case opaque alpha since the + /* Here we special-case opaque alpha since the compositioning used (>>8 instead of /255) doesn't handle - it correctly. Also special-case alpha=0 for speed? - Benchmark this! */ + it correctly. */ if (alpha) { if (alpha == (SDL_ALPHA_OPAQUE >> 3)) { *dstp = (Uint16)((s >> 8 & 0xf800) + (s >> 5 & 0x7e0) + (s >> 3 & 0x1f)); @@ -1235,8 +1234,7 @@ static void BlitARGBto565PixelAlpha(SDL_BlitInfo *info) * convert source and destination to G0RAB65565 * and blend all components at the same time */ - s = ((s & 0xfc00) << 11) + (s >> 8 & 0xf800) - + (s >> 3 & 0x1f); + s = ((s & 0xfc00) << 11) + (s >> 8 & 0xf800) + (s >> 3 & 0x1f); d = (d | d << 16) & 0x07e0f81f; d += (s - d) * alpha >> 5; d &= 0x07e0f81f; @@ -1268,21 +1266,19 @@ static void BlitARGBto555PixelAlpha(SDL_BlitInfo *info) unsigned alpha; Uint32 s = *srcp; alpha = s >> 27; /* downscale alpha to 5 bits */ - /* FIXME: Here we special-case opaque alpha since the + /* Here we special-case opaque alpha since the compositioning used (>>8 instead of /255) doesn't handle - it correctly. Also special-case alpha=0 for speed? - Benchmark this! */ + it correctly. */ if (alpha) { if (alpha == (SDL_ALPHA_OPAQUE >> 3)) { *dstp = (Uint16)((s >> 9 & 0x7c00) + (s >> 6 & 0x3e0) + (s >> 3 & 0x1f)); } else { Uint32 d = *dstp; /* - * convert source and destination to G0RAB65565 + * convert source and destination to G0RAB55555 * and blend all components at the same time */ - s = ((s & 0xf800) << 10) + (s >> 9 & 0x7c00) - + (s >> 3 & 0x1f); + s = ((s & 0xf800) << 10) + (s >> 9 & 0x7c00) + (s >> 3 & 0x1f); d = (d | d << 16) & 0x03e07c1f; d += (s - d) * alpha >> 5; d &= 0x03e07c1f; @@ -1452,7 +1448,7 @@ SDL_BlitFunc SDL_CalculateBlitA(SDL_Surface *surface) if (sf->BytesPerPixel == 4 && sf->Amask == 0xff000000 && sf->Gmask == 0xff00 && ((sf->Rmask == 0xff && df->Rmask == 0x1f) || (sf->Bmask == 0xff && df->Bmask == 0x1f))) { if (df->Gmask == 0x7e0) { return BlitARGBto565PixelAlpha; - } else if (df->Gmask == 0x3e0) { + } else if (df->Gmask == 0x3e0 && !df->Amask) { return BlitARGBto555PixelAlpha; } } diff --git a/src/video/SDL_blit_N.c b/src/video/SDL_blit_N.c index 123d0aa..01ba0c4 100644 --- a/src/video/SDL_blit_N.c +++ b/src/video/SDL_blit_N.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/SDL_blit_auto.c b/src/video/SDL_blit_auto.c index b05dc4a..e7a25e7 100644 --- a/src/video/SDL_blit_auto.c +++ b/src/video/SDL_blit_auto.c @@ -1,7 +1,7 @@ /* DO NOT EDIT! This file is generated by sdlgenblit.pl */ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/SDL_blit_auto.h b/src/video/SDL_blit_auto.h index 1b7f227..3f76c7e 100644 --- a/src/video/SDL_blit_auto.h +++ b/src/video/SDL_blit_auto.h @@ -1,7 +1,7 @@ /* DO NOT EDIT! This file is generated by sdlgenblit.pl */ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/SDL_blit_copy.c b/src/video/SDL_blit_copy.c index 47dafb5..4559c01 100644 --- a/src/video/SDL_blit_copy.c +++ b/src/video/SDL_blit_copy.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/SDL_blit_copy.h b/src/video/SDL_blit_copy.h index 0979a87..40a0dda 100644 --- a/src/video/SDL_blit_copy.h +++ b/src/video/SDL_blit_copy.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/SDL_blit_slow.c b/src/video/SDL_blit_slow.c index 7696dcf..2cdca1c 100644 --- a/src/video/SDL_blit_slow.c +++ b/src/video/SDL_blit_slow.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/SDL_blit_slow.h b/src/video/SDL_blit_slow.h index 05b1dca..76d173f 100644 --- a/src/video/SDL_blit_slow.h +++ b/src/video/SDL_blit_slow.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/SDL_bmp.c b/src/video/SDL_bmp.c index 10e99fb..292a061 100644 --- a/src/video/SDL_bmp.c +++ b/src/video/SDL_bmp.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/SDL_clipboard.c b/src/video/SDL_clipboard.c index 3111a63..ce61b00 100644 --- a/src/video/SDL_clipboard.c +++ b/src/video/SDL_clipboard.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/SDL_egl.c b/src/video/SDL_egl.c index a89c0e8..50f7082 100644 --- a/src/video/SDL_egl.c +++ b/src/video/SDL_egl.c @@ -1,6 +1,6 @@ /* * Simple DirectMedia Layer - * Copyright (C) 1997-2024 Sam Lantinga + * Copyright (C) 1997-2025 Sam Lantinga * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages diff --git a/src/video/SDL_egl_c.h b/src/video/SDL_egl_c.h index 3fc2977..f605261 100644 --- a/src/video/SDL_egl_c.h +++ b/src/video/SDL_egl_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/SDL_fillrect.c b/src/video/SDL_fillrect.c index d7d112f..8d87d9e 100644 --- a/src/video/SDL_fillrect.c +++ b/src/video/SDL_fillrect.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -63,6 +63,13 @@ static void SDL_FillRect##bpp##SSE(Uint8 *pixels, int pitch, Uint32 color, int w Uint8 *p = NULL; \ \ SSE_BEGIN; \ + \ + /* If the number of bytes per row is equal to the pitch, treat */ \ + /* all rows as one long continuous row (for better performance) */ \ + if ((w) * (bpp) == pitch) { \ + w = w * h; \ + h = 1; \ + } \ \ while (h--) { \ n = w * bpp; \ diff --git a/src/video/SDL_pixels.c b/src/video/SDL_pixels.c index a682178..034b47c 100644 --- a/src/video/SDL_pixels.c +++ b/src/video/SDL_pixels.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/SDL_pixels_c.h b/src/video/SDL_pixels_c.h index 7b5eff3..6ad77c3 100644 --- a/src/video/SDL_pixels_c.h +++ b/src/video/SDL_pixels_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/SDL_rect.c b/src/video/SDL_rect.c index 7af1125..77653c8 100644 --- a/src/video/SDL_rect.c +++ b/src/video/SDL_rect.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/SDL_rect_c.h b/src/video/SDL_rect_c.h index b7d6e7f..bcd9658 100644 --- a/src/video/SDL_rect_c.h +++ b/src/video/SDL_rect_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/SDL_rect_impl.h b/src/video/SDL_rect_impl.h index 288a727..ffc3d85 100644 --- a/src/video/SDL_rect_impl.h +++ b/src/video/SDL_rect_impl.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/SDL_shape.c b/src/video/SDL_shape.c index 77cc8dc..2ec6d02 100644 --- a/src/video/SDL_shape.c +++ b/src/video/SDL_shape.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/SDL_shape_internals.h b/src/video/SDL_shape_internals.h index ed0b0d0..dafd3b2 100644 --- a/src/video/SDL_shape_internals.h +++ b/src/video/SDL_shape_internals.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/SDL_stretch.c b/src/video/SDL_stretch.c index a2bae05..5277b79 100644 --- a/src/video/SDL_stretch.c +++ b/src/video/SDL_stretch.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -367,7 +367,7 @@ static void printf_128(const char *str, __m128i var) } #endif -static SDL_INLINE int hasSSE2() +static SDL_INLINE int hasSSE2(void) { static int val = -1; if (val != -1) { diff --git a/src/video/SDL_surface.c b/src/video/SDL_surface.c index 9db0c50..d05c8b1 100644 --- a/src/video/SDL_surface.c +++ b/src/video/SDL_surface.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index 7dfbe32..258d2af 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,6 +24,7 @@ #define SDL_sysvideo_h_ #include "SDL_messagebox.h" +#include "SDL_mouse.h" #include "SDL_shape.h" #include "SDL_thread.h" #include "SDL_metal.h" @@ -510,6 +511,7 @@ extern void SDL_OnWindowShown(SDL_Window *window); extern void SDL_OnWindowHidden(SDL_Window *window); extern void SDL_OnWindowMoved(SDL_Window *window); extern void SDL_OnWindowResized(SDL_Window *window); +extern void SDL_OnWindowLiveResizeUpdate(SDL_Window *window); extern void SDL_OnWindowMinimized(SDL_Window *window); extern void SDL_OnWindowRestored(SDL_Window *window); extern void SDL_OnWindowEnter(SDL_Window *window); @@ -529,6 +531,10 @@ extern int SDL_GetPointDisplayIndex(const SDL_Point *point); extern int SDL_GL_SwapWindowWithResult(SDL_Window *window); +#if defined(SDL_VIDEO_DRIVER_X11) || defined(SDL_VIDEO_DRIVER_WAYLAND) || defined(SDL_VIDEO_DRIVER_EMSCRIPTEN) +const char *SDL_GetCSSCursorName(SDL_SystemCursor id, const char **fallback_name); +#endif + #endif /* SDL_sysvideo_h_ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 2ad82fa..1be5abf 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -57,6 +57,10 @@ #include #endif +#ifdef __3DS__ +#include <3ds.h> +#endif + #ifdef __LINUX__ #include #include @@ -227,26 +231,37 @@ static int SDL_CreateWindowTexture(SDL_VideoDevice *_this, SDL_Window *window, U if (!data) { SDL_Renderer *renderer = NULL; - const char *hint = SDL_GetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION); - const SDL_bool specific_accelerated_renderer = (hint && *hint != '0' && *hint != '1' && - SDL_strcasecmp(hint, "true") != 0 && - SDL_strcasecmp(hint, "false") != 0 && - SDL_strcasecmp(hint, "software") != 0); + const char *render_driver = NULL; + const char *hint; + + /* See if there's a render driver being requested */ + hint = SDL_GetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION); + if (hint && *hint != '0' && *hint != '1' && + SDL_strcasecmp(hint, "true") != 0 && + SDL_strcasecmp(hint, "false") != 0 && + SDL_strcasecmp(hint, "software") != 0) { + render_driver = hint; + } + + if (!render_driver) { + hint = SDL_GetHint(SDL_HINT_RENDER_DRIVER); + if (hint && *hint && SDL_strcasecmp(hint, "software") != 0) { + render_driver = hint; + } + } /* Check to see if there's a specific driver requested */ - if (specific_accelerated_renderer) { + if (render_driver) { for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) { SDL_GetRenderDriverInfo(i, &info); - if (SDL_strcasecmp(info.name, hint) == 0) { + if (SDL_strcasecmp(info.name, render_driver) == 0) { renderer = SDL_CreateRenderer(window, i, 0); break; } } - if (!renderer || (SDL_GetRendererInfo(renderer, &info) == -1)) { - if (renderer) { - SDL_DestroyRenderer(renderer); - } - return SDL_SetError("Requested renderer for " SDL_HINT_FRAMEBUFFER_ACCELERATION " is not available"); + if (!renderer) { + /* The error for this specific renderer has already been set */ + return -1; } /* if it was specifically requested, even if SDL_RENDERER_ACCELERATED isn't set, we'll accept this renderer. */ } else { @@ -672,9 +687,9 @@ void SDL_DelVideoDisplay(int index) SDL_SendDisplayEvent(&_this->displays[index], SDL_DISPLAYEVENT_DISCONNECTED, 0); + SDL_free(_this->displays[index].driverdata); + SDL_free(_this->displays[index].name); if (index < (_this->num_displays - 1)) { - SDL_free(_this->displays[index].driverdata); - SDL_free(_this->displays[index].name); SDL_memmove(&_this->displays[index], &_this->displays[index + 1], (_this->num_displays - index - 1) * sizeof(_this->displays[index])); } --_this->num_displays; @@ -1941,12 +1956,6 @@ int SDL_RecreateWindow(SDL_Window *window, Uint32 flags) /* Tear down the old native window */ SDL_DestroyWindowSurface(window); - if (_this->checked_texture_framebuffer) { /* never checked? No framebuffer to destroy. Don't risk calling the wrong implementation. */ - if (_this->DestroyWindowFramebuffer) { - _this->DestroyWindowFramebuffer(_this, window); - } - } - if (_this->DestroyWindow && !(flags & SDL_WINDOW_FOREIGN)) { _this->DestroyWindow(_this, window); } @@ -2645,39 +2654,29 @@ int SDL_SetWindowFullscreen(SDL_Window *window, Uint32 flags) return -1; } -static SDL_Surface *SDL_CreateWindowFramebuffer(SDL_Window *window) +static SDL_bool ShouldAttemptTextureFramebuffer(void) { - Uint32 format = 0; - void *pixels = NULL; - int pitch = 0; - int bpp; - Uint32 Rmask, Gmask, Bmask, Amask; - SDL_bool created_framebuffer = SDL_FALSE; - int w, h; - - SDL_GetWindowSizeInPixels(window, &w, &h); - - /* This will switch the video backend from using a software surface to - using a GPU texture through the 2D render API, if we think this would - be more efficient. This only checks once, on demand. */ - if (!_this->checked_texture_framebuffer) { - SDL_bool attempt_texture_framebuffer = SDL_TRUE; + const char *hint; + SDL_bool attempt_texture_framebuffer = SDL_TRUE; - /* See if the user or application wants to specifically disable the framebuffer */ - const char *hint = SDL_GetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION); - if (hint) { - if ((*hint == '0') || (SDL_strcasecmp(hint, "false") == 0) || (SDL_strcasecmp(hint, "software") == 0)) { - attempt_texture_framebuffer = SDL_FALSE; - } - } + /* The dummy driver never has GPU support, of course. */ + if (_this->is_dummy) { + return SDL_FALSE; + } - if (_this->is_dummy) { /* dummy driver never has GPU support, of course. */ + /* See if there's a hint override */ + hint = SDL_GetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION); + if (hint && *hint) { + if (*hint == '0' || SDL_strcasecmp(hint, "false") == 0 || SDL_strcasecmp(hint, "software") == 0) { attempt_texture_framebuffer = SDL_FALSE; + } else { + attempt_texture_framebuffer = SDL_TRUE; } - + } else { + /* Check for platform specific defaults */ #if defined(__LINUX__) /* On WSL, direct X11 is faster than using OpenGL for window framebuffers, so try to detect WSL and avoid texture framebuffer. */ - else if ((_this->CreateWindowFramebuffer) && (SDL_strcmp(_this->name, "x11") == 0)) { + if ((_this->CreateWindowFramebuffer) && (SDL_strcmp(_this->name, "x11") == 0)) { struct stat sb; if ((stat("/proc/sys/fs/binfmt_misc/WSLInterop", &sb) == 0) || (stat("/run/WSL", &sb) == 0)) { /* if either of these exist, we're on WSL. */ attempt_texture_framebuffer = SDL_FALSE; @@ -2685,18 +2684,35 @@ static SDL_Surface *SDL_CreateWindowFramebuffer(SDL_Window *window) } #endif #if defined(__WIN32__) || defined(__WINGDK__) /* GDI BitBlt() is way faster than Direct3D dynamic textures right now. (!!! FIXME: is this still true?) */ - else if ((_this->CreateWindowFramebuffer) && (SDL_strcmp(_this->name, "windows") == 0)) { + if (_this->CreateWindowFramebuffer && (SDL_strcmp(_this->name, "windows") == 0)) { attempt_texture_framebuffer = SDL_FALSE; } #endif #if defined(__EMSCRIPTEN__) - else { - attempt_texture_framebuffer = SDL_FALSE; - } + attempt_texture_framebuffer = SDL_FALSE; #endif + } + return attempt_texture_framebuffer; +} + +static SDL_Surface *SDL_CreateWindowFramebuffer(SDL_Window *window) +{ + Uint32 format = 0; + void *pixels = NULL; + int pitch = 0; + int bpp; + Uint32 Rmask, Gmask, Bmask, Amask; + SDL_bool created_framebuffer = SDL_FALSE; + int w, h; + + SDL_GetWindowSizeInPixels(window, &w, &h); - if (attempt_texture_framebuffer) { - if (SDL_CreateWindowTexture(_this, window, &format, &pixels, &pitch) == -1) { + /* This will switch the video backend from using a software surface to + using a GPU texture through the 2D render API, if we think this would + be more efficient. This only checks once, on demand. */ + if (!_this->checked_texture_framebuffer) { + if (ShouldAttemptTextureFramebuffer()) { + if (SDL_CreateWindowTexture(_this, window, &format, &pixels, &pitch) < 0) { /* !!! FIXME: if this failed halfway (made renderer, failed to make texture, etc), !!! FIXME: we probably need to clean this up so it doesn't interfere with !!! FIXME: a software fallback at the system level (can we blit to an @@ -2718,6 +2734,7 @@ static SDL_Surface *SDL_CreateWindowFramebuffer(SDL_Window *window) if (!created_framebuffer) { if (!_this->CreateWindowFramebuffer || !_this->UpdateWindowFramebuffer) { + SDL_SetError("Window framebuffer support not available"); return NULL; } @@ -2727,6 +2744,7 @@ static SDL_Surface *SDL_CreateWindowFramebuffer(SDL_Window *window) } if (window->surface) { + /* We may have gone recursive and already created the surface */ return window->surface; } @@ -2749,7 +2767,12 @@ SDL_Surface *SDL_GetWindowSurface(SDL_Window *window) CHECK_WINDOW_MAGIC(window, NULL); if (!window->surface_valid) { - SDL_DestroyWindowSurface(window); + if (window->surface) { + window->surface->flags &= ~SDL_DONTFREE; + SDL_FreeSurface(window->surface); + window->surface = NULL; + } + window->surface = SDL_CreateWindowFramebuffer(window); if (window->surface) { window->surface_valid = SDL_TRUE; @@ -2786,6 +2809,25 @@ int SDL_UpdateWindowSurfaceRects(SDL_Window *window, const SDL_Rect *rects, return _this->UpdateWindowFramebuffer(_this, window, rects, numrects); } +int SDL_DestroyWindowSurface(SDL_Window *window) +{ + CHECK_WINDOW_MAGIC(window, -1); + + if (window->surface) { + window->surface->flags &= ~SDL_DONTFREE; + SDL_FreeSurface(window->surface); + window->surface = NULL; + window->surface_valid = SDL_FALSE; + } + + if (_this->checked_texture_framebuffer) { /* never checked? No framebuffer to destroy. Don't risk calling the wrong implementation. */ + if (_this->DestroyWindowFramebuffer) { + _this->DestroyWindowFramebuffer(_this, window); + } + } + return 0; +} + int SDL_SetWindowBrightness(SDL_Window * window, float brightness) { Uint16 ramp[256]; @@ -2831,19 +2873,6 @@ int SDL_SetWindowOpacity(SDL_Window * window, float opacity) return retval; } -int SDL_DestroyWindowSurface(SDL_Window *window) -{ - CHECK_WINDOW_MAGIC(window, -1); - - if (window->surface) { - window->surface->flags &= ~SDL_DONTFREE; - SDL_FreeSurface(window->surface); - window->surface = NULL; - window->surface_valid = SDL_FALSE; - } - return 0; -} - int SDL_GetWindowOpacity(SDL_Window *window, float *out_opacity) { CHECK_WINDOW_MAGIC(window, -1); @@ -3142,6 +3171,12 @@ void SDL_OnWindowMoved(SDL_Window *window) } } +void SDL_OnWindowLiveResizeUpdate(SDL_Window *window) +{ + /* Send an expose event so the application can redraw */ + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_EXPOSED, 0, 0); +} + void SDL_OnWindowMinimized(SDL_Window *window) { if (!DisableUnsetFullscreenOnMinimize(_this)) { @@ -3278,23 +3313,22 @@ void SDL_DestroyWindow(SDL_Window *window) if (SDL_GetKeyboardFocus() == window) { SDL_SetKeyboardFocus(NULL); } + if ((window->flags & SDL_WINDOW_MOUSE_CAPTURE)) { + SDL_UpdateMouseCapture(SDL_TRUE); + } if (SDL_GetMouseFocus() == window) { SDL_SetMouseFocus(NULL); } - /* make no context current if this is the current context window. */ + SDL_DestroyWindowSurface(window); + + /* Make no context current if this is the current context window */ if (window->flags & SDL_WINDOW_OPENGL) { if (_this->current_glwin == window) { SDL_GL_MakeCurrent(window, NULL); } } - SDL_DestroyWindowSurface(window); - if (_this->checked_texture_framebuffer) { /* never checked? No framebuffer to destroy. Don't risk calling the wrong implementation. */ - if (_this->DestroyWindowFramebuffer) { - _this->DestroyWindowFramebuffer(_this, window); - } - } if (_this->DestroyWindow) { _this->DestroyWindow(_this, window); } @@ -4518,6 +4552,23 @@ int SDL_ShowSimpleMessageBox(Uint32 flags, const char *title, const char *messag }, title, message); return 0; +#elif defined(__3DS__) + errorConf errCnf; + bool hasGpuRight; + + /* If the video subsystem has not been initialised, set up graphics temporarily */ + hasGpuRight = gspHasGpuRight(); + if (!hasGpuRight) + gfxInitDefault(); + + errorInit(&errCnf, ERROR_TEXT_WORD_WRAP, CFG_LANGUAGE_EN); + errorText(&errCnf, message); + errorDisp(&errCnf); + + if (!hasGpuRight) + gfxExit(); + + return 0; #else SDL_MessageBoxData data; SDL_MessageBoxButtonData button; @@ -4780,4 +4831,93 @@ void SDL_Metal_GetDrawableSize(SDL_Window *window, int *w, int *h) } } +#if defined(SDL_VIDEO_DRIVER_X11) || defined(SDL_VIDEO_DRIVER_WAYLAND) || defined(SDL_VIDEO_DRIVER_EMSCRIPTEN) +const char *SDL_GetCSSCursorName(SDL_SystemCursor id, const char **fallback_name) +{ + /* Reference: https://www.w3.org/TR/css-ui-4/#cursor */ + /* Also in: https://www.freedesktop.org/wiki/Specifications/cursor-spec/ */ + switch (id) { + case SDL_SYSTEM_CURSOR_ARROW: + return "default"; + + case SDL_SYSTEM_CURSOR_IBEAM: + return "text"; + + case SDL_SYSTEM_CURSOR_WAIT: + return "wait"; + + case SDL_SYSTEM_CURSOR_CROSSHAIR: + return "crosshair"; + + case SDL_SYSTEM_CURSOR_WAITARROW: + return "progress"; + + case SDL_SYSTEM_CURSOR_SIZENWSE: + if (fallback_name) { + /* only a single arrow */ + *fallback_name = "nw-resize"; + } + return "nwse-resize"; + + case SDL_SYSTEM_CURSOR_SIZENESW: + if (fallback_name) { + /* only a single arrow */ + *fallback_name = "ne-resize"; + } + return "nesw-resize"; + + case SDL_SYSTEM_CURSOR_SIZEWE: + if (fallback_name) { + *fallback_name = "col-resize"; + } + return "ew-resize"; + + case SDL_SYSTEM_CURSOR_SIZENS: + if (fallback_name) { + *fallback_name = "row-resize"; + } + return "ns-resize"; + + case SDL_SYSTEM_CURSOR_SIZEALL: + return "all-scroll"; + + case SDL_SYSTEM_CURSOR_NO: + return "not-allowed"; + + case SDL_SYSTEM_CURSOR_HAND: + return "pointer"; + +#if 0 + case SDL_SYSTEM_CURSOR_WINDOW_TOPLEFT: + return "nw-resize"; + + case SDL_SYSTEM_CURSOR_WINDOW_TOP: + return "n-resize"; + + case SDL_SYSTEM_CURSOR_WINDOW_TOPRIGHT: + return "ne-resize"; + + case SDL_SYSTEM_CURSOR_WINDOW_RIGHT: + return "e-resize"; + + case SDL_SYSTEM_CURSOR_WINDOW_BOTTOMRIGHT: + return "se-resize"; + + case SDL_SYSTEM_CURSOR_WINDOW_BOTTOM: + return "s-resize"; + + case SDL_SYSTEM_CURSOR_WINDOW_BOTTOMLEFT: + return "sw-resize"; + + case SDL_SYSTEM_CURSOR_WINDOW_LEFT: + return "w-resize"; +#endif + + default: + SDL_assert(0); + return "default"; + } +} +#endif + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/SDL_vulkan_internal.h b/src/video/SDL_vulkan_internal.h index 28728fa..ac14f9a 100644 --- a/src/video/SDL_vulkan_internal.h +++ b/src/video/SDL_vulkan_internal.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/SDL_vulkan_utils.c b/src/video/SDL_vulkan_utils.c index 7a1579d..1c796e7 100644 --- a/src/video/SDL_vulkan_utils.c +++ b/src/video/SDL_vulkan_utils.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/SDL_yuv.c b/src/video/SDL_yuv.c index 14f5746..3334b75 100644 --- a/src/video/SDL_yuv.c +++ b/src/video/SDL_yuv.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/SDL_yuv_c.h b/src/video/SDL_yuv_c.h index 3fda84b..ea58ea4 100644 --- a/src/video/SDL_yuv_c.h +++ b/src/video/SDL_yuv_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/android/SDL_androidclipboard.c b/src/video/android/SDL_androidclipboard.c index afd729e..6a8b872 100644 --- a/src/video/android/SDL_androidclipboard.c +++ b/src/video/android/SDL_androidclipboard.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/android/SDL_androidclipboard.h b/src/video/android/SDL_androidclipboard.h index 8097d71..eee537b 100644 --- a/src/video/android/SDL_androidclipboard.h +++ b/src/video/android/SDL_androidclipboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/android/SDL_androidevents.c b/src/video/android/SDL_androidevents.c index cbb3b02..cbe7dd1 100644 --- a/src/video/android/SDL_androidevents.c +++ b/src/video/android/SDL_androidevents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -150,10 +150,7 @@ void Android_PumpEvents_Blocking(_THIS) #endif /* Make sure SW Keyboard is restored when an app becomes foreground */ - if (SDL_IsTextInputActive() && - SDL_GetHintBoolean(SDL_HINT_ENABLE_SCREEN_KEYBOARD, SDL_TRUE)) { - Android_ShowScreenKeyboard(_this, Android_Window); /* Only showTextInput */ - } + Android_RestoreScreenKeyboardOnResume(_this, Android_Window); } } else { if (videodata->isPausing || SDL_SemTryWait(Android_PauseSem) == 0) { @@ -235,10 +232,7 @@ void Android_PumpEvents_NonBlocking(_THIS) #endif /* Make sure SW Keyboard is restored when an app becomes foreground */ - if (SDL_IsTextInputActive() && - SDL_GetHintBoolean(SDL_HINT_ENABLE_SCREEN_KEYBOARD, SDL_TRUE)) { - Android_ShowScreenKeyboard(_this, Android_Window); /* Only showTextInput */ - } + Android_RestoreScreenKeyboardOnResume(_this, Android_Window); } } else { if (videodata->isPausing || SDL_SemTryWait(Android_PauseSem) == 0) { diff --git a/src/video/android/SDL_androidevents.h b/src/video/android/SDL_androidevents.h index 921daa6..cf043aa 100644 --- a/src/video/android/SDL_androidevents.h +++ b/src/video/android/SDL_androidevents.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/android/SDL_androidgl.c b/src/video/android/SDL_androidgl.c index 5e5ef60..dade42b 100644 --- a/src/video/android/SDL_androidgl.c +++ b/src/video/android/SDL_androidgl.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/android/SDL_androidgl.h b/src/video/android/SDL_androidgl.h index 4fb505c..e9fd3fb 100644 --- a/src/video/android/SDL_androidgl.h +++ b/src/video/android/SDL_androidgl.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/android/SDL_androidkeyboard.c b/src/video/android/SDL_androidkeyboard.c index 13b0563..a9ad490 100644 --- a/src/video/android/SDL_androidkeyboard.c +++ b/src/video/android/SDL_androidkeyboard.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -313,6 +313,8 @@ static SDL_Scancode Android_Keycodes[] = { SDL_SCANCODE_PASTE, /* AKEYCODE_PASTE */ }; +static SDL_bool SDL_screen_keyboard_shown; + static SDL_Scancode TranslateKeycode(int keycode) { SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN; @@ -345,11 +347,20 @@ void Android_ShowScreenKeyboard(_THIS, SDL_Window *window) { SDL_VideoData *videodata = _this->driverdata; Android_JNI_ShowScreenKeyboard(&videodata->textRect); + SDL_screen_keyboard_shown = SDL_TRUE; } void Android_HideScreenKeyboard(_THIS, SDL_Window *window) { Android_JNI_HideScreenKeyboard(); + SDL_screen_keyboard_shown = SDL_FALSE; +} + +void Android_RestoreScreenKeyboardOnResume(_THIS, SDL_Window *window) +{ + if (SDL_screen_keyboard_shown) { + Android_ShowScreenKeyboard(_this, window); + } } SDL_bool Android_IsScreenKeyboardShown(_THIS, SDL_Window *window) diff --git a/src/video/android/SDL_androidkeyboard.h b/src/video/android/SDL_androidkeyboard.h index 1124b4a..829a4f4 100644 --- a/src/video/android/SDL_androidkeyboard.h +++ b/src/video/android/SDL_androidkeyboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,6 +28,7 @@ extern int Android_OnKeyUp(int keycode); extern SDL_bool Android_HasScreenKeyboardSupport(_THIS); extern void Android_ShowScreenKeyboard(_THIS, SDL_Window *window); extern void Android_HideScreenKeyboard(_THIS, SDL_Window *window); +extern void Android_RestoreScreenKeyboardOnResume(_THIS, SDL_Window *window); extern SDL_bool Android_IsScreenKeyboardShown(_THIS, SDL_Window *window); extern void Android_SetTextInputRect(_THIS, const SDL_Rect *rect); diff --git a/src/video/android/SDL_androidmessagebox.c b/src/video/android/SDL_androidmessagebox.c index cb2ad28..d30c6e6 100644 --- a/src/video/android/SDL_androidmessagebox.c +++ b/src/video/android/SDL_androidmessagebox.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/android/SDL_androidmessagebox.h b/src/video/android/SDL_androidmessagebox.h index 7c93c0e..254790c 100644 --- a/src/video/android/SDL_androidmessagebox.h +++ b/src/video/android/SDL_androidmessagebox.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/android/SDL_androidmouse.c b/src/video/android/SDL_androidmouse.c index 29ee05e..4f12dd1 100644 --- a/src/video/android/SDL_androidmouse.c +++ b/src/video/android/SDL_androidmouse.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -78,7 +78,7 @@ static SDL_Cursor *Android_WrapCursor(int custom_cursor, int system_cursor) return cursor; } -static SDL_Cursor *Android_CreateDefaultCursor() +static SDL_Cursor *Android_CreateDefaultCursor(void) { return Android_WrapCursor(0, SDL_SYSTEM_CURSOR_ARROW); } @@ -116,7 +116,7 @@ static void Android_FreeCursor(SDL_Cursor *cursor) SDL_free(cursor); } -static SDL_Cursor *Android_CreateEmptyCursor() +static SDL_Cursor *Android_CreateEmptyCursor(void) { if (!empty_cursor) { SDL_Surface *empty_surface = SDL_CreateRGBSurfaceWithFormat(0, 1, 1, 32, SDL_PIXELFORMAT_ARGB8888); @@ -129,7 +129,7 @@ static SDL_Cursor *Android_CreateEmptyCursor() return empty_cursor; } -static void Android_DestroyEmptyCursor() +static void Android_DestroyEmptyCursor(void) { if (empty_cursor) { Android_FreeCursor(empty_cursor); diff --git a/src/video/android/SDL_androidmouse.h b/src/video/android/SDL_androidmouse.h index 6ff7249..561a1f8 100644 --- a/src/video/android/SDL_androidmouse.h +++ b/src/video/android/SDL_androidmouse.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/android/SDL_androidtouch.c b/src/video/android/SDL_androidtouch.c index c44f2b0..5741a86 100644 --- a/src/video/android/SDL_androidtouch.c +++ b/src/video/android/SDL_androidtouch.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/android/SDL_androidtouch.h b/src/video/android/SDL_androidtouch.h index 067842a..806f6b8 100644 --- a/src/video/android/SDL_androidtouch.h +++ b/src/video/android/SDL_androidtouch.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/android/SDL_androidvideo.c b/src/video/android/SDL_androidvideo.c index f54b4c3..12a976c 100644 --- a/src/video/android/SDL_androidvideo.c +++ b/src/video/android/SDL_androidvideo.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/android/SDL_androidvideo.h b/src/video/android/SDL_androidvideo.h index 7eb4f9a..0ba1326 100644 --- a/src/video/android/SDL_androidvideo.h +++ b/src/video/android/SDL_androidvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/android/SDL_androidvulkan.c b/src/video/android/SDL_androidvulkan.c index 6ade57e..c4c2155 100644 --- a/src/video/android/SDL_androidvulkan.c +++ b/src/video/android/SDL_androidvulkan.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/android/SDL_androidvulkan.h b/src/video/android/SDL_androidvulkan.h index caee0a6..2cf99e8 100644 --- a/src/video/android/SDL_androidvulkan.h +++ b/src/video/android/SDL_androidvulkan.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/android/SDL_androidwindow.c b/src/video/android/SDL_androidwindow.c index 2624331..7af5669 100644 --- a/src/video/android/SDL_androidwindow.c +++ b/src/video/android/SDL_androidwindow.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/android/SDL_androidwindow.h b/src/video/android/SDL_androidwindow.h index 240c77c..eddfe7f 100644 --- a/src/video/android/SDL_androidwindow.h +++ b/src/video/android/SDL_androidwindow.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/cocoa/SDL_cocoaclipboard.h b/src/video/cocoa/SDL_cocoaclipboard.h index a7b7a54..b3b3d81 100644 --- a/src/video/cocoa/SDL_cocoaclipboard.h +++ b/src/video/cocoa/SDL_cocoaclipboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/cocoa/SDL_cocoaclipboard.m b/src/video/cocoa/SDL_cocoaclipboard.m index 136dba4..5b32bbc 100644 --- a/src/video/cocoa/SDL_cocoaclipboard.m +++ b/src/video/cocoa/SDL_cocoaclipboard.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/cocoa/SDL_cocoaevents.h b/src/video/cocoa/SDL_cocoaevents.h index 421df3a..e99089a 100644 --- a/src/video/cocoa/SDL_cocoaevents.h +++ b/src/video/cocoa/SDL_cocoaevents.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/cocoa/SDL_cocoaevents.m b/src/video/cocoa/SDL_cocoaevents.m index 441985d..25f8aa9 100644 --- a/src/video/cocoa/SDL_cocoaevents.m +++ b/src/video/cocoa/SDL_cocoaevents.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/cocoa/SDL_cocoakeyboard.h b/src/video/cocoa/SDL_cocoakeyboard.h index d080664..62d6f03 100644 --- a/src/video/cocoa/SDL_cocoakeyboard.h +++ b/src/video/cocoa/SDL_cocoakeyboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/cocoa/SDL_cocoakeyboard.m b/src/video/cocoa/SDL_cocoakeyboard.m index 605a4d4..2a67632 100644 --- a/src/video/cocoa/SDL_cocoakeyboard.m +++ b/src/video/cocoa/SDL_cocoakeyboard.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/cocoa/SDL_cocoamessagebox.h b/src/video/cocoa/SDL_cocoamessagebox.h index 765ffe7..501ffa5 100644 --- a/src/video/cocoa/SDL_cocoamessagebox.h +++ b/src/video/cocoa/SDL_cocoamessagebox.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/cocoa/SDL_cocoamessagebox.m b/src/video/cocoa/SDL_cocoamessagebox.m index 4e342c1..90b0644 100644 --- a/src/video/cocoa/SDL_cocoamessagebox.m +++ b/src/video/cocoa/SDL_cocoamessagebox.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/cocoa/SDL_cocoametalview.h b/src/video/cocoa/SDL_cocoametalview.h index d4a5374..b8b6b7a 100644 --- a/src/video/cocoa/SDL_cocoametalview.h +++ b/src/video/cocoa/SDL_cocoametalview.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/cocoa/SDL_cocoametalview.m b/src/video/cocoa/SDL_cocoametalview.m index d71f651..9591f97 100644 --- a/src/video/cocoa/SDL_cocoametalview.m +++ b/src/video/cocoa/SDL_cocoametalview.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/cocoa/SDL_cocoamodes.h b/src/video/cocoa/SDL_cocoamodes.h index 426036e..dc6273d 100644 --- a/src/video/cocoa/SDL_cocoamodes.h +++ b/src/video/cocoa/SDL_cocoamodes.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/cocoa/SDL_cocoamodes.m b/src/video/cocoa/SDL_cocoamodes.m index d1ef99e..fa5b184 100644 --- a/src/video/cocoa/SDL_cocoamodes.m +++ b/src/video/cocoa/SDL_cocoamodes.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/cocoa/SDL_cocoamouse.h b/src/video/cocoa/SDL_cocoamouse.h index 0d5f5db..4fee865 100644 --- a/src/video/cocoa/SDL_cocoamouse.h +++ b/src/video/cocoa/SDL_cocoamouse.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/cocoa/SDL_cocoamouse.m b/src/video/cocoa/SDL_cocoamouse.m index c14f9ab..e70c409 100644 --- a/src/video/cocoa/SDL_cocoamouse.m +++ b/src/video/cocoa/SDL_cocoamouse.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/cocoa/SDL_cocoaopengl.h b/src/video/cocoa/SDL_cocoaopengl.h index 26462bb..f152a72 100644 --- a/src/video/cocoa/SDL_cocoaopengl.h +++ b/src/video/cocoa/SDL_cocoaopengl.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/cocoa/SDL_cocoaopengl.m b/src/video/cocoa/SDL_cocoaopengl.m index bda9315..ffc59e6 100644 --- a/src/video/cocoa/SDL_cocoaopengl.m +++ b/src/video/cocoa/SDL_cocoaopengl.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -507,13 +507,31 @@ int Cocoa_GL_SwapWindow(_THIS, SDL_Window * window) return 0; }} +static void DispatchedDeleteContext(SDL_GLContext context) +{ + @autoreleasepool { + SDLOpenGLContext *nscontext = (__bridge SDLOpenGLContext *)context; + [nscontext cleanup]; + CFRelease(context); + } +} + void Cocoa_GL_DeleteContext(_THIS, SDL_GLContext context) -{ @autoreleasepool { - SDLOpenGLContext *nscontext = (__bridge SDLOpenGLContext *)context; - [nscontext cleanup]; - CFRelease(context); -}} + if ([NSThread isMainThread]) { + DispatchedDeleteContext(context); + } else { + if (SDL_opengl_async_dispatch) { + dispatch_async(dispatch_get_main_queue(), ^{ + DispatchedDeleteContext(context); + }); + } else { + dispatch_sync(dispatch_get_main_queue(), ^{ + DispatchedDeleteContext(context); + }); + } + } +} /* We still support OpenGL as long as Apple offers it, deprecated or not, so disable deprecation warnings about it. */ #ifdef __clang__ diff --git a/src/video/cocoa/SDL_cocoaopengles.h b/src/video/cocoa/SDL_cocoaopengles.h index 0729b6b..8ec93a3 100644 --- a/src/video/cocoa/SDL_cocoaopengles.h +++ b/src/video/cocoa/SDL_cocoaopengles.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/cocoa/SDL_cocoaopengles.m b/src/video/cocoa/SDL_cocoaopengles.m index abb2014..0746460 100644 --- a/src/video/cocoa/SDL_cocoaopengles.m +++ b/src/video/cocoa/SDL_cocoaopengles.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/cocoa/SDL_cocoashape.h b/src/video/cocoa/SDL_cocoashape.h index f37c2d4..82b8658 100644 --- a/src/video/cocoa/SDL_cocoashape.h +++ b/src/video/cocoa/SDL_cocoashape.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/cocoa/SDL_cocoashape.m b/src/video/cocoa/SDL_cocoashape.m index 11642de..e1421ee 100644 --- a/src/video/cocoa/SDL_cocoashape.m +++ b/src/video/cocoa/SDL_cocoashape.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/cocoa/SDL_cocoavideo.h b/src/video/cocoa/SDL_cocoavideo.h index 0082171..d7663f9 100644 --- a/src/video/cocoa/SDL_cocoavideo.h +++ b/src/video/cocoa/SDL_cocoavideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/cocoa/SDL_cocoavideo.m b/src/video/cocoa/SDL_cocoavideo.m index 156af89..811e85d 100644 --- a/src/video/cocoa/SDL_cocoavideo.m +++ b/src/video/cocoa/SDL_cocoavideo.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/cocoa/SDL_cocoavulkan.h b/src/video/cocoa/SDL_cocoavulkan.h index fc90ee1..3de20dc 100644 --- a/src/video/cocoa/SDL_cocoavulkan.h +++ b/src/video/cocoa/SDL_cocoavulkan.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/cocoa/SDL_cocoavulkan.m b/src/video/cocoa/SDL_cocoavulkan.m index d1ea16f..1454de5 100644 --- a/src/video/cocoa/SDL_cocoavulkan.m +++ b/src/video/cocoa/SDL_cocoavulkan.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/cocoa/SDL_cocoawindow.h b/src/video/cocoa/SDL_cocoawindow.h index 0cf9e9a..2f93246 100644 --- a/src/video/cocoa/SDL_cocoawindow.h +++ b/src/video/cocoa/SDL_cocoawindow.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -54,6 +54,7 @@ typedef enum NSInteger focusClickPending; int pendingWindowWarpX, pendingWindowWarpY; BOOL isDragAreaRunning; + NSTimer *liveResizeTimer; } -(BOOL) isTouchFromTrackpad:(NSEvent *)theEvent; @@ -77,6 +78,8 @@ typedef enum /* Window delegate functionality */ -(BOOL) windowShouldClose:(id) sender; -(void) windowDidExpose:(NSNotification *) aNotification; +-(void) windowWillStartLiveResize:(NSNotification *)aNotification; +-(void) windowDidEndLiveResize:(NSNotification *)aNotification; -(void) windowDidMove:(NSNotification *) aNotification; -(void) windowDidResize:(NSNotification *) aNotification; -(void) windowDidMiniaturize:(NSNotification *) aNotification; diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m index b7ff1ca..0dc6383 100644 --- a/src/video/cocoa/SDL_cocoawindow.m +++ b/src/video/cocoa/SDL_cocoawindow.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -460,6 +460,17 @@ static void Cocoa_UpdateClipCursor(SDL_Window * window) } } +static NSCursor *Cocoa_GetDesiredCursor(void) +{ + SDL_Mouse *mouse = SDL_GetMouse(); + + if (mouse->cursor_shown && mouse->cur_cursor && !mouse->relative_mode) { + return (__bridge NSCursor *)mouse->cur_cursor->driverdata; + } + + return [NSCursor invisibleCursor]; +} + @implementation Cocoa_WindowListener @@ -479,11 +490,14 @@ - (void)listen:(SDL_WindowData *)data isMoving = NO; isDragAreaRunning = NO; pendingWindowWarpX = pendingWindowWarpY = INT_MAX; + liveResizeTimer = nil; center = [NSNotificationCenter defaultCenter]; if ([window delegate] != nil) { [center addObserver:self selector:@selector(windowDidExpose:) name:NSWindowDidExposeNotification object:window]; + [center addObserver:self selector:@selector(windowWillStartLiveResize:) name:NSWindowWillStartLiveResizeNotification object:window]; + [center addObserver:self selector:@selector(windowDidEndLiveResize:) name:NSWindowDidEndLiveResizeNotification object:window]; [center addObserver:self selector:@selector(windowDidMove:) name:NSWindowDidMoveNotification object:window]; [center addObserver:self selector:@selector(windowDidResize:) name:NSWindowDidResizeNotification object:window]; [center addObserver:self selector:@selector(windowDidMiniaturize:) name:NSWindowDidMiniaturizeNotification object:window]; @@ -617,6 +631,8 @@ - (void)close if ([window delegate] != self) { [center removeObserver:self name:NSWindowDidExposeNotification object:window]; + [center removeObserver:self name:NSWindowWillStartLiveResizeNotification object:window]; + [center removeObserver:self name:NSWindowDidEndLiveResizeNotification object:window]; [center removeObserver:self name:NSWindowDidMoveNotification object:window]; [center removeObserver:self name:NSWindowDidResizeNotification object:window]; [center removeObserver:self name:NSWindowDidMiniaturizeNotification object:window]; @@ -727,6 +743,26 @@ - (void)windowDidExpose:(NSNotification *)aNotification SDL_SendWindowEvent(_data.window, SDL_WINDOWEVENT_EXPOSED, 0, 0); } +- (void)windowWillStartLiveResize:(NSNotification *)aNotification +{ + // We'll try to maintain 60 FPS during live resizing + const NSTimeInterval interval = 1.0 / 60.0; + liveResizeTimer = [NSTimer scheduledTimerWithTimeInterval:interval + repeats:TRUE + block:^(NSTimer *unusedTimer) + { + SDL_OnWindowLiveResizeUpdate(_data.window); + }]; + + [[NSRunLoop currentRunLoop] addTimer:liveResizeTimer forMode:NSRunLoopCommonModes]; +} + +- (void)windowDidEndLiveResize:(NSNotification *)aNotification +{ + [liveResizeTimer invalidate]; + liveResizeTimer = nil; +} + - (void)windowWillMove:(NSNotification *)aNotification { if ([_data.nswindow isKindOfClass:[SDLWindow class]]) { @@ -922,11 +958,13 @@ - (void)windowDidChangeScreenProfile:(NSNotification *)aNotification - (void)windowDidChangeScreen:(NSNotification *)aNotification { /*printf("WINDOWDIDCHANGESCREEN\n");*/ +#ifdef SDL_VIDEO_OPENGL if (_data && _data.nscontexts) { for (SDLOpenGLContext *context in _data.nscontexts) { [context movedToNewScreen]; } } +#endif /* SDL_VIDEO_OPENGL */ } - (void)windowWillEnterFullScreen:(NSNotification *)aNotification @@ -1323,6 +1361,7 @@ - (void)mouseMoved:(NSEvent *)theEvent NSPoint point; int x, y; SDL_Window *window; + NSView *contentView; if (!mouse) { return; @@ -1330,6 +1369,17 @@ - (void)mouseMoved:(NSEvent *)theEvent mouseID = mouse->mouseID; window = _data.window; + contentView = _data.sdlContentView; + point = [theEvent locationInWindow]; + + if ([contentView mouse:[contentView convertPoint:point fromView:nil] inRect:[contentView bounds]] && + [NSCursor currentCursor] != Cocoa_GetDesiredCursor()) { + // The wrong cursor is on screen, fix it. This fixes an macOS bug that is only known to + // occur in fullscreen windows on the built-in displays of newer MacBooks with camera + // notches. When the mouse is moved near the top of such a window (within about 44 units) + // and then moved back down, the cursor rects aren't respected. + [_data.nswindow invalidateCursorRectsForView:contentView]; + } if ([self processHitTest:theEvent]) { SDL_SendWindowEvent(window, SDL_WINDOWEVENT_HIT_TEST, 0, 0); @@ -1340,7 +1390,6 @@ - (void)mouseMoved:(NSEvent *)theEvent return; } - point = [theEvent locationInWindow]; x = (int)point.x; y = (int)(window->h - point.y); @@ -1590,17 +1639,9 @@ - (BOOL)mouseDownCanMoveWindow - (void)resetCursorRects { - SDL_Mouse *mouse; [super resetCursorRects]; - mouse = SDL_GetMouse(); - - if (mouse->cursor_shown && mouse->cur_cursor && !mouse->relative_mode) { - [self addCursorRect:[self bounds] - cursor:(__bridge NSCursor *)mouse->cur_cursor->driverdata]; - } else { - [self addCursorRect:[self bounds] - cursor:[NSCursor invisibleCursor]]; - } + [self addCursorRect:[self bounds] + cursor:Cocoa_GetDesiredCursor()]; } - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent @@ -2332,7 +2373,10 @@ void Cocoa_DestroyWindow(_THIS, SDL_Window * window) SDL_WindowData *data = (SDL_WindowData *) CFBridgingRelease(window->driverdata); if (data) { +#ifdef SDL_VIDEO_OPENGL NSArray *contexts; +#endif + if ([data.listener isInFullscreenSpace]) { [NSMenu setMenuBarVisible:YES]; } @@ -2344,15 +2388,13 @@ void Cocoa_DestroyWindow(_THIS, SDL_Window * window) [data.nswindow close]; } - #ifdef SDL_VIDEO_OPENGL - +#ifdef SDL_VIDEO_OPENGL contexts = [data.nscontexts copy]; for (SDLOpenGLContext *context in contexts) { /* Calling setWindow:NULL causes the context to remove itself from the context list. */ [context setWindow:NULL]; } - - #endif /* SDL_VIDEO_OPENGL */ +#endif /* SDL_VIDEO_OPENGL */ if (window->shaper) { CFBridgingRelease(window->shaper->driverdata); diff --git a/src/video/directfb/SDL_DirectFB_WM.c b/src/video/directfb/SDL_DirectFB_WM.c index d32ab5d..425ca09 100644 --- a/src/video/directfb/SDL_DirectFB_WM.c +++ b/src/video/directfb/SDL_DirectFB_WM.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/directfb/SDL_DirectFB_WM.h b/src/video/directfb/SDL_DirectFB_WM.h index d373ee6..d36ada4 100644 --- a/src/video/directfb/SDL_DirectFB_WM.h +++ b/src/video/directfb/SDL_DirectFB_WM.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/directfb/SDL_DirectFB_dyn.c b/src/video/directfb/SDL_DirectFB_dyn.c index b4c734a..e3aca31 100644 --- a/src/video/directfb/SDL_DirectFB_dyn.c +++ b/src/video/directfb/SDL_DirectFB_dyn.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/directfb/SDL_DirectFB_dyn.h b/src/video/directfb/SDL_DirectFB_dyn.h index dc08d98..854ce43 100644 --- a/src/video/directfb/SDL_DirectFB_dyn.h +++ b/src/video/directfb/SDL_DirectFB_dyn.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/directfb/SDL_DirectFB_events.c b/src/video/directfb/SDL_DirectFB_events.c index 1b2d654..e076ff0 100644 --- a/src/video/directfb/SDL_DirectFB_events.c +++ b/src/video/directfb/SDL_DirectFB_events.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/directfb/SDL_DirectFB_events.h b/src/video/directfb/SDL_DirectFB_events.h index 65ee229..c41cb15 100644 --- a/src/video/directfb/SDL_DirectFB_events.h +++ b/src/video/directfb/SDL_DirectFB_events.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/directfb/SDL_DirectFB_modes.c b/src/video/directfb/SDL_DirectFB_modes.c index 3c69a82..6829e20 100644 --- a/src/video/directfb/SDL_DirectFB_modes.c +++ b/src/video/directfb/SDL_DirectFB_modes.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/directfb/SDL_DirectFB_modes.h b/src/video/directfb/SDL_DirectFB_modes.h index 236ea8b..58374c8 100644 --- a/src/video/directfb/SDL_DirectFB_modes.h +++ b/src/video/directfb/SDL_DirectFB_modes.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/directfb/SDL_DirectFB_mouse.c b/src/video/directfb/SDL_DirectFB_mouse.c index 363509e..0e24fbf 100644 --- a/src/video/directfb/SDL_DirectFB_mouse.c +++ b/src/video/directfb/SDL_DirectFB_mouse.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/directfb/SDL_DirectFB_mouse.h b/src/video/directfb/SDL_DirectFB_mouse.h index 6d90970..d45b202 100644 --- a/src/video/directfb/SDL_DirectFB_mouse.h +++ b/src/video/directfb/SDL_DirectFB_mouse.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/directfb/SDL_DirectFB_opengl.c b/src/video/directfb/SDL_DirectFB_opengl.c index 338d53a..17737c2 100644 --- a/src/video/directfb/SDL_DirectFB_opengl.c +++ b/src/video/directfb/SDL_DirectFB_opengl.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/directfb/SDL_DirectFB_opengl.h b/src/video/directfb/SDL_DirectFB_opengl.h index 3700da7..1e27774 100644 --- a/src/video/directfb/SDL_DirectFB_opengl.h +++ b/src/video/directfb/SDL_DirectFB_opengl.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/directfb/SDL_DirectFB_render.c b/src/video/directfb/SDL_DirectFB_render.c index 0d96f86..38ff16f 100644 --- a/src/video/directfb/SDL_DirectFB_render.c +++ b/src/video/directfb/SDL_DirectFB_render.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -561,7 +561,7 @@ static void DirectFB_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * textur } } -static void DirectFB_SetTextureScaleMode() +static void DirectFB_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture, SDL_ScaleMode scaleMode) { } diff --git a/src/video/directfb/SDL_DirectFB_render.h b/src/video/directfb/SDL_DirectFB_render.h index 7637039..8030948 100644 --- a/src/video/directfb/SDL_DirectFB_render.h +++ b/src/video/directfb/SDL_DirectFB_render.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/directfb/SDL_DirectFB_shape.c b/src/video/directfb/SDL_DirectFB_shape.c index f738605..3167a5b 100644 --- a/src/video/directfb/SDL_DirectFB_shape.c +++ b/src/video/directfb/SDL_DirectFB_shape.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/directfb/SDL_DirectFB_shape.h b/src/video/directfb/SDL_DirectFB_shape.h index a34b571..70e97b9 100644 --- a/src/video/directfb/SDL_DirectFB_shape.h +++ b/src/video/directfb/SDL_DirectFB_shape.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/directfb/SDL_DirectFB_video.c b/src/video/directfb/SDL_DirectFB_video.c index 931a705..b3110cb 100644 --- a/src/video/directfb/SDL_DirectFB_video.c +++ b/src/video/directfb/SDL_DirectFB_video.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/directfb/SDL_DirectFB_video.h b/src/video/directfb/SDL_DirectFB_video.h index 958caef..39d7b2a 100644 --- a/src/video/directfb/SDL_DirectFB_video.h +++ b/src/video/directfb/SDL_DirectFB_video.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/directfb/SDL_DirectFB_vulkan.c b/src/video/directfb/SDL_DirectFB_vulkan.c index 5dcd021..24bacbb 100644 --- a/src/video/directfb/SDL_DirectFB_vulkan.c +++ b/src/video/directfb/SDL_DirectFB_vulkan.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/directfb/SDL_DirectFB_vulkan.h b/src/video/directfb/SDL_DirectFB_vulkan.h index de04213..54e109d 100644 --- a/src/video/directfb/SDL_DirectFB_vulkan.h +++ b/src/video/directfb/SDL_DirectFB_vulkan.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/directfb/SDL_DirectFB_window.c b/src/video/directfb/SDL_DirectFB_window.c index fb9ce7b..601a9f9 100644 --- a/src/video/directfb/SDL_DirectFB_window.c +++ b/src/video/directfb/SDL_DirectFB_window.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/directfb/SDL_DirectFB_window.h b/src/video/directfb/SDL_DirectFB_window.h index f736e1e..8046b62 100644 --- a/src/video/directfb/SDL_DirectFB_window.h +++ b/src/video/directfb/SDL_DirectFB_window.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/dummy/SDL_nullevents.c b/src/video/dummy/SDL_nullevents.c index bbe02e0..c961d19 100644 --- a/src/video/dummy/SDL_nullevents.c +++ b/src/video/dummy/SDL_nullevents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/dummy/SDL_nullevents_c.h b/src/video/dummy/SDL_nullevents_c.h index 14021c5..5e6730b 100644 --- a/src/video/dummy/SDL_nullevents_c.h +++ b/src/video/dummy/SDL_nullevents_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/dummy/SDL_nullframebuffer.c b/src/video/dummy/SDL_nullframebuffer.c index 22a9d27..879b774 100644 --- a/src/video/dummy/SDL_nullframebuffer.c +++ b/src/video/dummy/SDL_nullframebuffer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/dummy/SDL_nullframebuffer_c.h b/src/video/dummy/SDL_nullframebuffer_c.h index dea414e..aeca720 100644 --- a/src/video/dummy/SDL_nullframebuffer_c.h +++ b/src/video/dummy/SDL_nullframebuffer_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/dummy/SDL_nullvideo.c b/src/video/dummy/SDL_nullvideo.c index 930e989..b5c60bb 100644 --- a/src/video/dummy/SDL_nullvideo.c +++ b/src/video/dummy/SDL_nullvideo.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -131,7 +131,7 @@ VideoBootStrap DUMMY_evdev_bootstrap = { NULL /* no ShowMessageBox implementation */ }; void SDL_EVDEV_Init(void); -void SDL_EVDEV_Poll(); +void SDL_EVDEV_Poll(void); void SDL_EVDEV_Quit(void); static void DUMMY_EVDEV_Poll(_THIS) { diff --git a/src/video/dummy/SDL_nullvideo.h b/src/video/dummy/SDL_nullvideo.h index 84a18a9..4292732 100644 --- a/src/video/dummy/SDL_nullvideo.h +++ b/src/video/dummy/SDL_nullvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/emscripten/SDL_emscriptenevents.c b/src/video/emscripten/SDL_emscriptenevents.c index 2017a6a..9fc0de5 100644 --- a/src/video/emscripten/SDL_emscriptenevents.c +++ b/src/video/emscripten/SDL_emscriptenevents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -714,20 +714,24 @@ static EM_BOOL Emscripten_HandleWheel(int eventType, const EmscriptenWheelEvent SDL_WindowData *window_data = userData; float deltaY = wheelEvent->deltaY; + float deltaX = wheelEvent->deltaX; switch (wheelEvent->deltaMode) { case DOM_DELTA_PIXEL: deltaY /= 100; /* 100 pixels make up a step */ + deltaX /= 100; /* 100 pixels make up a step */ break; case DOM_DELTA_LINE: deltaY /= 3; /* 3 lines make up a step */ + deltaX /= 3; /* 3 lines make up a step */ break; case DOM_DELTA_PAGE: deltaY *= 80; /* A page makes up 80 steps */ + deltaX *= 80; /* A page makes up 80 steps */ break; } - SDL_SendMouseWheel(window_data->window, 0, (float)wheelEvent->deltaX, -deltaY, SDL_MOUSEWHEEL_NORMAL); + SDL_SendMouseWheel(window_data->window, 0, deltaX, -deltaY, SDL_MOUSEWHEEL_NORMAL); return SDL_GetEventState(SDL_MOUSEWHEEL) == SDL_ENABLE; } diff --git a/src/video/emscripten/SDL_emscriptenevents.h b/src/video/emscripten/SDL_emscriptenevents.h index 502236a..cb4bdf0 100644 --- a/src/video/emscripten/SDL_emscriptenevents.h +++ b/src/video/emscripten/SDL_emscriptenevents.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/emscripten/SDL_emscriptenframebuffer.c b/src/video/emscripten/SDL_emscriptenframebuffer.c index 6a0e78f..422f41d 100644 --- a/src/video/emscripten/SDL_emscriptenframebuffer.c +++ b/src/video/emscripten/SDL_emscriptenframebuffer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -89,7 +89,7 @@ int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect SDL2.imageCtx = SDL2.ctx; } var data = SDL2.image.data; - var src = pixels >> 2; + var src = pixels / 4; var dst = 0; var num; if (typeof CanvasPixelArray !== 'undefined' && data instanceof CanvasPixelArray) { diff --git a/src/video/emscripten/SDL_emscriptenframebuffer.h b/src/video/emscripten/SDL_emscriptenframebuffer.h index fdf1c35..d022b4c 100644 --- a/src/video/emscripten/SDL_emscriptenframebuffer.h +++ b/src/video/emscripten/SDL_emscriptenframebuffer.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/emscripten/SDL_emscriptenmouse.c b/src/video/emscripten/SDL_emscriptenmouse.c index cdf83de..6007161 100644 --- a/src/video/emscripten/SDL_emscriptenmouse.c +++ b/src/video/emscripten/SDL_emscriptenmouse.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -98,7 +98,7 @@ static SDL_Cursor *Emscripten_CreateCursor(SDL_Surface *surface, int hot_x, int var image = ctx.createImageData(w, h); var data = image.data; - var src = pixels >> 2; + var src = pixels / 4; var dst = 0; var num; if (typeof CanvasPixelArray !== 'undefined' && data instanceof CanvasPixelArray) { @@ -141,49 +141,7 @@ static SDL_Cursor *Emscripten_CreateCursor(SDL_Surface *surface, int hot_x, int static SDL_Cursor *Emscripten_CreateSystemCursor(SDL_SystemCursor id) { - const char *cursor_name = NULL; - - switch (id) { - case SDL_SYSTEM_CURSOR_ARROW: - cursor_name = "default"; - break; - case SDL_SYSTEM_CURSOR_IBEAM: - cursor_name = "text"; - break; - case SDL_SYSTEM_CURSOR_WAIT: - cursor_name = "wait"; - break; - case SDL_SYSTEM_CURSOR_CROSSHAIR: - cursor_name = "crosshair"; - break; - case SDL_SYSTEM_CURSOR_WAITARROW: - cursor_name = "progress"; - break; - case SDL_SYSTEM_CURSOR_SIZENWSE: - cursor_name = "nwse-resize"; - break; - case SDL_SYSTEM_CURSOR_SIZENESW: - cursor_name = "nesw-resize"; - break; - case SDL_SYSTEM_CURSOR_SIZEWE: - cursor_name = "ew-resize"; - break; - case SDL_SYSTEM_CURSOR_SIZENS: - cursor_name = "ns-resize"; - break; - case SDL_SYSTEM_CURSOR_SIZEALL: - cursor_name = "move"; - break; - case SDL_SYSTEM_CURSOR_NO: - cursor_name = "not-allowed"; - break; - case SDL_SYSTEM_CURSOR_HAND: - cursor_name = "pointer"; - break; - default: - SDL_assert(0); - return NULL; - } + const char *cursor_name = SDL_GetCSSCursorName(id, NULL); return Emscripten_CreateCursorFromString(cursor_name, SDL_FALSE); } @@ -264,7 +222,7 @@ static int Emscripten_SetRelativeMouseMode(SDL_bool enabled) return -1; } -void Emscripten_InitMouse() +void Emscripten_InitMouse(void) { SDL_Mouse *mouse = SDL_GetMouse(); @@ -278,7 +236,7 @@ void Emscripten_InitMouse() SDL_SetDefaultCursor(Emscripten_CreateDefaultCursor()); } -void Emscripten_FiniMouse() +void Emscripten_FiniMouse(void) { } diff --git a/src/video/emscripten/SDL_emscriptenmouse.h b/src/video/emscripten/SDL_emscriptenmouse.h index 10cd24e..7ca4978 100644 --- a/src/video/emscripten/SDL_emscriptenmouse.h +++ b/src/video/emscripten/SDL_emscriptenmouse.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/emscripten/SDL_emscriptenopengles.c b/src/video/emscripten/SDL_emscriptenopengles.c index baf9eb7..b78c1ea 100644 --- a/src/video/emscripten/SDL_emscriptenopengles.c +++ b/src/video/emscripten/SDL_emscriptenopengles.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/emscripten/SDL_emscriptenopengles.h b/src/video/emscripten/SDL_emscriptenopengles.h index 184d0f2..cea5d27 100644 --- a/src/video/emscripten/SDL_emscriptenopengles.h +++ b/src/video/emscripten/SDL_emscriptenopengles.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/emscripten/SDL_emscriptenvideo.c b/src/video/emscripten/SDL_emscriptenvideo.c index e713e5b..d32dd2f 100644 --- a/src/video/emscripten/SDL_emscriptenvideo.c +++ b/src/video/emscripten/SDL_emscriptenvideo.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -342,6 +342,7 @@ static void Emscripten_SetWindowFullscreen(_THIS, SDL_Window *window, SDL_VideoD SDL_bool is_desktop_fullscreen = (window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP; int res; + SDL_zero(strategy); strategy.scaleMode = is_desktop_fullscreen ? EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH : EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT; if (!is_desktop_fullscreen) { diff --git a/src/video/emscripten/SDL_emscriptenvideo.h b/src/video/emscripten/SDL_emscriptenvideo.h index 2cbb671..2ec0d51 100644 --- a/src/video/emscripten/SDL_emscriptenvideo.h +++ b/src/video/emscripten/SDL_emscriptenvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/haiku/SDL_BApp.h b/src/video/haiku/SDL_BApp.h index 284445d..6027219 100644 --- a/src/video/haiku/SDL_BApp.h +++ b/src/video/haiku/SDL_BApp.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/haiku/SDL_BWin.h b/src/video/haiku/SDL_BWin.h index f1ad1ea..4d4d4af 100644 --- a/src/video/haiku/SDL_BWin.h +++ b/src/video/haiku/SDL_BWin.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/haiku/SDL_bclipboard.cc b/src/video/haiku/SDL_bclipboard.cc index 11e79f3..658cd5f 100644 --- a/src/video/haiku/SDL_bclipboard.cc +++ b/src/video/haiku/SDL_bclipboard.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/haiku/SDL_bclipboard.h b/src/video/haiku/SDL_bclipboard.h index 89e9e90..801d5d3 100644 --- a/src/video/haiku/SDL_bclipboard.h +++ b/src/video/haiku/SDL_bclipboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/haiku/SDL_bevents.cc b/src/video/haiku/SDL_bevents.cc index 45727a6..cd9f418 100644 --- a/src/video/haiku/SDL_bevents.cc +++ b/src/video/haiku/SDL_bevents.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/haiku/SDL_bevents.h b/src/video/haiku/SDL_bevents.h index 1afd33a..ac5b9b0 100644 --- a/src/video/haiku/SDL_bevents.h +++ b/src/video/haiku/SDL_bevents.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/haiku/SDL_bframebuffer.cc b/src/video/haiku/SDL_bframebuffer.cc index 1961cea..71e7689 100644 --- a/src/video/haiku/SDL_bframebuffer.cc +++ b/src/video/haiku/SDL_bframebuffer.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/haiku/SDL_bframebuffer.h b/src/video/haiku/SDL_bframebuffer.h index ce3649c..0b2a165 100644 --- a/src/video/haiku/SDL_bframebuffer.h +++ b/src/video/haiku/SDL_bframebuffer.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/haiku/SDL_bkeyboard.cc b/src/video/haiku/SDL_bkeyboard.cc index b9499ed..84dd4fd 100644 --- a/src/video/haiku/SDL_bkeyboard.cc +++ b/src/video/haiku/SDL_bkeyboard.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/haiku/SDL_bkeyboard.h b/src/video/haiku/SDL_bkeyboard.h index 46fd9d6..6fdc9cf 100644 --- a/src/video/haiku/SDL_bkeyboard.h +++ b/src/video/haiku/SDL_bkeyboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/haiku/SDL_bmessagebox.cc b/src/video/haiku/SDL_bmessagebox.cc index d0c43e2..d59c7a5 100644 --- a/src/video/haiku/SDL_bmessagebox.cc +++ b/src/video/haiku/SDL_bmessagebox.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga Copyright (C) 2018-2019 EXL This software is provided 'as-is', without any express or implied diff --git a/src/video/haiku/SDL_bmessagebox.h b/src/video/haiku/SDL_bmessagebox.h index 822d7c2..f61ecad 100644 --- a/src/video/haiku/SDL_bmessagebox.h +++ b/src/video/haiku/SDL_bmessagebox.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga Copyright (C) 2018-2019 EXL This software is provided 'as-is', without any express or implied diff --git a/src/video/haiku/SDL_bmodes.cc b/src/video/haiku/SDL_bmodes.cc index 6a162f6..77b9123 100644 --- a/src/video/haiku/SDL_bmodes.cc +++ b/src/video/haiku/SDL_bmodes.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/haiku/SDL_bmodes.h b/src/video/haiku/SDL_bmodes.h index e0d6f04..b0d956e 100644 --- a/src/video/haiku/SDL_bmodes.h +++ b/src/video/haiku/SDL_bmodes.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/haiku/SDL_bopengl.cc b/src/video/haiku/SDL_bopengl.cc index d34d592..eada4c0 100644 --- a/src/video/haiku/SDL_bopengl.cc +++ b/src/video/haiku/SDL_bopengl.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/haiku/SDL_bopengl.h b/src/video/haiku/SDL_bopengl.h index 0905b7c..b3bd6c8 100644 --- a/src/video/haiku/SDL_bopengl.h +++ b/src/video/haiku/SDL_bopengl.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/haiku/SDL_bvideo.cc b/src/video/haiku/SDL_bvideo.cc index aac091a..d541289 100644 --- a/src/video/haiku/SDL_bvideo.cc +++ b/src/video/haiku/SDL_bvideo.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/haiku/SDL_bvideo.h b/src/video/haiku/SDL_bvideo.h index 6c42048..21a6797 100644 --- a/src/video/haiku/SDL_bvideo.h +++ b/src/video/haiku/SDL_bvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/haiku/SDL_bwindow.cc b/src/video/haiku/SDL_bwindow.cc index 38863ab..0ca751a 100644 --- a/src/video/haiku/SDL_bwindow.cc +++ b/src/video/haiku/SDL_bwindow.cc @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/haiku/SDL_bwindow.h b/src/video/haiku/SDL_bwindow.h index cf0bdfd..fa42c35 100644 --- a/src/video/haiku/SDL_bwindow.h +++ b/src/video/haiku/SDL_bwindow.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/khronos/vulkan/vulkan_metal.h b/src/video/khronos/vulkan/vulkan_metal.h index e6f7bf7..badb450 100644 --- a/src/video/khronos/vulkan/vulkan_metal.h +++ b/src/video/khronos/vulkan/vulkan_metal.h @@ -27,6 +27,14 @@ extern "C" { typedef void CAMetalLayer; #endif +#define SDL_UNSAFE_UNRETAINED +#if defined(__OBJC__) && defined(__has_feature) +#if __has_feature(objc_arc) +#undef SDL_UNSAFE_UNRETAINED +#define SDL_UNSAFE_UNRETAINED __unsafe_unretained +#endif +#endif + #define VK_EXT_METAL_SURFACE_SPEC_VERSION 1 #define VK_EXT_METAL_SURFACE_EXTENSION_NAME "VK_EXT_metal_surface" typedef VkFlags VkMetalSurfaceCreateFlagsEXT; @@ -34,7 +42,7 @@ typedef struct VkMetalSurfaceCreateInfoEXT { VkStructureType sType; const void* pNext; VkMetalSurfaceCreateFlagsEXT flags; - const CAMetalLayer* pLayer; + const CAMetalLayer SDL_UNSAFE_UNRETAINED *pLayer; } VkMetalSurfaceCreateInfoEXT; typedef VkResult (VKAPI_PTR *PFN_vkCreateMetalSurfaceEXT)(VkInstance instance, const VkMetalSurfaceCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); @@ -113,27 +121,27 @@ typedef struct VkExportMetalObjectsInfoEXT { typedef struct VkExportMetalDeviceInfoEXT { VkStructureType sType; const void* pNext; - MTLDevice_id mtlDevice; + MTLDevice_id SDL_UNSAFE_UNRETAINED mtlDevice; } VkExportMetalDeviceInfoEXT; typedef struct VkExportMetalCommandQueueInfoEXT { VkStructureType sType; const void* pNext; VkQueue queue; - MTLCommandQueue_id mtlCommandQueue; + MTLCommandQueue_id SDL_UNSAFE_UNRETAINED mtlCommandQueue; } VkExportMetalCommandQueueInfoEXT; typedef struct VkExportMetalBufferInfoEXT { VkStructureType sType; const void* pNext; VkDeviceMemory memory; - MTLBuffer_id mtlBuffer; + MTLBuffer_id SDL_UNSAFE_UNRETAINED mtlBuffer; } VkExportMetalBufferInfoEXT; typedef struct VkImportMetalBufferInfoEXT { VkStructureType sType; const void* pNext; - MTLBuffer_id mtlBuffer; + MTLBuffer_id SDL_UNSAFE_UNRETAINED mtlBuffer; } VkImportMetalBufferInfoEXT; typedef struct VkExportMetalTextureInfoEXT { @@ -143,14 +151,14 @@ typedef struct VkExportMetalTextureInfoEXT { VkImageView imageView; VkBufferView bufferView; VkImageAspectFlagBits plane; - MTLTexture_id mtlTexture; + MTLTexture_id SDL_UNSAFE_UNRETAINED mtlTexture; } VkExportMetalTextureInfoEXT; typedef struct VkImportMetalTextureInfoEXT { VkStructureType sType; const void* pNext; VkImageAspectFlagBits plane; - MTLTexture_id mtlTexture; + MTLTexture_id SDL_UNSAFE_UNRETAINED mtlTexture; } VkImportMetalTextureInfoEXT; typedef struct VkExportMetalIOSurfaceInfoEXT { @@ -171,13 +179,13 @@ typedef struct VkExportMetalSharedEventInfoEXT { const void* pNext; VkSemaphore semaphore; VkEvent event; - MTLSharedEvent_id mtlSharedEvent; + MTLSharedEvent_id SDL_UNSAFE_UNRETAINED mtlSharedEvent; } VkExportMetalSharedEventInfoEXT; typedef struct VkImportMetalSharedEventInfoEXT { VkStructureType sType; const void* pNext; - MTLSharedEvent_id mtlSharedEvent; + MTLSharedEvent_id SDL_UNSAFE_UNRETAINED mtlSharedEvent; } VkImportMetalSharedEventInfoEXT; typedef void (VKAPI_PTR *PFN_vkExportMetalObjectsEXT)(VkDevice device, VkExportMetalObjectsInfoEXT* pMetalObjectsInfo); diff --git a/src/video/kmsdrm/SDL_kmsdrmdyn.c b/src/video/kmsdrm/SDL_kmsdrmdyn.c index 750babb..2947394 100644 --- a/src/video/kmsdrm/SDL_kmsdrmdyn.c +++ b/src/video/kmsdrm/SDL_kmsdrmdyn.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -47,7 +47,7 @@ static kmsdrmdynlib kmsdrmlibs[] = { { NULL, SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC } }; -static void *KMSDRM_GetSym(const char *fnname, int *pHasModule) +static void *KMSDRM_GetSym(const char *fnname, int *pHasModule, SDL_bool required) { int i; void *fn = NULL; @@ -67,7 +67,7 @@ static void *KMSDRM_GetSym(const char *fnname, int *pHasModule) SDL_Log("KMSDRM: Symbol '%s' NOT FOUND!\n", fnname); #endif - if (!fn) { + if (!fn && required) { *pHasModule = 0; /* kill this module. */ } @@ -80,6 +80,7 @@ static void *KMSDRM_GetSym(const char *fnname, int *pHasModule) #define SDL_KMSDRM_MODULE(modname) int SDL_KMSDRM_HAVE_##modname = 0; #define SDL_KMSDRM_SYM(rc, fn, params) SDL_DYNKMSDRMFN_##fn KMSDRM_##fn = NULL; #define SDL_KMSDRM_SYM_CONST(type, name) SDL_DYNKMSDRMCONST_##name KMSDRM_##name = NULL; +#define SDL_KMSDRM_SYM_OPT(rc, fn, params) SDL_DYNKMSDRMFN_##fn KMSDRM_##fn = NULL; #include "SDL_kmsdrmsym.h" static int kmsdrm_load_refcount = 0; @@ -97,6 +98,7 @@ void SDL_KMSDRM_UnloadSymbols(void) #define SDL_KMSDRM_MODULE(modname) SDL_KMSDRM_HAVE_##modname = 0; #define SDL_KMSDRM_SYM(rc, fn, params) KMSDRM_##fn = NULL; #define SDL_KMSDRM_SYM_CONST(type, name) KMSDRM_##name = NULL; +#define SDL_KMSDRM_SYM_OPT(rc, fn, params) KMSDRM_##fn = NULL; #include "SDL_kmsdrmsym.h" #ifdef SDL_VIDEO_DRIVER_KMSDRM_DYNAMIC @@ -130,9 +132,10 @@ int SDL_KMSDRM_LoadSymbols(void) #define SDL_KMSDRM_MODULE(modname) SDL_KMSDRM_HAVE_##modname = 1; /* default yes */ #include "SDL_kmsdrmsym.h" -#define SDL_KMSDRM_MODULE(modname) thismod = &SDL_KMSDRM_HAVE_##modname; -#define SDL_KMSDRM_SYM(rc, fn, params) KMSDRM_##fn = (SDL_DYNKMSDRMFN_##fn)KMSDRM_GetSym(#fn, thismod); -#define SDL_KMSDRM_SYM_CONST(type, name) KMSDRM_##name = *(SDL_DYNKMSDRMCONST_##name *)KMSDRM_GetSym(#name, thismod); +#define SDL_KMSDRM_MODULE(modname) thismod = &SDL_KMSDRM_HAVE_##modname; +#define SDL_KMSDRM_SYM(rc, fn, params) KMSDRM_##fn = (SDL_DYNKMSDRMFN_##fn)KMSDRM_GetSym(#fn, thismod, SDL_TRUE); +#define SDL_KMSDRM_SYM_CONST(type, name) KMSDRM_##name = *(SDL_DYNKMSDRMCONST_##name *)KMSDRM_GetSym(#name, thismod, SDL_TRUE); +#define SDL_KMSDRM_SYM_OPT(rc, fn, params) KMSDRM_##fn = (SDL_DYNKMSDRMFN_##fn)KMSDRM_GetSym(#fn, thismod, SDL_FALSE); #include "SDL_kmsdrmsym.h" if ((SDL_KMSDRM_HAVE_LIBDRM) && (SDL_KMSDRM_HAVE_GBM)) { @@ -149,6 +152,7 @@ int SDL_KMSDRM_LoadSymbols(void) #define SDL_KMSDRM_MODULE(modname) SDL_KMSDRM_HAVE_##modname = 1; /* default yes */ #define SDL_KMSDRM_SYM(rc, fn, params) KMSDRM_##fn = fn; #define SDL_KMSDRM_SYM_CONST(type, name) KMSDRM_##name = name; +#define SDL_KMSDRM_SYM_OPT(rc, fn, params) KMSDRM_##fn = fn; #include "SDL_kmsdrmsym.h" #endif diff --git a/src/video/kmsdrm/SDL_kmsdrmdyn.h b/src/video/kmsdrm/SDL_kmsdrmdyn.h index e6da337..63f39a6 100644 --- a/src/video/kmsdrm/SDL_kmsdrmdyn.h +++ b/src/video/kmsdrm/SDL_kmsdrmdyn.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -42,6 +42,9 @@ void SDL_KMSDRM_UnloadSymbols(void); #define SDL_KMSDRM_SYM_CONST(type, name) \ typedef type SDL_DYNKMSDRMCONST_##name; \ extern SDL_DYNKMSDRMCONST_##name KMSDRM_##name; +#define SDL_KMSDRM_SYM_OPT(rc, fn, params) \ + typedef rc(*SDL_DYNKMSDRMFN_##fn) params; \ + extern SDL_DYNKMSDRMFN_##fn KMSDRM_##fn; #include "SDL_kmsdrmsym.h" #ifdef __cplusplus diff --git a/src/video/kmsdrm/SDL_kmsdrmevents.c b/src/video/kmsdrm/SDL_kmsdrmevents.c index a52f1b6..39216ed 100644 --- a/src/video/kmsdrm/SDL_kmsdrmevents.c +++ b/src/video/kmsdrm/SDL_kmsdrmevents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/kmsdrm/SDL_kmsdrmevents.h b/src/video/kmsdrm/SDL_kmsdrmevents.h index 74625e3..b9c99fc 100644 --- a/src/video/kmsdrm/SDL_kmsdrmevents.h +++ b/src/video/kmsdrm/SDL_kmsdrmevents.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/kmsdrm/SDL_kmsdrmmouse.c b/src/video/kmsdrm/SDL_kmsdrmmouse.c index ec01004..c589476 100644 --- a/src/video/kmsdrm/SDL_kmsdrmmouse.c +++ b/src/video/kmsdrm/SDL_kmsdrmmouse.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/kmsdrm/SDL_kmsdrmmouse.h b/src/video/kmsdrm/SDL_kmsdrmmouse.h index 0485abf..b060dd3 100644 --- a/src/video/kmsdrm/SDL_kmsdrmmouse.h +++ b/src/video/kmsdrm/SDL_kmsdrmmouse.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/kmsdrm/SDL_kmsdrmopengles.c b/src/video/kmsdrm/SDL_kmsdrmopengles.c index 9b34d68..3115862 100644 --- a/src/video/kmsdrm/SDL_kmsdrmopengles.c +++ b/src/video/kmsdrm/SDL_kmsdrmopengles.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -194,7 +194,7 @@ int KMSDRM_GLES_SwapWindow(_THIS, SDL_Window *window) we have waited here, there won't be a pending pageflip so the WaitPageflip at the beginning of this function will be a no-op. Just leave it here and don't worry. - Run your SDL2 program with "SDL_KMSDRM_DOUBLE_BUFFER=1 " + Run your SDL2 program with "SDL_VIDEO_DOUBLE_BUFFER=1 " to enable this. */ if (windata->double_buffer) { if (!KMSDRM_WaitPageflip(_this, windata)) { diff --git a/src/video/kmsdrm/SDL_kmsdrmopengles.h b/src/video/kmsdrm/SDL_kmsdrmopengles.h index 63e548a..9307066 100644 --- a/src/video/kmsdrm/SDL_kmsdrmopengles.h +++ b/src/video/kmsdrm/SDL_kmsdrmopengles.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/kmsdrm/SDL_kmsdrmsym.h b/src/video/kmsdrm/SDL_kmsdrmsym.h index d1e856f..b0be627 100644 --- a/src/video/kmsdrm/SDL_kmsdrmsym.h +++ b/src/video/kmsdrm/SDL_kmsdrmsym.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -33,6 +33,10 @@ #define SDL_KMSDRM_SYM_CONST(type, name) #endif +#ifndef SDL_KMSDRM_SYM_OPT +#define SDL_KMSDRM_SYM_OPT(rc,fn,params) +#endif + SDL_KMSDRM_MODULE(LIBDRM) SDL_KMSDRM_SYM(void,drmModeFreeResources,(drmModeResPtr ptr)) @@ -49,11 +53,16 @@ SDL_KMSDRM_SYM(int,drmModeAddFB,(int fd, uint32_t width, uint32_t height, uint8_ uint8_t bpp, uint32_t pitch, uint32_t bo_handle, uint32_t *buf_id)) -SDL_KMSDRM_SYM(int,drmModeAddFB2,(int fd, uint32_t width, uint32_t height, +SDL_KMSDRM_SYM_OPT(int,drmModeAddFB2,(int fd, uint32_t width, uint32_t height, uint32_t pixel_format, const uint32_t bo_handles[4], const uint32_t pitches[4], const uint32_t offsets[4], uint32_t *buf_id, uint32_t flags)) +SDL_KMSDRM_SYM_OPT(int,drmModeAddFB2WithModifiers,(int fd, uint32_t width, + uint32_t height, uint32_t pixel_format, const uint32_t bo_handles[4], + const uint32_t pitches[4], const uint32_t offsets[4], + const uint64_t modifier[4], uint32_t *buf_id, uint32_t flags)) + SDL_KMSDRM_SYM(int,drmModeRmFB,(int fd, uint32_t bufferId)) SDL_KMSDRM_SYM(drmModeFBPtr,drmModeGetFB,(int fd, uint32_t buf)) SDL_KMSDRM_SYM(drmModeCrtcPtr,drmModeGetCrtc,(int fd, uint32_t crtcId)) @@ -124,10 +133,16 @@ SDL_KMSDRM_SYM(void,gbm_surface_destroy,(struct gbm_surface *surf)) SDL_KMSDRM_SYM(struct gbm_bo *,gbm_surface_lock_front_buffer,(struct gbm_surface *surf)) SDL_KMSDRM_SYM(void,gbm_surface_release_buffer,(struct gbm_surface *surf, struct gbm_bo *bo)) +SDL_KMSDRM_SYM_OPT(uint64_t,gbm_bo_get_modifier,(struct gbm_bo *bo)) +SDL_KMSDRM_SYM_OPT(int,gbm_bo_get_plane_count,(struct gbm_bo *bo)) +SDL_KMSDRM_SYM_OPT(uint32_t,gbm_bo_get_offset,(struct gbm_bo *bo, int plane)) +SDL_KMSDRM_SYM_OPT(uint32_t,gbm_bo_get_stride_for_plane,(struct gbm_bo *bo, int plane)) +SDL_KMSDRM_SYM_OPT(union gbm_bo_handle,gbm_bo_get_handle_for_plane,(struct gbm_bo *bo, int plane)) #undef SDL_KMSDRM_MODULE #undef SDL_KMSDRM_SYM #undef SDL_KMSDRM_SYM_CONST +#undef SDL_KMSDRM_SYM_OPT /* *INDENT-ON* */ /* clang-format on */ diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.c b/src/video/kmsdrm/SDL_kmsdrmvideo.c index 69033b0..8f080c2 100644 --- a/src/video/kmsdrm/SDL_kmsdrmvideo.c +++ b/src/video/kmsdrm/SDL_kmsdrmvideo.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -77,6 +77,7 @@ static int get_driindex(void) int devindex = -1; DIR *folder; const char *hint; + struct dirent *res; hint = SDL_GetHint(SDL_HINT_KMSDRM_DEVICE_INDEX); if (hint && *hint) { @@ -95,8 +96,8 @@ static int get_driindex(void) } SDL_strlcpy(device + kmsdrm_dri_pathsize, kmsdrm_dri_devname, - sizeof(device) - kmsdrm_dri_devnamesize); - for (struct dirent *res; (res = readdir(folder));) { + sizeof(device) - kmsdrm_dri_pathsize); + while((res = readdir(folder)) != NULL && available < 0) { if (SDL_memcmp(res->d_name, kmsdrm_dri_devname, kmsdrm_dri_devnamesize) == 0) { SDL_strlcpy(device + kmsdrm_dri_pathsize + kmsdrm_dri_devnamesize, @@ -122,7 +123,7 @@ static int get_driindex(void) resources->count_encoders > 0 && resources->count_crtcs > 0) { available = -ENOENT; - for (i = 0; i < resources->count_connectors; i++) { + for (i = 0; i < resources->count_connectors && available < 0; i++) { drmModeConnector *conn = KMSDRM_drmModeGetConnector( drm_fd, resources->connectors[i]); @@ -133,20 +134,21 @@ static int get_driindex(void) if (conn->connection == DRM_MODE_CONNECTED && conn->count_modes) { + SDL_bool access_denied = SDL_FALSE; if (SDL_GetHintBoolean( SDL_HINT_KMSDRM_REQUIRE_DRM_MASTER, SDL_TRUE)) { /* Skip this device if we can't obtain * DRM master */ KMSDRM_drmSetMaster(drm_fd); - if (KMSDRM_drmAuthMagic(drm_fd, 0) == - -EACCES) { - continue; + if (KMSDRM_drmAuthMagic(drm_fd, 0) == -EACCES) { + access_denied = SDL_TRUE; } } - available = devindex; - break; + if (!access_denied) { + available = devindex; + } } KMSDRM_drmModeFreeConnector(conn); @@ -157,11 +159,10 @@ static int get_driindex(void) SDL_KMSDRM_UnloadSymbols(); } close(drm_fd); + } else { + SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, + "Failed to open KMSDRM device %s, errno: %d\n", device, errno); } - - SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, - "Failed to open KMSDRM device %s, errno: %d\n", device, - errno); } } @@ -335,8 +336,10 @@ KMSDRM_FBInfo *KMSDRM_FBFromBO(_THIS, struct gbm_bo *bo) { SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); unsigned w, h; - int ret; - Uint32 stride, handle; + int rc = -1; + int num_planes = 0; + uint32_t format, strides[4] = { 0 }, handles[4] = { 0 }, offsets[4] = { 0 }, flags = 0; + uint64_t modifiers[4] = { 0 }; /* Check for an existing framebuffer */ KMSDRM_FBInfo *fb_info = (KMSDRM_FBInfo *)KMSDRM_gbm_bo_get_user_data(bo); @@ -356,20 +359,48 @@ KMSDRM_FBInfo *KMSDRM_FBFromBO(_THIS, struct gbm_bo *bo) fb_info->drm_fd = viddata->drm_fd; - /* Create framebuffer object for the buffer */ + /* Create framebuffer object for the buffer using the modifiers requested by GBM. + Use of the modifiers is necessary on some platforms. */ w = KMSDRM_gbm_bo_get_width(bo); h = KMSDRM_gbm_bo_get_height(bo); - stride = KMSDRM_gbm_bo_get_stride(bo); - handle = KMSDRM_gbm_bo_get_handle(bo).u32; - ret = KMSDRM_drmModeAddFB(viddata->drm_fd, w, h, 24, 32, stride, handle, - &fb_info->fb_id); - if (ret) { + format = KMSDRM_gbm_bo_get_format(bo); + + if (KMSDRM_drmModeAddFB2WithModifiers && + KMSDRM_gbm_bo_get_modifier && + KMSDRM_gbm_bo_get_plane_count && + KMSDRM_gbm_bo_get_offset && + KMSDRM_gbm_bo_get_stride_for_plane && + KMSDRM_gbm_bo_get_handle_for_plane) { + + modifiers[0] = KMSDRM_gbm_bo_get_modifier(bo); + num_planes = KMSDRM_gbm_bo_get_plane_count(bo); + for (int i = 0; i < num_planes; i++) { + strides[i] = KMSDRM_gbm_bo_get_stride_for_plane(bo, i); + handles[i] = KMSDRM_gbm_bo_get_handle_for_plane(bo, i).u32; + offsets[i] = KMSDRM_gbm_bo_get_offset(bo, i); + modifiers[i] = modifiers[0]; + } + + if (modifiers[0] && modifiers[0] != DRM_FORMAT_MOD_INVALID) { + flags = DRM_MODE_FB_MODIFIERS; + } + + rc = KMSDRM_drmModeAddFB2WithModifiers(viddata->drm_fd, w, h, format, handles, strides, offsets, modifiers, &fb_info->fb_id, flags); + } + + if (rc < 0) { + strides[0] = KMSDRM_gbm_bo_get_stride(bo); + handles[0] = KMSDRM_gbm_bo_get_handle(bo).u32; + rc = KMSDRM_drmModeAddFB(viddata->drm_fd, w, h, 24, 32, strides[0], handles[0], &fb_info->fb_id); + } + + if (rc < 0) { SDL_free(fb_info); return NULL; } - SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "New DRM FB (%u): %ux%u, stride %u from BO %p", - fb_info->fb_id, w, h, stride, (void *)bo); + SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "New DRM FB (%u): %ux%u, from BO %p", + fb_info->fb_id, w, h, (void *)bo); /* Associate our DRM framebuffer with this buffer object */ KMSDRM_gbm_bo_set_user_data(bo, fb_info, KMSDRM_FBDestroyCallback); @@ -499,10 +530,23 @@ static drmModeModeInfo *KMSDRM_GetClosestDisplayMode(SDL_VideoDisplay *display, /* _this is a SDL_VideoDevice * */ /*****************************************************************************/ +static SDL_bool KMSDRM_DropMaster(_THIS) +{ + SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); + + /* Check if we have DRM master to begin with */ + if (KMSDRM_drmAuthMagic(viddata->drm_fd, 0) == -EACCES) { + /* Nope, nothing to do then */ + return SDL_TRUE; + } + + return KMSDRM_drmDropMaster(viddata->drm_fd) < 0 ? SDL_FALSE : SDL_TRUE; +} + /* Deinitializes the driverdata of the SDL Displays in the SDL display list. */ static void KMSDRM_DeinitDisplays(_THIS) { - + SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata); SDL_DisplayData *dispdata; int num_displays, i; @@ -526,6 +570,11 @@ static void KMSDRM_DeinitDisplays(_THIS) dispdata->crtc = NULL; } } + + if (viddata->drm_fd >= 0) { + close(viddata->drm_fd); + viddata->drm_fd = -1; + } } static uint32_t KMSDRM_CrtcGetPropId(uint32_t drm_fd, @@ -881,8 +930,6 @@ static void KMSDRM_AddDisplay(_THIS, drmModeConnector *connector, drmModeRes *re /* Initializes the list of SDL displays: we build a new display for each connecter connector we find. - Inoffeensive for VK compatibility, except we must leave the drm_fd - closed when we get to the end of this function. This is to be called early, in VideoInit(), because it gets us the videomode information, which SDL needs immediately after VideoInit(). */ static int KMSDRM_InitDisplays(_THIS) @@ -955,10 +1002,13 @@ static int KMSDRM_InitDisplays(_THIS) /* Block for Vulkan compatibility. */ /***********************************/ - /* THIS IS FOR VULKAN! Leave the FD closed, so VK can work. - Will reopen this in CreateWindow, but only if requested a non-VK window. */ - close(viddata->drm_fd); - viddata->drm_fd = -1; + /* Vulkan requires DRM master on its own FD to work, so try to drop master + on our FD. This will only work without root on kernels v5.8 and later. + If it doesn't work, just close the FD and we'll reopen it later. */ + if (!KMSDRM_DropMaster(_this)) { + close(viddata->drm_fd); + viddata->drm_fd = -1; + } cleanup: if (resources) { @@ -986,10 +1036,15 @@ static int KMSDRM_GBMInit(_THIS, SDL_DisplayData *dispdata) SDL_VideoData *viddata = (SDL_VideoData *)_this->driverdata; int ret = 0; - /* Reopen the FD! */ - viddata->drm_fd = open(viddata->devpath, O_RDWR | O_CLOEXEC); + /* Reopen the FD if we weren't able to drop master on the original one */ + if (viddata->drm_fd < 0) { + viddata->drm_fd = open(viddata->devpath, O_RDWR | O_CLOEXEC); + if (viddata->drm_fd < 0) { + return SDL_SetError("Could not reopen %s", viddata->devpath); + } + } - /* Set the FD we just opened as current DRM master. */ + /* Set the FD as current DRM master. */ KMSDRM_drmSetMaster(viddata->drm_fd); /* Create the GBM device. */ @@ -1015,8 +1070,9 @@ static void KMSDRM_GBMDeinit(_THIS, SDL_DisplayData *dispdata) viddata->gbm_dev = NULL; } - /* Finally close DRM FD. May be reopen on next non-vulkan window creation. */ - if (viddata->drm_fd >= 0) { + /* Finally drop DRM master if possible, otherwise close DRM FD. + May be reopened on next non-vulkan window creation. */ + if (viddata->drm_fd >= 0 && !KMSDRM_DropMaster(_this)) { close(viddata->drm_fd); viddata->drm_fd = -1; } @@ -1450,6 +1506,12 @@ int KMSDRM_CreateWindow(_THIS, SDL_Window *window) windata->viddata = viddata; window->driverdata = windata; + /* Do we want a double buffering scheme to get low video lag? */ + windata->double_buffer = SDL_FALSE; + if (SDL_GetHintBoolean(SDL_HINT_VIDEO_DOUBLE_BUFFER, SDL_FALSE)) { + windata->double_buffer = SDL_TRUE; + } + if (!is_vulkan && !vulkan_mode) { /* NON-Vulkan block. */ /* Maybe you didn't ask for an OPENGL window, but that's what you will get. @@ -1555,7 +1617,12 @@ int KMSDRM_CreateWindow(_THIS, SDL_Window *window) SDL_SetKeyboardFocus(window); /* Tell the app that the window has moved to top-left. */ - SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, 0, 0); + { + SDL_Rect display_bounds; + SDL_zero(display_bounds); + SDL_GetDisplayBounds(SDL_GetWindowDisplayIndex(window), &display_bounds); + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, display_bounds.x, display_bounds.y); + } /* Allocated windata will be freed in KMSDRM_DestroyWindow, and KMSDRM_DestroyWindow() will be called by SDL_CreateWindow() diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.h b/src/video/kmsdrm/SDL_kmsdrmvideo.h index c9222f8..1643143 100644 --- a/src/video/kmsdrm/SDL_kmsdrmvideo.h +++ b/src/video/kmsdrm/SDL_kmsdrmvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -33,6 +33,45 @@ #include #include +#ifndef DRM_FORMAT_MOD_INVALID +#define DRM_FORMAT_MOD_INVALID 0x00ffffffffffffffULL +#endif + +#ifndef DRM_MODE_FB_MODIFIERS +#define DRM_MODE_FB_MODIFIERS 2 +#endif + +#ifndef DRM_MODE_PAGE_FLIP_ASYNC +#define DRM_MODE_PAGE_FLIP_ASYNC 2 +#endif + +#ifndef DRM_MODE_OBJECT_CONNECTOR +#define DRM_MODE_OBJECT_CONNECTOR 0xc0c0c0c0 +#endif + +#ifndef DRM_MODE_OBJECT_CRTC +#define DRM_MODE_OBJECT_CRTC 0xcccccccc +#endif + +#ifndef DRM_CAP_ASYNC_PAGE_FLIP +#define DRM_CAP_ASYNC_PAGE_FLIP 7 +#endif + +#ifndef DRM_CAP_CURSOR_WIDTH +#define DRM_CAP_CURSOR_WIDTH 8 +#endif + +#ifndef DRM_CAP_CURSOR_HEIGHT +#define DRM_CAP_CURSOR_HEIGHT 9 +#endif + +#ifndef GBM_FORMAT_ARGB8888 +#define GBM_FORMAT_ARGB8888 ((uint32_t)('A') | ((uint32_t)('R') << 8) | ((uint32_t)('2') << 16) | ((uint32_t)('4') << 24)) +#define GBM_BO_USE_CURSOR (1 << 1) +#define GBM_BO_USE_WRITE (1 << 3) +#define GBM_BO_USE_LINEAR (1 << 4) +#endif + typedef struct SDL_VideoData { int devindex; /* device index that was passed on creation */ diff --git a/src/video/kmsdrm/SDL_kmsdrmvulkan.c b/src/video/kmsdrm/SDL_kmsdrmvulkan.c index b5dc7b8..5190b77 100644 --- a/src/video/kmsdrm/SDL_kmsdrmvulkan.c +++ b/src/video/kmsdrm/SDL_kmsdrmvulkan.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/kmsdrm/SDL_kmsdrmvulkan.h b/src/video/kmsdrm/SDL_kmsdrmvulkan.h index 01a582a..1c2a48e 100644 --- a/src/video/kmsdrm/SDL_kmsdrmvulkan.h +++ b/src/video/kmsdrm/SDL_kmsdrmvulkan.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/n3ds/SDL_n3dsevents.c b/src/video/n3ds/SDL_n3dsevents.c index c45bb80..7d661c2 100644 --- a/src/video/n3ds/SDL_n3dsevents.c +++ b/src/video/n3ds/SDL_n3dsevents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/n3ds/SDL_n3dsevents_c.h b/src/video/n3ds/SDL_n3dsevents_c.h index 2e75951..f05cc7c 100644 --- a/src/video/n3ds/SDL_n3dsevents_c.h +++ b/src/video/n3ds/SDL_n3dsevents_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/n3ds/SDL_n3dsframebuffer.c b/src/video/n3ds/SDL_n3dsframebuffer.c index 784c2df..16e9e45 100644 --- a/src/video/n3ds/SDL_n3dsframebuffer.c +++ b/src/video/n3ds/SDL_n3dsframebuffer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/n3ds/SDL_n3dsframebuffer_c.h b/src/video/n3ds/SDL_n3dsframebuffer_c.h index 19a9e95..bbcfd4c 100644 --- a/src/video/n3ds/SDL_n3dsframebuffer_c.h +++ b/src/video/n3ds/SDL_n3dsframebuffer_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/n3ds/SDL_n3dsswkb.c b/src/video/n3ds/SDL_n3dsswkb.c index 9a35d27..af1d8fc 100644 --- a/src/video/n3ds/SDL_n3dsswkb.c +++ b/src/video/n3ds/SDL_n3dsswkb.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -30,17 +30,17 @@ static SwkbdState sw_keyboard; const static size_t BUFFER_SIZE = 256; -void N3DS_SwkbInit() +void N3DS_SwkbInit(void) { swkbdInit(&sw_keyboard, SWKBD_TYPE_NORMAL, 2, -1); } -void N3DS_SwkbPoll() +void N3DS_SwkbPoll(void) { return; } -void N3DS_SwkbQuit() +void N3DS_SwkbQuit(void) { return; } diff --git a/src/video/n3ds/SDL_n3dsswkb.h b/src/video/n3ds/SDL_n3dsswkb.h index 04a355b..196f7de 100644 --- a/src/video/n3ds/SDL_n3dsswkb.h +++ b/src/video/n3ds/SDL_n3dsswkb.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/n3ds/SDL_n3dstouch.c b/src/video/n3ds/SDL_n3dstouch.c index 982c578..593f64d 100644 --- a/src/video/n3ds/SDL_n3dstouch.c +++ b/src/video/n3ds/SDL_n3dstouch.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,7 +28,7 @@ #include "../../events/SDL_touch_c.h" #include "SDL_n3dstouch.h" -#define N3DS_TOUCH_ID 0 +#define N3DS_TOUCH_ID 1 /* Factors used to convert touchscreen coordinates to diff --git a/src/video/n3ds/SDL_n3dstouch.h b/src/video/n3ds/SDL_n3dstouch.h index d99e5a3..74aa5d5 100644 --- a/src/video/n3ds/SDL_n3dstouch.h +++ b/src/video/n3ds/SDL_n3dstouch.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/n3ds/SDL_n3dsvideo.c b/src/video/n3ds/SDL_n3dsvideo.c index fc875d3..e3c4f49 100644 --- a/src/video/n3ds/SDL_n3dsvideo.c +++ b/src/video/n3ds/SDL_n3dsvideo.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/n3ds/SDL_n3dsvideo.h b/src/video/n3ds/SDL_n3dsvideo.h index 455eaf4..3a9bfd9 100644 --- a/src/video/n3ds/SDL_n3dsvideo.h +++ b/src/video/n3ds/SDL_n3dsvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/nacl/SDL_naclevents.c b/src/video/nacl/SDL_naclevents.c index 6e7226e..08cba11 100644 --- a/src/video/nacl/SDL_naclevents.c +++ b/src/video/nacl/SDL_naclevents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/nacl/SDL_naclevents_c.h b/src/video/nacl/SDL_naclevents_c.h index 4bf777a..1b01e99 100644 --- a/src/video/nacl/SDL_naclevents_c.h +++ b/src/video/nacl/SDL_naclevents_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/nacl/SDL_naclglue.c b/src/video/nacl/SDL_naclglue.c index 04b0823..7ba6db3 100644 --- a/src/video/nacl/SDL_naclglue.c +++ b/src/video/nacl/SDL_naclglue.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/nacl/SDL_naclopengles.c b/src/video/nacl/SDL_naclopengles.c index fd121b7..f1fa797 100644 --- a/src/video/nacl/SDL_naclopengles.c +++ b/src/video/nacl/SDL_naclopengles.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/nacl/SDL_naclopengles.h b/src/video/nacl/SDL_naclopengles.h index 5ae3946..026eaa6 100644 --- a/src/video/nacl/SDL_naclopengles.h +++ b/src/video/nacl/SDL_naclopengles.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/nacl/SDL_naclvideo.c b/src/video/nacl/SDL_naclvideo.c index 53fc679..44e2aa9 100644 --- a/src/video/nacl/SDL_naclvideo.c +++ b/src/video/nacl/SDL_naclvideo.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/nacl/SDL_naclvideo.h b/src/video/nacl/SDL_naclvideo.h index 504f4d6..8be165f 100644 --- a/src/video/nacl/SDL_naclvideo.h +++ b/src/video/nacl/SDL_naclvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/nacl/SDL_naclwindow.c b/src/video/nacl/SDL_naclwindow.c index 200b345..3f61afc 100644 --- a/src/video/nacl/SDL_naclwindow.c +++ b/src/video/nacl/SDL_naclwindow.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/nacl/SDL_naclwindow.h b/src/video/nacl/SDL_naclwindow.h index 9ac941c..d2d5521 100644 --- a/src/video/nacl/SDL_naclwindow.h +++ b/src/video/nacl/SDL_naclwindow.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/ngage/SDL_ngageevents.cpp b/src/video/ngage/SDL_ngageevents.cpp index 3ecf164..9835364 100644 --- a/src/video/ngage/SDL_ngageevents.cpp +++ b/src/video/ngage/SDL_ngageevents.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/ngage/SDL_ngageevents_c.h b/src/video/ngage/SDL_ngageevents_c.h index e0ef5a0..45a3588 100644 --- a/src/video/ngage/SDL_ngageevents_c.h +++ b/src/video/ngage/SDL_ngageevents_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/ngage/SDL_ngageframebuffer.cpp b/src/video/ngage/SDL_ngageframebuffer.cpp index 98fb495..0975387 100644 --- a/src/video/ngage/SDL_ngageframebuffer.cpp +++ b/src/video/ngage/SDL_ngageframebuffer.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/ngage/SDL_ngageframebuffer_c.h b/src/video/ngage/SDL_ngageframebuffer_c.h index 02c50ef..57e8f3a 100644 --- a/src/video/ngage/SDL_ngageframebuffer_c.h +++ b/src/video/ngage/SDL_ngageframebuffer_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/ngage/SDL_ngagevideo.cpp b/src/video/ngage/SDL_ngagevideo.cpp index d18abc8..752f3df 100644 --- a/src/video/ngage/SDL_ngagevideo.cpp +++ b/src/video/ngage/SDL_ngagevideo.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/ngage/SDL_ngagevideo.h b/src/video/ngage/SDL_ngagevideo.h index 57386e1..a56b250 100644 --- a/src/video/ngage/SDL_ngagevideo.h +++ b/src/video/ngage/SDL_ngagevideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/ngage/SDL_ngagewindow.cpp b/src/video/ngage/SDL_ngagewindow.cpp index 37a6be0..3aa5d22 100644 --- a/src/video/ngage/SDL_ngagewindow.cpp +++ b/src/video/ngage/SDL_ngagewindow.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/ngage/SDL_ngagewindow.h b/src/video/ngage/SDL_ngagewindow.h index 933ca8e..76b4e4d 100644 --- a/src/video/ngage/SDL_ngagewindow.h +++ b/src/video/ngage/SDL_ngagewindow.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/offscreen/SDL_offscreenevents.c b/src/video/offscreen/SDL_offscreenevents.c index d825162..ef9cd0f 100644 --- a/src/video/offscreen/SDL_offscreenevents.c +++ b/src/video/offscreen/SDL_offscreenevents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/offscreen/SDL_offscreenevents_c.h b/src/video/offscreen/SDL_offscreenevents_c.h index ccbef93..201b432 100644 --- a/src/video/offscreen/SDL_offscreenevents_c.h +++ b/src/video/offscreen/SDL_offscreenevents_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/offscreen/SDL_offscreenframebuffer.c b/src/video/offscreen/SDL_offscreenframebuffer.c index 2b9337b..ef0c1e3 100644 --- a/src/video/offscreen/SDL_offscreenframebuffer.c +++ b/src/video/offscreen/SDL_offscreenframebuffer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/offscreen/SDL_offscreenframebuffer_c.h b/src/video/offscreen/SDL_offscreenframebuffer_c.h index 1151576..72840a2 100644 --- a/src/video/offscreen/SDL_offscreenframebuffer_c.h +++ b/src/video/offscreen/SDL_offscreenframebuffer_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/offscreen/SDL_offscreenopengles.c b/src/video/offscreen/SDL_offscreenopengles.c index a36cf51..95413d7 100644 --- a/src/video/offscreen/SDL_offscreenopengles.c +++ b/src/video/offscreen/SDL_offscreenopengles.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/offscreen/SDL_offscreenopengles.h b/src/video/offscreen/SDL_offscreenopengles.h index c8c23f1..15f7ecd 100644 --- a/src/video/offscreen/SDL_offscreenopengles.h +++ b/src/video/offscreen/SDL_offscreenopengles.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/offscreen/SDL_offscreenvideo.c b/src/video/offscreen/SDL_offscreenvideo.c index 2d42374..d9e31e5 100644 --- a/src/video/offscreen/SDL_offscreenvideo.c +++ b/src/video/offscreen/SDL_offscreenvideo.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/offscreen/SDL_offscreenvideo.h b/src/video/offscreen/SDL_offscreenvideo.h index f4e3c8f..17fc936 100644 --- a/src/video/offscreen/SDL_offscreenvideo.h +++ b/src/video/offscreen/SDL_offscreenvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/offscreen/SDL_offscreenwindow.c b/src/video/offscreen/SDL_offscreenwindow.c index 58fc2e9..bc0d121 100644 --- a/src/video/offscreen/SDL_offscreenwindow.c +++ b/src/video/offscreen/SDL_offscreenwindow.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/offscreen/SDL_offscreenwindow.h b/src/video/offscreen/SDL_offscreenwindow.h index aa189c0..08acba2 100644 --- a/src/video/offscreen/SDL_offscreenwindow.h +++ b/src/video/offscreen/SDL_offscreenwindow.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/os2/SDL_os2dive.c b/src/video/os2/SDL_os2dive.c index 0cb8735..66b3257 100644 --- a/src/video/os2/SDL_os2dive.c +++ b/src/video/os2/SDL_os2dive.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/os2/SDL_os2messagebox.c b/src/video/os2/SDL_os2messagebox.c index e394635..cf24b08 100644 --- a/src/video/os2/SDL_os2messagebox.c +++ b/src/video/os2/SDL_os2messagebox.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/os2/SDL_os2messagebox.h b/src/video/os2/SDL_os2messagebox.h index 453d035..f8fdd7f 100644 --- a/src/video/os2/SDL_os2messagebox.h +++ b/src/video/os2/SDL_os2messagebox.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/os2/SDL_os2mouse.c b/src/video/os2/SDL_os2mouse.c index 220766a..4842cbe 100644 --- a/src/video/os2/SDL_os2mouse.c +++ b/src/video/os2/SDL_os2mouse.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/os2/SDL_os2mouse.h b/src/video/os2/SDL_os2mouse.h index ccd99da..5ab8e01 100644 --- a/src/video/os2/SDL_os2mouse.h +++ b/src/video/os2/SDL_os2mouse.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/os2/SDL_os2output.h b/src/video/os2/SDL_os2output.h index 7115ab7..5f94d31 100644 --- a/src/video/os2/SDL_os2output.h +++ b/src/video/os2/SDL_os2output.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/os2/SDL_os2util.c b/src/video/os2/SDL_os2util.c index 44450b6..70aa293 100644 --- a/src/video/os2/SDL_os2util.c +++ b/src/video/os2/SDL_os2util.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/os2/SDL_os2util.h b/src/video/os2/SDL_os2util.h index 5def7b6..e612846 100644 --- a/src/video/os2/SDL_os2util.h +++ b/src/video/os2/SDL_os2util.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/os2/SDL_os2video.c b/src/video/os2/SDL_os2video.c index 8da1f4f..a5dd3f6 100644 --- a/src/video/os2/SDL_os2video.c +++ b/src/video/os2/SDL_os2video.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/os2/SDL_os2video.h b/src/video/os2/SDL_os2video.h index 0f9f379..e2aaa26 100644 --- a/src/video/os2/SDL_os2video.h +++ b/src/video/os2/SDL_os2video.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/os2/SDL_os2vman.c b/src/video/os2/SDL_os2vman.c index 5945e8e..0412ee0 100644 --- a/src/video/os2/SDL_os2vman.c +++ b/src/video/os2/SDL_os2vman.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/pandora/SDL_pandora.c b/src/video/pandora/SDL_pandora.c index 35e0623..03712b4 100644 --- a/src/video/pandora/SDL_pandora.c +++ b/src/video/pandora/SDL_pandora.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/pandora/SDL_pandora.h b/src/video/pandora/SDL_pandora.h index 43faa6a..307a12c 100644 --- a/src/video/pandora/SDL_pandora.h +++ b/src/video/pandora/SDL_pandora.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/pandora/SDL_pandora_events.c b/src/video/pandora/SDL_pandora_events.c index 4d6ef6e..372c0b7 100644 --- a/src/video/pandora/SDL_pandora_events.c +++ b/src/video/pandora/SDL_pandora_events.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/pandora/SDL_pandora_events.h b/src/video/pandora/SDL_pandora_events.h index 4753ff1..d4e2e76 100644 --- a/src/video/pandora/SDL_pandora_events.h +++ b/src/video/pandora/SDL_pandora_events.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/ps2/SDL_ps2video.c b/src/video/ps2/SDL_ps2video.c index 4e823fe..c80fc70 100644 --- a/src/video/ps2/SDL_ps2video.c +++ b/src/video/ps2/SDL_ps2video.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/ps2/SDL_ps2video.h b/src/video/ps2/SDL_ps2video.h index 6bc13b8..8c71666 100644 --- a/src/video/ps2/SDL_ps2video.h +++ b/src/video/ps2/SDL_ps2video.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/psp/SDL_pspevents.c b/src/video/psp/SDL_pspevents.c index 44b487f..3c4ae39 100644 --- a/src/video/psp/SDL_pspevents.c +++ b/src/video/psp/SDL_pspevents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/psp/SDL_pspevents_c.h b/src/video/psp/SDL_pspevents_c.h index fc9cd0e..e604d45 100644 --- a/src/video/psp/SDL_pspevents_c.h +++ b/src/video/psp/SDL_pspevents_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/psp/SDL_pspgl.c b/src/video/psp/SDL_pspgl.c index 7071091..381e832 100644 --- a/src/video/psp/SDL_pspgl.c +++ b/src/video/psp/SDL_pspgl.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/psp/SDL_pspgl_c.h b/src/video/psp/SDL_pspgl_c.h index b302c8e..e51aabc 100644 --- a/src/video/psp/SDL_pspgl_c.h +++ b/src/video/psp/SDL_pspgl_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/psp/SDL_pspmouse.c b/src/video/psp/SDL_pspmouse.c index 57fc45c..ce7658c 100644 --- a/src/video/psp/SDL_pspmouse.c +++ b/src/video/psp/SDL_pspmouse.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/psp/SDL_pspmouse_c.h b/src/video/psp/SDL_pspmouse_c.h index a961232..7abe075 100644 --- a/src/video/psp/SDL_pspmouse_c.h +++ b/src/video/psp/SDL_pspmouse_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/psp/SDL_pspvideo.c b/src/video/psp/SDL_pspvideo.c index 9631904..f678842 100644 --- a/src/video/psp/SDL_pspvideo.c +++ b/src/video/psp/SDL_pspvideo.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/psp/SDL_pspvideo.h b/src/video/psp/SDL_pspvideo.h index 442d3ea..56452cb 100644 --- a/src/video/psp/SDL_pspvideo.h +++ b/src/video/psp/SDL_pspvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/raspberry/SDL_rpievents.c b/src/video/raspberry/SDL_rpievents.c index 5b9bdf0..d97fb83 100644 --- a/src/video/raspberry/SDL_rpievents.c +++ b/src/video/raspberry/SDL_rpievents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/raspberry/SDL_rpievents_c.h b/src/video/raspberry/SDL_rpievents_c.h index e3b826c..7f8aec2 100644 --- a/src/video/raspberry/SDL_rpievents_c.h +++ b/src/video/raspberry/SDL_rpievents_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/raspberry/SDL_rpimouse.c b/src/video/raspberry/SDL_rpimouse.c index ff35a79..ea39049 100644 --- a/src/video/raspberry/SDL_rpimouse.c +++ b/src/video/raspberry/SDL_rpimouse.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/raspberry/SDL_rpimouse.h b/src/video/raspberry/SDL_rpimouse.h index 8ff70de..717b6b4 100644 --- a/src/video/raspberry/SDL_rpimouse.h +++ b/src/video/raspberry/SDL_rpimouse.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/raspberry/SDL_rpiopengles.c b/src/video/raspberry/SDL_rpiopengles.c index 27b4edf..91fe9f8 100644 --- a/src/video/raspberry/SDL_rpiopengles.c +++ b/src/video/raspberry/SDL_rpiopengles.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/raspberry/SDL_rpiopengles.h b/src/video/raspberry/SDL_rpiopengles.h index 15c6ab1..73f0642 100644 --- a/src/video/raspberry/SDL_rpiopengles.h +++ b/src/video/raspberry/SDL_rpiopengles.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/raspberry/SDL_rpivideo.c b/src/video/raspberry/SDL_rpivideo.c index 1442607..1604adb 100644 --- a/src/video/raspberry/SDL_rpivideo.c +++ b/src/video/raspberry/SDL_rpivideo.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -56,7 +56,7 @@ static void RPI_Destroy(SDL_VideoDevice *device) SDL_free(device); } -static int RPI_GetRefreshRate() +static int RPI_GetRefreshRate(void) { TV_DISPLAY_STATE_T tvstate; if (vc_tv_get_display_state(&tvstate) == 0) { diff --git a/src/video/raspberry/SDL_rpivideo.h b/src/video/raspberry/SDL_rpivideo.h index e2ffe6f..2f0135f 100644 --- a/src/video/raspberry/SDL_rpivideo.h +++ b/src/video/raspberry/SDL_rpivideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/riscos/SDL_riscosdefs.h b/src/video/riscos/SDL_riscosdefs.h index 8a621c2..03a6af1 100644 --- a/src/video/riscos/SDL_riscosdefs.h +++ b/src/video/riscos/SDL_riscosdefs.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/riscos/SDL_riscosevents.c b/src/video/riscos/SDL_riscosevents.c index cebb89f..f959f77 100644 --- a/src/video/riscos/SDL_riscosevents.c +++ b/src/video/riscos/SDL_riscosevents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/riscos/SDL_riscosevents_c.h b/src/video/riscos/SDL_riscosevents_c.h index 6f16b19..3b53d25 100644 --- a/src/video/riscos/SDL_riscosevents_c.h +++ b/src/video/riscos/SDL_riscosevents_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/riscos/SDL_riscosframebuffer.c b/src/video/riscos/SDL_riscosframebuffer.c index ae128d3..72bb8f9 100644 --- a/src/video/riscos/SDL_riscosframebuffer.c +++ b/src/video/riscos/SDL_riscosframebuffer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/riscos/SDL_riscosframebuffer_c.h b/src/video/riscos/SDL_riscosframebuffer_c.h index e4f79ad..61aa991 100644 --- a/src/video/riscos/SDL_riscosframebuffer_c.h +++ b/src/video/riscos/SDL_riscosframebuffer_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/riscos/SDL_riscosmessagebox.c b/src/video/riscos/SDL_riscosmessagebox.c index 9d44e07..e7dd119 100644 --- a/src/video/riscos/SDL_riscosmessagebox.c +++ b/src/video/riscos/SDL_riscosmessagebox.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/riscos/SDL_riscosmessagebox.h b/src/video/riscos/SDL_riscosmessagebox.h index 09f9c76..d56a64c 100644 --- a/src/video/riscos/SDL_riscosmessagebox.h +++ b/src/video/riscos/SDL_riscosmessagebox.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/riscos/SDL_riscosmodes.c b/src/video/riscos/SDL_riscosmodes.c index 79f5fa3..4975d04 100644 --- a/src/video/riscos/SDL_riscosmodes.c +++ b/src/video/riscos/SDL_riscosmodes.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/riscos/SDL_riscosmodes.h b/src/video/riscos/SDL_riscosmodes.h index f523dd4..c5347e0 100644 --- a/src/video/riscos/SDL_riscosmodes.h +++ b/src/video/riscos/SDL_riscosmodes.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/riscos/SDL_riscosmouse.c b/src/video/riscos/SDL_riscosmouse.c index 90c6de0..c1cd094 100644 --- a/src/video/riscos/SDL_riscosmouse.c +++ b/src/video/riscos/SDL_riscosmouse.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/riscos/SDL_riscosmouse.h b/src/video/riscos/SDL_riscosmouse.h index e675d84..5c12414 100644 --- a/src/video/riscos/SDL_riscosmouse.h +++ b/src/video/riscos/SDL_riscosmouse.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/riscos/SDL_riscosvideo.c b/src/video/riscos/SDL_riscosvideo.c index 1550139..380ad79 100644 --- a/src/video/riscos/SDL_riscosvideo.c +++ b/src/video/riscos/SDL_riscosvideo.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/riscos/SDL_riscosvideo.h b/src/video/riscos/SDL_riscosvideo.h index d014458..0734be2 100644 --- a/src/video/riscos/SDL_riscosvideo.h +++ b/src/video/riscos/SDL_riscosvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/riscos/SDL_riscoswindow.c b/src/video/riscos/SDL_riscoswindow.c index 5a59c49..32a7cfe 100644 --- a/src/video/riscos/SDL_riscoswindow.c +++ b/src/video/riscos/SDL_riscoswindow.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/riscos/SDL_riscoswindow.h b/src/video/riscos/SDL_riscoswindow.h index 48d17ba..59cb501 100644 --- a/src/video/riscos/SDL_riscoswindow.h +++ b/src/video/riscos/SDL_riscoswindow.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/riscos/scancodes_riscos.h b/src/video/riscos/scancodes_riscos.h index 1caa33a..79ed146 100644 --- a/src/video/riscos/scancodes_riscos.h +++ b/src/video/riscos/scancodes_riscos.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/sdlgenblit.pl b/src/video/sdlgenblit.pl index 4afef7a..5977448 100755 --- a/src/video/sdlgenblit.pl +++ b/src/video/sdlgenblit.pl @@ -92,7 +92,7 @@ sub open_file { /* DO NOT EDIT! This file is generated by sdlgenblit.pl */ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/uikit/SDL_uikitappdelegate.h b/src/video/uikit/SDL_uikitappdelegate.h index c40dae0..df3ff0f 100644 --- a/src/video/uikit/SDL_uikitappdelegate.h +++ b/src/video/uikit/SDL_uikitappdelegate.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/uikit/SDL_uikitappdelegate.m b/src/video/uikit/SDL_uikitappdelegate.m index 8fd4c71..31b114a 100644 --- a/src/video/uikit/SDL_uikitappdelegate.m +++ b/src/video/uikit/SDL_uikitappdelegate.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -189,12 +189,14 @@ - (instancetype)init - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { + NSString *screenname; + NSBundle *bundle; if (!(self = [super initWithNibName:nil bundle:nil])) { return nil; } - NSString *screenname = nibNameOrNil; - NSBundle *bundle = nibBundleOrNil; + screenname = nibNameOrNil; + bundle = nibBundleOrNil; /* A launch screen may not exist. Fall back to launch images in that case. */ if (screenname) { @@ -230,6 +232,10 @@ - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibB /* Xcode 5 introduced a dictionary of launch images in Info.plist. */ if (launchimages) { for (NSDictionary *dict in launchimages) { +#if !TARGET_OS_TV + UIInterfaceOrientationMask orientmask; + NSString *orientstring; +#endif NSString *minversion = dict[@"UILaunchImageMinimumOSVersion"]; NSString *sizestring = dict[@"UILaunchImageSize"]; @@ -247,8 +253,8 @@ - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibB } #if !TARGET_OS_TV - UIInterfaceOrientationMask orientmask = UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown; - NSString *orientstring = dict[@"UILaunchImageOrientation"]; + orientmask = UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown; + orientstring = dict[@"UILaunchImageOrientation"]; if (orientstring) { if ([orientstring isEqualToString:@"PortraitUpsideDown"]) { diff --git a/src/video/uikit/SDL_uikitclipboard.h b/src/video/uikit/SDL_uikitclipboard.h index ad26742..e3e8fcc 100644 --- a/src/video/uikit/SDL_uikitclipboard.h +++ b/src/video/uikit/SDL_uikitclipboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/uikit/SDL_uikitclipboard.m b/src/video/uikit/SDL_uikitclipboard.m index b025697..8bd3f97 100644 --- a/src/video/uikit/SDL_uikitclipboard.m +++ b/src/video/uikit/SDL_uikitclipboard.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/uikit/SDL_uikitevents.h b/src/video/uikit/SDL_uikitevents.h index fae3759..dda1944 100644 --- a/src/video/uikit/SDL_uikitevents.h +++ b/src/video/uikit/SDL_uikitevents.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/uikit/SDL_uikitevents.m b/src/video/uikit/SDL_uikitevents.m index 938b70a..0a96c68 100644 --- a/src/video/uikit/SDL_uikitevents.m +++ b/src/video/uikit/SDL_uikitevents.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -110,10 +110,11 @@ - (void)applicationDidChangeStatusBarOrientation void SDL_iPhoneSetEventPump(SDL_bool enabled) { - UIKit_EventPumpEnabled = enabled; - static SDL_LifecycleObserver *lifecycleObserver; static dispatch_once_t onceToken; + + UIKit_EventPumpEnabled = enabled; + dispatch_once(&onceToken, ^{ lifecycleObserver = [SDL_LifecycleObserver new]; }); @@ -122,10 +123,6 @@ void SDL_iPhoneSetEventPump(SDL_bool enabled) void UIKit_PumpEvents(_THIS) { - if (!UIKit_EventPumpEnabled) { - return; - } - /* Let the run loop run for a short amount of time: long enough for touch events to get processed (which is important to get certain elements of Game Center's GKLeaderboardViewController to respond @@ -133,9 +130,12 @@ touch events to get processed (which is important to get certain delay in the rest of the app. */ const CFTimeInterval seconds = 0.000002; + SInt32 result; + if (!UIKit_EventPumpEnabled) { + return; + } /* Pump most event types. */ - SInt32 result; do { result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, seconds, TRUE); } while (result == kCFRunLoopRunHandledSource); @@ -159,13 +159,14 @@ touch events to get processed (which is important to get certain static void OnGCKeyboardConnected(GCKeyboard *keyboard) API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)) { + dispatch_queue_t queue; keyboard_connected = SDL_TRUE; keyboard.keyboardInput.keyChangedHandler = ^(GCKeyboardInput *kbrd, GCControllerButtonInput *key, GCKeyCode keyCode, BOOL pressed) { SDL_SendKeyboardKey(pressed ? SDL_PRESSED : SDL_RELEASED, (SDL_Scancode)keyCode); }; - dispatch_queue_t queue = dispatch_queue_create( "org.libsdl.input.keyboard", DISPATCH_QUEUE_SERIAL ); + queue = dispatch_queue_create( "org.libsdl.input.keyboard", DISPATCH_QUEUE_SERIAL ); dispatch_set_target_queue( queue, dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0 ) ); keyboard.handlerQueue = queue; } @@ -275,7 +276,7 @@ static void UpdateScrollDirection(void) /* Couldn't read the preference, assume natural scrolling direction */ naturalScrollDirection = YES; } - if (naturalScrollDirection) { + if (naturalScrollDirection) { mouse_scroll_direction = SDL_MOUSEWHEEL_FLIPPED; } else { mouse_scroll_direction = SDL_MOUSEWHEEL_NORMAL; @@ -307,6 +308,8 @@ static void OnGCMouseButtonChanged(SDL_MouseID mouseID, Uint8 button, BOOL press static void OnGCMouseConnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)) { + int auxiliary_button; + dispatch_queue_t queue; SDL_MouseID mouseID = mice_connected; mouse.mouseInput.leftButton.pressedChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) @@ -322,7 +325,7 @@ static void OnGCMouseConnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios(14 OnGCMouseButtonChanged(mouseID, SDL_BUTTON_RIGHT, pressed); }; - int auxiliary_button = SDL_BUTTON_X1; + auxiliary_button = SDL_BUTTON_X1; for (GCControllerButtonInput *btn in mouse.mouseInput.auxiliaryButtons) { btn.pressedChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) { @@ -355,7 +358,7 @@ static void OnGCMouseConnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios(14 }; UpdateScrollDirection(); - dispatch_queue_t queue = dispatch_queue_create( "org.libsdl.input.mouse", DISPATCH_QUEUE_SERIAL ); + queue = dispatch_queue_create( "org.libsdl.input.mouse", DISPATCH_QUEUE_SERIAL ); dispatch_set_target_queue( queue, dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0 ) ); mouse.handlerQueue = queue; diff --git a/src/video/uikit/SDL_uikitmessagebox.h b/src/video/uikit/SDL_uikitmessagebox.h index 8723983..4a9a4dc 100644 --- a/src/video/uikit/SDL_uikitmessagebox.h +++ b/src/video/uikit/SDL_uikitmessagebox.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/uikit/SDL_uikitmessagebox.m b/src/video/uikit/SDL_uikitmessagebox.m index b68c065..a28f1cf 100644 --- a/src/video/uikit/SDL_uikitmessagebox.m +++ b/src/video/uikit/SDL_uikitmessagebox.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -56,12 +56,12 @@ static BOOL UIKit_ShowMessageBoxAlertController(const SDL_MessageBoxData *messag int __block clickedindex = messageboxdata->numbuttons; UIWindow *window = nil; UIWindow *alertwindow = nil; + UIAlertController *alert; if (![UIAlertController class]) { return NO; } - UIAlertController *alert; alert = [UIAlertController alertControllerWithTitle:@(messageboxdata->title) message:@(messageboxdata->message) preferredStyle:UIAlertControllerStyleAlert]; diff --git a/src/video/uikit/SDL_uikitmetalview.h b/src/video/uikit/SDL_uikitmetalview.h index 7a3060e..acc10fb 100644 --- a/src/video/uikit/SDL_uikitmetalview.h +++ b/src/video/uikit/SDL_uikitmetalview.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/uikit/SDL_uikitmetalview.m b/src/video/uikit/SDL_uikitmetalview.m index 5c41aa5..7c17d8d 100644 --- a/src/video/uikit/SDL_uikitmetalview.m +++ b/src/video/uikit/SDL_uikitmetalview.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/uikit/SDL_uikitmodes.h b/src/video/uikit/SDL_uikitmodes.h index 38511a2..e5b103a 100644 --- a/src/video/uikit/SDL_uikitmodes.h +++ b/src/video/uikit/SDL_uikitmodes.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/uikit/SDL_uikitmodes.m b/src/video/uikit/SDL_uikitmodes.m index 4772307..1b1b4de 100644 --- a/src/video/uikit/SDL_uikitmodes.m +++ b/src/video/uikit/SDL_uikitmodes.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -34,13 +34,17 @@ @implementation SDL_DisplayData - (instancetype)initWithScreen:(UIScreen*)screen { if (self = [super init]) { + NSDictionary* devices; + struct utsname systemInfo; + NSString* deviceName; + id foundDPI; self.uiscreen = screen; /* * A well up to date list of device info can be found here: * https://github.com/lmirosevic/GBDeviceInfo/blob/master/GBDeviceInfo/GBDeviceInfo_iOS.m */ - NSDictionary* devices = @{ + devices = @{ @"iPhone1,1": @163, @"iPhone1,2": @163, @"iPhone2,1": @163, @@ -138,11 +142,10 @@ - (instancetype)initWithScreen:(UIScreen*)screen @"iPod9,1": @326, }; - struct utsname systemInfo; uname(&systemInfo); - NSString* deviceName = + deviceName = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding]; - id foundDPI = devices[deviceName]; + foundDPI = devices[deviceName]; if (foundDPI) { self.screenDPI = (float)[foundDPI integerValue]; } else { @@ -296,6 +299,7 @@ int UIKit_AddDisplay(UIScreen *uiscreen, SDL_bool send_event) CGSize size = uiscreen.bounds.size; SDL_VideoDisplay display; SDL_DisplayMode mode; + SDL_DisplayData *data; SDL_zero(mode); /* Make sure the width/height are oriented correctly */ @@ -319,7 +323,7 @@ int UIKit_AddDisplay(UIScreen *uiscreen, SDL_bool send_event) display.current_mode = mode; /* Allocate the display data */ - SDL_DisplayData *data = [[SDL_DisplayData alloc] initWithScreen:uiscreen]; + data = [[SDL_DisplayData alloc] initWithScreen:uiscreen]; if (!data) { UIKit_FreeDisplayModeData(&display.desktop_mode); return SDL_OutOfMemory(); @@ -494,10 +498,11 @@ int UIKit_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * r void UIKit_QuitModes(_THIS) { + int i, j; + [SDL_DisplayWatch stop]; /* Release Objective-C objects, so higher level doesn't free() them. */ - int i, j; @autoreleasepool { for (i = 0; i < _this->num_displays; i++) { SDL_VideoDisplay *display = &_this->displays[i]; diff --git a/src/video/uikit/SDL_uikitopengles.h b/src/video/uikit/SDL_uikitopengles.h index 00efc46..0533f69 100644 --- a/src/video/uikit/SDL_uikitopengles.h +++ b/src/video/uikit/SDL_uikitopengles.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/uikit/SDL_uikitopengles.m b/src/video/uikit/SDL_uikitopengles.m index 8713ae3..988966d 100644 --- a/src/video/uikit/SDL_uikitopengles.m +++ b/src/video/uikit/SDL_uikitopengles.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/uikit/SDL_uikitopenglview.h b/src/video/uikit/SDL_uikitopenglview.h index d0eb0ac..70abdc9 100644 --- a/src/video/uikit/SDL_uikitopenglview.h +++ b/src/video/uikit/SDL_uikitopenglview.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/uikit/SDL_uikitopenglview.m b/src/video/uikit/SDL_uikitopenglview.m index 145e867..c36f060 100644 --- a/src/video/uikit/SDL_uikitopenglview.m +++ b/src/video/uikit/SDL_uikitopenglview.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -74,6 +74,7 @@ - (instancetype)initWithFrame:(CGRect)frame const BOOL useStencilBuffer = (stencilBits != 0); const BOOL useDepthBuffer = (depthBits != 0); NSString *colorFormat = nil; + CAEAGLLayer *eaglLayer; context = glcontext; samples = multisamples; @@ -105,7 +106,7 @@ - (instancetype)initWithFrame:(CGRect)frame colorBufferFormat = GL_RGB565; } - CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer; + eaglLayer = (CAEAGLLayer *)self.layer; eaglLayer.opaque = YES; eaglLayer.drawableProperties = @{ @@ -315,10 +316,13 @@ - (void)swapBuffers - (void)layoutSubviews { + int width; + int height; + [super layoutSubviews]; - int width = (int) (self.bounds.size.width * self.contentScaleFactor); - int height = (int) (self.bounds.size.height * self.contentScaleFactor); + width = (int) (self.bounds.size.width * self.contentScaleFactor); + height = (int) (self.bounds.size.height * self.contentScaleFactor); /* Update the color and depth buffer storage if the layer size has changed. */ if (width != backingWidth || height != backingHeight) { diff --git a/src/video/uikit/SDL_uikitvideo.h b/src/video/uikit/SDL_uikitvideo.h index 02a0110..4d3b81a 100644 --- a/src/video/uikit/SDL_uikitvideo.h +++ b/src/video/uikit/SDL_uikitvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/uikit/SDL_uikitvideo.m b/src/video/uikit/SDL_uikitvideo.m index f3257ea..f7aa3fd 100644 --- a/src/video/uikit/SDL_uikitvideo.m +++ b/src/video/uikit/SDL_uikitvideo.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -198,6 +198,11 @@ CGRect UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen) { SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; CGRect frame = screen.bounds; +#if !TARGET_OS_TV + UIInterfaceOrientation orient; + BOOL landscape; + BOOL fullscreen; +#endif /* Use the UIWindow bounds instead of the UIScreen bounds, when possible. * The uiwindow bounds may be smaller than the screen bounds when Split View @@ -215,10 +220,10 @@ CGRect UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen) * https://bugzilla.libsdl.org/show_bug.cgi?id=3505 * https://bugzilla.libsdl.org/show_bug.cgi?id=3465 * https://forums.developer.apple.com/thread/65337 */ - UIInterfaceOrientation orient = [UIApplication sharedApplication].statusBarOrientation; - BOOL landscape = UIInterfaceOrientationIsLandscape(orient) || + orient = [UIApplication sharedApplication].statusBarOrientation; + landscape = UIInterfaceOrientationIsLandscape(orient) || !(UIKit_GetSupportedOrientations(window) & (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown)); - BOOL fullscreen = CGRectEqualToRect(screen.bounds, frame); + fullscreen = CGRectEqualToRect(screen.bounds, frame); /* The orientation flip doesn't make sense when the window is smaller * than the screen (iPad Split View, for example). */ diff --git a/src/video/uikit/SDL_uikitview.h b/src/video/uikit/SDL_uikitview.h index c7fa8a8..9c35e63 100644 --- a/src/video/uikit/SDL_uikitview.h +++ b/src/video/uikit/SDL_uikitview.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/uikit/SDL_uikitview.m b/src/video/uikit/SDL_uikitview.m index 63afa09..676fedb 100644 --- a/src/video/uikit/SDL_uikitview.m +++ b/src/video/uikit/SDL_uikitview.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -53,20 +53,25 @@ - (instancetype)initWithFrame:(CGRect)frame { if ((self = [super initWithFrame:frame])) { #if TARGET_OS_TV + UISwipeGestureRecognizer *swipeUp; + UISwipeGestureRecognizer *swipeDown; + UISwipeGestureRecognizer *swipeLeft; + UISwipeGestureRecognizer *swipeRight; + /* Apple TV Remote touchpad swipe gestures. */ - UISwipeGestureRecognizer *swipeUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGesture:)]; + swipeUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGesture:)]; swipeUp.direction = UISwipeGestureRecognizerDirectionUp; [self addGestureRecognizer:swipeUp]; - UISwipeGestureRecognizer *swipeDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGesture:)]; + swipeDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGesture:)]; swipeDown.direction = UISwipeGestureRecognizerDirectionDown; [self addGestureRecognizer:swipeDown]; - UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGesture:)]; + swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGesture:)]; swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft; [self addGestureRecognizer:swipeLeft]; - UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGesture:)]; + swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGesture:)]; swipeRight.direction = UISwipeGestureRecognizerDirectionRight; [self addGestureRecognizer:swipeRight]; #endif @@ -257,6 +262,7 @@ - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event } #endif if (!handled) { + CGPoint locationInView; SDL_TouchDeviceType touchType = [self touchTypeForTouch:touch]; SDL_TouchID touchId = [self touchIdForType:touchType]; float pressure = [self pressureForTouch:touch]; @@ -267,7 +273,7 @@ - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event /* FIXME, need to send: int clicks = (int) touch.tapCount; ? */ - CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES]; + locationInView = [self touchLocation:touch shouldNormalize:YES]; SDL_SendTouch(touchId, (SDL_FingerID)((size_t)touch), sdlwindow, SDL_TRUE, locationInView.x, locationInView.y, pressure); } @@ -312,6 +318,7 @@ - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event } #endif if (!handled) { + CGPoint locationInView; SDL_TouchDeviceType touchType = [self touchTypeForTouch:touch]; SDL_TouchID touchId = [self touchIdForType:touchType]; float pressure = [self pressureForTouch:touch]; @@ -322,7 +329,7 @@ - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event /* FIXME, need to send: int clicks = (int) touch.tapCount; ? */ - CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES]; + locationInView = [self touchLocation:touch shouldNormalize:YES]; SDL_SendTouch(touchId, (SDL_FingerID)((size_t)touch), sdlwindow, SDL_FALSE, locationInView.x, locationInView.y, pressure); } @@ -348,6 +355,7 @@ - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event } #endif if (!handled) { + CGPoint locationInView; SDL_TouchDeviceType touchType = [self touchTypeForTouch:touch]; SDL_TouchID touchId = [self touchIdForType:touchType]; float pressure = [self pressureForTouch:touch]; @@ -356,7 +364,7 @@ - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event continue; } - CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES]; + locationInView = [self touchLocation:touch shouldNormalize:YES]; SDL_SendTouchMotion(touchId, (SDL_FingerID)((size_t)touch), sdlwindow, locationInView.x, locationInView.y, pressure); } diff --git a/src/video/uikit/SDL_uikitviewcontroller.h b/src/video/uikit/SDL_uikitviewcontroller.h index 660e11c..1ae4633 100644 --- a/src/video/uikit/SDL_uikitviewcontroller.h +++ b/src/video/uikit/SDL_uikitviewcontroller.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/uikit/SDL_uikitviewcontroller.m b/src/video/uikit/SDL_uikitviewcontroller.m index 0d8052b..dee4b19 100644 --- a/src/video/uikit/SDL_uikitviewcontroller.m +++ b/src/video/uikit/SDL_uikitviewcontroller.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -118,6 +118,20 @@ - (instancetype)initWithSDLWindow:(SDL_Window *)_window SDL_HideHomeIndicatorHintChanged, (__bridge void *) self); #endif + + /* Enable high refresh rates on iOS + * To enable this on phones, you should add the following line to Info.plist: + * CADisableMinimumFrameDurationOnPhone + */ + if (@available(iOS 15.0, tvOS 15.0, *)) { + SDL_DisplayMode mode; + if (SDL_GetDesktopDisplayMode(0, &mode) == 0 && mode.refresh_rate > 60.0f) { + int frame_rate = (int)mode.refresh_rate; + displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(doLoop:)]; + displayLink.preferredFrameRateRange = CAFrameRateRangeMake((frame_rate * 2) / 3, frame_rate, frame_rate); + [displayLink addToRunLoop:NSRunLoop.currentRunLoop forMode:NSDefaultRunLoopMode]; + } + } } return self; } @@ -147,6 +161,9 @@ - (void)setAnimationCallback:(int)interval { [self stopAnimation]; + if (interval <= 0) { + interval = 1; + } animationInterval = interval; animationCallback = callback; animationCallbackParam = callbackParam; @@ -158,10 +175,14 @@ - (void)setAnimationCallback:(int)interval - (void)startAnimation { +#ifdef __IPHONE_10_3 + SDL_WindowData *data; +#endif + displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(doLoop:)]; #ifdef __IPHONE_10_3 - SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; + data = (__bridge SDL_WindowData *) window->driverdata; if ([displayLink respondsToSelector:@selector(preferredFramesPerSecond)] && data != nil && data.uiwindow != nil @@ -187,7 +208,7 @@ - (void)stopAnimation - (void)doLoop:(CADisplayLink*)sender { /* Don't run the game loop while a messagebox is up */ - if (!UIKit_ShowingMessageBox()) { + if (animationCallback && !UIKit_ShowingMessageBox()) { /* See the comment in the function definition. */ #if defined(SDL_VIDEO_OPENGL_ES) || defined(SDL_VIDEO_OPENGL_ES2) UIKit_GL_RestoreCurrentContext(); @@ -269,6 +290,7 @@ - (BOOL)prefersPointerLocked /* Set ourselves up as a UITextFieldDelegate */ - (void)initKeyboard { + NSNotificationCenter *center; obligateForBackspace = @" "; /* 64 space */ textField = [[SDLUITextField alloc] initWithFrame:CGRectZero]; textField.delegate = self; @@ -288,7 +310,7 @@ - (void)initKeyboard textField.hidden = YES; keyboardVisible = NO; - NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + center = [NSNotificationCenter defaultCenter]; #if !TARGET_OS_TV [center addObserver:self selector:@selector(keyboardWillShow:) @@ -415,6 +437,9 @@ - (void)hideKeyboard - (void)keyboardWillShow:(NSNotification *)notification { BOOL shouldStartTextInput = NO; +#if !TARGET_OS_TV + CGRect kbrect; +#endif if (!SDL_IsTextInputActive() && !hidingKeyboard && !rotatingOrientation) { shouldStartTextInput = YES; @@ -422,7 +447,7 @@ - (void)keyboardWillShow:(NSNotification *)notification showingKeyboard = YES; #if !TARGET_OS_TV - CGRect kbrect = [[notification userInfo][UIKeyboardFrameEndUserInfoKey] CGRectValue]; + kbrect = [[notification userInfo][UIKeyboardFrameEndUserInfoKey] CGRectValue]; /* The keyboard rect is in the coordinate space of the screen/window, but we * want its height in the coordinate space of the view. */ @@ -568,12 +593,13 @@ - (BOOL)textFieldShouldReturn:(UITextField*)_textField static SDL_uikitviewcontroller *GetWindowViewController(SDL_Window * window) { + SDL_WindowData *data; if (!window || !window->driverdata) { SDL_SetError("Invalid window"); return nil; } - SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata; + data = (__bridge SDL_WindowData *)window->driverdata; return data.viewcontroller; } diff --git a/src/video/uikit/SDL_uikitvulkan.h b/src/video/uikit/SDL_uikitvulkan.h index fe558f9..af436c4 100644 --- a/src/video/uikit/SDL_uikitvulkan.h +++ b/src/video/uikit/SDL_uikitvulkan.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/uikit/SDL_uikitvulkan.m b/src/video/uikit/SDL_uikitvulkan.m index c0dfd29..01cfd7e 100644 --- a/src/video/uikit/SDL_uikitvulkan.m +++ b/src/video/uikit/SDL_uikitvulkan.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/uikit/SDL_uikitwindow.h b/src/video/uikit/SDL_uikitwindow.h index bf79ee1..7dd90ac 100644 --- a/src/video/uikit/SDL_uikitwindow.h +++ b/src/video/uikit/SDL_uikitwindow.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/uikit/SDL_uikitwindow.m b/src/video/uikit/SDL_uikitwindow.m index ff3cb85..8ce26a5 100644 --- a/src/video/uikit/SDL_uikitwindow.m +++ b/src/video/uikit/SDL_uikitwindow.m @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -155,6 +155,10 @@ int UIKit_CreateWindow(_THIS, SDL_Window *window) SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata; SDL_Window *other; + UIWindow *uiwindow; +#if !TARGET_OS_TV + const CGSize origsize = data.uiscreen.currentMode.size; +#endif /* We currently only handle a single window per display on iOS */ for (other = _this->windows; other; other = other->next) { @@ -167,14 +171,13 @@ int UIKit_CreateWindow(_THIS, SDL_Window *window) * user, so it's in standby), try to force the display to a resolution * that most closely matches the desired window size. */ #if !TARGET_OS_TV - const CGSize origsize = data.uiscreen.currentMode.size; if ((origsize.width == 0.0f) && (origsize.height == 0.0f)) { + int i; + const SDL_DisplayMode *bestmode = NULL; if (display->num_display_modes == 0) { _this->GetDisplayModes(_this, display); } - int i; - const SDL_DisplayMode *bestmode = NULL; for (i = display->num_display_modes; i >= 0; i--) { const SDL_DisplayMode *mode = &display->display_modes[i]; if ((mode->w >= window->w) && (mode->h >= window->h)) { @@ -204,7 +207,7 @@ int UIKit_CreateWindow(_THIS, SDL_Window *window) /* ignore the size user requested, and make a fullscreen window */ /* !!! FIXME: can we have a smaller view? */ - UIWindow *uiwindow = [[SDL_uikitwindow alloc] initWithFrame:data.uiscreen.bounds]; + uiwindow = [[SDL_uikitwindow alloc] initWithFrame:data.uiscreen.bounds]; /* put the window on an external display if appropriate. */ if (data.uiscreen != [UIScreen mainScreen]) { @@ -230,12 +233,14 @@ void UIKit_SetWindowTitle(_THIS, SDL_Window * window) void UIKit_ShowWindow(_THIS, SDL_Window * window) { @autoreleasepool { + SDL_VideoDisplay *display; + SDL_DisplayData *displaydata; SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata; [data.uiwindow makeKeyAndVisible]; /* Make this window the current mouse focus for touch input */ - SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); - SDL_DisplayData *displaydata = (__bridge SDL_DisplayData *) display->driverdata; + display = SDL_GetDisplayForWindow(window); + displaydata = (__bridge SDL_DisplayData *) display->driverdata; if (displaydata.uiscreen == [UIScreen mainScreen]) { SDL_SetMouseFocus(window); SDL_SetKeyboardFocus(window); diff --git a/src/video/vita/SDL_vitaframebuffer.c b/src/video/vita/SDL_vitaframebuffer.c index 56069b2..c0f9d9e 100644 --- a/src/video/vita/SDL_vitaframebuffer.c +++ b/src/video/vita/SDL_vitaframebuffer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/vita/SDL_vitaframebuffer.h b/src/video/vita/SDL_vitaframebuffer.h index 495d51b..cb6d317 100644 --- a/src/video/vita/SDL_vitaframebuffer.h +++ b/src/video/vita/SDL_vitaframebuffer.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/vita/SDL_vitagl_pvr.c b/src/video/vita/SDL_vitagl_pvr.c index 5e148f9..f984577 100644 --- a/src/video/vita/SDL_vitagl_pvr.c +++ b/src/video/vita/SDL_vitagl_pvr.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/vita/SDL_vitagl_pvr_c.h b/src/video/vita/SDL_vitagl_pvr_c.h index fee3d30..083ebac 100644 --- a/src/video/vita/SDL_vitagl_pvr_c.h +++ b/src/video/vita/SDL_vitagl_pvr_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/vita/SDL_vitagles.c b/src/video/vita/SDL_vitagles.c index 1944112..d3edcec 100644 --- a/src/video/vita/SDL_vitagles.c +++ b/src/video/vita/SDL_vitagles.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/vita/SDL_vitagles_c.h b/src/video/vita/SDL_vitagles_c.h index 6dcc651..a86e43b 100644 --- a/src/video/vita/SDL_vitagles_c.h +++ b/src/video/vita/SDL_vitagles_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/vita/SDL_vitagles_pvr.c b/src/video/vita/SDL_vitagles_pvr.c index cf917af..066e466 100644 --- a/src/video/vita/SDL_vitagles_pvr.c +++ b/src/video/vita/SDL_vitagles_pvr.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/vita/SDL_vitagles_pvr_c.h b/src/video/vita/SDL_vitagles_pvr_c.h index 2815057..5378865 100644 --- a/src/video/vita/SDL_vitagles_pvr_c.h +++ b/src/video/vita/SDL_vitagles_pvr_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/vita/SDL_vitakeyboard.c b/src/video/vita/SDL_vitakeyboard.c index 038e0ff..a110661 100644 --- a/src/video/vita/SDL_vitakeyboard.c +++ b/src/video/vita/SDL_vitakeyboard.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/vita/SDL_vitakeyboard.h b/src/video/vita/SDL_vitakeyboard.h index 3ea6465..d63e77c 100644 --- a/src/video/vita/SDL_vitakeyboard.h +++ b/src/video/vita/SDL_vitakeyboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/vita/SDL_vitamessagebox.c b/src/video/vita/SDL_vitamessagebox.c index dc57d28..f78c970 100644 --- a/src/video/vita/SDL_vitamessagebox.c +++ b/src/video/vita/SDL_vitamessagebox.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -26,13 +26,13 @@ #include "SDL_vitamessagebox.h" #include -#ifdef SDL_VIDEO_RENDER_VITA_GXM +#if SDL_VIDEO_RENDER_VITA_GXM #include "../../render/vitagxm/SDL_render_vita_gxm_tools.h" #endif /* SDL_VIDEO_RENDER_VITA_GXM */ int VITA_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) { -#ifdef SDL_VIDEO_RENDER_VITA_GXM +#if SDL_VIDEO_RENDER_VITA_GXM SceMsgDialogParam param; SceMsgDialogUserMessageParam msgParam; SceMsgDialogButtonsParam buttonParam; diff --git a/src/video/vita/SDL_vitamessagebox.h b/src/video/vita/SDL_vitamessagebox.h index 15aeb6d..5d54168 100644 --- a/src/video/vita/SDL_vitamessagebox.h +++ b/src/video/vita/SDL_vitamessagebox.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/vita/SDL_vitamouse.c b/src/video/vita/SDL_vitamouse.c index 47fa095..4c53406 100644 --- a/src/video/vita/SDL_vitamouse.c +++ b/src/video/vita/SDL_vitamouse.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -73,12 +73,28 @@ void VITA_PollMouse(void) else SDL_SendMouseButton(Vita_Window, 0, SDL_PRESSED, SDL_BUTTON_MIDDLE); } + if (changed_buttons & 0x8) { + if (prev_buttons & 0x8) + SDL_SendMouseButton(Vita_Window, 0, SDL_RELEASED, SDL_BUTTON_X1); + else + SDL_SendMouseButton(Vita_Window, 0, SDL_PRESSED, SDL_BUTTON_X1); + } + if (changed_buttons & 0x10) { + if (prev_buttons & 0x10) + SDL_SendMouseButton(Vita_Window, 0, SDL_RELEASED, SDL_BUTTON_X2); + else + SDL_SendMouseButton(Vita_Window, 0, SDL_PRESSED, SDL_BUTTON_X2); + } prev_buttons = m_reports[i].buttons; if (m_reports[i].rel_x || m_reports[i].rel_y) { SDL_SendMouseMotion(Vita_Window, 0, 1, m_reports[i].rel_x, m_reports[i].rel_y); } + + if (m_reports[i].tilt != 0 || m_reports[i].wheel != 0) { + SDL_SendMouseWheel(Vita_Window, 0, m_reports[i].tilt, m_reports[i].wheel, SDL_MOUSEWHEEL_NORMAL); + } } } } diff --git a/src/video/vita/SDL_vitamouse_c.h b/src/video/vita/SDL_vitamouse_c.h index 281a611..4104eb6 100644 --- a/src/video/vita/SDL_vitamouse_c.h +++ b/src/video/vita/SDL_vitamouse_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/vita/SDL_vitatouch.c b/src/video/vita/SDL_vitatouch.c index 07cbede..62d2977 100644 --- a/src/video/vita/SDL_vitatouch.c +++ b/src/video/vita/SDL_vitatouch.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -70,8 +70,8 @@ void VITA_InitTouch(void) } // Support passing both front and back touch devices in events - SDL_AddTouch((SDL_TouchID)0, SDL_TOUCH_DEVICE_DIRECT, "Front"); - SDL_AddTouch((SDL_TouchID)1, SDL_TOUCH_DEVICE_INDIRECT_ABSOLUTE, "Back"); + SDL_AddTouch((SDL_TouchID)1, SDL_TOUCH_DEVICE_DIRECT, "Front"); + SDL_AddTouch((SDL_TouchID)2, SDL_TOUCH_DEVICE_INDIRECT_ABSOLUTE, "Back"); } void VITA_QuitTouch(void) @@ -123,7 +123,7 @@ void VITA_PollTouch(void) // Skip if finger was already previously down if (!finger_down) { // Send an initial touch - SDL_SendTouch((SDL_TouchID)port, + SDL_SendTouch((SDL_TouchID)(port + 1), finger_id, Vita_Window, SDL_TRUE, @@ -133,7 +133,7 @@ void VITA_PollTouch(void) } // Always send the motion - SDL_SendTouchMotion((SDL_TouchID)port, + SDL_SendTouchMotion((SDL_TouchID)(port + 1), finger_id, Vita_Window, x, @@ -160,7 +160,7 @@ void VITA_PollTouch(void) VITA_ConvertTouchXYToSDLXY(&x, &y, touch_old[port].report[i].x, touch_old[port].report[i].y, port); finger_id = (SDL_FingerID)touch_old[port].report[i].id; // Finger released from screen - SDL_SendTouch((SDL_TouchID)port, + SDL_SendTouch((SDL_TouchID)(port + 1), finger_id, Vita_Window, SDL_FALSE, diff --git a/src/video/vita/SDL_vitatouch.h b/src/video/vita/SDL_vitatouch.h index 29369dc..62cd28d 100644 --- a/src/video/vita/SDL_vitatouch.h +++ b/src/video/vita/SDL_vitatouch.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/vita/SDL_vitavideo.c b/src/video/vita/SDL_vitavideo.c index 9b8839d..afa9b54 100644 --- a/src/video/vita/SDL_vitavideo.c +++ b/src/video/vita/SDL_vitavideo.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/vita/SDL_vitavideo.h b/src/video/vita/SDL_vitavideo.h index 5f23459..defc545 100644 --- a/src/video/vita/SDL_vitavideo.h +++ b/src/video/vita/SDL_vitavideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/vivante/SDL_vivanteopengles.c b/src/video/vivante/SDL_vivanteopengles.c index e088cf4..1939c74 100644 --- a/src/video/vivante/SDL_vivanteopengles.c +++ b/src/video/vivante/SDL_vivanteopengles.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/vivante/SDL_vivanteopengles.h b/src/video/vivante/SDL_vivanteopengles.h index 7dc55c2..d302bc8 100644 --- a/src/video/vivante/SDL_vivanteopengles.h +++ b/src/video/vivante/SDL_vivanteopengles.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/vivante/SDL_vivanteplatform.c b/src/video/vivante/SDL_vivanteplatform.c index cf4b5ac..7c17889 100644 --- a/src/video/vivante/SDL_vivanteplatform.c +++ b/src/video/vivante/SDL_vivanteplatform.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/vivante/SDL_vivanteplatform.h b/src/video/vivante/SDL_vivanteplatform.h index 19e8e3e..bcf7c8d 100644 --- a/src/video/vivante/SDL_vivanteplatform.h +++ b/src/video/vivante/SDL_vivanteplatform.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/vivante/SDL_vivantevideo.c b/src/video/vivante/SDL_vivantevideo.c index a501f65..bcfa365 100644 --- a/src/video/vivante/SDL_vivantevideo.c +++ b/src/video/vivante/SDL_vivantevideo.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/vivante/SDL_vivantevideo.h b/src/video/vivante/SDL_vivantevideo.h index 03dcb7e..dc1bab0 100644 --- a/src/video/vivante/SDL_vivantevideo.h +++ b/src/video/vivante/SDL_vivantevideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/vivante/SDL_vivantevulkan.c b/src/video/vivante/SDL_vivantevulkan.c index ce1e80c..f53b314 100644 --- a/src/video/vivante/SDL_vivantevulkan.c +++ b/src/video/vivante/SDL_vivantevulkan.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/vivante/SDL_vivantevulkan.h b/src/video/vivante/SDL_vivantevulkan.h index 4fb6964..e176335 100644 --- a/src/video/vivante/SDL_vivantevulkan.h +++ b/src/video/vivante/SDL_vivantevulkan.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/wayland/SDL_waylandclipboard.c b/src/video/wayland/SDL_waylandclipboard.c index fc3d285..38f4549 100644 --- a/src/video/wayland/SDL_waylandclipboard.c +++ b/src/video/wayland/SDL_waylandclipboard.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/wayland/SDL_waylandclipboard.h b/src/video/wayland/SDL_waylandclipboard.h index 012bf82..64c33ab 100644 --- a/src/video/wayland/SDL_waylandclipboard.h +++ b/src/video/wayland/SDL_waylandclipboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/wayland/SDL_waylanddatamanager.c b/src/video/wayland/SDL_waylanddatamanager.c index 8839e23..ed803ad 100644 --- a/src/video/wayland/SDL_waylanddatamanager.c +++ b/src/video/wayland/SDL_waylanddatamanager.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/wayland/SDL_waylanddatamanager.h b/src/video/wayland/SDL_waylanddatamanager.h index 496de21..f48bb82 100644 --- a/src/video/wayland/SDL_waylanddatamanager.h +++ b/src/video/wayland/SDL_waylanddatamanager.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/wayland/SDL_waylanddyn.c b/src/video/wayland/SDL_waylanddyn.c index f7d501a..81f7904 100644 --- a/src/video/wayland/SDL_waylanddyn.c +++ b/src/video/wayland/SDL_waylanddyn.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/wayland/SDL_waylanddyn.h b/src/video/wayland/SDL_waylanddyn.h index 6feb343..e86375a 100644 --- a/src/video/wayland/SDL_waylanddyn.h +++ b/src/video/wayland/SDL_waylanddyn.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c index a838281..2d85f80 100644 --- a/src/video/wayland/SDL_waylandevents.c +++ b/src/video/wayland/SDL_waylandevents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -248,12 +248,25 @@ static SDL_bool keyboard_repeat_key_is_set(SDL_WaylandKeyboardRepeat *repeat_inf return repeat_info->is_initialized && repeat_info->is_key_down && key == repeat_info->key; } +static void sync_done_handler(void *data, struct wl_callback *callback, uint32_t callback_data) +{ + /* Nothing to do, just destroy the callback */ + wl_callback_destroy(callback); +} + +static struct wl_callback_listener sync_listener = { + sync_done_handler +}; + void Wayland_SendWakeupEvent(_THIS, SDL_Window *window) { SDL_VideoData *d = _this->driverdata; - /* TODO: Maybe use a pipe to avoid the compositor roundtrip? */ - wl_display_sync(d->display); + /* Queue a sync event to unblock the event queue fd if it's empty and being waited on. + * TODO: Maybe use a pipe to avoid the compositor roundtrip? + */ + struct wl_callback *cb = wl_display_sync(d->display); + wl_callback_add_listener(cb, &sync_listener, NULL); WAYLAND_wl_display_flush(d->display); } @@ -994,6 +1007,13 @@ static void keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard, return; } + if (input->xkb.keymap != NULL) { + /* if there's already a keymap loaded, throw it away rather than leaking it before + * parsing the new one + */ + WAYLAND_xkb_keymap_unref(input->xkb.keymap); + input->xkb.keymap = NULL; + } input->xkb.keymap = WAYLAND_xkb_keymap_new_from_string(input->display->xkb_context, map_str, XKB_KEYMAP_FORMAT_TEXT_V1, @@ -1016,6 +1036,13 @@ static void keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard, input->xkb.idx_caps = 1 << GET_MOD_INDEX(CAPS); #undef GET_MOD_INDEX + if (input->xkb.state != NULL) { + /* if there's already a state, throw it away rather than leaking it before + * trying to create a new one with the new keymap. + */ + WAYLAND_xkb_state_unref(input->xkb.state); + input->xkb.state = NULL; + } input->xkb.state = WAYLAND_xkb_state_new(input->xkb.keymap); if (!input->xkb.state) { SDL_SetError("failed to create XKB state\n"); @@ -1061,10 +1088,18 @@ static void keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard, } /* Set up XKB compose table */ + if (input->xkb.compose_table != NULL) { + WAYLAND_xkb_compose_table_unref(input->xkb.compose_table); + input->xkb.compose_table = NULL; + } input->xkb.compose_table = WAYLAND_xkb_compose_table_new_from_locale(input->display->xkb_context, locale, XKB_COMPOSE_COMPILE_NO_FLAGS); if (input->xkb.compose_table) { /* Set up XKB compose state */ + if (input->xkb.compose_state != NULL) { + WAYLAND_xkb_compose_state_unref(input->xkb.compose_state); + input->xkb.compose_state = NULL; + } input->xkb.compose_state = WAYLAND_xkb_compose_state_new(input->xkb.compose_table, XKB_COMPOSE_STATE_NO_FLAGS); if (!input->xkb.compose_state) { @@ -1144,7 +1179,8 @@ static void keyboard_handle_enter(void *data, struct wl_keyboard *keyboard, const SDL_Scancode scancode = Wayland_get_scancode_from_key(input, *key + 8); if (scancode != SDL_SCANCODE_UNKNOWN) { - for (uint32_t i = 0; i < SDL_arraysize(mod_scancodes); ++i) { + uint32_t i; + for (i = 0; i < SDL_arraysize(mod_scancodes); ++i) { if (mod_scancodes[i] == scancode) { SDL_SendKeyboardKey(SDL_PRESSED, scancode); break; @@ -1299,6 +1335,12 @@ static void keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard, Wayland_Keymap keymap; const uint32_t modstate = (mods_depressed | mods_latched | mods_locked); + if (input->xkb.state == NULL) { + /* if we get a modifier notification before the keymap, there's nothing we can do with the information + */ + return; + } + WAYLAND_xkb_state_update_mask(input->xkb.state, mods_depressed, mods_latched, mods_locked, 0, 0, group); @@ -1786,7 +1828,8 @@ static void data_device_handle_drop(void *data, struct wl_data_device *wl_data_d char **paths = SDL_DBus_DocumentsPortalRetrieveFiles(buffer, &path_count); /* If dropped files contain a directory the list is empty */ if (paths && path_count > 0) { - for (int i = 0; i < path_count; i++) { + int i; + for (i = 0; i < path_count; i++) { SDL_SendDropFile(data_device->dnd_window, paths[i]); } dbus->free_string_array(paths); @@ -2492,6 +2535,9 @@ void Wayland_display_destroy_input(SDL_VideoData *d) if (input->primary_selection_device->selection_offer) { Wayland_primary_selection_offer_destroy(input->primary_selection_device->selection_offer); } + if (input->primary_selection_device->primary_selection_device) { + zwp_primary_selection_device_v1_destroy(input->primary_selection_device->primary_selection_device); + } SDL_free(input->primary_selection_device); } diff --git a/src/video/wayland/SDL_waylandevents_c.h b/src/video/wayland/SDL_waylandevents_c.h index d69888c..1849b9a 100644 --- a/src/video/wayland/SDL_waylandevents_c.h +++ b/src/video/wayland/SDL_waylandevents_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/wayland/SDL_waylandkeyboard.c b/src/video/wayland/SDL_waylandkeyboard.c index df0f865..486d488 100644 --- a/src/video/wayland/SDL_waylandkeyboard.c +++ b/src/video/wayland/SDL_waylandkeyboard.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/wayland/SDL_waylandkeyboard.h b/src/video/wayland/SDL_waylandkeyboard.h index 6a0fccd..bdc3434 100644 --- a/src/video/wayland/SDL_waylandkeyboard.h +++ b/src/video/wayland/SDL_waylandkeyboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/wayland/SDL_waylandmessagebox.c b/src/video/wayland/SDL_waylandmessagebox.c index 2fea3de..1744dbd 100644 --- a/src/video/wayland/SDL_waylandmessagebox.c +++ b/src/video/wayland/SDL_waylandmessagebox.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/wayland/SDL_waylandmessagebox.h b/src/video/wayland/SDL_waylandmessagebox.h index 2193a6b..87284d2 100644 --- a/src/video/wayland/SDL_waylandmessagebox.h +++ b/src/video/wayland/SDL_waylandmessagebox.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/wayland/SDL_waylandmouse.c b/src/video/wayland/SDL_waylandmouse.c index 4abc654..4852980 100644 --- a/src/video/wayland/SDL_waylandmouse.c +++ b/src/video/wayland/SDL_waylandmouse.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -23,11 +23,12 @@ #ifdef SDL_VIDEO_DRIVER_WAYLAND -#include #include #include #include #include +#include +#include #include "../SDL_sysvideo.h" @@ -58,6 +59,7 @@ typedef struct */ SDL_SystemCursor system_cursor; void *shm_data; + size_t shm_data_size; } Wayland_CursorData; #ifdef SDL_USE_LIBDBUS @@ -156,16 +158,40 @@ static SDL_bool wayland_dbus_read_cursor_theme(char **theme) #endif + +static const char *GetLegacyCursorName(SDL_SystemCursor system_cursor) +{ + switch (system_cursor) { + case SDL_SYSTEM_CURSOR_ARROW: return "left_ptr"; + case SDL_SYSTEM_CURSOR_IBEAM: return "xterm"; + case SDL_SYSTEM_CURSOR_WAIT: return "watch"; + case SDL_SYSTEM_CURSOR_CROSSHAIR: return "tcross"; + case SDL_SYSTEM_CURSOR_WAITARROW: return "watch"; + case SDL_SYSTEM_CURSOR_SIZENWSE: return "top_left_corner"; + case SDL_SYSTEM_CURSOR_SIZENESW: return "top_right_corner"; + case SDL_SYSTEM_CURSOR_SIZEWE: return "sb_h_double_arrow"; + case SDL_SYSTEM_CURSOR_SIZENS: return "sb_v_double_arrow"; + case SDL_SYSTEM_CURSOR_SIZEALL: return "fleur"; + case SDL_SYSTEM_CURSOR_NO: return "pirate"; + case SDL_SYSTEM_CURSOR_HAND: return "hand2"; + case SDL_NUM_SYSTEM_CURSORS: break; /* so the compiler might notice if an enum value is missing here. */ + } + + SDL_assert(0); + return NULL; +} + static SDL_bool wayland_get_system_cursor(SDL_VideoData *vdata, Wayland_CursorData *cdata, float *scale) { struct wl_cursor_theme *theme = NULL; struct wl_cursor *cursor; + const char *cssname = NULL; + const char *fallback_name = NULL; char *xcursor_size; int size = 0; SDL_Window *focus; - SDL_WindowData *focusdata; int i; /* @@ -189,16 +215,17 @@ static SDL_bool wayland_get_system_cursor(SDL_VideoData *vdata, Wayland_CursorDa } /* First, find the appropriate theme based on the current scale... */ focus = SDL_GetMouse()->focus; - if (!focus) { - /* Nothing to see here, bail. */ - return SDL_FALSE; + if (focus) { + SDL_WindowData *focusdata = (SDL_WindowData*)focus->driverdata; + + /* Cursors use integer scaling. */ + *scale = SDL_ceilf(focusdata->scale_factor); + } else { + *scale = 1.0f; } - focusdata = focus->driverdata; - /* Cursors use integer scaling. */ - *scale = SDL_ceilf(focusdata->scale_factor); - size *= *scale; - for (i = 0; i < vdata->num_cursor_themes; i += 1) { + size *= (int)*scale; + for (i = 0; i < vdata->num_cursor_themes; ++i) { if (vdata->cursor_themes[i].size == size) { theme = vdata->cursor_themes[i].theme; break; @@ -231,54 +258,28 @@ static SDL_bool wayland_get_system_cursor(SDL_VideoData *vdata, Wayland_CursorDa } /* Next, find the cursor from the theme... */ - switch (cdata->system_cursor) { - case SDL_SYSTEM_CURSOR_ARROW: - cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "left_ptr"); - break; - case SDL_SYSTEM_CURSOR_IBEAM: - cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "xterm"); - break; - case SDL_SYSTEM_CURSOR_WAIT: - cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "watch"); - break; - case SDL_SYSTEM_CURSOR_CROSSHAIR: - cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "tcross"); - break; - case SDL_SYSTEM_CURSOR_WAITARROW: - cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "watch"); - break; - case SDL_SYSTEM_CURSOR_SIZENWSE: - cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "top_left_corner"); - break; - case SDL_SYSTEM_CURSOR_SIZENESW: - cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "top_right_corner"); - break; - case SDL_SYSTEM_CURSOR_SIZEWE: - cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "sb_h_double_arrow"); - break; - case SDL_SYSTEM_CURSOR_SIZENS: - cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "sb_v_double_arrow"); - break; - case SDL_SYSTEM_CURSOR_SIZEALL: - cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "fleur"); - break; - case SDL_SYSTEM_CURSOR_NO: - cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "pirate"); - break; - case SDL_SYSTEM_CURSOR_HAND: - cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "hand2"); - break; - default: - SDL_assert(0); - return SDL_FALSE; + cssname = SDL_GetCSSCursorName(cdata->system_cursor, &fallback_name); + + cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, cssname); + if (!cursor && fallback_name) { + cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, fallback_name); + } + + /* try the legacy name if the fancy new CSS name doesn't work... */ + if (!cursor) { + cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, GetLegacyCursorName(cdata->system_cursor)); } /* Fallback to the default cursor if the chosen one wasn't found */ + if (!cursor) { + cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "default"); + } + /* Try the old X11 name as a last resort */ if (!cursor) { cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "left_ptr"); - if (!cursor) { - return SDL_FALSE; - } + } + if (!cursor) { + return SDL_FALSE; } /* ... Set the cursor data, finally. */ @@ -290,27 +291,72 @@ static SDL_bool wayland_get_system_cursor(SDL_VideoData *vdata, Wayland_CursorDa return SDL_TRUE; } -static int wayland_create_tmp_file(off_t size) +static int set_tmp_file_size(int fd, off_t size) { - static const char template[] = "/sdl-shared-XXXXXX"; - char *xdg_path; - char tmp_path[PATH_MAX]; - int fd; +#ifdef HAVE_POSIX_FALLOCATE + sigset_t set, old_set; + int ret; - xdg_path = SDL_getenv("XDG_RUNTIME_DIR"); - if (!xdg_path) { - return -1; - } + /* SIGALRM can potentially block a large posix_fallocate() operation + * from succeeding, so block it. + */ + sigemptyset(&set); + sigaddset(&set, SIGALRM); + sigprocmask(SIG_BLOCK, &set, &old_set); + + do { + ret = posix_fallocate(fd, 0, size); + } while (ret == EINTR); - SDL_strlcpy(tmp_path, xdg_path, PATH_MAX); - SDL_strlcat(tmp_path, template, PATH_MAX); + sigprocmask(SIG_SETMASK, &old_set, NULL); - fd = mkostemp(tmp_path, O_CLOEXEC); - if (fd < 0) { + if (ret == 0) { + return 0; + } + else if (ret != EINVAL && errno != EOPNOTSUPP) { return -1; } +#endif if (ftruncate(fd, size) < 0) { + return -1; + } + return 0; +} + +static int wayland_create_tmp_file(off_t size) +{ + int fd; + +#ifdef HAVE_MEMFD_CREATE + fd = memfd_create("SDL", MFD_CLOEXEC | MFD_ALLOW_SEALING); + if (fd >= 0) { + fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_SEAL); + } else +#endif + { + static const char template[] = "/sdl-shared-XXXXXX"; + char *xdg_path; + char tmp_path[PATH_MAX]; + + xdg_path = SDL_getenv("XDG_RUNTIME_DIR"); + if (!xdg_path) { + return -1; + } + + SDL_strlcpy(tmp_path, xdg_path, PATH_MAX); + SDL_strlcat(tmp_path, template, PATH_MAX); + + fd = mkostemp(tmp_path, O_CLOEXEC); + if (fd < 0) { + return -1; + } + + /* Need to manually unlink the temp files, or they can persist after close and fill up the temp storage. */ + unlink(tmp_path); + } + + if (set_tmp_file_size(fd, size) < 0) { close(fd); return -1; } @@ -334,19 +380,18 @@ static int create_buffer_from_shm(Wayland_CursorData *d, SDL_VideoDevice *vd = SDL_GetVideoDevice(); SDL_VideoData *data = (SDL_VideoData *)vd->driverdata; struct wl_shm_pool *shm_pool; + int shm_fd; int stride = width * 4; - int size = stride * height; - - int shm_fd; + d->shm_data_size = stride * height; - shm_fd = wayland_create_tmp_file(size); + shm_fd = wayland_create_tmp_file(d->shm_data_size); if (shm_fd < 0) { return SDL_SetError("Creating mouse cursor buffer failed."); } d->shm_data = mmap(NULL, - size, + d->shm_data_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, @@ -359,7 +404,7 @@ static int create_buffer_from_shm(Wayland_CursorData *d, SDL_assert(d->shm_data != NULL); - shm_pool = wl_shm_create_pool(data->shm, shm_fd, size); + shm_pool = wl_shm_create_pool(data->shm, shm_fd, d->shm_data_size); d->buffer = wl_shm_pool_create_buffer(shm_pool, 0, width, @@ -460,6 +505,7 @@ static void Wayland_FreeCursorData(Wayland_CursorData *d) if (d->buffer) { if (d->shm_data) { wl_buffer_destroy(d->buffer); + munmap(d->shm_data, d->shm_data_size); } d->buffer = NULL; } @@ -483,7 +529,6 @@ static void Wayland_FreeCursor(SDL_Cursor *cursor) Wayland_FreeCursorData((Wayland_CursorData *)cursor->driverdata); - /* Not sure what's meant to happen to shm_data */ SDL_free(cursor->driverdata); SDL_free(cursor); } @@ -550,6 +595,7 @@ static void Wayland_WarpMouse(SDL_Window *window, int x, int y) Wayland_input_lock_pointer(input); input->relative_mode_override = SDL_TRUE; } + SDL_SendMouseMotion(window, 0, 0, x, y); } } diff --git a/src/video/wayland/SDL_waylandmouse.h b/src/video/wayland/SDL_waylandmouse.h index 4f3296d..e5c95a4 100644 --- a/src/video/wayland/SDL_waylandmouse.h +++ b/src/video/wayland/SDL_waylandmouse.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/wayland/SDL_waylandopengles.c b/src/video/wayland/SDL_waylandopengles.c index cf91149..f271ac7 100644 --- a/src/video/wayland/SDL_waylandopengles.c +++ b/src/video/wayland/SDL_waylandopengles.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -120,13 +120,27 @@ int Wayland_GLES_SwapWindow(_THIS, SDL_Window *window) return 0; } + /* By default, we wait for Wayland frame callback and then issue pageflip (eglSwapBuffers), + * but if we want low latency (double buffer scheme), we issue the pageflip + * and then wait immediately for Wayland frame callback. + */ + + if (data->double_buffer) { + /* Feed the frame to Wayland. This will set it so the wl_surface_frame callback can fire again. */ + if (!_this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, data->egl_surface)) { + return SDL_EGL_SetError("unable to show color buffer in an OS-native window", "eglSwapBuffers"); + } + + WAYLAND_wl_display_flush(data->waylandData->display); + } + /* Control swap interval ourselves. See comments on Wayland_GLES_SetSwapInterval */ if (swap_interval != 0) { SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; struct wl_display *display = videodata->display; SDL_VideoDisplay *sdldisplay = SDL_GetDisplayForWindow(window); /* 1/3 speed (or 20hz), so we'll progress even if throttled to zero. */ - const Uint32 max_wait = SDL_GetTicks() + (sdldisplay->current_mode.refresh_rate ? (3000 / sdldisplay->current_mode.refresh_rate) : 50); + const Uint32 max_wait = SDL_GetTicks() + (sdldisplay && sdldisplay->current_mode.refresh_rate ? (3000 / sdldisplay->current_mode.refresh_rate) : 50); while (SDL_AtomicGet(&data->swap_interval_ready) == 0) { Uint32 now; @@ -162,12 +176,14 @@ int Wayland_GLES_SwapWindow(_THIS, SDL_Window *window) SDL_AtomicSet(&data->swap_interval_ready, 0); } - /* Feed the frame to Wayland. This will set it so the wl_surface_frame callback can fire again. */ - if (!_this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, data->egl_surface)) { - return SDL_EGL_SetError("unable to show color buffer in an OS-native window", "eglSwapBuffers"); - } + if (!data->double_buffer) { + /* Feed the frame to Wayland. This will set it so the wl_surface_frame callback can fire again. */ + if (!_this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, data->egl_surface)) { + return SDL_EGL_SetError("unable to show color buffer in an OS-native window", "eglSwapBuffers"); + } - WAYLAND_wl_display_flush(data->waylandData->display); + WAYLAND_wl_display_flush(data->waylandData->display); + } return 0; } diff --git a/src/video/wayland/SDL_waylandopengles.h b/src/video/wayland/SDL_waylandopengles.h index 772a80a..5805918 100644 --- a/src/video/wayland/SDL_waylandopengles.h +++ b/src/video/wayland/SDL_waylandopengles.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/wayland/SDL_waylandsym.h b/src/video/wayland/SDL_waylandsym.h index 1b02b01..8565e70 100644 --- a/src/video/wayland/SDL_waylandsym.h +++ b/src/video/wayland/SDL_waylandsym.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/wayland/SDL_waylandtouch.c b/src/video/wayland/SDL_waylandtouch.c index 7a6b7fc..73a431a 100644 --- a/src/video/wayland/SDL_waylandtouch.c +++ b/src/video/wayland/SDL_waylandtouch.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/wayland/SDL_waylandtouch.h b/src/video/wayland/SDL_waylandtouch.h index ed260ea..5756348 100644 --- a/src/video/wayland/SDL_waylandtouch.h +++ b/src/video/wayland/SDL_waylandtouch.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c index 2cae471..31f01cd 100644 --- a/src/video/wayland/SDL_waylandvideo.c +++ b/src/video/wayland/SDL_waylandvideo.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -78,7 +78,7 @@ static void Wayland_VideoQuit(_THIS); /* Find out what class name we should use * Based on src/video/x11/SDL_x11video.c */ -static char *get_classname() +static char *get_classname(void) { /* !!! FIXME: this is probably wrong, albeit harmless in many common cases. From protocol spec: "The surface class identifies the general class of applications @@ -478,17 +478,8 @@ static void display_handle_geometry(void *data, { SDL_WaylandOutputData *driverdata = data; - SDL_VideoDisplay *display; - int i; if (driverdata->wl_output_done_count) { - /* Clear the wl_output ref so Reset doesn't free it */ - display = SDL_GetDisplay(driverdata->index); - for (i = 0; i < display->num_display_modes; i += 1) { - display->display_modes[i].driverdata = NULL; - } - - /* Okay, now it's safe to reset */ SDL_ResetDisplayModes(driverdata->index); /* The display has officially started over. */ @@ -600,7 +591,6 @@ static void display_handle_done(void *data, native_mode.h = driverdata->native_height; } native_mode.refresh_rate = (int)SDL_round(driverdata->refresh / 1000.0); /* mHz to Hz */ - native_mode.driverdata = driverdata->output; /* The scaled desktop mode */ SDL_zero(desktop_mode); @@ -622,7 +612,6 @@ static void display_handle_done(void *data, desktop_mode.h = driverdata->width; } desktop_mode.refresh_rate = (int)SDL_round(driverdata->refresh / 1000.0); /* mHz to Hz */ - desktop_mode.driverdata = driverdata->output; /* * The native display mode is only exposed separately from the desktop size if the @@ -655,6 +644,11 @@ static void display_handle_done(void *data, if (driverdata->index > -1) { dpy = SDL_GetDisplay(driverdata->index); + + /* XXX: This can never happen, but jump threading during aggressive LTO can generate a warning without this check. */ + if (!dpy) { + dpy = &driverdata->placeholder; + } } else { dpy = &driverdata->placeholder; } @@ -762,12 +756,11 @@ static void Wayland_free_display(SDL_VideoData *d, uint32_t id) } } } - SDL_DelVideoDisplay(i); if (data->xdg_output) { zxdg_output_v1_destroy(data->xdg_output); } wl_output_destroy(data->output); - SDL_free(data); + SDL_DelVideoDisplay(i); /* Update the index for all remaining displays */ num_displays -= 1; @@ -1014,7 +1007,7 @@ static int Wayland_GetDisplayDPI(_THIS, SDL_VideoDisplay *sdl_display, float *dd static void Wayland_VideoCleanup(_THIS) { SDL_VideoData *data = _this->driverdata; - int i, j; + int i; Wayland_QuitWin(data); Wayland_FiniMouse(data); @@ -1027,13 +1020,6 @@ static void Wayland_VideoCleanup(_THIS) } wl_output_destroy(((SDL_WaylandOutputData *)display->driverdata)->output); - SDL_free(display->driverdata); - display->driverdata = NULL; - - for (j = display->num_display_modes; j--;) { - display->display_modes[j].driverdata = NULL; - } - display->desktop_mode.driverdata = NULL; SDL_DelVideoDisplay(i); } data->output_list = NULL; diff --git a/src/video/wayland/SDL_waylandvideo.h b/src/video/wayland/SDL_waylandvideo.h index b7b3348..f4247d1 100644 --- a/src/video/wayland/SDL_waylandvideo.h +++ b/src/video/wayland/SDL_waylandvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/wayland/SDL_waylandvulkan.c b/src/video/wayland/SDL_waylandvulkan.c index af956da..0c39d1b 100644 --- a/src/video/wayland/SDL_waylandvulkan.c +++ b/src/video/wayland/SDL_waylandvulkan.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/wayland/SDL_waylandvulkan.h b/src/video/wayland/SDL_waylandvulkan.h index f42ed8e..9e0a0d0 100644 --- a/src/video/wayland/SDL_waylandvulkan.h +++ b/src/video/wayland/SDL_waylandvulkan.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c index 08df363..d1acdd1 100644 --- a/src/video/wayland/SDL_waylandwindow.c +++ b/src/video/wayland/SDL_waylandwindow.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -118,47 +118,12 @@ static void GetFullScreenDimensions(SDL_Window *window, int *width, int *height, } } -SDL_FORCE_INLINE SDL_bool SurfaceScaleIsFractional(SDL_Window *window) -{ - SDL_WindowData *data = window->driverdata; - return !FloatEqual(SDL_roundf(data->scale_factor), data->scale_factor); -} - SDL_FORCE_INLINE SDL_bool FullscreenModeEmulation(SDL_Window *window) { return (window->flags & SDL_WINDOW_FULLSCREEN) && ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP); } -static SDL_bool NeedViewport(SDL_Window *window) -{ - SDL_WindowData *wind = window->driverdata; - SDL_VideoData *video = wind->waylandData; - 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; - - /* - * A viewport is only required when scaling is enabled and: - * - A fullscreen mode is being emulated and the mode does not match the logical desktop dimensions. - * - The desktop uses fractional scaling and the high-DPI flag is set. - */ - if (video->viewporter) { - if (FullscreenModeEmulation(window)) { - GetFullScreenDimensions(window, &fs_width, &fs_height, NULL, NULL); - if (fs_width != output_width || fs_height != output_height) { - return SDL_TRUE; - } - } else if (SurfaceScaleIsFractional(window) && (window->flags & SDL_WINDOW_ALLOW_HIGHDPI)) { - return SDL_TRUE; - } - } - - return SDL_FALSE; -} - static void GetBufferSize(SDL_Window *window, int *width, int *height) { SDL_WindowData *data = window->driverdata; @@ -167,15 +132,12 @@ static void GetBufferSize(SDL_Window *window, int *width, int *height) if (FullscreenModeEmulation(window)) { GetFullScreenDimensions(window, NULL, NULL, &buf_width, &buf_height); - } else if (NeedViewport(window)) { + } else if (data->draw_viewport) { /* Round fractional backbuffer sizes halfway away from zero. */ buf_width = (int)SDL_lroundf(window->w * data->scale_factor); buf_height = (int)SDL_lroundf(window->h * data->scale_factor); } else { - /* - * Integer scaled windowed or fullscreen with no viewport - * - * Round the scale factor up in the unlikely scenario of a compositor + /* Round the scale factor up in the unlikely scenario of a compositor * that supports fractional scaling, but not viewports. */ int scale_factor = (int)SDL_ceilf(data->scale_factor); @@ -192,31 +154,6 @@ static void GetBufferSize(SDL_Window *window, int *width, int *height) } } -static void SetDrawSurfaceViewport(SDL_Window *window, int src_width, int src_height, int dst_width, int dst_height) -{ - SDL_WindowData *wind = window->driverdata; - SDL_VideoData *video = wind->waylandData; - - if (video->viewporter) { - if (!wind->draw_viewport) { - wind->draw_viewport = wp_viewporter_get_viewport(video->viewporter, wind->surface); - } - - wp_viewport_set_source(wind->draw_viewport, wl_fixed_from_int(0), wl_fixed_from_int(0), wl_fixed_from_int(src_width), wl_fixed_from_int(src_height)); - wp_viewport_set_destination(wind->draw_viewport, dst_width, dst_height); - } -} - -static void UnsetDrawSurfaceViewport(SDL_Window *window) -{ - SDL_WindowData *wind = window->driverdata; - - if (wind->draw_viewport) { - wp_viewport_destroy(wind->draw_viewport); - wind->draw_viewport = NULL; - } -} - static void ConfigureWindowGeometry(SDL_Window *window) { SDL_WindowData *data = window->driverdata; @@ -240,7 +177,7 @@ static void ConfigureWindowGeometry(SDL_Window *window) 0, 0); } - if (FullscreenModeEmulation(window) && NeedViewport(window)) { + if (FullscreenModeEmulation(window) && data->draw_viewport) { int fs_width, fs_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); @@ -252,8 +189,7 @@ static void ConfigureWindowGeometry(SDL_Window *window) /* Set the buffer scale to 1 since a viewport will be used. */ wl_surface_set_buffer_scale(data->surface, 1); - SetDrawSurfaceViewport(window, data->drawable_width, data->drawable_height, - output_width, output_height); + wp_viewport_set_destination(data->draw_viewport, output_width, output_height); data->window_width = output_width; data->window_height = output_height; @@ -265,12 +201,10 @@ static void ConfigureWindowGeometry(SDL_Window *window) window_size_changed = data->window_width != window->w || data->window_height != window->h; if (window_size_changed || drawable_size_changed) { - if (NeedViewport(window)) { + if (data->draw_viewport) { wl_surface_set_buffer_scale(data->surface, 1); - SetDrawSurfaceViewport(window, data->drawable_width, data->drawable_height, window->w, window->h); + wp_viewport_set_destination(data->draw_viewport, window->w, window->h); } else { - UnsetDrawSurfaceViewport(window); - if (!FullscreenModeEmulation(window)) { /* Round to the next integer in case of a fractional value. */ wl_surface_set_buffer_scale(data->surface, (int32_t)SDL_ceilf(data->scale_factor)); @@ -293,8 +227,11 @@ static void ConfigureWindowGeometry(SDL_Window *window) * need to be recalculated if the output size has changed. */ if (window_size_changed) { - /* libdecor does this internally on frame commits, so it's only needed for xdg surfaces. */ - if (data->shell_surface_type != WAYLAND_SURFACE_LIBDECOR && + /* XXX: This is a hack and only set on the xdg-toplevel path when viewports + * aren't supported to avoid a potential protocol violation if a buffer + * with an old size is committed. + */ + if (!data->draw_viewport && data->shell_surface_type == WAYLAND_SURFACE_XDG_TOPLEVEL && viddata->shell.xdg && data->shell_surface.xdg.surface) { xdg_surface_set_window_geometry(data->shell_surface.xdg.surface, 0, 0, data->window_width, data->window_height); } @@ -1373,6 +1310,8 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window) 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); + + SetMinMaxDimensions(window, SDL_FALSE); } } @@ -1418,9 +1357,6 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window) &decoration_listener, window); } - - /* Set the geometry */ - xdg_surface_set_window_geometry(data->shell_surface.xdg.surface, 0, 0, data->window_width, data->window_height); } else { /* Nothing to see here, just commit. */ wl_surface_commit(data->surface); @@ -1479,6 +1415,9 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window) * HideWindow was called immediately before ShowWindow. */ WAYLAND_wl_display_roundtrip(c->display); + + /* Send an exposure event to signal that the client should draw. */ + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_EXPOSED, 0, 0); } static void Wayland_ReleasePopup(_THIS, SDL_Window *popup) @@ -2014,6 +1953,11 @@ int Wayland_CreateWindow(_THIS, SDL_Window *window) } } + data->double_buffer = SDL_FALSE; + if (SDL_GetHintBoolean(SDL_HINT_VIDEO_DOUBLE_BUFFER, SDL_FALSE)) { + data->double_buffer = SDL_TRUE; + } + data->outputs = NULL; data->num_outputs = 0; @@ -2026,6 +1970,13 @@ int Wayland_CreateWindow(_THIS, SDL_Window *window) SDL_WAYLAND_register_surface(data->surface); + if (c->viewporter) { + data->draw_viewport = wp_viewporter_get_viewport(c->viewporter, data->surface); + wp_viewport_set_source(data->draw_viewport, + wl_fixed_from_int(-1), wl_fixed_from_int(-1), + wl_fixed_from_int(-1), wl_fixed_from_int(-1)); + } + /* Must be called before EGL configuration to set the drawable backbuffer size. */ ConfigureWindowGeometry(window); @@ -2133,6 +2084,7 @@ static void Wayland_HandleResize(SDL_Window *window, int width, int height, floa window->w = 0; window->h = 0; SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, width, height); + SDL_SendWindowEvent(window, SDL_WINDOWEVENT_EXPOSED, 0, 0); window->w = width; window->h = height; data->needs_resize_event = SDL_FALSE; diff --git a/src/video/wayland/SDL_waylandwindow.h b/src/video/wayland/SDL_waylandwindow.h index 36600a4..1ae0efd 100644 --- a/src/video/wayland/SDL_waylandwindow.h +++ b/src/video/wayland/SDL_waylandwindow.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -116,6 +116,7 @@ typedef struct SDL_bool is_fullscreen; SDL_bool in_fullscreen_transition; Uint32 fullscreen_flags; + SDL_bool double_buffer; } SDL_WindowData; extern void Wayland_ShowWindow(_THIS, SDL_Window *window); diff --git a/src/video/windows/SDL_msctf.h b/src/video/windows/SDL_msctf.h index 738696f..fbe0272 100644 --- a/src/video/windows/SDL_msctf.h +++ b/src/video/windows/SDL_msctf.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/windows/SDL_vkeys.h b/src/video/windows/SDL_vkeys.h index fb4d27d..2aaa9ef 100644 --- a/src/video/windows/SDL_vkeys.h +++ b/src/video/windows/SDL_vkeys.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/windows/SDL_windowsclipboard.c b/src/video/windows/SDL_windowsclipboard.c index 24bc5ab..29593d3 100644 --- a/src/video/windows/SDL_windowsclipboard.c +++ b/src/video/windows/SDL_windowsclipboard.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/windows/SDL_windowsclipboard.h b/src/video/windows/SDL_windowsclipboard.h index 3db9bb9..66b3ae7 100644 --- a/src/video/windows/SDL_windowsclipboard.h +++ b/src/video/windows/SDL_windowsclipboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c index ca1b9bb..6f77ff7 100644 --- a/src/video/windows/SDL_windowsevents.c +++ b/src/video/windows/SDL_windowsevents.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -128,6 +128,10 @@ static SDL_Scancode VKeytoScancodeFallback(WPARAM vkey) return SDL_SCANCODE_RIGHT; case VK_DOWN: return SDL_SCANCODE_DOWN; + case VK_CONTROL: + return SDL_SCANCODE_LCTRL; + case VK_V: + return SDL_SCANCODE_V; default: return SDL_SCANCODE_UNKNOWN; @@ -137,6 +141,11 @@ static SDL_Scancode VKeytoScancodeFallback(WPARAM vkey) static SDL_Scancode VKeytoScancode(WPARAM vkey) { switch (vkey) { + case VK_BACK: + return SDL_SCANCODE_BACKSPACE; + case VK_CAPITAL: + return SDL_SCANCODE_CAPSLOCK; + case VK_MODECHANGE: return SDL_SCANCODE_MODE; case VK_SELECT: @@ -318,7 +327,7 @@ static SDL_Scancode WindowsScanCodeToSDLScanCode(LPARAM lParam, WPARAM wParam) } #if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) -static SDL_bool WIN_ShouldIgnoreFocusClick() +static SDL_bool WIN_ShouldIgnoreFocusClick(void) { return !SDL_GetHintBoolean(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, SDL_FALSE); } @@ -629,6 +638,10 @@ WIN_KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam) if (nCode < 0 || nCode != HC_ACTION) { return CallNextHookEx(NULL, nCode, wParam, lParam); } + if (hookData->scanCode == 0x21d) { + // Skip fake LCtrl when RAlt is pressed + return 1; + } switch (hookData->vkCode) { case VK_LWIN: @@ -683,6 +696,39 @@ WIN_KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam) #endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/ + +// Return 1 if spruious LCtrl is pressed +// LCtrl is sent when RAltGR is pressed +int skip_bad_lcrtl(WPARAM wParam, LPARAM lParam) +{ + MSG next_msg; + DWORD msg_time; + if (wParam != VK_CONTROL) { + return 0; + } + // Is this an extended key (i.e. right key)? + if (lParam & 0x01000000) + return 0; + + // Here is a trick: "Alt Gr" sends LCTRL, then RALT. We only + // want the RALT message, so we try to see if the next message + // is a RALT message. In that case, this is a false LCTRL! + msg_time = GetMessageTime(); + if (PeekMessage(&next_msg, NULL, 0, 0, PM_NOREMOVE)) { + if (next_msg.message == WM_KEYDOWN || + next_msg.message == WM_SYSKEYDOWN) { + if (next_msg.wParam == VK_MENU && + (next_msg.lParam & 0x01000000) && + next_msg.time == msg_time) { + // Next message is a RALT down message, which + // means that this is NOT a proper LCTRL message! + return 1; + } + } + } + return 0; +} + LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { @@ -1000,6 +1046,11 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) SDL_Scancode code = WindowsScanCodeToSDLScanCode(lParam, wParam); const Uint8 *keyboardState = SDL_GetKeyboardState(NULL); + if (skip_bad_lcrtl(wParam, lParam)) { + returnCode = 0; + break; + } + /* Detect relevant keyboard shortcuts */ if (keyboardState[SDL_SCANCODE_LALT] == SDL_PRESSED || keyboardState[SDL_SCANCODE_RALT] == SDL_PRESSED) { /* ALT+F4: Close window */ @@ -1022,6 +1073,11 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) SDL_Scancode code = WindowsScanCodeToSDLScanCode(lParam, wParam); const Uint8 *keyboardState = SDL_GetKeyboardState(NULL); + if (skip_bad_lcrtl(wParam, lParam)) { + returnCode = 0; + break; + } + if (code != SDL_SCANCODE_UNKNOWN) { if (code == SDL_SCANCODE_PRINTSCREEN && keyboardState[code] == SDL_RELEASED) { @@ -1274,8 +1330,7 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) case WM_TIMER: { if (wParam == (UINT_PTR)&s_ModalMoveResizeLoop) { - // Send an expose event so the application can redraw - SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_EXPOSED, 0, 0); + SDL_OnWindowLiveResizeUpdate(data->window); return 0; } } break; @@ -1738,7 +1793,7 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) } #if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) -static void WIN_UpdateClipCursorForWindows() +static void WIN_UpdateClipCursorForWindows(void) { SDL_VideoDevice *_this = SDL_GetVideoDevice(); SDL_Window *window; @@ -1760,7 +1815,7 @@ static void WIN_UpdateClipCursorForWindows() } } -static void WIN_UpdateMouseCapture() +static void WIN_UpdateMouseCapture(void) { SDL_Window *focusWindow = SDL_GetKeyboardFocus(); @@ -1803,11 +1858,44 @@ void SDL_SetWindowsMessageHook(SDL_WindowsMessageHook callback, void *userdata) int WIN_WaitEventTimeout(_THIS, int timeout) { if (g_WindowsEnableMessageLoop) { - if (MsgWaitForMultipleObjects(0, NULL, FALSE, (DWORD)timeout, QS_ALLINPUT)) { +#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) + DWORD dwMilliseconds, ret; + dwMilliseconds = timeout < 0 ? INFINITE : (DWORD)timeout; + ret = MsgWaitForMultipleObjects(0, NULL, FALSE, dwMilliseconds, QS_ALLINPUT); + if (ret == WAIT_OBJECT_0) { + return 1; + } else { + return 0; + } +#else + /* MsgWaitForMultipleObjects is desktop-only. */ + MSG msg; + BOOL message_result; + UINT_PTR timer_id = 0; + if (timeout > 0) { + timer_id = SetTimer(NULL, 0, timeout, NULL); + message_result = GetMessage(&msg, 0, 0, 0); + KillTimer(NULL, timer_id); + } else if (timeout == 0) { + message_result = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); + } else { + message_result = GetMessage(&msg, 0, 0, 0); + } + if (message_result) { + if (msg.message == WM_TIMER && !msg.hwnd && msg.wParam == timer_id) { + return 0; + } + if (g_WindowsMessageHook) { + g_WindowsMessageHook(g_WindowsMessageHookData, msg.hwnd, msg.message, msg.wParam, msg.lParam); + } + /* Always translate the message in case it's a non-SDL window (e.g. with Qt integration) */ + TranslateMessage(&msg); + DispatchMessage(&msg); return 1; } else { return 0; } +#endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/ } else { /* Fail the wait so the caller falls back to polling */ return -1; @@ -1924,13 +2012,26 @@ static void WIN_CleanRegisterApp(WNDCLASSEX wcex) SDL_Appname = NULL; } +static BOOL CALLBACK WIN_ResourceNameCallback(HMODULE hModule, LPCTSTR lpType, LPTSTR lpName, LONG_PTR lParam) +{ + WNDCLASSEX *wcex = (WNDCLASSEX *)lParam; + + (void)lpType; /* We already know that the resource type is RT_GROUP_ICON. */ + + /* We leave hIconSm as NULL as it will allow Windows to automatically + choose the appropriate small icon size to suit the current DPI. */ + wcex->hIcon = LoadIcon(hModule, lpName); + + /* Do not bother enumerating any more. */ + return FALSE; +} + /* Register the class for this application */ int SDL_RegisterApp(const char *name, Uint32 style, void *hInst) { WNDCLASSEX wcex; #if !defined(__XBOXONE__) && !defined(__XBOXSERIES__) const char *hint; - TCHAR path[MAX_PATH]; #endif /* Only do this once... */ @@ -1973,9 +2074,8 @@ int SDL_RegisterApp(const char *name, Uint32 style, void *hInst) wcex.hIconSm = LoadIcon(SDL_Instance, MAKEINTRESOURCE(SDL_atoi(hint))); } } else { - /* Use the first icon as a default icon, like in the Explorer */ - GetModuleFileName(SDL_Instance, path, MAX_PATH); - ExtractIconEx(path, 0, &wcex.hIcon, &wcex.hIconSm, 1); + /* Use the first icon as a default icon, like in the Explorer. */ + EnumResourceNames(SDL_Instance, RT_GROUP_ICON, WIN_ResourceNameCallback, (LONG_PTR)&wcex); } #endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/ @@ -1989,7 +2089,7 @@ int SDL_RegisterApp(const char *name, Uint32 style, void *hInst) } /* Unregisters the windowclass registered in SDL_RegisterApp above. */ -void SDL_UnregisterApp() +void SDL_UnregisterApp(void) { WNDCLASSEX wcex; diff --git a/src/video/windows/SDL_windowsevents.h b/src/video/windows/SDL_windowsevents.h index 3e337d0..7e1e5b1 100644 --- a/src/video/windows/SDL_windowsevents.h +++ b/src/video/windows/SDL_windowsevents.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/windows/SDL_windowsframebuffer.c b/src/video/windows/SDL_windowsframebuffer.c index 4234622..8160e3e 100644 --- a/src/video/windows/SDL_windowsframebuffer.c +++ b/src/video/windows/SDL_windowsframebuffer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/windows/SDL_windowsframebuffer.h b/src/video/windows/SDL_windowsframebuffer.h index adcac8a..f48d97e 100644 --- a/src/video/windows/SDL_windowsframebuffer.h +++ b/src/video/windows/SDL_windowsframebuffer.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/windows/SDL_windowskeyboard.c b/src/video/windows/SDL_windowskeyboard.c index c325242..12f84a3 100644 --- a/src/video/windows/SDL_windowskeyboard.c +++ b/src/video/windows/SDL_windowskeyboard.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -166,7 +166,7 @@ void WIN_QuitKeyboard(_THIS) #endif /* !SDL_DISABLE_WINDOWS_IME */ } -void WIN_ResetDeadKeys() +void WIN_ResetDeadKeys(void) { /* if a deadkey has been typed, but not the next character (which the deadkey might modify), @@ -367,7 +367,7 @@ static void UILess_ReleaseSinks(SDL_VideoData *videodata); static void UILess_EnableUIUpdates(SDL_VideoData *videodata); static void UILess_DisableUIUpdates(SDL_VideoData *videodata); -static SDL_bool WIN_ShouldShowNativeUI() +static SDL_bool WIN_ShouldShowNativeUI(void) { return SDL_GetHintBoolean(SDL_HINT_IME_SHOW_UI, SDL_FALSE); } @@ -1321,9 +1321,9 @@ STDMETHODIMP IPPASink_QueryInterface(TSFSink *sink, REFIID riid, PVOID *ppv) STDMETHODIMP IPPASink_OnActivated(TSFSink *sink, DWORD dwProfileType, LANGID langid, REFCLSID clsid, REFGUID catid, REFGUID guidProfile, HKL hkl, DWORD dwFlags) { - static const GUID TF_PROFILE_DAYI = { 0x037B2C25, 0x480C, 0x4D7F, { 0xB0, 0x27, 0xD6, 0xCA, 0x6B, 0x69, 0x78, 0x8A } }; + static const GUID SDL_TF_PROFILE_DAYI = { 0x037B2C25, 0x480C, 0x4D7F, { 0xB0, 0x27, 0xD6, 0xCA, 0x6B, 0x69, 0x78, 0x8A } }; SDL_VideoData *videodata = (SDL_VideoData *)sink->data; - videodata->ime_candlistindexbase = WIN_IsEqualGUID(&TF_PROFILE_DAYI, guidProfile) ? 0 : 1; + videodata->ime_candlistindexbase = WIN_IsEqualGUID(&SDL_TF_PROFILE_DAYI, guidProfile) ? 0 : 1; if (WIN_IsEqualIID(catid, &GUID_TFCAT_TIP_KEYBOARD) && (dwFlags & TF_IPSINK_FLAG_ACTIVE)) { IME_InputLangChanged((SDL_VideoData *)sink->data); } diff --git a/src/video/windows/SDL_windowskeyboard.h b/src/video/windows/SDL_windowskeyboard.h index 3eb2398..5471691 100644 --- a/src/video/windows/SDL_windowskeyboard.h +++ b/src/video/windows/SDL_windowskeyboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/windows/SDL_windowsmessagebox.c b/src/video/windows/SDL_windowsmessagebox.c index f90e0d2..7f27022 100644 --- a/src/video/windows/SDL_windowsmessagebox.c +++ b/src/video/windows/SDL_windowsmessagebox.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/windows/SDL_windowsmessagebox.h b/src/video/windows/SDL_windowsmessagebox.h index 5cddc87..fe0b16e 100644 --- a/src/video/windows/SDL_windowsmessagebox.h +++ b/src/video/windows/SDL_windowsmessagebox.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/windows/SDL_windowsmodes.c b/src/video/windows/SDL_windowsmodes.c index 9a37a11..0c4334f 100644 --- a/src/video/windows/SDL_windowsmodes.c +++ b/src/video/windows/SDL_windowsmodes.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -377,11 +377,10 @@ static void WIN_AddDisplay(_THIS, HMONITOR hMonitor, const MONITORINFOEXW *info, display.driverdata = displaydata; WIN_GetDisplayBounds(_this, &display, &displaydata->bounds); index = SDL_AddVideoDisplay(&display, send_event); - SDL_assert(index == *display_index); SDL_free(display.name); done: - *display_index += 1; + *display_index = index + 1; } typedef struct _WIN_AddDisplaysData diff --git a/src/video/windows/SDL_windowsmodes.h b/src/video/windows/SDL_windowsmodes.h index 9cec89e..a0c7724 100644 --- a/src/video/windows/SDL_windowsmodes.h +++ b/src/video/windows/SDL_windowsmodes.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/windows/SDL_windowsmouse.c b/src/video/windows/SDL_windowsmouse.c index 214197b..a713670 100644 --- a/src/video/windows/SDL_windowsmouse.c +++ b/src/video/windows/SDL_windowsmouse.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -474,7 +474,7 @@ static void WIN_SetLinearMouseScale(int mouse_speed) } } -void WIN_UpdateMouseSystemScale() +void WIN_UpdateMouseSystemScale(void) { int mouse_speed; int params[3] = { 0, 0, 0 }; diff --git a/src/video/windows/SDL_windowsmouse.h b/src/video/windows/SDL_windowsmouse.h index 25f510e..4fa51ff 100644 --- a/src/video/windows/SDL_windowsmouse.h +++ b/src/video/windows/SDL_windowsmouse.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/windows/SDL_windowsopengl.c b/src/video/windows/SDL_windowsopengl.c index 803b6a0..58d0dd7 100644 --- a/src/video/windows/SDL_windowsopengl.c +++ b/src/video/windows/SDL_windowsopengl.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -549,11 +549,11 @@ static int WIN_GL_ChoosePixelFormatARB(_THIS, int *iAttribs, float *fAttribs) _this->gl_data->wglChoosePixelFormatARB(hdc, iAttribs, fAttribs, 1, &pixel_format, &matching); - } - /* Check whether we actually got an SRGB capable buffer */ - _this->gl_data->wglGetPixelFormatAttribivARB(hdc, pixel_format, 0, 1, &qAttrib, &srgb); - _this->gl_config.framebuffer_srgb_capable = srgb; + /* Check whether we actually got an SRGB capable buffer */ + _this->gl_data->wglGetPixelFormatAttribivARB(hdc, pixel_format, 0, 1, &qAttrib, &srgb); + _this->gl_config.framebuffer_srgb_capable = srgb; + } _this->gl_data->wglMakeCurrent(hdc, NULL); _this->gl_data->wglDeleteContext(hglrc); @@ -642,6 +642,7 @@ static int WIN_GL_SetupWindowInternal(_THIS, SDL_Window *window) } if (_this->gl_config.floatbuffers) { + *iAttr++ = WGL_PIXEL_TYPE_ARB; *iAttr++ = WGL_TYPE_RGBA_FLOAT_ARB; } diff --git a/src/video/windows/SDL_windowsopengl.h b/src/video/windows/SDL_windowsopengl.h index 184a313..1fabe21 100644 --- a/src/video/windows/SDL_windowsopengl.h +++ b/src/video/windows/SDL_windowsopengl.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/windows/SDL_windowsopengles.c b/src/video/windows/SDL_windowsopengles.c index 1450d50..50e63fd 100644 --- a/src/video/windows/SDL_windowsopengles.c +++ b/src/video/windows/SDL_windowsopengles.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/windows/SDL_windowsopengles.h b/src/video/windows/SDL_windowsopengles.h index f7844b4..fb85da6 100644 --- a/src/video/windows/SDL_windowsopengles.h +++ b/src/video/windows/SDL_windowsopengles.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/windows/SDL_windowsshape.c b/src/video/windows/SDL_windowsshape.c index fdeb1cd..1c0bc4e 100644 --- a/src/video/windows/SDL_windowsshape.c +++ b/src/video/windows/SDL_windowsshape.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/windows/SDL_windowsshape.h b/src/video/windows/SDL_windowsshape.h index e1ce96a..3e5f300 100644 --- a/src/video/windows/SDL_windowsshape.h +++ b/src/video/windows/SDL_windowsshape.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/windows/SDL_windowsvideo.c b/src/video/windows/SDL_windowsvideo.c index 5f1902a..7f60dc4 100644 --- a/src/video/windows/SDL_windowsvideo.c +++ b/src/video/windows/SDL_windowsvideo.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/windows/SDL_windowsvideo.h b/src/video/windows/SDL_windowsvideo.h index 93ca1cb..617f116 100644 --- a/src/video/windows/SDL_windowsvideo.h +++ b/src/video/windows/SDL_windowsvideo.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/windows/SDL_windowsvulkan.c b/src/video/windows/SDL_windowsvulkan.c index 01ab8a5..9e985ca 100644 --- a/src/video/windows/SDL_windowsvulkan.c +++ b/src/video/windows/SDL_windowsvulkan.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/windows/SDL_windowsvulkan.h b/src/video/windows/SDL_windowsvulkan.h index 1545dcd..1e0e41b 100644 --- a/src/video/windows/SDL_windowsvulkan.h +++ b/src/video/windows/SDL_windowsvulkan.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/windows/SDL_windowswindow.c b/src/video/windows/SDL_windowswindow.c index cf49fbf..93470f3 100644 --- a/src/video/windows/SDL_windowswindow.c +++ b/src/video/windows/SDL_windowswindow.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/windows/SDL_windowswindow.h b/src/video/windows/SDL_windowswindow.h index 20f78b9..0134adc 100644 --- a/src/video/windows/SDL_windowswindow.h +++ b/src/video/windows/SDL_windowswindow.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/windows/wmmsg.h b/src/video/windows/wmmsg.h index 86e6c2a..24603be 100644 --- a/src/video/windows/wmmsg.h +++ b/src/video/windows/wmmsg.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/winrt/SDL_winrtevents.cpp b/src/video/winrt/SDL_winrtevents.cpp index 79468f7..6e72da3 100644 --- a/src/video/winrt/SDL_winrtevents.cpp +++ b/src/video/winrt/SDL_winrtevents.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/winrt/SDL_winrtevents_c.h b/src/video/winrt/SDL_winrtevents_c.h index d08cf9a..6030b92 100644 --- a/src/video/winrt/SDL_winrtevents_c.h +++ b/src/video/winrt/SDL_winrtevents_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/winrt/SDL_winrtgamebar.cpp b/src/video/winrt/SDL_winrtgamebar.cpp index e56def1..3cfc7e8 100644 --- a/src/video/winrt/SDL_winrtgamebar.cpp +++ b/src/video/winrt/SDL_winrtgamebar.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/winrt/SDL_winrtgamebar_cpp.h b/src/video/winrt/SDL_winrtgamebar_cpp.h index 7e3f5d9..43a9bf3 100644 --- a/src/video/winrt/SDL_winrtgamebar_cpp.h +++ b/src/video/winrt/SDL_winrtgamebar_cpp.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/winrt/SDL_winrtkeyboard.cpp b/src/video/winrt/SDL_winrtkeyboard.cpp index 26a1902..da2d09d 100644 --- a/src/video/winrt/SDL_winrtkeyboard.cpp +++ b/src/video/winrt/SDL_winrtkeyboard.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/winrt/SDL_winrtmessagebox.cpp b/src/video/winrt/SDL_winrtmessagebox.cpp index a2d66a3..7ef5478 100644 --- a/src/video/winrt/SDL_winrtmessagebox.cpp +++ b/src/video/winrt/SDL_winrtmessagebox.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/winrt/SDL_winrtmessagebox.h b/src/video/winrt/SDL_winrtmessagebox.h index ab02d3a..6ff3d3f 100644 --- a/src/video/winrt/SDL_winrtmessagebox.h +++ b/src/video/winrt/SDL_winrtmessagebox.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/winrt/SDL_winrtmouse.cpp b/src/video/winrt/SDL_winrtmouse.cpp index e46687f..49da531 100644 --- a/src/video/winrt/SDL_winrtmouse.cpp +++ b/src/video/winrt/SDL_winrtmouse.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/winrt/SDL_winrtmouse_c.h b/src/video/winrt/SDL_winrtmouse_c.h index 2271a14..cdeb578 100644 --- a/src/video/winrt/SDL_winrtmouse_c.h +++ b/src/video/winrt/SDL_winrtmouse_c.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/winrt/SDL_winrtopengles.cpp b/src/video/winrt/SDL_winrtopengles.cpp index cf70241..5fa15c4 100644 --- a/src/video/winrt/SDL_winrtopengles.cpp +++ b/src/video/winrt/SDL_winrtopengles.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/winrt/SDL_winrtopengles.h b/src/video/winrt/SDL_winrtopengles.h index c48a2df..29b919b 100644 --- a/src/video/winrt/SDL_winrtopengles.h +++ b/src/video/winrt/SDL_winrtopengles.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/winrt/SDL_winrtpointerinput.cpp b/src/video/winrt/SDL_winrtpointerinput.cpp index 63c2c86..8f1264c 100644 --- a/src/video/winrt/SDL_winrtpointerinput.cpp +++ b/src/video/winrt/SDL_winrtpointerinput.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/winrt/SDL_winrtvideo.cpp b/src/video/winrt/SDL_winrtvideo.cpp index 9160bbb..e7bdadb 100644 --- a/src/video/winrt/SDL_winrtvideo.cpp +++ b/src/video/winrt/SDL_winrtvideo.cpp @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/winrt/SDL_winrtvideo_cpp.h b/src/video/winrt/SDL_winrtvideo_cpp.h index a60b3aa..2928ee8 100644 --- a/src/video/winrt/SDL_winrtvideo_cpp.h +++ b/src/video/winrt/SDL_winrtvideo_cpp.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/x11/SDL_x11clipboard.c b/src/video/x11/SDL_x11clipboard.c index cf826a5..f9c0a43 100644 --- a/src/video/x11/SDL_x11clipboard.c +++ b/src/video/x11/SDL_x11clipboard.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/x11/SDL_x11clipboard.h b/src/video/x11/SDL_x11clipboard.h index c9849b7..cb010a3 100644 --- a/src/video/x11/SDL_x11clipboard.h +++ b/src/video/x11/SDL_x11clipboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/x11/SDL_x11dyn.c b/src/video/x11/SDL_x11dyn.c index 7a4f5cc..a940bea 100644 --- a/src/video/x11/SDL_x11dyn.c +++ b/src/video/x11/SDL_x11dyn.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/x11/SDL_x11dyn.h b/src/video/x11/SDL_x11dyn.h index 5a78ad0..34a0a90 100644 --- a/src/video/x11/SDL_x11dyn.h +++ b/src/video/x11/SDL_x11dyn.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c index 21b66ff..60c87a2 100644 --- a/src/video/x11/SDL_x11events.c +++ b/src/video/x11/SDL_x11events.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -676,9 +676,10 @@ static void X11_HandleClipboardEvent(_THIS, const XEvent *xevent) &overflow, &seln_data) == Success) { if (seln_format != None) { X11_XChangeProperty(display, req->requestor, req->property, - sevent.xselection.target, seln_format, PropModeReplace, + req->target, 8, PropModeReplace, seln_data, nbytes); sevent.xselection.property = req->property; + sevent.xselection.target = req->target; X11_XFree(seln_data); break; } else { diff --git a/src/video/x11/SDL_x11events.h b/src/video/x11/SDL_x11events.h index cec823c..c9534f1 100644 --- a/src/video/x11/SDL_x11events.h +++ b/src/video/x11/SDL_x11events.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/x11/SDL_x11framebuffer.c b/src/video/x11/SDL_x11framebuffer.c index 0a63eda..2bfdc74 100644 --- a/src/video/x11/SDL_x11framebuffer.c +++ b/src/video/x11/SDL_x11framebuffer.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/x11/SDL_x11framebuffer.h b/src/video/x11/SDL_x11framebuffer.h index f5fe142..d6fb21f 100644 --- a/src/video/x11/SDL_x11framebuffer.h +++ b/src/video/x11/SDL_x11framebuffer.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/x11/SDL_x11keyboard.c b/src/video/x11/SDL_x11keyboard.c index 9a23baf..7073e13 100644 --- a/src/video/x11/SDL_x11keyboard.c +++ b/src/video/x11/SDL_x11keyboard.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/x11/SDL_x11keyboard.h b/src/video/x11/SDL_x11keyboard.h index 53cf512..389119c 100644 --- a/src/video/x11/SDL_x11keyboard.h +++ b/src/video/x11/SDL_x11keyboard.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/x11/SDL_x11messagebox.c b/src/video/x11/SDL_x11messagebox.c index 0e3b67a..5868493 100644 --- a/src/video/x11/SDL_x11messagebox.c +++ b/src/video/x11/SDL_x11messagebox.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/x11/SDL_x11messagebox.h b/src/video/x11/SDL_x11messagebox.h index 1675979..6232b35 100644 --- a/src/video/x11/SDL_x11messagebox.h +++ b/src/video/x11/SDL_x11messagebox.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/x11/SDL_x11modes.c b/src/video/x11/SDL_x11modes.c index 35c02e3..842836c 100644 --- a/src/video/x11/SDL_x11modes.c +++ b/src/video/x11/SDL_x11modes.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/x11/SDL_x11modes.h b/src/video/x11/SDL_x11modes.h index 8c6c1c2..31dec38 100644 --- a/src/video/x11/SDL_x11modes.h +++ b/src/video/x11/SDL_x11modes.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/x11/SDL_x11mouse.c b/src/video/x11/SDL_x11mouse.c index 6d2a463..df5f968 100644 --- a/src/video/x11/SDL_x11mouse.c +++ b/src/video/x11/SDL_x11mouse.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -30,6 +30,7 @@ /* FIXME: Find a better place to put this... */ static Cursor x11_empty_cursor = None; +static SDL_bool x11_cursor_visible = SDL_TRUE; static Display *GetDisplay(void) { @@ -220,64 +221,53 @@ static SDL_Cursor *X11_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y) return cursor; } -static SDL_Cursor *X11_CreateSystemCursor(SDL_SystemCursor id) +static unsigned int GetLegacySystemCursorShape(SDL_SystemCursor id) { - SDL_Cursor *cursor; - unsigned int shape; - switch (id) { - default: - SDL_assert(0); - return NULL; - /* X Font Cursors reference: */ - /* http://tronche.com/gui/x/xlib/appendix/b/ */ - case SDL_SYSTEM_CURSOR_ARROW: - shape = XC_left_ptr; - break; - case SDL_SYSTEM_CURSOR_IBEAM: - shape = XC_xterm; - break; - case SDL_SYSTEM_CURSOR_WAIT: - shape = XC_watch; - break; - case SDL_SYSTEM_CURSOR_CROSSHAIR: - shape = XC_tcross; - break; - case SDL_SYSTEM_CURSOR_WAITARROW: - shape = XC_watch; - break; - case SDL_SYSTEM_CURSOR_SIZENWSE: - shape = XC_top_left_corner; - break; - case SDL_SYSTEM_CURSOR_SIZENESW: - shape = XC_top_right_corner; - break; - case SDL_SYSTEM_CURSOR_SIZEWE: - shape = XC_sb_h_double_arrow; - break; - case SDL_SYSTEM_CURSOR_SIZENS: - shape = XC_sb_v_double_arrow; - break; - case SDL_SYSTEM_CURSOR_SIZEALL: - shape = XC_fleur; - break; - case SDL_SYSTEM_CURSOR_NO: - shape = XC_pirate; - break; - case SDL_SYSTEM_CURSOR_HAND: - shape = XC_hand2; - break; + /* X Font Cursors reference: */ + /* http://tronche.com/gui/x/xlib/appendix/b/ */ + case SDL_SYSTEM_CURSOR_ARROW: return XC_left_ptr; + case SDL_SYSTEM_CURSOR_IBEAM: return XC_xterm; + case SDL_SYSTEM_CURSOR_WAIT: return XC_watch; + case SDL_SYSTEM_CURSOR_CROSSHAIR: return XC_tcross; + case SDL_SYSTEM_CURSOR_WAITARROW: return XC_watch; + case SDL_SYSTEM_CURSOR_SIZENWSE: return XC_top_left_corner; + case SDL_SYSTEM_CURSOR_SIZENESW: return XC_top_right_corner; + case SDL_SYSTEM_CURSOR_SIZEWE: return XC_sb_h_double_arrow; + case SDL_SYSTEM_CURSOR_SIZENS: return XC_sb_v_double_arrow; + case SDL_SYSTEM_CURSOR_SIZEALL: return XC_fleur; + case SDL_SYSTEM_CURSOR_NO: return XC_pirate; + case SDL_SYSTEM_CURSOR_HAND: return XC_hand2; + case SDL_NUM_SYSTEM_CURSORS: break; /* so the compiler might notice if an enum value is missing here. */ } - cursor = SDL_calloc(1, sizeof(*cursor)); - if (cursor) { - Cursor x11_cursor; + SDL_assert(0); + return 0; +} - x11_cursor = X11_XCreateFontCursor(GetDisplay(), shape); +static SDL_Cursor *X11_CreateSystemCursor(SDL_SystemCursor id) +{ + SDL_Cursor *cursor = NULL; + Display *dpy = GetDisplay(); + Cursor x11_cursor = None; - cursor->driverdata = (void *)(uintptr_t)x11_cursor; - } else { - SDL_OutOfMemory(); +#ifdef SDL_VIDEO_DRIVER_X11_XCURSOR + if (SDL_X11_HAVE_XCURSOR) { + x11_cursor = X11_XcursorLibraryLoadCursor(dpy, SDL_GetCSSCursorName(id, NULL)); + } +#endif + + if (x11_cursor == None) { + x11_cursor = X11_XCreateFontCursor(dpy, GetLegacySystemCursorShape(id)); + } + + if (x11_cursor != None) { + cursor = SDL_calloc(1, sizeof(*cursor)); + if (!cursor) { + SDL_OutOfMemory(); + } else { + cursor->driverdata = (void *)(uintptr_t)x11_cursor; + } } return cursor; @@ -309,6 +299,8 @@ static int X11_ShowCursor(SDL_Cursor *cursor) Display *display = GetDisplay(); SDL_Window *window; + x11_cursor_visible = !!cursor; + for (window = video->windows; window; window = window->next) { SDL_WindowData *data = (SDL_WindowData *)window->driverdata; if (data) { @@ -330,6 +322,18 @@ static void WarpMouseInternal(Window xwindow, const int x, const int y) Display *display = videodata->display; #ifdef SDL_VIDEO_DRIVER_X11_XINPUT2 int deviceid = 0; +#endif + SDL_bool warp_hack = SDL_FALSE; + + /* XWayland will only warp the cursor if it is hidden, so this workaround is required. */ + if (videodata->is_xwayland && x11_cursor_visible) { + warp_hack = SDL_TRUE; + } + + if (warp_hack) { + X11_ShowCursor(NULL); + } +#ifdef SDL_VIDEO_DRIVER_X11_XINPUT2 if (X11_Xinput2IsInitialized()) { /* It seems XIWarpPointer() doesn't work correctly on multi-head setups: * https://developer.blender.org/rB165caafb99c6846e53d11c4e966990aaffc06cea @@ -346,6 +350,10 @@ static void WarpMouseInternal(Window xwindow, const int x, const int y) { X11_XWarpPointer(display, None, xwindow, 0, 0, 0, 0, x, y); } + + if (warp_hack) { + X11_ShowCursor(SDL_GetCursor()); + } X11_XSync(display, False); videodata->global_mouse_changed = SDL_TRUE; } @@ -486,5 +494,3 @@ void X11_QuitMouse(_THIS) } #endif /* SDL_VIDEO_DRIVER_X11 */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/x11/SDL_x11mouse.h b/src/video/x11/SDL_x11mouse.h index 5cccd31..eb9153e 100644 --- a/src/video/x11/SDL_x11mouse.h +++ b/src/video/x11/SDL_x11mouse.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/x11/SDL_x11opengl.c b/src/video/x11/SDL_x11opengl.c index 30563fc..a597f4e 100644 --- a/src/video/x11/SDL_x11opengl.c +++ b/src/video/x11/SDL_x11opengl.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga Copyright (C) 2021 NVIDIA Corporation This software is provided 'as-is', without any express or implied @@ -575,6 +575,7 @@ static int X11_GL_GetAttributes(_THIS, Display *display, int screen, int *attrib } if (_this->gl_config.floatbuffers) { + attribs[i++] = GLX_RENDER_TYPE; attribs[i++] = GLX_RGBA_FLOAT_TYPE_ARB; } diff --git a/src/video/x11/SDL_x11opengl.h b/src/video/x11/SDL_x11opengl.h index e0e8e19..6d7f3c8 100644 --- a/src/video/x11/SDL_x11opengl.h +++ b/src/video/x11/SDL_x11opengl.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/x11/SDL_x11opengles.c b/src/video/x11/SDL_x11opengles.c index ad1e26b..09733c3 100644 --- a/src/video/x11/SDL_x11opengles.c +++ b/src/video/x11/SDL_x11opengles.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/x11/SDL_x11opengles.h b/src/video/x11/SDL_x11opengles.h index 23530d8..f940968 100644 --- a/src/video/x11/SDL_x11opengles.h +++ b/src/video/x11/SDL_x11opengles.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/x11/SDL_x11shape.c b/src/video/x11/SDL_x11shape.c index fee1c7a..88ff052 100644 --- a/src/video/x11/SDL_x11shape.c +++ b/src/video/x11/SDL_x11shape.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/x11/SDL_x11shape.h b/src/video/x11/SDL_x11shape.h index 7cd168c..79f99bc 100644 --- a/src/video/x11/SDL_x11shape.h +++ b/src/video/x11/SDL_x11shape.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/x11/SDL_x11sym.h b/src/video/x11/SDL_x11sym.h index 9de95e4..cc1a658 100644 --- a/src/video/x11/SDL_x11sym.h +++ b/src/video/x11/SDL_x11sym.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -253,6 +253,7 @@ SDL_X11_MODULE(XCURSOR) SDL_X11_SYM(XcursorImage*,XcursorImageCreate,(int a,int b),(a,b),return) SDL_X11_SYM(void,XcursorImageDestroy,(XcursorImage *a),(a),) SDL_X11_SYM(Cursor,XcursorImageLoadCursor,(Display *a,const XcursorImage *b),(a,b),return) +SDL_X11_SYM(Cursor,XcursorLibraryLoadCursor,(Display *a, const char *b),(a,b),return) #endif /* Xdbe support */ diff --git a/src/video/x11/SDL_x11touch.c b/src/video/x11/SDL_x11touch.c index 338001f..414d8e8 100644 --- a/src/video/x11/SDL_x11touch.c +++ b/src/video/x11/SDL_x11touch.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/x11/SDL_x11touch.h b/src/video/x11/SDL_x11touch.h index ca6edac..3ff0e9a 100644 --- a/src/video/x11/SDL_x11touch.h +++ b/src/video/x11/SDL_x11touch.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/x11/SDL_x11video.c b/src/video/x11/SDL_x11video.c index a9d7abe..9023add 100644 --- a/src/video/x11/SDL_x11video.c +++ b/src/video/x11/SDL_x11video.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -50,7 +50,7 @@ static int X11_VideoInit(_THIS); static void X11_VideoQuit(_THIS); /* Find out what class name we should use */ -static char *get_classname() +static char *get_classname(void) { char *spot; #if defined(__LINUX__) || defined(__FREEBSD__) @@ -145,6 +145,12 @@ static int X11_SafetyNetErrHandler(Display *d, XErrorEvent *e) return 0; } +static SDL_bool X11_IsXWayland(Display *d) +{ + int opcode, event, error; + return X11_XQueryExtension(d, "XWAYLAND", &opcode, &event, &error) == True; +} + static SDL_VideoDevice *X11_CreateDevice(void) { SDL_VideoDevice *device; @@ -322,6 +328,8 @@ static SDL_VideoDevice *X11_CreateDevice(void) device->Vulkan_CreateSurface = X11_Vulkan_CreateSurface; #endif + data->is_xwayland = X11_IsXWayland(x11_display); + return device; } diff --git a/src/video/x11/SDL_x11video.h b/src/video/x11/SDL_x11video.h index 07cb01e..274233d 100644 --- a/src/video/x11/SDL_x11video.h +++ b/src/video/x11/SDL_x11video.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -156,6 +156,8 @@ typedef struct SDL_VideoData SDL_bool is_steam_deck; SDL_bool steam_keyboard_open; + SDL_bool is_xwayland; + } SDL_VideoData; extern SDL_bool X11_UseDirectColorVisuals(void); diff --git a/src/video/x11/SDL_x11vulkan.c b/src/video/x11/SDL_x11vulkan.c index d9a0d2f..a2fe5ae 100644 --- a/src/video/x11/SDL_x11vulkan.c +++ b/src/video/x11/SDL_x11vulkan.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -32,8 +32,10 @@ #if defined(__OpenBSD__) #define DEFAULT_VULKAN "libvulkan.so" +#define DEFAULT_X11_XCB "libX11-xcb.so" #else #define DEFAULT_VULKAN "libvulkan.so.1" +#define DEFAULT_X11_XCB "libX11-xcb.so.1" #endif /* @@ -108,7 +110,7 @@ int X11_Vulkan_LoadLibrary(_THIS, const char *path) } else { const char *libX11XCBLibraryName = SDL_getenv("SDL_X11_XCB_LIBRARY"); if (!libX11XCBLibraryName) { - libX11XCBLibraryName = "libX11-xcb.so"; + libX11XCBLibraryName = DEFAULT_X11_XCB; } videoData->vulkan_xlib_xcb_library = SDL_LoadObject(libX11XCBLibraryName); if (!videoData->vulkan_xlib_xcb_library) { diff --git a/src/video/x11/SDL_x11vulkan.h b/src/video/x11/SDL_x11vulkan.h index 438b16d..480c5aa 100644 --- a/src/video/x11/SDL_x11vulkan.h +++ b/src/video/x11/SDL_x11vulkan.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c index 07ec431..a32ea48 100644 --- a/src/video/x11/SDL_x11window.c +++ b/src/video/x11/SDL_x11window.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/x11/SDL_x11window.h b/src/video/x11/SDL_x11window.h index 12a89b0..cc8511f 100644 --- a/src/video/x11/SDL_x11window.h +++ b/src/video/x11/SDL_x11window.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/x11/SDL_x11xfixes.c b/src/video/x11/SDL_x11xfixes.c index 6ae7e05..3fb000d 100644 --- a/src/video/x11/SDL_x11xfixes.c +++ b/src/video/x11/SDL_x11xfixes.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -74,12 +74,12 @@ void X11_InitXfixes(_THIS) xfixes_initialized = 1; } -int X11_XfixesIsInitialized() +int X11_XfixesIsInitialized(void) { return xfixes_initialized; } -int X11_GetXFixesSelectionNotifyEvent() +int X11_GetXFixesSelectionNotifyEvent(void) { return xfixes_selection_notify_event; } diff --git a/src/video/x11/SDL_x11xfixes.h b/src/video/x11/SDL_x11xfixes.h index 3464867..8c72b19 100644 --- a/src/video/x11/SDL_x11xfixes.h +++ b/src/video/x11/SDL_x11xfixes.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/video/x11/SDL_x11xinput2.c b/src/video/x11/SDL_x11xinput2.c index afed858..65ed9b6 100644 --- a/src/video/x11/SDL_x11xinput2.c +++ b/src/video/x11/SDL_x11xinput2.c @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -453,7 +453,7 @@ void X11_Xinput2SelectTouch(_THIS, SDL_Window *window) #endif } -int X11_Xinput2IsInitialized() +int X11_Xinput2IsInitialized(void) { #ifdef SDL_VIDEO_DRIVER_X11_XINPUT2 return xinput2_initialized; @@ -462,7 +462,7 @@ int X11_Xinput2IsInitialized() #endif } -int X11_Xinput2IsMultitouchSupported() +int X11_Xinput2IsMultitouchSupported(void) { #ifdef SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH return xinput2_initialized && xinput2_multitouch_supported; diff --git a/src/video/x11/SDL_x11xinput2.h b/src/video/x11/SDL_x11xinput2.h index 3a8e3c0..174033b 100644 --- a/src/video/x11/SDL_x11xinput2.h +++ b/src/video/x11/SDL_x11xinput2.h @@ -1,6 +1,6 @@ /* Simple DirectMedia Layer - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index f048d51..6388f9c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,5 +1,5 @@ -cmake_minimum_required(VERSION 3.0...3.5) -project(SDL2_test) +cmake_minimum_required(VERSION 3.0...3.10) +project(SDL2_test C) include(CheckCCompilerFlag) include(CMakeParseArguments) @@ -99,6 +99,8 @@ elseif(PS2) dmakit ps2_drivers ) +elseif(IOS OR TVOS) + link_libraries(SDL2::SDL2main SDL2::SDL2test SDL2::SDL2-static) else() link_libraries(SDL2::SDL2test SDL2::SDL2-static) endif() @@ -366,12 +368,11 @@ if(PSP) endif() if(N3DS) - set(ROMFS_DIR "${CMAKE_CURRENT_BINARY_DIR}/romfs") - file(COPY ${RESOURCE_FILES} DESTINATION "${ROMFS_DIR}") - foreach(APP IN LISTS SDL_TEST_EXECUTABLES) get_target_property(TARGET_BINARY_DIR ${APP} BINARY_DIR) + set(ROMFS_DIR "${TARGET_BINARY_DIR}/sdl-${APP}") set(SMDH_FILE "${TARGET_BINARY_DIR}/${APP}.smdh") + file(MAKE_DIRECTORY ${ROMFS_DIR}) ctr_generate_smdh("${SMDH_FILE}" NAME "SDL-${APP}" DESCRIPTION "SDL2 Test suite" @@ -428,7 +429,7 @@ add_custom_target(copy-sdl-test-resources ) foreach(APP IN LISTS SDL_TESTS_NEEDS_RESOURCES) - if(PSP OR PS2) + if(PSP OR PS2 OR N3DS) foreach(RESOURCE_FILE ${RESOURCE_FILES}) add_custom_command(TARGET ${APP} POST_BUILD COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${RESOURCE_FILE} $/sdl-${APP}) endforeach() diff --git a/test/checkkeys.c b/test/checkkeys.c index f546900..984ff23 100644 --- a/test/checkkeys.c +++ b/test/checkkeys.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -107,7 +107,7 @@ print_modifiers(char **text, size_t *maxlen) } static void -PrintModifierState() +PrintModifierState(void) { char message[512]; char *spot; @@ -166,7 +166,7 @@ PrintText(const char *eventtype, const char *text) SDL_Log("%s Text (%s): \"%s%s\"\n", eventtype, expanded, *text == '"' ? "\\" : "", text); } -void loop() +void loop(void) { SDL_Event event; /* Check for events */ diff --git a/test/checkkeysthreads.c b/test/checkkeysthreads.c index efd6548..959231d 100644 --- a/test/checkkeysthreads.c +++ b/test/checkkeysthreads.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -103,7 +103,7 @@ print_modifiers(char **text, size_t *maxlen) } static void -PrintModifierState() +PrintModifierState(void) { char message[512]; char *spot; @@ -162,7 +162,7 @@ PrintText(const char *eventtype, const char *text) SDL_Log("%s Text (%s): \"%s%s\"\n", eventtype, expanded, *text == '"' ? "\\" : "", text); } -void loop() +void loop(void) { SDL_Event event; /* Check for events */ diff --git a/test/controllermap.c b/test/controllermap.c index 982a9fb..aedaa14 100644 --- a/test/controllermap.c +++ b/test/controllermap.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/loopwave.c b/test/loopwave.c index 15f1365..a289812 100644 --- a/test/loopwave.c +++ b/test/loopwave.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -46,7 +46,7 @@ quit(int rc) } static void -close_audio() +close_audio(void) { if (device != 0) { SDL_CloseAudioDevice(device); @@ -55,7 +55,7 @@ close_audio() } static void -open_audio() +open_audio(void) { /* Initialize fillerup() variables */ device = SDL_OpenAudioDevice(NULL, SDL_FALSE, &wave.spec, NULL, 0); @@ -70,7 +70,7 @@ open_audio() } #ifndef __EMSCRIPTEN__ -static void reopen_audio() +static void reopen_audio(void) { close_audio(); open_audio(); @@ -103,7 +103,7 @@ fillerup(void *unused, Uint8 *stream, int len) static int done = 0; #ifdef __EMSCRIPTEN__ -void loop() +void loop(void) { if (done || (SDL_GetAudioDeviceStatus(device) != SDL_AUDIO_PLAYING)) { emscripten_cancel_main_loop(); diff --git a/test/loopwavequeue.c b/test/loopwavequeue.c index 01b6ece..4117915 100644 --- a/test/loopwavequeue.c +++ b/test/loopwavequeue.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -48,7 +48,7 @@ void poked(int sig) done = 1; } -void loop() +void loop(void) { #ifdef __EMSCRIPTEN__ if (done || (SDL_GetAudioStatus() != SDL_AUDIO_PLAYING)) { diff --git a/test/testatomic.c b/test/testatomic.c index 1a59910..a807eff 100644 --- a/test/testatomic.c +++ b/test/testatomic.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -31,7 +31,7 @@ tf(SDL_bool _tf) return f; } -static void RunBasicTest() +static void RunBasicTest(void) { int value; SDL_SpinLock lock = 0; @@ -153,7 +153,7 @@ static void runAdder(void) SDL_Log("Finished in %f sec\n", (end - start) / 1000.f); } -static void RunEpicTest() +static void RunEpicTest(void) { int b; atomicValue v; diff --git a/test/testaudiocapture.c b/test/testaudiocapture.c index 523385b..b07d563 100644 --- a/test/testaudiocapture.c +++ b/test/testaudiocapture.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,7 +24,7 @@ static SDL_AudioDeviceID devid_in = 0; static SDL_AudioDeviceID devid_out = 0; static void -loop() +loop(void) { SDL_bool please_quit = SDL_FALSE; SDL_Event e; diff --git a/test/testaudiohotplug.c b/test/testaudiohotplug.c index 354d464..cfa3e1b 100644 --- a/test/testaudiohotplug.c +++ b/test/testaudiohotplug.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -81,7 +81,7 @@ devtypestr(int iscapture) } static void -iteration() +iteration(void) { SDL_Event e; SDL_AudioDeviceID dev; @@ -124,7 +124,7 @@ iteration() } #ifdef __EMSCRIPTEN__ -void loop() +void loop(void) { if (done) emscripten_cancel_main_loop(); diff --git a/test/testaudioinfo.c b/test/testaudioinfo.c index ec4b864..43a3f63 100644 --- a/test/testaudioinfo.c +++ b/test/testaudioinfo.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testautomation.c b/test/testautomation.c index 3b5fad8..b0b6b00 100644 --- a/test/testautomation.c +++ b/test/testautomation.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testautomation_audio.c b/test/testautomation_audio.c index 16ab753..1564f05 100644 --- a/test/testautomation_audio.c +++ b/test/testautomation_audio.c @@ -96,7 +96,7 @@ static SDL_bool DriverIsProblematic(const char *driver) * \sa https://wiki.libsdl.org/SDL_QuitSubSystem * \sa https://wiki.libsdl.org/SDL_InitSubSystem */ -int audio_quitInitAudioSubSystem() +int audio_quitInitAudioSubSystem(void) { /* Stop SDL audio subsystem */ SDL_QuitSubSystem(SDL_INIT_AUDIO); @@ -114,7 +114,7 @@ int audio_quitInitAudioSubSystem() * \sa https://wiki.libsdl.org/SDL_InitAudio * \sa https://wiki.libsdl.org/SDL_QuitAudio */ -int audio_initQuitAudio() +int audio_initQuitAudio(void) { int result; int i, iMax; @@ -195,7 +195,7 @@ int audio_initQuitAudio() * \sa https://wiki.libsdl.org/SDL_CloseAudio * \sa https://wiki.libsdl.org/SDL_QuitAudio */ -int audio_initOpenCloseQuitAudio() +int audio_initOpenCloseQuitAudio(void) { int result, expectedResult; int i, iMax, j, k; @@ -318,7 +318,7 @@ int audio_initOpenCloseQuitAudio() * * \sa https://wiki.libsdl.org/SDL_PauseAudio */ -int audio_pauseUnpauseAudio() +int audio_pauseUnpauseAudio(void) { int result; int i, iMax, j, k, l; @@ -474,7 +474,7 @@ int audio_pauseUnpauseAudio() * \sa https://wiki.libsdl.org/SDL_GetNumAudioDevices * \sa https://wiki.libsdl.org/SDL_GetAudioDeviceName */ -int audio_enumerateAndNameAudioDevices() +int audio_enumerateAndNameAudioDevices(void) { int t, tt; int i, n, nn; @@ -532,7 +532,7 @@ int audio_enumerateAndNameAudioDevices() * \sa https://wiki.libsdl.org/SDL_GetNumAudioDevices * \sa https://wiki.libsdl.org/SDL_GetAudioDeviceName */ -int audio_enumerateAndNameAudioDevicesNegativeTests() +int audio_enumerateAndNameAudioDevicesNegativeTests(void) { int t; int i, j, no, nc; @@ -578,7 +578,7 @@ int audio_enumerateAndNameAudioDevicesNegativeTests() * \sa https://wiki.libsdl.org/SDL_GetNumAudioDrivers * \sa https://wiki.libsdl.org/SDL_GetAudioDriver */ -int audio_printAudioDrivers() +int audio_printAudioDrivers(void) { int i, n; const char *name; @@ -608,7 +608,7 @@ int audio_printAudioDrivers() * * \sa https://wiki.libsdl.org/SDL_GetCurrentAudioDriver */ -int audio_printCurrentAudioDriver() +int audio_printCurrentAudioDriver(void) { /* Check current audio driver */ const char *name = SDL_GetCurrentAudioDriver(); @@ -639,7 +639,7 @@ int _audioFrequencies[] = { 11025, 22050, 44100, 48000 }; * * \sa https://wiki.libsdl.org/SDL_BuildAudioCVT */ -int audio_buildAudioCVT() +int audio_buildAudioCVT(void) { int result; SDL_AudioCVT cvt; @@ -703,7 +703,7 @@ int audio_buildAudioCVT() * * \sa https://wiki.libsdl.org/SDL_BuildAudioCVT */ -int audio_buildAudioCVTNegative() +int audio_buildAudioCVTNegative(void) { const char *expectedError = "Parameter 'cvt' is invalid"; const char *error; @@ -798,7 +798,7 @@ int audio_buildAudioCVTNegative() * * \sa https://wiki.libsdl.org/SDL_GetAudioStatus */ -int audio_getAudioStatus() +int audio_getAudioStatus(void) { SDL_AudioStatus result; @@ -817,7 +817,7 @@ int audio_getAudioStatus() * * \sa https://wiki.libsdl.org/SDL_GetAudioStatus */ -int audio_openCloseAndGetAudioStatus() +int audio_openCloseAndGetAudioStatus(void) { SDL_AudioStatus result; int i; @@ -878,7 +878,7 @@ int audio_openCloseAndGetAudioStatus() * \sa https://wiki.libsdl.org/SDL_LockAudioDevice * \sa https://wiki.libsdl.org/SDL_UnlockAudioDevice */ -int audio_lockUnlockOpenAudioDevice() +int audio_lockUnlockOpenAudioDevice(void) { int i; int count; @@ -942,7 +942,7 @@ int audio_lockUnlockOpenAudioDevice() * \sa https://wiki.libsdl.org/SDL_BuildAudioCVT * \sa https://wiki.libsdl.org/SDL_ConvertAudio */ -int audio_convertAudio() +int audio_convertAudio(void) { int result; SDL_AudioCVT cvt; @@ -1043,7 +1043,7 @@ int audio_convertAudio() * * \sa https://wiki.libsdl.org/SDL_AudioDeviceConnected */ -int audio_openCloseAudioDeviceConnected() +int audio_openCloseAudioDeviceConnected(void) { int result = -1; int i; @@ -1118,7 +1118,7 @@ static double sine_wave_sample(const Sint64 idx, const Sint64 rate, const Sint64 * \sa https://wiki.libsdl.org/SDL_BuildAudioCVT * \sa https://wiki.libsdl.org/SDL_ConvertAudio */ -int audio_resampleLoss() +int audio_resampleLoss(void) { /* Note: always test long input time (>= 5s from experience) in some test * cases because an improper implementation may suffer from low resampling diff --git a/test/testautomation_keyboard.c b/test/testautomation_keyboard.c index 5ed9207..d59f2fd 100644 --- a/test/testautomation_keyboard.c +++ b/test/testautomation_keyboard.c @@ -102,7 +102,7 @@ int keyboard_getKeyFromName(void *arg) /* * Local helper to check for the invalid scancode error message */ -void _checkInvalidScancodeError() +void _checkInvalidScancodeError(void) { const char *expectedError = "Parameter 'scancode' is invalid"; const char *error; @@ -574,7 +574,7 @@ int keyboard_getScancodeFromName(void *arg) /* * Local helper to check for the invalid scancode error message */ -void _checkInvalidNameError() +void _checkInvalidNameError(void) { const char *expectedError = "Parameter 'name' is invalid"; const char *error; diff --git a/test/testautomation_log.c b/test/testautomation_log.c index 4edb487..1ad1894 100644 --- a/test/testautomation_log.c +++ b/test/testautomation_log.c @@ -21,7 +21,7 @@ static void EnableTestLog(int *message_count) SDL_LogSetOutputFunction(TestLogOutput, message_count); } -static void DisableTestLog() +static void DisableTestLog(void) { SDL_LogSetOutputFunction(original_function, original_userdata); } diff --git a/test/testautomation_math.c b/test/testautomation_math.c index ef9b40b..314d8ba 100644 --- a/test/testautomation_math.c +++ b/test/testautomation_math.c @@ -82,7 +82,7 @@ helper_dtod(const char *func_name, d_to_d_func func, Uint32 i; for (i = 0; i < cases_size; i++) { const double result = func(cases[i].input); - SDLTest_AssertCheck((result - cases[i].expected) < FLT_EPSILON, + SDLTest_AssertCheck(SDL_fabs(result - cases[i].expected) < FLT_EPSILON, "%s(%f), expected %f, got %f", func_name, cases[i].input, @@ -117,11 +117,10 @@ helper_dtod_inexact(const char *func_name, d_to_d_func func, max_err = -max_err; } SDLTest_AssertCheck(diff <= max_err, - "%s(%f), expected [%f,%f], got %f", + "%s(%f), expected %f +/- %g, got %f", func_name, cases[i].input, - cases[i].expected - EPSILON, - cases[i].expected + EPSILON, + cases[i].expected, max_err, result); } @@ -182,11 +181,10 @@ helper_ddtod_inexact(const char *func_name, dd_to_d_func func, } SDLTest_AssertCheck(diff <= max_err, - "%s(%f,%f), expected [%f,%f], got %f", + "%s(%f,%f), expected %f +/- %g, got %f", func_name, cases[i].x_input, cases[i].y_input, - cases[i].expected - EPSILON, - cases[i].expected + EPSILON, + cases[i].expected, max_err, result); } @@ -1114,7 +1112,7 @@ exp_regularCases(void *args) { 112.89, 10653788283588960962604279261058893737879589093376.0 }, { 539.483, 1970107755334319939701129934673541628417235942656909222826926175622435588279443011110464355295725187195188154768877850257012251677751742837992843520967922303961718983154427294786640886286983037548604937796221048661733679844353544028160.0 }, }; - return helper_dtod("Exp", SDL_exp, regular_cases, SDL_arraysize(regular_cases)); + return helper_dtod_inexact("Exp", SDL_exp, regular_cases, SDL_arraysize(regular_cases)); } /* SDL_log tests functions */ @@ -1161,7 +1159,7 @@ log_baseCases(void *args) 1.0, 0.0, result); result = SDL_log(EULER); - SDLTest_AssertCheck((result - 1.) < FLT_EPSILON, + SDLTest_AssertCheck(SDL_fabs(result - 1.) < FLT_EPSILON, "Log(%f), expected %f, got %f", EULER, 1.0, result); diff --git a/test/testautomation_stdlib.c b/test/testautomation_stdlib.c index ed9f13e..969dd39 100644 --- a/test/testautomation_stdlib.c +++ b/test/testautomation_stdlib.c @@ -62,6 +62,18 @@ int stdlib_snprintf(void *arg) SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text); SDLTest_AssertCheck(result == SDL_strlen(text), "Check result value, expected: %d, got: %d", (int)SDL_strlen(text), result); + result = SDL_snprintf(text, sizeof(text), "%10sA", "foo"); + expected = " fooA"; + SDLTest_AssertPass("Call to SDL_snprintf(\"%%10sA\", \"foo\")"); + SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text); + SDLTest_AssertCheck(result == SDL_strlen(text), "Check result value, expected: %d, got: %d", (int)SDL_strlen(text), result); + + result = SDL_snprintf(text, sizeof(text), "%-10sA", "foo"); + expected = "foo A"; + SDLTest_AssertPass("Call to SDL_snprintf(\"%%-10sA\", \"foo\")"); + SDLTest_AssertCheck(SDL_strcmp(text, expected) == 0, "Check text, expected: %s, got: %s", expected, text); + SDLTest_AssertCheck(result == SDL_strlen(text), "Check result value, expected: %d, got: %d", (int)SDL_strlen(text), result); + result = SDL_snprintf(text, sizeof(text), "%S", L"foo"); expected = "foo"; SDLTest_AssertPass("Call to SDL_snprintf(\"%%S\", \"foo\")"); diff --git a/test/testautomation_subsystems.c b/test/testautomation_subsystems.c index d25edee..15b1753 100644 --- a/test/testautomation_subsystems.c +++ b/test/testautomation_subsystems.c @@ -40,7 +40,7 @@ static void subsystemsTearDown(void *arg) * \sa SDL_QuitSubSystem * */ -static int subsystems_referenceCount() +static int subsystems_referenceCount(void) { const int system = SDL_INIT_VIDEO; int result; @@ -90,7 +90,7 @@ static int subsystems_referenceCount() * \sa SDL_QuitSubSystem * */ -static int subsystems_dependRefCountInitAllQuitByOne() +static int subsystems_dependRefCountInitAllQuitByOne(void) { int result; /* Ensure that we start with reset subsystems. */ @@ -128,7 +128,7 @@ static int subsystems_dependRefCountInitAllQuitByOne() * \sa SDL_QuitSubSystem * */ -static int subsystems_dependRefCountInitByOneQuitAll() +static int subsystems_dependRefCountInitByOneQuitAll(void) { int result; /* Ensure that we start with reset subsystems. */ @@ -163,7 +163,7 @@ static int subsystems_dependRefCountInitByOneQuitAll() * \sa SDL_QuitSubSystem * */ -static int subsystems_dependRefCountWithExtraInit() +static int subsystems_dependRefCountWithExtraInit(void) { int result; /* Ensure that we start with reset subsystems. */ diff --git a/test/testautomation_surface.c b/test/testautomation_surface.c index fcc4bc1..575ebcf 100644 --- a/test/testautomation_surface.c +++ b/test/testautomation_surface.c @@ -81,7 +81,7 @@ void _surfaceTearDown(void *arg) /** * Helper that clears the test surface */ -void _clearTestSurface() +void _clearTestSurface(void) { int ret; Uint32 color; @@ -346,7 +346,9 @@ int surface_testCompleteSurfaceConversion(void *arg) SDL_PIXELFORMAT_RGBA8888, SDL_PIXELFORMAT_ABGR8888, SDL_PIXELFORMAT_BGRA8888, +#if 0 /* We aren't testing HDR10 colorspace conversion */ SDL_PIXELFORMAT_ARGB2101010, +#endif }; SDL_Surface *face = NULL, *cvt1, *cvt2, *final; SDL_PixelFormat *fmt1, *fmt2; diff --git a/test/testautomation_video.c b/test/testautomation_video.c index dd8f1c5..bf24bbb 100644 --- a/test/testautomation_video.c +++ b/test/testautomation_video.c @@ -624,7 +624,7 @@ int video_getWindowDisplayMode(void *arg) } /* Helper function that checks for an 'Invalid window' error */ -void _checkInvalidWindowError() +void _checkInvalidWindowError(void) { const char *invalidWindowError = "Invalid window"; char *lastError; @@ -1300,7 +1300,7 @@ int video_getSetWindowPosition(void *arg) } /* Helper function that checks for an 'Invalid parameter' error */ -void _checkInvalidParameterError() +void _checkInvalidParameterError(void) { const char *invalidParameterError = "Parameter"; char *lastError; @@ -2181,6 +2181,76 @@ int video_setWindowCenteredOnDisplay(void *arg) return TEST_COMPLETED; } +/** + * Tests window surface functionality + */ +static int video_getWindowSurface(void *arg) +{ + const char *title = "video_getWindowSurface Test Window"; + SDL_Window *window; + SDL_Surface *surface; + SDL_Renderer *renderer; + Uint32 renderer_flags = SDL_RENDERER_ACCELERATED; + int result; + + if (SDL_strcmp(SDL_GetCurrentVideoDriver(), "dummy") == 0) { + renderer_flags = SDL_RENDERER_SOFTWARE; + } + + /* Make sure we're testing interaction with an accelerated renderer */ + SDL_SetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION, "1"); + + window = SDL_CreateWindow(title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 320, 320, 0); + SDLTest_AssertPass("Call to SDL_CreateWindow('%s', SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 320, 320, 0)", title); + SDLTest_AssertCheck(window != NULL, "Validate that returned window is not NULL"); + + surface = SDL_GetWindowSurface(window); + SDLTest_AssertPass("Call to SDL_GetWindowSurface(window)"); + SDLTest_AssertCheck(surface != NULL, "Validate that returned surface is not NULL"); + SDLTest_AssertCheck(SDL_HasWindowSurface(window), "Validate that window has a surface"); + + result = SDL_UpdateWindowSurface(window); + SDLTest_AssertPass("Call to SDL_UpdateWindowSurface(window)"); + SDLTest_AssertCheck(result == 0, "Verify return value; expected: 0, got: %d", result); + + /* We shouldn't be able to create a renderer on a window with a surface */ + renderer = SDL_CreateRenderer(window, -1, renderer_flags); + SDLTest_AssertPass("Call to SDL_CreateRenderer(window)"); + SDLTest_AssertCheck(renderer == NULL, "Validate that returned renderer is NULL"); + + result = SDL_DestroyWindowSurface(window); + SDLTest_AssertPass("Call to SDL_DestroyWindowSurface(window)"); + SDLTest_AssertCheck(result == 0, "Verify return value; expected: 0, got: %d", result); + SDLTest_AssertCheck(!SDL_HasWindowSurface(window), "Validate that window does not have a surface"); + + /* We should be able to create a renderer on the window now */ + renderer = SDL_CreateRenderer(window, -1, renderer_flags); + SDLTest_AssertPass("Call to SDL_CreateRenderer(window)"); + SDLTest_AssertCheck(renderer != NULL, "Validate that returned renderer is not NULL"); + + /* We should not be able to create a window surface now, unless it was created by the renderer */ + if (!SDL_HasWindowSurface(window)) { + surface = SDL_GetWindowSurface(window); + SDLTest_AssertPass("Call to SDL_GetWindowSurface(window)"); + SDLTest_AssertCheck(surface == NULL, "Validate that returned surface is NULL"); + } + + SDL_DestroyRenderer(renderer); + SDLTest_AssertPass("Call to SDL_DestroyRenderer(renderer)"); + SDLTest_AssertCheck(!SDL_HasWindowSurface(window), "Validate that window does not have a surface"); + + /* We should be able to create a window surface again */ + surface = SDL_GetWindowSurface(window); + SDLTest_AssertPass("Call to SDL_GetWindowSurface(window)"); + SDLTest_AssertCheck(surface != NULL, "Validate that returned surface is not NULL"); + SDLTest_AssertCheck(SDL_HasWindowSurface(window), "Validate that window has a surface"); + + /* Clean up */ + SDL_DestroyWindow(window); + + return TEST_COMPLETED; +} + /* ================= Test References ================== */ /* Video test cases */ @@ -2265,13 +2335,17 @@ static const SDLTest_TestCaseReference videoTest23 = static const SDLTest_TestCaseReference videoTest24 = { (SDLTest_TestCaseFp) video_setWindowCenteredOnDisplay, "video_setWindowCenteredOnDisplay", "Checks using SDL_WINDOWPOS_CENTERED_DISPLAY centers the window on a display", TEST_ENABLED }; +static const SDLTest_TestCaseReference videoTest25 = { + (SDLTest_TestCaseFp)video_getWindowSurface, "video_getWindowSurface", "Checks window surface functionality", TEST_ENABLED +}; + /* Sequence of Video test cases */ static const SDLTest_TestCaseReference *videoTests[] = { &videoTest1, &videoTest2, &videoTest3, &videoTest4, &videoTest5, &videoTest6, &videoTest7, &videoTest8, &videoTest9, &videoTest10, &videoTest11, &videoTest12, &videoTest13, &videoTest14, &videoTest15, &videoTest16, &videoTest17, &videoTest18, &videoTest19, &videoTest20, &videoTest21, &videoTest22, - &videoTest23, &videoTest24, NULL + &videoTest23, &videoTest24, &videoTest25, NULL }; /* Video test suite (global) */ diff --git a/test/testbounds.c b/test/testbounds.c index 9bd73ac..54e89aa 100644 --- a/test/testbounds.c +++ b/test/testbounds.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testcustomcursor.c b/test/testcustomcursor.c index aec3c78..2d13fd5 100644 --- a/test/testcustomcursor.c +++ b/test/testcustomcursor.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -148,7 +148,7 @@ quit(int rc) exit(rc); } -void loop() +void loop(void) { int i; SDL_Event event; diff --git a/test/testdisplayinfo.c b/test/testdisplayinfo.c index 9740ab1..5b6543e 100644 --- a/test/testdisplayinfo.c +++ b/test/testdisplayinfo.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testdraw2.c b/test/testdraw2.c index 43aa184..4e8c5a2 100644 --- a/test/testdraw2.c +++ b/test/testdraw2.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -174,7 +174,7 @@ void DrawRects(SDL_Renderer *renderer) } } -void loop() +void loop(void) { Uint32 now; int i; diff --git a/test/testdrawchessboard.c b/test/testdrawchessboard.c index 4dffe06..db9da41 100644 --- a/test/testdrawchessboard.c +++ b/test/testdrawchessboard.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -12,7 +12,10 @@ This file is created by : Nitin Jain (nitin.j4@samsung.com) */ -/* Sample program: Draw a Chess Board by using SDL_CreateSoftwareRenderer API */ +/* Sample program: Draw a Chess Board by using the SDL render API */ + +/* This allows testing SDL_CreateSoftwareRenderer with the window surface API. Undefine it to use the accelerated renderer instead. */ +#define USE_SOFTWARE_RENDERER #include #include @@ -25,10 +28,13 @@ SDL_Window *window; SDL_Renderer *renderer; -SDL_Surface *surface; int done; -void DrawChessBoard() +#ifdef USE_SOFTWARE_RENDERER +SDL_Surface *surface; +#endif + +void DrawChessBoard(void) { int row = 0, column = 0, x = 0; SDL_Rect rect, darea; @@ -50,14 +56,14 @@ void DrawChessBoard() SDL_RenderFillRect(renderer, &rect); } } - SDL_RenderPresent(renderer); } -void loop() +void loop(void) { SDL_Event e; while (SDL_PollEvent(&e)) { +#ifdef USE_SOFTWARE_RENDERER /* Re-create when window has been resized */ if ((e.type == SDL_WINDOWEVENT) && (e.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)) { @@ -69,6 +75,7 @@ void loop() SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF); SDL_RenderClear(renderer); } +#endif if (e.type == SDL_QUIT) { done = 1; @@ -87,11 +94,19 @@ void loop() } } + /* Clear the rendering surface with the specified color */ + SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF); + SDL_RenderClear(renderer); + DrawChessBoard(); + SDL_RenderPresent(renderer); + +#ifdef USE_SOFTWARE_RENDERER /* Got everything on rendering surface, now Update the drawing image on window screen */ SDL_UpdateWindowSurface(window); +#endif } int main(int argc, char *argv[]) @@ -111,17 +126,17 @@ int main(int argc, char *argv[]) SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Window creation fail : %s\n", SDL_GetError()); return 1; } +#ifdef USE_SOFTWARE_RENDERER surface = SDL_GetWindowSurface(window); renderer = SDL_CreateSoftwareRenderer(surface); +#else + renderer = SDL_CreateRenderer(window, -1, 0); +#endif if (!renderer) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Render creation for surface fail : %s\n", SDL_GetError()); return 1; } - /* Clear the rendering surface with the specified color */ - SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF); - SDL_RenderClear(renderer); - /* Draw the Image on rendering surface */ done = 0; #ifdef __EMSCRIPTEN__ diff --git a/test/testdropfile.c b/test/testdropfile.c index 2184f06..80fcd4a 100644 --- a/test/testdropfile.c +++ b/test/testdropfile.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testerror.c b/test/testerror.c index 25874d1..a4615d1 100644 --- a/test/testerror.c +++ b/test/testerror.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testevdev.c b/test/testevdev.c index 67124ae..07e85c5 100644 --- a/test/testevdev.c +++ b/test/testevdev.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga Copyright (C) 2020-2022 Collabora Ltd. This software is provided 'as-is', without any express or implied diff --git a/test/testfile.c b/test/testfile.c index a35da02..67ef4ae 100644 --- a/test/testfile.c +++ b/test/testfile.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testfilesystem.c b/test/testfilesystem.c index af0bd9f..2380251 100644 --- a/test/testfilesystem.c +++ b/test/testfilesystem.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testfilesystem_pre.c b/test/testfilesystem_pre.c index 11615ab..49b7013 100644 --- a/test/testfilesystem_pre.c +++ b/test/testfilesystem_pre.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testgamecontroller.c b/test/testgamecontroller.c index 52d3b2d..fa9b240 100644 --- a/test/testgamecontroller.c +++ b/test/testgamecontroller.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -107,7 +107,7 @@ static int virtual_axis_start_x; static int virtual_axis_start_y; static SDL_GameControllerButton virtual_button_active = SDL_CONTROLLER_BUTTON_INVALID; -static void UpdateWindowTitle() +static void UpdateWindowTitle(void) { if (!window) { return; @@ -329,7 +329,7 @@ typedef struct Uint8 ucLedBlue; /* 46 */ } DS5EffectsState_t; -static void CyclePS5TriggerEffect() +static void CyclePS5TriggerEffect(void) { DS5EffectsState_t state; @@ -351,7 +351,7 @@ static void CyclePS5TriggerEffect() SDL_GameControllerSendEffect(gamecontroller, &state, sizeof(state)); } -static SDL_bool ShowingFront() +static SDL_bool ShowingFront(void) { SDL_bool showing_front = SDL_TRUE; int i; @@ -394,7 +394,7 @@ static int SDLCALL VirtualControllerSetLED(void *userdata, Uint8 red, Uint8 gree return 0; } -static void OpenVirtualController() +static void OpenVirtualController(void) { SDL_VirtualJoystickDesc desc; int virtual_index; @@ -420,7 +420,7 @@ static void OpenVirtualController() } } -static void CloseVirtualController() +static void CloseVirtualController(void) { int i; diff --git a/test/testgeometry.c b/test/testgeometry.c index e09c383..f6377e2 100644 --- a/test/testgeometry.c +++ b/test/testgeometry.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -62,7 +62,7 @@ int LoadSprite(const char *file) return 0; } -void loop() +void loop(void) { int i; SDL_Event event; diff --git a/test/testgesture.c b/test/testgesture.c index 9870b60..1a5d72d 100644 --- a/test/testgesture.c +++ b/test/testgesture.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testgl2.c b/test/testgl2.c index d14ae16..1c283c8 100644 --- a/test/testgl2.c +++ b/test/testgl2.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -78,7 +78,7 @@ quit(int rc) } static void -Render() +Render(void) { static float color[8][3] = { { 1.0, 1.0, 0.0 }, diff --git a/test/testgles.c b/test/testgles.c index b1577cd..f092075 100644 --- a/test/testgles.c +++ b/test/testgles.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -49,7 +49,7 @@ quit(int rc) } static void -Render() +Render(void) { static GLubyte color[8][4] = { { 255, 0, 0, 0 }, { 255, 0, 0, 255 }, diff --git a/test/testgles2.c b/test/testgles2.c index bafc524..78bc18a 100644 --- a/test/testgles2.c +++ b/test/testgles2.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -569,7 +569,7 @@ render_thread_fn(void *render_ctx) } static void -loop_threaded() +loop_threaded(void) { SDL_Event event; int i; @@ -598,7 +598,7 @@ loop_threaded() #endif static void -loop() +loop(void) { SDL_Event event; int i; diff --git a/test/testgles2_sdf.c b/test/testgles2_sdf.c index 3b15f72..2d6427b 100644 --- a/test/testgles2_sdf.c +++ b/test/testgles2_sdf.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -325,7 +325,7 @@ int done; Uint32 frames; shader_data *datas; -void loop() +void loop(void) { SDL_Event event; int i; diff --git a/test/testhotplug.c b/test/testhotplug.c index aca1741..57706a7 100644 --- a/test/testhotplug.c +++ b/test/testhotplug.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testiconv.c b/test/testiconv.c index fcdd728..7c27d58 100644 --- a/test/testiconv.c +++ b/test/testiconv.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testime.c b/test/testime.c index fb5756d..8dcd6bb 100644 --- a/test/testime.c +++ b/test/testime.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -333,7 +333,7 @@ static Sint32 unifont_draw_glyph(Uint32 codepoint, int rendererID, SDL_Rect *dst return unifontGlyph[codepoint].width; } -static void unifont_cleanup() +static void unifont_cleanup(void) { int i, j; for (i = 0; i < state->num_windows; ++i) { @@ -425,12 +425,12 @@ Uint32 utf8_decode(char *p, size_t len) return codepoint; } -void usage() +void usage(void) { SDL_Log("usage: testime [--font fontfile]\n"); } -void InitInput() +void InitInput(void) { /* Prepare a rect for text input */ textRect.x = textRect.y = 100; @@ -444,7 +444,7 @@ void InitInput() SDL_StartTextInput(); } -void CleanupVideo() +void CleanupVideo(void) { SDL_StopTextInput(); #ifdef HAVE_SDL_TTF @@ -597,7 +597,7 @@ void _Redraw(int rendererID) SDL_SetTextInputRect(&markedRect); } -void Redraw() +void Redraw(void) { int i; for (i = 0; i < state->num_windows; ++i) { diff --git a/test/testintersections.c b/test/testintersections.c index bb95fbe..b3a91f7 100644 --- a/test/testintersections.c +++ b/test/testintersections.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -208,7 +208,7 @@ DrawRectRectIntersections(SDL_Renderer *renderer) } } -void loop() +void loop(void) { int i; SDL_Event event; diff --git a/test/testjoystick.c b/test/testjoystick.c index 3898580..f9d445d 100644 --- a/test/testjoystick.c +++ b/test/testjoystick.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testkeys.c b/test/testkeys.c index c7b120b..23c375f 100644 --- a/test/testkeys.c +++ b/test/testkeys.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testloadso.c b/test/testloadso.c index fa6923b..a7d1970 100644 --- a/test/testloadso.c +++ b/test/testloadso.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testlocale.c b/test/testlocale.c index 6e371ca..5d19bf4 100644 --- a/test/testlocale.c +++ b/test/testlocale.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testlock.c b/test/testlock.c index 1af8846..1a3c2e9 100644 --- a/test/testlock.c +++ b/test/testlock.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testmessage.c b/test/testmessage.c index d3de67e..2bf9009 100644 --- a/test/testmessage.c +++ b/test/testmessage.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testmouse.c b/test/testmouse.c index 0583ead..4f50034 100644 --- a/test/testmouse.c +++ b/test/testmouse.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testmultiaudio.c b/test/testmultiaudio.c index 5939420..1b09d95 100644 --- a/test/testmultiaudio.c +++ b/test/testmultiaudio.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -53,7 +53,7 @@ play_through_once(void *arg, Uint8 *stream, int len) } } -void loop() +void loop(void) { if (SDL_AtomicGet(&cbd[0].done)) { #ifdef __EMSCRIPTEN__ diff --git a/test/testnative.c b/test/testnative.c index ad47e4a..64abd4a 100644 --- a/test/testnative.c +++ b/test/testnative.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testnative.h b/test/testnative.h index e264390..516c835 100644 --- a/test/testnative.h +++ b/test/testnative.h @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testnativeos2.c b/test/testnativeos2.c index bbdbe90..cf36291 100644 --- a/test/testnativeos2.c +++ b/test/testnativeos2.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testnativew32.c b/test/testnativew32.c index dfd0b63..83ffd9a 100644 --- a/test/testnativew32.c +++ b/test/testnativew32.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testnativex11.c b/test/testnativex11.c index a891f46..086ce63 100644 --- a/test/testnativex11.c +++ b/test/testnativex11.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testoffscreen.c b/test/testoffscreen.c index 09ef7fc..059a267 100644 --- a/test/testoffscreen.c +++ b/test/testoffscreen.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -32,7 +32,7 @@ static int width = 640; static int height = 480; static unsigned int max_frames = 200; -void draw() +void draw(void) { SDL_Rect Rect; @@ -50,7 +50,7 @@ void draw() SDL_RenderPresent(renderer); } -void save_surface_to_bmp() +void save_surface_to_bmp(void) { SDL_Surface *surface; Uint32 r_mask, g_mask, b_mask, a_mask; @@ -71,7 +71,7 @@ void save_surface_to_bmp() SDL_FreeSurface(surface); } -void loop() +void loop(void) { SDL_Event event; diff --git a/test/testoverlay2.c b/test/testoverlay2.c index ccfa8e5..d8d2e50 100644 --- a/test/testoverlay2.c +++ b/test/testoverlay2.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -178,7 +178,7 @@ PrintUsage(char *argv0) SDL_Log("\n"); } -void loop() +void loop(void) { SDL_Event event; diff --git a/test/testplatform.c b/test/testplatform.c index 353758a..543f640 100644 --- a/test/testplatform.c +++ b/test/testplatform.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testpower.c b/test/testpower.c index 1c13b4d..31795a7 100644 --- a/test/testpower.c +++ b/test/testpower.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testqsort.c b/test/testqsort.c index 9c1f764..65666d5 100644 --- a/test/testqsort.c +++ b/test/testqsort.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testrelative.c b/test/testrelative.c index 3f777cd..c0c7099 100644 --- a/test/testrelative.c +++ b/test/testrelative.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -35,7 +35,7 @@ DrawRects(SDL_Renderer *renderer) } static void -loop() +loop(void) { /* Check for events */ while (SDL_PollEvent(&event)) { diff --git a/test/testrendercopyex.c b/test/testrendercopyex.c index 832101a..6ecc31e 100644 --- a/test/testrendercopyex.c +++ b/test/testrendercopyex.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -87,7 +87,7 @@ void Draw(DrawState *s) /* SDL_Delay(10); */ } -void loop() +void loop(void) { int i; SDL_Event event; diff --git a/test/testrendertarget.c b/test/testrendertarget.c index 9693df4..7e62b5b 100644 --- a/test/testrendertarget.c +++ b/test/testrendertarget.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -173,7 +173,7 @@ Draw(DrawState *s) return SDL_TRUE; } -void loop() +void loop(void) { int i; SDL_Event event; diff --git a/test/testresample.c b/test/testresample.c index 21ff8e1..e1608a3 100644 --- a/test/testresample.c +++ b/test/testresample.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testrumble.c b/test/testrumble.c index 401b760..29c0ae2 100644 --- a/test/testrumble.c +++ b/test/testrumble.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testscale.c b/test/testscale.c index 3659c91..f98d4d9 100644 --- a/test/testscale.c +++ b/test/testscale.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -78,7 +78,7 @@ void Draw(DrawState *s) SDL_RenderPresent(s->renderer); } -void loop() +void loop(void) { int i; SDL_Event event; diff --git a/test/testsem.c b/test/testsem.c index 5740833..5afa79c 100644 --- a/test/testsem.c +++ b/test/testsem.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testsensor.c b/test/testsensor.c index 2b9af58..d3523d8 100644 --- a/test/testsensor.c +++ b/test/testsensor.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testshader.c b/test/testshader.c index 48535dc..f930071 100644 --- a/test/testshader.c +++ b/test/testshader.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -11,6 +11,7 @@ */ /* This is a simple example of using GLSL shaders with SDL */ +#include #include "SDL.h" #ifdef HAVE_OPENGL @@ -228,7 +229,7 @@ static void DestroyShaderProgram(ShaderData *data) } } -static SDL_bool InitShaders() +static SDL_bool InitShaders(void) { int i; @@ -282,7 +283,7 @@ static SDL_bool InitShaders() return SDL_TRUE; } -static void QuitShaders() +static void QuitShaders(void) { int i; diff --git a/test/testshape.c b/test/testshape.c index 112ec0c..3a84d21 100644 --- a/test/testshape.c +++ b/test/testshape.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testsprite2.c b/test/testsprite2.c index 71b5656..204c08b 100644 --- a/test/testsprite2.c +++ b/test/testsprite2.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -392,7 +392,7 @@ void MoveSprites(SDL_Renderer *renderer, SDL_Texture *sprite) SDL_RenderPresent(renderer); } -static void MoveAllSprites() +static void MoveAllSprites(void) { int i; @@ -404,7 +404,7 @@ static void MoveAllSprites() } } -void loop() +void loop(void) { Uint32 now; SDL_Event event; diff --git a/test/testspriteminimal.c b/test/testspriteminimal.c index b81101e..faa2dc8 100644 --- a/test/testspriteminimal.c +++ b/test/testspriteminimal.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -43,7 +43,7 @@ quit(int rc) exit(rc); } -void MoveSprites() +void MoveSprites(void) { int i; int window_w = WINDOW_WIDTH; @@ -77,7 +77,7 @@ void MoveSprites() SDL_RenderPresent(renderer); } -void loop() +void loop(void) { SDL_Event event; diff --git a/test/teststreaming.c b/test/teststreaming.c index 45202a7..65686c9 100644 --- a/test/teststreaming.c +++ b/test/teststreaming.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -94,7 +94,7 @@ void UpdateTexture(SDL_Texture *texture) SDL_UnlockTexture(texture); } -void loop() +void loop(void) { SDL_Event event; diff --git a/test/testsurround.c b/test/testsurround.c index b7dc7d7..9f439df 100644 --- a/test/testsurround.c +++ b/test/testsurround.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testthread.c b/test/testthread.c index 5ceac05..9cf3459 100644 --- a/test/testthread.c +++ b/test/testthread.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -19,7 +19,8 @@ #include "SDL.h" static SDL_TLSID tls; -static int alive = 0; +static SDL_Thread *thread = NULL; +static SDL_atomic_t alive; static int testprio = 0; /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ @@ -55,7 +56,7 @@ ThreadFunc(void *data) SDL_TLSSet(tls, "baby thread", NULL); SDL_Log("Started thread %s: My thread id is %lu, thread data = %s\n", (char *)data, SDL_ThreadID(), (const char *)SDL_TLSGet(tls)); - while (alive) { + while (SDL_AtomicGet(&alive)) { SDL_Log("Thread '%s' is alive!\n", (char *)data); if (testprio) { @@ -76,14 +77,14 @@ killed(int sig) { SDL_Log("Killed with SIGTERM, waiting 5 seconds to exit\n"); SDL_Delay(5 * 1000); - alive = 0; + SDL_AtomicSet(&alive, 0); + SDL_WaitThread(thread, NULL); quit(0); } int main(int argc, char *argv[]) { int arg = 1; - SDL_Thread *thread; /* Enable standard application logging */ SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); @@ -112,7 +113,7 @@ int main(int argc, char *argv[]) SDL_TLSSet(tls, "main thread", NULL); SDL_Log("Main thread data initially: %s\n", (const char *)SDL_TLSGet(tls)); - alive = 1; + SDL_AtomicSet(&alive, 1); thread = SDL_CreateThread(ThreadFunc, "One", "#1"); if (!thread) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create thread: %s\n", SDL_GetError()); @@ -120,12 +121,12 @@ int main(int argc, char *argv[]) } SDL_Delay(5 * 1000); SDL_Log("Waiting for thread #1\n"); - alive = 0; + SDL_AtomicSet(&alive, 0); SDL_WaitThread(thread, NULL); SDL_Log("Main thread data finally: %s\n", (const char *)SDL_TLSGet(tls)); - alive = 1; + SDL_AtomicSet(&alive, 1); (void)signal(SIGTERM, killed); thread = SDL_CreateThread(ThreadFunc, "Two", "#2"); if (!thread) { diff --git a/test/testtimer.c b/test/testtimer.c index eea9730..57deffc 100644 --- a/test/testtimer.c +++ b/test/testtimer.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testurl.c b/test/testurl.c index 2008186..6791557 100644 --- a/test/testurl.c +++ b/test/testurl.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testutils.c b/test/testutils.c index 3b76ea8..ed8b7d7 100644 --- a/test/testutils.c +++ b/test/testutils.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga Copyright 2022 Collabora Ltd. This software is provided 'as-is', without any express or implied diff --git a/test/testutils.h b/test/testutils.h index a10aaad..ee32b0b 100644 --- a/test/testutils.h +++ b/test/testutils.h @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga Copyright 2022 Collabora Ltd. This software is provided 'as-is', without any express or implied diff --git a/test/testver.c b/test/testver.c index 409b1f1..740941c 100644 --- a/test/testver.c +++ b/test/testver.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testviewport.c b/test/testviewport.c index ee76a37..83fa2b0 100644 --- a/test/testviewport.c +++ b/test/testviewport.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -95,7 +95,7 @@ void DrawOnViewport(SDL_Renderer *renderer) SDL_RenderSetClipRect(renderer, NULL); } -void loop() +void loop(void) { SDL_Event event; int i; diff --git a/test/testvulkan.c b/test/testvulkan.c index 8a4ac89..ad09f82 100644 --- a/test/testvulkan.c +++ b/test/testvulkan.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testwm2.c b/test/testwm2.c index 5236a7f..faa97a3 100644 --- a/test/testwm2.c +++ b/test/testwm2.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -143,7 +143,7 @@ draw_modes_menu(SDL_Window *window, SDL_Renderer *renderer, SDL_Rect viewport) } } -void loop() +void loop(void) { int i; SDL_Event event; diff --git a/test/testyuv.c b/test/testyuv.c index e9038ed..20708de 100644 --- a/test/testyuv.c +++ b/test/testyuv.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testyuv_cvt.c b/test/testyuv_cvt.c index d78e5b1..9857627 100644 --- a/test/testyuv_cvt.c +++ b/test/testyuv_cvt.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/testyuv_cvt.h b/test/testyuv_cvt.h index fa736be..6565e52 100644 --- a/test/testyuv_cvt.h +++ b/test/testyuv_cvt.h @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/test/torturethread.c b/test/torturethread.c index b612cda..3b0737c 100644 --- a/test/torturethread.c +++ b/test/torturethread.c @@ -1,5 +1,5 @@ /* - Copyright (C) 1997-2024 Sam Lantinga + Copyright (C) 1997-2025 Sam Lantinga This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -34,8 +34,9 @@ quit(int rc) int SDLCALL SubThreadFunc(void *data) { - while (!*(int volatile *)data) { - ; /* SDL_Delay(10); */ /* do nothing */ + SDL_atomic_t *flag = (SDL_atomic_t *)data; + while (!SDL_AtomicGet(flag)) { + SDL_Delay(10); } return 0; } @@ -44,7 +45,7 @@ int SDLCALL ThreadFunc(void *data) { SDL_Thread *sub_threads[NUMTHREADS]; - int flags[NUMTHREADS]; + SDL_atomic_t flags[NUMTHREADS]; int i; int tid = (int)(uintptr_t)data; @@ -53,7 +54,7 @@ ThreadFunc(void *data) for (i = 0; i < NUMTHREADS; i++) { char name[64]; (void)SDL_snprintf(name, sizeof(name), "Child%d_%d", tid, i); - flags[i] = 0; + SDL_AtomicSet(&flags[i], 0); sub_threads[i] = SDL_CreateThread(SubThreadFunc, name, &flags[i]); } @@ -64,7 +65,7 @@ ThreadFunc(void *data) SDL_Log("Thread '%d' sending signals to subthreads\n", tid); for (i = 0; i < NUMTHREADS; i++) { - flags[i] = 1; + SDL_AtomicSet(&flags[i], 1); SDL_WaitThread(sub_threads[i], NULL); } diff --git a/test/watcom.mif b/test/watcom.mif index b81dad8..aa15f66 100644 --- a/test/watcom.mif +++ b/test/watcom.mif @@ -108,14 +108,14 @@ testutils.lib: testutils.obj check: .SYMBOLIC $(TESTS) @set SDL_AUDIODRIVER=dummy @set SDL_VIDEODRIVER=dummy - @copy "../SDL2.dll" . + @copy ..\SDL2.dll . @for %exe in ($(TESTS)) do %exe check-quick: .SYMBOLIC $(TESTS) @set SDL_TESTS_QUICK=1 @set SDL_AUDIODRIVER=dummy @set SDL_VIDEODRIVER=dummy - @copy "../SDL2.dll" . + @copy ..\SDL2.dll . @for %exe in ($(TESTS)) do %exe clean: .SYMBOLIC diff --git a/visualtest/COPYING.txt b/visualtest/COPYING.txt new file mode 100644 index 0000000..6a3adc9 --- /dev/null +++ b/visualtest/COPYING.txt @@ -0,0 +1,18 @@ +Visual and Interactive Test Automation for SDL 2.0 +Copyright (C) 2013 Apoorv Upreti + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. diff --git a/visualtest/Makefile.in b/visualtest/Makefile.in new file mode 100644 index 0000000..3cf2f6d --- /dev/null +++ b/visualtest/Makefile.in @@ -0,0 +1,44 @@ +# Makefile to build the SDL tests + +srcdir = @srcdir@ +CC = @CC@ +EXE = @EXE@ +CFLAGS = @CFLAGS@ -I../include -I./include +LIBS = @LIBS@ + +TARGETS = \ + testharness$(EXE) \ + testquit$(EXE) + +all: Makefile $(TARGETS) + +Makefile: $(srcdir)/Makefile.in + $(SHELL) config.status $@ + +testharness$(EXE): $(srcdir)/src/action_configparser.c \ + $(srcdir)/src/harness_argparser.c \ + $(srcdir)/src/rwhelper.c \ + $(srcdir)/src/testharness.c \ + $(srcdir)/src/variator_exhaustive.c \ + $(srcdir)/src/variators.c \ + $(srcdir)/src/screenshot.c \ + $(srcdir)/src/harness_argparser.c \ + $(srcdir)/src/sut_configparser.c \ + $(srcdir)/src/variator_common.c \ + $(srcdir)/src/variator_random.c \ + $(srcdir)/src/parsehelper.c \ + $(srcdir)/src/mischelper.c \ + $(srcdir)/src/linux/linux_process.c \ + $(srcdir)/src/windows/windows_process.c \ + $(srcdir)/src/windows/windows_screenshot.c + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + +testquit$(EXE): $(srcdir)/unittest/testquit.c + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + +clean: + rm -f $(TARGETS) +distclean: clean + rm -f Makefile + rm -f config.status config.cache config.log + rm -rf $(srcdir)/autom4te* diff --git a/visualtest/README.txt b/visualtest/README.txt new file mode 100644 index 0000000..0d9a905 --- /dev/null +++ b/visualtest/README.txt @@ -0,0 +1,214 @@ +/*! + +\mainpage Visual and Interactive Test Automation for SDL 2.0 + +\section license_sec License +Check the file \c LICENSE.txt for licensing information. + +\section intro_sec Introduction +The goal of this GSoC project is to automate the testing of testsprite2. +testsprite2 takes 26 parameters which have thousands of valid combinations and is +used to validate SDL's window, mouse and rendering behaviour. By having a test +harness that runs testsprite2 with various command line argument strings and +validates the output for each run, we can make testing an easier task for +maintainers, contributors and testers. The test harness can be used by a continuous +integration system (like buildbot or jenkins) to validate SDL after checkins. + +SDL Homepage: http://libsdl.org/ + +\section build_sec Building + +\subsection build_linux Building on Linux/Cygwin +./autogen.sh; ./configure; make; + +\subsection build_windows Building on Windows +Use the Visual Studio solution under \c SDL/VisualC/visualtest. + +\section docs_sec Documentation +Documentation is available via Doxygen. To build the documentation, cd to the +SDL/visualtest/docs directory and run \c doxygen. A good starting point for +exploring the documentation is \c SDL/visualtest/docs/html/index.html + +\section usage_sec Usage +To see all the options supported by the test harness, just run \c testharness +with no arguments. + +At the moment the following options are supported: +\li \c sutapp - Path to the system under test (SUT) application +\li \c sutargs - Launch the SUT with the specified arguments string +\li \c timeout - The maximum time after which the SUT process will be killed; + passed as hh:mm:ss; default 00:01:00 +\li \c variator - Which variator to use; see \ref variators_sec +\li \c num-variations - The number of variations to run for; taken to be + 1 for the random variator and ALL for the exhaustive variator by default +\li \c no-launch - Just print the arguments string for each variation without + launching the SUT or performing any actions +\li \c parameter-config - A config file that describes the command line parameters + supported by the SUT; see \ref paramconfig_sec or the sample *.parameters files + for more details +\li \c action-config - A config file with a list of actions to be performed while + the SUT is running; see \ref actionconfig_sec or the sample *.actions files +\li \c output-dir - Path to the directory where screenshots should be saved; is + created if it doesn't exist; taken to be "./output" by default +\li \c verify-dir - Path to the directory with the verification images; taken to + be "./verify" by default + +Paths can be relative or absolute. + +Alternatively, the options can be passed as a config file for convenience: + +testharness \-\-config testsprite2_sample.config + +For a sample, take a look at the *.config files in this repository. + +We can also pass a config file and override certain options as necessary: +testharness \-\-config testsprite2_sample.config \-\-num-variations 10 + +Note: You may find it convenient to copy the SUT executable along with any +resources to the test harness directory. Also note that testsprite2 and its +resources (icon.bmp) are automatically copied when using the Visual Studio +solution. + +\subsection usageexamples_subsec Usage examples: + +Passing a custom arguments string: +testharness \-\-sutapp testsprite2 \-\-sutargs "\-\-cyclecolor \-\-blend mod +\-\-iterations 2" \-\-action-config xyz.actions + +Using the random variator: +testharness \-\-sutapp testsprite2 \-\-variator random \-\-num-variations 5 +\-\-parameter-config xyz.parameters \-\-action-config xyz.actions + +\subsection config_subsec Config Files +Config files are an alternate way to pass parameters to the test harness. We +describe the paramters in a config file and pass that to the test harness using +the \-\-config option. The config file consists of lines of the form "x=y" where +x is an option and y is it's value. For boolean options, we simply give the name +of the option to indicate that it is to be passed to the testharness. + +The hash '#' character can be used to start a comment from that point to the end +of the line. + +\section paramconfig_sec The SUT Parameters File +To generate variations we need to describe the parameters the will be passed to +the SUT. This description is given in a parameters file. Each line of the parameters +file (except the blank lines) represents one command line option with five +comma separated fields: +name, type, values, required, categories + +\li \c name is the name of the option, e.g., \c \-\-cyclecolor. +\li \c type can have one of three values - integer, boolean and enum. +\li \c values - for integer options this is the valid range of values the option + can take, i.e., [min max]. For enum options this is a list of strings that + the option can take, e.g., [val1 val2 val3]. For boolean options this field + is ignored. +\li \c required - true if the option is required, false otherwise. +\li \c categories - a list of categories that the option belongs to. For example, + [video mouse audio] + +Just like with config files, hash characters can be used to start comments. + +\subsection additionalnotes_subsec Additional Notes + +\li If you want to have an option that always takes a certain value, use an enum + with only one value. +\li Currently there isn't any way to turn an option off, i.e., all options will + be included in the command line options string that is generated using the + config. If you don't want an option to be passed to the SUT, remove it from + the config file or comment it out. + +\section variators_sec Variators +Variators are the mechanism by which we generate strings of command line arguments +to test the SUT with. A variator is quite simply an iterator that iterates through +different variations of command line options. There are two variators supported at +the moment: +\li \b Exhaustive - Generate all possible combinations of command line arguments + that are valid. +\li \b Random - Generate a random variation each time the variator is called. + +As an example, let's try a simple .parameters file:\n + +\-\-blend, enum, [add mod], false, [] \n +\-\-fullscreen, boolean, [], false, [] + + +The exhaustive variator would generate the following four variations:\n + +\-\-blend add \n +\-\-blend mod \n +\-\-blend add \-\-fullscreen \n +\-\-blend mod \-\-fullscreen \n + + +The random variator would simply generate a random variation like the following:\n +\-\-blend mod + +\section actionconfig_sec The Actions File +Once the SUT process has been launched, automated testing happens using a mechanism +called actions. A list of actions is read from a file and each action is performed +on the SUT process sequentially. Each line in the actions file describes an action. +The format for an action is hh:mm:ss ACTION_NAME additional parameters. +There are five actions supported at the moment: +\li \b SCREENSHOT - Takes a screenshot of each window owned by the SUT process. The + images are saved as \c [hash]_[i].bmp where \c [hash] is the 32 character long + hexadecimal MD5 hash of the arguments string that was passed to the SUT while + launching it and \c i is the window number. i = 1 is an exceptional case + where the \c _[i] is dropped and the filename is simply \c [hash].bmp\n + Note: The screenshots are only of the window's client area. +\li \b VERIFY - Verifies the screenshots taken by the last SCREENSHOT action by + comparing them against a verification image. Each \c [hash]_i.bmp image output + by the SCREENSHOT action is compared against a \c [hash].bmp image in the + verify-dir. +\li \b QUIT - Gracefully quits the SUT process. On Windows this means sending a + WM_CLOSE message to each window owned by the SUT process. On Linux it means + sending a SIGQUIT signal to the SUT process. +\li \b KILL - Forcefully kills the SUT process. This is useful when the SUT process + doesn't respond to the QUIT action. +\li LAUNCH [/path/to/executable] [args] - Runs an executable with \c [args] + as the arguments string. + +Just like with config files, hash characters can be used to start comments. + +\section contint_sec Continuous Integration (CI) +One of the goals of the project was to create a test harness that integrates +with CI systems to provide automated visual and interactive testing to SDL. + +At the moment the test harness can be run in two modes that are useful for CI: +\li Crash testing mode - launch the SUT with every variation and all parameters, + report to the CI if there's a crash +\li Visual testing mode - launch and visually verify the SUT for a smaller subset + of the parameters + +Look at the launch_harness.sh/launch_harness.cmd for an example scripts that run the +test harness for all variations with all parameters and report an error on a crash. +The script uses the testsprite2_crashtest config, so remember to copy those files +over to the test harness executable directory along with the script. + +\section todo_sec TODOs +\li Allow specifying a clipping box along with the VERIFY action, i.e., hh:mm:ss + VERIFY x, y, w, h +\li Add support for spaces between the equals sign in test harness config files +\li Implement the SCREENSHOT action on Linux +\li Add a pairwise variator +\li Add actions to inject keyboard/mouse events +\li Add actions to manipulate the SUT window, e.g., minimize, restore, resize +\li Add support to load and save screenshots as .pngs instead of .bmps + +\section issues_sec Known Issues +\li The QUIT action does not work on a testsprite2 process with multiple windows. + This appears to be an issue with testsprite2. +\li The SCREENSHOT action doesn't capture the testsprite2 window correctly if the + --fullscreen option is supplied. It works with --fullscreen-desktop, however. + +\section moreinfo_sec More Information + +Author Contact Info:\n +Apoorv Upreti \c \ + +Other useful links: +- Project Repository: https://bitbucket.org/nerdap/sdlvisualtest +- Project Wiki: https://github.com/nerdap/autotestsprite2/wiki +- Project Blog: http://nerdap.github.io +- Verification images for testsprite2_blendmodes: https://www.dropbox.com/s/nm02aem76m812ng/testsprite2_blendmodes.zip +- Verification images for testsprite2_geometry: https://www.dropbox.com/s/csypwryopaslpaf/testsprite2_geometry.zip +*/ diff --git a/visualtest/acinclude.m4 b/visualtest/acinclude.m4 new file mode 100644 index 0000000..0fdf353 --- /dev/null +++ b/visualtest/acinclude.m4 @@ -0,0 +1,337 @@ +# Configure paths for SDL +# Sam Lantinga 9/21/99 +# stolen from Manish Singh +# stolen back from Frank Belew +# stolen from Manish Singh +# Shamelessly stolen from Owen Taylor + +# serial 2 + +dnl AM_PATH_SDL2([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) +dnl Test for SDL, and define SDL_CFLAGS and SDL_LIBS +dnl +AC_DEFUN([AM_PATH_SDL2], +[dnl +dnl Get the cflags and libraries from the sdl2-config script +dnl +AC_ARG_WITH(sdl-prefix,[ --with-sdl-prefix=PFX Prefix where SDL is installed (optional)], + sdl_prefix="$withval", sdl_prefix="") +AC_ARG_WITH(sdl-exec-prefix,[ --with-sdl-exec-prefix=PFX Exec prefix where SDL is installed (optional)], + sdl_exec_prefix="$withval", sdl_exec_prefix="") +AC_ARG_ENABLE(sdltest, [ --disable-sdltest Do not try to compile and run a test SDL program], + , enable_sdltest=yes) + + min_sdl_version=ifelse([$1], ,2.0.0,$1) + + if test "x$sdl_prefix$sdl_exec_prefix" = x ; then + PKG_CHECK_MODULES([SDL], [sdl2 >= $min_sdl_version], + [sdl_pc=yes], + [sdl_pc=no]) + else + sdl_pc=no + if test x$sdl_exec_prefix != x ; then + sdl_config_args="$sdl_config_args --exec-prefix=$sdl_exec_prefix" + if test x${SDL2_CONFIG+set} != xset ; then + SDL2_CONFIG=$sdl_exec_prefix/bin/sdl2-config + fi + fi + if test x$sdl_prefix != x ; then + sdl_config_args="$sdl_config_args --prefix=$sdl_prefix" + if test x${SDL2_CONFIG+set} != xset ; then + SDL2_CONFIG=$sdl_prefix/bin/sdl2-config + fi + fi + fi + + if test "x$sdl_pc" = xyes ; then + no_sdl="" + SDL2_CONFIG="pkg-config sdl2" + else + as_save_PATH="$PATH" + if test "x$prefix" != xNONE && test "$cross_compiling" != yes; then + PATH="$prefix/bin:$prefix/usr/bin:$PATH" + fi + AC_PATH_PROG(SDL2_CONFIG, sdl2-config, no, [$PATH]) + PATH="$as_save_PATH" + AC_MSG_CHECKING(for SDL - version >= $min_sdl_version) + no_sdl="" + + if test "$SDL2_CONFIG" = "no" ; then + no_sdl=yes + else + SDL_CFLAGS=`$SDL2_CONFIG $sdl_config_args --cflags` + SDL_LIBS=`$SDL2_CONFIG $sdl_config_args --libs` + + sdl_major_version=`$SDL2_CONFIG $sdl_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + sdl_minor_version=`$SDL2_CONFIG $sdl_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + sdl_micro_version=`$SDL2_CONFIG $sdl_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + if test "x$enable_sdltest" = "xyes" ; then + ac_save_CFLAGS="$CFLAGS" + ac_save_CXXFLAGS="$CXXFLAGS" + ac_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $SDL_CFLAGS" + CXXFLAGS="$CXXFLAGS $SDL_CFLAGS" + LIBS="$LIBS $SDL_LIBS" +dnl +dnl Now check if the installed SDL is sufficiently new. (Also sanity +dnl checks the results of sdl2-config to some extent +dnl + rm -f conf.sdltest + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include +#include +#include "SDL.h" + +int main (int argc, char *argv[]) +{ + int major, minor, micro; + FILE *fp = fopen("conf.sdltest", "w"); + + if (fp) fclose(fp); + + if (sscanf("$min_sdl_version", "%d.%d.%d", &major, &minor, µ) != 3) { + printf("%s, bad version string\n", "$min_sdl_version"); + exit(1); + } + + if (($sdl_major_version > major) || + (($sdl_major_version == major) && ($sdl_minor_version > minor)) || + (($sdl_major_version == major) && ($sdl_minor_version == minor) && ($sdl_micro_version >= micro))) + { + return 0; + } + else + { + printf("\n*** 'sdl2-config --version' returned %d.%d.%d, but the minimum version\n", $sdl_major_version, $sdl_minor_version, $sdl_micro_version); + printf("*** of SDL required is %d.%d.%d. If sdl2-config is correct, then it is\n", major, minor, micro); + printf("*** best to upgrade to the required version.\n"); + printf("*** If sdl2-config was wrong, set the environment variable SDL2_CONFIG\n"); + printf("*** to point to the correct copy of sdl2-config, and remove the file\n"); + printf("*** config.cache before re-running configure\n"); + return 1; + } +} + +]])], [], [no_sdl=yes], [echo $ac_n "cross compiling; assumed OK... $ac_c"]) + CFLAGS="$ac_save_CFLAGS" + CXXFLAGS="$ac_save_CXXFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + if test "x$no_sdl" = x ; then + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + fi + if test "x$no_sdl" = x ; then + ifelse([$2], , :, [$2]) + else + if test "$SDL2_CONFIG" = "no" ; then + echo "*** The sdl2-config script installed by SDL could not be found" + echo "*** If SDL was installed in PREFIX, make sure PREFIX/bin is in" + echo "*** your path, or set the SDL2_CONFIG environment variable to the" + echo "*** full path to sdl2-config." + else + if test -f conf.sdltest ; then + : + else + echo "*** Could not run SDL test program, checking why..." + CFLAGS="$CFLAGS $SDL_CFLAGS" + CXXFLAGS="$CXXFLAGS $SDL_CFLAGS" + LIBS="$LIBS $SDL_LIBS" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include +#include "SDL.h" + +int main(int argc, char *argv[]) +{ return 0; } +#undef main +#define main K_and_R_C_main +]], [[ return 0; ]])], + [ echo "*** The test program compiled, but did not run. This usually means" + echo "*** that the run-time linker is not finding SDL or finding the wrong" + echo "*** version of SDL. If it is not finding SDL, you'll need to set your" + echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" + echo "*** to the installed location Also, make sure you have run ldconfig if that" + echo "*** is required on your system" + echo "***" + echo "*** If you have an old version installed, it is best to remove it, although" + echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"], + [ echo "*** The test program failed to compile or link. See the file config.log for the" + echo "*** exact error that occured. This usually means SDL was incorrectly installed" + echo "*** or that you have moved SDL since it was installed. In the latter case, you" + echo "*** may want to edit the sdl2-config script: $SDL2_CONFIG" ]) + CFLAGS="$ac_save_CFLAGS" + CXXFLAGS="$ac_save_CXXFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + SDL_CFLAGS="" + SDL_LIBS="" + ifelse([$3], , :, [$3]) + fi + AC_SUBST(SDL_CFLAGS) + AC_SUBST(SDL_LIBS) + rm -f conf.sdltest +]) +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# serial 1 (pkg-config-0.24) +# +# Copyright © 2004 Scott James Remnant . +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# PKG_PROG_PKG_CONFIG([MIN-VERSION]) +# ---------------------------------- +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_PATH|_LIBDIR)?$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) +AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) +AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi +fi[]dnl +])# PKG_PROG_PKG_CONFIG + +# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# +# Check to see whether a particular set of modules exists. Similar +# to PKG_CHECK_MODULES(), but does not set variables or print errors. +# +# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +# only at the first occurence in configure.ac, so if the first place +# it's called might be skipped (such as if it is within an "if", you +# have to call PKG_CHECK_EXISTS manually +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_default([$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + +# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +# --------------------------------------------- +m4_define([_PKG_CONFIG], +[if test -n "$$1"; then + pkg_cv_[]$1="$$1" + elif test -n "$PKG_CONFIG"; then + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`], + [pkg_failed=yes]) + else + pkg_failed=untried +fi[]dnl +])# _PKG_CONFIG + +# _PKG_SHORT_ERRORS_SUPPORTED +# ----------------------------- +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])# _PKG_SHORT_ERRORS_SUPPORTED + + +# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +# [ACTION-IF-NOT-FOUND]) +# +# +# Note that if there is a possibility the first call to +# PKG_CHECK_MODULES might not happen, you should be sure to include an +# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +# +# +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $2]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) + +if test $pkg_failed = yes; then + AC_MSG_RESULT([no]) + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "$2" 2>&1` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors "$2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + m4_default([$4], [AC_MSG_ERROR( +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT])[]dnl + ]) +elif test $pkg_failed = untried; then + AC_MSG_RESULT([no]) + m4_default([$4], [AC_MSG_FAILURE( +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +_PKG_TEXT + +To get pkg-config, see .])[]dnl + ]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + $3 +fi[]dnl +])# PKG_CHECK_MODULES diff --git a/visualtest/autogen.sh b/visualtest/autogen.sh new file mode 100755 index 0000000..988d417 --- /dev/null +++ b/visualtest/autogen.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +cp acinclude.m4 aclocal.m4 + +if test "$AUTOCONF"x = x; then + AUTOCONF=autoconf +fi + +$AUTOCONF || exit 1 +rm aclocal.m4 +rm -rf autom4te.cache diff --git a/visualtest/configs/testsprite2_blendmodes/testsprite2_blendmodes.actions b/visualtest/configs/testsprite2_blendmodes/testsprite2_blendmodes.actions new file mode 100644 index 0000000..ef54e86 --- /dev/null +++ b/visualtest/configs/testsprite2_blendmodes/testsprite2_blendmodes.actions @@ -0,0 +1,3 @@ +00:00:03 SCREENSHOT +00:00:06 VERIFY +00:00:09 QUIT \ No newline at end of file diff --git a/visualtest/configs/testsprite2_blendmodes/testsprite2_blendmodes.config b/visualtest/configs/testsprite2_blendmodes/testsprite2_blendmodes.config new file mode 100644 index 0000000..0d707bc --- /dev/null +++ b/visualtest/configs/testsprite2_blendmodes/testsprite2_blendmodes.config @@ -0,0 +1,5 @@ +parameter-config=testsprite2_blendmodes.parameters +variator=exhaustive +sutapp=testsprite2 +timeout=00:00:15 +action-config=testsprite2_blendmodes.actions \ No newline at end of file diff --git a/visualtest/configs/testsprite2_blendmodes/testsprite2_blendmodes.parameters b/visualtest/configs/testsprite2_blendmodes/testsprite2_blendmodes.parameters new file mode 100644 index 0000000..a5df29c --- /dev/null +++ b/visualtest/configs/testsprite2_blendmodes/testsprite2_blendmodes.parameters @@ -0,0 +1,5 @@ +# parameter name, type, value range, required, categories +--blend, enum, [none blend add mod], false, [] +--cyclecolor, boolean, [], false, [] +--cyclealpha, boolean, [], false, [] +--iterations, integer, [1000 1000], true, [] \ No newline at end of file diff --git a/visualtest/configs/testsprite2_crashtest/testsprite2_crashtest.actions b/visualtest/configs/testsprite2_crashtest/testsprite2_crashtest.actions new file mode 100644 index 0000000..75af9d7 --- /dev/null +++ b/visualtest/configs/testsprite2_crashtest/testsprite2_crashtest.actions @@ -0,0 +1 @@ +00:00:02 QUIT \ No newline at end of file diff --git a/visualtest/configs/testsprite2_crashtest/testsprite2_crashtest.config b/visualtest/configs/testsprite2_crashtest/testsprite2_crashtest.config new file mode 100644 index 0000000..c8f07ca --- /dev/null +++ b/visualtest/configs/testsprite2_crashtest/testsprite2_crashtest.config @@ -0,0 +1,5 @@ +parameter-config=testsprite2_crashtest.parameters +variator=exhaustive +sutapp=testsprite2 +timeout=00:00:10 +action-config=testsprite2_crashtest.actions \ No newline at end of file diff --git a/visualtest/configs/testsprite2_crashtest/testsprite2_crashtest.parameters b/visualtest/configs/testsprite2_crashtest/testsprite2_crashtest.parameters new file mode 100644 index 0000000..e89ce60 --- /dev/null +++ b/visualtest/configs/testsprite2_crashtest/testsprite2_crashtest.parameters @@ -0,0 +1,24 @@ +# parameter name, type, value range, required, categories +--display, integer, [1 5], false, [] +--fullscreen, boolean, [], false, [] +--fullscreen-desktop, boolean, [], false, [] +--title, enum, [vartest bartest footest], false, [] +--icon, enum, [icon.bmp], false, [] +--center, boolean, [], false, [] +--position, enum, [300,300], false, [] +--geometry, enum, [500x500], false, [] +--min-geometry, enum, [100x100 200x200], false, [] +--max-geometry, enum, [600x600 700x700], false, [] +--logical, enum, [500x500 550x450], false, [] +--scale, integer, [1 5], false, [] +--depth, integer, [1 5], false, [] +--refresh, integer, [1 5], false, [] +--vsync, boolean, [], false, [] +--noframe, boolean, [], false, [] +--resize, boolean, [], false, [] +--minimize, boolean, [], false, [] +--maximize, boolean, [], false, [] +--grab, boolean, [], false, [mouse] +--blend, enum, [none blend add mod], false, [] +--cyclecolor, boolean, [], false, [] +--cyclealpha, boolean, [], false, [] \ No newline at end of file diff --git a/visualtest/configs/testsprite2_fullscreen/testsprite2_fullscreen.actions b/visualtest/configs/testsprite2_fullscreen/testsprite2_fullscreen.actions new file mode 100644 index 0000000..ef54e86 --- /dev/null +++ b/visualtest/configs/testsprite2_fullscreen/testsprite2_fullscreen.actions @@ -0,0 +1,3 @@ +00:00:03 SCREENSHOT +00:00:06 VERIFY +00:00:09 QUIT \ No newline at end of file diff --git a/visualtest/configs/testsprite2_fullscreen/testsprite2_fullscreen.config b/visualtest/configs/testsprite2_fullscreen/testsprite2_fullscreen.config new file mode 100644 index 0000000..361020a --- /dev/null +++ b/visualtest/configs/testsprite2_fullscreen/testsprite2_fullscreen.config @@ -0,0 +1,5 @@ +parameter-config=testsprite2_fullscreen.parameters +variator=exhaustive +sutapp=testsprite2 +timeout=00:00:15 +action-config=testsprite2_fullscreen.actions \ No newline at end of file diff --git a/visualtest/configs/testsprite2_fullscreen/testsprite2_fullscreen.parameters b/visualtest/configs/testsprite2_fullscreen/testsprite2_fullscreen.parameters new file mode 100644 index 0000000..8da1967 --- /dev/null +++ b/visualtest/configs/testsprite2_fullscreen/testsprite2_fullscreen.parameters @@ -0,0 +1,5 @@ +# parameter name, type, value range, required, categories +--blend, enum, [none blend add mod], false, [] +--fullscreen, boolean, [], false, [] +--fullscreen-desktop, boolean, [], false, [] +--iterations, integer, [1000 1000], true, [] \ No newline at end of file diff --git a/visualtest/configs/testsprite2_geometry/testsprite2_geometry.actions b/visualtest/configs/testsprite2_geometry/testsprite2_geometry.actions new file mode 100644 index 0000000..ef54e86 --- /dev/null +++ b/visualtest/configs/testsprite2_geometry/testsprite2_geometry.actions @@ -0,0 +1,3 @@ +00:00:03 SCREENSHOT +00:00:06 VERIFY +00:00:09 QUIT \ No newline at end of file diff --git a/visualtest/configs/testsprite2_geometry/testsprite2_geometry.config b/visualtest/configs/testsprite2_geometry/testsprite2_geometry.config new file mode 100644 index 0000000..f3cda9a --- /dev/null +++ b/visualtest/configs/testsprite2_geometry/testsprite2_geometry.config @@ -0,0 +1,5 @@ +parameter-config=testsprite2_geometry.parameters +variator=exhaustive +sutapp=testsprite2 +timeout=00:00:15 +action-config=testsprite2_geometry.actions \ No newline at end of file diff --git a/visualtest/configs/testsprite2_geometry/testsprite2_geometry.parameters b/visualtest/configs/testsprite2_geometry/testsprite2_geometry.parameters new file mode 100644 index 0000000..c1ac8ef --- /dev/null +++ b/visualtest/configs/testsprite2_geometry/testsprite2_geometry.parameters @@ -0,0 +1,5 @@ +# parameter name, type, value range, required, categories +--geometry, enum, [500x500 600x600], false, [] +--logical, enum, [300x500 550x450], false, [] +--scale, integer, [1 5], false, [] +--iterations, integer, [1000 1000], true, [] \ No newline at end of file diff --git a/visualtest/configure b/visualtest/configure new file mode 100755 index 0000000..ca7c71e --- /dev/null +++ b/visualtest/configure @@ -0,0 +1,4442 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69. +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= +PACKAGE_URL= + +ac_unique_file="unittest/testquit.c" +ac_subst_vars='LTLIBOBJS +LIBOBJS +LIBUNWIND_LIBS +LIBUNWIND_CFLAGS +SDL2_CONFIG +SDL_LIBS +SDL_CFLAGS +PKG_CONFIG_LIBDIR +PKG_CONFIG_PATH +PKG_CONFIG +EXE +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +with_sdl_prefix +with_sdl_exec_prefix +enable_sdltest +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +PKG_CONFIG +PKG_CONFIG_PATH +PKG_CONFIG_LIBDIR +SDL_CFLAGS +SDL_LIBS +LIBUNWIND_CFLAGS +LIBUNWIND_LIBS' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-sdltest Do not try to compile and run a test SDL program + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-sdl-prefix=PFX Prefix where SDL is installed (optional) + --with-sdl-exec-prefix=PFX Exec prefix where SDL is installed (optional) + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + PKG_CONFIG path to pkg-config utility + PKG_CONFIG_PATH + directories to add to pkg-config's search path + PKG_CONFIG_LIBDIR + path overriding pkg-config's built-in search path + SDL_CFLAGS C compiler flags for SDL, overriding pkg-config + SDL_LIBS linker flags for SDL, overriding pkg-config + LIBUNWIND_CFLAGS + C compiler flags for LIBUNWIND, overriding pkg-config + LIBUNWIND_LIBS + linker flags for LIBUNWIND, overriding pkg-config + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to the package provider. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +configure +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + +ac_aux_dir= +for ac_dir in ../build-scripts "$srcdir"/../build-scripts; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in ../build-scripts \"$srcdir\"/../build-scripts" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +case "$host" in + *-*-cygwin* | *-*-mingw*) + EXE=".exe" + EXTRALIB="-lshlwapi" + ;; + *) + EXE="" + EXTRALIB="" + ;; +esac + + +SDL_VERSION=2.0.0 + + + + + + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_PKG_CONFIG"; then + ac_pt_PKG_CONFIG=$PKG_CONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG +if test -n "$ac_pt_PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 +$as_echo "$ac_pt_PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_PKG_CONFIG" = x; then + PKG_CONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKG_CONFIG=$ac_pt_PKG_CONFIG + fi +else + PKG_CONFIG="$ac_cv_path_PKG_CONFIG" +fi + +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=0.9.0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 +$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + PKG_CONFIG="" + fi +fi + + +# Check whether --with-sdl-prefix was given. +if test "${with_sdl_prefix+set}" = set; then : + withval=$with_sdl_prefix; sdl_prefix="$withval" +else + sdl_prefix="" +fi + + +# Check whether --with-sdl-exec-prefix was given. +if test "${with_sdl_exec_prefix+set}" = set; then : + withval=$with_sdl_exec_prefix; sdl_exec_prefix="$withval" +else + sdl_exec_prefix="" +fi + +# Check whether --enable-sdltest was given. +if test "${enable_sdltest+set}" = set; then : + enableval=$enable_sdltest; +else + enable_sdltest=yes +fi + + + min_sdl_version=$SDL_VERSION + + if test "x$sdl_prefix$sdl_exec_prefix" = x ; then + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sdl2 >= $min_sdl_version" >&5 +$as_echo_n "checking for sdl2 >= $min_sdl_version... " >&6; } + +if test -n "$SDL_CFLAGS"; then + pkg_cv_SDL_CFLAGS="$SDL_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sdl2 >= \$min_sdl_version\""; } >&5 + ($PKG_CONFIG --exists --print-errors "sdl2 >= $min_sdl_version") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_SDL_CFLAGS=`$PKG_CONFIG --cflags "sdl2 >= $min_sdl_version" 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$SDL_LIBS"; then + pkg_cv_SDL_LIBS="$SDL_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sdl2 >= \$min_sdl_version\""; } >&5 + ($PKG_CONFIG --exists --print-errors "sdl2 >= $min_sdl_version") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_SDL_LIBS=`$PKG_CONFIG --libs "sdl2 >= $min_sdl_version" 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + SDL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "sdl2 >= $min_sdl_version" 2>&1` + else + SDL_PKG_ERRORS=`$PKG_CONFIG --print-errors "sdl2 >= $min_sdl_version" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$SDL_PKG_ERRORS" >&5 + + sdl_pc=no +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + sdl_pc=no +else + SDL_CFLAGS=$pkg_cv_SDL_CFLAGS + SDL_LIBS=$pkg_cv_SDL_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + sdl_pc=yes +fi + else + sdl_pc=no + if test x$sdl_exec_prefix != x ; then + sdl_config_args="$sdl_config_args --exec-prefix=$sdl_exec_prefix" + if test x${SDL2_CONFIG+set} != xset ; then + SDL2_CONFIG=$sdl_exec_prefix/bin/sdl2-config + fi + fi + if test x$sdl_prefix != x ; then + sdl_config_args="$sdl_config_args --prefix=$sdl_prefix" + if test x${SDL2_CONFIG+set} != xset ; then + SDL2_CONFIG=$sdl_prefix/bin/sdl2-config + fi + fi + fi + + if test "x$sdl_pc" = xyes ; then + no_sdl="" + SDL2_CONFIG="pkg-config sdl2" + else + as_save_PATH="$PATH" + if test "x$prefix" != xNONE && test "$cross_compiling" != yes; then + PATH="$prefix/bin:$prefix/usr/bin:$PATH" + fi + # Extract the first word of "sdl2-config", so it can be a program name with args. +set dummy sdl2-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_SDL2_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $SDL2_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_SDL2_CONFIG="$SDL2_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_SDL2_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_SDL2_CONFIG" && ac_cv_path_SDL2_CONFIG="no" + ;; +esac +fi +SDL2_CONFIG=$ac_cv_path_SDL2_CONFIG +if test -n "$SDL2_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SDL2_CONFIG" >&5 +$as_echo "$SDL2_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + PATH="$as_save_PATH" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SDL - version >= $min_sdl_version" >&5 +$as_echo_n "checking for SDL - version >= $min_sdl_version... " >&6; } + no_sdl="" + + if test "$SDL2_CONFIG" = "no" ; then + no_sdl=yes + else + SDL_CFLAGS=`$SDL2_CONFIG $sdl_config_args --cflags` + SDL_LIBS=`$SDL2_CONFIG $sdl_config_args --libs` + + sdl_major_version=`$SDL2_CONFIG $sdl_config_args --version | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1/'` + sdl_minor_version=`$SDL2_CONFIG $sdl_config_args --version | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\2/'` + sdl_micro_version=`$SDL2_CONFIG $sdl_config_args --version | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3/'` + if test "x$enable_sdltest" = "xyes" ; then + ac_save_CFLAGS="$CFLAGS" + ac_save_CXXFLAGS="$CXXFLAGS" + ac_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $SDL_CFLAGS" + CXXFLAGS="$CXXFLAGS $SDL_CFLAGS" + LIBS="$LIBS $SDL_LIBS" + rm -f conf.sdltest + if test "$cross_compiling" = yes; then : + echo $ac_n "cross compiling; assumed OK... $ac_c" +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include "SDL.h" + +int main (int argc, char *argv[]) +{ + int major, minor, micro; + FILE *fp = fopen("conf.sdltest", "w"); + + if (fp) fclose(fp); + + if (sscanf("$min_sdl_version", "%d.%d.%d", &major, &minor, µ) != 3) { + printf("%s, bad version string\n", "$min_sdl_version"); + exit(1); + } + + if (($sdl_major_version > major) || + (($sdl_major_version == major) && ($sdl_minor_version > minor)) || + (($sdl_major_version == major) && ($sdl_minor_version == minor) && ($sdl_micro_version >= micro))) + { + return 0; + } + else + { + printf("\n*** 'sdl2-config --version' returned %d.%d.%d, but the minimum version\n", $sdl_major_version, $sdl_minor_version, $sdl_micro_version); + printf("*** of SDL required is %d.%d.%d. If sdl2-config is correct, then it is\n", major, minor, micro); + printf("*** best to upgrade to the required version.\n"); + printf("*** If sdl2-config was wrong, set the environment variable SDL2_CONFIG\n"); + printf("*** to point to the correct copy of sdl2-config, and remove the file\n"); + printf("*** config.cache before re-running configure\n"); + return 1; + } +} + + +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + no_sdl=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + CFLAGS="$ac_save_CFLAGS" + CXXFLAGS="$ac_save_CXXFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + if test "x$no_sdl" = x ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + fi + if test "x$no_sdl" = x ; then + : + else + if test "$SDL2_CONFIG" = "no" ; then + echo "*** The sdl2-config script installed by SDL could not be found" + echo "*** If SDL was installed in PREFIX, make sure PREFIX/bin is in" + echo "*** your path, or set the SDL2_CONFIG environment variable to the" + echo "*** full path to sdl2-config." + else + if test -f conf.sdltest ; then + : + else + echo "*** Could not run SDL test program, checking why..." + CFLAGS="$CFLAGS $SDL_CFLAGS" + CXXFLAGS="$CXXFLAGS $SDL_CFLAGS" + LIBS="$LIBS $SDL_LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include "SDL.h" + +int main(int argc, char *argv[]) +{ return 0; } +#undef main +#define main K_and_R_C_main + +int +main () +{ + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + echo "*** The test program compiled, but did not run. This usually means" + echo "*** that the run-time linker is not finding SDL or finding the wrong" + echo "*** version of SDL. If it is not finding SDL, you'll need to set your" + echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" + echo "*** to the installed location Also, make sure you have run ldconfig if that" + echo "*** is required on your system" + echo "***" + echo "*** If you have an old version installed, it is best to remove it, although" + echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" +else + echo "*** The test program failed to compile or link. See the file config.log for the" + echo "*** exact error that occured. This usually means SDL was incorrectly installed" + echo "*** or that you have moved SDL since it was installed. In the latter case, you" + echo "*** may want to edit the sdl2-config script: $SDL2_CONFIG" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + CFLAGS="$ac_save_CFLAGS" + CXXFLAGS="$ac_save_CXXFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + SDL_CFLAGS="" + SDL_LIBS="" + as_fn_error $? "*** SDL version $SDL_VERSION not found!" "$LINENO" 5 + + fi + + + rm -f conf.sdltest + +CFLAGS="$CFLAGS $SDL_CFLAGS" +LIBS="$LIBS -lSDL2_test $SDL_LIBS $EXTRALIB" + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libunwind" >&5 +$as_echo_n "checking for libunwind... " >&6; } + +if test -n "$LIBUNWIND_CFLAGS"; then + pkg_cv_LIBUNWIND_CFLAGS="$LIBUNWIND_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libunwind\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libunwind") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBUNWIND_CFLAGS=`$PKG_CONFIG --cflags "libunwind" 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LIBUNWIND_LIBS"; then + pkg_cv_LIBUNWIND_LIBS="$LIBUNWIND_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libunwind\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libunwind") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBUNWIND_LIBS=`$PKG_CONFIG --libs "libunwind" 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LIBUNWIND_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "libunwind" 2>&1` + else + LIBUNWIND_PKG_ERRORS=`$PKG_CONFIG --print-errors "libunwind" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LIBUNWIND_PKG_ERRORS" >&5 + + have_libunwind=no +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + have_libunwind=no +else + LIBUNWIND_CFLAGS=$pkg_cv_LIBUNWIND_CFLAGS + LIBUNWIND_LIBS=$pkg_cv_LIBUNWIND_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + have_libunwind=yes +fi +if test x$have_libunwind = xyes ; then + LIBS="$LIBS $LIBUNWIND_LIBS" +fi + +ac_config_files="$ac_config_files Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +# +# If the first sed substitution is executed (which looks for macros that +# take arguments), then branch to the quote section. Otherwise, +# look for a macro that doesn't take arguments. +ac_script=' +:mline +/\\$/{ + N + s,\\\n,, + b mline +} +t clear +:clear +s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g +t quote +s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g +t quote +b any +:quote +s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g +s/\[/\\&/g +s/\]/\\&/g +s/\$/$$/g +H +:any +${ + g + s/^\n// + s/\n/ /g + p +} +' +DEFS=`sed -n "$ac_script" confdefs.h` + + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by $as_me, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + +Configuration files: +$config_files + +Report bugs to the package provider." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h | --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + + +eval set X " :F $CONFIG_FILES " +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + + + + esac + +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff --git a/visualtest/configure.ac b/visualtest/configure.ac new file mode 100644 index 0000000..3566bf0 --- /dev/null +++ b/visualtest/configure.ac @@ -0,0 +1,41 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT +AC_CONFIG_SRCDIR([unittest/testquit.c]) + +dnl Detect the canonical build and host environments +AC_CONFIG_AUX_DIR([../build-scripts]) +AC_CANONICAL_HOST + +dnl Check for tools +AC_PROG_CC + +dnl Figure out which math or extra library to use +case "$host" in + *-*-cygwin* | *-*-mingw*) + EXE=".exe" + EXTRALIB="-lshlwapi" + ;; + *) + EXE="" + EXTRALIB="" + ;; +esac +AC_SUBST(EXE) + +dnl Check for SDL +SDL_VERSION=2.0.0 +AM_PATH_SDL2($SDL_VERSION, + :, + AC_MSG_ERROR([*** SDL version $SDL_VERSION not found!]) +) +CFLAGS="$CFLAGS $SDL_CFLAGS" +LIBS="$LIBS -lSDL2_test $SDL_LIBS $EXTRALIB" + +PKG_CHECK_MODULES(LIBUNWIND, libunwind, have_libunwind=yes, have_libunwind=no) +if test x$have_libunwind = xyes ; then + LIBS="$LIBS $LIBUNWIND_LIBS" +fi + +dnl Finally create all the generated files +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/visualtest/docs/Doxyfile b/visualtest/docs/Doxyfile new file mode 100644 index 0000000..08caeb4 --- /dev/null +++ b/visualtest/docs/Doxyfile @@ -0,0 +1,1936 @@ +# Doxyfile 1.8.4 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or sequence of words) that should +# identify the project. Note that if you do not use Doxywizard you need +# to put quotes around the project name if it contains spaces. + +PROJECT_NAME = "SDL Visual Test" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = . + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Latvian, Lithuanian, Norwegian, Macedonian, +# Persian, Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, +# Slovak, Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. Note that you specify absolute paths here, but also +# relative paths, which will be relative from the directory where doxygen is +# started. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding +# "class=itcl::class" will allow you to use the command class in the +# itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, +# and language is one of the parsers supported by doxygen: IDL, Java, +# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, +# C++. For instance to make doxygen treat .inc files as Fortran files (default +# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note +# that for custom extensions you also need to set FILE_PATTERNS otherwise the +# files are not read by doxygen. + +EXTENSION_MAPPING = + +# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all +# comments according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you +# can mix doxygen, HTML, and XML commands with Markdown formatting. +# Disable only in case of backward compatibilities issues. + +MARKDOWN_SUPPORT = YES + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by by putting a % sign in front of the word +# or globally by setting AUTOLINK_SUPPORT to NO. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES (the +# default) will make doxygen replace the get and set methods by a property in +# the documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and +# unions with only public data fields or simple typedef fields will be shown +# inline in the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO (the default), structs, classes, and unions are shown on a separate +# page (for HTML and Man pages) or section (for LaTeX and RTF). + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can +# be an expensive process and often the same symbol appear multiple times in +# the code, doxygen keeps a cache of pre-resolved symbols. If the cache is too +# small doxygen will become slower. If the cache is too large, memory is wasted. +# The cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid +# range is 0..9, the default is 0, corresponding to a cache size of 2^16 = 65536 +# symbols. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# scope will be included in the documentation. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = YES + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if section-label ... \endif +# and \cond section-label ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files +# containing the references data. This must be a list of .bib files. The +# .bib extension is automatically appended if omitted. Using this command +# requires the bibtex tool to be installed. See also +# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style +# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this +# feature you need bibtex and perl available in the search path. Do not use +# file names with spaces, bibtex cannot handle them. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = ../ + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.d \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.cs \ + *.php \ + *.php3 \ + *.inc \ + *.m \ + *.markdown \ + *.md \ + *.mm \ + *.dox \ + *.py \ + *.f90 \ + *.f \ + *.for \ + *.vhd \ + *.vhdl \ + README.txt + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be ignored. +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C, C++ and Fortran comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +# If CLANG_ASSISTED_PARSING is set to YES, then doxygen will use the clang parser +# for more acurate parsing at the cost of reduced performance. This can be +# particularly helpful with template rich C++ code for which doxygen's built-in +# parser lacks the necessairy type information. + +CLANG_ASSISTED_PARSING = NO + +# If clang assisted parsing is enabled you can provide the compiler with command +# line options that you would normally use when invoking the compiler. Note that +# the include paths will already be set by doxygen for the files and directories +# specified at INPUT and INCLUDE_PATH. + +CLANG_OPTIONS = + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is advised to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when +# changing the value of configuration settings such as GENERATE_TREEVIEW! + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If left blank doxygen will +# generate a default style sheet. Note that it is recommended to use +# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this +# tag will in the future become obsolete. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional +# user-defined cascading style sheet that is included after the standard +# style sheets created by doxygen. Using this option one can overrule +# certain style aspects. This is preferred over using HTML_STYLESHEET +# since it does not replace the standard style sheet and is therefor more +# robust against future updates. Doxygen will copy the style sheet file to +# the output directory. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the style sheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of +# entries shown in the various tree structured indices initially; the user +# can expand and collapse entries dynamically later on. Doxygen will expand +# the tree to such a level that at most the specified number of entries are +# visible (unless a fully collapsed tree already exceeds this amount). +# So setting the number of entries 1 will produce a full collapsed tree by +# default. 0 is a special value representing an infinite number of entries +# and will result in a full expanded tree by default. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely +# identify the documentation publisher. This should be a reverse domain-name +# style string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) +# at top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. Since the tabs have the same information as the +# navigation tree you can set this option to NO if you already set +# GENERATE_TREEVIEW to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. +# Since the tree basically has the same information as the tab index you +# could consider to set DISABLE_INDEX to NO when enabling this option. + +GENERATE_TREEVIEW = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you may also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and +# SVG. The default value is HTML-CSS, which is slower, but has the best +# compatibility. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to +# the MathJax Content Delivery Network so you can quickly see the result without +# installing MathJax. However, it is strongly recommended to install a local +# copy of MathJax from http://www.mathjax.org before deployment. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension +# names that should be enabled during MathJax rendering. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript +# pieces of code that will be used on startup of the MathJax code. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a web server instead of a web client using Javascript. +# There are two flavours of web server based search depending on the +# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for +# searching and an index file used by the script. When EXTERNAL_SEARCH is +# enabled the indexing and searching needs to be provided by external tools. +# See the manual for details. + +SERVER_BASED_SEARCH = NO + +# When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP +# script for searching. Instead the search results are written to an XML file +# which needs to be processed by an external indexer. Doxygen will invoke an +# external search engine pointed to by the SEARCHENGINE_URL option to obtain +# the search results. Doxygen ships with an example indexer (doxyindexer) and +# search engine (doxysearch.cgi) which are based on the open source search +# engine library Xapian. See the manual for configuration details. + +EXTERNAL_SEARCH = NO + +# The SEARCHENGINE_URL should point to a search engine hosted by a web server +# which will returned the search results when EXTERNAL_SEARCH is enabled. +# Doxygen ships with an example search engine (doxysearch) which is based on +# the open source search engine library Xapian. See the manual for configuration +# details. + +SEARCHENGINE_URL = + +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed +# search data is written to a file for indexing by an external tool. With the +# SEARCHDATA_FILE tag the name of this file can be specified. + +SEARCHDATA_FILE = searchdata.xml + +# When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the +# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is +# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple +# projects and redirect the results back to the right project. + +EXTERNAL_SEARCH_ID = + +# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen +# projects other than the one defined by this configuration file, but that are +# all added to the same external search index. Each project needs to have a +# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id +# of to a relative location where the documentation can be found. +# The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ... + +EXTRA_SEARCH_MAPPINGS = + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4 will be used. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images +# or other source files which should be copied to the LaTeX output directory. +# Note that the files will be copied as-is; there are no commands or markers +# available. + +LATEX_EXTRA_FILES = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See +# http://en.wikipedia.org/wiki/BibTeX for more info. + +LATEX_BIB_STYLE = plain + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load style sheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options related to the DOCBOOK output +#--------------------------------------------------------------------------- + +# If the GENERATE_DOCBOOK tag is set to YES Doxygen will generate DOCBOOK files +# that can be used to generate PDF. + +GENERATE_DOCBOOK = NO + +# The DOCBOOK_OUTPUT tag is used to specify where the DOCBOOK pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in +# front of it. If left blank docbook will be used as the default path. + +DOCBOOK_OUTPUT = docbook + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# pointed to by INCLUDE_PATH will be searched when a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. For each +# tag file the location of the external documentation should be added. The +# format of a tag file without this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths +# or URLs. Note that each tag file must have a unique name (where the name does +# NOT include the path). If a tag file is not located in the directory in which +# doxygen is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed +# in the related pages index. If set to NO, only the current project's +# pages will be listed. + +EXTERNAL_PAGES = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will use the Helvetica font for all dot files that +# doxygen generates. When you want a differently looking font you can specify +# the font name using DOT_FONTNAME. You need to make sure dot is able to find +# the font, which can be done by putting it in a standard location or by setting +# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the Helvetica font. +# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to +# set the path where dot can find it. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If the UML_LOOK tag is enabled, the fields and methods are shown inside +# the class node. If there are many fields or methods and many nodes the +# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS +# threshold limits the number of items for each type to make the size more +# manageable. Set this to 0 for no limit. Note that the threshold may be +# exceeded by 50% before the limit is enforced. + +UML_LIMIT_NUM_FIELDS = 10 + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. If you choose svg you need to set +# HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible in IE 9+ (other browsers do not have this requirement). + +DOT_IMAGE_FORMAT = png + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# Note that this requires a modern browser other than Internet Explorer. +# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you +# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible. Older versions of IE do not have SVG support. + +INTERACTIVE_SVG = NO + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/visualtest/include/SDL_visualtest_action_configparser.h b/visualtest/include/SDL_visualtest_action_configparser.h new file mode 100644 index 0000000..40481f3 --- /dev/null +++ b/visualtest/include/SDL_visualtest_action_configparser.h @@ -0,0 +1,149 @@ +/* See LICENSE.txt for the full license governing this code. */ +/** + * \file SDL_visualtest_action_configparser.h + * + * Header file for the parser for action config files. + */ + +#ifndef SDL_visualtest_action_configparser_h_ +#define SDL_visualtest_action_configparser_h_ + +/** The maximum length of one line in the actions file */ +#define MAX_ACTION_LINE_LENGTH 300 + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Type of the action. + */ +typedef enum +{ + /*! Launch an application with some given arguments */ + SDL_ACTION_LAUNCH = 0, + /*! Kill the SUT process */ + SDL_ACTION_KILL, + /*! Quit (Gracefully exit) the SUT process */ + SDL_ACTION_QUIT, + /*! Take a screenshot of the SUT window */ + SDL_ACTION_SCREENSHOT, + /*! Verify a previously taken screenshot */ + SDL_ACTION_VERIFY +} SDLVisualTest_ActionType; + +/** + * Struct that defines an action that will be performed on the SUT process at + * a specific time. + */ +typedef struct SDLVisualTest_Action +{ + /*! The type of action to be performed */ + SDLVisualTest_ActionType type; + /*! The time, in milliseconds from the launch of the SUT, when the action + will be performed */ + int time; + /*! Any additional information needed to perform the action. */ + union + { + /*! The path and arguments to the process to be launched */ + struct + { + char* path; + char* args; + } process; + } extra; +} SDLVisualTest_Action; + +/** + * Struct for a node in the action queue. + */ +typedef struct SDLVisualTest_ActionNode +{ + /*! The action in this node */ + SDLVisualTest_Action action; + /*! Pointer to the next element in the queue */ + struct SDLVisualTest_ActionNode* next; +} SDLVisualTest_ActionNode; + +/** + * Queue structure for actions loaded from the actions config file. + */ +typedef struct SDLVisualTest_ActionQueue +{ + /*! Pointer to the front of the queue */ + SDLVisualTest_ActionNode* front; + /*! Pointer to the rear of the queue */ + SDLVisualTest_ActionNode* rear; + /*! Number of nodes in the queue */ + int size; +} SDLVisualTest_ActionQueue; + +/** + * Add an action pointed to by \c action to the rear of the action queue pointed + * to by \c queue. + * + * \return 1 on success, 0 on failure. + */ +int SDLVisualTest_EnqueueAction(SDLVisualTest_ActionQueue* queue, + SDLVisualTest_Action action); + +/** + * Remove an action from the front of the action queue pointed to by \c queue. + * + * \return 1 on success, 0 on failure. + */ +int SDLVisualTest_DequeueAction(SDLVisualTest_ActionQueue* queue); + +/** + * Initialize the action queue pointed to by \c queue. + */ +void SDLVisualTest_InitActionQueue(SDLVisualTest_ActionQueue* queue); + +/** + * Get the action at the front of the action queue pointed to by \c queue. + * The returned action pointer may become invalid after subsequent dequeues. + * + * \return pointer to the action on success, NULL on failure. + */ +SDLVisualTest_Action* SDLVisualTest_GetQueueFront(SDLVisualTest_ActionQueue* queue); + +/** + * Check if the queue pointed to by \c queue is empty or not. + * + * \return 1 if the queue is empty, 0 otherwise. + */ +int SDLVisualTest_IsActionQueueEmpty(SDLVisualTest_ActionQueue* queue); + +/** + * Dequeues all the elements in the queque pointed to by \c queue. + */ +void SDLVisualTest_EmptyActionQueue(SDLVisualTest_ActionQueue* queue); + +/** + * Inserts an action \c action into the queue pointed to by \c queue such that + * the times of actions in the queue increase as we move from the front to the + * rear. + * + * \return 1 on success, 0 on failure. + */ +int SDLVisualTest_InsertIntoActionQueue(SDLVisualTest_ActionQueue* queue, + SDLVisualTest_Action action); + +/** + * Parses an action config file with path \c file and populates an action queue + * pointed to by \c queue with actions. + * + * \return 1 on success, 0 on failure. + */ +int SDLVisualTest_ParseActionConfig(const char* file, SDLVisualTest_ActionQueue* queue); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + +#endif /* SDL_visualtest_action_configparser_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/visualtest/include/SDL_visualtest_exhaustive_variator.h b/visualtest/include/SDL_visualtest_exhaustive_variator.h new file mode 100644 index 0000000..4637ce2 --- /dev/null +++ b/visualtest/include/SDL_visualtest_exhaustive_variator.h @@ -0,0 +1,64 @@ +/* See LICENSE.txt for the full license governing this code. */ +/** + * \file SDL_visualtest_exhaustive_variator.h + * + * Header for the exhaustive variator. + */ + +#include "SDL_visualtest_harness_argparser.h" +#include "SDL_visualtest_variator_common.h" + +#ifndef SDL_visualtest_exhaustive_variator_h_ +#define SDL_visualtest_exhaustive_variator_h_ + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Struct for the variator that exhaustively iterates through all variations of + * command line arguments to the SUT. + */ +typedef struct SDLVisualTest_ExhaustiveVariator +{ + /*! The current variation. */ + SDLVisualTest_Variation variation; + /*! Configuration object for the SUT that the variator is running for. */ + SDLVisualTest_SUTConfig config; + /*! Buffer to store the arguments string built from the variation */ + char buffer[MAX_SUT_ARGS_LEN]; +} SDLVisualTest_ExhaustiveVariator; + +/** + * Initializes the variator. + * + * \return 1 on success, 0 on failure + */ +int SDLVisualTest_InitExhaustiveVariator(SDLVisualTest_ExhaustiveVariator* variator, + SDLVisualTest_SUTConfig* config); + +/** + * Gets the arguments string for the next variation using the variator and updates + * the variator's current variation object to the next variation. + * + * \return The arguments string representing the next variation on success, and + * NULL on failure or if we have iterated through all possible variations. + * In the latter case subsequent calls will start the variations again from + * the very beginning. The pointer returned should not be freed. + */ +char* SDLVisualTest_GetNextExhaustiveVariation(SDLVisualTest_ExhaustiveVariator* variator); + +/** + * Frees any resources associated with the variator. + */ +void SDLVisualTest_FreeExhaustiveVariator(SDLVisualTest_ExhaustiveVariator* variator); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + +#endif /* SDL_visualtest_exhaustive_variator_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/visualtest/include/SDL_visualtest_harness_argparser.h b/visualtest/include/SDL_visualtest_harness_argparser.h new file mode 100644 index 0000000..75420fe --- /dev/null +++ b/visualtest/include/SDL_visualtest_harness_argparser.h @@ -0,0 +1,75 @@ +/** + * \file SDL_visualtest_harness_argparser.h + * + * Provides functionality to parse command line arguments to the test harness. + */ + +#include +#include "SDL_visualtest_sut_configparser.h" +#include "SDL_visualtest_variator_common.h" +#include "SDL_visualtest_action_configparser.h" + +#ifndef SDL_visualtest_harness_argparser_h_ +#define SDL_visualtest_harness_argparser_h_ + +/** Maximum length of a path string */ +#define MAX_PATH_LEN 300 +/** Maximum length of a string of SUT arguments */ +#define MAX_SUT_ARGS_LEN 600 + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Stores the state of the test harness. + */ +typedef struct SDLVisualTest_HarnessState +{ + /*! Path to the System Under Test (SUT) executable */ + char sutapp[MAX_PATH_LEN]; + /*! Command line arguments to be passed to the SUT */ + char sutargs[MAX_SUT_ARGS_LEN]; + /*! Time in milliseconds after which to kill the SUT */ + int timeout; + /*! Configuration object for the SUT */ + SDLVisualTest_SUTConfig sut_config; + /*! What type of variator to use to generate argument strings */ + SDLVisualTest_VariatorType variator_type; + /*! The number of variations to generate */ + int num_variations; + /*! If true, the test harness will just print the different variations + without launching the SUT for each one */ + SDL_bool no_launch; + /*! A queue with actions to be performed while the SUT is running */ + SDLVisualTest_ActionQueue action_queue; + /*! Output directory to save the screenshots */ + char output_dir[MAX_PATH_LEN]; + /*! Path to directory with the verification images */ + char verify_dir[MAX_PATH_LEN]; +} SDLVisualTest_HarnessState; + +/** + * Parse command line paramters to the test harness and populate a state object. + * + * \param argv The array of command line parameters. + * \param state Pointer to the state object to be populated. + * + * \return Non-zero on success, zero on failure. + */ +int SDLVisualTest_ParseHarnessArgs(char** argv, SDLVisualTest_HarnessState* state); + +/** + * Frees any resources associated with the state object pointed to by \c state. + */ +void SDLVisualTest_FreeHarnessState(SDLVisualTest_HarnessState* state); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + +#endif /* SDL_visualtest_harness_argparser_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/visualtest/include/SDL_visualtest_mischelper.h b/visualtest/include/SDL_visualtest_mischelper.h new file mode 100644 index 0000000..5faffa5 --- /dev/null +++ b/visualtest/include/SDL_visualtest_mischelper.h @@ -0,0 +1,28 @@ +/** + * \file mischelper.c + * + * Header with miscellaneous helper functions. + */ + +#ifndef SDL_visualtest_mischelper_h_ +#define SDL_visualtest_mischelper_h_ + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Stores a 32 digit hexadecimal string representing the MD5 hash of the + * string \c str in \c hash. + */ +void SDLVisualTest_HashString(char* str, char hash[33]); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + +#endif /* SDL_visualtest_mischelper_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/visualtest/include/SDL_visualtest_parsehelper.h b/visualtest/include/SDL_visualtest_parsehelper.h new file mode 100644 index 0000000..4558552 --- /dev/null +++ b/visualtest/include/SDL_visualtest_parsehelper.h @@ -0,0 +1,46 @@ +/* See LICENSE.txt for the full license governing this code. */ +/** + * \file SDL_visualtest_parsehelper.h + * + * Header with some helper functions for parsing strings. + */ + +#ifndef SDL_visualtest_parsehelper_h_ +#define SDL_visualtest_parsehelper_h_ + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Takes an string of command line arguments and breaks them up into an array + * based on whitespace. + * + * \param args The string of arguments. + * + * \return NULL on failure, an array of strings on success. The last element + * of the array is NULL. The first element of the array is NULL and should + * be set to the path of the executable by the caller. + */ +char** SDLVisualTest_ParseArgsToArgv(char* args); + +/** + * Takes a string and breaks it into tokens by splitting on whitespace. + * + * \param str The string to be split. + * \param max_token_len Length of each element in the array to be returned. + * + * \return NULL on failure; an array of strings with the tokens on success. The + * last element of the array is NULL. + */ +char** SDLVisualTest_Tokenize(char* str, int max_token_len); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + +#endif /* SDL_visualtest_parsehelper_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/visualtest/include/SDL_visualtest_process.h b/visualtest/include/SDL_visualtest_process.h new file mode 100644 index 0000000..26ce5a0 --- /dev/null +++ b/visualtest/include/SDL_visualtest_process.h @@ -0,0 +1,112 @@ +/* See LICENSE.txt for the full license governing this code. */ +/** + * \file SDL_visualtest_process.h + * + * Provides cross-platfrom process launching and termination functionality. + */ + +#include + +#if defined(__WIN32__) +#include +#include +#elif defined(__LINUX__) +#include +#else +#error "Unsupported platform." +#endif + +#ifndef SDL_visualtest_process_h_ +#define SDL_visualtest_process_h_ + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Struct to store a platform specific handle to a process. + */ +typedef struct SDL_ProcessInfo +{ +//#if defined(_WIN32) || defined(__WIN32__) +#if defined(__WIN32__) + PROCESS_INFORMATION pi; +//#elif defined(__linux__) +#elif defined(__LINUX__) + int pid; +#endif +} SDL_ProcessInfo; + +/** + * This structure stores the exit status (value returned by main()) and + * whether the process exited sucessfully or not. + */ +typedef struct SDL_ProcessExitStatus +{ + int exit_success; /*!< Zero if the process exited successfully */ + int exit_status; /*!< The exit status of the process. 8-bit value. */ +} SDL_ProcessExitStatus; + +/** + * Launches a process with the given commandline arguments. + * + * \param file The path to the executable to be launched. + * \param args The command line arguments to be passed to the process. + * \param pinfo Pointer to an SDL_ProcessInfo object to be populated with + * platform specific information about the launched process. + * + * \return Non-zero on success, zero on failure. + */ +int SDL_LaunchProcess(char* file, char* args, SDL_ProcessInfo* pinfo); + +/** + * Checks if a process is running or not. + * + * \param pinfo Pointer to SDL_ProcessInfo object of the process that needs to be + * checked. + * + * \return 1 if the process is still running; zero if it is not and -1 if the + * status could not be retrieved. + */ +int SDL_IsProcessRunning(SDL_ProcessInfo* pinfo); + +/** + * Kills a currently running process. + * + * \param pinfo Pointer to a SDL_ProcessInfo object of the process to be terminated. + * \param ps Pointer to a SDL_ProcessExitStatus object which will be populated + * with the exit status. + * + * \return 1 on success, 0 on failure. + */ +int SDL_KillProcess(SDL_ProcessInfo* pinfo, SDL_ProcessExitStatus* ps); + +/** + * Cleanly exits the process represented by \c pinfo and stores the exit status + * in the exit status object pointed to by \c ps. + * + * \return 1 on success, 0 on failure. + */ +int SDL_QuitProcess(SDL_ProcessInfo* pinfo, SDL_ProcessExitStatus* ps); + +/** + * Gets the exit status of a process. If the exit status is -1, the process is + * still running. + * + * \param pinfo Pointer to a SDL_ProcessInfo object of the process to be checked. + * \param ps Pointer to a SDL_ProcessExitStatus object which will be populated + * with the exit status. + * + * \return 1 on success, 0 on failure. + */ +int SDL_GetProcessExitStatus(SDL_ProcessInfo* pinfo, SDL_ProcessExitStatus* ps); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + +#endif /* SDL_visualtest_process_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/visualtest/include/SDL_visualtest_random_variator.h b/visualtest/include/SDL_visualtest_random_variator.h new file mode 100644 index 0000000..0514ce6 --- /dev/null +++ b/visualtest/include/SDL_visualtest_random_variator.h @@ -0,0 +1,61 @@ +/* See LICENSE.txt for the full license governing this code. */ +/** + * \file SDL_visualtest_random_variator.h + * + * Header for the random variator. + */ + +#include "SDL_visualtest_harness_argparser.h" +#include "SDL_visualtest_variator_common.h" + +#ifndef SDL_visualtest_random_variator_h_ +#define SDL_visualtest_random_variator_h_ + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Struct for the variator that randomly generates variations of command line + * arguments to the SUT. + */ +typedef struct SDLVisualTest_RandomVariator +{ + /*! The current variation. */ + SDLVisualTest_Variation variation; + /*! Configuration object for the SUT that the variator is running for. */ + SDLVisualTest_SUTConfig config; + /*! Buffer to store the arguments string built from the variation */ + char buffer[MAX_SUT_ARGS_LEN]; +} SDLVisualTest_RandomVariator; + +/** + * Initializes the variator. + * + * \return 1 on success, 0 on failure + */ +int SDLVisualTest_InitRandomVariator(SDLVisualTest_RandomVariator* variator, + SDLVisualTest_SUTConfig* config, Uint64 seed); + +/** + * Generates a new random variation. + * + * \return The arguments string representing the random variation on success, and + * NULL on failure. The pointer returned should not be freed. + */ +char* SDLVisualTest_GetNextRandomVariation(SDLVisualTest_RandomVariator* variator); + +/** + * Frees any resources associated with the variator. + */ +void SDLVisualTest_FreeRandomVariator(SDLVisualTest_RandomVariator* variator); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + +#endif /* SDL_visualtest_random_variator_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/visualtest/include/SDL_visualtest_rwhelper.h b/visualtest/include/SDL_visualtest_rwhelper.h new file mode 100644 index 0000000..bc39425 --- /dev/null +++ b/visualtest/include/SDL_visualtest_rwhelper.h @@ -0,0 +1,87 @@ +/* See LICENSE.txt for the full license governing this code. */ +/** + * \file rwhelper.c + * + * Header file with some helper functions for working with SDL_RWops. + */ + +#include + +#ifndef SDL_visualtest_rwhelper_h_ +#define SDL_visualtest_rwhelper_h_ + +/** Length of the buffer in SDLVisualTest_RWHelperBuffer */ +#define RWOPS_BUFFER_LEN 256 + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Struct that is used as a buffer by the RW helper functions. Should be initialized by calling + * SDLVisualTest_RWHelperResetBuffer() before being used. + */ +typedef struct SDLVisualTest_RWHelperBuffer +{ + /*! Character buffer that data is read into */ + char buffer[RWOPS_BUFFER_LEN]; + /*! buffer[buffer_pos] is the next character to be read from the buffer */ + int buffer_pos; + /*! Number of character read into the buffer */ + int buffer_width; +} SDLVisualTest_RWHelperBuffer; + +/** + * Resets the buffer pointed to by \c buffer used by some of the helper functions. + * This function should be called when you're using one of the helper functions + * with a new SDL_RWops object. + */ +void SDLVisualTest_RWHelperResetBuffer(SDLVisualTest_RWHelperBuffer* buffer); + +/** + * Reads a single character using the SDL_RWops object pointed to by \c rw. + * This function reads data in blocks and stores them in the buffer pointed to by + * \c buffer, so other SDL_RWops functions should not be used in conjunction + * with this function. + * + * \return The character that was read. + */ +char SDLVisualTest_RWHelperReadChar(SDL_RWops* rw, + SDLVisualTest_RWHelperBuffer* buffer); + +/** + * Reads characters using the SDL_RWops object pointed to by \c rw into the + * character array pointed to by \c str (of size \c size) until either the + * array is full or a new line is encountered. If \c comment_char is encountered, + * all characters from that position till the end of the line are ignored. The new line + * is not included as part of the buffer. Lines with only whitespace and comments + * are ignored. This function reads data in blocks and stores them in the buffer + * pointed to by \c buffer, so other SDL_RWops functions should not be used in + * conjunction with this function. + * + * \return pointer to the string on success, NULL on failure or EOF. + */ +char* SDLVisualTest_RWHelperReadLine(SDL_RWops* rw, char* str, int size, + SDLVisualTest_RWHelperBuffer* buffer, + char comment_char); + +/** + * Counts the number of lines that are not all whitespace and comments using the + * SDL_RWops object pointed to by \c rw. \c comment_char indicates the character + * used for comments. Uses the buffer pointed to by \c buffer to read data in blocks. + * + * \return Number of lines on success, -1 on failure. + */ +int SDLVisualTest_RWHelperCountNonEmptyLines(SDL_RWops* rw, + SDLVisualTest_RWHelperBuffer* buffer, + char comment_char); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + +#endif /* SDL_visualtest_rwhelper_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/visualtest/include/SDL_visualtest_screenshot.h b/visualtest/include/SDL_visualtest_screenshot.h new file mode 100644 index 0000000..69411e9 --- /dev/null +++ b/visualtest/include/SDL_visualtest_screenshot.h @@ -0,0 +1,52 @@ +/* See LICENSE.txt for the full license governing this code. */ +/** + * \file SDL_visualtest_screenshot.h + * + * Header for the screenshot API. + */ + +#include "SDL_visualtest_process.h" + +#ifndef SDL_visualtest_screenshot_h_ +#define SDL_visualtest_screenshot_h_ + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Takes a screenshot of each window owned by the process \c pinfo and saves + * it in a file \c prefix-i.png where \c prefix is the full path to the file + * along with a prefix given to each screenshot. + * + * \return 1 on success, 0 on failure. + */ +int SDLVisualTest_ScreenshotProcess(SDL_ProcessInfo* pinfo, char* prefix); + +/** + * Takes a screenshot of the desktop and saves it into the file with path + * \c filename. + * + * \return 1 on success, 0 on failure. + */ +int SDLVisualTest_ScreenshotDesktop(char* filename); + +/** + * Compare a screenshot taken previously with SUT arguments \c args that is + * located in \c test_dir with a verification image that is located in + * \c verify_dir. + * + * \return -1 on failure, 0 if the images were not equal, 1 if the images are equal + * and 2 if the verification image is not present. + */ +int SDLVisualTest_VerifyScreenshots(char* args, char* test_dir, char* verify_dir); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + +#endif /* SDL_visualtest_screenshot_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/visualtest/include/SDL_visualtest_sut_configparser.h b/visualtest/include/SDL_visualtest_sut_configparser.h new file mode 100644 index 0000000..63506f5 --- /dev/null +++ b/visualtest/include/SDL_visualtest_sut_configparser.h @@ -0,0 +1,105 @@ +/* See LICENSE.txt for the full license governing this code. */ +/** + * \file SDL_visualtest_sut_configparser.h + * + * Header for the parser for SUT config files. + */ + +#ifndef SDL_visualtest_sut_configparser_h_ +#define SDL_visualtest_sut_configparser_h_ + +/** Maximum length of the name of an SUT option */ +#define MAX_SUTOPTION_NAME_LEN 100 +/** Maximum length of the name of a category of an SUT option */ +#define MAX_SUTOPTION_CATEGORY_LEN 40 +/** Maximum length of one enum value of an SUT option */ +#define MAX_SUTOPTION_ENUMVAL_LEN 40 +/** Maximum length of a line in the paramters file */ +#define MAX_SUTOPTION_LINE_LENGTH 256 + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Describes the different kinds of options to the SUT. + */ +typedef enum { + SDL_SUT_OPTIONTYPE_STRING = 0, + SDL_SUT_OPTIONTYPE_INT, + SDL_SUT_OPTIONTYPE_ENUM, + SDL_SUT_OPTIONTYPE_BOOL +} SDLVisualTest_SUTOptionType; + +/** + * Represents the range of values an integer option can take. + */ +typedef struct SDLVisualTest_SUTIntRange { + /*! Minimum value of the integer option */ + int min; + /*! Maximum value of the integer option */ + int max; +} SDLVisualTest_SUTIntRange; + +/** + * Struct that defines an option to be passed to the SUT. + */ +typedef struct SDLVisualTest_SUTOption { + /*! The name of the option. This is what you would pass in the command line + along with two leading hyphens. */ + char name[MAX_SUTOPTION_NAME_LEN]; + /*! An array of categories that the option belongs to. The last element is + NULL. */ + char** categories; + /*! Type of the option - integer, boolean, etc. */ + SDLVisualTest_SUTOptionType type; + /*! Whether the option is required or not */ + SDL_bool required; + /*! extra data that is required for certain types */ + union { + /*! This field is valid only for integer type options; it defines the + valid range for such an option */ + SDLVisualTest_SUTIntRange range; + /*! This field is valid only for enum type options; it holds the list of values + that the option can take. The last element is NULL */ + char** enum_values; + } data; +} SDLVisualTest_SUTOption; + +/** + * Struct to hold all the options to an SUT application. + */ +typedef struct SDLVisualTest_SUTConfig +{ + /*! Pointer to an array of options */ + SDLVisualTest_SUTOption* options; + /*! Number of options in \c options */ + int num_options; +} SDLVisualTest_SUTConfig; + +/** + * Parses a configuration file that describes the command line options an SUT + * application will take and populates a SUT config object. All lines in the + * config file must be smaller than + * + * \param file Path to the configuration file. + * \param config Pointer to an object that represents an SUT configuration. + * + * \return zero on failure, non-zero on success + */ +int SDLVisualTest_ParseSUTConfig(char* file, SDLVisualTest_SUTConfig* config); + +/** + * Free any resources associated with the config object pointed to by \c config. + */ +void SDLVisualTest_FreeSUTConfig(SDLVisualTest_SUTConfig* config); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + +#endif /* SDL_visualtest_sut_configparser_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/visualtest/include/SDL_visualtest_variator_common.h b/visualtest/include/SDL_visualtest_variator_common.h new file mode 100644 index 0000000..19a5b37 --- /dev/null +++ b/visualtest/include/SDL_visualtest_variator_common.h @@ -0,0 +1,122 @@ +/* See LICENSE.txt for the full license governing this code. */ +/** + * \file SDL_visualtest_variator_common.h + * + * Header for common functionality used by variators. + */ + +#include +#include "SDL_visualtest_sut_configparser.h" + +#ifndef SDL_visualtest_variator_common_h_ +#define SDL_visualtest_variator_common_h_ + +/** The number of variations one integer option would generate */ +#define SDL_SUT_INTEGER_OPTION_TEST_STEPS 3 + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** enum for indicating the type of variator being used */ +typedef enum SDLVisualTest_VariatorType +{ + SDL_VARIATOR_NONE = 0, + SDL_VARIATOR_EXHAUSTIVE, + SDL_VARIATOR_RANDOM +} SDLVisualTest_VariatorType; + +/** + * One possible value for a command line option to the SUT. + */ +typedef union SDLVisualTest_SUTOptionValue +{ + /*! Value if the option is of type boolean */ + SDL_bool bool_value; + /*! Value if the option is of type integer. If on is true then the option + will be passed to the SUT, otherwise it will be ignored. */ + struct { + int value; + SDL_bool on; + } integer; + /*! Index of the string in the enum_values field of the corresponding + SDLVisualTest_SUTOption object. If on is true the option will passed + to the SUT, otherwise it will be ignored. */ + struct { + int index; + SDL_bool on; + } enumerated; + /*! Value if the option is of type string. If on is true the option will + be passed to the SUT, otherwise it will be ignored. */ + struct { + char* value; + SDL_bool on; + } string; +} SDLVisualTest_SUTOptionValue; + +/** + * Represents a valid combination of parameters that can be passed to the SUT. + * The ordering of the values here is the same as the ordering of the options in + * the SDLVisualTest_SUTConfig object for this variation. + */ +typedef struct SDLVisualTest_Variation +{ + /*! Pointer to array of option values */ + SDLVisualTest_SUTOptionValue* vars; + /*! Number of option values in \c vars */ + int num_vars; +} SDLVisualTest_Variation; + +/** + * "Increments" the value of the option by one and returns the carry. We wrap + * around to the initial value on overflow which makes the carry one. + * For example: "incrementing" an SDL_FALSE option makes it SDL_TRUE with no + * carry, and "incrementing" an SDL_TRUE option makes it SDL_FALSE with carry + * one. For integers, a random value in the valid range for the option is used. + * + * \param var Value of the option + * \param opt Object with metadata about the option + * + * \return 1 if there is a carry for enum and bool type options, 0 otherwise. + * 1 is always returned for integer and string type options. -1 is + * returned on error. + */ +int SDLVisualTest_NextValue(SDLVisualTest_SUTOptionValue* var, + SDLVisualTest_SUTOption* opt); + +/** + * Converts a variation object into a string of command line arguments. + * + * \param variation Variation object to be converted. + * \param config Config object for the SUT. + * \param buffer Pointer to the buffer the arguments string will be copied into. + * \param size Size of the buffer. + * + * \return 1 on success, 0 on failure + */ +int SDLVisualTest_MakeStrFromVariation(SDLVisualTest_Variation* variation, + SDLVisualTest_SUTConfig* config, + char* buffer, int size); + +/** + * Initializes the variation using the following rules: + * - Boolean options are initialized to SDL_FALSE. + * - Integer options are initialized to the minimum valid value they can hold. + * - Enum options are initialized to the first element in the list of values they + * can take. + * - String options are initialized to the name of the option. + * + * \return 1 on success, 0 on failure. + */ +int SDLVisualTest_InitVariation(SDLVisualTest_Variation* variation, + SDLVisualTest_SUTConfig* config); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + +#endif /* SDL_visualtest_variator_common_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/visualtest/include/SDL_visualtest_variators.h b/visualtest/include/SDL_visualtest_variators.h new file mode 100644 index 0000000..e14f67d --- /dev/null +++ b/visualtest/include/SDL_visualtest_variators.h @@ -0,0 +1,66 @@ +/* See LICENSE.txt for the full license governing this code. */ +/** + * \file SDL_visualtest_variators.h + * + * Header for all the variators that vary input parameters to a SUT application. + */ + +#include "SDL_visualtest_exhaustive_variator.h" +#include "SDL_visualtest_random_variator.h" + +#ifndef SDL_visualtest_variators_h_ +#define SDL_visualtest_variators_h_ + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Struct that acts like a wrapper around the different types of variators + * available. + */ +typedef struct SDLVisualTest_Variator +{ + /*! Type of the variator */ + SDLVisualTest_VariatorType type; + /*! union object that stores the variator */ + union + { + SDLVisualTest_ExhaustiveVariator exhaustive; + SDLVisualTest_RandomVariator random; + } data; +} SDLVisualTest_Variator; + +/** + * Initializes the variator object pointed to by \c variator of type \c type + * with information from the config object pointed to by \c config. + * + * \return 1 on success, 0 on failure + */ +int SDLVisualTest_InitVariator(SDLVisualTest_Variator* variator, + SDLVisualTest_SUTConfig* config, + SDLVisualTest_VariatorType type, + Uint64 seed); + +/** + * Gets the next variation using the variator. + * + * \return The arguments string representing the variation on success, and + * NULL on failure. The pointer returned should not be freed. + */ +char* SDLVisualTest_GetNextVariation(SDLVisualTest_Variator* variator); + +/** + * Frees any resources associated with the variator. + */ +void SDLVisualTest_FreeVariator(SDLVisualTest_Variator* variator); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif + +#endif /* SDL_visualtest_variators_h_ */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/visualtest/launch_harness.cmd b/visualtest/launch_harness.cmd new file mode 100644 index 0000000..93462a9 --- /dev/null +++ b/visualtest/launch_harness.cmd @@ -0,0 +1,2 @@ +start /wait testharness.exe --config testsprite2_crashtest.config > testrun.log 2>&1 +if %ERRORLEVEL% NEQ 0 echo TEST RUN FAILED (see testrun.log) \ No newline at end of file diff --git a/visualtest/launch_harness.sh b/visualtest/launch_harness.sh new file mode 100755 index 0000000..a2d1471 --- /dev/null +++ b/visualtest/launch_harness.sh @@ -0,0 +1,6 @@ +#!/bin/bash +./testharness.exe --config testsprite2_crashtest.config > testrun.log 2>&1 +if [ "$?" != "0" ]; then + echo TEST RUN FAILED (see testrun.log) + # report error code to CI +fi \ No newline at end of file diff --git a/visualtest/src/action_configparser.c b/visualtest/src/action_configparser.c new file mode 100644 index 0000000..f3b1afd --- /dev/null +++ b/visualtest/src/action_configparser.c @@ -0,0 +1,399 @@ +/* See LICENSE.txt for the full license governing this code. */ +/** + * \file action_configparser.c + * + * Source file for the parser for action config files. + */ + +#include +#include +#include +#include "SDL_visualtest_action_configparser.h" +#include "SDL_visualtest_rwhelper.h" +#include "SDL_visualtest_parsehelper.h" + +static void +FreeAction(SDLVisualTest_Action* action) +{ + if(!action) + return; + switch(action->type) + { + case SDL_ACTION_LAUNCH: + { + char* path; + char* args; + + path = action->extra.process.path; + args = action->extra.process.args; + + if(path) + SDL_free(path); + if(args) + SDL_free(args); + + action->extra.process.path = NULL; + action->extra.process.args = NULL; + } + break; + + default: + break; + } +} + +int +SDLVisualTest_EnqueueAction(SDLVisualTest_ActionQueue* queue, + SDLVisualTest_Action action) +{ + SDLVisualTest_ActionNode* node; + if(!queue) + { + SDLTest_LogError("queue argument cannot be NULL"); + return 0; + } + + node = (SDLVisualTest_ActionNode*)SDL_malloc( + sizeof(SDLVisualTest_ActionNode)); + if(!node) + { + SDLTest_LogError("SDL_malloc() failed"); + return 0; + } + node->action = action; + node->next = NULL; + queue->size++; + if(!queue->rear) + queue->rear = queue->front = node; + else + { + queue->rear->next = node; + queue->rear = node; + } + return 1; +} + +int +SDLVisualTest_DequeueAction(SDLVisualTest_ActionQueue* queue) +{ + SDLVisualTest_ActionNode* node; + if(!queue) + { + SDLTest_LogError("queue argument cannot be NULL"); + return 0; + } + if(SDLVisualTest_IsActionQueueEmpty(queue)) + { + SDLTest_LogError("cannot dequeue from empty queue"); + return 0; + } + if(queue->front == queue->rear) + { + FreeAction(&queue->front->action); + SDL_free(queue->front); + queue->front = queue->rear = NULL; + } + else + { + node = queue->front; + queue->front = queue->front->next; + FreeAction(&node->action); + SDL_free(node); + } + queue->size--; + return 1; +} + +void +SDLVisualTest_InitActionQueue(SDLVisualTest_ActionQueue* queue) +{ + if(!queue) + { + SDLTest_LogError("queue argument cannot be NULL"); + return; + } + queue->front = NULL; + queue->rear = NULL; + queue->size = 0; +} + +SDLVisualTest_Action* +SDLVisualTest_GetQueueFront(SDLVisualTest_ActionQueue* queue) +{ + if(!queue) + { + SDLTest_LogError("queue argument cannot be NULL"); + return NULL; + } + if(!queue->front) + { + SDLTest_LogError("cannot get front of empty queue"); + return NULL; + } + + return &queue->front->action; +} + +int +SDLVisualTest_IsActionQueueEmpty(SDLVisualTest_ActionQueue* queue) +{ + if(!queue) + { + SDLTest_LogError("queue argument cannot be NULL"); + return 1; + } + + if(queue->size > 0) + return 0; + return 1; +} + +void +SDLVisualTest_EmptyActionQueue(SDLVisualTest_ActionQueue* queue) +{ + if(queue) + { + while(!SDLVisualTest_IsActionQueueEmpty(queue)) + SDLVisualTest_DequeueAction(queue); + } +} + +/* Since the size of the queue is not likely to be larger than 100 elements + we can get away with using insertion sort. */ +static void +SortQueue(SDLVisualTest_ActionQueue* queue) +{ + SDLVisualTest_ActionNode* head; + SDLVisualTest_ActionNode* tail; + + if(!queue || SDLVisualTest_IsActionQueueEmpty(queue)) + return; + + head = queue->front; + for(tail = head; tail && tail->next;) + { + SDLVisualTest_ActionNode* pos; + SDLVisualTest_ActionNode* element = tail->next; + + if(element->action.time < head->action.time) + { + tail->next = tail->next->next; + element->next = head; + head = element; + } + else if(element->action.time >= tail->action.time) + { + tail = tail->next; + } + else + { + for(pos = head; + (pos->next->action.time < element->action.time); + pos = pos->next); + tail->next = tail->next->next; + element->next = pos->next; + pos->next = element; + } + } + + queue->front = head; + queue->rear = tail; +} + +int +SDLVisualTest_InsertIntoActionQueue(SDLVisualTest_ActionQueue* queue, + SDLVisualTest_Action action) +{ + SDLVisualTest_ActionNode* n; + SDLVisualTest_ActionNode* prev; + SDLVisualTest_ActionNode* newnode; + if(!queue) + { + SDLTest_LogError("queue argument cannot be NULL"); + return 0; + } + + if(SDLVisualTest_IsActionQueueEmpty(queue)) + { + if(!SDLVisualTest_EnqueueAction(queue, action)) + { + SDLTest_LogError("SDLVisualTest_EnqueueAction() failed"); + return 0; + } + return 1; + } + + newnode = (SDLVisualTest_ActionNode*)SDL_malloc(sizeof(SDLVisualTest_ActionNode)); + if(!newnode) + { + SDLTest_LogError("SDL_malloc() failed"); + return 0; + } + newnode->action = action; + + queue->size++; + for(n = queue->front, prev = NULL; n; n = n->next) + { + if(action.time < n->action.time) + { + if(prev) + { + prev->next = newnode; + newnode->next = n; + } + else + { + newnode->next = queue->front; + queue->front = newnode; + } + return 1; + } + prev = n; + } + + queue->rear->next = newnode; + newnode->next = NULL; + queue->rear = newnode; + + return 1; +} + +int +SDLVisualTest_ParseActionConfig(const char* file, SDLVisualTest_ActionQueue* queue) +{ + char line[MAX_ACTION_LINE_LENGTH]; + SDLVisualTest_RWHelperBuffer buffer; + char* token_ptr; + int linenum; + SDL_RWops* rw; + + if(!file) + { + SDLTest_LogError("file argument cannot be NULL"); + return 0; + } + if(!queue) + { + SDLTest_LogError("queue argument cannot be NULL"); + return 0; + } + + rw = SDL_RWFromFile(file, "r"); + if(!rw) + { + SDLTest_LogError("SDL_RWFromFile() failed"); + return 0; + } + + SDLVisualTest_RWHelperResetBuffer(&buffer); + SDLVisualTest_InitActionQueue(queue); + linenum = 0; + while(SDLVisualTest_RWHelperReadLine(rw, line, MAX_ACTION_LINE_LENGTH, + &buffer, '#')) + { + SDLVisualTest_Action action; + int hr, min, sec; + + /* parse time */ + token_ptr = strtok(line, " "); + if(!token_ptr || + (SDL_sscanf(token_ptr, "%d:%d:%d", &hr, &min, &sec) != 3)) + { + SDLTest_LogError("Could not parse time token at line: %d", + linenum); + SDLVisualTest_EmptyActionQueue(queue); + SDL_RWclose(rw); + return 0; + } + action.time = (((hr * 60 + min) * 60) + sec) * 1000; + + /* parse type */ + token_ptr = strtok(NULL, " "); + if(SDL_strcasecmp(token_ptr, "launch") == 0) + action.type = SDL_ACTION_LAUNCH; + else if(SDL_strcasecmp(token_ptr, "kill") == 0) + action.type = SDL_ACTION_KILL; + else if(SDL_strcasecmp(token_ptr, "quit") == 0) + action.type = SDL_ACTION_QUIT; + else if(SDL_strcasecmp(token_ptr, "screenshot") == 0) + action.type = SDL_ACTION_SCREENSHOT; + else if(SDL_strcasecmp(token_ptr, "verify") == 0) + action.type = SDL_ACTION_VERIFY; + else + { + SDLTest_LogError("Could not parse type token at line: %d", + linenum); + SDLVisualTest_EmptyActionQueue(queue); + SDL_RWclose(rw); + return 0; + } + + /* parse the extra field */ + if(action.type == SDL_ACTION_LAUNCH) + { + int len; + char* args; + char* path; + token_ptr = strtok(NULL, " "); + len = token_ptr ? SDL_strlen(token_ptr) : 0; + if(len <= 0) + { + SDLTest_LogError("Please specify the process to launch at line: %d", + linenum); + SDLVisualTest_EmptyActionQueue(queue); + SDL_RWclose(rw); + return 0; + } + path = (char*)SDL_malloc(sizeof(char) * (len + 1)); + if(!path) + { + SDLTest_LogError("SDL_malloc() failed"); + SDLVisualTest_EmptyActionQueue(queue); + SDL_RWclose(rw); + return 0; + } + SDL_strlcpy(path, token_ptr, len + 1); + + token_ptr = strtok(NULL, ""); + len = token_ptr ? SDL_strlen(token_ptr) : 0; + if(len > 0) + { + args = (char*)SDL_malloc(sizeof(char) * (len + 1)); + if(!args) + { + SDLTest_LogError("SDL_malloc() failed"); + SDL_free(path); + SDLVisualTest_EmptyActionQueue(queue); + SDL_RWclose(rw); + return 0; + } + SDL_strlcpy(args, token_ptr, len + 1); + } + else + args = NULL; + + action.extra.process.path = path; + action.extra.process.args = args; + } + + /* add the action to the queue */ + if(!SDLVisualTest_EnqueueAction(queue, action)) + { + SDLTest_LogError("SDLVisualTest_EnqueueAction() failed"); + if(action.type == SDL_ACTION_LAUNCH) + { + SDL_free(action.extra.process.path); + if(action.extra.process.args) + SDL_free(action.extra.process.args); + } + SDLVisualTest_EmptyActionQueue(queue); + SDL_RWclose(rw); + return 0; + } + } + /* sort the queue of actions */ + SortQueue(queue); + + SDL_RWclose(rw); + return 1; +} diff --git a/visualtest/src/harness_argparser.c b/visualtest/src/harness_argparser.c new file mode 100644 index 0000000..8bc5706 --- /dev/null +++ b/visualtest/src/harness_argparser.c @@ -0,0 +1,358 @@ +/* See LICENSE.txt for the full license governing this code. */ +/** + * \file harness_argparser.c + * + * Source file for functions to parse arguments to the test harness. + */ + +#include +#include +#include + +#include "SDL_visualtest_harness_argparser.h" +#include "SDL_visualtest_rwhelper.h" + +/** Maximum length of one line in the config file */ +#define MAX_CONFIG_LINE_LEN 400 +/** Default value for the timeout after which the SUT is forcefully killed */ +#define DEFAULT_SUT_TIMEOUT (60 * 1000) + +/* String compare s1 and s2 ignoring leading hyphens */ +static int +StrCaseCmpIgnoreHyphen(const char* s1, const char* s2) +{ + /* treat NULL pointer as empty strings */ + if(!s1) + s1 = ""; + if(!s2) + s2 = ""; + + while(*s1 == '-') + s1++; + while(*s2 == '-') + s2++; + + return SDL_strcasecmp(s1, s2); +} + +/* parser an argument, updates the state object and returns the number of + arguments processed; returns -1 on failure */ +static int +ParseArg(char** argv, int index, SDLVisualTest_HarnessState* state) +{ + if(!argv || !argv[index] || !state) + return 0; + + if(StrCaseCmpIgnoreHyphen("sutapp", argv[index]) == 0) + { + index++; + if(!argv[index]) + { + SDLTest_LogError("Arguments parsing error: Invalid argument for sutapp."); + return -1; + } + SDL_strlcpy(state->sutapp, argv[index], MAX_PATH_LEN); + SDLTest_Log("SUT Application: %s", state->sutapp); + return 2; + } + else if(StrCaseCmpIgnoreHyphen("output-dir", argv[index]) == 0) + { + index++; + if(!argv[index]) + { + SDLTest_LogError("Arguments parsing error: Invalid argument for output-dir."); + return -1; + } + SDL_strlcpy(state->output_dir, argv[index], MAX_PATH_LEN); + SDLTest_Log("Screenshot Output Directory: %s", state->output_dir); + return 2; + } + else if(StrCaseCmpIgnoreHyphen("verify-dir", argv[index]) == 0) + { + index++; + if(!argv[index]) + { + SDLTest_LogError("Arguments parsing error: Invalid argument for verify-dir."); + return -1; + } + SDL_strlcpy(state->verify_dir, argv[index], MAX_PATH_LEN); + SDLTest_Log("Screenshot Verification Directory: %s", state->verify_dir); + return 2; + } + else if(StrCaseCmpIgnoreHyphen("sutargs", argv[index]) == 0) + { + index++; + if(!argv[index]) + { + SDLTest_LogError("Arguments parsing error: Invalid argument for sutargs."); + return -1; + } + SDL_strlcpy(state->sutargs, argv[index], MAX_SUT_ARGS_LEN); + SDLTest_Log("SUT Arguments: %s", state->sutargs); + return 2; + } + else if(StrCaseCmpIgnoreHyphen("timeout", argv[index]) == 0) + { + int hr, min, sec; + index++; + if(!argv[index] || SDL_sscanf(argv[index], "%d:%d:%d", &hr, &min, &sec) != 3) + { + SDLTest_LogError("Arguments parsing error: Invalid argument for timeout."); + return -1; + } + state->timeout = (((hr * 60) + min) * 60 + sec) * 1000; + SDLTest_Log("Maximum Timeout for each SUT run: %d milliseconds", + state->timeout); + return 2; + } + else if(StrCaseCmpIgnoreHyphen("parameter-config", argv[index]) == 0) + { + index++; + if(!argv[index]) + { + SDLTest_LogError("Arguments parsing error: Invalid argument for parameter-config."); + return -1; + } + SDLTest_Log("SUT Parameters file: %s", argv[index]); + SDLVisualTest_FreeSUTConfig(&state->sut_config); + if(!SDLVisualTest_ParseSUTConfig(argv[index], &state->sut_config)) + { + SDLTest_LogError("Failed to parse SUT parameters file"); + return -1; + } + return 2; + } + else if(StrCaseCmpIgnoreHyphen("variator", argv[index]) == 0) + { + index++; + if(!argv[index]) + { + SDLTest_LogError("Arguments parsing error: Invalid argument for variator."); + return -1; + } + SDLTest_Log("Variator: %s", argv[index]); + if(SDL_strcasecmp("exhaustive", argv[index]) == 0) + state->variator_type = SDL_VARIATOR_EXHAUSTIVE; + else if(SDL_strcasecmp("random", argv[index]) == 0) + state->variator_type = SDL_VARIATOR_RANDOM; + else + { + SDLTest_LogError("Arguments parsing error: Invalid variator name."); + return -1; + } + return 2; + } + else if(StrCaseCmpIgnoreHyphen("num-variations", argv[index]) == 0) + { + index++; + if(!argv[index]) + { + SDLTest_LogError("Arguments parsing error: Invalid argument for num-variations."); + return -1; + } + state->num_variations = SDL_atoi(argv[index]); + SDLTest_Log("Number of variations to run: %d", state->num_variations); + if(state->num_variations <= 0) + { + SDLTest_LogError("Arguments parsing error: num-variations must be positive."); + return -1; + } + return 2; + } + else if(StrCaseCmpIgnoreHyphen("no-launch", argv[index]) == 0) + { + state->no_launch = SDL_TRUE; + SDLTest_Log("SUT will not be launched."); + return 1; + } + else if(StrCaseCmpIgnoreHyphen("action-config", argv[index]) == 0) + { + index++; + if(!argv[index]) + { + SDLTest_LogError("Arguments parsing error: invalid argument for action-config"); + return -1; + } + SDLTest_Log("Action Config file: %s", argv[index]); + SDLVisualTest_EmptyActionQueue(&state->action_queue); + if(!SDLVisualTest_ParseActionConfig(argv[index], &state->action_queue)) + { + SDLTest_LogError("SDLVisualTest_ParseActionConfig() failed"); + return -1; + } + return 2; + } + else if(StrCaseCmpIgnoreHyphen("config", argv[index]) == 0) + { + index++; + if(!argv[index]) + { + SDLTest_LogError("Arguments parsing error: invalid argument for config"); + return -1; + } + + /* do nothing, this option has already been handled */ + return 2; + } + return 0; +} + +/* TODO: Trailing/leading spaces and spaces between equals sign not supported. */ +static int +ParseConfig(const char* file, SDLVisualTest_HarnessState* state) +{ + SDL_RWops* rw; + SDLVisualTest_RWHelperBuffer buffer; + char line[MAX_CONFIG_LINE_LEN]; + + rw = SDL_RWFromFile(file, "r"); + if(!rw) + { + SDLTest_LogError("SDL_RWFromFile() failed"); + return 0; + } + + SDLVisualTest_RWHelperResetBuffer(&buffer); + while(SDLVisualTest_RWHelperReadLine(rw, line, MAX_CONFIG_LINE_LEN, + &buffer, '#')) + { + char** argv; + int i, num_params; + + /* count number of parameters and replace the trailing newline with 0 */ + num_params = 1; + for(i = 0; line[i]; i++) + { + if(line[i] == '=') + { + num_params = 2; + break; + } + } + + /* populate argv */ + argv = (char**)SDL_malloc((num_params + 1) * sizeof(char*)); + if(!argv) + { + SDLTest_LogError("SDL_malloc() failed."); + SDL_RWclose(rw); + return 0; + } + + argv[num_params] = NULL; + for(i = 0; i < num_params; i++) + { + argv[i] = strtok(i == 0 ? line : NULL, "="); + } + + if(ParseArg(argv, 0, state) == -1) + { + SDLTest_LogError("ParseArg() failed"); + SDL_free(argv); + SDL_RWclose(rw); + return 0; + } + SDL_free(argv); + } + SDL_RWclose(rw); + + if(!state->sutapp[0]) + return 0; + return 1; +} + +int +SDLVisualTest_ParseHarnessArgs(char** argv, SDLVisualTest_HarnessState* state) +{ + int i; + + SDLTest_Log("Parsing commandline arguments.."); + + if(!argv) + { + SDLTest_LogError("argv is NULL"); + return 0; + } + if(!state) + { + SDLTest_LogError("state is NULL"); + return 0; + } + + /* initialize the state object */ + state->sutargs[0] = '\0'; + state->sutapp[0] = '\0'; + state->output_dir[0] = '\0'; + state->verify_dir[0] = '\0'; + state->timeout = DEFAULT_SUT_TIMEOUT; + SDL_memset(&state->sut_config, 0, sizeof(SDLVisualTest_SUTConfig)); + SDL_memset(&state->action_queue, 0, sizeof(SDLVisualTest_ActionQueue)); + state->variator_type = SDL_VARIATOR_RANDOM; + state->num_variations = -1; + state->no_launch = SDL_FALSE; + + /* parse config file if passed */ + for(i = 0; argv[i]; i++) + { + if(StrCaseCmpIgnoreHyphen("config", argv[i]) == 0) + { + if(!argv[i + 1]) + { + SDLTest_Log("Arguments parsing error: invalid argument for config."); + return 0; + } + if(!ParseConfig(argv[i + 1], state)) + { + SDLTest_LogError("ParseConfig() failed"); + return 0; + } + } + } + + /* parse the arguments */ + for(i = 0; argv[i];) + { + int consumed = ParseArg(argv, i, state); + if(consumed == -1 || consumed == 0) + { + SDLTest_LogError("ParseArg() failed"); + return 0; + } + i += consumed; + } + + if(state->variator_type == SDL_VARIATOR_RANDOM && state->num_variations == -1) + state->num_variations = 1; + + /* check to see if required options have been passed */ + if(!state->sutapp[0]) + { + SDLTest_LogError("sutapp must be passed."); + return 0; + } + if(!state->sutargs[0] && !state->sut_config.options) + { + SDLTest_LogError("Either sutargs or parameter-config must be passed."); + return 0; + } + if(!state->output_dir[0]) + { + SDL_strlcpy(state->output_dir, "./output", MAX_PATH_LEN); + } + if(!state->verify_dir[0]) + { + SDL_strlcpy(state->verify_dir, "./verify", MAX_PATH_LEN); + } + + return 1; +} + +void +SDLVisualTest_FreeHarnessState(SDLVisualTest_HarnessState* state) +{ + if(state) + { + SDLVisualTest_EmptyActionQueue(&state->action_queue); + SDLVisualTest_FreeSUTConfig(&state->sut_config); + } +} diff --git a/visualtest/src/linux/linux_process.c b/visualtest/src/linux/linux_process.c new file mode 100644 index 0000000..b93f340 --- /dev/null +++ b/visualtest/src/linux/linux_process.c @@ -0,0 +1,208 @@ +/* See LICENSE.txt for the full license governing this code. */ +/** + * \file linux_process.c + * + * Source file for the process API on linux. + */ + + +#include +#include + +#include "SDL_visualtest_process.h" +#include "SDL_visualtest_harness_argparser.h" +#include "SDL_visualtest_parsehelper.h" + +#if defined(__LINUX__) +#include +#include +#include +#include + +static void +LogLastError(const char* str) +{ + const char* error = strerror(errno); + if(!str || !error) + return; + SDLTest_LogError("%s: %s", str, error); +} + +int +SDL_LaunchProcess(char* file, char* args, SDL_ProcessInfo* pinfo) +{ + pid_t pid; + char** argv; + + if(!file) + { + SDLTest_LogError("file argument cannot be NULL"); + return 0; + } + if(!pinfo) + { + SDLTest_LogError("pinfo cannot be NULL"); + return 0; + } + pid = fork(); + if(pid == -1) + { + LogLastError("fork() failed"); + return 0; + } + else if(pid == 0) + { + /* parse the arguments string */ + argv = SDLVisualTest_ParseArgsToArgv(args); + argv[0] = file; + execv(file, argv); + LogLastError("execv() failed"); + return 0; + } + else + { + pinfo->pid = pid; + return 1; + } + + /* never executed */ + return 0; +} + +int +SDL_GetProcessExitStatus(SDL_ProcessInfo* pinfo, SDL_ProcessExitStatus* ps) +{ + int success, status; + if(!pinfo) + { + SDLTest_LogError("pinfo argument cannot be NULL"); + return 0; + } + if(!ps) + { + SDLTest_LogError("ps argument cannot be NULL"); + return 0; + } + success = waitpid(pinfo->pid, &status, WNOHANG); + if(success == -1) + { + LogLastError("waitpid() failed"); + return 0; + } + else if(success == 0) + { + ps->exit_status = -1; + ps->exit_success = 1; + } + else + { + ps->exit_success = WIFEXITED(status); + ps->exit_status = WEXITSTATUS(status); + } + return 1; +} + +int +SDL_IsProcessRunning(SDL_ProcessInfo* pinfo) +{ + int success; + + if(!pinfo) + { + SDLTest_LogError("pinfo cannot be NULL"); + return -1; + } + + success = kill(pinfo->pid, 0); + if(success == -1) + { + if(errno == ESRCH) /* process is not running */ + return 0; + else + { + LogLastError("kill() failed"); + return -1; + } + } + return 1; +} + +int +SDL_QuitProcess(SDL_ProcessInfo* pinfo, SDL_ProcessExitStatus* ps) +{ + int success, status; + + if(!pinfo) + { + SDLTest_LogError("pinfo argument cannot be NULL"); + return 0; + } + if(!ps) + { + SDLTest_LogError("ps argument cannot be NULL"); + return 0; + } + + success = kill(pinfo->pid, SIGQUIT); + if(success == -1) + { + LogLastError("kill() failed"); + return 0; + } + + success = waitpid(pinfo->pid, &status, 0); + if(success == -1) + { + LogLastError("waitpid() failed"); + return 0; + } + + ps->exit_success = WIFEXITED(status); + ps->exit_status = WEXITSTATUS(status); + return 1; +} + +int +SDL_KillProcess(SDL_ProcessInfo* pinfo, SDL_ProcessExitStatus* ps) +{ + int success, status; + + if(!pinfo) + { + SDLTest_LogError("pinfo argument cannot be NULL"); + return 0; + } + if(!ps) + { + SDLTest_LogError("ps argument cannot be NULL"); + return 0; + } + + success = kill(pinfo->pid, SIGKILL); + if(success == -1) + { + LogLastError("kill() failed"); + return 0; + } + success = waitpid(pinfo->pid, &status, 0); + if(success == -1) + { + LogLastError("waitpid() failed"); + return 0; + } + + ps->exit_success = WIFEXITED(status); + ps->exit_status = WEXITSTATUS(status); + return 1; +} + +/* each window of the process will have a screenshot taken. The file name will be + prefix-i.png for the i'th window. */ +int +SDLVisualTest_ScreenshotProcess(SDL_ProcessInfo* pinfo, char* prefix) +{ + SDLTest_LogError("Screenshot process not implemented"); + return 0; +} + +#endif diff --git a/visualtest/src/mischelper.c b/visualtest/src/mischelper.c new file mode 100644 index 0000000..9684af6 --- /dev/null +++ b/visualtest/src/mischelper.c @@ -0,0 +1,28 @@ +/** + * \file mischelper.c + * + * Source file with miscellaneous helper functions. + */ + +#include + +void +SDLVisualTest_HashString(char* str, char hash[33]) +{ + SDLTest_Md5Context md5c; + int i; + + if(!str) + { + SDLTest_LogError("str argument cannot be NULL"); + return; + } + + SDLTest_Md5Init(&md5c); + SDLTest_Md5Update(&md5c, (unsigned char*)str, SDL_strlen(str)); + SDLTest_Md5Final(&md5c); + + /* convert the md5 hash to an array of hexadecimal digits */ + for(i = 0; i < 16; i++) + SDL_snprintf(hash + 2 * i, 33 - 2 * i, "%02x", (int)md5c.digest[i]); +} diff --git a/visualtest/src/parsehelper.c b/visualtest/src/parsehelper.c new file mode 100644 index 0000000..9d38cb2 --- /dev/null +++ b/visualtest/src/parsehelper.c @@ -0,0 +1,231 @@ +/* See LICENSE.txt for the full license governing this code. */ +/** + * \file parsehelper.c + * + * Source file with some helper functions for parsing strings. + */ + +#include +#include "SDL_visualtest_harness_argparser.h" + +/* this function uses a DFA to count the number of tokens in an agruments string. + state 0 is taken to be the start and end state. State 1 handles a double quoted + argument and state 2 handles unquoted arguments. */ +static int +CountTokens(char* args) +{ + int index, num_tokens; + int state; /* current state of the DFA */ + + if(!args) + return -1; + + index = 0; + state = 0; + num_tokens = 0; + while(args[index]) + { + char ch = args[index]; + switch(state) + { + case 0: + if(ch == '\"') + { + state = 1; + num_tokens++; + } + else if(!SDL_isspace(ch)) + { + state = 2; + num_tokens++; + } + break; + + case 1: + if(ch == '\"') + { + state = 0; + } + break; + + case 2: + if(SDL_isspace(ch)) + { + state = 0; + } + break; + } + index++; + } + return num_tokens; +} + +/* - size of tokens is num_tokens + 1 +- uses the same DFA used in CountTokens() to split args into an array of strings */ +static int +TokenizeHelper(char* str, char** tokens, int num_tokens, int max_token_len) +{ + int index, state, done, st_index, token_index; + + if(!str) + { + SDLTest_LogError("str argument cannot be NULL"); + return 0; + } + if(!tokens) + { + SDLTest_LogError("tokens argument cannot be NULL"); + return 0; + } + if(num_tokens <= 0) + { + SDLTest_LogError("num_tokens argument must be positive"); + return 0; + } + if(max_token_len <= 0) + { + SDLTest_LogError("max_token_len argument must be positive"); + return 0; + } + + /* allocate memory for the tokens */ + tokens[num_tokens] = NULL; + for(index = 0; index < num_tokens; index++) + { + tokens[index] = (char*)SDL_malloc(max_token_len); + if(!tokens[index]) + { + int i; + SDLTest_LogError("SDL_malloc() failed."); + for(i = 0; i < index; i++) + SDL_free(tokens[i]); + return 0; + } + tokens[index][0] = '\0'; + } + + /* copy the tokens into the array */ + st_index = 0; + index = 0; + token_index = 0; + state = 0; + done = 0; + while(!done) + { + char ch = str[index]; + switch(state) + { + case 0: + if(ch == '\"') + { + state = 1; + st_index = index + 1; + } + else if(!ch) + done = 1; + else if(ch && !SDL_isspace(ch)) + { + state = 2; + st_index = index; + } + break; + + case 1: + if(ch == '\"') + { + int i; + state = 0; + for(i = st_index; i < index; i++) + { + tokens[token_index][i - st_index] = str[i]; + } + tokens[token_index][i - st_index] = '\0'; + token_index++; + } + else if(!ch) + { + SDLTest_LogError("Parsing Error!"); + done = 1; + } + break; + + case 2: + if(!ch) + done = 1; + if(SDL_isspace(ch) || !ch) + { + int i; + state = 0; + for(i = st_index; i < index; i++) + { + tokens[token_index][i - st_index] = str[i]; + } + tokens[token_index][i - st_index] = '\0'; + token_index++; + } + break; + } + index++; + } + return 1; +} + +char** +SDLVisualTest_Tokenize(char* str, int max_token_len) +{ + int num_tokens; + char** tokens; + + if(!str) + { + SDLTest_LogError("str argument cannot be NULL"); + return NULL; + } + if(max_token_len <= 0) + { + SDLTest_LogError("max_token_len argument must be positive"); + return NULL; + } + + num_tokens = CountTokens(str); + if(num_tokens == 0) + return NULL; + + tokens = (char**)SDL_malloc(sizeof(char*) * (num_tokens + 1)); + if(!TokenizeHelper(str, tokens, num_tokens, max_token_len)) + { + SDLTest_LogError("TokenizeHelper() failed"); + SDL_free(tokens); + return NULL; + } + return tokens; +} + +char** +SDLVisualTest_ParseArgsToArgv(char* args) +{ + char** argv; + int num_tokens; + + num_tokens = CountTokens(args); + if(num_tokens == 0) + return NULL; + + /* allocate space for arguments */ + argv = (char**)SDL_malloc((num_tokens + 2) * sizeof(char*)); + if(!argv) + { + SDLTest_LogError("SDL_malloc() failed."); + return NULL; + } + + /* tokenize */ + if(!TokenizeHelper(args, argv + 1, num_tokens, MAX_SUT_ARGS_LEN)) + { + SDLTest_LogError("TokenizeHelper() failed"); + SDL_free(argv); + return NULL; + } + argv[0] = NULL; + return argv; +} diff --git a/visualtest/src/rwhelper.c b/visualtest/src/rwhelper.c new file mode 100644 index 0000000..1ff9190 --- /dev/null +++ b/visualtest/src/rwhelper.c @@ -0,0 +1,131 @@ +/* See LICENSE.txt for the full license governing this code. */ +/** + * \file rwhelper.c + * + * Source file with some helper functions for working with SDL_RWops. + */ + +#include +#include "SDL_visualtest_sut_configparser.h" +#include "SDL_visualtest_rwhelper.h" + +void +SDLVisualTest_RWHelperResetBuffer(SDLVisualTest_RWHelperBuffer* buffer) +{ + if(!buffer) + { + SDLTest_LogError("buffer argument cannot be NULL"); + return; + } + buffer->buffer_pos = 0; + buffer->buffer_width = 0; +} + +char +SDLVisualTest_RWHelperReadChar(SDL_RWops* rw, SDLVisualTest_RWHelperBuffer* buffer) +{ + if(!rw || !buffer) + return 0; + /* if the buffer has been consumed, we fill it up again */ + if(buffer->buffer_pos == buffer->buffer_width) + { + buffer->buffer_width = SDL_RWread(rw, buffer->buffer, 1, RWOPS_BUFFER_LEN); + buffer->buffer_pos = 0; + if(buffer->buffer_width == 0) + return 0; + } + buffer->buffer_pos++; + return buffer->buffer[buffer->buffer_pos - 1]; +} + +/* does not include new lines in the buffer and adds a trailing null character */ +char* +SDLVisualTest_RWHelperReadLine(SDL_RWops* rw, char* str, int size, + SDLVisualTest_RWHelperBuffer* buffer, + char comment_char) +{ + char ch; + int current_pos, done; + if(!rw) + { + SDLTest_LogError("rw argument cannot be NULL"); + return NULL; + } + if(!str) + { + SDLTest_LogError("str argument cannot be NULL"); + return NULL; + } + if(!buffer) + { + SDLTest_LogError("buffer argument cannot be NULL"); + return NULL; + } + if(size <= 0) + { + SDLTest_LogError("size argument should be positive"); + return NULL; + } + + done = 0; + while(!done) + { + /* ignore leading whitespace */ + for(ch = SDLVisualTest_RWHelperReadChar(rw, buffer); ch && SDL_isspace(ch); + ch = SDLVisualTest_RWHelperReadChar(rw, buffer)); + + for(current_pos = 0; + ch && ch != '\n' && ch != '\r' && ch != comment_char; + current_pos++) + { + str[current_pos] = ch; + if(current_pos >= size - 2) + { + current_pos++; + break; + } + ch = SDLVisualTest_RWHelperReadChar(rw, buffer); + } + + done = 1; + if(ch == comment_char) /* discard all characters until the next line */ + { + do + { + ch = SDLVisualTest_RWHelperReadChar(rw, buffer); + }while(ch && ch != '\n' && ch != '\r'); + + if(current_pos == 0) + done = 0; + } + } + if(current_pos == 0) + return NULL; + + str[current_pos] = '\0'; + return str; +} + +/* Lines with all whitespace are ignored */ +int +SDLVisualTest_RWHelperCountNonEmptyLines(SDL_RWops* rw, + SDLVisualTest_RWHelperBuffer* buffer, + char comment_char) +{ + int num_lines = 0; + char str[MAX_SUTOPTION_LINE_LENGTH]; + if(!rw) + { + SDLTest_LogError("rw argument cannot be NULL"); + return -1; + } + if(!buffer) + { + SDLTest_LogError("buffer argument cannot be NULL"); + return -1; + } + while(SDLVisualTest_RWHelperReadLine(rw, str, MAX_SUTOPTION_LINE_LENGTH, + buffer, comment_char)) + num_lines++; + return num_lines; +} diff --git a/visualtest/src/screenshot.c b/visualtest/src/screenshot.c new file mode 100644 index 0000000..be5e4df --- /dev/null +++ b/visualtest/src/screenshot.c @@ -0,0 +1,136 @@ +/* See LICENSE.txt for the full license governing this code. */ +/** + * \file screenshot.c + * + * Source file for the screenshot API. + */ + +#include "SDL_visualtest_mischelper.h" +#include + +int +SDLVisualTest_VerifyScreenshots(char* args, char* test_dir, char* verify_dir) +{ + int i, verify_len, return_code, test_len; + char hash[33]; + char* verify_path; /* path to the bmp file used for verification */ + char* test_path; /* path to the bmp file to be verified */ + SDL_RWops* rw; + SDL_Surface* verifybmp; + + return_code = 1; + + if(!args) + { + SDLTest_LogError("args argument cannot be NULL"); + return_code = -1; + goto verifyscreenshots_cleanup_generic; + } + if(!test_dir) + { + SDLTest_LogError("test_dir argument cannot be NULL"); + return_code = -1; + goto verifyscreenshots_cleanup_generic; + } + if(!verify_dir) + { + SDLTest_LogError("verify_dir argument cannot be NULL"); + return_code = -1; + goto verifyscreenshots_cleanup_generic; + } + + /* generate the MD5 hash */ + SDLVisualTest_HashString(args, hash); + + /* find the verification image */ + /* path_len + hash_len + some number of extra characters */ + verify_len = SDL_strlen(verify_dir) + 32 + 10; + verify_path = (char*)SDL_malloc(verify_len * sizeof(char)); + if(!verify_path) + { + SDLTest_LogError("SDL_malloc() failed"); + return_code = -1; + goto verifyscreenshots_cleanup_generic; + } + SDL_snprintf(verify_path, verify_len - 1, + "%s/%s.bmp", verify_dir, hash); + rw = SDL_RWFromFile(verify_path, "rb"); + if(!rw) + { + SDLTest_Log("Verification image does not exist." + " Please manually verify that the SUT is working correctly."); + return_code = 2; + goto verifyscreenshots_cleanup_verifypath; + } + + /* load the verification image */ + verifybmp = SDL_LoadBMP_RW(rw, 1); + if(!verifybmp) + { + SDLTest_LogError("SDL_LoadBMP_RW() failed"); + return_code = -1; + goto verifyscreenshots_cleanup_verifypath; + } + + /* load the test images and compare with the verification image */ + /* path_len + hash_len + some number of extra characters */ + test_len = SDL_strlen(test_dir) + 32 + 10; + test_path = (char*)SDL_malloc(test_len * sizeof(char)); + if(!test_path) + { + SDLTest_LogError("SDL_malloc() failed"); + return_code = -1; + goto verifyscreenshots_cleanup_verifybmp; + } + + for(i = 1; ; i++) + { + SDL_RWops* testrw; + SDL_Surface* testbmp; + + if(i == 1) + SDL_snprintf(test_path, test_len - 1, "%s/%s.bmp", test_dir, hash); + else + SDL_snprintf(test_path, test_len - 1, "%s/%s_%d.bmp", test_dir, hash, i); + testrw = SDL_RWFromFile(test_path, "rb"); + + /* we keep going until we've iterated through the screenshots each + SUT window */ + if(!testrw) + break; + + /* load the test screenshot */ + testbmp = SDL_LoadBMP_RW(testrw, 1); + if(!testbmp) + { + SDLTest_LogError("SDL_LoadBMP_RW() failed"); + return_code = -1; + goto verifyscreenshots_cleanup_verifybmp; + } + + /* compare with the verification image */ + if(SDLTest_CompareSurfaces(testbmp, verifybmp, 0) != 0) + { + return_code = 0; + SDL_FreeSurface(testbmp); + goto verifyscreenshots_cleanup_verifybmp; + } + + SDL_FreeSurface(testbmp); + } + + if(i == 1) + { + SDLTest_LogError("No verification images found"); + return_code = -1; + } + +verifyscreenshots_cleanup_verifybmp: + SDL_FreeSurface(verifybmp); + +verifyscreenshots_cleanup_verifypath: + SDL_free(verify_path); + +verifyscreenshots_cleanup_generic: + return return_code; +} diff --git a/visualtest/src/sut_configparser.c b/visualtest/src/sut_configparser.c new file mode 100644 index 0000000..fa8c2d4 --- /dev/null +++ b/visualtest/src/sut_configparser.c @@ -0,0 +1,232 @@ +/* See LICENSE.txt for the full license governing this code. */ +/** + * \file sut_configparser.c + * + * Source file for the parser for SUT config files. + */ + +#include +#include +#include +#include +#include "SDL_visualtest_sut_configparser.h" +#include "SDL_visualtest_parsehelper.h" +#include "SDL_visualtest_rwhelper.h" + +int +SDLVisualTest_ParseSUTConfig(char* file, SDLVisualTest_SUTConfig* config) +{ + char line[MAX_SUTOPTION_LINE_LENGTH]; + SDLVisualTest_RWHelperBuffer buffer; + char* token_ptr; + char* token_end; + int num_lines, i, token_len; + SDL_RWops* rw; + + if(!file) + { + SDLTest_LogError("file argument cannot be NULL"); + return 0; + } + if(!config) + { + SDLTest_LogError("config argument cannot be NULL"); + return 0; + } + + /* count the number of lines */ + rw = SDL_RWFromFile(file, "r"); + if(!rw) + { + SDLTest_LogError("SDL_RWFromFile() failed"); + return 0; + } + SDLVisualTest_RWHelperResetBuffer(&buffer); + num_lines = SDLVisualTest_RWHelperCountNonEmptyLines(rw, &buffer, '#'); + if(num_lines == -1) + return 0; + else if(num_lines == 0) + { + config->options = NULL; + config->num_options = 0; + SDL_RWclose(rw); + return 1; + } + + /* allocate memory */ + SDL_RWseek(rw, 0, RW_SEEK_SET); + SDLVisualTest_RWHelperResetBuffer(&buffer); + config->num_options = num_lines; + config->options = (SDLVisualTest_SUTOption*)SDL_malloc(num_lines * + sizeof(SDLVisualTest_SUTOption)); + if(!config->options) + { + SDLTest_LogError("SDL_malloc() failed"); + SDL_RWclose(rw); + return 0; + } + + /* actually parse the options */ + for(i = 0; i < num_lines; i++) + { + if(!SDLVisualTest_RWHelperReadLine(rw, line, MAX_SUTOPTION_LINE_LENGTH, + &buffer, '#')) + { + SDLTest_LogError("SDLVisualTest_RWHelperReadLine() failed"); + SDL_free(config->options); + SDL_RWclose(rw); + return 0; + } + + /* parse name */ + token_ptr = strtok(line, ", "); + if(!token_ptr) + { + SDLTest_LogError("Could not parse line %d", i + 1); + SDL_free(config->options); + SDL_RWclose(rw); + return 0; + } + token_len = SDL_strlen(token_ptr) + 1; + SDL_strlcpy(config->options[i].name, token_ptr, token_len); + + /* parse type */ + token_ptr = strtok(NULL, ", "); + if(!token_ptr) + { + SDLTest_LogError("Could not parse line %d", i + 1); + SDL_free(config->options); + SDL_RWclose(rw); + return 0; + } + if(SDL_strcmp(token_ptr, "string") == 0) + config->options[i].type = SDL_SUT_OPTIONTYPE_STRING; + else if(SDL_strcmp(token_ptr, "integer") == 0) + config->options[i].type = SDL_SUT_OPTIONTYPE_INT; + else if(SDL_strcmp(token_ptr, "enum") == 0) + config->options[i].type = SDL_SUT_OPTIONTYPE_ENUM; + else if(SDL_strcmp(token_ptr, "boolean") == 0) + config->options[i].type = SDL_SUT_OPTIONTYPE_BOOL; + else + { + SDLTest_LogError("Could not parse type token at line %d", i + 1); + SDL_free(config->options); + SDL_RWclose(rw); + return 0; + } + + /* parse values */ + token_ptr = strtok(NULL, "]"); + if(!token_ptr) + { + SDLTest_LogError("Could not parse line %d", i + 1); + SDL_free(config->options); + SDL_RWclose(rw); + return 0; + } + token_ptr = SDL_strchr(token_ptr, '['); + if(!token_ptr) + { + SDLTest_LogError("Could not parse enum token at line %d", i + 1); + SDL_free(config->options); + SDL_RWclose(rw); + return 0; + } + token_ptr++; + if(config->options[i].type == SDL_SUT_OPTIONTYPE_INT) + { + if(SDL_sscanf(token_ptr, "%d %d", &config->options[i].data.range.min, + &config->options[i].data.range.max) != 2) + { + config->options[i].data.range.min = INT_MIN; + config->options[i].data.range.max = INT_MAX; + } + } + else if(config->options[i].type == SDL_SUT_OPTIONTYPE_ENUM) + { + config->options[i].data.enum_values = SDLVisualTest_Tokenize(token_ptr, + MAX_SUTOPTION_ENUMVAL_LEN); + if(!config->options[i].data.enum_values) + { + SDLTest_LogError("Could not parse enum token at line %d", i + 1); + SDL_free(config->options); + SDL_RWclose(rw); + return 0; + } + } + + /* parse required */ + token_ptr = strtok(NULL, ", "); + if(!token_ptr) + { + SDLTest_LogError("Could not parse line %d", i + 1); + SDL_free(config->options); + SDL_RWclose(rw); + return 0; + } + + if(SDL_strcmp(token_ptr, "true") == 0) + config->options[i].required = SDL_TRUE; + else if(SDL_strcmp(token_ptr, "false") == 0) + config->options[i].required = SDL_FALSE; + else + { + SDLTest_LogError("Could not parse required token at line %d", i + 1); + SDL_free(config->options); + SDL_RWclose(rw); + return 0; + } + + /* parse categories */ + token_ptr = strtok(NULL, ","); + if(!token_ptr) + { + SDLTest_LogError("Could not parse line %d", i + 1); + SDL_free(config->options); + SDL_RWclose(rw); + return 0; + } + token_ptr = SDL_strchr(token_ptr, '['); + if(!token_ptr) + { + SDLTest_LogError("Could not parse enum token at line %d", i + 1); + SDL_free(config->options); + SDL_RWclose(rw); + return 0; + } + token_ptr++; + token_end = SDL_strchr(token_ptr, ']'); + *token_end = '\0'; + if(!token_end) + { + SDLTest_LogError("Could not parse enum token at line %d", i + 1); + SDL_free(config->options); + SDL_RWclose(rw); + return 0; + } + config->options[i].categories = SDLVisualTest_Tokenize(token_ptr, + MAX_SUTOPTION_CATEGORY_LEN); + } + SDL_RWclose(rw); + return 1; +} + +void +SDLVisualTest_FreeSUTConfig(SDLVisualTest_SUTConfig* config) +{ + if(config && config->options) + { + SDLVisualTest_SUTOption* option; + for(option = config->options; + option != config->options + config->num_options; option++) + { + if(option->categories) + SDL_free(option->categories); + if(option->type == SDL_SUT_OPTIONTYPE_ENUM && option->data.enum_values) + SDL_free(option->data.enum_values); + } + SDL_free(config->options); + config->options = NULL; + config->num_options = 0; + } +} diff --git a/visualtest/src/testharness.c b/visualtest/src/testharness.c new file mode 100644 index 0000000..db3ca55 --- /dev/null +++ b/visualtest/src/testharness.c @@ -0,0 +1,532 @@ +/* See LICENSE.txt for the full license governing this code. */ +/** + * \file testharness.c + * + * Source file for the test harness. + */ + +#include +#include +#include +#include +#include "SDL_visualtest_harness_argparser.h" +#include "SDL_visualtest_process.h" +#include "SDL_visualtest_variators.h" +#include "SDL_visualtest_screenshot.h" +#include "SDL_visualtest_mischelper.h" + +#if defined(__WIN32__) && !defined(__CYGWIN__) +#include +#elif defined(__WIN32__) && defined(__CYGWIN__) +#include +#elif defined(__LINUX__) +#include +#include +#include +#else +#error "Unsupported platform" +#endif + +/** Code for the user event triggered when a new action is to be executed */ +#define ACTION_TIMER_EVENT 0 +/** Code for the user event triggered when the maximum timeout is reached */ +#define KILL_TIMER_EVENT 1 +/** FPS value used for delays in the action loop */ +#define ACTION_LOOP_FPS 10 + +/** Value returned by RunSUTAndTest() when the test has passed */ +#define TEST_PASSED 1 +/** Value returned by RunSUTAndTest() when the test has failed */ +#define TEST_FAILED 0 +/** Value returned by RunSUTAndTest() on a fatal error */ +#define TEST_ERROR -1 + +static SDL_ProcessInfo pinfo; +static SDL_ProcessExitStatus sut_exitstatus; +static SDLVisualTest_HarnessState state; +static SDLVisualTest_Variator variator; +static SDLVisualTest_ActionNode* current; /* the current action being performed */ +static SDL_TimerID action_timer, kill_timer; + +/* returns a char* to be passed as the format argument of a printf-style function. */ +static const char* +usage(void) +{ + return "Usage: \n%s --sutapp xyz" + " [--sutargs abc | --parameter-config xyz.parameters" + " [--variator exhaustive|random]" + " [--num-variations N] [--no-launch]] [--timeout hh:mm:ss]" + " [--action-config xyz.actions]" + " [--output-dir /path/to/output]" + " [--verify-dir /path/to/verify]" + " or --config app.config"; +} + +/* register Ctrl+C handlers */ +#if defined(__LINUX__) || defined(__CYGWIN__) +static void +CtrlCHandlerCallback(int signum) +{ + SDL_Event event; + SDLTest_Log("Ctrl+C received"); + event.type = SDL_QUIT; + SDL_PushEvent(&event); +} +#endif + +static Uint32 +ActionTimerCallback(Uint32 interval, void* param) +{ + SDL_Event event; + SDL_UserEvent userevent; + Uint32 next_action_time; + + /* push an event to handle the action */ + SDL_zero(userevent); + userevent.type = SDL_USEREVENT; + userevent.code = ACTION_TIMER_EVENT; + userevent.data1 = ¤t->action; + + event.type = SDL_USEREVENT; + event.user = userevent; + SDL_PushEvent(&event); + + /* calculate the new interval and return it */ + if(current->next) + next_action_time = current->next->action.time - current->action.time; + else + { + next_action_time = 0; + action_timer = 0; + } + + current = current->next; + return next_action_time; +} + +static Uint32 +KillTimerCallback(Uint32 interval, void* param) +{ + SDL_Event event; + SDL_UserEvent userevent; + + SDL_zero(userevent); + userevent.type = SDL_USEREVENT; + userevent.code = KILL_TIMER_EVENT; + + event.type = SDL_USEREVENT; + event.user = userevent; + SDL_PushEvent(&event); + + kill_timer = 0; + return 0; +} + +static int +ProcessAction(SDLVisualTest_Action* action, int* sut_running, char* args) +{ + if(!action || !sut_running) + return TEST_ERROR; + + switch(action->type) + { + case SDL_ACTION_KILL: + SDLTest_Log("Action: Kill SUT"); + if(SDL_IsProcessRunning(&pinfo) == 1 && + !SDL_KillProcess(&pinfo, &sut_exitstatus)) + { + SDLTest_LogError("SDL_KillProcess() failed"); + return TEST_ERROR; + } + *sut_running = 0; + break; + + case SDL_ACTION_QUIT: + SDLTest_Log("Action: Quit SUT"); + if(SDL_IsProcessRunning(&pinfo) == 1 && + !SDL_QuitProcess(&pinfo, &sut_exitstatus)) + { + SDLTest_LogError("SDL_QuitProcess() failed"); + return TEST_FAILED; + } + *sut_running = 0; + break; + + case SDL_ACTION_LAUNCH: + { + char* path; + char* args; + SDL_ProcessInfo action_process; + SDL_ProcessExitStatus ps; + + path = action->extra.process.path; + args = action->extra.process.args; + if(args) + { + SDLTest_Log("Action: Launch process: %s with arguments: %s", + path, args); + } + else + SDLTest_Log("Action: Launch process: %s", path); + if(!SDL_LaunchProcess(path, args, &action_process)) + { + SDLTest_LogError("SDL_LaunchProcess() failed"); + return TEST_ERROR; + } + + /* small delay so that the process can do its job */ + SDL_Delay(1000); + + if(SDL_IsProcessRunning(&action_process) > 0) + { + SDLTest_LogError("Process %s took too long too complete." + " Force killing...", action->extra.process.path); + if(!SDL_KillProcess(&action_process, &ps)) + { + SDLTest_LogError("SDL_KillProcess() failed"); + return TEST_ERROR; + } + } + } + break; + + case SDL_ACTION_SCREENSHOT: + { + char path[MAX_PATH_LEN], hash[33]; + + SDLTest_Log("Action: Take screenshot"); + /* can't take a screenshot if the SUT isn't running */ + if(SDL_IsProcessRunning(&pinfo) != 1) + { + SDLTest_LogError("SUT has quit."); + *sut_running = 0; + return TEST_FAILED; + } + + /* file name for the screenshot image */ + SDLVisualTest_HashString(args, hash); + SDL_snprintf(path, MAX_PATH_LEN, "%s/%s", state.output_dir, hash); + if(!SDLVisualTest_ScreenshotProcess(&pinfo, path)) + { + SDLTest_LogError("SDLVisualTest_ScreenshotProcess() failed"); + return TEST_ERROR; + } + } + break; + + case SDL_ACTION_VERIFY: + { + int ret; + + SDLTest_Log("Action: Verify screenshot"); + ret = SDLVisualTest_VerifyScreenshots(args, state.output_dir, + state.verify_dir); + + if(ret == -1) + { + SDLTest_LogError("SDLVisualTest_VerifyScreenshots() failed"); + return TEST_ERROR; + } + else if(ret == 0) + { + SDLTest_Log("Verification failed: Images were not equal."); + return TEST_FAILED; + } + else if(ret == 1) + SDLTest_Log("Verification successful."); + else + { + SDLTest_Log("Verfication skipped."); + return TEST_FAILED; + } + } + break; + + default: + SDLTest_LogError("Invalid action type"); + return TEST_ERROR; + break; + } + + return TEST_PASSED; +} + +static int +RunSUTAndTest(char* sutargs, int variation_num) +{ + int success, sut_running, return_code; + char hash[33]; + SDL_Event event; + + return_code = TEST_PASSED; + + if(!sutargs) + { + SDLTest_LogError("sutargs argument cannot be NULL"); + return_code = TEST_ERROR; + goto runsutandtest_cleanup_generic; + } + + SDLVisualTest_HashString(sutargs, hash); + SDLTest_Log("Hash: %s", hash); + + success = SDL_LaunchProcess(state.sutapp, sutargs, &pinfo); + if(!success) + { + SDLTest_Log("Could not launch SUT."); + return_code = TEST_ERROR; + goto runsutandtest_cleanup_generic; + } + SDLTest_Log("SUT launch successful."); + SDLTest_Log("Process will be killed in %d milliseconds", state.timeout); + sut_running = 1; + + /* launch the timers */ + SDLTest_Log("Performing actions.."); + current = state.action_queue.front; + action_timer = 0; + kill_timer = 0; + if(current) + { + action_timer = SDL_AddTimer(current->action.time, ActionTimerCallback, NULL); + if(!action_timer) + { + SDLTest_LogError("SDL_AddTimer() failed"); + return_code = TEST_ERROR; + goto runsutandtest_cleanup_timer; + } + } + kill_timer = SDL_AddTimer(state.timeout, KillTimerCallback, NULL); + if(!kill_timer) + { + SDLTest_LogError("SDL_AddTimer() failed"); + return_code = TEST_ERROR; + goto runsutandtest_cleanup_timer; + } + + /* the timer stops running if the actions queue is empty, and the + SUT stops running if it crashes or if we encounter a KILL/QUIT action */ + while(sut_running) + { + /* process the actions by using an event queue */ + while(SDL_PollEvent(&event)) + { + if(event.type == SDL_USEREVENT) + { + if(event.user.code == ACTION_TIMER_EVENT) + { + SDLVisualTest_Action* action; + + action = (SDLVisualTest_Action*)event.user.data1; + + switch(ProcessAction(action, &sut_running, sutargs)) + { + case TEST_PASSED: + break; + + case TEST_FAILED: + return_code = TEST_FAILED; + goto runsutandtest_cleanup_timer; + break; + + default: + SDLTest_LogError("ProcessAction() failed"); + return_code = TEST_ERROR; + goto runsutandtest_cleanup_timer; + } + } + else if(event.user.code == KILL_TIMER_EVENT) + { + SDLTest_LogError("Maximum timeout reached. Force killing.."); + return_code = TEST_FAILED; + goto runsutandtest_cleanup_timer; + } + } + else if(event.type == SDL_QUIT) + { + SDLTest_LogError("Received QUIT event. Testharness is quitting.."); + return_code = TEST_ERROR; + goto runsutandtest_cleanup_timer; + } + } + SDL_Delay(1000/ACTION_LOOP_FPS); + } + + SDLTest_Log("SUT exit code was: %d", sut_exitstatus.exit_status); + if(sut_exitstatus.exit_status == 0) + { + return_code = TEST_PASSED; + goto runsutandtest_cleanup_timer; + } + else + { + return_code = TEST_FAILED; + goto runsutandtest_cleanup_timer; + } + + return_code = TEST_ERROR; + goto runsutandtest_cleanup_generic; + +runsutandtest_cleanup_timer: + if(action_timer && !SDL_RemoveTimer(action_timer)) + { + SDLTest_Log("SDL_RemoveTimer() failed"); + return_code = TEST_ERROR; + } + + if(kill_timer && !SDL_RemoveTimer(kill_timer)) + { + SDLTest_Log("SDL_RemoveTimer() failed"); + return_code = TEST_ERROR; + } +/* runsutandtest_cleanup_process: */ + if(SDL_IsProcessRunning(&pinfo) && !SDL_KillProcess(&pinfo, &sut_exitstatus)) + { + SDLTest_Log("SDL_KillProcess() failed"); + return_code = TEST_ERROR; + } +runsutandtest_cleanup_generic: + return return_code; +} + +/** Entry point for testharness */ +int +main(int argc, char* argv[]) +{ + int i, passed, return_code, failed; + + /* freeing resources, linux style! */ + return_code = 0; + + if(argc < 2) + { + SDLTest_Log(usage(), argv[0]); + goto cleanup_generic; + } + +#if defined(__LINUX__) || defined(__CYGWIN__) + signal(SIGINT, CtrlCHandlerCallback); +#endif + + /* parse arguments */ + if(!SDLVisualTest_ParseHarnessArgs(argv + 1, &state)) + { + SDLTest_Log(usage(), argv[0]); + return_code = 1; + goto cleanup_generic; + } + SDLTest_Log("Parsed harness arguments successfully."); + + /* initialize SDL */ + if(SDL_Init(SDL_INIT_TIMER) == -1) + { + SDLTest_LogError("SDL_Init() failed."); + SDLVisualTest_FreeHarnessState(&state); + return_code = 1; + goto cleanup_harness_state; + } + + /* create an output directory if none exists */ +#if defined(__LINUX__) || defined(__CYGWIN__) + mkdir(state.output_dir, 0777); +#elif defined(__WIN32__) + _mkdir(state.output_dir); +#else +#error "Unsupported platform" +#endif + + /* test with sutargs */ + if(SDL_strlen(state.sutargs)) + { + SDLTest_Log("Running: %s %s", state.sutapp, state.sutargs); + if(!state.no_launch) + { + switch(RunSUTAndTest(state.sutargs, 0)) + { + case TEST_PASSED: + SDLTest_Log("Status: PASSED"); + break; + + case TEST_FAILED: + SDLTest_Log("Status: FAILED"); + break; + + case TEST_ERROR: + SDLTest_LogError("Some error occurred while testing."); + return_code = 1; + goto cleanup_sdl; + break; + } + } + } + + if(state.sut_config.num_options > 0) + { + const char* variator_name = (state.variator_type == SDL_VARIATOR_RANDOM) ? + "RANDOM" : "EXHAUSTIVE"; + if(state.num_variations > 0) + SDLTest_Log("Testing SUT with variator: %s for %d variations", + variator_name, state.num_variations); + else + SDLTest_Log("Testing SUT with variator: %s and ALL variations", + variator_name); + /* initialize the variator */ + if(!SDLVisualTest_InitVariator(&variator, &state.sut_config, + state.variator_type, 0)) + { + SDLTest_LogError("Could not initialize variator"); + return_code = 1; + goto cleanup_sdl; + } + + /* iterate through all the variations */ + passed = 0; + failed = 0; + for(i = 0; state.num_variations > 0 ? (i < state.num_variations) : 1; i++) + { + char* args = SDLVisualTest_GetNextVariation(&variator); + if(!args) + break; + SDLTest_Log("\nVariation number: %d\nArguments: %s", i + 1, args); + + if(!state.no_launch) + { + switch(RunSUTAndTest(args, i + 1)) + { + case TEST_PASSED: + SDLTest_Log("Status: PASSED"); + passed++; + break; + + case TEST_FAILED: + SDLTest_Log("Status: FAILED"); + failed++; + break; + + case TEST_ERROR: + SDLTest_LogError("Some error occurred while testing."); + goto cleanup_variator; + break; + } + } + } + if(!state.no_launch) + { + /* report stats */ + SDLTest_Log("Testing complete."); + SDLTest_Log("%d/%d tests passed.", passed, passed + failed); + } + goto cleanup_variator; + } + + goto cleanup_sdl; + +cleanup_variator: + SDLVisualTest_FreeVariator(&variator); +cleanup_sdl: + SDL_Quit(); +cleanup_harness_state: + SDLVisualTest_FreeHarnessState(&state); +cleanup_generic: + return return_code; +} diff --git a/visualtest/src/variator_common.c b/visualtest/src/variator_common.c new file mode 100644 index 0000000..e8444b3 --- /dev/null +++ b/visualtest/src/variator_common.c @@ -0,0 +1,225 @@ +/* See LICENSE.txt for the full license governing this code. */ +/** + * \file variator_common.c + * + * Source file for some common functionality used by variators. + */ + +#include +#include "SDL_visualtest_variator_common.h" + +int +SDLVisualTest_NextValue(SDLVisualTest_SUTOptionValue* var, + SDLVisualTest_SUTOption* opt) +{ + if(!var) + { + SDLTest_LogError("var argument cannot be NULL"); + return -1; + } + if(!opt) + { + SDLTest_LogError("opt argument cannot be NULL"); + return -1; + } + + switch(opt->type) + { + case SDL_SUT_OPTIONTYPE_BOOL: + if(var->bool_value) + { + var->bool_value = SDL_FALSE; + return 1; + } + else + { + var->bool_value = SDL_TRUE; + return 0; + } + break; + + case SDL_SUT_OPTIONTYPE_ENUM: + var->enumerated.index++; + if(!opt->data.enum_values[var->enumerated.index]) + { + var->enumerated.index = 0; + return 1; + } + return 0; + break; + + case SDL_SUT_OPTIONTYPE_INT: + { + int increment = (opt->data.range.max - opt->data.range.min) / + SDL_SUT_INTEGER_OPTION_TEST_STEPS; + /* prevents infinite loop when rounding */ + if(increment == 0) + increment = 1; + var->integer.value += increment; + if(var->integer.value > opt->data.range.max) + { + var->integer.value = opt->data.range.min; + return 1; + } + return 0; + } + break; + + case SDL_SUT_OPTIONTYPE_STRING: + return 1; + break; + } + return -1; +} + +int +SDLVisualTest_MakeStrFromVariation(SDLVisualTest_Variation* variation, + SDLVisualTest_SUTConfig* config, + char* buffer, int size) +{ + int i, index; + SDLVisualTest_SUTOptionValue* vars; + SDLVisualTest_SUTOption* options; + if(!variation) + { + SDLTest_LogError("variation argument cannot be NULL"); + return 0; + } + if(!config) + { + SDLTest_LogError("config argument cannot be NULL"); + return 0; + } + if(!buffer) + { + SDLTest_LogError("buffer argument cannot be NULL"); + return 0; + } + if(size <= 0) + { + SDLTest_LogError("size argument should be positive"); + return 0; + } + + index = 0; + buffer[0] = '\0'; + options = config->options; + vars = variation->vars; + for(i = 0; i < variation->num_vars; i++) + { + int n, enum_index; + if(index >= size - 1) + { + SDLTest_LogError("String did not fit in buffer size"); + return 0; + } + switch(options[i].type) + { + case SDL_SUT_OPTIONTYPE_BOOL: + if(vars[i].bool_value) + { + n = SDL_snprintf(buffer + index, size - index, "%s ", + options[i].name); + if(n <= 0) + { + SDLTest_LogError("SDL_snprintf() failed"); + return 0; + } + index += n; + } + break; + + case SDL_SUT_OPTIONTYPE_ENUM: + if(vars[i].enumerated.on) + { + enum_index = vars[i].enumerated.index; + n = SDL_snprintf(buffer + index, size - index, "%s %s ", + options[i].name, options[i].data.enum_values[enum_index]); + index += n; + } + break; + + case SDL_SUT_OPTIONTYPE_INT: + if(vars[i].integer.on) + { + n = SDL_snprintf(buffer + index, size - index, "%s %d ", + options[i].name, vars[i].integer.value); + index += n; + } + break; + + case SDL_SUT_OPTIONTYPE_STRING: + if(vars[i].string.on) + { + n = SDL_snprintf(buffer + index, size - index, "%s %s ", + options[i].name, vars[i].string.value); + index += n; + } + break; + } + } + return 1; +} + +int +SDLVisualTest_InitVariation(SDLVisualTest_Variation* variation, + SDLVisualTest_SUTConfig* config) +{ + int i; + SDLVisualTest_SUTOptionValue* vars; + SDLVisualTest_SUTOption* options; + if(!variation) + { + SDLTest_LogError("variation argument cannot be NULL"); + return 0; + } + if(!config) + { + SDLTest_LogError("config argument cannot be NULL"); + return 0; + } + + /* initialize the first variation */ + if(config->num_options <= 0) + { + SDLTest_LogError("config->num_options must be positive"); + return 0; + } + variation->vars = (SDLVisualTest_SUTOptionValue*)SDL_malloc(config->num_options * + sizeof(SDLVisualTest_SUTOptionValue)); + if(!variation->vars) + { + SDLTest_LogError("SDL_malloc() failed"); + return 0; + } + variation->num_vars = config->num_options; + vars = variation->vars; + options = config->options; + for(i = 0; i < variation->num_vars; i++) + { + switch(options[i].type) + { + case SDL_SUT_OPTIONTYPE_BOOL: + vars[i].bool_value = SDL_FALSE; + break; + + case SDL_SUT_OPTIONTYPE_ENUM: + vars[i].enumerated.on = SDL_TRUE; + vars[i].enumerated.index = 0; + break; + + case SDL_SUT_OPTIONTYPE_INT: + { + vars[i].integer.on = SDL_TRUE; + vars[i].integer.value = options[i].data.range.min; + } + break; + + case SDL_SUT_OPTIONTYPE_STRING: + vars[i].string.on = SDL_TRUE; + vars[i].string.value = options[i].name; + break; + } + } + return 1; +} diff --git a/visualtest/src/variator_exhaustive.c b/visualtest/src/variator_exhaustive.c new file mode 100644 index 0000000..1e6a79e --- /dev/null +++ b/visualtest/src/variator_exhaustive.c @@ -0,0 +1,133 @@ +/* See LICENSE.txt for the full license governing this code. */ +/** + * \file variator_exhaustive.c + * + * Source file for the variator that tests the SUT with all the different + * variations of input parameters that are valid. + */ + +#include +#include +#include "SDL_visualtest_sut_configparser.h" +#include "SDL_visualtest_exhaustive_variator.h" + +static int +NextVariation(SDLVisualTest_Variation* variation, + SDLVisualTest_SUTConfig* config) +{ + int i, carry; + if(!variation) + { + SDLTest_LogError("variation argument cannot be NULL"); + return -1; + } + if(!config) + { + SDLTest_LogError("config argument cannot be NULL"); + return -1; + } + + carry = 1; + for(i = 0; i < variation->num_vars; i++) + { + carry = SDLVisualTest_NextValue(&variation->vars[i], &config->options[i]); + if(carry != 1) + break; + } + + if(carry == 1) /* we're done, we've tried all possible variations */ + return 0; + if(carry == 0) + return 1; + + SDLTest_LogError("NextVariation() failed"); + return -1; +} + +int +SDLVisualTest_InitExhaustiveVariator(SDLVisualTest_ExhaustiveVariator* variator, + SDLVisualTest_SUTConfig* config) +{ + if(!variator) + { + SDLTest_LogError("variator argument cannot be NULL"); + return 0; + } + if(!config) + { + SDLTest_LogError("config argument cannot be NULL"); + return 0; + } + + SDLTest_FuzzerInit(time(NULL)); + + variator->config = *config; + variator->variation.num_vars = 0; + variator->variation.vars = NULL; + + return 1; +} + +/* TODO: Right now variations where an option is not specified at all are not + tested for. This can be implemented by switching the on attribute for integer, + enum and string options to true and false. */ +char* +SDLVisualTest_GetNextExhaustiveVariation(SDLVisualTest_ExhaustiveVariator* variator) +{ + int success; + if(!variator) + { + SDLTest_LogError("variator argument cannot be NULL"); + return NULL; + } + + if(!variator->variation.vars) /* the first time this function is called */ + { + success = SDLVisualTest_InitVariation(&variator->variation, + &variator->config); + if(!success) + { + SDLTest_LogError("SDLVisualTest_InitVariation() failed"); + return NULL; + } + success = SDLVisualTest_MakeStrFromVariation(&variator->variation, + &variator->config, variator->buffer, MAX_SUT_ARGS_LEN); + if(!success) + { + SDLTest_LogError("SDLVisualTest_MakeStrFromVariation() failed"); + return NULL; + } + return variator->buffer; + } + else + { + success = NextVariation(&variator->variation, &variator->config); + if(success == 1) + { + success = SDLVisualTest_MakeStrFromVariation(&variator->variation, + &variator->config, variator->buffer, MAX_SUT_ARGS_LEN); + if(!success) + { + SDLTest_LogError("SDLVisualTest_MakeStrFromVariation() failed"); + return NULL; + } + return variator->buffer; + } + else if(success == -1) + SDLTest_LogError("NextVariation() failed."); + return NULL; + } + return NULL; +} + +void +SDLVisualTest_FreeExhaustiveVariator(SDLVisualTest_ExhaustiveVariator* variator) +{ + if(!variator) + { + SDLTest_LogError("variator argument cannot be NULL"); + return; + } + SDL_free(variator->variation.vars); + variator->variation.vars = NULL; +} diff --git a/visualtest/src/variator_random.c b/visualtest/src/variator_random.c new file mode 100644 index 0000000..4da4161 --- /dev/null +++ b/visualtest/src/variator_random.c @@ -0,0 +1,113 @@ +/* See LICENSE.txt for the full license governing this code. */ +/** + * \file variator_random.c + * + * Source file for the variator that tests the SUT with random variations to the + * input parameters. + */ + +#include +#include +#include "SDL_visualtest_random_variator.h" + +int +SDLVisualTest_InitRandomVariator(SDLVisualTest_RandomVariator* variator, + SDLVisualTest_SUTConfig* config, Uint64 seed) +{ + if(!variator) + { + SDLTest_LogError("variator argument cannot be NULL"); + return 0; + } + if(!config) + { + SDLTest_LogError("config argument cannot be NULL"); + return 0; + } + + if(seed) + SDLTest_FuzzerInit(seed); + else + SDLTest_FuzzerInit(time(NULL)); + + variator->config = *config; + + if(!SDLVisualTest_InitVariation(&variator->variation, &variator->config)) + { + SDLTest_LogError("SDLVisualTest_InitVariation() failed"); + return 0; + } + + return 1; +} + +char* +SDLVisualTest_GetNextRandomVariation(SDLVisualTest_RandomVariator* variator) +{ + SDLVisualTest_SUTOptionValue* vars; + SDLVisualTest_SUTOption* options; + int i; + + if(!variator) + { + SDLTest_LogError("variator argument cannot be NULL"); + return NULL; + } + + /* to save typing */ + vars = variator->variation.vars; + options = variator->config.options; + + /* generate a random variation */ + for(i = 0; i < variator->variation.num_vars; i++) + { + switch(options[i].type) + { + case SDL_SUT_OPTIONTYPE_BOOL: + vars[i].bool_value = SDLTest_RandomIntegerInRange(0, 1) ? SDL_FALSE : + SDL_TRUE; + break; + + case SDL_SUT_OPTIONTYPE_ENUM: + { + int emx = 0; + while(options[i].data.enum_values[emx]) + emx++; + vars[i].enumerated.index = SDLTest_RandomIntegerInRange(0, emx - 1); + } + break; + + case SDL_SUT_OPTIONTYPE_INT: + vars[i].integer.value = SDLTest_RandomIntegerInRange( + options[i].data.range.min, + options[i].data.range.max); + break; + + case SDL_SUT_OPTIONTYPE_STRING: + // String values are left unchanged + break; + } + } + + /* convert variation to an arguments string */ + if(!SDLVisualTest_MakeStrFromVariation(&variator->variation, &variator->config, + variator->buffer, MAX_SUT_ARGS_LEN)) + { + SDLTest_LogError("SDLVisualTest_MakeStrFromVariation() failed"); + return NULL; + } + + return variator->buffer; +} + +void SDLVisualTest_FreeRandomVariator(SDLVisualTest_RandomVariator* variator) +{ + if(!variator) + { + SDLTest_LogError("variator argument cannot be NULL"); + return; + } + + SDL_free(variator->variation.vars); + variator->variation.vars = NULL; +} diff --git a/visualtest/src/variators.c b/visualtest/src/variators.c new file mode 100644 index 0000000..e9485c6 --- /dev/null +++ b/visualtest/src/variators.c @@ -0,0 +1,95 @@ +/* See LICENSE.txt for the full license governing this code. */ +/** + * \file variators.c + * + * Source file for the operations that act on variators. + */ + +#include +#include "SDL_visualtest_variators.h" + +int +SDLVisualTest_InitVariator(SDLVisualTest_Variator* variator, + SDLVisualTest_SUTConfig* config, + SDLVisualTest_VariatorType type, + Uint64 seed) +{ + if(!variator) + { + SDLTest_LogError("variator argument cannot be NULL"); + return 0; + } + if(!config) + { + SDLTest_LogError("config argument cannot be NULL"); + return 0; + } + + variator->type = type; + switch(type) + { + case SDL_VARIATOR_EXHAUSTIVE: + return SDLVisualTest_InitExhaustiveVariator(&variator->data.exhaustive, + config); + break; + + case SDL_VARIATOR_RANDOM: + return SDLVisualTest_InitRandomVariator(&variator->data.random, + config, seed); + break; + + default: + SDLTest_LogError("Invalid value for variator type"); + return 0; + } + return 0; +} + +char* +SDLVisualTest_GetNextVariation(SDLVisualTest_Variator* variator) +{ + if(!variator) + { + SDLTest_LogError("variator argument cannot be NULL"); + return NULL; + } + + switch(variator->type) + { + case SDL_VARIATOR_EXHAUSTIVE: + return SDLVisualTest_GetNextExhaustiveVariation(&variator->data.exhaustive); + break; + + case SDL_VARIATOR_RANDOM: + return SDLVisualTest_GetNextRandomVariation(&variator->data.random); + break; + + default: + SDLTest_LogError("Invalid value for variator type"); + return NULL; + } + return NULL; +} + +void SDLVisualTest_FreeVariator(SDLVisualTest_Variator* variator) +{ + if(!variator) + { + SDLTest_LogError("variator argument cannot be NULL"); + return; + } + + switch(variator->type) + { + case SDL_VARIATOR_EXHAUSTIVE: + SDLVisualTest_FreeExhaustiveVariator(&variator->data.exhaustive); + break; + + case SDL_VARIATOR_RANDOM: + SDLVisualTest_FreeRandomVariator(&variator->data.random); + break; + + default: + SDLTest_LogError("Invalid value for variator type"); + } +} diff --git a/visualtest/src/windows/windows_process.c b/visualtest/src/windows/windows_process.c new file mode 100644 index 0000000..e7e265c --- /dev/null +++ b/visualtest/src/windows/windows_process.c @@ -0,0 +1,283 @@ +/* See LICENSE.txt for the full license governing this code. */ +/** + * \file windows_process.c + * + * Source file for the process API on windows. + */ + +#include +#include +#include +#include + +#include "SDL_visualtest_process.h" + +#if defined(__WIN32__) + +void +LogLastError(const char* str) +{ + LPVOID buffer; + DWORD dw = GetLastError(); + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM| + FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&buffer, + 0, NULL); + SDLTest_LogError("%s: %s", str, (char*)buffer); + LocalFree(buffer); +} + +int +SDL_LaunchProcess(char* file, char* args, SDL_ProcessInfo* pinfo) +{ + BOOL success; + char* working_directory; + char* command_line; + int path_length, args_length; + STARTUPINFO sui = {0}; + sui.cb = sizeof(sui); + + if(!file) + { + SDLTest_LogError("Path to executable to launched cannot be NULL."); + return 0; + } + if(!pinfo) + { + SDLTest_LogError("pinfo cannot be NULL."); + return 0; + } + + /* get the working directory of the process being launched, so that + the process can load any resources it has in it's working directory */ + path_length = SDL_strlen(file); + if(path_length == 0) + { + SDLTest_LogError("Length of the file parameter is zero."); + return 0; + } + + working_directory = (char*)SDL_malloc(path_length + 1); + if(!working_directory) + { + SDLTest_LogError("Could not allocate working_directory - SDL_malloc() failed."); + return 0; + } + + SDL_memcpy(working_directory, file, path_length + 1); + PathRemoveFileSpec(working_directory); + if(SDL_strlen(working_directory) == 0) + { + SDL_free(working_directory); + working_directory = NULL; + } + + /* join the file path and the args string together */ + if(!args) + args = ""; + args_length = SDL_strlen(args); + command_line = (char*)SDL_malloc(path_length + args_length + 2); + if(!command_line) + { + SDLTest_LogError("Could not allocate command_line - SDL_malloc() failed."); + return 0; + } + SDL_memcpy(command_line, file, path_length); + command_line[path_length] = ' '; + SDL_memcpy(command_line + path_length + 1, args, args_length + 1); + + /* create the process */ + success = CreateProcess(NULL, command_line, NULL, NULL, FALSE, + NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, + NULL, working_directory, &sui, &pinfo->pi); + if(working_directory) + { + SDL_free(working_directory); + working_directory = NULL; + } + SDL_free(command_line); + if(!success) + { + LogLastError("CreateProcess() failed"); + return 0; + } + + return 1; +} + +int +SDL_GetProcessExitStatus(SDL_ProcessInfo* pinfo, SDL_ProcessExitStatus* ps) +{ + DWORD exit_status; + BOOL success; + + if(!pinfo) + { + SDLTest_LogError("pinfo cannot be NULL"); + return 0; + } + if(!ps) + { + SDLTest_LogError("ps cannot be NULL"); + return 0; + } + + /* get the exit code */ + success = GetExitCodeProcess(pinfo->pi.hProcess, &exit_status); + if(!success) + { + LogLastError("GetExitCodeProcess() failed"); + return 0; + } + + if(exit_status == STILL_ACTIVE) + ps->exit_status = -1; + else + ps->exit_status = exit_status; + ps->exit_success = 1; + return 1; +} + + +int +SDL_IsProcessRunning(SDL_ProcessInfo* pinfo) +{ + DWORD exit_status; + BOOL success; + + if(!pinfo) + { + SDLTest_LogError("pinfo cannot be NULL"); + return -1; + } + + success = GetExitCodeProcess(pinfo->pi.hProcess, &exit_status); + if(!success) + { + LogLastError("GetExitCodeProcess() failed"); + return -1; + } + + if(exit_status == STILL_ACTIVE) + return 1; + return 0; +} + +static BOOL CALLBACK +CloseWindowCallback(HWND hwnd, LPARAM lparam) +{ + DWORD pid; + SDL_ProcessInfo* pinfo; + + pinfo = (SDL_ProcessInfo*)lparam; + + GetWindowThreadProcessId(hwnd, &pid); + if(pid == pinfo->pi.dwProcessId) + { + DWORD_PTR result; + if(!SendMessageTimeout(hwnd, WM_CLOSE, 0, 0, SMTO_BLOCK, + 1000, &result)) + { + if(GetLastError() != ERROR_TIMEOUT) + { + LogLastError("SendMessageTimeout() failed"); + return FALSE; + } + } + } + return TRUE; +} + +int +SDL_QuitProcess(SDL_ProcessInfo* pinfo, SDL_ProcessExitStatus* ps) +{ + DWORD wait_result; + if(!pinfo) + { + SDLTest_LogError("pinfo argument cannot be NULL"); + return 0; + } + if(!ps) + { + SDLTest_LogError("ps argument cannot be NULL"); + return 0; + } + + /* enumerate through all the windows, trying to close each one */ + if(!EnumWindows(CloseWindowCallback, (LPARAM)pinfo)) + { + SDLTest_LogError("EnumWindows() failed"); + return 0; + } + + /* wait until the process terminates */ + wait_result = WaitForSingleObject(pinfo->pi.hProcess, 1000); + if(wait_result == WAIT_FAILED) + { + LogLastError("WaitForSingleObject() failed"); + return 0; + } + if(wait_result != WAIT_OBJECT_0) + { + SDLTest_LogError("Process did not quit."); + return 0; + } + + /* get the exit code */ + if(!SDL_GetProcessExitStatus(pinfo, ps)) + { + SDLTest_LogError("SDL_GetProcessExitStatus() failed"); + return 0; + } + + return 1; +} + +int +SDL_KillProcess(SDL_ProcessInfo* pinfo, SDL_ProcessExitStatus* ps) +{ + BOOL success; + DWORD exit_status, wait_result; + + if(!pinfo) + { + SDLTest_LogError("pinfo argument cannot be NULL"); + return 0; + } + if(!ps) + { + SDLTest_LogError("ps argument cannot be NULL"); + return 0; + } + + /* initiate termination of the process */ + success = TerminateProcess(pinfo->pi.hProcess, 0); + if(!success) + { + LogLastError("TerminateProcess() failed"); + return 0; + } + + /* wait until the process terminates */ + wait_result = WaitForSingleObject(pinfo->pi.hProcess, INFINITE); + if(wait_result == WAIT_FAILED) + { + LogLastError("WaitForSingleObject() failed"); + return 0; + } + + /* get the exit code */ + success = GetExitCodeProcess(pinfo->pi.hProcess, &exit_status); + if(!success) + { + LogLastError("GetExitCodeProcess() failed"); + return 0; + } + + ps->exit_status = exit_status; + ps->exit_success = 1; + + return 1; +} + +#endif diff --git a/visualtest/src/windows/windows_screenshot.c b/visualtest/src/windows/windows_screenshot.c new file mode 100644 index 0000000..d4ac7d3 --- /dev/null +++ b/visualtest/src/windows/windows_screenshot.c @@ -0,0 +1,349 @@ +/* See LICENSE.txt for the full license governing this code. */ +/** + * \file windows_screenshot.c + * + * Source file for the screenshot API on windows. + */ + +#include "SDL_visualtest_process.h" +#include +#include + +#if defined(__CYGWIN__) +#include +#endif + +#if defined(__WIN32__) +#include + +void LogLastError(const char* str); + +static int img_num; +static SDL_ProcessInfo screenshot_pinfo; + +/* Saves a bitmap to a file using hdc as a device context */ +static int +SaveBitmapToFile(HDC hdc, HBITMAP hbitmap, char* filename) +{ + BITMAP bitmap; + BITMAPFILEHEADER bfh; + BITMAPINFOHEADER bih; + DWORD bmpsize, bytes_written; + HANDLE hdib, hfile; + char* bmpdata; + int return_code = 1; + + if(!hdc) + { + SDLTest_LogError("hdc argument is NULL"); + return 0; + } + if(!hbitmap) + { + SDLTest_LogError("hbitmap argument is NULL"); + return 0; + } + if(!filename) + { + SDLTest_LogError("filename argument is NULL"); + return 0; + } + + if(!GetObject(hbitmap, sizeof(BITMAP), (void*)&bitmap)) + { + SDLTest_LogError("GetObject() failed"); + return_code = 0; + goto savebitmaptofile_cleanup_generic; + } + + bih.biSize = sizeof(BITMAPINFOHEADER); + bih.biWidth = bitmap.bmWidth; + bih.biHeight = bitmap.bmHeight; + bih.biPlanes = 1; + bih.biBitCount = 32; + bih.biCompression = BI_RGB; + bih.biSizeImage = 0; + bih.biXPelsPerMeter = 0; + bih.biYPelsPerMeter = 0; + bih.biClrUsed = 0; + bih.biClrImportant = 0; + + bmpsize = ((bitmap.bmWidth * bih.biBitCount + 31) / 32) * 4 * bitmap.bmHeight; + + hdib = GlobalAlloc(GHND, bmpsize); + if(!hdib) + { + LogLastError("GlobalAlloc() failed"); + return_code = 0; + goto savebitmaptofile_cleanup_generic; + } + bmpdata = (char*)GlobalLock(hdib); + if(!bmpdata) + { + LogLastError("GlobalLock() failed"); + return_code = 0; + goto savebitmaptofile_cleanup_hdib; + } + + if(!GetDIBits(hdc, hbitmap, 0, (UINT)bitmap.bmHeight, bmpdata, + (LPBITMAPINFO)&bih, DIB_RGB_COLORS)) + { + SDLTest_LogError("GetDIBits() failed"); + return_code = 0; + goto savebitmaptofile_cleanup_unlockhdib; + } + + hfile = CreateFile(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, NULL); + if(hfile == INVALID_HANDLE_VALUE) + { + LogLastError("CreateFile()"); + return_code = 0; + goto savebitmaptofile_cleanup_unlockhdib; + } + bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); + bfh.bfSize = bmpsize + bfh.bfOffBits; + bfh.bfType = 0x4D42; + + bytes_written = 0; + if(!WriteFile(hfile, (void*)&bfh, sizeof(BITMAPFILEHEADER), &bytes_written, NULL) || + !WriteFile(hfile, (void*)&bih, sizeof(BITMAPINFOHEADER), &bytes_written, NULL) || + !WriteFile(hfile, (void*)bmpdata, bmpsize, &bytes_written, NULL)) + { + LogLastError("WriteFile() failed"); + return_code = 0; + goto savebitmaptofile_cleanup_hfile; + } + +savebitmaptofile_cleanup_hfile: + CloseHandle(hfile); + +/* make the screenshot file writable on cygwin, since it could be overwritten later */ +#if defined(__CYGWIN__) + if(chmod(filename, 0777) == -1) + { + SDLTest_LogError("chmod() failed"); + return_code = 0; + } +#endif + +savebitmaptofile_cleanup_unlockhdib: + GlobalUnlock(hdib); + +savebitmaptofile_cleanup_hdib: + GlobalFree(hdib); + +savebitmaptofile_cleanup_generic: + return return_code; +} + +/* Takes the screenshot of a window and saves it to a file. If only_client_area + is true, then only the client area of the window is considered */ +static int +ScreenshotWindow(HWND hwnd, char* filename, SDL_bool only_client_area) +{ + int width, height; + RECT dimensions; + HDC windowdc, capturedc; + HBITMAP capturebitmap; + HGDIOBJ select_success; + BOOL blt_success; + int return_code = 1; + + if(!filename) + { + SDLTest_LogError("filename argument cannot be NULL"); + return_code = 0; + goto screenshotwindow_cleanup_generic; + } + if(!hwnd) + { + SDLTest_LogError("hwnd argument cannot be NULL"); + return_code = 0; + goto screenshotwindow_cleanup_generic; + } + + if(!GetWindowRect(hwnd, &dimensions)) + { + LogLastError("GetWindowRect() failed"); + return_code = 0; + goto screenshotwindow_cleanup_generic; + } + + if(only_client_area) + { + RECT crect; + if(!GetClientRect(hwnd, &crect)) + { + SDLTest_LogError("GetClientRect() failed"); + return_code = 0; + goto screenshotwindow_cleanup_generic; + } + + width = crect.right; + height = crect.bottom; + windowdc = GetDC(hwnd); + if(!windowdc) + { + SDLTest_LogError("GetDC() failed"); + return_code = 0; + goto screenshotwindow_cleanup_generic; + } + } + else + { + width = dimensions.right - dimensions.left; + height = dimensions.bottom - dimensions.top; + windowdc = GetWindowDC(hwnd); + if(!windowdc) + { + SDLTest_LogError("GetWindowDC() failed"); + return_code = 0; + goto screenshotwindow_cleanup_generic; + } + } + + capturedc = CreateCompatibleDC(windowdc); + if(!capturedc) + { + SDLTest_LogError("CreateCompatibleDC() failed"); + return_code = 0; + goto screenshotwindow_cleanup_windowdc; + } + capturebitmap = CreateCompatibleBitmap(windowdc, width, height); + if(!capturebitmap) + { + SDLTest_LogError("CreateCompatibleBitmap() failed"); + return_code = 0; + goto screenshotwindow_cleanup_capturedc; + } + select_success = SelectObject(capturedc, capturebitmap); + if(!select_success || select_success == HGDI_ERROR) + { + SDLTest_LogError("SelectObject() failed"); + return_code = 0; + goto screenshotwindow_cleanup_capturebitmap; + } + blt_success = BitBlt(capturedc, 0, 0, width, height, windowdc, + 0, 0, SRCCOPY|CAPTUREBLT); + if(!blt_success) + { + LogLastError("BitBlt() failed"); + return_code = 0; + goto screenshotwindow_cleanup_capturebitmap; + } + + /* save bitmap as file */ + if(!SaveBitmapToFile(windowdc, capturebitmap, filename)) + { + SDLTest_LogError("SaveBitmapToFile() failed"); + return_code = 0; + goto screenshotwindow_cleanup_capturebitmap; + } + + /* Free resources */ + +screenshotwindow_cleanup_capturebitmap: + if(!DeleteObject(capturebitmap)) + { + SDLTest_LogError("DeleteObjectFailed"); + return_code = 0; + } + +screenshotwindow_cleanup_capturedc: + if(!DeleteDC(capturedc)) + { + SDLTest_LogError("DeleteDC() failed"); + return_code = 0; + } + +screenshotwindow_cleanup_windowdc: + if(!ReleaseDC(hwnd, windowdc)) + { + SDLTest_LogError("ReleaseDC() failed"); + return_code = 0; + } + +screenshotwindow_cleanup_generic: + return return_code; +} + +/* Takes the screenshot of the entire desktop and saves it to a file */ +int SDLVisualTest_ScreenshotDesktop(char* filename) +{ + HWND hwnd; + hwnd = GetDesktopWindow(); + return ScreenshotWindow(hwnd, filename, SDL_FALSE); +} + +/* take screenshot of a window and save it to a file */ +static BOOL CALLBACK +ScreenshotHwnd(HWND hwnd, LPARAM lparam) +{ + int len; + DWORD pid; + char* prefix; + char* filename; + + GetWindowThreadProcessId(hwnd, &pid); + if(pid != screenshot_pinfo.pi.dwProcessId) + return TRUE; + + if(!IsWindowVisible(hwnd)) + return TRUE; + + prefix = (char*)lparam; + len = SDL_strlen(prefix) + 100; + filename = (char*)SDL_malloc(len * sizeof(char)); + if(!filename) + { + SDLTest_LogError("SDL_malloc() failed"); + return FALSE; + } + + /* restore the window and bring it to the top */ + ShowWindowAsync(hwnd, SW_RESTORE); + /* restore is not instantaneous */ + SDL_Delay(500); + + /* take a screenshot of the client area */ + if(img_num == 1) + SDL_snprintf(filename, len, "%s.bmp", prefix); + else + SDL_snprintf(filename, len, "%s_%d.bmp", prefix, img_num); + img_num++; + ScreenshotWindow(hwnd, filename, SDL_TRUE); + + SDL_free(filename); + return TRUE; +} + + +/* each window of the process will have a screenshot taken. The file name will be + prefix-i.png for the i'th window. */ +int +SDLVisualTest_ScreenshotProcess(SDL_ProcessInfo* pinfo, char* prefix) +{ + if(!pinfo) + { + SDLTest_LogError("pinfo argument cannot be NULL"); + return 0; + } + if(!prefix) + { + SDLTest_LogError("prefix argument cannot be NULL"); + return 0; + } + + img_num = 1; + screenshot_pinfo = *pinfo; + if(!EnumWindows(ScreenshotHwnd, (LPARAM)prefix)) + { + SDLTest_LogError("EnumWindows() failed"); + return 0; + } + + return 1; +} + +#endif diff --git a/visualtest/testsprite2_sample.actions b/visualtest/testsprite2_sample.actions new file mode 100644 index 0000000..c0e9ab8 --- /dev/null +++ b/visualtest/testsprite2_sample.actions @@ -0,0 +1,3 @@ +00:00:02 SCREENSHOT # Take a screenshot of each window owned by the SUT process +00:00:05 VERIFY # Verify each screenshot taken with verification images +00:00:10 QUIT # Gracefully quit the SUT process \ No newline at end of file diff --git a/visualtest/testsprite2_sample.config b/visualtest/testsprite2_sample.config new file mode 100644 index 0000000..14eb462 --- /dev/null +++ b/visualtest/testsprite2_sample.config @@ -0,0 +1,6 @@ +parameter-config=testsprite2_sample.parameters +num-variations=10 +variator=random +sutapp=testsprite2 +timeout=00:00:20 +action-config=testsprite2_sample.actions \ No newline at end of file diff --git a/visualtest/testsprite2_sample.parameters b/visualtest/testsprite2_sample.parameters new file mode 100644 index 0000000..29e34cd --- /dev/null +++ b/visualtest/testsprite2_sample.parameters @@ -0,0 +1,29 @@ +# parameter name, type, value range, required, categories +--gldebug, boolean, [], false, [] +--info, enum, [all video modes render event], false, [] +--log, enum, [all error system audio video render input], false, [] +--display, integer, [1 5], false, [] +--fullscreen, boolean, [], false, [] +--fullscreen-desktop, boolean, [], false, [] +# --windows, integer, [1 5], false, [] # this option is not supported yet +--title, enum, [vartest bartest footest], false, [] +--icon, enum, [icon.bmp], false, [] +--center, boolean, [], false, [] +--position, enum, [300,300], false, [] +--geometry, enum, [500x500], false, [] +--min-geometry, enum, [100x100], false, [] +--max-geometry, enum, [600x600 700x700], false, [] +--logical, enum, [500x500 550x450], false, [] +--scale, integer, [1 5], false, [] +--depth, integer, [1 5], false, [] +--refresh, integer, [1 5], false, [] +--vsync, boolean, [], false, [] +--noframe, boolean, [], false, [] +--resize, boolean, [], false, [] +--minimize, boolean, [], false, [] +--maximize, boolean, [], false, [] +--grab, boolean, [], false, [mouse] +--blend, enum, [none blend add mod], false, [] +--cyclecolor, boolean, [], false, [] +--cyclealpha, boolean, [], false, [] +--iterations, integer, [10 100], false, [] \ No newline at end of file diff --git a/visualtest/unittest/testquit.actions b/visualtest/unittest/testquit.actions new file mode 100644 index 0000000..fa68805 --- /dev/null +++ b/visualtest/unittest/testquit.actions @@ -0,0 +1 @@ +00:00:05 QUIT \ No newline at end of file diff --git a/visualtest/unittest/testquit.c b/visualtest/unittest/testquit.c new file mode 100644 index 0000000..04e3c5c --- /dev/null +++ b/visualtest/unittest/testquit.c @@ -0,0 +1,102 @@ +/* + Copyright (C) 2013 Apoorv Upreti + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely. +*/ +/* Quits, hangs or crashes based on the command line options passed. */ + +#include +#include + +static SDLTest_CommonState *state; +static int exit_code; +static SDL_bool hang; +static SDL_bool crash; + +int +main(int argc, char** argv) +{ + int i, done; + SDL_Event event; + + state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); + if(!state) + return 1; + + state->window_flags |= SDL_WINDOW_RESIZABLE; + + exit_code = 0; + hang = SDL_FALSE; + crash = SDL_FALSE; + + for(i = 1; i < argc; ) + { + int consumed; + consumed = SDLTest_CommonArg(state, i); + if(consumed == 0) + { + consumed = -1; + if(SDL_strcasecmp(argv[i], "--exit-code") == 0) + { + if(argv[i + 1]) + { + exit_code = SDL_atoi(argv[i + 1]); + consumed = 2; + } + } + else if(SDL_strcasecmp(argv[i], "--hang") == 0) + { + hang = SDL_TRUE; + consumed = 1; + } + else if(SDL_strcasecmp(argv[i], "--crash") == 0) + { + crash = SDL_TRUE; + consumed = 1; + } + } + + if(consumed < 0) + { + static const char *options[] = { "[--exit-code N]", "[--crash]", "[--hang]", NULL }; + SDLTest_CommonLogUsage(state, argv[0], options); + SDLTest_CommonQuit(state); + return 1; + } + i += consumed; + } + + if(!SDLTest_CommonInit(state)) + { + SDLTest_CommonQuit(state); + return 1; + } + + /* infinite loop to hang the process */ + while(hang) + SDL_Delay(10); + + /* dereference NULL pointer to crash process */ + if(crash) + { + int* p = NULL; + *p = 5; + } + + /* event loop */ + done = 0; + while(!done) + { + while(SDL_PollEvent(&event)) + SDLTest_CommonEvent(state, &event, &done); + SDL_Delay(10); + } + + return exit_code; +} diff --git a/visualtest/unittest/testquit.config b/visualtest/unittest/testquit.config new file mode 100644 index 0000000..756dec8 --- /dev/null +++ b/visualtest/unittest/testquit.config @@ -0,0 +1,5 @@ +sutconfig=testquit.parameters +action-config=testquit.actions +variator=exhaustive +sutapp=testquit +timeout=00:00:10 \ No newline at end of file diff --git a/visualtest/unittest/testquit.parameters b/visualtest/unittest/testquit.parameters new file mode 100644 index 0000000..6e5887c --- /dev/null +++ b/visualtest/unittest/testquit.parameters @@ -0,0 +1,3 @@ +--exit-code, integer, [-1 1], false, [] # The exit code returned by the executable +--crash, boolean, [], false, [] # Crashes the SUT executable +--hang, boolean, [], false, [] # Runs the SUT in the infinite loop and ignores all events \ No newline at end of file