Mac and Linux SDL2 binary snapshots
Edward Rudd
2016-11-10 0588787d882ebce4e4993672d80a7a910bde3979

update source to SDL 2 2.0.5

1 files renamed
370 files modified
12 files added
1 files deleted
3 files copied
22372 ■■■■ changed files
source/.hgignore 4 ●●●● patch | view | raw | blame | history
source/.hgtags 1 ●●●● patch | view | raw | blame | history
source/BUGS.txt 2 ●●● patch | view | raw | blame | history
source/CMakeLists.txt 162 ●●●● patch | view | raw | blame | history
source/Makefile.in 11 ●●●● patch | view | raw | blame | history
source/Makefile.pandora 2 ●●● patch | view | raw | blame | history
source/Makefile.psp 1 ●●●● patch | view | raw | blame | history
source/Makefile.wiz 10 ●●●● patch | view | raw | blame | history
source/README-SDL.txt 4 ●●●● patch | view | raw | blame | history
source/VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj 10 ●●●●● patch | view | raw | blame | history
source/VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj.filters 9 ●●●●● patch | view | raw | blame | history
source/VisualC-WinRT/WinPhone80_VS2012/SDL-WinPhone80.vcxproj 8 ●●●● patch | view | raw | blame | history
source/VisualC-WinRT/WinPhone80_VS2012/SDL-WinPhone80.vcxproj.filters 9 ●●●●● patch | view | raw | blame | history
source/VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.vcxproj 8 ●●●● patch | view | raw | blame | history
source/VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.vcxproj.filters 9 ●●●●● patch | view | raw | blame | history
source/VisualC-WinRT/WinRT80_VS2012/SDL-WinRT80.vcxproj 10 ●●●●● patch | view | raw | blame | history
source/VisualC-WinRT/WinRT80_VS2012/SDL-WinRT80.vcxproj.filters 9 ●●●●● patch | view | raw | blame | history
source/VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj 10 ●●●●● patch | view | raw | blame | history
source/VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj.filters 9 ●●●●● patch | view | raw | blame | history
source/VisualC.html 4 ●●●● patch | view | raw | blame | history
source/VisualC/SDL/SDL.vcxproj 1 ●●●● patch | view | raw | blame | history
source/VisualC/SDL/SDL.vcxproj.filters 1 ●●●● patch | view | raw | blame | history
source/VisualC/SDL/SDL_VS2008.vcproj 6 ●●●●● patch | view | raw | blame | history
source/VisualC/SDLmain/SDLmain_VS2008.vcproj 2 ●●●●● patch | view | raw | blame | history
source/VisualC/SDLtest/SDLtest_VS2008.vcproj 2 ●●●●● patch | view | raw | blame | history
source/WhatsNew.txt 63 ●●●●● patch | view | raw | blame | history
source/Xcode-iOS/Demos/Demos.xcodeproj/project.pbxproj 257 ●●●●● patch | view | raw | blame | history
source/Xcode-iOS/Demos/Info.plist 4 ●●● patch | view | raw | blame | history
source/Xcode-iOS/Demos/README 6 ●●●● patch | view | raw | blame | history
source/Xcode-iOS/Demos/iOS Launch Screen.storyboard 40 ●●●●● patch | view | raw | blame | history
source/Xcode-iOS/Demos/src/accelerometer.c 45 ●●●●● patch | view | raw | blame | history
source/Xcode-iOS/Demos/src/common.c 20 ●●●●● patch | view | raw | blame | history
source/Xcode-iOS/Demos/src/common.h 4 ●●● patch | view | raw | blame | history
source/Xcode-iOS/Demos/src/fireworks.c 71 ●●●● patch | view | raw | blame | history
source/Xcode-iOS/Demos/src/happy.c 71 ●●●● patch | view | raw | blame | history
source/Xcode-iOS/Demos/src/keyboard.c 19 ●●●●● patch | view | raw | blame | history
source/Xcode-iOS/Demos/src/mixer.c 45 ●●●●● patch | view | raw | blame | history
source/Xcode-iOS/Demos/src/rectangles.c 91 ●●●●● patch | view | raw | blame | history
source/Xcode-iOS/Demos/src/touch.c 16 ●●●●● patch | view | raw | blame | history
source/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj 342 ●●●●● patch | view | raw | blame | history
source/Xcode-iOS/SDLtest/SDL2test.xcodeproj/project.pbxproj 145 ●●●●● patch | view | raw | blame | history
source/Xcode-iOS/Test/README 11 ●●●●● patch | view | raw | blame | history
source/Xcode-iOS/Test/TestiPhoneOS.xcodeproj/project.pbxproj 485 ●●●●● patch | view | raw | blame | history
source/Xcode/SDL/Info-Framework.plist 6 ●●●● patch | view | raw | blame | history
source/Xcode/SDL/SDL.xcodeproj/project.pbxproj 113 ●●●●● patch | view | raw | blame | history
source/android-project/AndroidManifest.xml 5 ●●●● patch | view | raw | blame | history
source/android-project/jni/Application.mk 4 ●●●● patch | view | raw | blame | history
source/android-project/src/org/libsdl/app/SDLActivity.java 157 ●●●● patch | view | raw | blame | history
source/autogen.sh 6 ●●●●● patch | view | raw | blame | history
source/build-scripts/androidbuild.sh 8 ●●●● patch | view | raw | blame | history
source/build-scripts/checker-buildbot.sh 6 ●●●● patch | view | raw | blame | history
source/build-scripts/emscripten-buildbot.sh 7 ●●●●● patch | view | raw | blame | history
source/build-scripts/g++-fat.sh 6 ●●●● patch | view | raw | blame | history
source/build-scripts/gcc-fat.sh 8 ●●●● patch | view | raw | blame | history
source/build-scripts/showrev.sh 4 ●●● patch | view | raw | blame | history
source/cmake/sdlchecks.cmake 98 ●●●●● patch | view | raw | blame | history
source/configure 289 ●●●●● patch | view | raw | blame | history
source/configure.in 200 ●●●●● patch | view | raw | blame | history
source/debian/changelog 6 ●●●●● patch | view | raw | blame | history
source/debian/copyright 11 ●●●●● patch | view | raw | blame | history
source/debian/libsdl2-dev.install 1 ●●●● patch | view | raw | blame | history
source/docs/README-android.md 27 ●●●● patch | view | raw | blame | history
source/docs/README-ios.md 18 ●●●● patch | view | raw | blame | history
source/docs/README-linux.md 168 ●●●● patch | view | raw | blame | history
source/docs/README-macosx.md 53 ●●●●● patch | view | raw | blame | history
source/docs/README-porting.md 9 ●●●●● patch | view | raw | blame | history
source/docs/README-raspberrypi.md 2 ●●● patch | view | raw | blame | history
source/docs/README-touch.md 14 ●●●● patch | view | raw | blame | history
source/docs/README-winrt.md 946 ●●●● patch | view | raw | blame | history
source/include/SDL.h 20 ●●●● patch | view | raw | blame | history
source/include/SDL_audio.h 95 ●●●● patch | view | raw | blame | history
source/include/SDL_config.h.cmake 2 ●●●●● patch | view | raw | blame | history
source/include/SDL_config.h.in 4 ●●●● patch | view | raw | blame | history
source/include/SDL_config_android.h 3 ●●●●● patch | view | raw | blame | history
source/include/SDL_config_iphoneos.h 6 ●●●● patch | view | raw | blame | history
source/include/SDL_events.h 8 ●●●● patch | view | raw | blame | history
source/include/SDL_gamecontroller.h 6 ●●●● patch | view | raw | blame | history
source/include/SDL_haptic.h 32 ●●●● patch | view | raw | blame | history
source/include/SDL_hints.h 112 ●●●● patch | view | raw | blame | history
source/include/SDL_joystick.h 2 ●●● patch | view | raw | blame | history
source/include/SDL_keyboard.h 2 ●●● patch | view | raw | blame | history
source/include/SDL_main.h 2 ●●● patch | view | raw | blame | history
source/include/SDL_mouse.h 6 ●●●●● patch | view | raw | blame | history
source/include/SDL_opengles.h 1 ●●●● patch | view | raw | blame | history
source/include/SDL_opengles2.h 2 ●●●●● patch | view | raw | blame | history
source/include/SDL_pixels.h 14 ●●●●● patch | view | raw | blame | history
source/include/SDL_platform.h 14 ●●●●● patch | view | raw | blame | history
source/include/SDL_render.h 27 ●●●●● patch | view | raw | blame | history
source/include/SDL_rwops.h 12 ●●●● patch | view | raw | blame | history
source/include/SDL_stdinc.h 10 ●●●● patch | view | raw | blame | history
source/include/SDL_surface.h 10 ●●●●● patch | view | raw | blame | history
source/include/SDL_syswm.h 22 ●●●●● patch | view | raw | blame | history
source/include/SDL_version.h 2 ●●● patch | view | raw | blame | history
source/include/SDL_video.h 133 ●●●●● patch | view | raw | blame | history
source/premake/README-ios.txt 1 ●●●● patch | view | raw | blame | history
source/premake/VisualC/VS2008/SDL2/SDL2.vcproj 4 ●●●● patch | view | raw | blame | history
source/premake/VisualC/VS2010/SDL2/SDL2.vcxproj 1 ●●●● patch | view | raw | blame | history
source/premake/VisualC/VS2010/SDL2/SDL2.vcxproj.filters 3 ●●●●● patch | view | raw | blame | history
source/premake/VisualC/VS2012/SDL2/SDL2.vcxproj 1 ●●●● patch | view | raw | blame | history
source/premake/VisualC/VS2012/SDL2/SDL2.vcxproj.filters 3 ●●●●● patch | view | raw | blame | history
source/premake/Xcode-iOS/SDL2/SDL2.xcodeproj/project.pbxproj 2 ●●●●● patch | view | raw | blame | history
source/premake/Xcode-iOS/SDL_config_premake.h 4 ●●●● patch | view | raw | blame | history
source/premake/Xcode/Xcode3/SDL2/SDL2.xcodeproj/project.pbxproj 2 ●●●●● patch | view | raw | blame | history
source/premake/Xcode/Xcode4/SDL2/SDL2.xcodeproj/project.pbxproj 2 ●●●●● patch | view | raw | blame | history
source/premake/premake4.lua 2 ●●● patch | view | raw | blame | history
source/premake/projects/SDL2.lua 5 ●●●●● patch | view | raw | blame | history
source/premake/util/sdl_check_compile.lua 22 ●●●● patch | view | raw | blame | history
source/premake/util/sdl_gen_config.lua 4 ●●●● patch | view | raw | blame | history
source/sdl2-config.cmake.in 1 ●●●● patch | view | raw | blame | history
source/sdl2.m4 54 ●●●● patch | view | raw | blame | history
source/src/SDL.c 22 ●●●● patch | view | raw | blame | history
source/src/SDL_error.c 7 ●●●●● patch | view | raw | blame | history
source/src/SDL_hints.c 13 ●●●●● patch | view | raw | blame | history
source/src/SDL_log.c 8 ●●●● patch | view | raw | blame | history
source/src/audio/SDL_audio.c 551 ●●●●● patch | view | raw | blame | history
source/src/audio/SDL_audio_c.h 3 ●●●●● patch | view | raw | blame | history
source/src/audio/SDL_mixer.c 50 ●●●●● patch | view | raw | blame | history
source/src/audio/SDL_sysaudio.h 24 ●●●●● patch | view | raw | blame | history
source/src/audio/SDL_wave.c 2 ●●● patch | view | raw | blame | history
source/src/audio/alsa/SDL_alsa_audio.c 452 ●●●● patch | view | raw | blame | history
source/src/audio/android/SDL_androidaudio.c 109 ●●●●● patch | view | raw | blame | history
source/src/audio/android/SDL_androidaudio.h 2 ●●●●● patch | view | raw | blame | history
source/src/audio/arts/SDL_artsaudio.c 33 ●●●● patch | view | raw | blame | history
source/src/audio/bsd/SDL_bsdaudio.c 165 ●●●●● patch | view | raw | blame | history
source/src/audio/coreaudio/SDL_coreaudio.c 698 ●●●●● patch | view | raw | blame | history
source/src/audio/coreaudio/SDL_coreaudio.h 16 ●●●● patch | view | raw | blame | history
source/src/audio/coreaudio/SDL_coreaudio.m 849 ●●●●● patch | view | raw | blame | history
source/src/audio/directsound/SDL_directsound.c 284 ●●●●● patch | view | raw | blame | history
source/src/audio/directsound/SDL_directsound.h 3 ●●●● patch | view | raw | blame | history
source/src/audio/disk/SDL_diskaudio.c 161 ●●●●● patch | view | raw | blame | history
source/src/audio/disk/SDL_diskaudio.h 5 ●●●●● patch | view | raw | blame | history
source/src/audio/dsp/SDL_dspaudio.c 74 ●●●●● patch | view | raw | blame | history
source/src/audio/dummy/SDL_dummyaudio.c 27 ●●●● patch | view | raw | blame | history
source/src/audio/emscripten/SDL_emscriptenaudio.c 288 ●●●● patch | view | raw | blame | history
source/src/audio/esd/SDL_esdaudio.c 22 ●●●● patch | view | raw | blame | history
source/src/audio/fusionsound/SDL_fsaudio.c 39 ●●●● patch | view | raw | blame | history
source/src/audio/haiku/SDL_haikuaudio.cc 24 ●●●●● patch | view | raw | blame | history
source/src/audio/nacl/SDL_naclaudio.c 37 ●●●● patch | view | raw | blame | history
source/src/audio/nas/SDL_nasaudio.c 166 ●●●●● patch | view | raw | blame | history
source/src/audio/paudio/SDL_paudio.c 24 ●●●● patch | view | raw | blame | history
source/src/audio/psp/SDL_pspaudio.c 63 ●●●●● patch | view | raw | blame | history
source/src/audio/pulseaudio/SDL_pulseaudio.c 203 ●●●●● patch | view | raw | blame | history
source/src/audio/pulseaudio/SDL_pulseaudio.h 3 ●●●●● patch | view | raw | blame | history
source/src/audio/qsa/SDL_qsa_audio.c 92 ●●●● patch | view | raw | blame | history
source/src/audio/qsa/SDL_qsa_audio.h 2 ●●● patch | view | raw | blame | history
source/src/audio/sndio/SDL_sndioaudio.c 31 ●●●● patch | view | raw | blame | history
source/src/audio/sun/SDL_sunaudio.c 21 ●●●●● patch | view | raw | blame | history
source/src/audio/winmm/SDL_winmm.c 192 ●●●●● patch | view | raw | blame | history
source/src/audio/xaudio2/SDL_xaudio2.c 84 ●●●●● patch | view | raw | blame | history
source/src/core/android/SDL_android.c 330 ●●●● patch | view | raw | blame | history
source/src/core/android/SDL_android.h 6 ●●●●● patch | view | raw | blame | history
source/src/core/linux/SDL_dbus.c 2 ●●● patch | view | raw | blame | history
source/src/core/linux/SDL_evdev.c 955 ●●●● patch | view | raw | blame | history
source/src/core/linux/SDL_evdev.h 20 ●●●●● patch | view | raw | blame | history
source/src/core/linux/SDL_fcitx.c 553 ●●●●● patch | view | raw | blame | history
source/src/core/linux/SDL_fcitx.h 21 ●●●● patch | view | raw | blame | history
source/src/core/linux/SDL_ibus.c 6 ●●●●● patch | view | raw | blame | history
source/src/core/linux/SDL_ime.c 138 ●●●●● patch | view | raw | blame | history
source/src/core/linux/SDL_ime.h 21 ●●●● patch | view | raw | blame | history
source/src/core/linux/SDL_udev.c 9 ●●●● patch | view | raw | blame | history
source/src/core/linux/SDL_udev.h 6 ●●●●● patch | view | raw | blame | history
source/src/core/windows/SDL_windows.c 78 ●●●●● patch | view | raw | blame | history
source/src/core/windows/SDL_windows.h 3 ●●●●● patch | view | raw | blame | history
source/src/core/winrt/SDL_winrtapp_direct3d.cpp 31 ●●●● patch | view | raw | blame | history
source/src/core/winrt/SDL_winrtapp_direct3d.h 4 ●●●● patch | view | raw | blame | history
source/src/dynapi/SDL_dynapi.c 2 ●●● patch | view | raw | blame | history
source/src/dynapi/SDL_dynapi.h 10 ●●●● patch | view | raw | blame | history
source/src/dynapi/SDL_dynapi_overrides.h 15 ●●●●● patch | view | raw | blame | history
source/src/dynapi/SDL_dynapi_procs.h 13 ●●●●● patch | view | raw | blame | history
source/src/events/SDL_dropevents.c 68 ●●●● patch | view | raw | blame | history
source/src/events/SDL_dropevents_c.h 4 ●●● patch | view | raw | blame | history
source/src/events/SDL_events.c 117 ●●●● patch | view | raw | blame | history
source/src/events/SDL_gesture.c 2 ●●● patch | view | raw | blame | history
source/src/events/SDL_mouse.c 70 ●●●● patch | view | raw | blame | history
source/src/events/SDL_mouse_c.h 3 ●●●●● patch | view | raw | blame | history
source/src/events/SDL_quit.c 4 ●●● patch | view | raw | blame | history
source/src/events/SDL_windowevents.c 18 ●●●●● patch | view | raw | blame | history
source/src/events/scancodes_linux.h 14 ●●●● patch | view | raw | blame | history
source/src/events/scancodes_xfree86.h 85 ●●●●● patch | view | raw | blame | history
source/src/filesystem/dummy/SDL_sysfilesystem.c 4 ●●●● patch | view | raw | blame | history
source/src/filesystem/unix/SDL_sysfilesystem.c 23 ●●●●● patch | view | raw | blame | history
source/src/haptic/linux/SDL_syshaptic.c 4 ●●●● patch | view | raw | blame | history
source/src/haptic/windows/SDL_dinputhaptic.c 19 ●●●● patch | view | raw | blame | history
source/src/haptic/windows/SDL_windowshaptic.c 2 ●●● patch | view | raw | blame | history
source/src/haptic/windows/SDL_windowshaptic_c.h 4 ●●●● patch | view | raw | blame | history
source/src/haptic/windows/SDL_xinputhaptic.c 19 ●●●● patch | view | raw | blame | history
source/src/joystick/SDL_gamecontroller.c 66 ●●●●● patch | view | raw | blame | history
source/src/joystick/SDL_gamecontrollerdb.h 14 ●●●●● patch | view | raw | blame | history
source/src/joystick/SDL_joystick.c 76 ●●●●● patch | view | raw | blame | history
source/src/joystick/SDL_joystick_c.h 6 ●●●●● patch | view | raw | blame | history
source/src/joystick/SDL_sysjoystick.h 1 ●●●● patch | view | raw | blame | history
source/src/joystick/android/SDL_sysjoystick.c 49 ●●●● patch | view | raw | blame | history
source/src/joystick/android/SDL_sysjoystick_c.h 38 ●●●● patch | view | raw | blame | history
source/src/joystick/bsd/SDL_sysjoystick.c 10 ●●●● patch | view | raw | blame | history
source/src/joystick/darwin/SDL_sysjoystick.c 54 ●●●● patch | view | raw | blame | history
source/src/joystick/emscripten/SDL_sysjoystick.c 41 ●●●● patch | view | raw | blame | history
source/src/joystick/emscripten/SDL_sysjoystick_c.h 32 ●●●● patch | view | raw | blame | history
source/src/joystick/haiku/SDL_haikujoystick.cc 4 ●●●● patch | view | raw | blame | history
source/src/joystick/iphoneos/SDL_sysjoystick.m 132 ●●●● patch | view | raw | blame | history
source/src/joystick/linux/SDL_sysjoystick.c 37 ●●●●● patch | view | raw | blame | history
source/src/joystick/psp/SDL_sysjoystick.c 4 ●●●● patch | view | raw | blame | history
source/src/joystick/windows/SDL_dinputjoystick.c 20 ●●●● patch | view | raw | blame | history
source/src/joystick/windows/SDL_windowsjoystick.c 47 ●●●● patch | view | raw | blame | history
source/src/joystick/windows/SDL_windowsjoystick_c.h 4 ●●●● patch | view | raw | blame | history
source/src/joystick/windows/SDL_xinputjoystick.c 10 ●●●●● patch | view | raw | blame | history
source/src/loadso/dlopen/SDL_sysloadso.c 18 ●●●● patch | view | raw | blame | history
source/src/main/android/SDL_android_main.c 11 ●●●● patch | view | raw | blame | history
source/src/main/haiku/SDL_BApp.h 14 ●●●●● patch | view | raw | blame | history
source/src/main/haiku/SDL_BeApp.cc 6 ●●●●● patch | view | raw | blame | history
source/src/main/windows/SDL_windows_main.c 84 ●●●● patch | view | raw | blame | history
source/src/main/windows/version.rc 8 ●●●● patch | view | raw | blame | history
source/src/main/winrt/SDL2-WinRTResource_BlankCursor.cur patch | view | raw | blame | history
source/src/main/winrt/SDL2-WinRTResources.rc 3 ●●●●● patch | view | raw | blame | history
source/src/power/uikit/SDL_syspower.m 17 ●●●●● patch | view | raw | blame | history
source/src/render/SDL_render.c 72 ●●●● patch | view | raw | blame | history
source/src/render/SDL_sysrender.h 3 ●●●●● patch | view | raw | blame | history
source/src/render/direct3d/SDL_render_d3d.c 16 ●●●● patch | view | raw | blame | history
source/src/render/direct3d11/SDL_render_d3d11.c 157 ●●●● patch | view | raw | blame | history
source/src/render/opengl/SDL_render_gl.c 72 ●●●●● patch | view | raw | blame | history
source/src/render/opengles/SDL_render_gles.c 178 ●●●●● patch | view | raw | blame | history
source/src/render/opengles2/SDL_render_gles2.c 58 ●●●●● patch | view | raw | blame | history
source/src/render/psp/SDL_render_psp.c 10 ●●●●● patch | view | raw | blame | history
source/src/render/software/SDL_render_sw.c 4 ●●●● patch | view | raw | blame | history
source/src/render/software/SDL_rotate.c 167 ●●●● patch | view | raw | blame | history
source/src/stdlib/SDL_iconv.c 3 ●●●● patch | view | raw | blame | history
source/src/stdlib/SDL_qsort.c 481 ●●●●● patch | view | raw | blame | history
source/src/stdlib/SDL_stdlib.c 14 ●●●● patch | view | raw | blame | history
source/src/stdlib/SDL_string.c 16 ●●●●● patch | view | raw | blame | history
source/src/test/SDL_test_assert.c 14 ●●●● patch | view | raw | blame | history
source/src/test/SDL_test_common.c 24 ●●●●● patch | view | raw | blame | history
source/src/test/SDL_test_compare.c 2 ●●● patch | view | raw | blame | history
source/src/test/SDL_test_harness.c 51 ●●●● patch | view | raw | blame | history
source/src/test/SDL_test_log.c 3 ●●●● patch | view | raw | blame | history
source/src/thread/SDL_systhread.h 5 ●●●●● patch | view | raw | blame | history
source/src/thread/SDL_thread.c 59 ●●●● patch | view | raw | blame | history
source/src/thread/SDL_thread_c.h 1 ●●●● patch | view | raw | blame | history
source/src/thread/psp/SDL_systhread.c 4 ●●●● patch | view | raw | blame | history
source/src/thread/pthread/SDL_systhread.c 23 ●●●● patch | view | raw | blame | history
source/src/thread/stdcpp/SDL_systhread.cpp 1 ●●●● patch | view | raw | blame | history
source/src/thread/windows/SDL_systhread.c 66 ●●●●● patch | view | raw | blame | history
source/src/timer/SDL_timer.c 59 ●●●●● patch | view | raw | blame | history
source/src/timer/windows/SDL_systimer.c 10 ●●●●● patch | view | raw | blame | history
source/src/video/SDL_blit_copy.c 18 ●●●● patch | view | raw | blame | history
source/src/video/SDL_blit_slow.c 5 ●●●● patch | view | raw | blame | history
source/src/video/SDL_bmp.c 68 ●●●● patch | view | raw | blame | history
source/src/video/SDL_egl.c 5 ●●●●● patch | view | raw | blame | history
source/src/video/SDL_surface.c 65 ●●●● patch | view | raw | blame | history
source/src/video/SDL_sysvideo.h 13 ●●●●● patch | view | raw | blame | history
source/src/video/SDL_video.c 220 ●●●● patch | view | raw | blame | history
source/src/video/android/SDL_androidevents.c 14 ●●●● patch | view | raw | blame | history
source/src/video/android/SDL_androidkeyboard.c 20 ●●●●● patch | view | raw | blame | history
source/src/video/android/SDL_androidmouse.c 18 ●●●● patch | view | raw | blame | history
source/src/video/android/SDL_androidmouse.h 1 ●●●● patch | view | raw | blame | history
source/src/video/android/SDL_androidtouch.c 2 ●●● patch | view | raw | blame | history
source/src/video/android/SDL_androidvideo.c 29 ●●●●● patch | view | raw | blame | history
source/src/video/cocoa/SDL_cocoaclipboard.m 16 ●●●● patch | view | raw | blame | history
source/src/video/cocoa/SDL_cocoaevents.m 114 ●●●●● patch | view | raw | blame | history
source/src/video/cocoa/SDL_cocoakeyboard.m 160 ●●●● patch | view | raw | blame | history
source/src/video/cocoa/SDL_cocoamodes.h 4 ●●● patch | view | raw | blame | history
source/src/video/cocoa/SDL_cocoamodes.m 222 ●●●●● patch | view | raw | blame | history
source/src/video/cocoa/SDL_cocoamouse.m 30 ●●●● patch | view | raw | blame | history
source/src/video/cocoa/SDL_cocoamousetap.m 15 ●●●● patch | view | raw | blame | history
source/src/video/cocoa/SDL_cocoaopengl.m 2 ●●●●● patch | view | raw | blame | history
source/src/video/cocoa/SDL_cocoashape.m 4 ●●● patch | view | raw | blame | history
source/src/video/cocoa/SDL_cocoavideo.m 15 ●●●●● patch | view | raw | blame | history
source/src/video/cocoa/SDL_cocoawindow.h 2 ●●●●● patch | view | raw | blame | history
source/src/video/cocoa/SDL_cocoawindow.m 186 ●●●● patch | view | raw | blame | history
source/src/video/directfb/SDL_DirectFB_video.c 1 ●●●● patch | view | raw | blame | history
source/src/video/directfb/SDL_DirectFB_window.c 13 ●●●●● patch | view | raw | blame | history
source/src/video/directfb/SDL_DirectFB_window.h 1 ●●●● patch | view | raw | blame | history
source/src/video/emscripten/SDL_emscriptenevents.c 238 ●●●●● patch | view | raw | blame | history
source/src/video/emscripten/SDL_emscriptenevents.h 3 ●●●●● patch | view | raw | blame | history
source/src/video/emscripten/SDL_emscriptenframebuffer.c 76 ●●●● patch | view | raw | blame | history
source/src/video/emscripten/SDL_emscriptenmouse.c 4 ●●●● patch | view | raw | blame | history
source/src/video/emscripten/SDL_emscriptenvideo.c 80 ●●●●● patch | view | raw | blame | history
source/src/video/emscripten/SDL_emscriptenvideo.h 8 ●●●●● patch | view | raw | blame | history
source/src/video/haiku/SDL_BWin.h 40 ●●●●● patch | view | raw | blame | history
source/src/video/haiku/SDL_bvideo.cc 1 ●●●● patch | view | raw | blame | history
source/src/video/haiku/SDL_bwindow.cc 6 ●●●●● patch | view | raw | blame | history
source/src/video/haiku/SDL_bwindow.h 1 ●●●● patch | view | raw | blame | history
source/src/video/mir/SDL_mirdyn.c 15 ●●●● patch | view | raw | blame | history
source/src/video/mir/SDL_mirdyn.h 6 ●●●● patch | view | raw | blame | history
source/src/video/mir/SDL_mirevents.c 249 ●●●●● patch | view | raw | blame | history
source/src/video/mir/SDL_mirevents.h 2 ●●● patch | view | raw | blame | history
source/src/video/mir/SDL_mirframebuffer.c 37 ●●●● patch | view | raw | blame | history
source/src/video/mir/SDL_mirmouse.c 149 ●●●●● patch | view | raw | blame | history
source/src/video/mir/SDL_mirsym.h 117 ●●●● patch | view | raw | blame | history
source/src/video/mir/SDL_mirvideo.c 229 ●●●●● patch | view | raw | blame | history
source/src/video/mir/SDL_mirvideo.h 13 ●●●● patch | view | raw | blame | history
source/src/video/mir/SDL_mirwindow.c 254 ●●●● patch | view | raw | blame | history
source/src/video/mir/SDL_mirwindow.h 32 ●●●● patch | view | raw | blame | history
source/src/video/pandora/SDL_pandora.c 32 ●●●● patch | view | raw | blame | history
source/src/video/pandora/SDL_pandora.h 2 ●●● patch | view | raw | blame | history
source/src/video/psp/SDL_pspevents.c 4 ●●●● patch | view | raw | blame | history
source/src/video/psp/SDL_pspvideo.c 5 ●●●●● patch | view | raw | blame | history
source/src/video/raspberry/SDL_rpimouse.c 146 ●●●●● patch | view | raw | blame | history
source/src/video/raspberry/SDL_rpivideo.c 23 ●●●● patch | view | raw | blame | history
source/src/video/uikit/SDL_uikitappdelegate.h 2 ●●● patch | view | raw | blame | history
source/src/video/uikit/SDL_uikitappdelegate.m 100 ●●●● patch | view | raw | blame | history
source/src/video/uikit/SDL_uikitclipboard.h 16 ●●●● patch | view | raw | blame | history
source/src/video/uikit/SDL_uikitclipboard.m 111 ●●●●● patch | view | raw | blame | history
source/src/video/uikit/SDL_uikitevents.m 4 ●●●● patch | view | raw | blame | history
source/src/video/uikit/SDL_uikitmodes.h 1 ●●●● patch | view | raw | blame | history
source/src/video/uikit/SDL_uikitmodes.m 49 ●●●●● patch | view | raw | blame | history
source/src/video/uikit/SDL_uikitopengles.h 2 ●●●●● patch | view | raw | blame | history
source/src/video/uikit/SDL_uikitopengles.m 29 ●●●●● patch | view | raw | blame | history
source/src/video/uikit/SDL_uikitopenglview.m 2 ●●● patch | view | raw | blame | history
source/src/video/uikit/SDL_uikitvideo.h 17 ●●●● patch | view | raw | blame | history
source/src/video/uikit/SDL_uikitvideo.m 122 ●●●●● patch | view | raw | blame | history
source/src/video/uikit/SDL_uikitview.m 71 ●●●●● patch | view | raw | blame | history
source/src/video/uikit/SDL_uikitviewcontroller.h 49 ●●●●● patch | view | raw | blame | history
source/src/video/uikit/SDL_uikitviewcontroller.m 36 ●●●●● patch | view | raw | blame | history
source/src/video/uikit/SDL_uikitwindow.m 14 ●●●● patch | view | raw | blame | history
source/src/video/vivante/SDL_vivantevideo.c 8 ●●●●● patch | view | raw | blame | history
source/src/video/wayland/SDL_waylanddyn.c 17 ●●●●● patch | view | raw | blame | history
source/src/video/wayland/SDL_waylanddyn.h 9 ●●●●● patch | view | raw | blame | history
source/src/video/wayland/SDL_waylandevents.c 201 ●●●●● patch | view | raw | blame | history
source/src/video/wayland/SDL_waylandevents_c.h 9 ●●●●● patch | view | raw | blame | history
source/src/video/wayland/SDL_waylandmouse.c 35 ●●●● patch | view | raw | blame | history
source/src/video/wayland/SDL_waylandsym.h 19 ●●●●● patch | view | raw | blame | history
source/src/video/wayland/SDL_waylandvideo.c 79 ●●●● patch | view | raw | blame | history
source/src/video/wayland/SDL_waylandvideo.h 7 ●●●● patch | view | raw | blame | history
source/src/video/wayland/SDL_waylandwindow.c 64 ●●●●● patch | view | raw | blame | history
source/src/video/wayland/SDL_waylandwindow.h 4 ●●●● patch | view | raw | blame | history
source/src/video/windows/SDL_windowsevents.c 125 ●●●●● patch | view | raw | blame | history
source/src/video/windows/SDL_windowskeyboard.c 46 ●●●●● patch | view | raw | blame | history
source/src/video/windows/SDL_windowskeyboard.h 2 ●●●●● patch | view | raw | blame | history
source/src/video/windows/SDL_windowsmessagebox.c 6 ●●●● patch | view | raw | blame | history
source/src/video/windows/SDL_windowsmodes.c 123 ●●●● patch | view | raw | blame | history
source/src/video/windows/SDL_windowsmodes.h 1 ●●●● patch | view | raw | blame | history
source/src/video/windows/SDL_windowsvideo.c 3 ●●●●● patch | view | raw | blame | history
source/src/video/windows/SDL_windowswindow.c 52 ●●●●● patch | view | raw | blame | history
source/src/video/windows/SDL_windowswindow.h 4 ●●● patch | view | raw | blame | history
source/src/video/winrt/SDL_winrtevents.cpp 3 ●●●● patch | view | raw | blame | history
source/src/video/winrt/SDL_winrtevents_c.h 7 ●●●●● patch | view | raw | blame | history
source/src/video/winrt/SDL_winrtgamebar.cpp 196 ●●●●● patch | view | raw | blame | history
source/src/video/winrt/SDL_winrtgamebar_cpp.h 16 ●●●● patch | view | raw | blame | history
source/src/video/winrt/SDL_winrtkeyboard.cpp 44 ●●●●● patch | view | raw | blame | history
source/src/video/winrt/SDL_winrtmouse.cpp 63 ●●●●● patch | view | raw | blame | history
source/src/video/winrt/SDL_winrtvideo.cpp 98 ●●●●● patch | view | raw | blame | history
source/src/video/winrt/SDL_winrtvideo_cpp.h 11 ●●●●● patch | view | raw | blame | history
source/src/video/x11/SDL_x11dyn.c 15 ●●●●● patch | view | raw | blame | history
source/src/video/x11/SDL_x11dyn.h 6 ●●●●● patch | view | raw | blame | history
source/src/video/x11/SDL_x11events.c 215 ●●●●● patch | view | raw | blame | history
source/src/video/x11/SDL_x11keyboard.c 154 ●●●● patch | view | raw | blame | history
source/src/video/x11/SDL_x11keyboard.h 1 ●●●● patch | view | raw | blame | history
source/src/video/x11/SDL_x11modes.c 74 ●●●● patch | view | raw | blame | history
source/src/video/x11/SDL_x11modes.h 1 ●●●● patch | view | raw | blame | history
source/src/video/x11/SDL_x11mouse.c 57 ●●●●● patch | view | raw | blame | history
source/src/video/x11/SDL_x11opengl.c 12 ●●●● patch | view | raw | blame | history
source/src/video/x11/SDL_x11sym.h 18 ●●●●● patch | view | raw | blame | history
source/src/video/x11/SDL_x11video.c 79 ●●●●● patch | view | raw | blame | history
source/src/video/x11/SDL_x11video.h 18 ●●●●● patch | view | raw | blame | history
source/src/video/x11/SDL_x11window.c 198 ●●●● patch | view | raw | blame | history
source/src/video/x11/SDL_x11window.h 11 ●●●●● patch | view | raw | blame | history
source/src/video/x11/SDL_x11xinput2.c 10 ●●●●● patch | view | raw | blame | history
source/src/video/x11/edid-parse.c 4 ●●● patch | view | raw | blame | history
source/src/video/x11/imKStoUCS.c 496 ●●●● patch | view | raw | blame | history
source/src/video/x11/imKStoUCS.h 39 ●●●● patch | view | raw | blame | history
source/test/Makefile.in 16 ●●●●● patch | view | raw | blame | history
source/test/controllermap.c 9 ●●●●● patch | view | raw | blame | history
source/test/testatomic.c 14 ●●●● patch | view | raw | blame | history
source/test/testaudiocapture.c 165 ●●●●● patch | view | raw | blame | history
source/test/testaudiohotplug.c 28 ●●●● patch | view | raw | blame | history
source/test/testaudioinfo.c 12 ●●●●● patch | view | raw | blame | history
source/test/testautomation_events.c 4 ●●●● patch | view | raw | blame | history
source/test/testautomation_keyboard.c 16 ●●●● patch | view | raw | blame | history
source/test/testautomation_main.c 4 ●●●● patch | view | raw | blame | history
source/test/testautomation_sdltest.c 2 ●●● patch | view | raw | blame | history
source/test/testautomation_stdlib.c 44 ●●●●● patch | view | raw | blame | history
source/test/testbounds.c 40 ●●●●● patch | view | raw | blame | history
source/test/testcustomcursor.c 216 ●●●●● patch | view | raw | blame | history
source/test/testdisplayinfo.c 7 ●●●●● patch | view | raw | blame | history
source/test/testdrawchessboard.c 2 ●●● patch | view | raw | blame | history
source/test/testdropfile.c 9 ●●●● patch | view | raw | blame | history
source/test/testfilesystem.c 5 ●●●●● patch | view | raw | blame | history
source/test/testgamecontroller.c 12 ●●●●● patch | view | raw | blame | history
source/test/testgles.c 2 ●●● patch | view | raw | blame | history
source/test/testgles2.c 4 ●●●● patch | view | raw | blame | history
source/test/testime.c 500 ●●●●● patch | view | raw | blame | history
source/test/testlock.c 12 ●●●●● patch | view | raw | blame | history
source/test/testmultiaudio.c 11 ●●●● patch | view | raw | blame | history
source/test/testqsort.c 108 ●●●●● patch | view | raw | blame | history
source/test/testrendercopyex.c 4 ●●●● patch | view | raw | blame | history
source/test/testshape.c 4 ●●●● patch | view | raw | blame | history
source/test/testwm2.c 14 ●●●●● patch | view | raw | blame | history
source/test/torturethread.c 8 ●●●● patch | view | raw | blame | history
source/.hgignore
@@ -8,6 +8,7 @@
sdl-config
SDL2.spec
build
gen
Build
# for Xcode
@@ -116,8 +117,11 @@
test/testver
test/testviewport
test/testwm2
test/testbounds
test/torturethread
test/testdisplayinfo
test/testqsort
test/testaudiocapture
test/*.exe
test/*.dSYM
buildbot
source/.hgtags
@@ -28,3 +28,4 @@
f285b9487756ff681f76c85644222c03a7bfa1c7 release-2.0.3
f285b9487756ff681f76c85644222c03a7bfa1c7 release-2.0.3
704a0bfecf754e4e1383f83c7d5118b00cae26ea release-2.0.3
e12c387305129c847b3928a123300b113782fe3f release-2.0.4
source/BUGS.txt
@@ -1,7 +1,7 @@
Bugs are now managed in the SDL bug tracker, here:
    http://bugzilla.libsdl.org/
    https://bugzilla.libsdl.org/
You may report bugs there, and search to see if a given issue has already
 been reported, discussed, and maybe even fixed.
source/CMakeLists.txt
old mode 100755 new mode 100644
@@ -2,8 +2,19 @@
  message(FATAL_ERROR "Prevented in-tree built. Please create a build directory outside of the SDL source code and call cmake from there")
endif()
cmake_minimum_required(VERSION 2.8)
cmake_minimum_required(VERSION 2.8.5)
project(SDL2 C)
# !!! FIXME: this should probably do "MACOSX_RPATH ON" as a target property
# !!! FIXME:  for the SDL2 shared library (so you get an
# !!! FIXME:  install_name ("soname") of "@rpath/libSDL-whatever.dylib"
# !!! FIXME:  instead of "/usr/local/lib/libSDL-whatever.dylib"), but I'm
# !!! FIXME:  punting for now and leaving the existing behavior. Until this
# !!! FIXME:  properly resolved, this line silences a warning in CMake 3.0+.
# !!! FIXME:  remove it and this comment entirely once the problem is
# !!! FIXME:  properly resolved.
#cmake_policy(SET CMP0042 OLD)
include(CheckFunctionExists)
include(CheckLibraryExists)
include(CheckIncludeFiles)
@@ -15,6 +26,7 @@
include(CheckStructHasMember)
include(CMakeDependentOption)
include(FindPkgConfig)
include(GNUInstallDirs)
set(CMAKE_MODULE_PATH "${SDL2_SOURCE_DIR}/cmake")
include(${SDL2_SOURCE_DIR}/cmake/macros.cmake)
include(${SDL2_SOURCE_DIR}/cmake/sdlchecks.cmake)
@@ -29,9 +41,9 @@
# set SDL_BINARY_AGE and SDL_INTERFACE_AGE to 0.
set(SDL_MAJOR_VERSION 2)
set(SDL_MINOR_VERSION 0)
set(SDL_MICRO_VERSION 4)
set(SDL_INTERFACE_AGE 0)
set(SDL_BINARY_AGE 4)
set(SDL_MICRO_VERSION 5)
set(SDL_INTERFACE_AGE 1)
set(SDL_BINARY_AGE 5)
set(SDL_VERSION "${SDL_MAJOR_VERSION}.${SDL_MINOR_VERSION}.${SDL_MICRO_VERSION}")
# Calculate a libtool-like version number
@@ -147,8 +159,10 @@
# Default flags, if not set otherwise
if("$ENV{CFLAGS}" STREQUAL "")
  if(USE_GCC OR USE_CLANG)
    set(CMAKE_C_FLAGS "-g -O3")
  if(CMAKE_BUILD_TYPE STREQUAL "")
    if(USE_GCC OR USE_CLANG)
      set(CMAKE_C_FLAGS "-g -O3")
    endif()
  endif()
else()
  set(CMAKE_C_FLAGS "$ENV{CFLAGS}")
@@ -192,7 +206,7 @@
if(CYGWIN)
  # We build SDL on cygwin without the UNIX emulation layer
  include_directories("-I/usr/include/mingw")
  set(CMAKE_REQUIRED_FLAGS "-mno-cygwin")
  set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -mno-cygwin")
  check_c_source_compiles("int main(int argc, char **argv) {}"
    HAVE_GCC_NO_CYGWIN)
  set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
@@ -299,6 +313,8 @@
set(SDL_SHARED ${SDL_SHARED_ENABLED_BY_DEFAULT} CACHE BOOL "Build a shared version of the library")
set(SDL_STATIC ON CACHE BOOL "Build a static version of the library")
dep_option(SDL_STATIC_PIC      "Static version of the library should be built with Position Independent Code" OFF "SDL_STATIC" OFF)
# General source files
file(GLOB SOURCE_FILES
  ${SDL2_SOURCE_DIR}/src/*.c
@@ -334,6 +350,24 @@
# Compiler option evaluation
if(USE_GCC OR USE_CLANG)
  # Check for -Wall first, so later things can override pieces of it.
  check_c_compiler_flag(-Wall HAVE_GCC_WALL)
  if(HAVE_GCC_WALL)
    list(APPEND EXTRA_CFLAGS "-Wall")
    if(HAIKU)
      set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-multichar")
    endif()
  endif()
  check_c_compiler_flag(-Wdeclaration-after-statement HAVE_GCC_WDECLARATION_AFTER_STATEMENT)
  if(HAVE_GCC_WDECLARATION_AFTER_STATEMENT)
    check_c_compiler_flag(-Werror=declaration-after-statement HAVE_GCC_WERROR_DECLARATION_AFTER_STATEMENT)
    if(HAVE_GCC_WERROR_DECLARATION_AFTER_STATEMENT)
      list(APPEND EXTRA_CFLAGS "-Werror=declaration-after-statement")
    endif()
    list(APPEND EXTRA_CFLAGS "-Wdeclaration-after-statement")
  endif()
  if(DEPENDENCY_TRACKING)
    check_c_source_compiles("
        #if !defined(__GNUC__) || __GNUC__ < 3
@@ -375,13 +409,6 @@
  endif()
  set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
  check_c_compiler_flag(-Wall HAVE_GCC_WALL)
  if(HAVE_GCC_WALL)
    list(APPEND EXTRA_CFLAGS "-Wall")
    if(HAIKU)
      set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-multichar")
    endif()
  endif()
  check_c_compiler_flag(-Wshadow HAVE_GCC_WSHADOW)
  if(HAVE_GCC_WSHADOW)
    list(APPEND EXTRA_CFLAGS "-Wshadow")
@@ -770,6 +797,16 @@
    set(SOURCE_FILES ${SOURCE_FILES} ${EM_POWER_SOURCES})
    set(HAVE_SDL_POWER TRUE)
  endif()
  if(SDL_TIMERS)
    set(SDL_TIMER_UNIX 1)
    file(GLOB TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/unix/*.c)
    set(SOURCE_FILES ${SOURCE_FILES} ${TIMER_SOURCES})
    set(HAVE_SDL_TIMERS TRUE)
    if(CLOCK_GETTIME)
      set(HAVE_CLOCK_GETTIME 1)
    endif()
  endif()
  if(SDL_VIDEO)
    set(SDL_VIDEO_DRIVER_EMSCRIPTEN 1)
    file(GLOB EM_VIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/emscripten/*.c)
@@ -863,8 +900,24 @@
    check_include_file("libudev.h" HAVE_LIBUDEV_H)
    # !!! FIXME: this needs pkg-config to find the include path, I think.
    check_include_file("dbus/dbus.h" HAVE_DBUS_DBUS_H)
    if(PKG_CONFIG_FOUND)
      pkg_search_module(DBUS dbus-1 dbus)
      if(DBUS_FOUND)
        set(HAVE_DBUS_DBUS_H TRUE)
        include_directories(${DBUS_INCLUDE_DIRS})
        list(APPEND EXTRA_LIBS ${DBUS_LIBRARIES})
      endif()
      pkg_search_module(IBUS ibus-1.0 ibus)
      if(IBUS_FOUND)
        set(HAVE_IBUS_IBUS_H TRUE)
        include_directories(${IBUS_INCLUDE_DIRS})
        list(APPEND EXTRA_LIBS ${IBUS_LIBRARIES})
      endif()
    endif()
    check_include_file("fcitx/frontend.h" HAVE_FCITX_FRONTEND_H)
  endif()
  if(INPUT_TSLIB)
@@ -933,7 +986,14 @@
  if(RPATH)
    set(SDL_RLD_FLAGS "")
    if(BSDI OR FREEBSD OR LINUX OR NETBSD)
      set(SDL_RLD_FLAGS "-Wl,-rpath,\${libdir}")
      set(CMAKE_REQUIRED_FLAGS "-Wl,--enable-new-dtags")
      check_c_compiler_flag("" HAVE_ENABLE_NEW_DTAGS)
      set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
      if(HAVE_ENABLE_NEW_DTAGS)
        set(SDL_RLD_FLAGS "-Wl,-rpath,\${libdir} -Wl,--enable-new-dtags")
      else()
        set(SDL_RLD_FLAGS "-Wl,-rpath,\${libdir}")
      endif()
    elseif(SOLARIS)
      set(SDL_RLD_FLAGS "-R\${libdir}")
    endif()
@@ -1105,7 +1165,7 @@
    set(SOURCE_FILES ${SOURCE_FILES} ${JOYSTICK_SOURCES})
    if(HAVE_DINPUT_H)
      set(SDL_JOYSTICK_DINPUT 1)
      list(APPEND EXTRA_LIBS dinput8 dxguid)
      list(APPEND EXTRA_LIBS dinput8)
      if(CMAKE_COMPILER_IS_MINGW)
        list(APPEND EXTRA_LIBS dxerr8)
      elseif (NOT USE_WINSDK_DIRECTX)
@@ -1163,16 +1223,20 @@
  if(SDL_AUDIO)
    set(SDL_AUDIO_DRIVER_COREAUDIO 1)
    file(GLOB AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/coreaudio/*.c)
    file(GLOB AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/coreaudio/*.m)
    set(SOURCE_FILES ${SOURCE_FILES} ${AUDIO_SOURCES})
    set(HAVE_SDL_AUDIO TRUE)
    set(SDL_FRAMEWORK_COREAUDIO 1)
    set(SDL_FRAMEWORK_AUDIOUNIT 1)
    set(SDL_FRAMEWORK_AUDIOTOOLBOX 1)
  endif()
  if(SDL_JOYSTICK)
    set(SDL_JOYSTICK_IOKIT 1)
    file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/darwin/*.c)
    if (IOS)
      file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/iphoneos/*.m)
    else()
      file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/darwin/*.c)
    endif()
    set(SOURCE_FILES ${SOURCE_FILES} ${JOYSTICK_SOURCES})
    set(HAVE_SDL_JOYSTICK TRUE)
    set(SDL_FRAMEWORK_IOKIT 1)
@@ -1181,7 +1245,12 @@
  if(SDL_HAPTIC)
    set(SDL_HAPTIC_IOKIT 1)
    file(GLOB HAPTIC_SOURCES ${SDL2_SOURCE_DIR}/src/haptic/darwin/*.c)
    if (IOS)
      file(GLOB POWER_SOURCES ${SDL2_SOURCE_DIR}/src/power/dummy/*.c)
      set(SDL_HAPTIC_DUMMY 1)
    else()
      file(GLOB HAPTIC_SOURCES ${SDL2_SOURCE_DIR}/src/haptic/darwin/*.c)
    endif()
    set(SOURCE_FILES ${SOURCE_FILES} ${HAPTIC_SOURCES})
    set(HAVE_SDL_HAPTIC TRUE)
    set(SDL_FRAMEWORK_IOKIT 1)
@@ -1193,7 +1262,11 @@
  if(SDL_POWER)
    set(SDL_POWER_MACOSX 1)
    file(GLOB POWER_SOURCES ${SDL2_SOURCE_DIR}/src/power/macosx/*.c)
    if (IOS)
      file(GLOB POWER_SOURCES ${SDL2_SOURCE_DIR}/src/power/uikit/*.m)
    else()
      file(GLOB POWER_SOURCES ${SDL2_SOURCE_DIR}/src/power/macosx/*.c)
    endif()
    set(SOURCE_FILES ${SOURCE_FILES} ${POWER_SOURCES})
    set(HAVE_SDL_POWER TRUE)
    set(SDL_FRAMEWORK_CARBON 1)
@@ -1240,19 +1313,25 @@
    find_library(COREAUDIO CoreAudio)
    list(APPEND EXTRA_LIBS ${COREAUDIO})
  endif()
  if(SDL_FRAMEWORK_AUDIOUNIT)
    find_library(AUDIOUNIT AudioUnit)
    list(APPEND EXTRA_LIBS ${AUDIOUNIT})
  if(SDL_FRAMEWORK_AUDIOTOOLBOX)
    find_library(AUDIOTOOLBOX AudioToolbox)
    list(APPEND EXTRA_LIBS ${AUDIOTOOLBOX})
  endif()
  # iOS hack needed - http://code.google.com/p/ios-cmake/ ?
  if(SDL_VIDEO)
    CheckCOCOA()
    if(VIDEO_OPENGL)
      set(SDL_VIDEO_OPENGL 1)
      set(SDL_VIDEO_OPENGL_CGL 1)
      set(SDL_VIDEO_RENDER_OGL 1)
      set(HAVE_VIDEO_OPENGL TRUE)
    if (IOS)
      set(SDL_VIDEO_DRIVER_UIKIT 1)
      file(GLOB UIKITVIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/uikit/*.m)
      set(SOURCE_FILES ${SOURCE_FILES} ${UIKITVIDEO_SOURCES})
    else()
      CheckCOCOA()
      if(VIDEO_OPENGL)
        set(SDL_VIDEO_OPENGL 1)
        set(SDL_VIDEO_OPENGL_CGL 1)
        set(SDL_VIDEO_RENDER_OGL 1)
        set(HAVE_VIDEO_OPENGL TRUE)
      endif()
    endif()
  endif()
@@ -1439,6 +1518,9 @@
message(STATUS "")
message(STATUS " Build Shared Library: ${SDL_SHARED}")
message(STATUS " Build Static Library: ${SDL_STATIC}")
if(SDL_STATIC)
    message(STATUS " Build Static Library with Position Independent Code: ${SDL_STATIC_PIC}")
endif()
message(STATUS "")
if(UNIX)
  message(STATUS "If something was not detected, although the libraries")
@@ -1455,7 +1537,7 @@
set(_INSTALL_LIBS "SDL2main")
if(SDL_SHARED)
  add_library(SDL2 SHARED ${SOURCE_FILES})
  add_library(SDL2 SHARED ${SOURCE_FILES} ${VERSION_SOURCES})
  if(UNIX)
    set_target_properties(SDL2 PROPERTIES
      VERSION ${LT_VERSION}
@@ -1481,6 +1563,7 @@
  set (BUILD_SHARED_LIBS FALSE)
  add_library(SDL2-static STATIC ${SOURCE_FILES})
  set_target_properties(SDL2-static PROPERTIES OUTPUT_NAME "SDL2")
  set_target_properties(SDL2-static PROPERTIES POSITION_INDEPENDENT_CODE ${SDL_STATIC_PIC})
  if(MSVC)
    set_target_properties(SDL2-static PROPERTIES LINK_FLAGS_RELEASE "/NODEFAULTLIB")
    set_target_properties(SDL2-static PROPERTIES LINK_FLAGS_DEBUG "/NODEFAULTLIB")
@@ -1507,12 +1590,17 @@
list(APPEND INCLUDE_FILES ${BIN_INCLUDE_FILES})
install(FILES ${INCLUDE_FILES} DESTINATION include/SDL2)
if(NOT WINDOWS OR CYGWIN)
if(NOT (WINDOWS OR CYGWIN))
  if(SDL_SHARED)
    if (APPLE)
        set(SOEXT "dylib")
    else()
        set(SOEXT "so")
    endif()
    install(CODE "
      execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink
      \"libSDL2-2.0.so\" \"libSDL2.so\")")
    install(FILES ${SDL2_BINARY_DIR}/libSDL2.so DESTINATION "lib${LIB_SUFFIX}")
      \"libSDL2-2.0.${SOEXT}\" \"libSDL2.${SOEXT}\")")
    install(FILES ${SDL2_BINARY_DIR}/libSDL2.${SOEXT} DESTINATION "lib${LIB_SUFFIX}")
  endif()
  if(FREEBSD)
    # FreeBSD uses ${PREFIX}/libdata/pkgconfig
@@ -1523,7 +1611,7 @@
  endif()
  install(PROGRAMS ${SDL2_BINARY_DIR}/sdl2-config DESTINATION bin)
  # TODO: what about the .spec file? Is it only needed for RPM creation?
  install(FILES "${SDL2_SOURCE_DIR}/sdl2.m4" DESTINATION "share/aclocal")
  install(FILES "${SDL2_SOURCE_DIR}/sdl2.m4" DESTINATION "${CMAKE_INSTALL_FULL_DATAROOTDIR}/aclocal")
endif()
##### Uninstall target #####
source/Makefile.in
@@ -3,6 +3,7 @@
top_builddir = .
srcdir  = @srcdir@
objects = build
gen = gen
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir    = @bindir@
@@ -31,6 +32,8 @@
TARGET  = libSDL2.la
OBJECTS = @OBJECTS@
GEN_HEADERS = @GEN_HEADERS@
GEN_OBJECTS = @GEN_OBJECTS@
VERSION_OBJECTS = @VERSION_OBJECTS@
SDLMAIN_TARGET = libSDL2main.a
@@ -38,6 +41,8 @@
SDLTEST_TARGET = libSDL2_test.a
SDLTEST_OBJECTS = @SDLTEST_OBJECTS@
WAYLAND_SCANNER = @WAYLAND_SCANNER@
SRC_DIST = *.txt acinclude Android.mk autogen.sh android-project build-scripts cmake cmake_uninstall.cmake.in configure configure.in debian docs include Makefile.* sdl2-config.cmake.in sdl2-config.in sdl2.m4 sdl2.pc.in SDL2.spec.in src test VisualC.html VisualC VisualC-WinRT Xcode Xcode-iOS
GEN_DIST = SDL2.spec
@@ -48,6 +53,7 @@
RUN_CMD_CXX    = @echo "  CXX   " $@;
RUN_CMD_LTLINK = @echo "  LTLINK" $@;
RUN_CMD_RANLIB = @echo "  RANLIB" $@;
RUN_CMD_GEN    = @echo "  GEN   " $@;
LIBTOOL += --quiet
endif
@@ -137,8 +143,8 @@
.PHONY: all update-revision install install-bin install-hdrs install-lib install-data uninstall uninstall-bin uninstall-hdrs uninstall-lib uninstall-data clean distclean dist $(OBJECTS:.lo=.d)
$(objects)/$(TARGET): $(OBJECTS) $(VERSION_OBJECTS)
    $(RUN_CMD_LTLINK)$(LIBTOOL) --tag=CC --mode=link $(CC) -o $@ $(OBJECTS) $(VERSION_OBJECTS) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LT_LDFLAGS)
$(objects)/$(TARGET): $(GEN_HEADERS) $(GEN_OBJECTS) $(OBJECTS) $(VERSION_OBJECTS)
    $(RUN_CMD_LTLINK)$(LIBTOOL) --tag=CC --mode=link $(CC) -o $@ $(OBJECTS) $(GEN_OBJECTS) $(VERSION_OBJECTS) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LT_LDFLAGS)
$(objects)/$(SDLMAIN_TARGET): $(SDLMAIN_OBJECTS)
    $(RUN_CMD_AR)$(AR) cru $@ $(SDLMAIN_OBJECTS)
@@ -200,6 +206,7 @@
clean:
    rm -rf $(objects)
    rm -rf $(gen)
    if test -f test/Makefile; then (cd test; $(MAKE) $@); fi
distclean: clean
source/Makefile.pandora
@@ -19,7 +19,7 @@
    ./src/thread/pthread/SDL_systhread.c ./src/thread/pthread/SDL_syssem.c \
    ./src/thread/pthread/SDL_sysmutex.c ./src/thread/pthread/SDL_syscond.c \
    ./src/joystick/linux/*.c ./src/haptic/linux/*.c ./src/timer/unix/*.c \
    ./src/atomic/linux/*.c ./src/filesystem/unix/*.c \
    ./src/atomic/*.c ./src/filesystem/unix/*.c \
    ./src/video/pandora/SDL_pandora.o ./src/video/pandora/SDL_pandora_events.o ./src/video/x11/*.c 
    
source/Makefile.psp
@@ -49,6 +49,7 @@
      src/stdlib/SDL_stdlib.o \
      src/stdlib/SDL_string.o \
      src/thread/SDL_thread.o \
      src/thread/generic/SDL_systls.o \
      src/thread/psp/SDL_syssem.o \
      src/thread/psp/SDL_systhread.o \
      src/thread/psp/SDL_sysmutex.o \
source/Makefile.wiz
@@ -9,8 +9,8 @@
CFLAGS  = -Wall -fPIC -I./include -I$(WIZSDK)/include -DWIZ_GLES_LITE
TARGET_STATIC  = libSDL13.a
TARGET_SHARED  = libSDL13.so
TARGET_STATIC  = libSDL2.a
TARGET_SHARED  = libSDL2.so
SOURCES = ./src/*.c ./src/audio/*.c ./src/cpuinfo/*.c ./src/events/*.c \
    ./src/file/*.c ./src/stdlib/*.c ./src/thread/*.c ./src/timer/*.c ./src/video/*.c \
@@ -43,7 +43,7 @@
install:
    mkdir -p $(WIZSDK)/lib
    mkdir -p $(WIZSDK)/include/SDL13
    mkdir -p $(WIZSDK)/include/SDL2
    cp -f $(TARGET_STATIC) $(WIZSDK)/lib
    cp -f $(TARGET_SHARED).0.0.1 $(WIZSDK)/lib
    rm -f $(WIZSDK)/lib/$(TARGET_SHARED).0 $(WIZSDK)/lib/$(TARGET_SHARED)
@@ -57,5 +57,5 @@
    ln -s ../../toolchain/libs/$(TARGET_SHARED).0 ../../toolchain/libs/$(TARGET_SHARED)
    cp $(TARGET_SHARED).0.0.1 ../nehe_demos/build/$(TARGET_SHARED).0
    cp -f include/*.h $(WIZSDK)/include/SDL13/
    cp -f include/*.h ../../toolchain/include/SDL13/
    cp -f include/*.h $(WIZSDK)/include/SDL2/
    cp -f include/*.h ../../toolchain/include/SDL2/
source/README-SDL.txt
@@ -2,8 +2,8 @@
Please distribute this file with the SDL runtime environment:
The Simple DirectMedia Layer (SDL for short) is a cross-platform library
designed to make it easy to write multi-media software, such as games and
emulators.
designed to make it easy to write multi-media software, such as games
and emulators.
The Simple DirectMedia Layer library source code is available from:
http://www.libsdl.org/
source/VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj
@@ -81,7 +81,6 @@
    <ClInclude Include="..\..\src\audio\disk\SDL_diskaudio.h" />
    <ClInclude Include="..\..\src\audio\dummy\SDL_dummyaudio.h" />
    <ClInclude Include="..\..\src\audio\SDL_audiodev_c.h" />
    <ClInclude Include="..\..\src\audio\SDL_audiomem.h" />
    <ClInclude Include="..\..\src\audio\SDL_audio_c.h" />
    <ClInclude Include="..\..\src\audio\SDL_sysaudio.h" />
    <ClInclude Include="..\..\src\audio\SDL_wave.h" />
@@ -156,6 +155,7 @@
    <ClInclude Include="..\..\src\video\SDL_shape_internals.h" />
    <ClInclude Include="..\..\src\video\SDL_sysvideo.h" />
    <ClInclude Include="..\..\src\video\winrt\SDL_winrtevents_c.h" />
    <ClInclude Include="..\..\src\video\winrt\SDL_winrtgamebar_cpp.h" />
    <ClInclude Include="..\..\src\video\winrt\SDL_winrtmessagebox.h" />
    <ClInclude Include="..\..\src\video\winrt\SDL_winrtmouse_c.h" />
    <ClInclude Include="..\..\src\video\winrt\SDL_winrtopengles.h" />
@@ -311,6 +311,14 @@
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</CompileAsWinRT>
    </ClCompile>
    <ClCompile Include="..\..\src\video\winrt\SDL_winrtgamebar.cpp">
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</CompileAsWinRT>
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</CompileAsWinRT>
    </ClCompile>
    <ClCompile Include="..\..\src\video\winrt\SDL_winrtkeyboard.cpp">
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
source/VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj.filters
@@ -174,9 +174,6 @@
    <ClInclude Include="..\..\src\audio\SDL_audiodev_c.h">
      <Filter>Source Files</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\audio\SDL_audiomem.h">
      <Filter>Source Files</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\audio\SDL_audio_c.h">
      <Filter>Source Files</Filter>
    </ClInclude>
@@ -400,6 +397,9 @@
    <ClInclude Include="..\..\src\haptic\windows\SDL_windowshaptic_c.h" />
    <ClInclude Include="..\..\src\haptic\windows\SDL_xinputhaptic_c.h" />
    <ClInclude Include="..\..\src\audio\xaudio2\SDL_xaudio2.h">
      <Filter>Source Files</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\video\winrt\SDL_winrtgamebar_cpp.h">
      <Filter>Source Files</Filter>
    </ClInclude>
  </ItemGroup>
@@ -716,5 +716,8 @@
    <ClCompile Include="..\..\src\audio\xaudio2\SDL_xaudio2.c">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\video\winrt\SDL_winrtgamebar.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
  </ItemGroup>
</Project>
source/VisualC-WinRT/WinPhone80_VS2012/SDL-WinPhone80.vcxproj
@@ -208,7 +208,6 @@
    <ClInclude Include="..\..\src\audio\disk\SDL_diskaudio.h" />
    <ClInclude Include="..\..\src\audio\dummy\SDL_dummyaudio.h" />
    <ClInclude Include="..\..\src\audio\SDL_audiodev_c.h" />
    <ClInclude Include="..\..\src\audio\SDL_audiomem.h" />
    <ClInclude Include="..\..\src\audio\SDL_audio_c.h" />
    <ClInclude Include="..\..\src\audio\SDL_sysaudio.h" />
    <ClInclude Include="..\..\src\audio\SDL_wave.h" />
@@ -273,6 +272,7 @@
    <ClInclude Include="..\..\src\video\SDL_shape_internals.h" />
    <ClInclude Include="..\..\src\video\SDL_sysvideo.h" />
    <ClInclude Include="..\..\src\video\winrt\SDL_winrtevents_c.h" />
    <ClInclude Include="..\..\src\video\winrt\SDL_winrtgamebar_cpp.h" />
    <ClInclude Include="..\..\src\video\winrt\SDL_winrtmessagebox.h" />
    <ClInclude Include="..\..\src\video\winrt\SDL_winrtmouse_c.h" />
    <ClInclude Include="..\..\src\video\winrt\SDL_winrtopengles.h" />
@@ -408,6 +408,12 @@
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
    </ClCompile>
    <ClCompile Include="..\..\src\video\winrt\SDL_winrtgamebar.cpp">
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
    </ClCompile>
    <ClCompile Include="..\..\src\video\winrt\SDL_winrtkeyboard.cpp">
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
source/VisualC-WinRT/WinPhone80_VS2012/SDL-WinPhone80.vcxproj.filters
@@ -159,9 +159,6 @@
    <ClInclude Include="..\..\src\audio\SDL_audiodev_c.h">
      <Filter>Source Files</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\audio\SDL_audiomem.h">
      <Filter>Source Files</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\audio\SDL_audio_c.h">
      <Filter>Source Files</Filter>
    </ClInclude>
@@ -370,6 +367,9 @@
      <Filter>Source Files</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\video\SDL_egl_c.h">
      <Filter>Source Files</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\video\winrt\SDL_winrtgamebar_cpp.h">
      <Filter>Source Files</Filter>
    </ClInclude>
  </ItemGroup>
@@ -674,5 +674,8 @@
    <ClCompile Include="..\..\src\video\SDL_egl.c">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\video\winrt\SDL_winrtgamebar.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
  </ItemGroup>
</Project>
source/VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.vcxproj
@@ -73,7 +73,6 @@
    <ClInclude Include="..\..\src\audio\disk\SDL_diskaudio.h" />
    <ClInclude Include="..\..\src\audio\dummy\SDL_dummyaudio.h" />
    <ClInclude Include="..\..\src\audio\SDL_audiodev_c.h" />
    <ClInclude Include="..\..\src\audio\SDL_audiomem.h" />
    <ClInclude Include="..\..\src\audio\SDL_audio_c.h" />
    <ClInclude Include="..\..\src\audio\SDL_sysaudio.h" />
    <ClInclude Include="..\..\src\audio\SDL_wave.h" />
@@ -139,6 +138,7 @@
    <ClInclude Include="..\..\src\video\SDL_shape_internals.h" />
    <ClInclude Include="..\..\src\video\SDL_sysvideo.h" />
    <ClInclude Include="..\..\src\video\winrt\SDL_winrtevents_c.h" />
    <ClInclude Include="..\..\src\video\winrt\SDL_winrtgamebar_cpp.h" />
    <ClInclude Include="..\..\src\video\winrt\SDL_winrtmessagebox.h" />
    <ClInclude Include="..\..\src\video\winrt\SDL_winrtmouse_c.h" />
    <ClInclude Include="..\..\src\video\winrt\SDL_winrtopengles.h" />
@@ -275,6 +275,12 @@
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
    </ClCompile>
    <ClCompile Include="..\..\src\video\winrt\SDL_winrtgamebar.cpp">
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
    </ClCompile>
    <ClCompile Include="..\..\src\video\winrt\SDL_winrtkeyboard.cpp">
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
source/VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.vcxproj.filters
@@ -174,9 +174,6 @@
    <ClInclude Include="..\..\src\audio\SDL_audiodev_c.h">
      <Filter>Source Files</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\audio\SDL_audiomem.h">
      <Filter>Source Files</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\audio\SDL_audio_c.h">
      <Filter>Source Files</Filter>
    </ClInclude>
@@ -379,6 +376,9 @@
      <Filter>Source Files</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\thread\windows\SDL_systhread_c.h">
      <Filter>Source Files</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\video\winrt\SDL_winrtgamebar_cpp.h">
      <Filter>Source Files</Filter>
    </ClInclude>
  </ItemGroup>
@@ -686,5 +686,8 @@
    <ClCompile Include="..\..\src\thread\generic\SDL_syscond.c">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\video\winrt\SDL_winrtgamebar.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
  </ItemGroup>
</Project>
source/VisualC-WinRT/WinRT80_VS2012/SDL-WinRT80.vcxproj
@@ -175,6 +175,14 @@
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</CompileAsWinRT>
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</CompileAsWinRT>
    </ClCompile>
    <ClCompile Include="..\..\src\video\winrt\SDL_winrtgamebar.cpp">
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</CompileAsWinRT>
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</CompileAsWinRT>
    </ClCompile>
    <ClCompile Include="..\..\src\video\winrt\SDL_winrtkeyboard.cpp">
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
@@ -279,7 +287,6 @@
    <ClInclude Include="..\..\src\audio\disk\SDL_diskaudio.h" />
    <ClInclude Include="..\..\src\audio\dummy\SDL_dummyaudio.h" />
    <ClInclude Include="..\..\src\audio\SDL_audiodev_c.h" />
    <ClInclude Include="..\..\src\audio\SDL_audiomem.h" />
    <ClInclude Include="..\..\src\audio\SDL_audio_c.h" />
    <ClInclude Include="..\..\src\audio\SDL_sysaudio.h" />
    <ClInclude Include="..\..\src\audio\SDL_wave.h" />
@@ -353,6 +360,7 @@
    <ClInclude Include="..\..\src\video\SDL_shape_internals.h" />
    <ClInclude Include="..\..\src\video\SDL_sysvideo.h" />
    <ClInclude Include="..\..\src\video\winrt\SDL_winrtevents_c.h" />
    <ClInclude Include="..\..\src\video\winrt\SDL_winrtgamebar_cpp.h" />
    <ClInclude Include="..\..\src\video\winrt\SDL_winrtmessagebox.h" />
    <ClInclude Include="..\..\src\video\winrt\SDL_winrtmouse_c.h" />
    <ClInclude Include="..\..\src\video\winrt\SDL_winrtopengles.h" />
source/VisualC-WinRT/WinRT80_VS2012/SDL-WinRT80.vcxproj.filters
@@ -316,6 +316,9 @@
    <ClCompile Include="..\..\src\haptic\windows\SDL_windowshaptic.c">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\video\winrt\SDL_winrtgamebar.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
  </ItemGroup>
  <ItemGroup>
    <ClInclude Include="..\..\include\begin_code.h">
@@ -416,9 +419,6 @@
    </ClInclude>
    <ClInclude Include="..\..\include\SDL_clipboard.h">
      <Filter>Header Files</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\audio\SDL_audiomem.h">
      <Filter>Source Files</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\render\software\SDL_blendfillrect.h">
      <Filter>Source Files</Filter>
@@ -714,6 +714,9 @@
    <ClInclude Include="..\..\src\haptic\windows\SDL_xinputhaptic_c.h">
      <Filter>Source Files</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\video\winrt\SDL_winrtgamebar_cpp.h">
      <Filter>Source Files</Filter>
    </ClInclude>
  </ItemGroup>
  <ItemGroup>
    <Filter Include="Header Files">
source/VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj
@@ -81,7 +81,6 @@
    <ClInclude Include="..\..\src\audio\disk\SDL_diskaudio.h" />
    <ClInclude Include="..\..\src\audio\dummy\SDL_dummyaudio.h" />
    <ClInclude Include="..\..\src\audio\SDL_audiodev_c.h" />
    <ClInclude Include="..\..\src\audio\SDL_audiomem.h" />
    <ClInclude Include="..\..\src\audio\SDL_audio_c.h" />
    <ClInclude Include="..\..\src\audio\SDL_sysaudio.h" />
    <ClInclude Include="..\..\src\audio\SDL_wave.h" />
@@ -153,6 +152,7 @@
    <ClInclude Include="..\..\src\video\SDL_shape_internals.h" />
    <ClInclude Include="..\..\src\video\SDL_sysvideo.h" />
    <ClInclude Include="..\..\src\video\winrt\SDL_winrtevents_c.h" />
    <ClInclude Include="..\..\src\video\winrt\SDL_winrtgamebar_cpp.h" />
    <ClInclude Include="..\..\src\video\winrt\SDL_winrtmessagebox.h" />
    <ClInclude Include="..\..\src\video\winrt\SDL_winrtmouse_c.h" />
    <ClInclude Include="..\..\src\video\winrt\SDL_winrtopengles.h" />
@@ -309,6 +309,14 @@
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</CompileAsWinRT>
    </ClCompile>
    <ClCompile Include="..\..\src\video\winrt\SDL_winrtgamebar.cpp">
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</CompileAsWinRT>
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</CompileAsWinRT>
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</CompileAsWinRT>
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</CompileAsWinRT>
    </ClCompile>
    <ClCompile Include="..\..\src\video\winrt\SDL_winrtkeyboard.cpp">
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</CompileAsWinRT>
      <CompileAsWinRT Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</CompileAsWinRT>
source/VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj.filters
@@ -174,9 +174,6 @@
    <ClInclude Include="..\..\src\audio\SDL_audiodev_c.h">
      <Filter>Source Files</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\audio\SDL_audiomem.h">
      <Filter>Source Files</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\audio\SDL_audio_c.h">
      <Filter>Source Files</Filter>
    </ClInclude>
@@ -391,6 +388,9 @@
    <ClInclude Include="..\..\src\haptic\windows\SDL_dinputhaptic_c.h" />
    <ClInclude Include="..\..\src\haptic\windows\SDL_xinputhaptic_c.h" />
    <ClInclude Include="..\..\src\thread\windows\SDL_systhread_c.h">
      <Filter>Source Files</Filter>
    </ClInclude>
    <ClInclude Include="..\..\src\video\winrt\SDL_winrtgamebar_cpp.h">
      <Filter>Source Files</Filter>
    </ClInclude>
  </ItemGroup>
@@ -710,5 +710,8 @@
    <ClCompile Include="..\..\src\thread\windows\SDL_syssem.c">
      <Filter>Source Files</Filter>
    </ClCompile>
    <ClCompile Include="..\..\src\video\winrt\SDL_winrtgamebar.cpp">
      <Filter>Source Files</Filter>
    </ClCompile>
  </ItemGroup>
</Project>
source/VisualC.html
@@ -21,7 +21,7 @@
        </P>
        <P>
            There are different solution files for the various
            versions of the IDE. Please use the appropiate version
            versions of the IDE. Please use the appropriate version
            2008, 2010, 2012 or 2013.
        </P>
        <P>
@@ -101,7 +101,7 @@
                files to project")
            </P>
        <P><STRONG><FONT color="#009900">Instead of adding the files to your project it is more 
                    desireable to add them to the linker options: Project|Properties|Linker|Command
                    desirable to add them to the linker options: Project|Properties|Linker|Command
                    Line and type the names of the libraries to link with in the "Additional 
                    Options:" box.&nbsp; Note: This must be done&nbsp;for&nbsp;each&nbsp;build 
                    configuration (e.g. Release,Debug).</FONT></STRONG></P>
source/VisualC/SDL/SDL.vcxproj
@@ -294,7 +294,6 @@
    <ClInclude Include="resource.h" />
    <ClInclude Include="..\..\src\audio\SDL_audio_c.h" />
    <ClInclude Include="..\..\src\audio\SDL_audiodev_c.h" />
    <ClInclude Include="..\..\src\audio\SDL_audiomem.h" />
    <ClInclude Include="..\..\src\render\software\SDL_blendfillrect.h" />
    <ClInclude Include="..\..\src\render\software\SDL_blendline.h" />
    <ClInclude Include="..\..\src\render\software\SDL_blendpoint.h" />
source/VisualC/SDL/SDL.vcxproj.filters
@@ -230,7 +230,6 @@
    <ClInclude Include="resource.h" />
    <ClInclude Include="..\..\src\audio\SDL_audio_c.h" />
    <ClInclude Include="..\..\src\audio\SDL_audiodev_c.h" />
    <ClInclude Include="..\..\src\audio\SDL_audiomem.h" />
    <ClInclude Include="..\..\src\render\software\SDL_blendfillrect.h" />
    <ClInclude Include="..\..\src\render\software\SDL_blendline.h" />
    <ClInclude Include="..\..\src\render\software\SDL_blendpoint.h" />
source/VisualC/SDL/SDL_VS2008.vcproj
@@ -140,7 +140,6 @@
                PreprocessorDefinitions="_DEBUG;_WINDOWS"
                RuntimeLibrary="2"
                BufferSecurityCheck="false"
                EnableEnhancedInstructionSet="1"
                WarningLevel="3"
                DebugInformationFormat="1"
                OmitDefaultLibName="true"
@@ -305,7 +304,6 @@
                PreprocessorDefinitions="NDEBUG;_WINDOWS"
                RuntimeLibrary="2"
                BufferSecurityCheck="false"
                EnableEnhancedInstructionSet="1"
                WarningLevel="3"
                DebugInformationFormat="3"
                OmitDefaultLibName="true"
@@ -769,10 +767,6 @@
        </File>
        <File
            RelativePath="..\..\src\audio\SDL_audiodev_c.h"
            >
        </File>
        <File
            RelativePath="..\..\src\audio\SDL_audiomem.h"
            >
        </File>
        <File
source/VisualC/SDLmain/SDLmain_VS2008.vcproj
@@ -117,7 +117,6 @@
                StringPooling="true"
                RuntimeLibrary="2"
                BufferSecurityCheck="false"
                EnableEnhancedInstructionSet="1"
                WarningLevel="3"
                DebugInformationFormat="1"
                OmitDefaultLibName="true"
@@ -249,7 +248,6 @@
                PreprocessorDefinitions="WIN32,_DEBUG,_WINDOWS"
                RuntimeLibrary="2"
                BufferSecurityCheck="false"
                EnableEnhancedInstructionSet="1"
                WarningLevel="3"
                DebugInformationFormat="1"
                OmitDefaultLibName="true"
source/VisualC/SDLtest/SDLtest_VS2008.vcproj
@@ -117,7 +117,6 @@
                StringPooling="true"
                RuntimeLibrary="2"
                BufferSecurityCheck="false"
                EnableEnhancedInstructionSet="1"
                WarningLevel="3"
                DebugInformationFormat="1"
                OmitDefaultLibName="true"
@@ -249,7 +248,6 @@
                PreprocessorDefinitions="WIN32,_DEBUG,_WINDOWS"
                RuntimeLibrary="2"
                BufferSecurityCheck="false"
                EnableEnhancedInstructionSet="1"
                WarningLevel="3"
                DebugInformationFormat="1"
                OmitDefaultLibName="true"
source/WhatsNew.txt
@@ -2,6 +2,69 @@
This is a list of major changes in SDL's version history.
---------------------------------------------------------------------------
2.0.5:
---------------------------------------------------------------------------
General:
* Implemented audio capture support for some platforms
* Added SDL_DequeueAudio() to retrieve audio when buffer queuing is turned on for audio capture
* Added events for dragging and dropping text
* Added events for dragging and dropping multiple items
* By default the click raising a window will not be delivered to the SDL application. You can set the hint SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH to "1" to allow that click through to the window.
* Saving a surface with an alpha channel as a BMP will use a newer BMP format that supports alpha information. You can set the hint SDL_HINT_BMP_SAVE_LEGACY_FORMAT to "1" to use the old format.
* Added SDL_GetHintBoolean() to get the boolean value of a hint
* Added SDL_RenderSetIntegerScale() to set whether to smoothly scale or use integral multiples of the viewport size when scaling the rendering output
* Added SDL_CreateRGBSurfaceWithFormat() and SDL_CreateRGBSurfaceWithFormatFrom() to create an SDL surface with a specific pixel format
* Added SDL_GetDisplayUsableBounds() which returns the area usable for windows. For example, on Mac OS X, this subtracts the area occupied by the menu bar and dock.
* Added SDL_GetWindowBordersSize() which returns the size of the window's borders around the client area
* Added a window event SDL_WINDOWEVENT_HIT_TEST when a window had a hit test that wasn't SDL_HITTEST_NORMAL (e.g. in the title bar or window frame)
* Added SDL_SetWindowResizable() to change whether a window is resizable
* Added SDL_SetWindowOpacity() and SDL_GetWindowOpacity() to affect the window transparency
* Added SDL_SetWindowModalFor() to set a window as modal for another window
* Added support for AUDIO_U16LSB and AUDIO_U16MSB to SDL_MixAudioFormat()
* Fixed flipped images when reading back from target textures when using the OpenGL renderer
* Fixed texture color modulation with SDL_BLENDMODE_NONE when using the OpenGL renderer
* Fixed bug where the alpha value of colorkeys was ignored when blitting in some cases
Windows:
* Added a hint SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING to prevent SDL from raising a debugger exception to name threads. This exception can cause problems with .NET applications when running under a debugger.
* The hint SDL_HINT_THREAD_STACK_SIZE is now supported on Windows
* Fixed XBox controller triggers automatically being pulled at startup
* The first icon from the executable is used as the default window icon at runtime
* Fixed SDL log messages being printed twice if SDL was built with C library support
* Reset dead keys when the SDL window loses focus, so dead keys pressed in SDL applications don't affect text input into other applications.
Mac OS X:
* Fixed selecting the dummy video driver
* The caps lock key now generates a pressed event when pressed and a released event when released, instead of a press/release event pair when pressed.
* Fixed mouse wheel events on Mac OS X 10.12
* The audio driver has been updated to use AVFoundation for better compatibility with newer versions of Mac OS X
Linux:
* Added support for the Fcitx IME
* Added a window event SDL_WINDOWEVENT_TAKE_FOCUS when a window manager asks the SDL window whether it wants to take focus.
* Refresh rates are now rounded instead of truncated, e.g. 59.94 Hz is rounded up to 60 Hz instead of 59.
* Added initial support for touchscreens on Raspberry Pi
OpenBSD:
* SDL_GetBasePath() is now implemented on OpenBSD
iOS:
* Added support for dynamically loaded objects on iOS 8 and newer
tvOS:
* Added support for Apple TV
* Added a hint SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION to control whether he Apple TV remote's joystick axes will automatically match the rotation of the remote.
Android:
* Fixed SDL not resizing window when Android screen resolution changes
* Corrected the joystick Z axis reporting for the accelerometer
Emscripten (running in a web browser):
* Many bug fixes and improvements
---------------------------------------------------------------------------
2.0.4:
---------------------------------------------------------------------------
source/Xcode-iOS/Demos/Demos.xcodeproj/project.pbxproj
@@ -10,6 +10,27 @@
        1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; };
        1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
        1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; };
        FA30DEB01BBF5A8F009C397F /* common.c in Sources */ = {isa = PBXBuildFile; fileRef = FD77A0060E26BC0500F39101 /* common.c */; };
        FA30DEB11BBF5A93009C397F /* happy.c in Sources */ = {isa = PBXBuildFile; fileRef = FD77A0080E26BC0500F39101 /* happy.c */; };
        FA30DEB31BBF5AD7009C397F /* icon.bmp in Resources */ = {isa = PBXBuildFile; fileRef = FDB651CC0E43D19800F688B5 /* icon.bmp */; };
        FA30DEB41BBF5ADD009C397F /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = FD925B180E0F276600E92347 /* Icon.png */; };
        FA30DEB61BBF5AE6009C397F /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = FD787AA00E22A5CC003E8E36 /* Default.png */; };
        FA30DEB71BBF5BB8009C397F /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FA30DEAC1BBF59D9009C397F /* libSDL2.a */; };
        FA30DEC81BBF5C14009C397F /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAE0E9691BAF96A00098DFA4 /* GameController.framework */; };
        FA30DEC91BBF5C14009C397F /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDF0D7220E12D31800247964 /* AudioToolbox.framework */; };
        FA30DECA1BBF5C14009C397F /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDB96EDF0DEFC9DC00FAF19F /* QuartzCore.framework */; };
        FA30DECB1BBF5C14009C397F /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDB96ED30DEFC9C700FAF19F /* OpenGLES.framework */; };
        FA30DECC1BBF5C14009C397F /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; };
        FA30DECD1BBF5C14009C397F /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; };
        FA30DECE1BBF5C14009C397F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
        FA30DECF1BBF5C14009C397F /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDF0D71D0E12D2AB00247964 /* CoreAudio.framework */; };
        FA86C0371D9765BB009CB637 /* iOS Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FA86C0361D9765BA009CB637 /* iOS Launch Screen.storyboard */; };
        FA86C0381D9765BB009CB637 /* iOS Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FA86C0361D9765BA009CB637 /* iOS Launch Screen.storyboard */; };
        FA86C0391D9765BB009CB637 /* iOS Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FA86C0361D9765BA009CB637 /* iOS Launch Screen.storyboard */; };
        FA86C03A1D9765BB009CB637 /* iOS Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FA86C0361D9765BA009CB637 /* iOS Launch Screen.storyboard */; };
        FA86C03B1D9765BB009CB637 /* iOS Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FA86C0361D9765BA009CB637 /* iOS Launch Screen.storyboard */; };
        FA86C03C1D9765BB009CB637 /* iOS Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FA86C0361D9765BA009CB637 /* iOS Launch Screen.storyboard */; };
        FA86C03D1D9765BB009CB637 /* iOS Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FA86C0361D9765BA009CB637 /* iOS Launch Screen.storyboard */; };
        FA8B4BA31967070A00F8EB7C /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA8B4BA21967070A00F8EB7C /* CoreMotion.framework */; };
        FA8B4BA41967071300F8EB7C /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA8B4BA21967070A00F8EB7C /* CoreMotion.framework */; };
        FA8B4BA51967071A00F8EB7C /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA8B4BA21967070A00F8EB7C /* CoreMotion.framework */; };
@@ -17,6 +38,14 @@
        FA8B4BA71967072800F8EB7C /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA8B4BA21967070A00F8EB7C /* CoreMotion.framework */; };
        FA8B4BA81967073400F8EB7C /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA8B4BA21967070A00F8EB7C /* CoreMotion.framework */; };
        FA8B4BA91967073D00F8EB7C /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA8B4BA21967070A00F8EB7C /* CoreMotion.framework */; };
        FABA34D41D8B5E5600915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34D31D8B5E5600915323 /* AVFoundation.framework */; };
        FABA34D61D8B5E5A00915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34D31D8B5E5600915323 /* AVFoundation.framework */; };
        FABA34D81D8B5E7700915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34D71D8B5E7700915323 /* AVFoundation.framework */; };
        FABA34D91D8B5E7B00915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34D31D8B5E5600915323 /* AVFoundation.framework */; };
        FABA34DA1D8B5E7F00915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34D31D8B5E5600915323 /* AVFoundation.framework */; };
        FABA34DB1D8B5E8500915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34D31D8B5E5600915323 /* AVFoundation.framework */; };
        FABA34DC1D8B5E8900915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34D31D8B5E5600915323 /* AVFoundation.framework */; };
        FABA34DD1D8B5E8D00915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34D31D8B5E5600915323 /* AVFoundation.framework */; };
        FAE0E96A1BAF96A00098DFA4 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAE0E9691BAF96A00098DFA4 /* GameController.framework */; };
        FAE0E96C1BAF96A90098DFA4 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAE0E9691BAF96A00098DFA4 /* GameController.framework */; };
        FAE0E96D1BAF96AF0098DFA4 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAE0E9691BAF96A00098DFA4 /* GameController.framework */; };
@@ -168,6 +197,20 @@
            remoteGlobalIDString = FD6526620DE8FCCB002AD96B;
            remoteInfo = libSDL;
        };
        FA30DEAB1BBF59D9009C397F /* PBXContainerItemProxy */ = {
            isa = PBXContainerItemProxy;
            containerPortal = FD1B48920E313154007AB34E /* SDL.xcodeproj */;
            proxyType = 2;
            remoteGlobalIDString = FAB598141BB5C1B100BE72C5;
            remoteInfo = "libSDL-tv";
        };
        FA30DEAE1BBF5A69009C397F /* PBXContainerItemProxy */ = {
            isa = PBXContainerItemProxy;
            containerPortal = FD1B48920E313154007AB34E /* SDL.xcodeproj */;
            proxyType = 1;
            remoteGlobalIDString = FAB598131BB5C1B100BE72C5;
            remoteInfo = "libSDL-tv";
        };
        FD1B489D0E313154007AB34E /* PBXContainerItemProxy */ = {
            isa = PBXContainerItemProxy;
            containerPortal = FD1B48920E313154007AB34E /* SDL.xcodeproj */;
@@ -183,7 +226,11 @@
        1D6058910D05DD3D006BFB54 /* Rectangles.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Rectangles.app; sourceTree = BUILT_PRODUCTS_DIR; };
        1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
        8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
        FA30DE961BBF59D9009C397F /* Happy-TV.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Happy-TV.app"; sourceTree = BUILT_PRODUCTS_DIR; };
        FA86C0361D9765BA009CB637 /* iOS Launch Screen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = "iOS Launch Screen.storyboard"; sourceTree = "<group>"; };
        FA8B4BA21967070A00F8EB7C /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = System/Library/Frameworks/CoreMotion.framework; sourceTree = SDKROOT; };
        FABA34D31D8B5E5600915323 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
        FABA34D71D8B5E7700915323 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS10.0.sdk/System/Library/Frameworks/AVFoundation.framework; sourceTree = DEVELOPER_DIR; };
        FAE0E9691BAF96A00098DFA4 /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = System/Library/Frameworks/GameController.framework; sourceTree = SDKROOT; };
        FD15FCB20E086866003BDF25 /* Happy.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Happy.app; sourceTree = BUILT_PRODUCTS_DIR; };
        FD1B48920E313154007AB34E /* SDL.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SDL.xcodeproj; path = ../SDL/SDL.xcodeproj; sourceTree = SOURCE_ROOT; };
@@ -224,6 +271,7 @@
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34D41D8B5E5600915323 /* AVFoundation.framework in Frameworks */,
                FD1B48DD0E313255007AB34E /* libSDL2.a in Frameworks */,
                FAE0E96A1BAF96A00098DFA4 /* GameController.framework in Frameworks */,
                FA8B4BA31967070A00F8EB7C /* CoreMotion.framework in Frameworks */,
@@ -237,10 +285,28 @@
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
        FA30DE931BBF59D9009C397F /* Frameworks */ = {
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34D81D8B5E7700915323 /* AVFoundation.framework in Frameworks */,
                FA30DEB71BBF5BB8009C397F /* libSDL2.a in Frameworks */,
                FA30DEC81BBF5C14009C397F /* GameController.framework in Frameworks */,
                FA30DEC91BBF5C14009C397F /* AudioToolbox.framework in Frameworks */,
                FA30DECA1BBF5C14009C397F /* QuartzCore.framework in Frameworks */,
                FA30DECB1BBF5C14009C397F /* OpenGLES.framework in Frameworks */,
                FA30DECC1BBF5C14009C397F /* CoreGraphics.framework in Frameworks */,
                FA30DECD1BBF5C14009C397F /* UIKit.framework in Frameworks */,
                FA30DECE1BBF5C14009C397F /* Foundation.framework in Frameworks */,
                FA30DECF1BBF5C14009C397F /* CoreAudio.framework in Frameworks */,
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
        FD15FCB00E086866003BDF25 /* Frameworks */ = {
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34D61D8B5E5A00915323 /* AVFoundation.framework in Frameworks */,
                FD1B49980E313261007AB34E /* libSDL2.a in Frameworks */,
                FAE0E96C1BAF96A90098DFA4 /* GameController.framework in Frameworks */,
                FA8B4BA41967071300F8EB7C /* CoreMotion.framework in Frameworks */,
@@ -258,6 +324,7 @@
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34D91D8B5E7B00915323 /* AVFoundation.framework in Frameworks */,
                FD1B499C0E313269007AB34E /* libSDL2.a in Frameworks */,
                FAE0E96D1BAF96AF0098DFA4 /* GameController.framework in Frameworks */,
                FA8B4BA51967071A00F8EB7C /* CoreMotion.framework in Frameworks */,
@@ -275,6 +342,7 @@
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34DD1D8B5E8D00915323 /* AVFoundation.framework in Frameworks */,
                FDB652000E43D1F300F688B5 /* libSDL2.a in Frameworks */,
                FAE0E9711BAF96BB0098DFA4 /* GameController.framework in Frameworks */,
                FA8B4BA91967073D00F8EB7C /* CoreMotion.framework in Frameworks */,
@@ -292,6 +360,7 @@
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34DA1D8B5E7F00915323 /* AVFoundation.framework in Frameworks */,
                FD1B499E0E31326C007AB34E /* libSDL2.a in Frameworks */,
                FAE0E96E1BAF96B10098DFA4 /* GameController.framework in Frameworks */,
                FA8B4BA61967072100F8EB7C /* CoreMotion.framework in Frameworks */,
@@ -309,6 +378,7 @@
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34DC1D8B5E8900915323 /* AVFoundation.framework in Frameworks */,
                FD1B49A20E313273007AB34E /* libSDL2.a in Frameworks */,
                FAE0E9701BAF96B80098DFA4 /* GameController.framework in Frameworks */,
                FA8B4BA81967073400F8EB7C /* CoreMotion.framework in Frameworks */,
@@ -326,6 +396,7 @@
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34DB1D8B5E8500915323 /* AVFoundation.framework in Frameworks */,
                FD1B49A00E313270007AB34E /* libSDL2.a in Frameworks */,
                FAE0E96F1BAF96B50098DFA4 /* GameController.framework in Frameworks */,
                FA8B4BA71967072800F8EB7C /* CoreMotion.framework in Frameworks */,
@@ -352,6 +423,7 @@
                FDF0D6A40E12D05400247964 /* Mixer.app */,
                FDC52EDE0E2843D6008D768C /* Fireworks.app */,
                FDB6520C0E43D1F300F688B5 /* Keyboard.app */,
                FA30DE961BBF59D9009C397F /* Happy-TV.app */,
            );
            name = Products;
            sourceTree = "<group>";
@@ -359,6 +431,7 @@
        29B97314FDCFA39411CA2CEA /* CustomTemplate */ = {
            isa = PBXGroup;
            children = (
                FA86C0361D9765BA009CB637 /* iOS Launch Screen.storyboard */,
                FD1B48920E313154007AB34E /* SDL.xcodeproj */,
                FD77A0040E26BC0500F39101 /* src */,
                29B97317FDCFA39411CA2CEA /* Resources */,
@@ -382,6 +455,8 @@
        29B97323FDCFA39411CA2CEA /* Frameworks */ = {
            isa = PBXGroup;
            children = (
                FABA34D71D8B5E7700915323 /* AVFoundation.framework */,
                FABA34D31D8B5E5600915323 /* AVFoundation.framework */,
                FAE0E9691BAF96A00098DFA4 /* GameController.framework */,
                FA8B4BA21967070A00F8EB7C /* CoreMotion.framework */,
                FDF0D7220E12D31800247964 /* AudioToolbox.framework */,
@@ -399,6 +474,7 @@
            isa = PBXGroup;
            children = (
                FD1B489E0E313154007AB34E /* libSDL2.a */,
                FA30DEAC1BBF59D9009C397F /* libSDL2.a */,
            );
            name = Products;
            sourceTree = "<group>";
@@ -471,6 +547,24 @@
            name = Rectangles;
            productName = SDLiPodTest;
            productReference = 1D6058910D05DD3D006BFB54 /* Rectangles.app */;
            productType = "com.apple.product-type.application";
        };
        FA30DE951BBF59D9009C397F /* Happy-TV */ = {
            isa = PBXNativeTarget;
            buildConfigurationList = FA30DEAD1BBF59D9009C397F /* Build configuration list for PBXNativeTarget "Happy-TV" */;
            buildPhases = (
                FA30DE921BBF59D9009C397F /* Sources */,
                FA30DE941BBF59D9009C397F /* Resources */,
                FA30DE931BBF59D9009C397F /* Frameworks */,
            );
            buildRules = (
            );
            dependencies = (
                FA30DEAF1BBF5A69009C397F /* PBXTargetDependency */,
            );
            name = "Happy-TV";
            productName = "Happy-TV";
            productReference = FA30DE961BBF59D9009C397F /* Happy-TV.app */;
            productType = "com.apple.product-type.application";
        };
        FD15FCB10E086866003BDF25 /* Happy */ = {
@@ -588,6 +682,14 @@
            isa = PBXProject;
            attributes = {
                LastUpgradeCheck = 0630;
                TargetAttributes = {
                    FA30DE951BBF59D9009C397F = {
                        CreatedOnToolsVersion = 7.1;
                    };
                    FDC52EC60E2843D6008D768C = {
                        ProvisioningStyle = Automatic;
                    };
                };
            };
            buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Demos" */;
            compatibilityVersion = "Xcode 3.2";
@@ -598,6 +700,7 @@
                Japanese,
                French,
                German,
                Base,
            );
            mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */;
            projectDirPath = "";
@@ -611,6 +714,7 @@
            targets = (
                1D6058900D05DD3D006BFB54 /* Rectangles */,
                FD15FCB10E086866003BDF25 /* Happy */,
                FA30DE951BBF59D9009C397F /* Happy-TV */,
                FD5F9BE30E0DEBEA008E885B /* Accel */,
                FDC202DD0E107B1200ABAC90 /* Touch */,
                FDF0D6920E12D05400247964 /* Mixer */,
@@ -621,6 +725,13 @@
/* End PBXProject section */
/* Begin PBXReferenceProxy section */
        FA30DEAC1BBF59D9009C397F /* libSDL2.a */ = {
            isa = PBXReferenceProxy;
            fileType = archive.ar;
            path = libSDL2.a;
            remoteRef = FA30DEAB1BBF59D9009C397F /* PBXContainerItemProxy */;
            sourceTree = BUILT_PRODUCTS_DIR;
        };
        FD1B489E0E313154007AB34E /* libSDL2.a */ = {
            isa = PBXReferenceProxy;
            fileType = archive.ar;
@@ -635,8 +746,19 @@
            isa = PBXResourcesBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FA86C0371D9765BB009CB637 /* iOS Launch Screen.storyboard in Resources */,
                FD925B1B0E0F276600E92347 /* Icon.png in Resources */,
                FD787AA20E22A5CC003E8E36 /* Default.png in Resources */,
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
        FA30DE941BBF59D9009C397F /* Resources */ = {
            isa = PBXResourcesBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FA30DEB31BBF5AD7009C397F /* icon.bmp in Resources */,
                FA30DEB41BBF5ADD009C397F /* Icon.png in Resources */,
                FA30DEB61BBF5AE6009C397F /* Default.png in Resources */,
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
@@ -645,6 +767,7 @@
            buildActionMask = 2147483647;
            files = (
                FDB651D00E43D1AD00F688B5 /* icon.bmp in Resources */,
                FA86C0381D9765BB009CB637 /* iOS Launch Screen.storyboard in Resources */,
                FD925B1A0E0F276600E92347 /* Icon.png in Resources */,
                FD787AA10E22A5CC003E8E36 /* Default.png in Resources */,
            );
@@ -658,6 +781,7 @@
                FDB651D10E43D1B300F688B5 /* ship.bmp in Resources */,
                FD925B190E0F276600E92347 /* Icon.png in Resources */,
                FD787AA30E22A5CC003E8E36 /* Default.png in Resources */,
                FA86C0391D9765BB009CB637 /* iOS Launch Screen.storyboard in Resources */,
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
@@ -669,6 +793,7 @@
                FDB651FA0E43D1F300F688B5 /* Icon.png in Resources */,
                FDB651FB0E43D1F300F688B5 /* Default.png in Resources */,
                FDB652C70E43E25900F688B5 /* kromasky_16x16.bmp in Resources */,
                FA86C03D1D9765BB009CB637 /* iOS Launch Screen.storyboard in Resources */,
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
@@ -677,6 +802,7 @@
            buildActionMask = 2147483647;
            files = (
                FDB651D30E43D1BA00F688B5 /* stroke.bmp in Resources */,
                FA86C03A1D9765BB009CB637 /* iOS Launch Screen.storyboard in Resources */,
                FDC202E10E107B1200ABAC90 /* Icon.png in Resources */,
                FD787AA40E22A5CC003E8E36 /* Default.png in Resources */,
            );
@@ -687,6 +813,7 @@
            buildActionMask = 2147483647;
            files = (
                FDB651D80E43D1D800F688B5 /* stroke.bmp in Resources */,
                FA86C03C1D9765BB009CB637 /* iOS Launch Screen.storyboard in Resources */,
                FDC52EC80E2843D6008D768C /* Icon.png in Resources */,
                FDC52EC90E2843D6008D768C /* Default.png in Resources */,
            );
@@ -699,6 +826,7 @@
                FDB651D40E43D1C500F688B5 /* ds_brush_snare.wav in Resources */,
                FDB651D50E43D1C500F688B5 /* ds_china.wav in Resources */,
                FDB651D60E43D1C500F688B5 /* ds_kick_big_amb.wav in Resources */,
                FA86C03B1D9765BB009CB637 /* iOS Launch Screen.storyboard in Resources */,
                FDB651D70E43D1C500F688B5 /* ds_loose_skin_mute.wav in Resources */,
                FDF0D6960E12D05400247964 /* Icon.png in Resources */,
                FD787AA50E22A5CC003E8E36 /* Default.png in Resources */,
@@ -714,6 +842,15 @@
            files = (
                FD77A0130E26BC0500F39101 /* common.c in Sources */,
                FD77A0160E26BC0500F39101 /* rectangles.c in Sources */,
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
        FA30DE921BBF59D9009C397F /* Sources */ = {
            isa = PBXSourcesBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FA30DEB01BBF5A8F009C397F /* common.c in Sources */,
                FA30DEB11BBF5A93009C397F /* happy.c in Sources */,
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
@@ -809,6 +946,11 @@
            name = libSDL;
            targetProxy = 049F36A0130CD8A000FF080F /* PBXContainerItemProxy */;
        };
        FA30DEAF1BBF5A69009C397F /* PBXTargetDependency */ = {
            isa = PBXTargetDependency;
            name = "libSDL-tv";
            targetProxy = FA30DEAE1BBF5A69009C397F /* PBXContainerItemProxy */;
        };
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
@@ -816,6 +958,7 @@
            isa = XCBuildConfiguration;
            buildSettings = {
                INFOPLIST_FILE = Info.plist;
                PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.Rectangles;
                PRODUCT_NAME = Rectangles;
            };
            name = Debug;
@@ -824,6 +967,7 @@
            isa = XCBuildConfiguration;
            buildSettings = {
                INFOPLIST_FILE = Info.plist;
                PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.Rectangles;
                PRODUCT_NAME = Rectangles;
            };
            name = Release;
@@ -852,11 +996,100 @@
            };
            name = Release;
        };
        FA30DEA71BBF59D9009C397F /* Debug */ = {
            isa = XCBuildConfiguration;
            buildSettings = {
                ALWAYS_SEARCH_USER_PATHS = NO;
                CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
                CLANG_CXX_LIBRARY = "libc++";
                CLANG_ENABLE_MODULES = YES;
                CLANG_ENABLE_OBJC_ARC = YES;
                CLANG_WARN_BOOL_CONVERSION = YES;
                CLANG_WARN_CONSTANT_CONVERSION = YES;
                CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
                CLANG_WARN_EMPTY_BODY = YES;
                CLANG_WARN_ENUM_CONVERSION = YES;
                CLANG_WARN_INT_CONVERSION = YES;
                CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
                CLANG_WARN_UNREACHABLE_CODE = YES;
                CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
                COPY_PHASE_STRIP = NO;
                DEBUG_INFORMATION_FORMAT = dwarf;
                DEVELOPMENT_TEAM = "";
                ENABLE_STRICT_OBJC_MSGSEND = YES;
                ENABLE_TESTABILITY = YES;
                GCC_C_LANGUAGE_STANDARD = gnu99;
                GCC_DYNAMIC_NO_PIC = NO;
                GCC_NO_COMMON_BLOCKS = YES;
                GCC_PREPROCESSOR_DEFINITIONS = (
                    "DEBUG=1",
                    "$(inherited)",
                );
                GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
                GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
                GCC_WARN_UNDECLARED_SELECTOR = YES;
                GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
                GCC_WARN_UNUSED_FUNCTION = YES;
                GCC_WARN_UNUSED_VARIABLE = YES;
                INFOPLIST_FILE = Info.plist;
                LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
                MTL_ENABLE_DEBUG_INFO = YES;
                PRODUCT_BUNDLE_IDENTIFIER = "com.yourcompany.Happy-TV";
                PRODUCT_NAME = "$(TARGET_NAME)";
                SDKROOT = appletvos;
                TARGETED_DEVICE_FAMILY = 3;
                TVOS_DEPLOYMENT_TARGET = 9.0;
            };
            name = Debug;
        };
        FA30DEA81BBF59D9009C397F /* Release */ = {
            isa = XCBuildConfiguration;
            buildSettings = {
                ALWAYS_SEARCH_USER_PATHS = NO;
                CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
                CLANG_CXX_LIBRARY = "libc++";
                CLANG_ENABLE_MODULES = YES;
                CLANG_ENABLE_OBJC_ARC = YES;
                CLANG_WARN_BOOL_CONVERSION = YES;
                CLANG_WARN_CONSTANT_CONVERSION = YES;
                CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
                CLANG_WARN_EMPTY_BODY = YES;
                CLANG_WARN_ENUM_CONVERSION = YES;
                CLANG_WARN_INT_CONVERSION = YES;
                CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
                CLANG_WARN_UNREACHABLE_CODE = YES;
                CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
                COPY_PHASE_STRIP = NO;
                DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
                DEVELOPMENT_TEAM = "";
                ENABLE_NS_ASSERTIONS = NO;
                ENABLE_STRICT_OBJC_MSGSEND = YES;
                GCC_C_LANGUAGE_STANDARD = gnu99;
                GCC_NO_COMMON_BLOCKS = YES;
                GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
                GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
                GCC_WARN_UNDECLARED_SELECTOR = YES;
                GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
                GCC_WARN_UNUSED_FUNCTION = YES;
                GCC_WARN_UNUSED_VARIABLE = YES;
                INFOPLIST_FILE = Info.plist;
                LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
                MTL_ENABLE_DEBUG_INFO = NO;
                PRODUCT_BUNDLE_IDENTIFIER = "com.yourcompany.Happy-TV";
                PRODUCT_NAME = "$(TARGET_NAME)";
                SDKROOT = appletvos;
                TARGETED_DEVICE_FAMILY = 3;
                TVOS_DEPLOYMENT_TARGET = 9.0;
                VALIDATE_PRODUCT = YES;
            };
            name = Release;
        };
        FD15FCB50E086866003BDF25 /* Debug */ = {
            isa = XCBuildConfiguration;
            buildSettings = {
                GCC_DYNAMIC_NO_PIC = NO;
                INFOPLIST_FILE = Info.plist;
                PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.Happy;
                PRODUCT_NAME = Happy;
                SDKROOT = iphoneos;
            };
@@ -866,6 +1099,7 @@
            isa = XCBuildConfiguration;
            buildSettings = {
                INFOPLIST_FILE = Info.plist;
                PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.Happy;
                PRODUCT_NAME = Happy;
                SDKROOT = iphoneos;
            };
@@ -875,6 +1109,7 @@
            isa = XCBuildConfiguration;
            buildSettings = {
                INFOPLIST_FILE = Info.plist;
                PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.Accel;
                PRODUCT_NAME = Accel;
                SDKROOT = iphoneos;
            };
@@ -884,6 +1119,7 @@
            isa = XCBuildConfiguration;
            buildSettings = {
                INFOPLIST_FILE = Info.plist;
                PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.Accel;
                PRODUCT_NAME = Accel;
                SDKROOT = iphoneos;
            };
@@ -893,6 +1129,7 @@
            isa = XCBuildConfiguration;
            buildSettings = {
                INFOPLIST_FILE = Info.plist;
                PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.Keyboard;
                PRODUCT_NAME = Keyboard;
                SDKROOT = iphoneos;
            };
@@ -902,6 +1139,7 @@
            isa = XCBuildConfiguration;
            buildSettings = {
                INFOPLIST_FILE = Info.plist;
                PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.Keyboard;
                PRODUCT_NAME = Keyboard;
                SDKROOT = iphoneos;
            };
@@ -911,6 +1149,7 @@
            isa = XCBuildConfiguration;
            buildSettings = {
                INFOPLIST_FILE = Info.plist;
                PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.Touch;
                PRODUCT_NAME = Touch;
                SDKROOT = iphoneos;
            };
@@ -920,6 +1159,7 @@
            isa = XCBuildConfiguration;
            buildSettings = {
                INFOPLIST_FILE = Info.plist;
                PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.Touch;
                PRODUCT_NAME = Touch;
                SDKROOT = iphoneos;
            };
@@ -928,7 +1168,10 @@
        FDC52EDC0E2843D6008D768C /* Debug */ = {
            isa = XCBuildConfiguration;
            buildSettings = {
                "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
                DEVELOPMENT_TEAM = "";
                INFOPLIST_FILE = Info.plist;
                PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.Fireworks;
                PRODUCT_NAME = Fireworks;
                SDKROOT = iphoneos;
            };
@@ -937,7 +1180,10 @@
        FDC52EDD0E2843D6008D768C /* Release */ = {
            isa = XCBuildConfiguration;
            buildSettings = {
                "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
                DEVELOPMENT_TEAM = "";
                INFOPLIST_FILE = Info.plist;
                PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.Fireworks;
                PRODUCT_NAME = Fireworks;
                SDKROOT = iphoneos;
            };
@@ -947,6 +1193,7 @@
            isa = XCBuildConfiguration;
            buildSettings = {
                INFOPLIST_FILE = Info.plist;
                PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.Mixer;
                PRODUCT_NAME = Mixer;
                SDKROOT = iphoneos;
            };
@@ -956,6 +1203,7 @@
            isa = XCBuildConfiguration;
            buildSettings = {
                INFOPLIST_FILE = Info.plist;
                PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.Mixer;
                PRODUCT_NAME = Mixer;
                SDKROOT = iphoneos;
            };
@@ -982,6 +1230,15 @@
            defaultConfigurationIsVisible = 0;
            defaultConfigurationName = Release;
        };
        FA30DEAD1BBF59D9009C397F /* Build configuration list for PBXNativeTarget "Happy-TV" */ = {
            isa = XCConfigurationList;
            buildConfigurations = (
                FA30DEA71BBF59D9009C397F /* Debug */,
                FA30DEA81BBF59D9009C397F /* Release */,
            );
            defaultConfigurationIsVisible = 0;
            defaultConfigurationName = Release;
        };
        FD15FCB70E086867003BDF25 /* Build configuration list for PBXNativeTarget "Happy" */ = {
            isa = XCConfigurationList;
            buildConfigurations = (
source/Xcode-iOS/Demos/Info.plist
@@ -11,7 +11,7 @@
    <key>CFBundleIconFile</key>
    <string></string>
    <key>CFBundleIdentifier</key>
    <string>com.yourcompany.${PRODUCT_NAME:identifier}</string>
    <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
@@ -24,6 +24,8 @@
    <string>1.0</string>
    <key>NSMainNibFile</key>
    <string></string>
    <key>UILaunchStoryboardName</key>
    <string>iOS Launch Screen</string>
    <key>UISupportedInterfaceOrientations</key>
    <array/>
</dict>
source/Xcode-iOS/Demos/README
@@ -2,15 +2,15 @@
About the iPhone OS Demo Applications
==============================================================================
Demos.xcodeproj contains several targets for iPhone oriented SDL demos.  These demos are written strictly using SDL 1.3 calls.  All the demos except for Fireworks (which requires OpenGL ES) should work on platforms other than iPhone OS, though you'll need to write your own compile script.  To run them on your favorite platform, you may wish to set the macros SCREEN_WIDTH and SCREEN_HEIGHT, located in common.h.
Demos.xcodeproj contains several targets for iPhone oriented SDL demos.  These demos are written strictly using SDL 2.0 calls.  All the demos except for Fireworks (which requires OpenGL ES) should work on platforms other than iPhone OS, though you'll need to write your own compile script.
Common files:
    common.c and common.h contain code common to all demo applications.  This includes macros about the screen dimensions (in pixels), simple error handling, and functions for generating random numbers.
    common.c and common.h contain code common to all demo applications.  This includes functions about delta timing (in seconds), simple error handling, and functions for generating random numbers.
Rectangles (rectangles.c):
    Draws randomly sized and colored rectangles all over the screen by using SDL_RenderFill.  This is the simplest of all the demos.
    Draws randomly sized and colored rectangles all over the screen by using SDL_RenderFillRect.  This is the simplest of all the demos.
Happy (happy.c):
source/Xcode-iOS/Demos/iOS Launch Screen.storyboard
New file
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11201" systemVersion="16A323" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
    <dependencies>
        <deployment identifier="iOS"/>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11161"/>
        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
    </dependencies>
    <scenes>
        <!--View Controller-->
        <scene sceneID="EHf-IW-A2E">
            <objects>
                <viewController id="01J-lp-oVM" sceneMemberID="viewController">
                    <layoutGuides>
                        <viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/>
                        <viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
                    </layoutGuides>
                    <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <subviews>
                            <imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Default.png" translatesAutoresizingMaskIntoConstraints="NO" id="VeL-6u-rS3"/>
                        </subviews>
                        <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                        <constraints>
                            <constraint firstItem="VeL-6u-rS3" firstAttribute="top" secondItem="Ze5-6b-2t3" secondAttribute="top" id="C5X-Vg-tvO"/>
                            <constraint firstAttribute="trailing" secondItem="VeL-6u-rS3" secondAttribute="trailing" id="X4i-1U-3JE"/>
                            <constraint firstItem="VeL-6u-rS3" firstAttribute="bottom" secondItem="xb3-aO-Qok" secondAttribute="top" id="dSu-2l-DcF"/>
                            <constraint firstItem="VeL-6u-rS3" firstAttribute="leading" secondItem="Ze5-6b-2t3" secondAttribute="leading" id="xKC-uj-bxE"/>
                        </constraints>
                    </view>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="52" y="374.66266866566718"/>
        </scene>
    </scenes>
    <resources>
        <image name="Default.png" width="320" height="480"/>
    </resources>
</document>
source/Xcode-iOS/Demos/src/accelerometer.c
@@ -8,7 +8,6 @@
#include "math.h"
#include "common.h"
#define MILLESECONDS_PER_FRAME 16       /* about 60 frames per second */
#define DAMPING 0.5f;           /* after bouncing off a wall, damping coefficient determines final speed */
#define FRICTION 0.0008f        /* coefficient of acceleration that opposes direction of motion */
#define GRAVITY_CONSTANT 0.004f /* how sensitive the ship is to the accelerometer */
@@ -31,9 +30,10 @@
static SDL_Texture *space = 0;       /* texture for space (background */
void
render(SDL_Renderer *renderer, int w, int h)
render(SDL_Renderer *renderer, int w, int h, double deltaTime)
{
    double deltaMilliseconds = deltaTime * 1000;
    float speed;
    /* get joystick (accelerometer) axis values and normalize them */
    float ax = SDL_JoystickGetAxis(accelerometer, 0);
@@ -53,12 +53,12 @@
     */
    shipData.vx +=
        ax * SDL_IPHONE_MAX_GFORCE / SINT16_MAX * GRAVITY_CONSTANT *
        MILLESECONDS_PER_FRAME;
        deltaMilliseconds;
    shipData.vy +=
        ay * SDL_IPHONE_MAX_GFORCE / SINT16_MAX * GRAVITY_CONSTANT *
        MILLESECONDS_PER_FRAME;
        deltaMilliseconds;
    float speed = sqrt(shipData.vx * shipData.vx + shipData.vy * shipData.vy);
    speed = sqrt(shipData.vx * shipData.vx + shipData.vy * shipData.vy);
    if (speed > 0) {
        /* compensate for friction */
@@ -66,10 +66,10 @@
        float diry = shipData.vy / speed;   /* normalized y velocity */
        /* update velocity due to friction */
        if (speed - FRICTION * MILLESECONDS_PER_FRAME > 0) {
        if (speed - FRICTION * deltaMilliseconds > 0) {
            /* apply friction */
            shipData.vx -= dirx * FRICTION * MILLESECONDS_PER_FRAME;
            shipData.vy -= diry * FRICTION * MILLESECONDS_PER_FRAME;
            shipData.vx -= dirx * FRICTION * deltaMilliseconds;
            shipData.vy -= diry * FRICTION * deltaMilliseconds;
        } else {
            /* applying friction would MORE than stop the ship, so just stop the ship */
            shipData.vx = 0.0f;
@@ -78,8 +78,8 @@
    }
    /* update ship location */
    shipData.x += shipData.vx * MILLESECONDS_PER_FRAME;
    shipData.y += shipData.vy * MILLESECONDS_PER_FRAME;
    shipData.x += shipData.vx * deltaMilliseconds;
    shipData.y += shipData.vy * deltaMilliseconds;
    if (shipData.x > maxx) {
        shipData.x = maxx;
@@ -160,9 +160,6 @@
    SDL_Window *window;         /* main window */
    SDL_Renderer *renderer;
    Uint32 startFrame;          /* time frame began to process */
    Uint32 endFrame;            /* time frame ended processing */
    Sint32 delay;               /* time to pause waiting to draw next frame */
    int done;                   /* should we clean up and exit? */
    int w, h;
@@ -172,12 +169,11 @@
    }
    /* create main window and renderer */
    window = SDL_CreateWindow(NULL, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT,
                                SDL_WINDOW_OPENGL |
                                SDL_WINDOW_FULLSCREEN);
    window = SDL_CreateWindow(NULL, 0, 0, 320, 480, SDL_WINDOW_FULLSCREEN | SDL_WINDOW_ALLOW_HIGHDPI);
    renderer = SDL_CreateRenderer(window, 0, 0);
    
    SDL_GetWindowSize(window, &w, &h);
    SDL_RenderSetLogicalSize(renderer, w, h);
    /* print out some info about joysticks and try to open accelerometer for use */
    printf("There are %d joysticks available\n", SDL_NumJoysticks());
@@ -207,24 +203,15 @@
    done = 0;
    /* enter main loop */
    while (!done) {
        startFrame = SDL_GetTicks();
        double deltaTime = updateDeltaTime();
        SDL_Event event;
        while (SDL_PollEvent(&event)) {
            if (event.type == SDL_QUIT) {
                done = 1;
            }
        }
        render(renderer, w, h);
        endFrame = SDL_GetTicks();
        /* figure out how much time we have left, and then sleep */
        delay = MILLESECONDS_PER_FRAME - (endFrame - startFrame);
        if (delay < 0) {
            delay = 0;
        } else if (delay > MILLESECONDS_PER_FRAME) {
            delay = MILLESECONDS_PER_FRAME;
        }
        SDL_Delay(delay);
        render(renderer, w, h, deltaTime);
        SDL_Delay(1);
    }
    /* delete textures */
source/Xcode-iOS/Demos/src/common.c
@@ -32,5 +32,25 @@
fatalError(const char *string)
{
    printf("%s: %s\n", string, SDL_GetError());
    SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, string, SDL_GetError(), NULL);
    exit(1);
}
static Uint64 prevTime = 0;
double
updateDeltaTime()
{
    Uint64 curTime;
    double deltaTime;
    if (prevTime == 0) {
        prevTime = SDL_GetPerformanceCounter();
    }
    curTime = SDL_GetPerformanceCounter();
    deltaTime = (double) (curTime - prevTime) / (double) SDL_GetPerformanceFrequency();
    prevTime = curTime;
    return deltaTime;
}
source/Xcode-iOS/Demos/src/common.h
@@ -4,9 +4,7 @@
 *  use however you want
 */
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 480
extern int randomInt(int min, int max);
extern float randomFloat(float min, float max);
extern void fatalError(const char *string);
extern double updateDeltaTime();
source/Xcode-iOS/Demos/src/fireworks.c
@@ -10,13 +10,13 @@
#include <math.h>
#include <time.h>
#define MILLESECONDS_PER_FRAME 16       /* about 60 frames per second */
#define ACCEL 0.0001f           /* acceleration due to gravity, units in pixels per millesecond squared */
#define WIND_RESISTANCE 0.00005f        /* acceleration per unit velocity due to wind resistance */
#define MAX_PARTICLES 2000      /* maximum number of particles displayed at once */
static GLuint particleTextureID;        /* OpenGL particle texture id */
static SDL_bool pointSizeExtensionSupported;    /* is GL_OES_point_size_array supported ? */
static float pointSizeScale;
/*
    used to describe what type of particle a given struct particle is.
    emitter - this particle flies up, shooting off trail particles, then finally explodes into dust particles.
@@ -55,7 +55,7 @@
void initializeTexture();
int nextPowerOfTwo(int x);
void drawParticles();
void stepParticles(void);
void stepParticles(double deltaTime);
/*  helper function (used in texture loading)
    returns next power of two greater than or equal to x
@@ -71,11 +71,12 @@
}
/*
    steps each active particle by timestep MILLESECONDS_PER_FRAME
    steps each active particle by timestep deltaTime
*/
void
stepParticles(void)
stepParticles(double deltaTime)
{
    float deltaMilliseconds = deltaTime * 1000;
    int i;
    struct particle *slot = particles;
    struct particle *curr = particles;
@@ -93,10 +94,10 @@
                curr->isActive = 0;
            /* step velocity, then step position */
            curr->yvel += ACCEL * MILLESECONDS_PER_FRAME;
            curr->yvel += ACCEL * deltaMilliseconds;
            curr->xvel += 0.0f;
            curr->y += curr->yvel * MILLESECONDS_PER_FRAME;
            curr->x += curr->xvel * MILLESECONDS_PER_FRAME;
            curr->y += curr->yvel * deltaMilliseconds;
            curr->x += curr->xvel * deltaMilliseconds;
            /* particle behavior */
            if (curr->type == emitter) {
@@ -111,29 +112,29 @@
                    sqrt(curr->xvel * curr->xvel + curr->yvel * curr->yvel);
                /*      if wind resistance is not powerful enough to stop us completely,
                   then apply winde resistance, otherwise just stop us completely */
                if (WIND_RESISTANCE * MILLESECONDS_PER_FRAME < speed) {
                if (WIND_RESISTANCE * deltaMilliseconds < speed) {
                    float normx = curr->xvel / speed;
                    float normy = curr->yvel / speed;
                    curr->xvel -=
                        normx * WIND_RESISTANCE * MILLESECONDS_PER_FRAME;
                        normx * WIND_RESISTANCE * deltaMilliseconds;
                    curr->yvel -=
                        normy * WIND_RESISTANCE * MILLESECONDS_PER_FRAME;
                        normy * WIND_RESISTANCE * deltaMilliseconds;
                } else {
                    curr->xvel = curr->yvel = 0;        /* stop particle */
                }
                if (curr->color[3] <= MILLESECONDS_PER_FRAME * 0.1275f) {
                if (curr->color[3] <= deltaMilliseconds * 0.1275f) {
                    /* if this next step will cause us to fade out completely
                       then just mark for deletion */
                    curr->isActive = 0;
                } else {
                    /* otherwise, let's fade a bit more */
                    curr->color[3] -= MILLESECONDS_PER_FRAME * 0.1275f;
                    curr->color[3] -= deltaMilliseconds * 0.1275f;
                }
                /* if we're a dust particle, shrink our size */
                if (curr->type == dust)
                    curr->size -= MILLESECONDS_PER_FRAME * 0.010f;
                    curr->size -= deltaMilliseconds * 0.010f;
            }
@@ -147,7 +148,7 @@
    /* the number of active particles is computed as the difference between
       old number of active particles, where slot points, and the
       new size of the array, where particles points */
    num_active_particles = slot - particles;
    num_active_particles = (int) (slot - particles);
}
/*
@@ -206,7 +207,7 @@
        p->y = emitter->y + emitter->yvel;
        p->isActive = 1;
        p->type = dust;
        p->size = 15;
        p->size = 15 * pointSizeScale;
        /* inherit emitter's color */
        p->color[0] = emitter->color[0];
        p->color[1] = emitter->color[1];
@@ -244,7 +245,7 @@
    p->color[3] = (0.7f) * 255;
    /* set other attributes */
    p->size = 10;
    p->size = 10 * pointSizeScale;
    p->type = trail;
    p->isActive = 1;
@@ -298,7 +299,7 @@
    p->xvel = 0;
    p->yvel = -sqrt(2 * ACCEL * (screen_h - y));
    /* set other attributes */
    p->size = 10;
    p->size = 10 * pointSizeScale;
    p->type = emitter;
    p->isActive = 1;
    /* our array has expanded at the end */
@@ -363,7 +364,7 @@
{
    SDL_Window *window;         /* main window */
    SDL_GLContext context;
    int w, h;
    int drawableW, drawableH;
    Uint32 startFrame;          /* time frame began to process */
    Uint32 endFrame;            /* time frame ended processing */
    Uint32 delay;               /* time to pause waiting to draw next frame */
@@ -391,10 +392,18 @@
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
    /* create main window and renderer */
    window = SDL_CreateWindow(NULL, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT,
                                SDL_WINDOW_OPENGL |
                                SDL_WINDOW_BORDERLESS);
    window = SDL_CreateWindow(NULL, 0, 0, 320, 480,
                                SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS | SDL_WINDOW_ALLOW_HIGHDPI);
    context = SDL_GL_CreateContext(window);
    /* The window size and drawable size may be different when highdpi is enabled,
     * due to the increased pixel density of the drawable. */
    SDL_GetWindowSize(window, &screen_w, &screen_h);
    SDL_GL_GetDrawableSize(window, &drawableW, &drawableH);
    /* In OpenGL, point sizes are always in pixels. We don't want them looking
     * tiny on a retina screen. */
    pointSizeScale = (float) drawableH / (float) screen_h;
    /* load the particle texture */
    initializeTexture();
@@ -412,8 +421,7 @@
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    SDL_GetWindowSize(window, &screen_w, &screen_h);
    glViewport(0, 0, screen_w, screen_h);
    glViewport(0, 0, drawableW, drawableH);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
@@ -436,14 +444,14 @@
        glEnableClientState(GL_POINT_SIZE_ARRAY_OES);
    } else {
        /* if extension not available then all particles have size 10 */
        glPointSize(10);
        glPointSize(10 * pointSizeScale);
    }
    done = 0;
    /* enter main loop */
    while (!done) {
        startFrame = SDL_GetTicks();
        SDL_Event event;
        double deltaTime = updateDeltaTime();
        while (SDL_PollEvent(&event)) {
            if (event.type == SDL_QUIT) {
                done = 1;
@@ -454,19 +462,10 @@
                spawnEmitterParticle(x, y);
            }
        }
        stepParticles();
        stepParticles(deltaTime);
        drawParticles();
        SDL_GL_SwapWindow(window);
        endFrame = SDL_GetTicks();
        /* figure out how much time we have left, and then sleep */
        delay = MILLESECONDS_PER_FRAME - (endFrame - startFrame);
        if (delay > MILLESECONDS_PER_FRAME) {
            delay = MILLESECONDS_PER_FRAME;
        }
        if (delay > 0) {
            SDL_Delay(delay);
        }
        SDL_Delay(1);
    }
    /* delete textures */
source/Xcode-iOS/Demos/src/happy.c
@@ -8,8 +8,7 @@
#include "common.h"
#define NUM_HAPPY_FACES 100     /* number of faces to draw */
#define MILLESECONDS_PER_FRAME 16       /* about 60 frames per second */
#define HAPPY_FACE_SIZE 32      /* width and height of happyface (pixels) */
#define HAPPY_FACE_SIZE 32      /* width and height of happyface */
static SDL_Texture *texture = 0;    /* reference to texture holding happyface */
@@ -24,30 +23,37 @@
    units of velocity are pixels per millesecond
*/
void
initializeHappyFaces()
initializeHappyFaces(SDL_Renderer *renderer)
{
    int i;
    int w;
    int h;
    SDL_RenderGetLogicalSize(renderer, &w, &h);
    for (i = 0; i < NUM_HAPPY_FACES; i++) {
        faces[i].x = randomFloat(0.0f, SCREEN_WIDTH - HAPPY_FACE_SIZE);
        faces[i].y = randomFloat(0.0f, SCREEN_HEIGHT - HAPPY_FACE_SIZE);
        faces[i].xvel = randomFloat(-0.1f, 0.1f);
        faces[i].yvel = randomFloat(-0.1f, 0.1f);
        faces[i].x = randomFloat(0.0f, w - HAPPY_FACE_SIZE);
        faces[i].y = randomFloat(0.0f, h - HAPPY_FACE_SIZE);
        faces[i].xvel = randomFloat(-60.0f, 60.0f);
        faces[i].yvel = randomFloat(-60.0f, 60.0f);
    }
}
void
render(SDL_Renderer *renderer)
render(SDL_Renderer *renderer, double deltaTime)
{
    int i;
    SDL_Rect srcRect;
    SDL_Rect dstRect;
    int w;
    int h;
    SDL_RenderGetLogicalSize(renderer, &w, &h);
    /* setup boundaries for happyface bouncing */
    Uint16 maxx = SCREEN_WIDTH - HAPPY_FACE_SIZE;
    Uint16 maxy = SCREEN_HEIGHT - HAPPY_FACE_SIZE;
    Uint16 minx = 0;
    Uint16 miny = 0;
    int maxx = w - HAPPY_FACE_SIZE;
    int maxy = h - HAPPY_FACE_SIZE;
    int minx = 0;
    int miny = 0;
    /* setup rects for drawing */
    srcRect.x = 0;
@@ -68,8 +74,8 @@
       - draw
     */
    for (i = 0; i < NUM_HAPPY_FACES; i++) {
        faces[i].x += faces[i].xvel * MILLESECONDS_PER_FRAME;
        faces[i].y += faces[i].yvel * MILLESECONDS_PER_FRAME;
        faces[i].x += faces[i].xvel * deltaTime;
        faces[i].y += faces[i].yvel * deltaTime;
        if (faces[i].x > maxx) {
            faces[i].x = maxx;
            faces[i].xvel = -faces[i].xvel;
@@ -123,48 +129,45 @@
int
main(int argc, char *argv[])
{
    SDL_Window *window;
    SDL_Renderer *renderer;
    Uint32 startFrame;
    Uint32 endFrame;
    Uint32 delay;
    int done;
    int width;
    int height;
    /* initialize SDL */
    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        fatalError("Could not initialize SDL");
    }
    window = SDL_CreateWindow(NULL, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT,
                                SDL_WINDOW_OPENGL |
                                SDL_WINDOW_BORDERLESS);
    /* The specified window size doesn't matter - except for its aspect ratio,
     * which determines whether the window is in portrait or landscape on iOS
     * (if SDL_WINDOW_RESIZABLE isn't specified). */
    window = SDL_CreateWindow(NULL, 0, 0, 320, 480, SDL_WINDOW_FULLSCREEN | SDL_WINDOW_ALLOW_HIGHDPI);
    renderer = SDL_CreateRenderer(window, -1, 0);
    SDL_GetWindowSize(window, &width, &height);
    SDL_RenderSetLogicalSize(renderer, width, height);
    initializeTexture(renderer);
    initializeHappyFaces();
    initializeHappyFaces(renderer);
    /* main loop */
    done = 0;
    while (!done) {
        startFrame = SDL_GetTicks();
        SDL_Event event;
        double deltaTime = updateDeltaTime();
        while (SDL_PollEvent(&event)) {
            if (event.type == SDL_QUIT) {
                done = 1;
            }
        }
        render(renderer);
        endFrame = SDL_GetTicks();
        /* figure out how much time we have left, and then sleep */
        delay = MILLESECONDS_PER_FRAME - (endFrame - startFrame);
        if (delay < 0) {
            delay = 0;
        } else if (delay > MILLESECONDS_PER_FRAME) {
            delay = MILLESECONDS_PER_FRAME;
        }
        SDL_Delay(delay);
        render(renderer, deltaTime);
        SDL_Delay(1);
    }
    /* cleanup */
source/Xcode-iOS/Demos/src/keyboard.c
@@ -4,8 +4,8 @@
 *  use however you want
 */
#import "SDL.h"
#import "common.h"
#include "SDL.h"
#include "common.h"
#define GLYPH_SIZE_IMAGE 16     /* size of glyphs (characters) in the bitmap font file */
#define GLYPH_SIZE_SCREEN 32    /* size of glyphs (characters) as shown on the screen */
@@ -132,10 +132,13 @@
void
getPositionForCharNumber(int n, int *x, int *y)
{
    int renderW, renderH;
    SDL_RenderGetLogicalSize(renderer, &renderW, &renderH);
    int x_padding = 16;         /* padding space on left and right side of screen */
    int y_padding = 32;         /* padding space at top of screen */
    /* figure out the number of characters that can fit horizontally across the screen */
    int max_x_chars = (SCREEN_WIDTH - 2 * x_padding) / GLYPH_SIZE_SCREEN;
    int max_x_chars = (renderW - 2 * x_padding) / GLYPH_SIZE_SCREEN;
    int line_separation = 5;    /* pixels between each line */
    *x = (n % max_x_chars) * GLYPH_SIZE_SCREEN + x_padding;
    *y = (n / max_x_chars) * (GLYPH_SIZE_SCREEN + line_separation) +
@@ -228,20 +231,24 @@
int
main(int argc, char *argv[])
{
    int index;                  /* index of last key we pushed in the bitmap font */
    SDL_Window *window;
    SDL_Event event;            /* last event received */
    SDL_Keymod mod;             /* key modifiers of last key we pushed */
    SDL_Scancode scancode;      /* scancode of last key we pushed */
    int width;
    int height;
    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        printf("Error initializing SDL: %s", SDL_GetError());
    }
    /* create window */
    window = SDL_CreateWindow("iPhone keyboard test", 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0);
    window = SDL_CreateWindow("iPhone keyboard test", 0, 0, 320, 480, SDL_WINDOW_ALLOW_HIGHDPI);
    /* create renderer */
    renderer = SDL_CreateRenderer(window, -1, 0);
    SDL_GetWindowSize(window, &width, &height);
    SDL_RenderSetLogicalSize(renderer, width, height);
    /* load up our font */
    loadFont();
@@ -253,7 +260,7 @@
    int done = 0;
    /* loop till we get SDL_Quit */
    while (SDL_WaitEvent(&event)) {
    while (!done && SDL_WaitEvent(&event)) {
        switch (event.type) {
        case SDL_QUIT:
            done = 1;
source/Xcode-iOS/Demos/src/mixer.c
@@ -4,12 +4,11 @@
 *  use however you want
 */
#import "SDL.h"
#import "common.h"
#include "SDL.h"
#include "common.h"
#define NUM_CHANNELS 8          /* max number of sounds we can play at once */
#define NUM_DRUMS 4             /* number of drums in our set */
#define MILLESECONDS_PER_FRAME 16       /* about 60 frames per second */
static struct
{
@@ -33,7 +32,7 @@
void handleMouseButtonDown(SDL_Event * event);
void handleMouseButtonUp(SDL_Event * event);
int playSound(struct sound *);
void initializeButtons();
void initializeButtons(SDL_Renderer *);
void audioCallback(void *userdata, Uint8 * stream, int len);
void loadSound(const char *file, struct sound *s);
@@ -52,19 +51,21 @@
/* sets up the buttons (color, position, state) */
void
initializeButtons()
initializeButtons(SDL_Renderer *renderer)
{
    int i;
    int spacing = 10;           /* gap between drum buttons */
    SDL_Rect buttonRect;        /* keeps track of where to position drum */
    SDL_Color upColor = { 86, 86, 140, 255 };   /* color of drum when not pressed */
    SDL_Color downColor = { 191, 191, 221, 255 };       /* color of drum when pressed */
    int renderW, renderH;
    SDL_RenderGetLogicalSize(renderer, &renderW, &renderH);
    buttonRect.x = spacing;
    buttonRect.y = spacing;
    buttonRect.w = SCREEN_WIDTH - 2 * spacing;
    buttonRect.h = (SCREEN_HEIGHT - (NUM_DRUMS + 1) * spacing) / NUM_DRUMS;
    buttonRect.w = renderW - 2 * spacing;
    buttonRect.h = (renderH - (NUM_DRUMS + 1) * spacing) / NUM_DRUMS;
    /* setup each button */
    for (i = 0; i < NUM_DRUMS; i++) {
@@ -270,22 +271,22 @@
int
main(int argc, char *argv[])
{
    int done;                   /* has user tried to quit ? */
    SDL_Window *window;         /* main window */
    SDL_Renderer *renderer;
    SDL_Event event;
    Uint32 startFrame;          /* holds when frame started processing */
    Uint32 endFrame;            /* holds when frame ended processing */
    Uint32 delay;               /* calculated delay, how long should we wait before next frame? */
    int i;
    int width;
    int height;
    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) {
        fatalError("could not initialize SDL");
    }
    window =
        SDL_CreateWindow(NULL, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT,
                         SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS);
    window = SDL_CreateWindow(NULL, 0, 0, 320, 480, SDL_WINDOW_BORDERLESS | SDL_WINDOW_ALLOW_HIGHDPI);
    renderer = SDL_CreateRenderer(window, 0, 0);
    SDL_GetWindowSize(window, &width, &height);
    SDL_RenderSetLogicalSize(renderer, width, height);
    /* initialize the mixer */
    SDL_memset(&mixer, 0, sizeof(mixer));
@@ -309,12 +310,11 @@
    loadSound("ds_china.wav", &drums[0]);
    /* setup positions, colors, and state of buttons */
    initializeButtons();
    initializeButtons(renderer);
    /* enter main loop */
    done = 0;
    while (!done) {
        startFrame = SDL_GetTicks();
        while (SDL_PollEvent(&event)) {
            switch (event.type) {
            case SDL_MOUSEBUTTONDOWN:
@@ -329,20 +329,11 @@
            }
        }
        render(renderer);               /* draw buttons */
        endFrame = SDL_GetTicks();
        /* figure out how much time we have left, and then sleep */
        delay = MILLESECONDS_PER_FRAME - (endFrame - startFrame);
        if (delay < 0) {
            delay = 0;
        } else if (delay > MILLESECONDS_PER_FRAME) {
            delay = MILLESECONDS_PER_FRAME;
        }
        SDL_Delay(delay);
        SDL_Delay(1);
    }
    /* cleanup code, let's free up those sound buffers */
    int i;
    for (i = 0; i < NUM_DRUMS; i++) {
        SDL_free(drums[i].buffer);
    }
source/Xcode-iOS/Demos/src/rectangles.c
@@ -11,14 +11,18 @@
void
render(SDL_Renderer *renderer)
{
    Uint8 r, g, b;
    int renderW;
    int renderH;
    SDL_RenderGetLogicalSize(renderer, &renderW, &renderH);
    /*  Come up with a random rectangle */
    SDL_Rect rect;
    rect.w = randomInt(64, 128);
    rect.h = randomInt(64, 128);
    rect.x = randomInt(0, SCREEN_WIDTH);
    rect.y = randomInt(0, SCREEN_HEIGHT);
    rect.x = randomInt(0, renderW);
    rect.y = randomInt(0, renderH);
    /* Come up with a random color */
    r = randomInt(50, 255);
@@ -31,51 +35,58 @@
    /* update screen */
    SDL_RenderPresent(renderer);
}
int
main(int argc, char *argv[])
{
    if (SDL_Init(SDL_INIT_VIDEO/* | SDL_INIT_AUDIO */) < 0)
    {
        printf("Unable to initialize SDL");
    SDL_Window *window;
    SDL_Renderer *renderer;
    int done;
    SDL_Event event;
    int windowW;
    int windowH;
    /* initialize SDL */
    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        fatalError("Could not initialize SDL");
    }
    SDL_LogSetAllPriority(SDL_LOG_PRIORITY_WARN);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    int landscape = 1;
    int modes = SDL_GetNumDisplayModes(0);
    int sx = 0, sy = 0;
    for (int i = 0; i < modes; i++)
    {
        SDL_DisplayMode mode;
        SDL_GetDisplayMode(0, i, &mode);
        if (landscape ? mode.w > sx : mode.h > sy)
        {
            sx = mode.w;
            sy = mode.h;
    /* seed random number generator */
    srand(time(NULL));
    /* create window and renderer */
    window = SDL_CreateWindow(NULL, 0, 0, 320, 480, SDL_WINDOW_ALLOW_HIGHDPI);
    if (window == 0) {
        fatalError("Could not initialize Window");
    }
    renderer = SDL_CreateRenderer(window, -1, 0);
    if (!renderer) {
        fatalError("Could not create renderer");
    }
    SDL_GetWindowSize(window, &windowW, &windowH);
    SDL_RenderSetLogicalSize(renderer, windowW, windowH);
    /* Fill screen with black */
    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
    SDL_RenderClear(renderer);
    /* Enter render loop, waiting for user to quit */
    done = 0;
    while (!done) {
        while (SDL_PollEvent(&event)) {
            if (event.type == SDL_QUIT) {
                done = 1;
            }
        }
        render(renderer);
        SDL_Delay(1);
    }
    printf("picked: %d %d\n", sx, sy);
    SDL_Window *_sdl_window = NULL;
    SDL_GLContext _sdl_context = NULL;
    _sdl_window = SDL_CreateWindow("fred",
                                   0, 0,
                                   sx, sy,
                                   SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS);
    SDL_SetHint("SDL_HINT_ORIENTATIONS", "LandscapeLeft LandscapeRight");
    int ax = 0, ay = 0;
    SDL_GetWindowSize(_sdl_window, &ax, &ay);
    printf("given: %d %d\n", ax, ay);
    /* shutdown SDL */
    SDL_Quit();
    return 0;
}
source/Xcode-iOS/Demos/src/touch.c
@@ -26,15 +26,17 @@
    float dx_prime = dx / iterations;   /* x-shift per iteration */
    float dy_prime = dy / iterations;   /* y-shift per iteration */
    SDL_Rect dstRect;           /* rect to draw brush sprite into */
    float x;
    float y;
    int i;
    dstRect.w = BRUSH_SIZE;
    dstRect.h = BRUSH_SIZE;
    /* setup x and y for the location of the first sprite */
    float x = startx - BRUSH_SIZE / 2.0f;
    float y = starty - BRUSH_SIZE / 2.0f;
    x = startx - BRUSH_SIZE / 2.0f;
    y = starty - BRUSH_SIZE / 2.0f;
    int i;
    /* draw a series of blots to form the line */
    for (i = 0; i < iterations; i++) {
        dstRect.x = x;
@@ -80,6 +82,7 @@
    SDL_Window *window;         /* main window */
    SDL_Renderer *renderer;
    int done;                   /* does user want to quit? */
    int w, h;
    /* initialize SDL */
    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
@@ -87,11 +90,12 @@
    }
    /* create main window and renderer */
    window = SDL_CreateWindow(NULL, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT,
                                SDL_WINDOW_OPENGL |
                                SDL_WINDOW_BORDERLESS);
    window = SDL_CreateWindow(NULL, 0, 0, 320, 480, SDL_WINDOW_BORDERLESS | SDL_WINDOW_ALLOW_HIGHDPI);
    renderer = SDL_CreateRenderer(window, 0, 0);
    SDL_GetWindowSize(window, &w, &h);
    SDL_RenderSetLogicalSize(renderer, w, h);
    /* load brush texture */
    initializeTexture(renderer);
source/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj
@@ -74,7 +74,7 @@
        56A6703818565E760007D20F /* SDL_dynapi.h in Headers */ = {isa = PBXBuildFile; fileRef = 56A6703418565E760007D20F /* SDL_dynapi.h */; };
        56C181DF17C44D5E00406AE3 /* SDL_filesystem.h in Headers */ = {isa = PBXBuildFile; fileRef = 56C181DE17C44D5E00406AE3 /* SDL_filesystem.h */; };
        56C181E217C44D7A00406AE3 /* SDL_sysfilesystem.m in Sources */ = {isa = PBXBuildFile; fileRef = 56C181E117C44D7A00406AE3 /* SDL_sysfilesystem.m */; };
        56EA86FB13E9EC2B002E47EB /* SDL_coreaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = 56EA86F913E9EC2B002E47EB /* SDL_coreaudio.c */; };
        56EA86FB13E9EC2B002E47EB /* SDL_coreaudio.m in Sources */ = {isa = PBXBuildFile; fileRef = 56EA86F913E9EC2B002E47EB /* SDL_coreaudio.m */; };
        56EA86FC13E9EC2B002E47EB /* SDL_coreaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 56EA86FA13E9EC2B002E47EB /* SDL_coreaudio.h */; };
        56ED04E1118A8EE200A56AA6 /* SDL_power.c in Sources */ = {isa = PBXBuildFile; fileRef = 56ED04E0118A8EE200A56AA6 /* SDL_power.c */; };
        56ED04E3118A8EFD00A56AA6 /* SDL_syspower.m in Sources */ = {isa = PBXBuildFile; fileRef = 56ED04E2118A8EFD00A56AA6 /* SDL_syspower.m */; };
@@ -143,7 +143,104 @@
        AABCC3941640643D00AB8930 /* SDL_uikitmessagebox.h in Headers */ = {isa = PBXBuildFile; fileRef = AABCC3921640643D00AB8930 /* SDL_uikitmessagebox.h */; };
        AABCC3951640643D00AB8930 /* SDL_uikitmessagebox.m in Sources */ = {isa = PBXBuildFile; fileRef = AABCC3931640643D00AB8930 /* SDL_uikitmessagebox.m */; };
        AADA5B8F16CCAB7C00107CF7 /* SDL_bits.h in Headers */ = {isa = PBXBuildFile; fileRef = AADA5B8E16CCAB7C00107CF7 /* SDL_bits.h */; };
        FAD4F7021BA3C4E8008346CE /* SDL_sysjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = FAD4F7011BA3C4E8008346CE /* SDL_sysjoystick_c.h */; settings = {ASSET_TAGS = (); }; };
        FA1DC2721C62BE65008F99A0 /* SDL_uikitclipboard.h in Headers */ = {isa = PBXBuildFile; fileRef = FA1DC2701C62BE65008F99A0 /* SDL_uikitclipboard.h */; };
        FA1DC2731C62BE65008F99A0 /* SDL_uikitclipboard.m in Sources */ = {isa = PBXBuildFile; fileRef = FA1DC2711C62BE65008F99A0 /* SDL_uikitclipboard.m */; };
        FAB5981D1BB5C31500BE72C5 /* SDL_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = 04FFAB8912E23B8D00BA343D /* SDL_atomic.c */; };
        FAB5981E1BB5C31500BE72C5 /* SDL_spinlock.c in Sources */ = {isa = PBXBuildFile; fileRef = 04FFAB8A12E23B8D00BA343D /* SDL_spinlock.c */; };
        FAB5981F1BB5C31500BE72C5 /* SDL_coreaudio.m in Sources */ = {isa = PBXBuildFile; fileRef = 56EA86F913E9EC2B002E47EB /* SDL_coreaudio.m */; };
        FAB598211BB5C31500BE72C5 /* SDL_dummyaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99B91D0DD52EDC00FB1D6B /* SDL_dummyaudio.c */; };
        FAB598231BB5C31500BE72C5 /* SDL_audio.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99B9440DD52EDC00FB1D6B /* SDL_audio.c */; };
        FAB598251BB5C31500BE72C5 /* SDL_audiocvt.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99B9460DD52EDC00FB1D6B /* SDL_audiocvt.c */; };
        FAB598271BB5C31500BE72C5 /* SDL_audiotypecvt.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99B94A0DD52EDC00FB1D6B /* SDL_audiotypecvt.c */; };
        FAB598281BB5C31500BE72C5 /* SDL_mixer.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99B94B0DD52EDC00FB1D6B /* SDL_mixer.c */; };
        FAB5982A1BB5C31500BE72C5 /* SDL_wave.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99B9530DD52EDC00FB1D6B /* SDL_wave.c */; };
        FAB5982C1BB5C31500BE72C5 /* SDL_cpuinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99B98B0DD52EDC00FB1D6B /* SDL_cpuinfo.c */; };
        FAB5982F1BB5C31500BE72C5 /* SDL_dynapi.c in Sources */ = {isa = PBXBuildFile; fileRef = 56A6703318565E760007D20F /* SDL_dynapi.c */; };
        FAB598361BB5C31500BE72C5 /* SDL_clipboardevents.c in Sources */ = {isa = PBXBuildFile; fileRef = 0420496F11E6F03D007E7EC9 /* SDL_clipboardevents.c */; };
        FAB598381BB5C31500BE72C5 /* SDL_dropevents.c in Sources */ = {isa = PBXBuildFile; fileRef = AA704DD5162AA90A0076D1C1 /* SDL_dropevents.c */; };
        FAB5983A1BB5C31500BE72C5 /* SDL_events.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99B9930DD52EDC00FB1D6B /* SDL_events.c */; };
        FAB5983C1BB5C31500BE72C5 /* SDL_gesture.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BA9D6011EF474A00B60E01 /* SDL_gesture.c */; };
        FAB5983E1BB5C31500BE72C5 /* SDL_keyboard.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99B9950DD52EDC00FB1D6B /* SDL_keyboard.c */; };
        FAB598401BB5C31500BE72C5 /* SDL_mouse.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99B9970DD52EDC00FB1D6B /* SDL_mouse.c */; };
        FAB598421BB5C31500BE72C5 /* SDL_quit.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99B9990DD52EDC00FB1D6B /* SDL_quit.c */; };
        FAB598441BB5C31500BE72C5 /* SDL_touch.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BA9D6211EF474A00B60E01 /* SDL_touch.c */; };
        FAB598461BB5C31500BE72C5 /* SDL_windowevents.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99B99B0DD52EDC00FB1D6B /* SDL_windowevents.c */; };
        FAB598491BB5C31600BE72C5 /* SDL_rwopsbundlesupport.m in Sources */ = {isa = PBXBuildFile; fileRef = 006E9887119552DD001DE610 /* SDL_rwopsbundlesupport.m */; };
        FAB5984A1BB5C31600BE72C5 /* SDL_rwops.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99B99E0DD52EDC00FB1D6B /* SDL_rwops.c */; };
        FAB5984B1BB5C31600BE72C5 /* SDL_sysfilesystem.m in Sources */ = {isa = PBXBuildFile; fileRef = 56C181E117C44D7A00406AE3 /* SDL_sysfilesystem.m */; };
        FAB5984C1BB5C31600BE72C5 /* SDL_syshaptic.c in Sources */ = {isa = PBXBuildFile; fileRef = 047677B80EA76A31008ABAF1 /* SDL_syshaptic.c */; };
        FAB5984D1BB5C31600BE72C5 /* SDL_haptic.c in Sources */ = {isa = PBXBuildFile; fileRef = 047677B90EA76A31008ABAF1 /* SDL_haptic.c */; };
        FAB598501BB5C31600BE72C5 /* SDL_sysjoystick.m in Sources */ = {isa = PBXBuildFile; fileRef = FD689F000E26E5B600F90B21 /* SDL_sysjoystick.m */; };
        FAB598511BB5C31600BE72C5 /* SDL_gamecontroller.c in Sources */ = {isa = PBXBuildFile; fileRef = AA0AD06116647BBB00CE5896 /* SDL_gamecontroller.c */; };
        FAB598521BB5C31600BE72C5 /* SDL_joystick.c in Sources */ = {isa = PBXBuildFile; fileRef = FD5F9D1E0E0E08B3008E885B /* SDL_joystick.c */; };
        FAB598551BB5C31600BE72C5 /* SDL_sysloadso.c in Sources */ = {isa = PBXBuildFile; fileRef = 047AF1B20EA98D6C00811173 /* SDL_sysloadso.c */; };
        FAB598561BB5C31600BE72C5 /* SDL_sysloadso.c in Sources */ = {isa = PBXBuildFile; fileRef = FD8BD8190E27E25900B52CD5 /* SDL_sysloadso.c */; };
        FAB598571BB5C31600BE72C5 /* SDL_power.c in Sources */ = {isa = PBXBuildFile; fileRef = 56ED04E0118A8EE200A56AA6 /* SDL_power.c */; };
        FAB598581BB5C31600BE72C5 /* SDL_syspower.m in Sources */ = {isa = PBXBuildFile; fileRef = 56ED04E2118A8EFD00A56AA6 /* SDL_syspower.m */; };
        FAB598591BB5C31600BE72C5 /* SDL_render_gles.c in Sources */ = {isa = PBXBuildFile; fileRef = 0442EC5212FE1C28004C9285 /* SDL_render_gles.c */; };
        FAB5985A1BB5C31600BE72C5 /* SDL_render_gles2.c in Sources */ = {isa = PBXBuildFile; fileRef = 0402A85512FE70C600CECEE3 /* SDL_render_gles2.c */; };
        FAB5985B1BB5C31600BE72C5 /* SDL_shaders_gles2.c in Sources */ = {isa = PBXBuildFile; fileRef = 0402A85612FE70C600CECEE3 /* SDL_shaders_gles2.c */; };
        FAB5985D1BB5C31600BE72C5 /* SDL_blendfillrect.c in Sources */ = {isa = PBXBuildFile; fileRef = 04F7806A12FB751400FC43C0 /* SDL_blendfillrect.c */; };
        FAB5985F1BB5C31600BE72C5 /* SDL_blendline.c in Sources */ = {isa = PBXBuildFile; fileRef = 04F7806C12FB751400FC43C0 /* SDL_blendline.c */; };
        FAB598611BB5C31600BE72C5 /* SDL_blendpoint.c in Sources */ = {isa = PBXBuildFile; fileRef = 04F7806E12FB751400FC43C0 /* SDL_blendpoint.c */; };
        FAB598641BB5C31600BE72C5 /* SDL_drawline.c in Sources */ = {isa = PBXBuildFile; fileRef = 04F7807112FB751400FC43C0 /* SDL_drawline.c */; };
        FAB598661BB5C31600BE72C5 /* SDL_drawpoint.c in Sources */ = {isa = PBXBuildFile; fileRef = 04F7807312FB751400FC43C0 /* SDL_drawpoint.c */; };
        FAB598681BB5C31600BE72C5 /* SDL_render_sw.c in Sources */ = {isa = PBXBuildFile; fileRef = 0442EC4F12FE1C1E004C9285 /* SDL_render_sw.c */; };
        FAB5986A1BB5C31600BE72C5 /* SDL_rotate.c in Sources */ = {isa = PBXBuildFile; fileRef = AA628AD9159369E3005138DD /* SDL_rotate.c */; };
        FAB5986D1BB5C31600BE72C5 /* SDL_render.c in Sources */ = {isa = PBXBuildFile; fileRef = 041B2CEA12FA0F680087D585 /* SDL_render.c */; };
        FAB5986F1BB5C31600BE72C5 /* SDL_yuv_mmx.c in Sources */ = {isa = PBXBuildFile; fileRef = 04409BA312FA989600FB9AA8 /* SDL_yuv_mmx.c */; };
        FAB598711BB5C31600BE72C5 /* SDL_yuv_sw.c in Sources */ = {isa = PBXBuildFile; fileRef = 04409BA512FA989600FB9AA8 /* SDL_yuv_sw.c */; };
        FAB598721BB5C31600BE72C5 /* SDL_getenv.c in Sources */ = {isa = PBXBuildFile; fileRef = FD3F4A700DEA620800C5B771 /* SDL_getenv.c */; };
        FAB598731BB5C31600BE72C5 /* SDL_iconv.c in Sources */ = {isa = PBXBuildFile; fileRef = FD3F4A710DEA620800C5B771 /* SDL_iconv.c */; };
        FAB598741BB5C31600BE72C5 /* SDL_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = FD3F4A720DEA620800C5B771 /* SDL_malloc.c */; };
        FAB598751BB5C31600BE72C5 /* SDL_qsort.c in Sources */ = {isa = PBXBuildFile; fileRef = FD3F4A730DEA620800C5B771 /* SDL_qsort.c */; };
        FAB598761BB5C31600BE72C5 /* SDL_stdlib.c in Sources */ = {isa = PBXBuildFile; fileRef = FD3F4A740DEA620800C5B771 /* SDL_stdlib.c */; };
        FAB598771BB5C31600BE72C5 /* SDL_string.c in Sources */ = {isa = PBXBuildFile; fileRef = FD3F4A750DEA620800C5B771 /* SDL_string.c */; };
        FAB598781BB5C31600BE72C5 /* SDL_syscond.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99BA070DD52EDC00FB1D6B /* SDL_syscond.c */; };
        FAB598791BB5C31600BE72C5 /* SDL_sysmutex.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99BA080DD52EDC00FB1D6B /* SDL_sysmutex.c */; };
        FAB5987B1BB5C31600BE72C5 /* SDL_syssem.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99BA0A0DD52EDC00FB1D6B /* SDL_syssem.c */; };
        FAB5987C1BB5C31600BE72C5 /* SDL_systhread.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99BA0B0DD52EDC00FB1D6B /* SDL_systhread.c */; };
        FAB5987E1BB5C31600BE72C5 /* SDL_systls.c in Sources */ = {isa = PBXBuildFile; fileRef = AA0F8494178D5F1A00823F9D /* SDL_systls.c */; };
        FAB598801BB5C31600BE72C5 /* SDL_thread.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99BA150DD52EDC00FB1D6B /* SDL_thread.c */; };
        FAB598821BB5C31600BE72C5 /* SDL_systimer.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99BA310DD52EDC00FB1D6B /* SDL_systimer.c */; };
        FAB598831BB5C31600BE72C5 /* SDL_timer.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99BA2E0DD52EDC00FB1D6B /* SDL_timer.c */; };
        FAB598871BB5C31600BE72C5 /* SDL_uikitappdelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = FD689FCC0E26E9D400F90B21 /* SDL_uikitappdelegate.m */; };
        FAB598891BB5C31600BE72C5 /* SDL_uikitevents.m in Sources */ = {isa = PBXBuildFile; fileRef = FD689F0D0E26E5D900F90B21 /* SDL_uikitevents.m */; };
        FAB5988B1BB5C31600BE72C5 /* SDL_uikitmessagebox.m in Sources */ = {isa = PBXBuildFile; fileRef = AABCC3931640643D00AB8930 /* SDL_uikitmessagebox.m */; };
        FAB5988D1BB5C31600BE72C5 /* SDL_uikitmodes.m in Sources */ = {isa = PBXBuildFile; fileRef = AA126AD31617C5E6005ABC8F /* SDL_uikitmodes.m */; };
        FAB5988F1BB5C31600BE72C5 /* SDL_uikitopengles.m in Sources */ = {isa = PBXBuildFile; fileRef = FD689F0F0E26E5D900F90B21 /* SDL_uikitopengles.m */; };
        FAB598911BB5C31600BE72C5 /* SDL_uikitopenglview.m in Sources */ = {isa = PBXBuildFile; fileRef = FD689F170E26E5D900F90B21 /* SDL_uikitopenglview.m */; };
        FAB598931BB5C31600BE72C5 /* SDL_uikitvideo.m in Sources */ = {isa = PBXBuildFile; fileRef = FD689F110E26E5D900F90B21 /* SDL_uikitvideo.m */; };
        FAB598951BB5C31600BE72C5 /* SDL_uikitview.m in Sources */ = {isa = PBXBuildFile; fileRef = FD689F130E26E5D900F90B21 /* SDL_uikitview.m */; };
        FAB598971BB5C31600BE72C5 /* SDL_uikitviewcontroller.m in Sources */ = {isa = PBXBuildFile; fileRef = 93CB792513FC5F5300BD3E05 /* SDL_uikitviewcontroller.m */; };
        FAB598991BB5C31600BE72C5 /* SDL_uikitwindow.m in Sources */ = {isa = PBXBuildFile; fileRef = FD689F150E26E5D900F90B21 /* SDL_uikitwindow.m */; };
        FAB5989A1BB5C31600BE72C5 /* SDL_nullevents.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA685F50DF244C800F98A1A /* SDL_nullevents.c */; };
        FAB5989D1BB5C31600BE72C5 /* SDL_nullframebuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 04F7808312FB753F00FC43C0 /* SDL_nullframebuffer.c */; };
        FAB5989E1BB5C31600BE72C5 /* SDL_nullvideo.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA685F90DF244C800F98A1A /* SDL_nullvideo.c */; };
        FAB598A01BB5C31600BE72C5 /* SDL_blit.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA683000DF2374E00F98A1A /* SDL_blit.c */; };
        FAB598A21BB5C31600BE72C5 /* SDL_blit_0.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA683020DF2374E00F98A1A /* SDL_blit_0.c */; };
        FAB598A31BB5C31600BE72C5 /* SDL_blit_1.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA683030DF2374E00F98A1A /* SDL_blit_1.c */; };
        FAB598A41BB5C31600BE72C5 /* SDL_blit_A.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA683040DF2374E00F98A1A /* SDL_blit_A.c */; };
        FAB598A51BB5C31600BE72C5 /* SDL_blit_auto.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA683050DF2374E00F98A1A /* SDL_blit_auto.c */; };
        FAB598A71BB5C31600BE72C5 /* SDL_blit_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA683070DF2374E00F98A1A /* SDL_blit_copy.c */; };
        FAB598A91BB5C31600BE72C5 /* SDL_blit_N.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA683090DF2374E00F98A1A /* SDL_blit_N.c */; };
        FAB598AA1BB5C31600BE72C5 /* SDL_blit_slow.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA6830A0DF2374E00F98A1A /* SDL_blit_slow.c */; };
        FAB598AC1BB5C31600BE72C5 /* SDL_bmp.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA6830B0DF2374E00F98A1A /* SDL_bmp.c */; };
        FAB598AD1BB5C31600BE72C5 /* SDL_clipboard.c in Sources */ = {isa = PBXBuildFile; fileRef = 044E5FB711E606EB0076F181 /* SDL_clipboard.c */; };
        FAB598AE1BB5C31600BE72C5 /* SDL_fillrect.c in Sources */ = {isa = PBXBuildFile; fileRef = 0463873E0F0B5B7D0041FD65 /* SDL_fillrect.c */; };
        FAB598AF1BB5C31600BE72C5 /* SDL_pixels.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA6830F0DF2374E00F98A1A /* SDL_pixels.c */; };
        FAB598B11BB5C31600BE72C5 /* SDL_rect.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA683110DF2374E00F98A1A /* SDL_rect.c */; };
        FAB598B21BB5C31600BE72C5 /* SDL_RLEaccel.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA683150DF2374E00F98A1A /* SDL_RLEaccel.c */; };
        FAB598B41BB5C31600BE72C5 /* SDL_stretch.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA683170DF2374E00F98A1A /* SDL_stretch.c */; };
        FAB598B51BB5C31600BE72C5 /* SDL_surface.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA683190DF2374E00F98A1A /* SDL_surface.c */; };
        FAB598B71BB5C31600BE72C5 /* SDL_video.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA6831B0DF2374E00F98A1A /* SDL_video.c */; };
        FAB598B91BB5C31600BE72C5 /* SDL_assert.c in Sources */ = {isa = PBXBuildFile; fileRef = 04F2AF551104ABD200D6DDF7 /* SDL_assert.c */; };
        FAB598BC1BB5C31600BE72C5 /* SDL_error.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99B9D50DD52EDC00FB1D6B /* SDL_error.c */; };
        FAB598BD1BB5C31600BE72C5 /* SDL_hints.c in Sources */ = {isa = PBXBuildFile; fileRef = 0442EC5412FE1C3F004C9285 /* SDL_hints.c */; };
        FAB598BE1BB5C31600BE72C5 /* SDL_log.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BAC09B1300C1290055DE28 /* SDL_log.c */; };
        FAB598BF1BB5C31600BE72C5 /* SDL.c in Sources */ = {isa = PBXBuildFile; fileRef = FD99B9D80DD52EDC00FB1D6B /* SDL.c */; };
        FAD4F7021BA3C4E8008346CE /* SDL_sysjoystick_c.h in Headers */ = {isa = PBXBuildFile; fileRef = FAD4F7011BA3C4E8008346CE /* SDL_sysjoystick_c.h */; };
        FAFDF8C61D88D4530083E6F2 /* SDL_uikitclipboard.m in Sources */ = {isa = PBXBuildFile; fileRef = FA1DC2711C62BE65008F99A0 /* SDL_uikitclipboard.m */; };
        FD3F4A760DEA620800C5B771 /* SDL_getenv.c in Sources */ = {isa = PBXBuildFile; fileRef = FD3F4A700DEA620800C5B771 /* SDL_getenv.c */; };
        FD3F4A770DEA620800C5B771 /* SDL_iconv.c in Sources */ = {isa = PBXBuildFile; fileRef = FD3F4A710DEA620800C5B771 /* SDL_iconv.c */; };
        FD3F4A780DEA620800C5B771 /* SDL_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = FD3F4A720DEA620800C5B771 /* SDL_malloc.c */; };
@@ -271,7 +368,7 @@
        56A6703418565E760007D20F /* SDL_dynapi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_dynapi.h; path = ../../src/dynapi/SDL_dynapi.h; sourceTree = "<group>"; };
        56C181DE17C44D5E00406AE3 /* SDL_filesystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_filesystem.h; sourceTree = "<group>"; };
        56C181E117C44D7A00406AE3 /* SDL_sysfilesystem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDL_sysfilesystem.m; path = ../../src/filesystem/cocoa/SDL_sysfilesystem.m; sourceTree = "<group>"; };
        56EA86F913E9EC2B002E47EB /* SDL_coreaudio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_coreaudio.c; path = coreaudio/SDL_coreaudio.c; sourceTree = "<group>"; };
        56EA86F913E9EC2B002E47EB /* SDL_coreaudio.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDL_coreaudio.m; path = coreaudio/SDL_coreaudio.m; sourceTree = "<group>"; };
        56EA86FA13E9EC2B002E47EB /* SDL_coreaudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_coreaudio.h; path = coreaudio/SDL_coreaudio.h; sourceTree = "<group>"; };
        56ED04E0118A8EE200A56AA6 /* SDL_power.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_power.c; path = ../../src/power/SDL_power.c; sourceTree = SOURCE_ROOT; };
        56ED04E2118A8EFD00A56AA6 /* SDL_syspower.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDL_syspower.m; path = ../../src/power/uikit/SDL_syspower.m; sourceTree = SOURCE_ROOT; };
@@ -340,6 +437,9 @@
        AABCC3921640643D00AB8930 /* SDL_uikitmessagebox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_uikitmessagebox.h; sourceTree = "<group>"; };
        AABCC3931640643D00AB8930 /* SDL_uikitmessagebox.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_uikitmessagebox.m; sourceTree = "<group>"; };
        AADA5B8E16CCAB7C00107CF7 /* SDL_bits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_bits.h; sourceTree = "<group>"; };
        FA1DC2701C62BE65008F99A0 /* SDL_uikitclipboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_uikitclipboard.h; sourceTree = "<group>"; };
        FA1DC2711C62BE65008F99A0 /* SDL_uikitclipboard.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_uikitclipboard.m; sourceTree = "<group>"; };
        FAB598141BB5C1B100BE72C5 /* libSDL2.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSDL2.a; sourceTree = BUILT_PRODUCTS_DIR; };
        FAD4F7011BA3C4E8008346CE /* SDL_sysjoystick_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_sysjoystick_c.h; sourceTree = "<group>"; };
        FD0BBFEF0E3933DD00D833B1 /* SDL_uikitview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_uikitview.h; sourceTree = "<group>"; };
        FD3F4A700DEA620800C5B771 /* SDL_getenv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_getenv.c; sourceTree = "<group>"; };
@@ -372,7 +472,6 @@
        FD99B9440DD52EDC00FB1D6B /* SDL_audio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_audio.c; sourceTree = "<group>"; };
        FD99B9450DD52EDC00FB1D6B /* SDL_audio_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_audio_c.h; sourceTree = "<group>"; };
        FD99B9460DD52EDC00FB1D6B /* SDL_audiocvt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_audiocvt.c; sourceTree = "<group>"; };
        FD99B9490DD52EDC00FB1D6B /* SDL_audiomem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_audiomem.h; sourceTree = "<group>"; };
        FD99B94A0DD52EDC00FB1D6B /* SDL_audiotypecvt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_audiotypecvt.c; sourceTree = "<group>"; };
        FD99B94B0DD52EDC00FB1D6B /* SDL_mixer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_mixer.c; sourceTree = "<group>"; };
        FD99B9520DD52EDC00FB1D6B /* SDL_sysaudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_sysaudio.h; sourceTree = "<group>"; };
@@ -546,6 +645,7 @@
            isa = PBXGroup;
            children = (
                FD6526630DE8FCCB002AD96B /* libSDL2.a */,
                FAB598141BB5C1B100BE72C5 /* libSDL2.a */,
            );
            name = Products;
            sourceTree = "<group>";
@@ -583,7 +683,7 @@
        56EA86F813E9EBF9002E47EB /* coreaudio */ = {
            isa = PBXGroup;
            children = (
                56EA86F913E9EC2B002E47EB /* SDL_coreaudio.c */,
                56EA86F913E9EC2B002E47EB /* SDL_coreaudio.m */,
                56EA86FA13E9EC2B002E47EB /* SDL_coreaudio.h */,
            );
            name = coreaudio;
@@ -648,6 +748,8 @@
                FDC261780E3A3FC8001C4554 /* keyinfotable.h */,
                FD689FCD0E26E9D400F90B21 /* SDL_uikitappdelegate.h */,
                FD689FCC0E26E9D400F90B21 /* SDL_uikitappdelegate.m */,
                FA1DC2701C62BE65008F99A0 /* SDL_uikitclipboard.h */,
                FA1DC2711C62BE65008F99A0 /* SDL_uikitclipboard.m */,
                FD689F0C0E26E5D900F90B21 /* SDL_uikitevents.h */,
                FD689F0D0E26E5D900F90B21 /* SDL_uikitevents.m */,
                AABCC3921640643D00AB8930 /* SDL_uikitmessagebox.h */,
@@ -789,7 +891,6 @@
                FD99B9440DD52EDC00FB1D6B /* SDL_audio.c */,
                FD99B9450DD52EDC00FB1D6B /* SDL_audio_c.h */,
                FD99B9460DD52EDC00FB1D6B /* SDL_audiocvt.c */,
                FD99B9490DD52EDC00FB1D6B /* SDL_audiomem.h */,
                FD99B94A0DD52EDC00FB1D6B /* SDL_audiotypecvt.c */,
                FD99B94B0DD52EDC00FB1D6B /* SDL_mixer.c */,
                FD99B9520DD52EDC00FB1D6B /* SDL_sysaudio.h */,
@@ -994,6 +1095,7 @@
                04F7808012FB751400FC43C0 /* SDL_drawpoint.h in Headers */,
                04F7808412FB753F00FC43C0 /* SDL_nullframebuffer_c.h in Headers */,
                0442EC5012FE1C1E004C9285 /* SDL_render_sw_c.h in Headers */,
                FA1DC2721C62BE65008F99A0 /* SDL_uikitclipboard.h in Headers */,
                0402A85A12FE70C600CECEE3 /* SDL_shaders_gles2.h in Headers */,
                04BAC09C1300C1290055DE28 /* SDL_assert_c.h in Headers */,
                56EA86FC13E9EC2B002E47EB /* SDL_coreaudio.h in Headers */,
@@ -1064,6 +1166,21 @@
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
        FAB598131BB5C1B100BE72C5 /* libSDL-tv */ = {
            isa = PBXNativeTarget;
            buildConfigurationList = FAB5981A1BB5C1B100BE72C5 /* Build configuration list for PBXNativeTarget "libSDL-tv" */;
            buildPhases = (
                FAB598101BB5C1B100BE72C5 /* Sources */,
            );
            buildRules = (
            );
            dependencies = (
            );
            name = "libSDL-tv";
            productName = "libSDL-tv";
            productReference = FAB598141BB5C1B100BE72C5 /* libSDL2.a */;
            productType = "com.apple.product-type.library.static";
        };
        FD6526620DE8FCCB002AD96B /* libSDL */ = {
            isa = PBXNativeTarget;
            buildConfigurationList = FD6526990DE8FD14002AD96B /* Build configuration list for PBXNativeTarget "libSDL" */;
@@ -1086,7 +1203,12 @@
        29B97313FDCFA39411CA2CEA /* Project object */ = {
            isa = PBXProject;
            attributes = {
                LastUpgradeCheck = 0630;
                LastUpgradeCheck = 0800;
                TargetAttributes = {
                    FAB598131BB5C1B100BE72C5 = {
                        CreatedOnToolsVersion = 7.1;
                    };
                };
            };
            buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "SDL" */;
            compatibilityVersion = "Xcode 3.2";
@@ -1103,6 +1225,7 @@
            projectRoot = ../..;
            targets = (
                FD6526620DE8FCCB002AD96B /* libSDL */,
                FAB598131BB5C1B100BE72C5 /* libSDL-tv */,
                00B4F48B12F6A69C0084EC00 /* PrepareXcodeProjectTemplate */,
            );
        };
@@ -1126,6 +1249,108 @@
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
        FAB598101BB5C1B100BE72C5 /* Sources */ = {
            isa = PBXSourcesBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FAB5981D1BB5C31500BE72C5 /* SDL_atomic.c in Sources */,
                FAB5981E1BB5C31500BE72C5 /* SDL_spinlock.c in Sources */,
                FAB5981F1BB5C31500BE72C5 /* SDL_coreaudio.m in Sources */,
                FAB598211BB5C31500BE72C5 /* SDL_dummyaudio.c in Sources */,
                FAB598231BB5C31500BE72C5 /* SDL_audio.c in Sources */,
                FAB598251BB5C31500BE72C5 /* SDL_audiocvt.c in Sources */,
                FAB598271BB5C31500BE72C5 /* SDL_audiotypecvt.c in Sources */,
                FAB598281BB5C31500BE72C5 /* SDL_mixer.c in Sources */,
                FAB5982A1BB5C31500BE72C5 /* SDL_wave.c in Sources */,
                FAFDF8C61D88D4530083E6F2 /* SDL_uikitclipboard.m in Sources */,
                FAB5982C1BB5C31500BE72C5 /* SDL_cpuinfo.c in Sources */,
                FAB5982F1BB5C31500BE72C5 /* SDL_dynapi.c in Sources */,
                FAB598361BB5C31500BE72C5 /* SDL_clipboardevents.c in Sources */,
                FAB598381BB5C31500BE72C5 /* SDL_dropevents.c in Sources */,
                FAB5983A1BB5C31500BE72C5 /* SDL_events.c in Sources */,
                FAB5983C1BB5C31500BE72C5 /* SDL_gesture.c in Sources */,
                FAB5983E1BB5C31500BE72C5 /* SDL_keyboard.c in Sources */,
                FAB598401BB5C31500BE72C5 /* SDL_mouse.c in Sources */,
                FAB598421BB5C31500BE72C5 /* SDL_quit.c in Sources */,
                FAB598441BB5C31500BE72C5 /* SDL_touch.c in Sources */,
                FAB598461BB5C31500BE72C5 /* SDL_windowevents.c in Sources */,
                FAB598491BB5C31600BE72C5 /* SDL_rwopsbundlesupport.m in Sources */,
                FAB5984A1BB5C31600BE72C5 /* SDL_rwops.c in Sources */,
                FAB5984B1BB5C31600BE72C5 /* SDL_sysfilesystem.m in Sources */,
                FAB5984C1BB5C31600BE72C5 /* SDL_syshaptic.c in Sources */,
                FAB5984D1BB5C31600BE72C5 /* SDL_haptic.c in Sources */,
                FAB598501BB5C31600BE72C5 /* SDL_sysjoystick.m in Sources */,
                FAB598511BB5C31600BE72C5 /* SDL_gamecontroller.c in Sources */,
                FAB598521BB5C31600BE72C5 /* SDL_joystick.c in Sources */,
                FAB598551BB5C31600BE72C5 /* SDL_sysloadso.c in Sources */,
                FAB598561BB5C31600BE72C5 /* SDL_sysloadso.c in Sources */,
                FAB598571BB5C31600BE72C5 /* SDL_power.c in Sources */,
                FAB598581BB5C31600BE72C5 /* SDL_syspower.m in Sources */,
                FAB598591BB5C31600BE72C5 /* SDL_render_gles.c in Sources */,
                FAB5985A1BB5C31600BE72C5 /* SDL_render_gles2.c in Sources */,
                FAB5985B1BB5C31600BE72C5 /* SDL_shaders_gles2.c in Sources */,
                FAB5985D1BB5C31600BE72C5 /* SDL_blendfillrect.c in Sources */,
                FAB5985F1BB5C31600BE72C5 /* SDL_blendline.c in Sources */,
                FAB598611BB5C31600BE72C5 /* SDL_blendpoint.c in Sources */,
                FAB598641BB5C31600BE72C5 /* SDL_drawline.c in Sources */,
                FAB598661BB5C31600BE72C5 /* SDL_drawpoint.c in Sources */,
                FAB598681BB5C31600BE72C5 /* SDL_render_sw.c in Sources */,
                FAB5986A1BB5C31600BE72C5 /* SDL_rotate.c in Sources */,
                FAB5986D1BB5C31600BE72C5 /* SDL_render.c in Sources */,
                FAB5986F1BB5C31600BE72C5 /* SDL_yuv_mmx.c in Sources */,
                FAB598711BB5C31600BE72C5 /* SDL_yuv_sw.c in Sources */,
                FAB598721BB5C31600BE72C5 /* SDL_getenv.c in Sources */,
                FAB598731BB5C31600BE72C5 /* SDL_iconv.c in Sources */,
                FAB598741BB5C31600BE72C5 /* SDL_malloc.c in Sources */,
                FAB598751BB5C31600BE72C5 /* SDL_qsort.c in Sources */,
                FAB598761BB5C31600BE72C5 /* SDL_stdlib.c in Sources */,
                FAB598771BB5C31600BE72C5 /* SDL_string.c in Sources */,
                FAB598781BB5C31600BE72C5 /* SDL_syscond.c in Sources */,
                FAB598791BB5C31600BE72C5 /* SDL_sysmutex.c in Sources */,
                FAB5987B1BB5C31600BE72C5 /* SDL_syssem.c in Sources */,
                FAB5987C1BB5C31600BE72C5 /* SDL_systhread.c in Sources */,
                FAB5987E1BB5C31600BE72C5 /* SDL_systls.c in Sources */,
                FAB598801BB5C31600BE72C5 /* SDL_thread.c in Sources */,
                FAB598821BB5C31600BE72C5 /* SDL_systimer.c in Sources */,
                FAB598831BB5C31600BE72C5 /* SDL_timer.c in Sources */,
                FAB598871BB5C31600BE72C5 /* SDL_uikitappdelegate.m in Sources */,
                FAB598891BB5C31600BE72C5 /* SDL_uikitevents.m in Sources */,
                FAB5988B1BB5C31600BE72C5 /* SDL_uikitmessagebox.m in Sources */,
                FAB5988D1BB5C31600BE72C5 /* SDL_uikitmodes.m in Sources */,
                FAB5988F1BB5C31600BE72C5 /* SDL_uikitopengles.m in Sources */,
                FAB598911BB5C31600BE72C5 /* SDL_uikitopenglview.m in Sources */,
                FAB598931BB5C31600BE72C5 /* SDL_uikitvideo.m in Sources */,
                FAB598951BB5C31600BE72C5 /* SDL_uikitview.m in Sources */,
                FAB598971BB5C31600BE72C5 /* SDL_uikitviewcontroller.m in Sources */,
                FAB598991BB5C31600BE72C5 /* SDL_uikitwindow.m in Sources */,
                FAB5989A1BB5C31600BE72C5 /* SDL_nullevents.c in Sources */,
                FAB5989D1BB5C31600BE72C5 /* SDL_nullframebuffer.c in Sources */,
                FAB5989E1BB5C31600BE72C5 /* SDL_nullvideo.c in Sources */,
                FAB598A01BB5C31600BE72C5 /* SDL_blit.c in Sources */,
                FAB598A21BB5C31600BE72C5 /* SDL_blit_0.c in Sources */,
                FAB598A31BB5C31600BE72C5 /* SDL_blit_1.c in Sources */,
                FAB598A41BB5C31600BE72C5 /* SDL_blit_A.c in Sources */,
                FAB598A51BB5C31600BE72C5 /* SDL_blit_auto.c in Sources */,
                FAB598A71BB5C31600BE72C5 /* SDL_blit_copy.c in Sources */,
                FAB598A91BB5C31600BE72C5 /* SDL_blit_N.c in Sources */,
                FAB598AA1BB5C31600BE72C5 /* SDL_blit_slow.c in Sources */,
                FAB598AC1BB5C31600BE72C5 /* SDL_bmp.c in Sources */,
                FAB598AD1BB5C31600BE72C5 /* SDL_clipboard.c in Sources */,
                FAB598AE1BB5C31600BE72C5 /* SDL_fillrect.c in Sources */,
                FAB598AF1BB5C31600BE72C5 /* SDL_pixels.c in Sources */,
                FAB598B11BB5C31600BE72C5 /* SDL_rect.c in Sources */,
                FAB598B21BB5C31600BE72C5 /* SDL_RLEaccel.c in Sources */,
                FAB598B41BB5C31600BE72C5 /* SDL_stretch.c in Sources */,
                FAB598B51BB5C31600BE72C5 /* SDL_surface.c in Sources */,
                FAB598B71BB5C31600BE72C5 /* SDL_video.c in Sources */,
                FAB598B91BB5C31600BE72C5 /* SDL_assert.c in Sources */,
                FAB598BC1BB5C31600BE72C5 /* SDL_error.c in Sources */,
                FAB598BD1BB5C31600BE72C5 /* SDL_hints.c in Sources */,
                FAB598BE1BB5C31600BE72C5 /* SDL_log.c in Sources */,
                FAB598BF1BB5C31600BE72C5 /* SDL.c in Sources */,
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
        FD6526600DE8FCCB002AD96B /* Sources */ = {
            isa = PBXSourcesBuildPhase;
            buildActionMask = 2147483647;
@@ -1139,6 +1364,7 @@
                FD65266A0DE8FCDD002AD96B /* SDL_audiotypecvt.c in Sources */,
                FD65266B0DE8FCDD002AD96B /* SDL_mixer.c in Sources */,
                FD65266F0DE8FCDD002AD96B /* SDL_wave.c in Sources */,
                FA1DC2731C62BE65008F99A0 /* SDL_uikitclipboard.m in Sources */,
                FD6526700DE8FCDD002AD96B /* SDL_cpuinfo.c in Sources */,
                FD6526710DE8FCDD002AD96B /* SDL_events.c in Sources */,
                FD6526720DE8FCDD002AD96B /* SDL_keyboard.c in Sources */,
@@ -1215,7 +1441,7 @@
                0402A85812FE70C600CECEE3 /* SDL_render_gles2.c in Sources */,
                0402A85912FE70C600CECEE3 /* SDL_shaders_gles2.c in Sources */,
                04BAC09D1300C1290055DE28 /* SDL_log.c in Sources */,
                56EA86FB13E9EC2B002E47EB /* SDL_coreaudio.c in Sources */,
                56EA86FB13E9EC2B002E47EB /* SDL_coreaudio.m in Sources */,
                93CB792613FC5F5300BD3E05 /* SDL_uikitviewcontroller.m in Sources */,
                AA628ADB159369E3005138DD /* SDL_rotate.c in Sources */,
                AA126AD51617C5E7005ABC8F /* SDL_uikitmodes.m in Sources */,
@@ -1253,7 +1479,9 @@
        C01FCF4F08A954540054247B /* Debug */ = {
            isa = XCBuildConfiguration;
            buildSettings = {
                CLANG_ENABLE_OBJC_ARC = YES;
                "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
                ENABLE_TESTABILITY = YES;
                GCC_OPTIMIZATION_LEVEL = 0;
                GCC_SYMBOLS_PRIVATE_EXTERN = YES;
                GCC_WARN_ABOUT_RETURN_TYPE = YES;
@@ -1267,12 +1495,101 @@
        C01FCF5008A954540054247B /* Release */ = {
            isa = XCBuildConfiguration;
            buildSettings = {
                CLANG_ENABLE_OBJC_ARC = YES;
                "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
                GCC_SYMBOLS_PRIVATE_EXTERN = YES;
                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                IPHONEOS_DEPLOYMENT_TARGET = 5.1.1;
                SDKROOT = iphoneos;
                TARGETED_DEVICE_FAMILY = "1,2";
            };
            name = Release;
        };
        FAB5981B1BB5C1B100BE72C5 /* Debug */ = {
            isa = XCBuildConfiguration;
            buildSettings = {
                ALWAYS_SEARCH_USER_PATHS = NO;
                CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
                CLANG_CXX_LIBRARY = "libc++";
                CLANG_ENABLE_MODULES = YES;
                CLANG_ENABLE_OBJC_ARC = YES;
                CLANG_WARN_BOOL_CONVERSION = YES;
                CLANG_WARN_CONSTANT_CONVERSION = YES;
                CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
                CLANG_WARN_EMPTY_BODY = YES;
                CLANG_WARN_ENUM_CONVERSION = YES;
                CLANG_WARN_INFINITE_RECURSION = YES;
                CLANG_WARN_INT_CONVERSION = YES;
                CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
                CLANG_WARN_SUSPICIOUS_MOVE = YES;
                CLANG_WARN_UNREACHABLE_CODE = YES;
                CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
                COPY_PHASE_STRIP = NO;
                DEBUG_INFORMATION_FORMAT = dwarf;
                ENABLE_STRICT_OBJC_MSGSEND = YES;
                ENABLE_TESTABILITY = YES;
                GCC_C_LANGUAGE_STANDARD = gnu99;
                GCC_DYNAMIC_NO_PIC = NO;
                GCC_NO_COMMON_BLOCKS = YES;
                GCC_PREPROCESSOR_DEFINITIONS = (
                    "DEBUG=1",
                    "$(inherited)",
                );
                GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
                GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
                GCC_WARN_UNDECLARED_SELECTOR = YES;
                GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
                GCC_WARN_UNUSED_FUNCTION = YES;
                GCC_WARN_UNUSED_VARIABLE = YES;
                MTL_ENABLE_DEBUG_INFO = YES;
                OTHER_LDFLAGS = "-ObjC";
                PRODUCT_NAME = SDL2;
                SDKROOT = appletvos;
                SKIP_INSTALL = YES;
                TARGETED_DEVICE_FAMILY = 3;
                TVOS_DEPLOYMENT_TARGET = 9.0;
            };
            name = Debug;
        };
        FAB5981C1BB5C1B100BE72C5 /* Release */ = {
            isa = XCBuildConfiguration;
            buildSettings = {
                ALWAYS_SEARCH_USER_PATHS = NO;
                CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
                CLANG_CXX_LIBRARY = "libc++";
                CLANG_ENABLE_MODULES = YES;
                CLANG_ENABLE_OBJC_ARC = YES;
                CLANG_WARN_BOOL_CONVERSION = YES;
                CLANG_WARN_CONSTANT_CONVERSION = YES;
                CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
                CLANG_WARN_EMPTY_BODY = YES;
                CLANG_WARN_ENUM_CONVERSION = YES;
                CLANG_WARN_INFINITE_RECURSION = YES;
                CLANG_WARN_INT_CONVERSION = YES;
                CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
                CLANG_WARN_UNREACHABLE_CODE = YES;
                CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
                COPY_PHASE_STRIP = NO;
                DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
                ENABLE_NS_ASSERTIONS = NO;
                ENABLE_STRICT_OBJC_MSGSEND = YES;
                GCC_C_LANGUAGE_STANDARD = gnu99;
                GCC_NO_COMMON_BLOCKS = YES;
                GCC_SYMBOLS_PRIVATE_EXTERN = YES;
                GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
                GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
                GCC_WARN_UNDECLARED_SELECTOR = YES;
                GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
                GCC_WARN_UNUSED_FUNCTION = YES;
                GCC_WARN_UNUSED_VARIABLE = YES;
                MTL_ENABLE_DEBUG_INFO = NO;
                OTHER_LDFLAGS = "-ObjC";
                PRODUCT_NAME = SDL2;
                SDKROOT = appletvos;
                SKIP_INSTALL = YES;
                TARGETED_DEVICE_FAMILY = 3;
                TVOS_DEPLOYMENT_TARGET = 9.0;
                VALIDATE_PRODUCT = YES;
            };
            name = Release;
        };
@@ -1327,6 +1644,15 @@
            defaultConfigurationIsVisible = 0;
            defaultConfigurationName = Release;
        };
        FAB5981A1BB5C1B100BE72C5 /* Build configuration list for PBXNativeTarget "libSDL-tv" */ = {
            isa = XCConfigurationList;
            buildConfigurations = (
                FAB5981B1BB5C1B100BE72C5 /* Debug */,
                FAB5981C1BB5C1B100BE72C5 /* Release */,
            );
            defaultConfigurationIsVisible = 0;
            defaultConfigurationName = Release;
        };
        FD6526990DE8FD14002AD96B /* Build configuration list for PBXNativeTarget "libSDL" */ = {
            isa = XCConfigurationList;
            buildConfigurations = (
source/Xcode-iOS/SDLtest/SDL2test.xcodeproj/project.pbxproj
@@ -21,7 +21,33 @@
        AA1EE46D176059AB0029C7A5 /* SDL_test_log.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE45F176059AB0029C7A5 /* SDL_test_log.c */; };
        AA1EE46E176059AB0029C7A5 /* SDL_test_md5.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE460176059AB0029C7A5 /* SDL_test_md5.c */; };
        AA1EE46F176059AB0029C7A5 /* SDL_test_random.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE461176059AB0029C7A5 /* SDL_test_random.c */; };
        FA3D99011BC4E5BC002C96C8 /* SDL_test_common.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE454176059AB0029C7A5 /* SDL_test_common.c */; };
        FA3D99021BC4E5BC002C96C8 /* SDL_test_compare.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE455176059AB0029C7A5 /* SDL_test_compare.c */; };
        FA3D99031BC4E5BC002C96C8 /* SDL_test_crc32.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE456176059AB0029C7A5 /* SDL_test_crc32.c */; };
        FA3D99041BC4E5BC002C96C8 /* SDL_test_font.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE457176059AB0029C7A5 /* SDL_test_font.c */; };
        FA3D99051BC4E5BC002C96C8 /* SDL_test_fuzzer.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE458176059AB0029C7A5 /* SDL_test_fuzzer.c */; };
        FA3D99061BC4E5BC002C96C8 /* SDL_test_harness.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE459176059AB0029C7A5 /* SDL_test_harness.c */; };
        FA3D99071BC4E5BC002C96C8 /* SDL_test_imageBlit.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE45A176059AB0029C7A5 /* SDL_test_imageBlit.c */; };
        FA3D99081BC4E5BC002C96C8 /* SDL_test_imageBlitBlend.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE45B176059AB0029C7A5 /* SDL_test_imageBlitBlend.c */; };
        FA3D99091BC4E5BC002C96C8 /* SDL_test_imageFace.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE45C176059AB0029C7A5 /* SDL_test_imageFace.c */; };
        FA3D990A1BC4E5BC002C96C8 /* SDL_test_imagePrimitives.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE45D176059AB0029C7A5 /* SDL_test_imagePrimitives.c */; };
        FA3D990B1BC4E5BC002C96C8 /* SDL_test_imagePrimitivesBlend.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE45E176059AB0029C7A5 /* SDL_test_imagePrimitivesBlend.c */; };
        FA3D990C1BC4E5BC002C96C8 /* SDL_test_log.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE45F176059AB0029C7A5 /* SDL_test_log.c */; };
        FA3D990D1BC4E5BC002C96C8 /* SDL_test_md5.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE460176059AB0029C7A5 /* SDL_test_md5.c */; };
        FA3D990E1BC4E5BC002C96C8 /* SDL_test_random.c in Sources */ = {isa = PBXBuildFile; fileRef = AA1EE461176059AB0029C7A5 /* SDL_test_random.c */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
        FA3D98F61BC4E5A2002C96C8 /* CopyFiles */ = {
            isa = PBXCopyFilesBuildPhase;
            buildActionMask = 2147483647;
            dstPath = "include/$(PRODUCT_NAME)";
            dstSubfolderSpec = 16;
            files = (
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
        AA1EE4461760589B0029C7A5 /* libSDL2test.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSDL2test.a; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -39,10 +65,18 @@
        AA1EE45F176059AB0029C7A5 /* SDL_test_log.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_test_log.c; path = ../../src/test/SDL_test_log.c; sourceTree = "<group>"; };
        AA1EE460176059AB0029C7A5 /* SDL_test_md5.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_test_md5.c; path = ../../src/test/SDL_test_md5.c; sourceTree = "<group>"; };
        AA1EE461176059AB0029C7A5 /* SDL_test_random.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_test_random.c; path = ../../src/test/SDL_test_random.c; sourceTree = "<group>"; };
        FA3D98F81BC4E5A2002C96C8 /* libSDL2test-TV.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libSDL2test-TV.a"; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
        AA1EE4431760589B0029C7A5 /* Frameworks */ = {
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
        FA3D98F51BC4E5A2002C96C8 /* Frameworks */ = {
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
@@ -64,6 +98,7 @@
            isa = PBXGroup;
            children = (
                AA1EE4461760589B0029C7A5 /* libSDL2test.a */,
                FA3D98F81BC4E5A2002C96C8 /* libSDL2test-TV.a */,
            );
            name = Products;
            sourceTree = "<group>";
@@ -119,6 +154,23 @@
            productReference = AA1EE4461760589B0029C7A5 /* libSDL2test.a */;
            productType = "com.apple.product-type.library.static";
        };
        FA3D98F71BC4E5A2002C96C8 /* SDL2test-TV */ = {
            isa = PBXNativeTarget;
            buildConfigurationList = FA3D99001BC4E5A3002C96C8 /* Build configuration list for PBXNativeTarget "SDL2test-TV" */;
            buildPhases = (
                FA3D98F41BC4E5A2002C96C8 /* Sources */,
                FA3D98F51BC4E5A2002C96C8 /* Frameworks */,
                FA3D98F61BC4E5A2002C96C8 /* CopyFiles */,
            );
            buildRules = (
            );
            dependencies = (
            );
            name = "SDL2test-TV";
            productName = "SDL2test-TV";
            productReference = FA3D98F81BC4E5A2002C96C8 /* libSDL2test-TV.a */;
            productType = "com.apple.product-type.library.static";
        };
/* End PBXNativeTarget section */
/* Begin PBXProject section */
@@ -127,6 +179,11 @@
            attributes = {
                LastUpgradeCheck = 0460;
                ORGANIZATIONNAME = "Sam Lantinga";
                TargetAttributes = {
                    FA3D98F71BC4E5A2002C96C8 = {
                        CreatedOnToolsVersion = 7.1;
                    };
                };
            };
            buildConfigurationList = AA1EE4411760589B0029C7A5 /* Build configuration list for PBXProject "SDL2test" */;
            compatibilityVersion = "Xcode 3.2";
@@ -141,6 +198,7 @@
            projectRoot = "";
            targets = (
                AA1EE4451760589B0029C7A5 /* SDL2test */,
                FA3D98F71BC4E5A2002C96C8 /* SDL2test-TV */,
            );
        };
/* End PBXProject section */
@@ -164,6 +222,27 @@
                AA1EE46D176059AB0029C7A5 /* SDL_test_log.c in Sources */,
                AA1EE46E176059AB0029C7A5 /* SDL_test_md5.c in Sources */,
                AA1EE46F176059AB0029C7A5 /* SDL_test_random.c in Sources */,
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
        FA3D98F41BC4E5A2002C96C8 /* Sources */ = {
            isa = PBXSourcesBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FA3D99011BC4E5BC002C96C8 /* SDL_test_common.c in Sources */,
                FA3D99021BC4E5BC002C96C8 /* SDL_test_compare.c in Sources */,
                FA3D99031BC4E5BC002C96C8 /* SDL_test_crc32.c in Sources */,
                FA3D99041BC4E5BC002C96C8 /* SDL_test_font.c in Sources */,
                FA3D99051BC4E5BC002C96C8 /* SDL_test_fuzzer.c in Sources */,
                FA3D99061BC4E5BC002C96C8 /* SDL_test_harness.c in Sources */,
                FA3D99071BC4E5BC002C96C8 /* SDL_test_imageBlit.c in Sources */,
                FA3D99081BC4E5BC002C96C8 /* SDL_test_imageBlitBlend.c in Sources */,
                FA3D99091BC4E5BC002C96C8 /* SDL_test_imageFace.c in Sources */,
                FA3D990A1BC4E5BC002C96C8 /* SDL_test_imagePrimitives.c in Sources */,
                FA3D990B1BC4E5BC002C96C8 /* SDL_test_imagePrimitivesBlend.c in Sources */,
                FA3D990C1BC4E5BC002C96C8 /* SDL_test_log.c in Sources */,
                FA3D990D1BC4E5BC002C96C8 /* SDL_test_md5.c in Sources */,
                FA3D990E1BC4E5BC002C96C8 /* SDL_test_random.c in Sources */,
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
@@ -195,6 +274,7 @@
                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                GCC_WARN_UNINITIALIZED_AUTOS = YES;
                GCC_WARN_UNUSED_VARIABLE = YES;
                HEADER_SEARCH_PATHS = ../../include;
                MACOSX_DEPLOYMENT_TARGET = 10.8;
                ONLY_ACTIVE_ARCH = YES;
                SDKROOT = iphoneos;
@@ -220,6 +300,7 @@
                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                GCC_WARN_UNINITIALIZED_AUTOS = YES;
                GCC_WARN_UNUSED_VARIABLE = YES;
                HEADER_SEARCH_PATHS = ../../include;
                MACOSX_DEPLOYMENT_TARGET = 10.8;
                SDKROOT = iphoneos;
            };
@@ -229,7 +310,6 @@
            isa = XCBuildConfiguration;
            buildSettings = {
                EXECUTABLE_PREFIX = lib;
                HEADER_SEARCH_PATHS = ../../include;
                PRODUCT_NAME = "$(TARGET_NAME)";
            };
            name = Debug;
@@ -238,8 +318,60 @@
            isa = XCBuildConfiguration;
            buildSettings = {
                EXECUTABLE_PREFIX = lib;
                HEADER_SEARCH_PATHS = ../../include;
                PRODUCT_NAME = "$(TARGET_NAME)";
            };
            name = Release;
        };
        FA3D98FE1BC4E5A3002C96C8 /* Debug */ = {
            isa = XCBuildConfiguration;
            buildSettings = {
                CLANG_ENABLE_MODULES = YES;
                CLANG_ENABLE_OBJC_ARC = YES;
                CLANG_WARN_BOOL_CONVERSION = YES;
                CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
                CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
                CLANG_WARN_UNREACHABLE_CODE = YES;
                DEBUG_INFORMATION_FORMAT = dwarf;
                ENABLE_STRICT_OBJC_MSGSEND = YES;
                ENABLE_TESTABILITY = YES;
                GCC_NO_COMMON_BLOCKS = YES;
                GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
                GCC_WARN_UNDECLARED_SELECTOR = YES;
                GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
                GCC_WARN_UNUSED_FUNCTION = YES;
                MTL_ENABLE_DEBUG_INFO = YES;
                OTHER_LDFLAGS = "-ObjC";
                PRODUCT_NAME = "$(TARGET_NAME)";
                SDKROOT = appletvos;
                SKIP_INSTALL = YES;
                TVOS_DEPLOYMENT_TARGET = 9.0;
            };
            name = Debug;
        };
        FA3D98FF1BC4E5A3002C96C8 /* Release */ = {
            isa = XCBuildConfiguration;
            buildSettings = {
                CLANG_ENABLE_MODULES = YES;
                CLANG_ENABLE_OBJC_ARC = YES;
                CLANG_WARN_BOOL_CONVERSION = YES;
                CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
                CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
                CLANG_WARN_UNREACHABLE_CODE = YES;
                COPY_PHASE_STRIP = NO;
                ENABLE_NS_ASSERTIONS = NO;
                ENABLE_STRICT_OBJC_MSGSEND = YES;
                GCC_NO_COMMON_BLOCKS = YES;
                GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
                GCC_WARN_UNDECLARED_SELECTOR = YES;
                GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
                GCC_WARN_UNUSED_FUNCTION = YES;
                MTL_ENABLE_DEBUG_INFO = NO;
                OTHER_LDFLAGS = "-ObjC";
                PRODUCT_NAME = "$(TARGET_NAME)";
                SDKROOT = appletvos;
                SKIP_INSTALL = YES;
                TVOS_DEPLOYMENT_TARGET = 9.0;
                VALIDATE_PRODUCT = YES;
            };
            name = Release;
        };
@@ -264,6 +396,15 @@
            defaultConfigurationIsVisible = 0;
            defaultConfigurationName = Release;
        };
        FA3D99001BC4E5A3002C96C8 /* Build configuration list for PBXNativeTarget "SDL2test-TV" */ = {
            isa = XCConfigurationList;
            buildConfigurations = (
                FA3D98FE1BC4E5A3002C96C8 /* Debug */,
                FA3D98FF1BC4E5A3002C96C8 /* Release */,
            );
            defaultConfigurationIsVisible = 0;
            defaultConfigurationName = Release;
        };
/* End XCConfigurationList section */
    };
    rootObject = AA1EE43E1760589B0029C7A5 /* Project object */;
source/Xcode-iOS/Test/README
@@ -1,22 +1,11 @@
TestiPhoneOS.xcodeproj contains targets to compile many of the SDL test programs for iPhone OS.  Most of these test programs work fine, with the following exceptions:
testalpha:
    Program crashes.  Problem appears to effect Mac OS X as well.
testthread:
    SIGTERM kills the process immediately without executing the 'kill' function.  The posix standard says this shouldn't happen.  Apple seems intent on having iPhone apps exit promptly when the user requests it, so maybe that's why(?)
testlock:
    Locks appear to work, but there doesn't appear to be a simple way to send the process SIGINT.
testpalette:
    "SDL error: blitting boat: Blit combination not supported."  Happens on Mac OS X as well.
testsprite2: 
    SDL_CreateTextureFromSurface requests an ARGB pixel format, but iPhone's SDL video driver only supports ABGR.
testwin:
    Behaves as it does under Mac OS X ... not sure if that is correctly or not.
threadwin:
    Works if -threaded is not on.  Otherwise it doesn't work, but this is true under Mac OS X as well.
source/Xcode-iOS/Test/TestiPhoneOS.xcodeproj/project.pbxproj
@@ -65,7 +65,19 @@
        AAE7DFAC14CBB54E00DF1A0E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89D0E2D111A00EA573E /* Foundation.framework */; };
        AAE7DFAD14CBB54E00DF1A0E /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89E0E2D111A00EA573E /* CoreAudio.framework */; };
        AAE7DFB514CBB5F700DF1A0E /* testrendertarget.c in Sources */ = {isa = PBXBuildFile; fileRef = AAE7DFB414CBB5F700DF1A0E /* testrendertarget.c */; };
        FA0EF22E1BAF4654000E07A6 /* testjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA8A74E0E2D0F1600EA573E /* testjoystick.c */; settings = {ASSET_TAGS = (); }; };
        FA0EF22E1BAF4654000E07A6 /* testjoystick.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA8A74E0E2D0F1600EA573E /* testjoystick.c */; };
        FA3D99481BC4E6AD002C96C8 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA684F7A1BAF1A4400DCFD1A /* GameController.framework */; };
        FA3D994A1BC4E6AD002C96C8 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A8980E2D111A00EA573E /* AudioToolbox.framework */; };
        FA3D994B1BC4E6AD002C96C8 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A8990E2D111A00EA573E /* QuartzCore.framework */; };
        FA3D994C1BC4E6AD002C96C8 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89A0E2D111A00EA573E /* OpenGLES.framework */; };
        FA3D994D1BC4E6AD002C96C8 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89B0E2D111A00EA573E /* CoreGraphics.framework */; };
        FA3D994E1BC4E6AD002C96C8 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89C0E2D111A00EA573E /* UIKit.framework */; };
        FA3D994F1BC4E6AD002C96C8 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89D0E2D111A00EA573E /* Foundation.framework */; };
        FA3D99501BC4E6AD002C96C8 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89E0E2D111A00EA573E /* CoreAudio.framework */; };
        FA3D99521BC4E70C002C96C8 /* controllermap.bmp in Resources */ = {isa = PBXBuildFile; fileRef = FA0EF22A1BAF4487000E07A6 /* controllermap.bmp */; };
        FA3D99531BC4E70E002C96C8 /* axis.bmp in Resources */ = {isa = PBXBuildFile; fileRef = FA0EF2281BAF4487000E07A6 /* axis.bmp */; };
        FA3D99541BC4E70F002C96C8 /* button.bmp in Resources */ = {isa = PBXBuildFile; fileRef = FA0EF2291BAF4487000E07A6 /* button.bmp */; };
        FA3D99551BC4E712002C96C8 /* icon.bmp in Resources */ = {isa = PBXBuildFile; fileRef = FDA8AAD90E2D33B000EA573E /* icon.bmp */; };
        FA684F7B1BAF1A4400DCFD1A /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA684F7A1BAF1A4400DCFD1A /* GameController.framework */; };
        FA684F7F1BAF1A4D00DCFD1A /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA684F7A1BAF1A4400DCFD1A /* GameController.framework */; };
        FA684F801BAF1A5000DCFD1A /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA684F7A1BAF1A4400DCFD1A /* GameController.framework */; };
@@ -112,6 +124,59 @@
        FA8B4BDF196766F100F8EB7C /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA8B4BAC1967076F00F8EB7C /* CoreMotion.framework */; };
        FA8B4BE0196766F400F8EB7C /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA8B4BAC1967076F00F8EB7C /* CoreMotion.framework */; };
        FA8B4BE1196766F600F8EB7C /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA8B4BAC1967076F00F8EB7C /* CoreMotion.framework */; };
        FAA8CEE41BDF06D600D3BD45 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FA3D992B1BC4E619002C96C8 /* libSDL2.a */; };
        FABA34771D8B4EAD00915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34761D8B4EAD00915323 /* AVFoundation.framework */; };
        FABA34831D8B575200915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34761D8B4EAD00915323 /* AVFoundation.framework */; };
        FABA34841D8B575200915323 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD1B48B80E3131CA007AB34E /* libSDL2.a */; };
        FABA34851D8B575200915323 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA684F7A1BAF1A4400DCFD1A /* GameController.framework */; };
        FABA34861D8B575200915323 /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA8B4BAC1967076F00F8EB7C /* CoreMotion.framework */; };
        FABA34871D8B575200915323 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A8980E2D111A00EA573E /* AudioToolbox.framework */; };
        FABA34881D8B575200915323 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A8990E2D111A00EA573E /* QuartzCore.framework */; };
        FABA34891D8B575200915323 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89A0E2D111A00EA573E /* OpenGLES.framework */; };
        FABA348A1D8B575200915323 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89B0E2D111A00EA573E /* CoreGraphics.framework */; };
        FABA348B1D8B575200915323 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89C0E2D111A00EA573E /* UIKit.framework */; };
        FABA348C1D8B575200915323 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89D0E2D111A00EA573E /* Foundation.framework */; };
        FABA348D1D8B575200915323 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89E0E2D111A00EA573E /* CoreAudio.framework */; };
        FABA34941D8B578200915323 /* testaudiocapture.c in Sources */ = {isa = PBXBuildFile; fileRef = FABA34931D8B578200915323 /* testaudiocapture.c */; };
        FABA34951D8B578600915323 /* testaudiocapture.c in Sources */ = {isa = PBXBuildFile; fileRef = FABA34931D8B578200915323 /* testaudiocapture.c */; };
        FABA34981D8B582100915323 /* sample.wav in Resources */ = {isa = PBXBuildFile; fileRef = FDA8AAE20E2D33C600EA573E /* sample.wav */; };
        FABA349A1D8B582100915323 /* loopwave.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA8A78B0E2D0F3D00EA573E /* loopwave.c */; };
        FABA349C1D8B582100915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34761D8B4EAD00915323 /* AVFoundation.framework */; };
        FABA349D1D8B582100915323 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD1B48B80E3131CA007AB34E /* libSDL2.a */; };
        FABA349E1D8B582100915323 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA684F7A1BAF1A4400DCFD1A /* GameController.framework */; };
        FABA349F1D8B582100915323 /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA8B4BAC1967076F00F8EB7C /* CoreMotion.framework */; };
        FABA34A01D8B582100915323 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A8980E2D111A00EA573E /* AudioToolbox.framework */; };
        FABA34A11D8B582100915323 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A8990E2D111A00EA573E /* QuartzCore.framework */; };
        FABA34A21D8B582100915323 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89A0E2D111A00EA573E /* OpenGLES.framework */; };
        FABA34A31D8B582100915323 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89B0E2D111A00EA573E /* CoreGraphics.framework */; };
        FABA34A41D8B582100915323 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89C0E2D111A00EA573E /* UIKit.framework */; };
        FABA34A51D8B582100915323 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89D0E2D111A00EA573E /* Foundation.framework */; };
        FABA34A61D8B582100915323 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89E0E2D111A00EA573E /* CoreAudio.framework */; };
        FABA34AD1D8B58A700915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34AC1D8B58A700915323 /* AVFoundation.framework */; };
        FABA34AE1D8B58B200915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34761D8B4EAD00915323 /* AVFoundation.framework */; };
        FABA34AF1D8B59F800915323 /* testaudiocapture.c in Sources */ = {isa = PBXBuildFile; fileRef = FABA34931D8B578200915323 /* testaudiocapture.c */; };
        FABA34B01D8B5B6400915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34761D8B4EAD00915323 /* AVFoundation.framework */; };
        FABA34B11D8B5B6C00915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34761D8B4EAD00915323 /* AVFoundation.framework */; };
        FABA34B21D8B5B7300915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34761D8B4EAD00915323 /* AVFoundation.framework */; };
        FABA34B31D8B5B7800915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34761D8B4EAD00915323 /* AVFoundation.framework */; };
        FABA34B41D8B5B7C00915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34761D8B4EAD00915323 /* AVFoundation.framework */; };
        FABA34B51D8B5B8400915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34761D8B4EAD00915323 /* AVFoundation.framework */; };
        FABA34B61D8B5B8900915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34761D8B4EAD00915323 /* AVFoundation.framework */; };
        FABA34B71D8B5B8D00915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34761D8B4EAD00915323 /* AVFoundation.framework */; };
        FABA34B81D8B5B9200915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34761D8B4EAD00915323 /* AVFoundation.framework */; };
        FABA34B91D8B5B9600915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34761D8B4EAD00915323 /* AVFoundation.framework */; };
        FABA34BA1D8B5B9B00915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34761D8B4EAD00915323 /* AVFoundation.framework */; };
        FABA34BB1D8B5BA100915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34761D8B4EAD00915323 /* AVFoundation.framework */; };
        FABA34BC1D8B5BA600915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34761D8B4EAD00915323 /* AVFoundation.framework */; };
        FABA34BD1D8B5BAB00915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34761D8B4EAD00915323 /* AVFoundation.framework */; };
        FABA34BE1D8B5BB000915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34761D8B4EAD00915323 /* AVFoundation.framework */; };
        FABA34BF1D8B5BB500915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34761D8B4EAD00915323 /* AVFoundation.framework */; };
        FABA34C01D8B5BBA00915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34761D8B4EAD00915323 /* AVFoundation.framework */; };
        FABA34C11D8B5BBE00915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34761D8B4EAD00915323 /* AVFoundation.framework */; };
        FABA34C21D8B5BC200915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34761D8B4EAD00915323 /* AVFoundation.framework */; };
        FABA34C31D8B5BC600915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34761D8B4EAD00915323 /* AVFoundation.framework */; };
        FABA34C41D8B5BCB00915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34761D8B4EAD00915323 /* AVFoundation.framework */; };
        FABA34C51D8B5BD000915323 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABA34761D8B4EAD00915323 /* AVFoundation.framework */; };
        FAE0E9821BAF9B230098DFA4 /* icon.bmp in Resources */ = {isa = PBXBuildFile; fileRef = FDA8AAD90E2D33B000EA573E /* icon.bmp */; };
        FAE0E9861BAF9B230098DFA4 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD1B48B80E3131CA007AB34E /* libSDL2.a */; };
        FAE0E9871BAF9B230098DFA4 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA684F7A1BAF1A4400DCFD1A /* GameController.framework */; };
@@ -123,10 +188,10 @@
        FAE0E98D1BAF9B230098DFA4 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89C0E2D111A00EA573E /* UIKit.framework */; };
        FAE0E98E1BAF9B230098DFA4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89D0E2D111A00EA573E /* Foundation.framework */; };
        FAE0E98F1BAF9B230098DFA4 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89E0E2D111A00EA573E /* CoreAudio.framework */; };
        FAE0E9951BAF9B510098DFA4 /* testgamecontroller.c in Sources */ = {isa = PBXBuildFile; fileRef = FA0EF2221BAF43DE000E07A6 /* testgamecontroller.c */; settings = {ASSET_TAGS = (); }; };
        FAE0E9961BAF9B650098DFA4 /* controllermap.bmp in Resources */ = {isa = PBXBuildFile; fileRef = FA0EF22A1BAF4487000E07A6 /* controllermap.bmp */; settings = {ASSET_TAGS = (); }; };
        FAE0E9971BAF9B6A0098DFA4 /* button.bmp in Resources */ = {isa = PBXBuildFile; fileRef = FA0EF2291BAF4487000E07A6 /* button.bmp */; settings = {ASSET_TAGS = (); }; };
        FAE0E9981BAF9B6E0098DFA4 /* axis.bmp in Resources */ = {isa = PBXBuildFile; fileRef = FA0EF2281BAF4487000E07A6 /* axis.bmp */; settings = {ASSET_TAGS = (); }; };
        FAE0E9951BAF9B510098DFA4 /* testgamecontroller.c in Sources */ = {isa = PBXBuildFile; fileRef = FA0EF2221BAF43DE000E07A6 /* testgamecontroller.c */; };
        FAE0E9961BAF9B650098DFA4 /* controllermap.bmp in Resources */ = {isa = PBXBuildFile; fileRef = FA0EF22A1BAF4487000E07A6 /* controllermap.bmp */; };
        FAE0E9971BAF9B6A0098DFA4 /* button.bmp in Resources */ = {isa = PBXBuildFile; fileRef = FA0EF2291BAF4487000E07A6 /* button.bmp */; };
        FAE0E9981BAF9B6E0098DFA4 /* axis.bmp in Resources */ = {isa = PBXBuildFile; fileRef = FA0EF2281BAF4487000E07A6 /* axis.bmp */; };
        FDA8A79C0E2D0F9300EA573E /* testwm2.c in Sources */ = {isa = PBXBuildFile; fileRef = FDA8A75F0E2D0F1600EA573E /* testwm2.c */; };
        FDA8A89F0E2D111A00EA573E /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A8980E2D111A00EA573E /* AudioToolbox.framework */; };
        FDA8A8A00E2D111A00EA573E /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A8990E2D111A00EA573E /* QuartzCore.framework */; };
@@ -304,6 +369,27 @@
            remoteGlobalIDString = AA1EE4461760589B0029C7A5;
            remoteInfo = SDL2test;
        };
        FA3D992A1BC4E619002C96C8 /* PBXContainerItemProxy */ = {
            isa = PBXContainerItemProxy;
            containerPortal = FD1B48AC0E3131CA007AB34E /* SDL.xcodeproj */;
            proxyType = 2;
            remoteGlobalIDString = FAB598141BB5C1B100BE72C5;
            remoteInfo = "libSDL-tv";
        };
        FA3D992E1BC4E619002C96C8 /* PBXContainerItemProxy */ = {
            isa = PBXContainerItemProxy;
            containerPortal = AA1EE44D176059220029C7A5 /* SDL2test.xcodeproj */;
            proxyType = 2;
            remoteGlobalIDString = FA3D98F81BC4E5A2002C96C8;
            remoteInfo = "SDL2test-TV";
        };
        FAA8CEE51BDF06DC00D3BD45 /* PBXContainerItemProxy */ = {
            isa = PBXContainerItemProxy;
            containerPortal = FD1B48AC0E3131CA007AB34E /* SDL.xcodeproj */;
            proxyType = 1;
            remoteGlobalIDString = FAB598131BB5C1B100BE72C5;
            remoteInfo = "libSDL-tv";
        };
        FD1B48B70E3131CA007AB34E /* PBXContainerItemProxy */ = {
            isa = PBXContainerItemProxy;
            containerPortal = FD1B48AC0E3131CA007AB34E /* SDL.xcodeproj */;
@@ -330,8 +416,14 @@
        FA0EF2281BAF4487000E07A6 /* axis.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; name = axis.bmp; path = ../../test/axis.bmp; sourceTree = "<group>"; };
        FA0EF2291BAF4487000E07A6 /* button.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; name = button.bmp; path = ../../test/button.bmp; sourceTree = "<group>"; };
        FA0EF22A1BAF4487000E07A6 /* controllermap.bmp */ = {isa = PBXFileReference; lastKnownFileType = image.bmp; name = controllermap.bmp; path = ../../test/controllermap.bmp; sourceTree = "<group>"; };
        FA3D99341BC4E644002C96C8 /* testgamecontroller-TV.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "testgamecontroller-TV.app"; sourceTree = BUILT_PRODUCTS_DIR; };
        FA684F7A1BAF1A4400DCFD1A /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = System/Library/Frameworks/GameController.framework; sourceTree = SDKROOT; };
        FA8B4BAC1967076F00F8EB7C /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = System/Library/Frameworks/CoreMotion.framework; sourceTree = SDKROOT; };
        FABA34761D8B4EAD00915323 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
        FABA34911D8B575200915323 /* testaudiocapture.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testaudiocapture.app; sourceTree = BUILT_PRODUCTS_DIR; };
        FABA34931D8B578200915323 /* testaudiocapture.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = testaudiocapture.c; path = ../../test/testaudiocapture.c; sourceTree = "<group>"; };
        FABA34AA1D8B582100915323 /* loopwav-TV.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "loopwav-TV.app"; sourceTree = BUILT_PRODUCTS_DIR; };
        FABA34AC1D8B58A700915323 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS10.0.sdk/System/Library/Frameworks/AVFoundation.framework; sourceTree = DEVELOPER_DIR; };
        FAE0E9931BAF9B230098DFA4 /* testgamecontroller.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testgamecontroller.app; sourceTree = BUILT_PRODUCTS_DIR; };
        FD1B48AC0E3131CA007AB34E /* SDL.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SDL.xcodeproj; path = ../SDL/SDL.xcodeproj; sourceTree = SOURCE_ROOT; };
        FDA8A7410E2D0F1600EA573E /* testaudioinfo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = testaudioinfo.c; path = ../../test/testaudioinfo.c; sourceTree = SOURCE_ROOT; };
@@ -390,6 +482,7 @@
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34B51D8B5B8400915323 /* AVFoundation.framework in Frameworks */,
                046CEF7B13254F23007AD51D /* libSDL2.a in Frameworks */,
                FA684F841BAF1A5C00DCFD1A /* GameController.framework in Frameworks */,
                FA8B4BD1196766C900F8EB7C /* CoreMotion.framework in Frameworks */,
@@ -407,6 +500,7 @@
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34B01D8B5B6400915323 /* AVFoundation.framework in Frameworks */,
                AA1EE470176059D00029C7A5 /* libSDL2test.a in Frameworks */,
                047A63E213285C3200CD7973 /* libSDL2.a in Frameworks */,
                FA684F7B1BAF1A4400DCFD1A /* GameController.framework in Frameworks */,
@@ -425,6 +519,7 @@
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34C41D8B5BCB00915323 /* AVFoundation.framework in Frameworks */,
                AA1EE47817605BF60029C7A5 /* libSDL2test.a in Frameworks */,
                FDBDE5810E313465006BAC0B /* libSDL2.a in Frameworks */,
                FA684F931BAF1A8A00DCFD1A /* GameController.framework in Frameworks */,
@@ -443,6 +538,7 @@
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34BC1D8B5BA600915323 /* AVFoundation.framework in Frameworks */,
                56ED0502118A8FE400A56AA6 /* libSDL2.a in Frameworks */,
                FA684F8B1BAF1A7100DCFD1A /* GameController.framework in Frameworks */,
                FA8B4BD8196766DD00F8EB7C /* CoreMotion.framework in Frameworks */,
@@ -460,6 +556,7 @@
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34BE1D8B5BB000915323 /* AVFoundation.framework in Frameworks */,
                AA1EE47617605B9E0029C7A5 /* libSDL2test.a in Frameworks */,
                AAE7DEE114CBB1E100DF1A0E /* libSDL2.a in Frameworks */,
                FA684F8D1BAF1A7800DCFD1A /* GameController.framework in Frameworks */,
@@ -478,6 +575,7 @@
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34BD1D8B5BAB00915323 /* AVFoundation.framework in Frameworks */,
                AA1EE47517605B930029C7A5 /* libSDL2test.a in Frameworks */,
                AAE7DFA614CBB54E00DF1A0E /* libSDL2.a in Frameworks */,
                FA684F8C1BAF1A7400DCFD1A /* GameController.framework in Frameworks */,
@@ -492,10 +590,64 @@
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
        FA3D99311BC4E644002C96C8 /* Frameworks */ = {
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34AD1D8B58A700915323 /* AVFoundation.framework in Frameworks */,
                FAA8CEE41BDF06D600D3BD45 /* libSDL2.a in Frameworks */,
                FA3D99481BC4E6AD002C96C8 /* GameController.framework in Frameworks */,
                FA3D994A1BC4E6AD002C96C8 /* AudioToolbox.framework in Frameworks */,
                FA3D994B1BC4E6AD002C96C8 /* QuartzCore.framework in Frameworks */,
                FA3D994C1BC4E6AD002C96C8 /* OpenGLES.framework in Frameworks */,
                FA3D994D1BC4E6AD002C96C8 /* CoreGraphics.framework in Frameworks */,
                FA3D994E1BC4E6AD002C96C8 /* UIKit.framework in Frameworks */,
                FA3D994F1BC4E6AD002C96C8 /* Foundation.framework in Frameworks */,
                FA3D99501BC4E6AD002C96C8 /* CoreAudio.framework in Frameworks */,
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
        FABA34821D8B575200915323 /* Frameworks */ = {
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34831D8B575200915323 /* AVFoundation.framework in Frameworks */,
                FABA34841D8B575200915323 /* libSDL2.a in Frameworks */,
                FABA34851D8B575200915323 /* GameController.framework in Frameworks */,
                FABA34861D8B575200915323 /* CoreMotion.framework in Frameworks */,
                FABA34871D8B575200915323 /* AudioToolbox.framework in Frameworks */,
                FABA34881D8B575200915323 /* QuartzCore.framework in Frameworks */,
                FABA34891D8B575200915323 /* OpenGLES.framework in Frameworks */,
                FABA348A1D8B575200915323 /* CoreGraphics.framework in Frameworks */,
                FABA348B1D8B575200915323 /* UIKit.framework in Frameworks */,
                FABA348C1D8B575200915323 /* Foundation.framework in Frameworks */,
                FABA348D1D8B575200915323 /* CoreAudio.framework in Frameworks */,
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
        FABA349B1D8B582100915323 /* Frameworks */ = {
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA349C1D8B582100915323 /* AVFoundation.framework in Frameworks */,
                FABA349D1D8B582100915323 /* libSDL2.a in Frameworks */,
                FABA349E1D8B582100915323 /* GameController.framework in Frameworks */,
                FABA349F1D8B582100915323 /* CoreMotion.framework in Frameworks */,
                FABA34A01D8B582100915323 /* AudioToolbox.framework in Frameworks */,
                FABA34A11D8B582100915323 /* QuartzCore.framework in Frameworks */,
                FABA34A21D8B582100915323 /* OpenGLES.framework in Frameworks */,
                FABA34A31D8B582100915323 /* CoreGraphics.framework in Frameworks */,
                FABA34A41D8B582100915323 /* UIKit.framework in Frameworks */,
                FABA34A51D8B582100915323 /* Foundation.framework in Frameworks */,
                FABA34A61D8B582100915323 /* CoreAudio.framework in Frameworks */,
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
        FAE0E9851BAF9B230098DFA4 /* Frameworks */ = {
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34AE1D8B58B200915323 /* AVFoundation.framework in Frameworks */,
                FAE0E9861BAF9B230098DFA4 /* libSDL2.a in Frameworks */,
                FAE0E9871BAF9B230098DFA4 /* GameController.framework in Frameworks */,
                FAE0E9881BAF9B230098DFA4 /* CoreMotion.framework in Frameworks */,
@@ -513,6 +665,7 @@
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34771D8B4EAD00915323 /* AVFoundation.framework in Frameworks */,
                FDBDE5850E313495006BAC0B /* libSDL2.a in Frameworks */,
                FA684F7F1BAF1A4D00DCFD1A /* GameController.framework in Frameworks */,
                FA8B4BC9196766BC00F8EB7C /* CoreMotion.framework in Frameworks */,
@@ -530,6 +683,7 @@
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34B11D8B5B6C00915323 /* AVFoundation.framework in Frameworks */,
                FDBDE58C0E3134F3006BAC0B /* libSDL2.a in Frameworks */,
                FA684F801BAF1A5000DCFD1A /* GameController.framework in Frameworks */,
                FA8B4BCD196766BF00F8EB7C /* CoreMotion.framework in Frameworks */,
@@ -547,6 +701,7 @@
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34B31D8B5B7800915323 /* AVFoundation.framework in Frameworks */,
                FDBDE59B0E31356A006BAC0B /* libSDL2.a in Frameworks */,
                FA684F821BAF1A5700DCFD1A /* GameController.framework in Frameworks */,
                FA8B4BCF196766C400F8EB7C /* CoreMotion.framework in Frameworks */,
@@ -564,6 +719,7 @@
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34B41D8B5B7C00915323 /* AVFoundation.framework in Frameworks */,
                FDBDE59F0E31358D006BAC0B /* libSDL2.a in Frameworks */,
                FA684F831BAF1A5A00DCFD1A /* GameController.framework in Frameworks */,
                FA8B4BD0196766C600F8EB7C /* CoreMotion.framework in Frameworks */,
@@ -581,6 +737,7 @@
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34B61D8B5B8900915323 /* AVFoundation.framework in Frameworks */,
                AA1EE47417605B5C0029C7A5 /* libSDL2test.a in Frameworks */,
                FDBDE57C0E313445006BAC0B /* libSDL2.a in Frameworks */,
                FA684F851BAF1A6000DCFD1A /* GameController.framework in Frameworks */,
@@ -599,6 +756,7 @@
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34B21D8B5B7300915323 /* AVFoundation.framework in Frameworks */,
                AA1EE47117605A7F0029C7A5 /* libSDL2test.a in Frameworks */,
                FDC42FF40F0D866D009C87E1 /* libSDL2.a in Frameworks */,
                FA684F811BAF1A5300DCFD1A /* GameController.framework in Frameworks */,
@@ -617,6 +775,7 @@
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34C11D8B5BBE00915323 /* AVFoundation.framework in Frameworks */,
                FDBDE5A90E3135C0006BAC0B /* libSDL2.a in Frameworks */,
                FA684F901BAF1A8100DCFD1A /* GameController.framework in Frameworks */,
                FA8B4BDD196766EB00F8EB7C /* CoreMotion.framework in Frameworks */,
@@ -634,6 +793,7 @@
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34B71D8B5B8D00915323 /* AVFoundation.framework in Frameworks */,
                FDBDE5AE0E3135E6006BAC0B /* libSDL2.a in Frameworks */,
                FA684F861BAF1A6200DCFD1A /* GameController.framework in Frameworks */,
                FA8B4BD3196766CE00F8EB7C /* CoreMotion.framework in Frameworks */,
@@ -651,6 +811,7 @@
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34B81D8B5B9200915323 /* AVFoundation.framework in Frameworks */,
                FDBDE5B60E3135FE006BAC0B /* libSDL2.a in Frameworks */,
                FA684F871BAF1A6500DCFD1A /* GameController.framework in Frameworks */,
                FA8B4BD4196766D100F8EB7C /* CoreMotion.framework in Frameworks */,
@@ -668,6 +829,7 @@
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34B91D8B5B9600915323 /* AVFoundation.framework in Frameworks */,
                FDBDE5BC0E31364D006BAC0B /* libSDL2.a in Frameworks */,
                FA684F881BAF1A6800DCFD1A /* GameController.framework in Frameworks */,
                FA8B4BD5196766D400F8EB7C /* CoreMotion.framework in Frameworks */,
@@ -685,6 +847,7 @@
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34BA1D8B5B9B00915323 /* AVFoundation.framework in Frameworks */,
                FDBDE5C20E313663006BAC0B /* libSDL2.a in Frameworks */,
                FA684F891BAF1A6A00DCFD1A /* GameController.framework in Frameworks */,
                FA8B4BD6196766D700F8EB7C /* CoreMotion.framework in Frameworks */,
@@ -702,6 +865,7 @@
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34BB1D8B5BA100915323 /* AVFoundation.framework in Frameworks */,
                FDBDE5C60E3136F1006BAC0B /* libSDL2.a in Frameworks */,
                FA684F8A1BAF1A6D00DCFD1A /* GameController.framework in Frameworks */,
                FA8B4BD7196766DA00F8EB7C /* CoreMotion.framework in Frameworks */,
@@ -719,6 +883,7 @@
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34BF1D8B5BB500915323 /* AVFoundation.framework in Frameworks */,
                FDBDE5C80E313702006BAC0B /* libSDL2.a in Frameworks */,
                FA684F8E1BAF1A7B00DCFD1A /* GameController.framework in Frameworks */,
                FA8B4BDB196766E500F8EB7C /* CoreMotion.framework in Frameworks */,
@@ -736,6 +901,7 @@
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34C01D8B5BBA00915323 /* AVFoundation.framework in Frameworks */,
                AA1EE47717605BAB0029C7A5 /* libSDL2test.a in Frameworks */,
                FDBDE5CA0E313712006BAC0B /* libSDL2.a in Frameworks */,
                FA684F8F1BAF1A7E00DCFD1A /* GameController.framework in Frameworks */,
@@ -754,6 +920,7 @@
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34C21D8B5BC200915323 /* AVFoundation.framework in Frameworks */,
                FDBDE5CC0E31372B006BAC0B /* libSDL2.a in Frameworks */,
                FA684F911BAF1A8400DCFD1A /* GameController.framework in Frameworks */,
                FA8B4BDE196766EE00F8EB7C /* CoreMotion.framework in Frameworks */,
@@ -771,6 +938,7 @@
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34C31D8B5BC600915323 /* AVFoundation.framework in Frameworks */,
                FDBDE5CE0E31373E006BAC0B /* libSDL2.a in Frameworks */,
                FA684F921BAF1A8700DCFD1A /* GameController.framework in Frameworks */,
                FA8B4BDF196766F100F8EB7C /* CoreMotion.framework in Frameworks */,
@@ -788,6 +956,7 @@
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34C51D8B5BD000915323 /* AVFoundation.framework in Frameworks */,
                FDBDE5D40E313789006BAC0B /* libSDL2.a in Frameworks */,
                FA684F941BAF1A9400DCFD1A /* GameController.framework in Frameworks */,
                FA8B4BE1196766F600F8EB7C /* CoreMotion.framework in Frameworks */,
@@ -831,6 +1000,9 @@
                AAE7DEEC14CBB1E100DF1A0E /* testscale.app */,
                AAE7DFB114CBB54E00DF1A0E /* testrendertarget.app */,
                FAE0E9931BAF9B230098DFA4 /* testgamecontroller.app */,
                FA3D99341BC4E644002C96C8 /* testgamecontroller-TV.app */,
                FABA34911D8B575200915323 /* testaudiocapture.app */,
                FABA34AA1D8B582100915323 /* loopwav-TV.app */,
            );
            name = Products;
            sourceTree = "<group>";
@@ -844,6 +1016,7 @@
                FDA8A7C30E2D10FA00EA573E /* Linked Frameworks */,
                FDA8A73B0E2D0F0400EA573E /* src */,
                19C28FACFE9D520D11CA2CBB /* Products */,
                FABA34751D8B4EAC00915323 /* Frameworks */,
            );
            name = CustomTemplate;
            sourceTree = "<group>";
@@ -852,14 +1025,25 @@
            isa = PBXGroup;
            children = (
                AA1EE452176059230029C7A5 /* libSDL2test.a */,
                FA3D992F1BC4E619002C96C8 /* libSDL2test-TV.a */,
            );
            name = Products;
            sourceTree = "<group>";
        };
        FABA34751D8B4EAC00915323 /* Frameworks */ = {
            isa = PBXGroup;
            children = (
                FABA34AC1D8B58A700915323 /* AVFoundation.framework */,
                FABA34761D8B4EAD00915323 /* AVFoundation.framework */,
            );
            name = Frameworks;
            sourceTree = "<group>";
        };
        FD1B48AD0E3131CA007AB34E /* Products */ = {
            isa = PBXGroup;
            children = (
                FD1B48B80E3131CA007AB34E /* libSDL2.a */,
                FA3D992B1BC4E619002C96C8 /* libSDL2.a */,
            );
            name = Products;
            sourceTree = "<group>";
@@ -867,6 +1051,7 @@
        FDA8A73B0E2D0F0400EA573E /* src */ = {
            isa = PBXGroup;
            children = (
                FABA34931D8B578200915323 /* testaudiocapture.c */,
                047A63F013285CD100CD7973 /* checkkeys.c */,
                FDA8A78B0E2D0F3D00EA573E /* loopwave.c */,
                FDA8A7410E2D0F1600EA573E /* testaudioinfo.c */,
@@ -1031,6 +1216,58 @@
            name = testrendertarget;
            productName = Test;
            productReference = AAE7DFB114CBB54E00DF1A0E /* testrendertarget.app */;
            productType = "com.apple.product-type.application";
        };
        FA3D99331BC4E644002C96C8 /* testgamecontroller-TV */ = {
            isa = PBXNativeTarget;
            buildConfigurationList = FA3D99451BC4E645002C96C8 /* Build configuration list for PBXNativeTarget "testgamecontroller-TV" */;
            buildPhases = (
                FA3D99301BC4E644002C96C8 /* Sources */,
                FA3D99311BC4E644002C96C8 /* Frameworks */,
                FA3D99321BC4E644002C96C8 /* Resources */,
            );
            buildRules = (
            );
            dependencies = (
                FAA8CEE61BDF06DC00D3BD45 /* PBXTargetDependency */,
            );
            name = "testgamecontroller-TV";
            productName = "testgamecontroller-TV";
            productReference = FA3D99341BC4E644002C96C8 /* testgamecontroller-TV.app */;
            productType = "com.apple.product-type.application";
        };
        FABA347D1D8B575200915323 /* testaudiocapture */ = {
            isa = PBXNativeTarget;
            buildConfigurationList = FABA348E1D8B575200915323 /* Build configuration list for PBXNativeTarget "testaudiocapture" */;
            buildPhases = (
                FABA347E1D8B575200915323 /* Resources */,
                FABA34801D8B575200915323 /* Sources */,
                FABA34821D8B575200915323 /* Frameworks */,
            );
            buildRules = (
            );
            dependencies = (
            );
            name = testaudiocapture;
            productName = Test;
            productReference = FABA34911D8B575200915323 /* testaudiocapture.app */;
            productType = "com.apple.product-type.application";
        };
        FABA34961D8B582100915323 /* loopwav-TV */ = {
            isa = PBXNativeTarget;
            buildConfigurationList = FABA34A71D8B582100915323 /* Build configuration list for PBXNativeTarget "loopwav-TV" */;
            buildPhases = (
                FABA34971D8B582100915323 /* Resources */,
                FABA34991D8B582100915323 /* Sources */,
                FABA349B1D8B582100915323 /* Frameworks */,
            );
            buildRules = (
            );
            dependencies = (
            );
            name = "loopwav-TV";
            productName = Test;
            productReference = FABA34AA1D8B582100915323 /* loopwav-TV.app */;
            productType = "com.apple.product-type.application";
        };
        FAE0E9801BAF9B230098DFA4 /* testgamecontroller */ = {
@@ -1346,6 +1583,14 @@
            isa = PBXProject;
            attributes = {
                LastUpgradeCheck = 0630;
                TargetAttributes = {
                    FA3D99331BC4E644002C96C8 = {
                        CreatedOnToolsVersion = 7.1;
                    };
                    FABA34961D8B582100915323 = {
                        ProvisioningStyle = Automatic;
                    };
                };
            };
            buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "TestiPhoneOS" */;
            compatibilityVersion = "Xcode 3.2";
@@ -1356,6 +1601,7 @@
                Japanese,
                French,
                German,
                Base,
            );
            mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */;
            projectDirPath = "";
@@ -1372,12 +1618,15 @@
            projectRoot = "";
            targets = (
                047A63DD13285C3200CD7973 /* checkkeys */,
                FABA347D1D8B575200915323 /* testaudiocapture */,
                FDA8AAAA0E2D330F00EA573E /* loopwav */,
                FABA34961D8B582100915323 /* loopwav-TV */,
                FDAAC3BB0E2D47E6001DB1D8 /* testaudioinfo */,
                FDC42FEF0F0D866D009C87E1 /* testdraw2 */,
                FDAAC58A0E2D5429001DB1D8 /* testerror */,
                FDAAC5B80E2D55B5001DB1D8 /* testfile */,
                FAE0E9801BAF9B230098DFA4 /* testgamecontroller */,
                FA3D99331BC4E644002C96C8 /* testgamecontroller-TV */,
                046CEF7513254F23007AD51D /* testgesture */,
                FDAAC6150E2D5914001DB1D8 /* testgles */,
                FDD2C1700E2E52C000B7A85F /* testiconv */,
@@ -1405,6 +1654,20 @@
            fileType = archive.ar;
            path = libSDL2test.a;
            remoteRef = AA1EE451176059230029C7A5 /* PBXContainerItemProxy */;
            sourceTree = BUILT_PRODUCTS_DIR;
        };
        FA3D992B1BC4E619002C96C8 /* libSDL2.a */ = {
            isa = PBXReferenceProxy;
            fileType = archive.ar;
            path = libSDL2.a;
            remoteRef = FA3D992A1BC4E619002C96C8 /* PBXContainerItemProxy */;
            sourceTree = BUILT_PRODUCTS_DIR;
        };
        FA3D992F1BC4E619002C96C8 /* libSDL2test-TV.a */ = {
            isa = PBXReferenceProxy;
            fileType = archive.ar;
            path = "libSDL2test-TV.a";
            remoteRef = FA3D992E1BC4E619002C96C8 /* PBXContainerItemProxy */;
            sourceTree = BUILT_PRODUCTS_DIR;
        };
        FD1B48B80E3131CA007AB34E /* libSDL2.a */ = {
@@ -1462,6 +1725,32 @@
            files = (
                AAE7DFA014CBB54E00DF1A0E /* icon.bmp in Resources */,
                AAE7DFA114CBB54E00DF1A0E /* sample.bmp in Resources */,
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
        FA3D99321BC4E644002C96C8 /* Resources */ = {
            isa = PBXResourcesBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FA3D99521BC4E70C002C96C8 /* controllermap.bmp in Resources */,
                FA3D99541BC4E70F002C96C8 /* button.bmp in Resources */,
                FA3D99531BC4E70E002C96C8 /* axis.bmp in Resources */,
                FA3D99551BC4E712002C96C8 /* icon.bmp in Resources */,
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
        FABA347E1D8B575200915323 /* Resources */ = {
            isa = PBXResourcesBuildPhase;
            buildActionMask = 2147483647;
            files = (
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
        FABA34971D8B582100915323 /* Resources */ = {
            isa = PBXResourcesBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34981D8B582100915323 /* sample.wav in Resources */,
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
@@ -1617,6 +1906,7 @@
            buildActionMask = 2147483647;
            files = (
                047A63F113285CD100CD7973 /* checkkeys.c in Sources */,
                FABA34941D8B578200915323 /* testaudiocapture.c in Sources */,
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
@@ -1649,6 +1939,30 @@
            buildActionMask = 2147483647;
            files = (
                AAE7DFB514CBB5F700DF1A0E /* testrendertarget.c in Sources */,
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
        FA3D99301BC4E644002C96C8 /* Sources */ = {
            isa = PBXSourcesBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34AF1D8B59F800915323 /* testaudiocapture.c in Sources */,
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
        FABA34801D8B575200915323 /* Sources */ = {
            isa = PBXSourcesBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA34951D8B578600915323 /* testaudiocapture.c in Sources */,
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
        FABA34991D8B582100915323 /* Sources */ = {
            isa = PBXSourcesBuildPhase;
            buildActionMask = 2147483647;
            files = (
                FABA349A1D8B582100915323 /* loopwave.c in Sources */,
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
@@ -1798,6 +2112,14 @@
        };
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
        FAA8CEE61BDF06DC00D3BD45 /* PBXTargetDependency */ = {
            isa = PBXTargetDependency;
            name = "libSDL-tv";
            targetProxy = FAA8CEE51BDF06DC00D3BD45 /* PBXContainerItemProxy */;
        };
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
        046CEF8413254F23007AD51D /* Debug */ = {
            isa = XCBuildConfiguration;
@@ -1918,6 +2240,132 @@
                "PROVISIONING_PROFILE[sdk=iphoneos*]" = "";
                SDKROOT = iphoneos;
                TARGETED_DEVICE_FAMILY = "1,2";
            };
            name = Release;
        };
        FA3D99461BC4E645002C96C8 /* Debug */ = {
            isa = XCBuildConfiguration;
            buildSettings = {
                ALWAYS_SEARCH_USER_PATHS = NO;
                CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
                CLANG_CXX_LIBRARY = "libc++";
                CLANG_ENABLE_MODULES = YES;
                CLANG_ENABLE_OBJC_ARC = YES;
                CLANG_WARN_BOOL_CONVERSION = YES;
                CLANG_WARN_CONSTANT_CONVERSION = YES;
                CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
                CLANG_WARN_EMPTY_BODY = YES;
                CLANG_WARN_ENUM_CONVERSION = YES;
                CLANG_WARN_INT_CONVERSION = YES;
                CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
                CLANG_WARN_UNREACHABLE_CODE = YES;
                CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
                COPY_PHASE_STRIP = NO;
                DEBUG_INFORMATION_FORMAT = dwarf;
                ENABLE_STRICT_OBJC_MSGSEND = YES;
                ENABLE_TESTABILITY = YES;
                GCC_C_LANGUAGE_STANDARD = gnu99;
                GCC_DYNAMIC_NO_PIC = NO;
                GCC_NO_COMMON_BLOCKS = YES;
                GCC_PREPROCESSOR_DEFINITIONS = (
                    "DEBUG=1",
                    "$(inherited)",
                );
                GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
                GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
                GCC_WARN_UNDECLARED_SELECTOR = YES;
                GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
                GCC_WARN_UNUSED_FUNCTION = YES;
                GCC_WARN_UNUSED_VARIABLE = YES;
                INFOPLIST_FILE = Info.plist;
                LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
                MTL_ENABLE_DEBUG_INFO = YES;
                PRODUCT_NAME = "$(TARGET_NAME)";
                SDKROOT = appletvos;
                TARGETED_DEVICE_FAMILY = 3;
                TVOS_DEPLOYMENT_TARGET = 9.0;
            };
            name = Debug;
        };
        FA3D99471BC4E645002C96C8 /* Release */ = {
            isa = XCBuildConfiguration;
            buildSettings = {
                ALWAYS_SEARCH_USER_PATHS = NO;
                CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
                CLANG_CXX_LIBRARY = "libc++";
                CLANG_ENABLE_MODULES = YES;
                CLANG_ENABLE_OBJC_ARC = YES;
                CLANG_WARN_BOOL_CONVERSION = YES;
                CLANG_WARN_CONSTANT_CONVERSION = YES;
                CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
                CLANG_WARN_EMPTY_BODY = YES;
                CLANG_WARN_ENUM_CONVERSION = YES;
                CLANG_WARN_INT_CONVERSION = YES;
                CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
                CLANG_WARN_UNREACHABLE_CODE = YES;
                CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
                COPY_PHASE_STRIP = NO;
                DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
                ENABLE_NS_ASSERTIONS = NO;
                ENABLE_STRICT_OBJC_MSGSEND = YES;
                GCC_C_LANGUAGE_STANDARD = gnu99;
                GCC_NO_COMMON_BLOCKS = YES;
                GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
                GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
                GCC_WARN_UNDECLARED_SELECTOR = YES;
                GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
                GCC_WARN_UNUSED_FUNCTION = YES;
                GCC_WARN_UNUSED_VARIABLE = YES;
                INFOPLIST_FILE = Info.plist;
                LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
                MTL_ENABLE_DEBUG_INFO = NO;
                PRODUCT_NAME = "$(TARGET_NAME)";
                SDKROOT = appletvos;
                TARGETED_DEVICE_FAMILY = 3;
                TVOS_DEPLOYMENT_TARGET = 9.0;
                VALIDATE_PRODUCT = YES;
            };
            name = Release;
        };
        FABA348F1D8B575200915323 /* Debug */ = {
            isa = XCBuildConfiguration;
            buildSettings = {
                INFOPLIST_FILE = Info.plist;
                PRODUCT_NAME = "$(TARGET_NAME)";
            };
            name = Debug;
        };
        FABA34901D8B575200915323 /* Release */ = {
            isa = XCBuildConfiguration;
            buildSettings = {
                INFOPLIST_FILE = Info.plist;
                PRODUCT_NAME = "$(TARGET_NAME)";
            };
            name = Release;
        };
        FABA34A81D8B582100915323 /* Debug */ = {
            isa = XCBuildConfiguration;
            buildSettings = {
                DEVELOPMENT_TEAM = "";
                INFOPLIST_FILE = Info.plist;
                PRODUCT_NAME = "$(TARGET_NAME)";
                SDKROOT = appletvos;
                SUPPORTED_PLATFORMS = "appletvsimulator appletvos";
                TVOS_DEPLOYMENT_TARGET = 9.0;
                VALID_ARCHS = arm64;
            };
            name = Debug;
        };
        FABA34A91D8B582100915323 /* Release */ = {
            isa = XCBuildConfiguration;
            buildSettings = {
                DEVELOPMENT_TEAM = "";
                INFOPLIST_FILE = Info.plist;
                PRODUCT_NAME = "$(TARGET_NAME)";
                SDKROOT = appletvos;
                SUPPORTED_PLATFORMS = "appletvsimulator appletvos";
                TVOS_DEPLOYMENT_TARGET = 9.0;
                VALID_ARCHS = arm64;
            };
            name = Release;
        };
@@ -2275,6 +2723,33 @@
            defaultConfigurationIsVisible = 0;
            defaultConfigurationName = Release;
        };
        FA3D99451BC4E645002C96C8 /* Build configuration list for PBXNativeTarget "testgamecontroller-TV" */ = {
            isa = XCConfigurationList;
            buildConfigurations = (
                FA3D99461BC4E645002C96C8 /* Debug */,
                FA3D99471BC4E645002C96C8 /* Release */,
            );
            defaultConfigurationIsVisible = 0;
            defaultConfigurationName = Release;
        };
        FABA348E1D8B575200915323 /* Build configuration list for PBXNativeTarget "testaudiocapture" */ = {
            isa = XCConfigurationList;
            buildConfigurations = (
                FABA348F1D8B575200915323 /* Debug */,
                FABA34901D8B575200915323 /* Release */,
            );
            defaultConfigurationIsVisible = 0;
            defaultConfigurationName = Release;
        };
        FABA34A71D8B582100915323 /* Build configuration list for PBXNativeTarget "loopwav-TV" */ = {
            isa = XCConfigurationList;
            buildConfigurations = (
                FABA34A81D8B582100915323 /* Debug */,
                FABA34A91D8B582100915323 /* Release */,
            );
            defaultConfigurationIsVisible = 0;
            defaultConfigurationName = Release;
        };
        FAE0E9901BAF9B230098DFA4 /* Build configuration list for PBXNativeTarget "testgamecontroller" */ = {
            isa = XCConfigurationList;
            buildConfigurations = (
source/Xcode/SDL/Info-Framework.plist
@@ -11,7 +11,7 @@
    <key>CFBundleIconFile</key>
    <string></string>
    <key>CFBundleIdentifier</key>
    <string>org.libsdl.SDL2</string>
    <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
@@ -19,10 +19,10 @@
    <key>CFBundlePackageType</key>
    <string>FMWK</string>
    <key>CFBundleShortVersionString</key>
    <string>2.0.4</string>
    <string>2.0.5</string>
    <key>CFBundleSignature</key>
    <string>SDLX</string>
    <key>CFBundleVersion</key>
    <string>2.0.4</string>
    <string>2.0.5</string>
</dict>
</plist>
source/Xcode/SDL/SDL.xcodeproj/project.pbxproj
@@ -7,15 +7,9 @@
    objects = {
/* Begin PBXBuildFile section */
        007317A20858DECD00B2BC32 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179B0858DECD00B2BC32 /* AudioToolbox.framework */; };
        007317A30858DECD00B2BC32 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179C0858DECD00B2BC32 /* AudioUnit.framework */; };
        007317A40858DECD00B2BC32 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179D0858DECD00B2BC32 /* Cocoa.framework */; };
        007317A50858DECD00B2BC32 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179E0858DECD00B2BC32 /* CoreAudio.framework */; };
        007317A60858DECD00B2BC32 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179F0858DECD00B2BC32 /* IOKit.framework */; };
        007317A90858DECD00B2BC32 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179B0858DECD00B2BC32 /* AudioToolbox.framework */; };
        007317AA0858DECD00B2BC32 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179C0858DECD00B2BC32 /* AudioUnit.framework */; };
        007317AB0858DECD00B2BC32 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179D0858DECD00B2BC32 /* Cocoa.framework */; };
        007317AC0858DECD00B2BC32 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179E0858DECD00B2BC32 /* CoreAudio.framework */; };
        007317AD0858DECD00B2BC32 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179F0858DECD00B2BC32 /* IOKit.framework */; };
        007317C30858E15000B2BC32 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 007317C10858E15000B2BC32 /* Carbon.framework */; };
        00CFA89D106B4BA100758660 /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00CFA89C106B4BA100758660 /* ForceFeedback.framework */; };
@@ -57,14 +51,12 @@
        04BD000912E6671800899322 /* SDL_diskaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFD8912E6671700899322 /* SDL_diskaudio.h */; };
        04BD001012E6671800899322 /* SDL_dummyaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFD9412E6671700899322 /* SDL_dummyaudio.c */; };
        04BD001112E6671800899322 /* SDL_dummyaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFD9512E6671700899322 /* SDL_dummyaudio.h */; };
        04BD001812E6671800899322 /* SDL_coreaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFDA012E6671700899322 /* SDL_coreaudio.c */; };
        04BD001912E6671800899322 /* SDL_coreaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFDA112E6671700899322 /* SDL_coreaudio.h */; };
        04BD002612E6671800899322 /* SDL_audio.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFDB412E6671700899322 /* SDL_audio.c */; };
        04BD002712E6671800899322 /* SDL_audio_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFDB512E6671700899322 /* SDL_audio_c.h */; };
        04BD002812E6671800899322 /* SDL_audiocvt.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFDB612E6671700899322 /* SDL_audiocvt.c */; };
        04BD002912E6671800899322 /* SDL_audiodev.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFDB712E6671700899322 /* SDL_audiodev.c */; };
        04BD002A12E6671800899322 /* SDL_audiodev_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFDB812E6671700899322 /* SDL_audiodev_c.h */; };
        04BD002B12E6671800899322 /* SDL_audiomem.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFDB912E6671700899322 /* SDL_audiomem.h */; };
        04BD002C12E6671800899322 /* SDL_audiotypecvt.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFDBA12E6671700899322 /* SDL_audiotypecvt.c */; };
        04BD002D12E6671800899322 /* SDL_mixer.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFDBB12E6671700899322 /* SDL_mixer.c */; };
        04BD003412E6671800899322 /* SDL_sysaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFDC212E6671700899322 /* SDL_sysaudio.h */; };
@@ -211,14 +203,12 @@
        04BD022512E6671800899322 /* SDL_diskaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFD8912E6671700899322 /* SDL_diskaudio.h */; };
        04BD022C12E6671800899322 /* SDL_dummyaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFD9412E6671700899322 /* SDL_dummyaudio.c */; };
        04BD022D12E6671800899322 /* SDL_dummyaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFD9512E6671700899322 /* SDL_dummyaudio.h */; };
        04BD023412E6671800899322 /* SDL_coreaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFDA012E6671700899322 /* SDL_coreaudio.c */; };
        04BD023512E6671800899322 /* SDL_coreaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFDA112E6671700899322 /* SDL_coreaudio.h */; };
        04BD024212E6671800899322 /* SDL_audio.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFDB412E6671700899322 /* SDL_audio.c */; };
        04BD024312E6671800899322 /* SDL_audio_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFDB512E6671700899322 /* SDL_audio_c.h */; };
        04BD024412E6671800899322 /* SDL_audiocvt.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFDB612E6671700899322 /* SDL_audiocvt.c */; };
        04BD024512E6671800899322 /* SDL_audiodev.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFDB712E6671700899322 /* SDL_audiodev.c */; };
        04BD024612E6671800899322 /* SDL_audiodev_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFDB812E6671700899322 /* SDL_audiodev_c.h */; };
        04BD024712E6671800899322 /* SDL_audiomem.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFDB912E6671700899322 /* SDL_audiomem.h */; };
        04BD024812E6671800899322 /* SDL_audiotypecvt.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFDBA12E6671700899322 /* SDL_audiotypecvt.c */; };
        04BD024912E6671800899322 /* SDL_mixer.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFDBB12E6671700899322 /* SDL_mixer.c */; };
        04BD025012E6671800899322 /* SDL_sysaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFDC212E6671700899322 /* SDL_sysaudio.h */; };
@@ -387,6 +377,10 @@
        04F7805D12FB74A200FC43C0 /* SDL_drawline.h in Headers */ = {isa = PBXBuildFile; fileRef = 04F7804512FB74A200FC43C0 /* SDL_drawline.h */; };
        04F7805E12FB74A200FC43C0 /* SDL_drawpoint.c in Sources */ = {isa = PBXBuildFile; fileRef = 04F7804612FB74A200FC43C0 /* SDL_drawpoint.c */; };
        04F7805F12FB74A200FC43C0 /* SDL_drawpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 04F7804712FB74A200FC43C0 /* SDL_drawpoint.h */; };
        562C4AE91D8F496200AF9EBE /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E931D8B69C300B177DD /* AudioToolbox.framework */; };
        562C4AEA1D8F496300AF9EBE /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E931D8B69C300B177DD /* AudioToolbox.framework */; };
        562D3C7C1D8F4933003FEEE6 /* SDL_coreaudio.m in Sources */ = {isa = PBXBuildFile; fileRef = FABA34C61D8B5DB100915323 /* SDL_coreaudio.m */; };
        562D3C7D1D8F4933003FEEE6 /* SDL_coreaudio.m in Sources */ = {isa = PBXBuildFile; fileRef = FABA34C61D8B5DB100915323 /* SDL_coreaudio.m */; };
        566CDE8F148F0AC200C5A9BB /* SDL_dropevents_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 566CDE8D148F0AC200C5A9BB /* SDL_dropevents_c.h */; };
        566CDE90148F0AC200C5A9BB /* SDL_dropevents.c in Sources */ = {isa = PBXBuildFile; fileRef = 566CDE8E148F0AC200C5A9BB /* SDL_dropevents.c */; };
        567E2F1C17C44BB2005F1892 /* SDL_sysfilesystem.m in Sources */ = {isa = PBXBuildFile; fileRef = 567E2F1B17C44BB2005F1892 /* SDL_sysfilesystem.m */; };
@@ -406,6 +400,12 @@
        56A6702A185654B40007D20F /* SDL_dynapi_overrides.h in Headers */ = {isa = PBXBuildFile; fileRef = 56A67020185654B40007D20F /* SDL_dynapi_overrides.h */; };
        56A6702B185654B40007D20F /* SDL_dynapi_overrides.h in Headers */ = {isa = PBXBuildFile; fileRef = 56A67020185654B40007D20F /* SDL_dynapi_overrides.h */; };
        56A6702C185654B40007D20F /* SDL_dynapi_overrides.h in Headers */ = {isa = PBXBuildFile; fileRef = 56A67020185654B40007D20F /* SDL_dynapi_overrides.h */; };
        56C5237E1D8F4985001F2F30 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E951D8B69D600B177DD /* CoreAudio.framework */; };
        56C5237F1D8F4985001F2F30 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E951D8B69D600B177DD /* CoreAudio.framework */; };
        56C523801D8F498B001F2F30 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00D0D08310675DD9004B05EF /* CoreFoundation.framework */; };
        56C523811D8F498C001F2F30 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00D0D08310675DD9004B05EF /* CoreFoundation.framework */; };
        A7381E961D8B69D600B177DD /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E951D8B69D600B177DD /* CoreAudio.framework */; };
        A7381E971D8B6A0300B177DD /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A7381E931D8B69C300B177DD /* AudioToolbox.framework */; };
        A77E6EB4167AB0A90010E40B /* SDL_gamecontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A77E6EB3167AB0A90010E40B /* SDL_gamecontroller.h */; settings = {ATTRIBUTES = (Public, ); }; };
        A77E6EB5167AB0A90010E40B /* SDL_gamecontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A77E6EB3167AB0A90010E40B /* SDL_gamecontroller.h */; settings = {ATTRIBUTES = (Public, ); }; };
        AA0AD09D16648D1700CE5896 /* SDL_gamecontroller.c in Sources */ = {isa = PBXBuildFile; fileRef = BBFC088A164C6514003E6A99 /* SDL_gamecontroller.c */; };
@@ -563,7 +563,6 @@
        DB313F7617554B71006C0E22 /* SDL_coreaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFDA112E6671700899322 /* SDL_coreaudio.h */; };
        DB313F7717554B71006C0E22 /* SDL_audio_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFDB512E6671700899322 /* SDL_audio_c.h */; };
        DB313F7817554B71006C0E22 /* SDL_audiodev_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFDB812E6671700899322 /* SDL_audiodev_c.h */; };
        DB313F7917554B71006C0E22 /* SDL_audiomem.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFDB912E6671700899322 /* SDL_audiomem.h */; };
        DB313F7A17554B71006C0E22 /* SDL_sysaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFDC212E6671700899322 /* SDL_sysaudio.h */; };
        DB313F7B17554B71006C0E22 /* SDL_wave.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFDC412E6671700899322 /* SDL_wave.h */; };
        DB313F7C17554B71006C0E22 /* blank_cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = 04BDFDD612E6671700899322 /* blank_cursor.h */; };
@@ -698,7 +697,6 @@
        DB313FFF17554B71006C0E22 /* SDL_spinlock.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFD7512E6671700899322 /* SDL_spinlock.c */; };
        DB31400017554B71006C0E22 /* SDL_diskaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFD8812E6671700899322 /* SDL_diskaudio.c */; };
        DB31400117554B71006C0E22 /* SDL_dummyaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFD9412E6671700899322 /* SDL_dummyaudio.c */; };
        DB31400217554B71006C0E22 /* SDL_coreaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFDA012E6671700899322 /* SDL_coreaudio.c */; };
        DB31400317554B71006C0E22 /* SDL_audio.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFDB412E6671700899322 /* SDL_audio.c */; };
        DB31400417554B71006C0E22 /* SDL_audiocvt.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFDB612E6671700899322 /* SDL_audiocvt.c */; };
        DB31400517554B71006C0E22 /* SDL_audiodev.c in Sources */ = {isa = PBXBuildFile; fileRef = 04BDFDB712E6671700899322 /* SDL_audiodev.c */; };
@@ -802,10 +800,7 @@
        DB31406817554B71006C0E22 /* SDL_x11xinput2.c in Sources */ = {isa = PBXBuildFile; fileRef = AA628ACF159367F2005138DD /* SDL_x11xinput2.c */; };
        DB31406917554B71006C0E22 /* SDL_x11messagebox.c in Sources */ = {isa = PBXBuildFile; fileRef = AA9E4092163BE51E007A2AD0 /* SDL_x11messagebox.c */; };
        DB31406A17554B71006C0E22 /* SDL_cocoamessagebox.m in Sources */ = {isa = PBXBuildFile; fileRef = AABCC38C164063D200AB8930 /* SDL_cocoamessagebox.m */; };
        DB31406C17554B71006C0E22 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179B0858DECD00B2BC32 /* AudioToolbox.framework */; };
        DB31406D17554B71006C0E22 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179C0858DECD00B2BC32 /* AudioUnit.framework */; };
        DB31406E17554B71006C0E22 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179D0858DECD00B2BC32 /* Cocoa.framework */; };
        DB31406F17554B71006C0E22 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179E0858DECD00B2BC32 /* CoreAudio.framework */; };
        DB31407017554B71006C0E22 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0073179F0858DECD00B2BC32 /* IOKit.framework */; };
        DB31407217554B71006C0E22 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 007317C10858E15000B2BC32 /* Carbon.framework */; };
        DB31408B17554D37006C0E22 /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00CFA89C106B4BA100758660 /* ForceFeedback.framework */; };
@@ -813,6 +808,7 @@
        FA73671D19A540EF004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73671C19A540EF004122E4 /* CoreVideo.framework */; };
        FA73671E19A54140004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73671C19A540EF004122E4 /* CoreVideo.framework */; };
        FA73671F19A54144004122E4 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA73671C19A540EF004122E4 /* CoreVideo.framework */; };
        FABA34C71D8B5DB100915323 /* SDL_coreaudio.m in Sources */ = {isa = PBXBuildFile; fileRef = FABA34C61D8B5DB100915323 /* SDL_coreaudio.m */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -826,10 +822,7 @@
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
        0073179B0858DECD00B2BC32 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = /System/Library/Frameworks/AudioToolbox.framework; sourceTree = "<absolute>"; };
        0073179C0858DECD00B2BC32 /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = /System/Library/Frameworks/AudioUnit.framework; sourceTree = "<absolute>"; };
        0073179D0858DECD00B2BC32 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
        0073179E0858DECD00B2BC32 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = /System/Library/Frameworks/CoreAudio.framework; sourceTree = "<absolute>"; };
        0073179F0858DECD00B2BC32 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = "<absolute>"; };
        007317C10858E15000B2BC32 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
        00794D3F09D0C461003FC8A1 /* License.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = License.txt; sourceTree = "<group>"; };
@@ -857,14 +850,12 @@
        04BDFD8912E6671700899322 /* SDL_diskaudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_diskaudio.h; sourceTree = "<group>"; };
        04BDFD9412E6671700899322 /* SDL_dummyaudio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_dummyaudio.c; sourceTree = "<group>"; };
        04BDFD9512E6671700899322 /* SDL_dummyaudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_dummyaudio.h; sourceTree = "<group>"; };
        04BDFDA012E6671700899322 /* SDL_coreaudio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_coreaudio.c; sourceTree = "<group>"; };
        04BDFDA112E6671700899322 /* SDL_coreaudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_coreaudio.h; sourceTree = "<group>"; };
        04BDFDB412E6671700899322 /* SDL_audio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_audio.c; sourceTree = "<group>"; };
        04BDFDB512E6671700899322 /* SDL_audio_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_audio_c.h; sourceTree = "<group>"; };
        04BDFDB612E6671700899322 /* SDL_audiocvt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_audiocvt.c; sourceTree = "<group>"; };
        04BDFDB712E6671700899322 /* SDL_audiodev.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_audiodev.c; sourceTree = "<group>"; };
        04BDFDB812E6671700899322 /* SDL_audiodev_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_audiodev_c.h; sourceTree = "<group>"; };
        04BDFDB912E6671700899322 /* SDL_audiomem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_audiomem.h; sourceTree = "<group>"; };
        04BDFDBA12E6671700899322 /* SDL_audiotypecvt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_audiotypecvt.c; sourceTree = "<group>"; };
        04BDFDBB12E6671700899322 /* SDL_mixer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_mixer.c; sourceTree = "<group>"; };
        04BDFDC212E6671700899322 /* SDL_sysaudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_sysaudio.h; sourceTree = "<group>"; };
@@ -1027,6 +1018,8 @@
        56A6701E185654B40007D20F /* SDL_dynapi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SDL_dynapi.c; path = ../../src/dynapi/SDL_dynapi.c; sourceTree = "<group>"; };
        56A6701F185654B40007D20F /* SDL_dynapi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_dynapi.h; path = ../../src/dynapi/SDL_dynapi.h; sourceTree = "<group>"; };
        56A67020185654B40007D20F /* SDL_dynapi_overrides.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_dynapi_overrides.h; path = ../../src/dynapi/SDL_dynapi_overrides.h; sourceTree = "<group>"; };
        A7381E931D8B69C300B177DD /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
        A7381E951D8B69D600B177DD /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; };
        A77E6EB3167AB0A90010E40B /* SDL_gamecontroller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_gamecontroller.h; sourceTree = "<group>"; };
        AA0F8490178D5ECC00823F9D /* SDL_systls.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_systls.c; sourceTree = "<group>"; };
        AA628AC8159367B7005138DD /* SDL_rotate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_rotate.c; sourceTree = "<group>"; };
@@ -1106,6 +1099,7 @@
        F59C710600D5CB5801000001 /* SDL.info */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = SDL.info; sourceTree = "<group>"; };
        F5A2EF3900C6A39A01000001 /* BUGS.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = BUGS.txt; path = ../../BUGS.txt; sourceTree = SOURCE_ROOT; };
        FA73671C19A540EF004122E4 /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = /System/Library/Frameworks/CoreVideo.framework; sourceTree = "<absolute>"; };
        FABA34C61D8B5DB100915323 /* SDL_coreaudio.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_coreaudio.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -1113,11 +1107,10 @@
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                A7381E971D8B6A0300B177DD /* AudioToolbox.framework in Frameworks */,
                A7381E961D8B69D600B177DD /* CoreAudio.framework in Frameworks */,
                FA73671D19A540EF004122E4 /* CoreVideo.framework in Frameworks */,
                007317A20858DECD00B2BC32 /* AudioToolbox.framework in Frameworks */,
                007317A30858DECD00B2BC32 /* AudioUnit.framework in Frameworks */,
                007317A40858DECD00B2BC32 /* Cocoa.framework in Frameworks */,
                007317A50858DECD00B2BC32 /* CoreAudio.framework in Frameworks */,
                007317A60858DECD00B2BC32 /* IOKit.framework in Frameworks */,
                00D0D08410675DD9004B05EF /* CoreFoundation.framework in Frameworks */,
                00D0D0D810675E46004B05EF /* Carbon.framework in Frameworks */,
@@ -1129,14 +1122,14 @@
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                56C5237E1D8F4985001F2F30 /* CoreAudio.framework in Frameworks */,
                FA73671E19A54140004122E4 /* CoreVideo.framework in Frameworks */,
                007317A90858DECD00B2BC32 /* AudioToolbox.framework in Frameworks */,
                007317AA0858DECD00B2BC32 /* AudioUnit.framework in Frameworks */,
                007317AB0858DECD00B2BC32 /* Cocoa.framework in Frameworks */,
                007317AC0858DECD00B2BC32 /* CoreAudio.framework in Frameworks */,
                007317AD0858DECD00B2BC32 /* IOKit.framework in Frameworks */,
                56C523801D8F498B001F2F30 /* CoreFoundation.framework in Frameworks */,
                007317C30858E15000B2BC32 /* Carbon.framework in Frameworks */,
                DB31408B17554D37006C0E22 /* ForceFeedback.framework in Frameworks */,
                562C4AE91D8F496200AF9EBE /* AudioToolbox.framework in Frameworks */,
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
@@ -1144,14 +1137,14 @@
            isa = PBXFrameworksBuildPhase;
            buildActionMask = 2147483647;
            files = (
                56C5237F1D8F4985001F2F30 /* CoreAudio.framework in Frameworks */,
                FA73671F19A54144004122E4 /* CoreVideo.framework in Frameworks */,
                DB31406C17554B71006C0E22 /* AudioToolbox.framework in Frameworks */,
                DB31406D17554B71006C0E22 /* AudioUnit.framework in Frameworks */,
                DB31406E17554B71006C0E22 /* Cocoa.framework in Frameworks */,
                DB31406F17554B71006C0E22 /* CoreAudio.framework in Frameworks */,
                DB31407017554B71006C0E22 /* IOKit.framework in Frameworks */,
                56C523811D8F498C001F2F30 /* CoreFoundation.framework in Frameworks */,
                DB31407217554B71006C0E22 /* Carbon.framework in Frameworks */,
                DB31408D17554D3C006C0E22 /* ForceFeedback.framework in Frameworks */,
                562C4AEA1D8F496300AF9EBE /* AudioToolbox.framework in Frameworks */,
            );
            runOnlyForDeploymentPostprocessing = 0;
        };
@@ -1307,7 +1300,6 @@
                04BDFDB612E6671700899322 /* SDL_audiocvt.c */,
                04BDFDB712E6671700899322 /* SDL_audiodev.c */,
                04BDFDB812E6671700899322 /* SDL_audiodev_c.h */,
                04BDFDB912E6671700899322 /* SDL_audiomem.h */,
                04BDFDBA12E6671700899322 /* SDL_audiotypecvt.c */,
                04BDFDBB12E6671700899322 /* SDL_mixer.c */,
                04BDFDC212E6671700899322 /* SDL_sysaudio.h */,
@@ -1339,8 +1331,8 @@
        04BDFD9F12E6671700899322 /* coreaudio */ = {
            isa = PBXGroup;
            children = (
                04BDFDA012E6671700899322 /* SDL_coreaudio.c */,
                04BDFDA112E6671700899322 /* SDL_coreaudio.h */,
                FABA34C61D8B5DB100915323 /* SDL_coreaudio.m */,
            );
            path = coreaudio;
            sourceTree = "<group>";
@@ -1737,13 +1729,12 @@
        BEC562FE0761C0E800A33029 /* Linked Frameworks */ = {
            isa = PBXGroup;
            children = (
                A7381E931D8B69C300B177DD /* AudioToolbox.framework */,
                A7381E951D8B69D600B177DD /* CoreAudio.framework */,
                FA73671C19A540EF004122E4 /* CoreVideo.framework */,
                00D0D08310675DD9004B05EF /* CoreFoundation.framework */,
                007317C10858E15000B2BC32 /* Carbon.framework */,
                0073179B0858DECD00B2BC32 /* AudioToolbox.framework */,
                0073179C0858DECD00B2BC32 /* AudioUnit.framework */,
                0073179D0858DECD00B2BC32 /* Cocoa.framework */,
                0073179E0858DECD00B2BC32 /* CoreAudio.framework */,
                0073179F0858DECD00B2BC32 /* IOKit.framework */,
                00CFA89C106B4BA100758660 /* ForceFeedback.framework */,
            );
@@ -1840,7 +1831,6 @@
                04BD001912E6671800899322 /* SDL_coreaudio.h in Headers */,
                04BD002712E6671800899322 /* SDL_audio_c.h in Headers */,
                04BD002A12E6671800899322 /* SDL_audiodev_c.h in Headers */,
                04BD002B12E6671800899322 /* SDL_audiomem.h in Headers */,
                04BD003412E6671800899322 /* SDL_sysaudio.h in Headers */,
                04BD003612E6671800899322 /* SDL_wave.h in Headers */,
                04BD004212E6671800899322 /* blank_cursor.h in Headers */,
@@ -1996,7 +1986,6 @@
                04BD024312E6671800899322 /* SDL_audio_c.h in Headers */,
                04BD024612E6671800899322 /* SDL_audiodev_c.h in Headers */,
                AAC070FD195606770073DCDF /* SDL_opengles2_gl2.h in Headers */,
                04BD024712E6671800899322 /* SDL_audiomem.h in Headers */,
                04BD025012E6671800899322 /* SDL_sysaudio.h in Headers */,
                04BD025212E6671800899322 /* SDL_wave.h in Headers */,
                04BD025D12E6671800899322 /* blank_cursor.h in Headers */,
@@ -2151,7 +2140,6 @@
                DB313F7717554B71006C0E22 /* SDL_audio_c.h in Headers */,
                DB313F7817554B71006C0E22 /* SDL_audiodev_c.h in Headers */,
                AAC070FE195606770073DCDF /* SDL_opengles2_gl2.h in Headers */,
                DB313F7917554B71006C0E22 /* SDL_audiomem.h in Headers */,
                DB313F7A17554B71006C0E22 /* SDL_sysaudio.h in Headers */,
                DB313F7B17554B71006C0E22 /* SDL_wave.h in Headers */,
                DB313F7C17554B71006C0E22 /* blank_cursor.h in Headers */,
@@ -2323,7 +2311,7 @@
        0867D690FE84028FC02AAC07 /* Project object */ = {
            isa = PBXProject;
            attributes = {
                LastUpgradeCheck = 0630;
                LastUpgradeCheck = 0730;
                TargetAttributes = {
                    BECDF5FE0761BA81005FE872 = {
                        DevelopmentTeam = EH385AYQ6F;
@@ -2404,7 +2392,6 @@
                04BDFFFC12E6671800899322 /* SDL_spinlock.c in Sources */,
                04BD000812E6671800899322 /* SDL_diskaudio.c in Sources */,
                04BD001012E6671800899322 /* SDL_dummyaudio.c in Sources */,
                04BD001812E6671800899322 /* SDL_coreaudio.c in Sources */,
                04BD002612E6671800899322 /* SDL_audio.c in Sources */,
                04BD002812E6671800899322 /* SDL_audiocvt.c in Sources */,
                04BD002912E6671800899322 /* SDL_audiodev.c in Sources */,
@@ -2440,6 +2427,7 @@
                04BD00A812E6671800899322 /* SDL_string.c in Sources */,
                04BD00BD12E6671800899322 /* SDL_syscond.c in Sources */,
                04BD00BE12E6671800899322 /* SDL_sysmutex.c in Sources */,
                FABA34C71D8B5DB100915323 /* SDL_coreaudio.m in Sources */,
                04BD00C012E6671800899322 /* SDL_syssem.c in Sources */,
                04BD00C112E6671800899322 /* SDL_systhread.c in Sources */,
                04BD00CA12E6671800899322 /* SDL_thread.c in Sources */,
@@ -2523,7 +2511,6 @@
                04BD021812E6671800899322 /* SDL_spinlock.c in Sources */,
                04BD022412E6671800899322 /* SDL_diskaudio.c in Sources */,
                04BD022C12E6671800899322 /* SDL_dummyaudio.c in Sources */,
                04BD023412E6671800899322 /* SDL_coreaudio.c in Sources */,
                04BD024212E6671800899322 /* SDL_audio.c in Sources */,
                04BD024412E6671800899322 /* SDL_audiocvt.c in Sources */,
                04BD024512E6671800899322 /* SDL_audiodev.c in Sources */,
@@ -2559,6 +2546,7 @@
                04BD02C012E6671800899322 /* SDL_qsort.c in Sources */,
                04BD02C112E6671800899322 /* SDL_stdlib.c in Sources */,
                04BD02C212E6671800899322 /* SDL_string.c in Sources */,
                562D3C7C1D8F4933003FEEE6 /* SDL_coreaudio.m in Sources */,
                04BD02D712E6671800899322 /* SDL_syscond.c in Sources */,
                04BD02D812E6671800899322 /* SDL_sysmutex.c in Sources */,
                04BD02DA12E6671800899322 /* SDL_syssem.c in Sources */,
@@ -2642,7 +2630,6 @@
                DB313FFF17554B71006C0E22 /* SDL_spinlock.c in Sources */,
                DB31400017554B71006C0E22 /* SDL_diskaudio.c in Sources */,
                DB31400117554B71006C0E22 /* SDL_dummyaudio.c in Sources */,
                DB31400217554B71006C0E22 /* SDL_coreaudio.c in Sources */,
                DB31400317554B71006C0E22 /* SDL_audio.c in Sources */,
                DB31400417554B71006C0E22 /* SDL_audiocvt.c in Sources */,
                DB31400517554B71006C0E22 /* SDL_audiodev.c in Sources */,
@@ -2678,6 +2665,7 @@
                DB31402417554B71006C0E22 /* SDL_qsort.c in Sources */,
                DB31402517554B71006C0E22 /* SDL_stdlib.c in Sources */,
                DB31402617554B71006C0E22 /* SDL_string.c in Sources */,
                562D3C7D1D8F4933003FEEE6 /* SDL_coreaudio.m in Sources */,
                DB31402717554B71006C0E22 /* SDL_syscond.c in Sources */,
                DB31402817554B71006C0E22 /* SDL_sysmutex.c in Sources */,
                DB31402917554B71006C0E22 /* SDL_syssem.c in Sources */,
@@ -2767,13 +2755,30 @@
        00CFA621106A567900758660 /* Release */ = {
            isa = XCBuildConfiguration;
            buildSettings = {
                CLANG_WARN_BOOL_CONVERSION = YES;
                CLANG_WARN_CONSTANT_CONVERSION = YES;
                CLANG_WARN_EMPTY_BODY = YES;
                CLANG_WARN_ENUM_CONVERSION = YES;
                CLANG_WARN_INFINITE_RECURSION = YES;
                CLANG_WARN_INT_CONVERSION = YES;
                CLANG_WARN_SUSPICIOUS_MOVE = YES;
                CLANG_WARN_UNREACHABLE_CODE = YES;
                CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
                DEPLOYMENT_POSTPROCESSING = YES;
                ENABLE_STRICT_OBJC_MSGSEND = YES;
                GCC_ALTIVEC_EXTENSIONS = YES;
                GCC_AUTO_VECTORIZATION = YES;
                GCC_ENABLE_SSE3_EXTENSIONS = YES;
                GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
                GCC_NO_COMMON_BLOCKS = YES;
                GCC_OPTIMIZATION_LEVEL = 3;
                GCC_SYMBOLS_PRIVATE_EXTERN = YES;
                GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                GCC_WARN_UNDECLARED_SELECTOR = YES;
                GCC_WARN_UNINITIALIZED_AUTOS = YES;
                GCC_WARN_UNUSED_FUNCTION = YES;
                GCC_WARN_UNUSED_VARIABLE = YES;
                MACOSX_DEPLOYMENT_TARGET = 10.6;
                SDKROOT = macosx;
                STRIP_STYLE = "non-global";
@@ -2783,15 +2788,17 @@
        00CFA622106A567900758660 /* Release */ = {
            isa = XCBuildConfiguration;
            buildSettings = {
                ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
                CLANG_LINK_OBJC_RUNTIME = NO;
                COMBINE_HIDPI_IMAGES = YES;
                DYLIB_COMPATIBILITY_VERSION = 1.0.0;
                DYLIB_CURRENT_VERSION = 5.0.0;
                DYLIB_CURRENT_VERSION = 5.1.0;
                FRAMEWORK_VERSION = A;
                HEADER_SEARCH_PATHS = /usr/X11R6/include;
                INFOPLIST_FILE = "Info-Framework.plist";
                INSTALL_PATH = "@rpath";
                OTHER_LDFLAGS = "-liconv";
                PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.SDL2;
                PRODUCT_NAME = SDL2;
                PROVISIONING_PROFILE = "";
                WRAPPER_EXTENSION = framework;
@@ -2827,11 +2834,29 @@
        00CFA627106A568900758660 /* Debug */ = {
            isa = XCBuildConfiguration;
            buildSettings = {
                CLANG_WARN_BOOL_CONVERSION = YES;
                CLANG_WARN_CONSTANT_CONVERSION = YES;
                CLANG_WARN_EMPTY_BODY = YES;
                CLANG_WARN_ENUM_CONVERSION = YES;
                CLANG_WARN_INFINITE_RECURSION = YES;
                CLANG_WARN_INT_CONVERSION = YES;
                CLANG_WARN_SUSPICIOUS_MOVE = YES;
                CLANG_WARN_UNREACHABLE_CODE = YES;
                CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
                ENABLE_STRICT_OBJC_MSGSEND = YES;
                ENABLE_TESTABILITY = YES;
                GCC_ALTIVEC_EXTENSIONS = YES;
                GCC_AUTO_VECTORIZATION = YES;
                GCC_ENABLE_SSE3_EXTENSIONS = YES;
                GCC_NO_COMMON_BLOCKS = YES;
                GCC_OPTIMIZATION_LEVEL = 0;
                GCC_SYMBOLS_PRIVATE_EXTERN = YES;
                GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
                GCC_WARN_ABOUT_RETURN_TYPE = YES;
                GCC_WARN_UNDECLARED_SELECTOR = YES;
                GCC_WARN_UNINITIALIZED_AUTOS = YES;
                GCC_WARN_UNUSED_FUNCTION = YES;
                GCC_WARN_UNUSED_VARIABLE = YES;
                MACOSX_DEPLOYMENT_TARGET = 10.6;
                ONLY_ACTIVE_ARCH = YES;
                SDKROOT = macosx;
@@ -2842,15 +2867,17 @@
        00CFA628106A568900758660 /* Debug */ = {
            isa = XCBuildConfiguration;
            buildSettings = {
                ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
                CLANG_LINK_OBJC_RUNTIME = NO;
                COMBINE_HIDPI_IMAGES = YES;
                DYLIB_COMPATIBILITY_VERSION = 1.0.0;
                DYLIB_CURRENT_VERSION = 5.0.0;
                DYLIB_CURRENT_VERSION = 5.1.0;
                FRAMEWORK_VERSION = A;
                HEADER_SEARCH_PATHS = /usr/X11R6/include;
                INFOPLIST_FILE = "Info-Framework.plist";
                INSTALL_PATH = "@rpath";
                OTHER_LDFLAGS = "-liconv";
                PRODUCT_BUNDLE_IDENTIFIER = org.libsdl.SDL2;
                PRODUCT_NAME = SDL2;
                PROVISIONING_PROFILE = "";
                WRAPPER_EXTENSION = framework;
source/android-project/AndroidManifest.xml
@@ -17,6 +17,9 @@
    <!-- Allow writing to external storage -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <!-- if you want to capture audio, uncomment this. -->
    <!-- <uses-permission android:name="android.permission.RECORD_AUDIO" /> -->
    <!-- Create a Java class extending SDLActivity and place it in a
         directory under src matching the package, e.g.
             src/com/gamemaker/game/MyGame.java
@@ -24,7 +27,7 @@
         then replace "SDLActivity" with the name of your class (e.g. "MyGame")
         in the XML below.
         An example Java class can be found in README-android.txt
         An example Java class can be found in README-android.md
    -->
    <application android:label="@string/app_name"
                 android:icon="@drawable/ic_launcher"
source/android-project/jni/Application.mk
@@ -4,3 +4,7 @@
# APP_STL := stlport_static 
APP_ABI := armeabi armeabi-v7a x86
# Min SDK level
APP_PLATFORM=android-10
source/android-project/src/org/libsdl/app/SDLActivity.java
@@ -17,7 +17,7 @@
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import android.widget.AbsoluteLayout;
import android.widget.RelativeLayout;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
@@ -59,6 +59,7 @@
    // Audio
    protected static AudioTrack mAudioTrack;
    protected static AudioRecord mAudioRecord;
    /**
     * This method is called by SDL before loading the native shared libraries.
@@ -106,6 +107,7 @@
        mJoystickHandler = null;
        mSDLThread = null;
        mAudioTrack = null;
        mAudioRecord = null;
        mExitCalledFromJava = false;
        mBrokenLibraries = false;
        mIsPaused = false;
@@ -171,7 +173,7 @@
            mJoystickHandler = new SDLJoystickHandler();
        }
        mLayout = new AbsoluteLayout(this);
        mLayout = new RelativeLayout(this);
        mLayout.addView(mSurface);
        setContentView(mLayout);
@@ -367,7 +369,10 @@
                break;
            case COMMAND_TEXTEDIT_HIDE:
                if (mTextEdit != null) {
                    mTextEdit.setVisibility(View.GONE);
                    // Note: On some devices setting view to GONE creates a flicker in landscape.
                    // Setting the View's sizes to 0 is similar to GONE but without the flicker.
                    // The sizes will be set to useful values when the keyboard is shown again.
                    mTextEdit.setLayoutParams(new RelativeLayout.LayoutParams(0, 0));
                    InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
                    imm.hideSoftInputFromWindow(mTextEdit.getWindowToken(), 0);
@@ -504,8 +509,9 @@
        @Override
        public void run() {
            AbsoluteLayout.LayoutParams params = new AbsoluteLayout.LayoutParams(
                    w, h + HEIGHT_PADDING, x, y);
            RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(w, h + HEIGHT_PADDING);
            params.leftMargin = x;
            params.topMargin = y;
            if (mTextEdit == null) {
                mTextEdit = new DummyEdit(getContext());
@@ -543,7 +549,7 @@
    /**
     * This method is called by SDL using JNI.
     */
    public static int audioInit(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) {
    public static int audioOpen(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) {
        int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO : AudioFormat.CHANNEL_CONFIGURATION_MONO;
        int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT;
        int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1);
@@ -622,12 +628,71 @@
    /**
     * This method is called by SDL using JNI.
     */
    public static void audioQuit() {
    public static int captureOpen(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) {
        int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO : AudioFormat.CHANNEL_CONFIGURATION_MONO;
        int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT;
        int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1);
        Log.v(TAG, "SDL capture: wanted " + (isStereo ? "stereo" : "mono") + " " + (is16Bit ? "16-bit" : "8-bit") + " " + (sampleRate / 1000f) + "kHz, " + desiredFrames + " frames buffer");
        // Let the user pick a larger buffer if they really want -- but ye
        // gods they probably shouldn't, the minimums are horrifyingly high
        // latency already
        desiredFrames = Math.max(desiredFrames, (AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat) + frameSize - 1) / frameSize);
        if (mAudioRecord == null) {
            mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, sampleRate,
                    channelConfig, audioFormat, desiredFrames * frameSize);
            // see notes about AudioTrack state in audioOpen(), above. Probably also applies here.
            if (mAudioRecord.getState() != AudioRecord.STATE_INITIALIZED) {
                Log.e(TAG, "Failed during initialization of AudioRecord");
                mAudioRecord.release();
                mAudioRecord = null;
                return -1;
            }
            mAudioRecord.startRecording();
        }
        Log.v(TAG, "SDL capture: got " + ((mAudioRecord.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioRecord.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + (mAudioRecord.getSampleRate() / 1000f) + "kHz, " + desiredFrames + " frames buffer");
        return 0;
    }
    /** This method is called by SDL using JNI. */
    public static int captureReadShortBuffer(short[] buffer, boolean blocking) {
        // !!! FIXME: this is available in API Level 23. Until then, we always block.  :(
        //return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING);
        return mAudioRecord.read(buffer, 0, buffer.length);
    }
    /** This method is called by SDL using JNI. */
    public static int captureReadByteBuffer(byte[] buffer, boolean blocking) {
        // !!! FIXME: this is available in API Level 23. Until then, we always block.  :(
        //return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING);
        return mAudioRecord.read(buffer, 0, buffer.length);
    }
    /** This method is called by SDL using JNI. */
    public static void audioClose() {
        if (mAudioTrack != null) {
            mAudioTrack.stop();
            mAudioTrack.release();
            mAudioTrack = null;
        }
    }
    /** This method is called by SDL using JNI. */
    public static void captureClose() {
        if (mAudioRecord != null) {
            mAudioRecord.stop();
            mAudioRecord.release();
            mAudioRecord = null;
        }
    }
    // Input
@@ -662,6 +727,21 @@
        }
    }
    // Check if a given device is considered a possible SDL joystick
    public static boolean isDeviceSDLJoystick(int deviceId) {
        InputDevice device = InputDevice.getDevice(deviceId);
        // We cannot use InputDevice.isVirtual before API 16, so let's accept
        // only nonnegative device ids (VIRTUAL_KEYBOARD equals -1)
        if ((device == null) || (deviceId < 0)) {
            return false;
        }
        int sources = device.getSources();
        return (((sources & InputDevice.SOURCE_CLASS_JOYSTICK) == InputDevice.SOURCE_CLASS_JOYSTICK) ||
                ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD) ||
                ((sources & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD)
        );
    }
    // APK expansion files support
    /** com.android.vending.expansion.zipfile.ZipResourceFile object or null. */
@@ -669,15 +749,6 @@
    /** com.android.vending.expansion.zipfile.ZipResourceFile's getInputStream() or null. */
    private Method expansionFileMethod;
    /**
     * This method was called by SDL using JNI.
     * @deprecated because of an incorrect name
     */
    @Deprecated
    public InputStream openAPKExtensionInputStream(String fileName) throws IOException {
        return openAPKExpansionInputStream(fileName);
    }
    /**
     * This method is called by SDL using JNI.
@@ -1167,11 +1238,14 @@
    @Override
    public boolean onKey(View  v, int keyCode, KeyEvent event) {
        // Dispatch the different events depending on where they come from
        // Some SOURCE_DPAD or SOURCE_GAMEPAD are also SOURCE_KEYBOARD
        // So, we try to process them as DPAD or GAMEPAD events first, if that fails we try them as KEYBOARD
        if ( (event.getSource() & InputDevice.SOURCE_GAMEPAD) != 0 ||
                   (event.getSource() & InputDevice.SOURCE_DPAD) != 0 ) {
        // Some SOURCE_JOYSTICK, SOURCE_DPAD or SOURCE_GAMEPAD are also SOURCE_KEYBOARD
        // So, we try to process them as JOYSTICK/DPAD/GAMEPAD events first, if that fails we try them as KEYBOARD
        //
        // Furthermore, it's possible a game controller has SOURCE_KEYBOARD and
        // SOURCE_JOYSTICK, while its key events arrive from the keyboard source
        // So, retrieve the device itself and check all of its sources
        if (SDLActivity.isDeviceSDLJoystick(event.getDeviceId())) {
            // Note that we process events with specific key codes here
            if (event.getAction() == KeyEvent.ACTION_DOWN) {
                if (SDLActivity.onNativePadDown(event.getDeviceId(), keyCode) == 0) {
                    return true;
@@ -1183,7 +1257,7 @@
            }
        }
        if( (event.getSource() & InputDevice.SOURCE_KEYBOARD) != 0) {
        if ((event.getSource() & InputDevice.SOURCE_KEYBOARD) != 0) {
            if (event.getAction() == KeyEvent.ACTION_DOWN) {
                //Log.v("SDL", "key down: " + keyCode);
                SDLActivity.onNativeKeyDown(keyCode);
@@ -1193,6 +1267,20 @@
                //Log.v("SDL", "key up: " + keyCode);
                SDLActivity.onNativeKeyUp(keyCode);
                return true;
            }
        }
        if ((event.getSource() & InputDevice.SOURCE_MOUSE) != 0) {
            // on some devices key events are sent for mouse BUTTON_BACK/FORWARD presses
            // they are ignored here because sending them as mouse input to SDL is messy
            if ((keyCode == KeyEvent.KEYCODE_BACK) || (keyCode == KeyEvent.KEYCODE_FORWARD)) {
                switch (event.getAction()) {
                case KeyEvent.ACTION_DOWN:
                case KeyEvent.ACTION_UP:
                    // mark the event as handled or it will be handled by system
                    // handling KEYCODE_BACK by system will call onBackPressed()
                    return true;
                }
            }
        }
@@ -1214,7 +1302,7 @@
        // !!! FIXME: dump this SDK check after 2.0.4 ships and require API14.
        if (event.getSource() == InputDevice.SOURCE_MOUSE && SDLActivity.mSeparateMouseAndTouch) {
            if (Build.VERSION.SDK_INT < 14) {
                mouseButton = 1;    // For Android==12 all mouse buttons are the left button
                mouseButton = 1; // all mouse buttons are the left button
            } else {
                try {
                    mouseButton = (Integer) event.getClass().getMethod("getButtonState").invoke(event);
@@ -1328,7 +1416,7 @@
            }
            SDLActivity.onNativeAccel(-x / SensorManager.GRAVITY_EARTH,
                                      y / SensorManager.GRAVITY_EARTH,
                                      event.values[2] / SensorManager.GRAVITY_EARTH - 1);
                                      event.values[2] / SensorManager.GRAVITY_EARTH);
        }
    }
}
@@ -1355,7 +1443,7 @@
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        // This handles the hardware keyboard input
        if (event.isPrintingKey()) {
        if (event.isPrintingKey() || keyCode == KeyEvent.KEYCODE_SPACE) {
            if (event.getAction() == KeyEvent.ACTION_DOWN) {
                ic.commitText(String.valueOf((char) event.getUnicodeChar()), 1);
            }
@@ -1379,7 +1467,7 @@
        // As seen on StackOverflow: http://stackoverflow.com/questions/7634346/keyboard-hide-event
        // FIXME: Discussion at http://bugzilla.libsdl.org/show_bug.cgi?id=1639
        // FIXME: This is not a 100% effective solution to the problem of detecting if the keyboard is showing or not
        // FIXME: A more effective solution would be to change our Layout from AbsoluteLayout to Relative or Linear
        // FIXME: A more effective solution would be to assume our Layout to be RelativeLayout or LinearLayout
        // FIXME: And determine the keyboard presence doing this: http://stackoverflow.com/questions/2150078/how-to-check-visibility-of-software-keyboard-in-android
        // FIXME: An even more effective way would be if Android provided this out of the box, but where would the fun be in that :)
        if (event.getAction()==KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
@@ -1418,7 +1506,7 @@
         */
        int keyCode = event.getKeyCode();
        if (event.getAction() == KeyEvent.ACTION_DOWN) {
            if (event.isPrintingKey()) {
            if (event.isPrintingKey() || keyCode == KeyEvent.KEYCODE_SPACE) {
                commitText(String.valueOf((char) event.getUnicodeChar()), 1);
            }
            SDLActivity.onNativeKeyDown(keyCode);
@@ -1519,13 +1607,7 @@
            if (joystick == null) {
                joystick = new SDLJoystick();
                InputDevice joystickDevice = InputDevice.getDevice(deviceIds[i]);
                if (
                      (joystickDevice.getSources() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0
                   ||
                      (joystickDevice.getSources() & InputDevice.SOURCE_CLASS_BUTTON) != 0
                  )
                {
                if (SDLActivity.isDeviceSDLJoystick(deviceIds[i])) {
                    joystick.device_id = deviceIds[i];
                    joystick.name = joystickDevice.getName();
                    joystick.axes = new ArrayList<InputDevice.MotionRange>();
@@ -1534,7 +1616,7 @@
                    List<InputDevice.MotionRange> ranges = joystickDevice.getMotionRanges();
                    Collections.sort(ranges, new RangeComparator());
                    for (InputDevice.MotionRange range : ranges ) {
                        if ((range.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0 ) {
                        if ((range.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
                            if (range.getAxis() == MotionEvent.AXIS_HAT_X ||
                                range.getAxis() == MotionEvent.AXIS_HAT_Y) {
                                joystick.hats.add(range);
@@ -1588,7 +1670,7 @@
    @Override
    public boolean handleMotionEvent(MotionEvent event) {
        if ( (event.getSource() & InputDevice.SOURCE_JOYSTICK) != 0) {
        if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) != 0) {
            int actionPointerIndex = event.getActionIndex();
            int action = event.getActionMasked();
            switch(action) {
@@ -1627,8 +1709,7 @@
            case InputDevice.SOURCE_JOYSTICK:
            case InputDevice.SOURCE_GAMEPAD:
            case InputDevice.SOURCE_DPAD:
                SDLActivity.handleJoystickMotionEvent(event);
                return true;
                return SDLActivity.handleJoystickMotionEvent(event);
            case InputDevice.SOURCE_MOUSE:
                action = event.getActionMasked();
source/autogen.sh
@@ -3,6 +3,10 @@
echo "Generating build information using autoconf"
echo "This may take a while ..."
srcdir=`dirname $0`
test -z "$srcdir" && srcdir=.
pushd $srcdir
# Regenerate configuration files
cat acinclude/* >aclocal.m4
found=false
@@ -15,5 +19,7 @@
fi
(cd test; sh autogen.sh)
popd
# Run configure for this platform
echo "Now you are ready to run ./configure"
source/build-scripts/androidbuild.sh
@@ -87,8 +87,8 @@
fi
cp -r $SDLPATH/Android.mk $BUILDPATH/jni/SDL
sed -i "s|YourSourceHere.c|$MKSOURCES|g" $BUILDPATH/jni/src/Android.mk
sed -i "s|org\.libsdl\.app|$APP|g" $BUILDPATH/AndroidManifest.xml
sed -i -e "s|YourSourceHere.c|$MKSOURCES|g" $BUILDPATH/jni/src/Android.mk
sed -i -e "s|org\.libsdl\.app|$APP|g" $BUILDPATH/AndroidManifest.xml
# Copy user sources
for src in "${SOURCES[@]}"
@@ -105,8 +105,8 @@
done
ACTIVITY="${folder}Activity"
sed -i "s|SDLActivity|$ACTIVITY|g" $BUILDPATH/AndroidManifest.xml
sed -i "s|SDLActivity|$APP|g" $BUILDPATH/build.xml
sed -i -e "s|SDLActivity|$ACTIVITY|g" $BUILDPATH/AndroidManifest.xml
sed -i -e "s|SDLActivity|$APP|g" $BUILDPATH/build.xml
# Fill in a default Activity
echo "package $APP;" >  "$ACTIVITY.java"
source/build-scripts/checker-buildbot.sh
@@ -61,13 +61,13 @@
cd checker-buildbot
# You might want to do this for CMake-backed builds instead...
PATH="$CHECKERDIR:$PATH" scan-build -o analysis cmake -DCMAKE_BUILD_TYPE=Debug ..
PATH="$CHECKERDIR:$PATH" scan-build -o analysis cmake -DCMAKE_BUILD_TYPE=Debug -DASSERTIONS=enabled ..
# ...or run configure without the scan-build wrapper...
#CC="$CHECKERDIR/libexec/ccc-analyzer" CFLAGS="-O0" ../configure
#CC="$CHECKERDIR/libexec/ccc-analyzer" CFLAGS="-O0" ../configure --enable-assertions=enabled
# ...but this works for our buildbots just fine (EXCEPT ON LATEST MAC OS X).
#CFLAGS="-O0" PATH="$CHECKERDIR:$PATH" scan-build -o analysis ../configure
#CFLAGS="-O0" PATH="$CHECKERDIR:$PATH" scan-build -o analysis ../configure --enable-assertions=enabled
rm -rf analysis
PATH="$CHECKERDIR:$PATH" scan-build -o analysis $MAKE
source/build-scripts/emscripten-buildbot.sh
@@ -51,13 +51,14 @@
pushd buildbot
echo "Configuring..."
emconfigure ../configure --host=asmjs-unknown-emscripten --disable-assembly --disable-threads --enable-cpuinfo=false CFLAGS="-O2 -Wno-warn-absolute-paths -Wdeclaration-after-statement -Werror=declaration-after-statement" --prefix="$PWD/emscripten-sdl2-installed"
emconfigure ../configure --host=asmjs-unknown-emscripten --disable-assembly --disable-threads --enable-cpuinfo=false CFLAGS="-O2 -Wno-warn-absolute-paths -Wdeclaration-after-statement -Werror=declaration-after-statement" --prefix="$PWD/emscripten-sdl2-installed" || exit $?
echo "Building..."
emmake $MAKE
emmake $MAKE || exit $?
echo "Moving things around..."
emmake $MAKE install
emmake $MAKE install || exit $?
# Fix up a few things to a real install path
perl -w -pi -e "s#$PWD/emscripten-sdl2-installed#/usr/local#g;" ./emscripten-sdl2-installed/lib/libSDL2.la ./emscripten-sdl2-installed/lib/pkgconfig/sdl2.pc ./emscripten-sdl2-installed/bin/sdl2-config
mkdir -p ./usr
source/build-scripts/g++-fat.sh
@@ -6,11 +6,11 @@
DEVELOPER="`xcode-select -print-path`/Platforms/MacOSX.platform/Developer"
# Intel 32-bit compiler flags (10.5 runtime compatibility)
GCC_COMPILE_X86="g++ -arch i386 -mmacosx-version-min=10.5 \
# Intel 32-bit compiler flags (10.6 runtime compatibility)
GCC_COMPILE_X86="g++ -arch i386 -mmacosx-version-min=10.6 \
-I/usr/local/include"
GCC_LINK_X86="-mmacosx-version-min=10.5"
GCC_LINK_X86="-mmacosx-version-min=10.6"
# Intel 64-bit compiler flags (10.6 runtime compatibility)
GCC_COMPILE_X64="g++ -arch x86_64 -mmacosx-version-min=10.6 \
source/build-scripts/gcc-fat.sh
@@ -6,15 +6,15 @@
DEVELOPER="`xcode-select -print-path`/Platforms/MacOSX.platform/Developer"
# Intel 32-bit compiler flags (10.5 runtime compatibility)
GCC_COMPILE_X86="gcc -arch i386 -mmacosx-version-min=10.5 \
# Intel 32-bit compiler flags (10.6 runtime compatibility)
GCC_COMPILE_X86="gcc -arch i386 -mmacosx-version-min=10.6 \
-I/usr/local/include"
GCC_LINK_X86="-mmacosx-version-min=10.5"
GCC_LINK_X86="-mmacosx-version-min=10.6"
# Intel 64-bit compiler flags (10.6 runtime compatibility)
GCC_COMPILE_X64="gcc -arch x86_64 -mmacosx-version-min=10.6 \
-DMAC_OS_X_VERSION_MIN_REQUIRED=1050 \
-DMAC_OS_X_VERSION_MIN_REQUIRED=1060 \
-I/usr/local/include"
GCC_LINK_X64="-mmacosx-version-min=10.6"
source/build-scripts/showrev.sh
@@ -2,6 +2,4 @@
#
# Print the current source revision, if available
# FIXME: this prints the tip, which isn't useful if you're on a different
#  branch, or just not sync'd to the tip.
hg tip --template 'hg-{rev}:{node|short}' || (echo "hg-0:baadf00d"; exit 1)
hg parents --template 'hg-{rev}:{node|short}' || (echo "hg-0:baadf00d"; exit 1)
source/cmake/sdlchecks.cmake
@@ -105,7 +105,9 @@
  if(ALSA)
    CHECK_INCLUDE_FILE(alsa/asoundlib.h HAVE_ASOUNDLIB_H)
    if(HAVE_ASOUNDLIB_H)
      CHECK_LIBRARY_EXISTS(asound snd_pcm_open "" HAVE_LIBASOUND)
      CHECK_LIBRARY_EXISTS(asound snd_pcm_recover "" HAVE_LIBASOUND)
    endif()
    if(HAVE_LIBASOUND)
      set(HAVE_ALSA TRUE)
      file(GLOB ALSA_SOURCES ${SDL2_SOURCE_DIR}/src/audio/alsa/*.c)
      set(SOURCE_FILES ${SOURCE_FILES} ${ALSA_SOURCES})
@@ -537,6 +539,27 @@
    endif()
endmacro()
macro(WaylandProtocolGen _SCANNER _XML _PROTL)
    set(_WAYLAND_PROT_C_CODE "${CMAKE_CURRENT_BINARY_DIR}/wayland-generated-protocols/${_PROTL}-protocol.c")
    set(_WAYLAND_PROT_H_CODE "${CMAKE_CURRENT_BINARY_DIR}/wayland-generated-protocols/${_PROTL}-client-protocol.h")
    add_custom_command(
        OUTPUT "${_WAYLAND_PROT_H_CODE}"
        DEPENDS "${_XML}"
        COMMAND "${_SCANNER}"
        ARGS client-header "${_XML}" "${_WAYLAND_PROT_H_CODE}"
    )
    add_custom_command(
        OUTPUT "${_WAYLAND_PROT_C_CODE}"
        DEPENDS "${_WAYLAND_PROT_H_CODE}"
        COMMAND "${_SCANNER}"
        ARGS code "${_XML}" "${_WAYLAND_PROT_C_CODE}"
    )
    set(SOURCE_FILES ${SOURCE_FILES} "${CMAKE_CURRENT_BINARY_DIR}/wayland-generated-protocols/${_PROTL}-protocol.c")
endmacro()
# Requires:
# - EGL
# - PkgCheckModules
@@ -545,7 +568,51 @@
# - HAVE_DLOPEN opt
macro(CheckWayland)
  if(VIDEO_WAYLAND)
    pkg_check_modules(WAYLAND wayland-client wayland-cursor wayland-egl egl xkbcommon)
    pkg_check_modules(WAYLAND wayland-client wayland-scanner wayland-protocols wayland-egl wayland-cursor egl xkbcommon)
    # We have to generate some protocol interface code for some various Wayland features.
    if(WAYLAND_FOUND)
      execute_process(
        COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=pkgdatadir wayland-client
        WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
        RESULT_VARIABLE WAYLAND_CORE_PROTOCOL_DIR_RC
        OUTPUT_VARIABLE WAYLAND_CORE_PROTOCOL_DIR
        ERROR_QUIET
        OUTPUT_STRIP_TRAILING_WHITESPACE
      )
      if(NOT WAYLAND_CORE_PROTOCOL_DIR_RC EQUAL 0)
        set(WAYLAND_FOUND FALSE)
      endif()
    endif()
    if(WAYLAND_FOUND)
      execute_process(
        COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=pkgdatadir wayland-protocols
        WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
        RESULT_VARIABLE WAYLAND_PROTOCOLS_DIR_RC
        OUTPUT_VARIABLE WAYLAND_PROTOCOLS_DIR
        ERROR_QUIET
        OUTPUT_STRIP_TRAILING_WHITESPACE
      )
      if(NOT WAYLAND_PROTOCOLS_DIR_RC EQUAL 0)
        set(WAYLAND_FOUND FALSE)
      endif()
    endif()
    if(WAYLAND_FOUND)
      execute_process(
        COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=wayland_scanner wayland-scanner
        WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
        RESULT_VARIABLE WAYLAND_SCANNER_RC
        OUTPUT_VARIABLE WAYLAND_SCANNER
        ERROR_QUIET
        OUTPUT_STRIP_TRAILING_WHITESPACE
      )
      if(NOT WAYLAND_SCANNER_RC EQUAL 0)
        set(WAYLAND_FOUND FALSE)
      endif()
    endif()
    if(WAYLAND_FOUND)
      link_directories(
          ${WAYLAND_LIBRARY_DIRS}
@@ -558,6 +625,17 @@
      file(GLOB WAYLAND_SOURCES ${SDL2_SOURCE_DIR}/src/video/wayland/*.c)
      set(SOURCE_FILES ${SOURCE_FILES} ${WAYLAND_SOURCES})
      # We have to generate some protocol interface code for some unstable Wayland features.
      file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/wayland-generated-protocols")
      include_directories("${CMAKE_CURRENT_BINARY_DIR}/wayland-generated-protocols")
      WaylandProtocolGen("${WAYLAND_SCANNER}" "${WAYLAND_CORE_PROTOCOL_DIR}/wayland.xml" "wayland")
      foreach(_PROTL relative-pointer-unstable-v1 pointer-constraints-unstable-v1)
        string(REGEX REPLACE "\\-unstable\\-.*$" "" PROTSUBDIR ${_PROTL})
        WaylandProtocolGen("${WAYLAND_SCANNER}" "${WAYLAND_PROTOCOLS_DIR}/unstable/${PROTSUBDIR}/${_PROTL}.xml" "${_PROTL}")
      endforeach()
      if(VIDEO_WAYLAND_QT_TOUCH)
          set(SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH 1)
@@ -679,7 +757,6 @@
      set(SDL_VIDEO_OPENGL 1)
      set(SDL_VIDEO_OPENGL_GLX 1)
      set(SDL_VIDEO_RENDER_OGL 1)
      list(APPEND EXTRA_LIBS GL)
    endif()
  endif()
endmacro()
@@ -767,7 +844,8 @@
    endif()
    # Run some tests
    set(CMAKE_REQUIRED_FLAGS "${PTHREAD_CFLAGS} ${PTHREAD_LDFLAGS}")
    set(ORIG_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
    set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${PTHREAD_CFLAGS} ${PTHREAD_LDFLAGS}")
    if(CMAKE_CROSSCOMPILING)
      set(HAVE_PTHREADS 1)
    else()
@@ -829,7 +907,7 @@
          int main(int argc, char** argv) { return 0; }" HAVE_PTHREAD_NP_H)
      check_function_exists(pthread_setname_np HAVE_PTHREAD_SETNAME_NP)
      check_function_exists(pthread_set_name_np HAVE_PTHREAD_SET_NAME_NP)
      set(CMAKE_REQUIRED_FLAGS)
      set(CMAKE_REQUIRED_FLAGS "${ORIG_CMAKE_REQUIRED_FLAGS}")
      set(SOURCE_FILES ${SOURCE_FILES}
          ${SDL2_SOURCE_DIR}/src/thread/pthread/SDL_systhread.c
@@ -883,7 +961,8 @@
    endif()
  endif()
  set(CMAKE_REQUIRED_FLAGS "${USB_CFLAGS}")
  set(ORIG_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
  set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${USB_CFLAGS}")
  set(CMAKE_REQUIRED_LIBRARIES "${USB_LIBS}")
  check_c_source_compiles("
       #include <sys/types.h>
@@ -984,7 +1063,7 @@
    set(HAVE_SDL_JOYSTICK TRUE)
    set(CMAKE_REQUIRED_LIBRARIES)
    set(CMAKE_REQUIRED_FLAGS)
    set(CMAKE_REQUIRED_FLAGS "${ORIG_CMAKE_REQUIRED_FLAGS}")
  endif()
endmacro()
@@ -998,12 +1077,13 @@
    listtostr(VIDEO_RPI_INCLUDE_DIRS VIDEO_RPI_INCLUDE_FLAGS "-I")
    listtostr(VIDEO_RPI_LIBRARY_DIRS VIDEO_RPI_LIBRARY_FLAGS "-L")
    set(CMAKE_REQUIRED_FLAGS "${VIDEO_RPI_INCLUDE_FLAGS} ${VIDEO_RPI_LIBRARY_FLAGS}")
    set(ORIG_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
    set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${VIDEO_RPI_INCLUDE_FLAGS} ${VIDEO_RPI_LIBRARY_FLAGS}")
    set(CMAKE_REQUIRED_LIBRARIES "${VIDEO_RPI_LIBS}")
    check_c_source_compiles("
        #include <bcm_host.h>
        int main(int argc, char **argv) {}" HAVE_VIDEO_RPI)
    set(CMAKE_REQUIRED_FLAGS)
    set(CMAKE_REQUIRED_FLAGS "${ORIG_CMAKE_REQUIRED_FLAGS}")
    set(CMAKE_REQUIRED_LIBRARIES)
    if(SDL_VIDEO AND HAVE_VIDEO_RPI)
source/configure
@@ -630,6 +630,7 @@
#endif"
ac_subst_vars='LTLIBOBJS
WAYLAND_SCANNER
EXTRA_LDFLAGS
BUILD_LDFLAGS
EXTRA_CFLAGS
@@ -637,6 +638,8 @@
SDLTEST_OBJECTS
SDLMAIN_OBJECTS
VERSION_OBJECTS
GEN_OBJECTS
GEN_HEADERS
OBJECTS
INCLUDE
ac_aux_dir
@@ -846,7 +849,9 @@
enable_video_opengles2
enable_libudev
enable_dbus
enable_ime
enable_ibus
enable_fcitx
enable_input_tslib
enable_pthreads
enable_pthread_sem
@@ -1584,7 +1589,9 @@
                          include OpenGL ES 2.0 support [[default=yes]]
  --enable-libudev        enable libudev support [[default=yes]]
  --enable-dbus           enable D-Bus support [[default=yes]]
  --enable-ime            enable IME support [[default=yes]]
  --enable-ibus           enable IBus support [[default=yes]]
  --enable-fcitx          enable fcitx support [[default=yes]]
  --enable-input-tslib    use the Touchscreen library for input
                          [[default=yes]]
  --enable-pthreads       use POSIX threads for multi-threading
@@ -2683,9 +2690,9 @@
#
SDL_MAJOR_VERSION=2
SDL_MINOR_VERSION=0
SDL_MICRO_VERSION=4
SDL_INTERFACE_AGE=0
SDL_BINARY_AGE=4
SDL_MICRO_VERSION=5
SDL_INTERFACE_AGE=1
SDL_BINARY_AGE=5
SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION
@@ -17601,7 +17608,7 @@
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ALSA_LIBS" >&5
$as_echo "$ALSA_LIBS" >&6; }
min_alsa_version=0.9.0
min_alsa_version=1.0.11
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libasound headers version >= $min_alsa_version" >&5
$as_echo_n "checking for libasound headers version >= $min_alsa_version... " >&6; }
no_alsa=""
@@ -18650,6 +18657,43 @@
    fi
}
CheckDeclarationAfterStatement()
{
    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC -Wdeclaration-after-statement option" >&5
$as_echo_n "checking for GCC -Wdeclaration-after-statement option... " >&6; }
    have_gcc_declaration_after_statement=no
    save_CFLAGS="$CFLAGS"
    CFLAGS="$save_CFLAGS -Wdeclaration-after-statement -Werror=declaration-after-statement"
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
    int x = 0;
int
main ()
{
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
    have_gcc_declaration_after_statement=yes
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_gcc_declaration_after_statement" >&5
$as_echo "$have_gcc_declaration_after_statement" >&6; }
    CFLAGS="$save_CFLAGS"
    if test x$have_gcc_declaration_after_statement = xyes; then
        EXTRA_CFLAGS="$EXTRA_CFLAGS -Wdeclaration-after-statement -Werror=declaration-after-statement"
    fi
}
CheckWarnAll()
{
    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GCC -Wall option" >&5
@@ -18767,9 +18811,12 @@
        if  test x$PKG_CONFIG != xno && \
            test x$video_opengl_egl = xyes && \
            test x$video_opengles_v2 = xyes; then
            if $PKG_CONFIG --exists wayland-client wayland-egl wayland-cursor egl xkbcommon ; then
            if $PKG_CONFIG --exists wayland-client wayland-scanner wayland-protocols wayland-egl wayland-cursor egl xkbcommon ; then
                WAYLAND_CFLAGS=`$PKG_CONFIG --cflags wayland-client wayland-egl wayland-cursor xkbcommon`
                WAYLAND_LIBS=`$PKG_CONFIG --libs wayland-client wayland-egl wayland-cursor xkbcommon`
                WAYLAND_SCANNER=`$PKG_CONFIG --variable=wayland_scanner wayland-scanner`
                WAYLAND_CORE_PROTOCOL_DIR=`$PKG_CONFIG --variable=pkgdatadir wayland-client`
                WAYLAND_PROTOCOLS_DIR=`$PKG_CONFIG --variable=pkgdatadir wayland-protocols`
                video_wayland=yes
            fi
        fi
@@ -18785,8 +18832,11 @@
$as_echo "#define SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH 1" >>confdefs.h
            fi
            WAYLAND_PROTOCOLS_UNSTABLE="relative-pointer-unstable-v1 pointer-constraints-unstable-v1"
            SOURCES="$SOURCES $srcdir/src/video/wayland/*.c"
            EXTRA_CFLAGS="$EXTRA_CFLAGS $WAYLAND_CFLAGS"
            EXTRA_CFLAGS="$EXTRA_CFLAGS $WAYLAND_CFLAGS -I\$(gen)"
            # Check whether --enable-wayland-shared was given.
if test "${enable_wayland_shared+set}" = set; then :
  enableval=$enable_wayland_shared;
@@ -18928,7 +18978,7 @@
main ()
{
                    MirMotionToolType tool = mir_motion_tool_type_mouse;
                    MirTouchAction actions = mir_touch_actions
  ;
  return 0;
@@ -21604,6 +21654,23 @@
    fi
}
CheckIME()
{
    # Check whether --enable-ime was given.
if test "${enable_ime+set}" = set; then :
  enableval=$enable_ime;
else
  enable_ime=yes
fi
    if test x$enable_ime = xyes; then
$as_echo "#define SDL_USE_IME 1" >>confdefs.h
            SOURCES="$SOURCES $srcdir/src/core/linux/SDL_ime.c"
    fi
}
CheckIBus()
{
    # Check whether --enable-ibus was given.
@@ -21677,7 +21744,11 @@
            CFLAGS="$save_CFLAGS"
            if test x$have_ibus_ibus_h_hdr = xyes; then
                if test x$enable_dbus != xyes; then
                if test x$enable_ime != xyes; then
                    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: IME support is required for IBus." >&5
$as_echo "$as_me: WARNING: IME support is required for IBus." >&2;}
                    have_ibus_ibus_h_hdr=no
                elif test x$enable_dbus != xyes; then
                    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: DBus support is required for IBus." >&5
$as_echo "$as_me: WARNING: DBus support is required for IBus." >&2;}
                    have_ibus_ibus_h_hdr=no
@@ -21691,6 +21762,90 @@
                    EXTRA_CFLAGS="$EXTRA_CFLAGS $IBUS_CFLAGS"
                    SOURCES="$SOURCES $srcdir/src/core/linux/SDL_ibus.c"
               fi
            fi
        fi
    fi
}
CheckFcitx()
{
    # Check whether --enable-fcitx was given.
if test "${enable_fcitx+set}" = set; then :
  enableval=$enable_fcitx;
else
  enable_fcitx=yes
fi
    if test x$enable_fcitx = xyes; then
        # 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_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
  test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no"
  ;;
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
        if test x$PKG_CONFIG != xno; then
            FCITX_CFLAGS=`$PKG_CONFIG --cflags fcitx`
            CFLAGS="$CFLAGS $FCITX_CFLAGS"
            ac_fn_c_check_header_mongrel "$LINENO" "fcitx/frontend.h" "ac_cv_header_fcitx_frontend_h" "$ac_includes_default"
if test "x$ac_cv_header_fcitx_frontend_h" = xyes; then :
  have_fcitx_frontend_h_hdr=yes
else
  have_fcitx_frontend_h_hdr=no
fi
            CFLAGS="$save_CFLAGS"
            if test x$have_fcitx_frontend_h_hdr = xyes; then
                if test x$enable_ime != xyes; then
                    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: IME support is required for fcitx." >&5
$as_echo "$as_me: WARNING: IME support is required for fcitx." >&2;}
                    have_fcitx_frontend_h_hdr=no
                elif test x$enable_dbus != xyes; then
                    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: DBus support is required for fcitx." >&5
$as_echo "$as_me: WARNING: DBus support is required for fcitx." >&2;}
                    have_fcitx_frontend_h_hdr=no
                else
$as_echo "#define HAVE_FCITX_FRONTEND_H 1" >>confdefs.h
                    EXTRA_CFLAGS="$EXTRA_CFLAGS $FCITX_CFLAGS"
                    SOURCES="$SOURCES $srcdir/src/core/linux/SDL_fcitx.c"
               fi
            fi
        fi
@@ -22894,6 +23049,8 @@
}
CheckWarnAll
case "$host" in
    *-*-linux*|*-*-uclinux*|*-*-gnu*|*-*-k*bsd*-gnu|*-*-bsdi*|*-*-freebsd*|*-*-dragonfly*|*-*-netbsd*|*-*-openbsd*|*-*-sysv5*|*-*-solaris*|*-*-hpux*|*-*-aix*|*-*-minix*)
        case "$host" in
@@ -22962,6 +23119,7 @@
            *-*-minix*)         ARCH=minix ;;
        esac
        CheckVisibilityHidden
        CheckDeclarationAfterStatement
        CheckDummyVideo
        CheckDiskAudio
        CheckDummyAudio
@@ -22982,7 +23140,9 @@
        CheckWayland
        CheckLibUDev
        CheckDBus
        CheckIME
        CheckIBus
        CheckFcitx
        case $ARCH in
          linux)
              CheckInputEvents
@@ -23392,6 +23552,7 @@
        ARCH=ios
        CheckVisibilityHidden
        CheckDeclarationAfterStatement
        CheckDummyVideo
        CheckDiskAudio
        CheckDummyAudio
@@ -23402,7 +23563,7 @@
        # Set up files for the audio library
        if test x$enable_audio = xyes; then
            SOURCES="$SOURCES $srcdir/src/audio/coreaudio/*.c"
            SOURCES="$SOURCES $srcdir/src/audio/coreaudio/*.m"
            SUMMARY_audio="${SUMMARY_audio} coreaudio"
            have_audio=yes
        fi
@@ -23461,6 +23622,7 @@
        EXTRA_CFLAGS="$EXTRA_CFLAGS -DTARGET_API_MAC_OSX"
        CheckVisibilityHidden
        CheckDeclarationAfterStatement
        CheckDummyVideo
        CheckDiskAudio
        CheckDummyAudio
@@ -23476,7 +23638,8 @@
$as_echo "#define SDL_AUDIO_DRIVER_COREAUDIO 1" >>confdefs.h
            SOURCES="$SOURCES $srcdir/src/audio/coreaudio/*.c"
            SOURCES="$SOURCES $srcdir/src/audio/coreaudio/*.m"
            EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,CoreAudio -Wl,-framework,AudioToolbox"
            SUMMARY_audio="${SUMMARY_audio} coreaudio"
            have_audio=yes
        fi
@@ -23494,8 +23657,8 @@
$as_echo "#define SDL_HAPTIC_IOKIT 1" >>confdefs.h
            SOURCES="$SOURCES $srcdir/src/haptic/darwin/*.c"
            have_haptic=yes
            EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,ForceFeedback"
            have_haptic=yes
        fi
        # Set up files for the power library
        if test x$enable_power = xyes; then
@@ -23532,10 +23695,6 @@
        EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,Cocoa"
        EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,Carbon"
        EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,IOKit"
        # If audio is used, add the AudioUnit framework
        if test x$enable_audio = xyes; then
            EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,CoreAudio -Wl,-framework,AudioToolbox -Wl,-framework,AudioUnit"
        fi
        ;;
    *-nacl|*-pnacl)
        ARCH=nacl
@@ -23581,6 +23740,7 @@
        fi
        CheckVisibilityHidden
        CheckDeclarationAfterStatement
        CheckDummyVideo
        CheckDiskAudio
        CheckDummyAudio
@@ -23629,8 +23789,6 @@
        " "$LINENO" 5
        ;;
esac
CheckWarnAll
# Verify that we have all the platform specific files we need
@@ -23687,6 +23845,57 @@
fi
SDLTEST_SOURCES="$srcdir/src/test/*.c"
if test x$video_wayland = xyes; then
    WAYLAND_CORE_PROTOCOL_SOURCE='$(gen)/wayland-protocol.c'
    WAYLAND_CORE_PROTOCOL_HEADER='$(gen)/wayland-client-protocol.h'
    WAYLAND_PROTOCOLS_UNSTABLE_SOURCES=`echo $WAYLAND_PROTOCOLS_UNSTABLE |\
        sed 's,[^ ]\+,\\$(gen)/&-protocol.c,g'`
    WAYLAND_PROTOCOLS_UNSTABLE_HEADERS=`echo $WAYLAND_PROTOCOLS_UNSTABLE |\
        sed 's,[^ ]\+,\\$(gen)/&-client-protocol.h,g'`
    GEN_SOURCES="$GEN_SOURCES $WAYLAND_CORE_PROTOCOL_SOURCE $WAYLAND_PROTOCOLS_UNSTABLE_SOURCES"
    GEN_HEADERS="$GEN_HEADERS $WAYLAND_CORE_PROTOCOL_HEADER $WAYLAND_PROTOCOLS_UNSTABLE_HEADERS"
    WAYLAND_CORE_PROTOCOL_SOURCE_DEPENDS="
$WAYLAND_CORE_PROTOCOL_SOURCE: $WAYLAND_CORE_PROTOCOL_DIR/wayland.xml
    \$(SHELL) \$(auxdir)/mkinstalldirs \$(gen)
    \$(RUN_CMD_GEN)\$(WAYLAND_SCANNER) code \$< \$@"
    WAYLAND_CORE_PROTOCOL_HEADER_DEPENDS="
$WAYLAND_CORE_PROTOCOL_HEADER: $WAYLAND_CORE_PROTOCOL_DIR/wayland.xml
    \$(SHELL) \$(auxdir)/mkinstalldirs \$(gen)
    \$(RUN_CMD_GEN)\$(WAYLAND_SCANNER) client-header \$< \$@"
    WAYLAND_CORE_PROTOCOL_OBJECT="
\$(objects)/`echo $WAYLAND_CORE_PROTOCOL_SOURCE | sed 's/\$(gen)\/\(.*\).c$/\1.lo/'`: $WAYLAND_CORE_PROTOCOL_SOURCE
    \$(RUN_CMD_CC)\$(LIBTOOL) --tag=CC --mode=compile \$(CC) \$(CFLAGS) \$(EXTRA_CFLAGS) $DEPENDENCY_TRACKING_OPTIONS -c \$< -o \$@"
    WAYLAND_PROTOCOLS_CLIENT_HEADER_UNSTABLE_DEPENDS=`for p in $WAYLAND_PROTOCOLS_UNSTABLE;\
        do echo ; echo \$p | sed\
        "s,^\\([a-z\\-]\\+\\)-unstable-\\(v[0-9]\+\\)\$,\\$(gen)/&-client-protocol.h: $WAYLAND_PROTOCOLS_DIR/unstable/\1/&.xml\\\\
    \\$(SHELL) \\$(auxdir)/mkinstalldirs \\$(gen)\\\\
    \\$(RUN_CMD_GEN)\\$(WAYLAND_SCANNER) client-header \\$< \\$@," ; done`
    WAYLAND_PROTOCOLS_CODE_UNSTABLE_DEPENDS=`for p in $WAYLAND_PROTOCOLS_UNSTABLE;\
        do echo ; echo \$p | sed\
        "s,^\\([a-z\\-]\\+\\)-unstable-\\(v[0-9]\+\\)\$,\\$(gen)/&-protocol.c: $WAYLAND_PROTOCOLS_DIR/unstable/\1/&.xml\\\\
    \\$(SHELL) \\$(auxdir)/mkinstalldirs \\$(gen)\\\\
    \\$(RUN_CMD_GEN)\\$(WAYLAND_SCANNER) code \\$< \\$@," ; done`
    WAYLAND_PROTOCOLS_OBJECTS_UNSTABLE=`for p in $WAYLAND_PROTOCOLS_UNSTABLE;\
        do echo ; echo \$p | sed\
        "s,^\\([a-z\\-]\\+\\)-unstable-\\(v[0-9]\+\\)\$,\\\$(objects)/&-protocol.lo: \\$(gen)/&-protocol.c \\$(gen)/&-client-protocol.h\\\\
    \\$(RUN_CMD_CC)\\$(LIBTOOL) --tag=CC --mode=compile \\$(CC) \\$(CFLAGS) \\$(EXTRA_CFLAGS) $DEPENDENCY_TRACKING_OPTIONS -c \\$< -o \\$@," ; done`
    WAYLAND_PROTOCOLS_DEPENDS="
$WAYLAND_CORE_PROTOCOL_SOURCE_DEPENDS
$WAYLAND_CORE_PROTOCOL_HEADER_DEPENDS
$WAYLAND_CORE_PROTOCOL_OBJECT
$WAYLAND_PROTOCOLS_CLIENT_HEADER_UNSTABLE_DEPENDS
$WAYLAND_PROTOCOLS_CODE_UNSTABLE_DEPENDS
$WAYLAND_PROTOCOLS_OBJECTS_UNSTABLE
"
fi
OBJECTS=`echo $SOURCES`
DEPENDS=`echo $SOURCES | tr ' ' '\n'`
for EXT in asm cc m c S; do
@@ -23695,6 +23904,8 @@
\\$(objects)/\\2.lo: \\1/\\2.$EXT\\\\
    \\$(RUN_CMD_CC)\\$(LIBTOOL) --tag=CC --mode=compile \\$(CC) \\$(CFLAGS) \\$(EXTRA_CFLAGS) $DEPENDENCY_TRACKING_OPTIONS -c \\$< -o \\$@,g"`
done
GEN_OBJECTS=`echo "$GEN_SOURCES" | sed 's,[^ ]*/\([^ ]*\)\.c,$(objects)/\1.lo,g'`
VERSION_OBJECTS=`echo $VERSION_SOURCES`
VERSION_DEPENDS=`echo $VERSION_SOURCES`
@@ -23722,6 +23933,36 @@
if test "x$enable_rpath" = "xyes"; then
  if test $ARCH = bsdi -o $ARCH = freebsd -o $ARCH = linux -o $ARCH = netbsd; then
    SDL_RLD_FLAGS="-Wl,-rpath,\${libdir}"
    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for linker option --enable-new-dtags" >&5
$as_echo_n "checking for linker option --enable-new-dtags... " >&6; }
    have_enable_new_dtags=no
    save_LDFLAGS="$LDFLAGS"
    LDFLAGS="$LDFLAGS -Wl,--enable-new-dtags"
    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
int
main ()
{
  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
    have_enable_new_dtags=yes
    SDL_RLD_FLAGS="$SDL_RLD_FLAGS -Wl,--enable-new-dtags"
fi
rm -f core conftest.err conftest.$ac_objext \
    conftest$ac_exeext conftest.$ac_ext
    LDFLAGS="$save_LDFLAGS"
    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_enable_new_dtags" >&5
$as_echo "$have_enable_new_dtags" >&6; }
  fi
  if test $ARCH = solaris; then
    SDL_RLD_FLAGS="-R\${libdir}"
@@ -23767,6 +24008,9 @@
cat >Makefile.rules <<__EOF__
# Build rules for objects
@@ -23778,6 +24022,7 @@
$VERSION_DEPENDS
$SDLMAIN_DEPENDS
$SDLTEST_DEPENDS
$WAYLAND_PROTOCOLS_DEPENDS
__EOF__
ac_config_files="$ac_config_files Makefile:Makefile.in:Makefile.rules sdl2-config sdl2-config.cmake SDL2.spec sdl2.pc"
@@ -23810,11 +24055,21 @@
else
    SUMMARY="${SUMMARY}Using dbus      : NO\n"
fi
if test x$enable_ime = xyes; then
    SUMMARY="${SUMMARY}Using ime       : YES\n"
else
    SUMMARY="${SUMMARY}Using ime       : NO\n"
fi
if test x$have_ibus_ibus_h_hdr = xyes; then
    SUMMARY="${SUMMARY}Using ibus      : YES\n"
else
    SUMMARY="${SUMMARY}Using ibus      : NO\n"
fi
if test x$have_fcitx_frontend_h_hdr = xyes; then
    SUMMARY="${SUMMARY}Using fcitx     : YES\n"
else
    SUMMARY="${SUMMARY}Using fcitx     : NO\n"
fi
ac_config_commands="$ac_config_commands summary"
source/configure.in
@@ -20,9 +20,9 @@
#
SDL_MAJOR_VERSION=2
SDL_MINOR_VERSION=0
SDL_MICRO_VERSION=4
SDL_INTERFACE_AGE=0
SDL_BINARY_AGE=4
SDL_MICRO_VERSION=5
SDL_INTERFACE_AGE=1
SDL_BINARY_AGE=5
SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION
AC_SUBST(SDL_MAJOR_VERSION)
@@ -770,7 +770,7 @@
AC_HELP_STRING([--enable-alsa], [support the ALSA audio API [[default=yes]]]),
                  , enable_alsa=yes)
    if test x$enable_audio = xyes -a x$enable_alsa = xyes; then
        AM_PATH_ALSA(0.9.0, have_alsa=yes, have_alsa=no)
        AM_PATH_ALSA(1.0.11, have_alsa=yes, have_alsa=no)
        # Restore all flags from before the ALSA detection runs
        CFLAGS="$alsa_save_CFLAGS"
        LDFLAGS="$alsa_save_LDFLAGS"
@@ -1124,6 +1124,30 @@
    fi
}
dnl See if GCC's -Wdeclaration-after-statement is supported.
dnl  This lets us catch things that would fail on a C89 compiler when using
dnl  a modern GCC.
CheckDeclarationAfterStatement()
{
    AC_MSG_CHECKING(for GCC -Wdeclaration-after-statement option)
    have_gcc_declaration_after_statement=no
    save_CFLAGS="$CFLAGS"
    CFLAGS="$save_CFLAGS -Wdeclaration-after-statement -Werror=declaration-after-statement"
    AC_TRY_COMPILE([
    int x = 0;
    ],[
    ],[
    have_gcc_declaration_after_statement=yes
    ])
    AC_MSG_RESULT($have_gcc_declaration_after_statement)
    CFLAGS="$save_CFLAGS"
    if test x$have_gcc_declaration_after_statement = xyes; then
        EXTRA_CFLAGS="$EXTRA_CFLAGS -Wdeclaration-after-statement -Werror=declaration-after-statement"
    fi
}
dnl See if GCC's -Wall is supported.
CheckWarnAll()
{
@@ -1177,9 +1201,12 @@
        if  test x$PKG_CONFIG != xno && \
            test x$video_opengl_egl = xyes && \
            test x$video_opengles_v2 = xyes; then
            if $PKG_CONFIG --exists wayland-client wayland-egl wayland-cursor egl xkbcommon ; then
            if $PKG_CONFIG --exists wayland-client wayland-scanner wayland-protocols wayland-egl wayland-cursor egl xkbcommon ; then
                WAYLAND_CFLAGS=`$PKG_CONFIG --cflags wayland-client wayland-egl wayland-cursor xkbcommon`
                WAYLAND_LIBS=`$PKG_CONFIG --libs wayland-client wayland-egl wayland-cursor xkbcommon`
                WAYLAND_SCANNER=`$PKG_CONFIG --variable=wayland_scanner wayland-scanner`
                WAYLAND_CORE_PROTOCOL_DIR=`$PKG_CONFIG --variable=pkgdatadir wayland-client`
                WAYLAND_PROTOCOLS_DIR=`$PKG_CONFIG --variable=pkgdatadir wayland-protocols`
                video_wayland=yes
            fi
        fi
@@ -1190,8 +1217,11 @@
            if test x$enable_video_wayland_qt_touch = xyes; then
                AC_DEFINE(SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH, 1, [ ])
            fi
            WAYLAND_PROTOCOLS_UNSTABLE="relative-pointer-unstable-v1 pointer-constraints-unstable-v1"
            SOURCES="$SOURCES $srcdir/src/video/wayland/*.c"
            EXTRA_CFLAGS="$EXTRA_CFLAGS $WAYLAND_CFLAGS"
            EXTRA_CFLAGS="$EXTRA_CFLAGS $WAYLAND_CFLAGS -I\$(gen)"
            AC_ARG_ENABLE(wayland-shared,
AC_HELP_STRING([--enable-wayland-shared], [dynamically load Wayland support [[default=maybe]]]),
                          , enable_wayland_shared=maybe)
@@ -1260,12 +1290,12 @@
                MIR_LIBS=`$PKG_CONFIG --libs mirclient egl xkbcommon`
                save_CFLAGS="$CFLAGS"
                CFLAGS="$save_CFLAGS $MIR_CFLAGS"
                dnl This will disable Mir on Ubuntu < 14.04
                dnl This will disable Mir if >= v0.25 is not available
                AC_TRY_COMPILE([
                #include <mir_toolkit/mir_client_library.h>
                ],[
                    MirMotionToolType tool = mir_motion_tool_type_mouse;
                    MirTouchAction actions = mir_touch_actions
                ],[
                video_mir=yes
                ])
@@ -2230,6 +2260,18 @@
    fi
}
dnl See if the platform wanna IME support.
CheckIME()
{
    AC_ARG_ENABLE(ime,
AC_HELP_STRING([--enable-ime], [enable IME support [[default=yes]]]),
                  , enable_ime=yes)
    if test x$enable_ime = xyes; then
        AC_DEFINE(SDL_USE_IME, 1, [ ])
            SOURCES="$SOURCES $srcdir/src/core/linux/SDL_ime.c"
    fi
}
dnl See if the platform has libibus IME support.
CheckIBus()
{
@@ -2250,7 +2292,10 @@
                            have_inotify_inotify_h_hdr=no)
            CFLAGS="$save_CFLAGS"
            if test x$have_ibus_ibus_h_hdr = xyes; then
                if test x$enable_dbus != xyes; then
                if test x$enable_ime != xyes; then
                    AC_MSG_WARN([IME support is required for IBus.])
                    have_ibus_ibus_h_hdr=no
                elif test x$enable_dbus != xyes; then
                    AC_MSG_WARN([DBus support is required for IBus.])
                    have_ibus_ibus_h_hdr=no
                elif test x$have_inotify_inotify_h_hdr != xyes; then
@@ -2260,6 +2305,38 @@
                    AC_DEFINE(HAVE_IBUS_IBUS_H, 1, [ ])
                    EXTRA_CFLAGS="$EXTRA_CFLAGS $IBUS_CFLAGS"
                    SOURCES="$SOURCES $srcdir/src/core/linux/SDL_ibus.c"
               fi
            fi
        fi
    fi
}
dnl See if the platform has fcitx IME support.
CheckFcitx()
{
    AC_ARG_ENABLE(fcitx,
AC_HELP_STRING([--enable-fcitx], [enable fcitx support [[default=yes]]]),
                  , enable_fcitx=yes)
    if test x$enable_fcitx = xyes; then
        AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
        if test x$PKG_CONFIG != xno; then
            FCITX_CFLAGS=`$PKG_CONFIG --cflags fcitx`
            CFLAGS="$CFLAGS $FCITX_CFLAGS"
            AC_CHECK_HEADER(fcitx/frontend.h,
                            have_fcitx_frontend_h_hdr=yes,
                            have_fcitx_frontend_h_hdr=no)
            CFLAGS="$save_CFLAGS"
            if test x$have_fcitx_frontend_h_hdr = xyes; then
                if test x$enable_ime != xyes; then
                    AC_MSG_WARN([IME support is required for fcitx.])
                    have_fcitx_frontend_h_hdr=no
                elif test x$enable_dbus != xyes; then
                    AC_MSG_WARN([DBus support is required for fcitx.])
                    have_fcitx_frontend_h_hdr=no
                else
                    AC_DEFINE(HAVE_FCITX_FRONTEND_H, 1, [ ])
                    EXTRA_CFLAGS="$EXTRA_CFLAGS $FCITX_CFLAGS"
                    SOURCES="$SOURCES $srcdir/src/core/linux/SDL_fcitx.c"
               fi
            fi
        fi
@@ -2801,6 +2878,9 @@
                  , enable_rpath=yes)
}
dnl Do this on all platforms, before everything else (other things might want to override it).
CheckWarnAll
dnl Set up the configuration based on the host platform!
case "$host" in
    *-*-linux*|*-*-uclinux*|*-*-gnu*|*-*-k*bsd*-gnu|*-*-bsdi*|*-*-freebsd*|*-*-dragonfly*|*-*-netbsd*|*-*-openbsd*|*-*-sysv5*|*-*-solaris*|*-*-hpux*|*-*-aix*|*-*-minix*)
@@ -2870,6 +2950,7 @@
            *-*-minix*)         ARCH=minix ;;
        esac
        CheckVisibilityHidden
        CheckDeclarationAfterStatement
        CheckDummyVideo
        CheckDiskAudio
        CheckDummyAudio
@@ -2890,7 +2971,9 @@
        CheckWayland
        CheckLibUDev
        CheckDBus
        CheckIME
        CheckIBus
        CheckFcitx
        case $ARCH in
          linux)
              CheckInputEvents
@@ -3196,6 +3279,7 @@
        ARCH=ios
        CheckVisibilityHidden
        CheckDeclarationAfterStatement
        CheckDummyVideo
        CheckDiskAudio
        CheckDummyAudio
@@ -3206,7 +3290,7 @@
        # Set up files for the audio library
        if test x$enable_audio = xyes; then
            SOURCES="$SOURCES $srcdir/src/audio/coreaudio/*.c"
            SOURCES="$SOURCES $srcdir/src/audio/coreaudio/*.m"
            SUMMARY_audio="${SUMMARY_audio} coreaudio"
            have_audio=yes
        fi
@@ -3265,6 +3349,7 @@
        EXTRA_CFLAGS="$EXTRA_CFLAGS -DTARGET_API_MAC_OSX"
        CheckVisibilityHidden
        CheckDeclarationAfterStatement
        CheckDummyVideo
        CheckDiskAudio
        CheckDummyAudio
@@ -3278,7 +3363,8 @@
        # Set up files for the audio library
        if test x$enable_audio = xyes; then
            AC_DEFINE(SDL_AUDIO_DRIVER_COREAUDIO, 1, [ ])
            SOURCES="$SOURCES $srcdir/src/audio/coreaudio/*.c"
            SOURCES="$SOURCES $srcdir/src/audio/coreaudio/*.m"
            EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,CoreAudio -Wl,-framework,AudioToolbox"
            SUMMARY_audio="${SUMMARY_audio} coreaudio"
            have_audio=yes
        fi
@@ -3292,8 +3378,8 @@
        if test x$enable_haptic = xyes; then
            AC_DEFINE(SDL_HAPTIC_IOKIT, 1, [ ])
            SOURCES="$SOURCES $srcdir/src/haptic/darwin/*.c"
            have_haptic=yes
            EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,ForceFeedback"
            have_haptic=yes
        fi
        # Set up files for the power library
        if test x$enable_power = xyes; then
@@ -3324,10 +3410,6 @@
        EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,Cocoa"
        EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,Carbon"
        EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,IOKit"
        # If audio is used, add the AudioUnit framework
        if test x$enable_audio = xyes; then
            EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,CoreAudio -Wl,-framework,AudioToolbox -Wl,-framework,AudioUnit"
        fi
        ;;
    *-nacl|*-pnacl)
        ARCH=nacl
@@ -3366,6 +3448,7 @@
        fi
        CheckVisibilityHidden
        CheckDeclarationAfterStatement
        CheckDummyVideo
        CheckDiskAudio
        CheckDummyAudio
@@ -3406,9 +3489,6 @@
        ])
        ;;
esac
dnl Do this on all platforms, after everything else.
CheckWarnAll
# Verify that we have all the platform specific files we need
@@ -3453,6 +3533,57 @@
fi
SDLTEST_SOURCES="$srcdir/src/test/*.c"
if test x$video_wayland = xyes; then
    WAYLAND_CORE_PROTOCOL_SOURCE='$(gen)/wayland-protocol.c'
    WAYLAND_CORE_PROTOCOL_HEADER='$(gen)/wayland-client-protocol.h'
    WAYLAND_PROTOCOLS_UNSTABLE_SOURCES=`echo $WAYLAND_PROTOCOLS_UNSTABLE |\
        sed 's,[[^ ]]\+,\\$(gen)/&-protocol.c,g'`
    WAYLAND_PROTOCOLS_UNSTABLE_HEADERS=`echo $WAYLAND_PROTOCOLS_UNSTABLE |\
        sed 's,[[^ ]]\+,\\$(gen)/&-client-protocol.h,g'`
    GEN_SOURCES="$GEN_SOURCES $WAYLAND_CORE_PROTOCOL_SOURCE $WAYLAND_PROTOCOLS_UNSTABLE_SOURCES"
    GEN_HEADERS="$GEN_HEADERS $WAYLAND_CORE_PROTOCOL_HEADER $WAYLAND_PROTOCOLS_UNSTABLE_HEADERS"
    WAYLAND_CORE_PROTOCOL_SOURCE_DEPENDS="
$WAYLAND_CORE_PROTOCOL_SOURCE: $WAYLAND_CORE_PROTOCOL_DIR/wayland.xml
    \$(SHELL) \$(auxdir)/mkinstalldirs \$(gen)
    \$(RUN_CMD_GEN)\$(WAYLAND_SCANNER) code \$< \$@"
    WAYLAND_CORE_PROTOCOL_HEADER_DEPENDS="
$WAYLAND_CORE_PROTOCOL_HEADER: $WAYLAND_CORE_PROTOCOL_DIR/wayland.xml
    \$(SHELL) \$(auxdir)/mkinstalldirs \$(gen)
    \$(RUN_CMD_GEN)\$(WAYLAND_SCANNER) client-header \$< \$@"
    WAYLAND_CORE_PROTOCOL_OBJECT="
\$(objects)/`echo $WAYLAND_CORE_PROTOCOL_SOURCE | sed 's/\$(gen)\/\(.*\).c$/\1.lo/'`: $WAYLAND_CORE_PROTOCOL_SOURCE
    \$(RUN_CMD_CC)\$(LIBTOOL) --tag=CC --mode=compile \$(CC) \$(CFLAGS) \$(EXTRA_CFLAGS) $DEPENDENCY_TRACKING_OPTIONS -c \$< -o \$@"
    WAYLAND_PROTOCOLS_CLIENT_HEADER_UNSTABLE_DEPENDS=`for p in $WAYLAND_PROTOCOLS_UNSTABLE;\
        do echo ; echo \$p | sed\
        "s,^\\([[a-z\\-]]\\+\\)-unstable-\\(v[[0-9]]\+\\)\$,\\$(gen)/&-client-protocol.h: $WAYLAND_PROTOCOLS_DIR/unstable/\1/&.xml\\\\
    \\$(SHELL) \\$(auxdir)/mkinstalldirs \\$(gen)\\\\
    \\$(RUN_CMD_GEN)\\$(WAYLAND_SCANNER) client-header \\$< \\$@," ; done`
    WAYLAND_PROTOCOLS_CODE_UNSTABLE_DEPENDS=`for p in $WAYLAND_PROTOCOLS_UNSTABLE;\
        do echo ; echo \$p | sed\
        "s,^\\([[a-z\\-]]\\+\\)-unstable-\\(v[[0-9]]\+\\)\$,\\$(gen)/&-protocol.c: $WAYLAND_PROTOCOLS_DIR/unstable/\1/&.xml\\\\
    \\$(SHELL) \\$(auxdir)/mkinstalldirs \\$(gen)\\\\
    \\$(RUN_CMD_GEN)\\$(WAYLAND_SCANNER) code \\$< \\$@," ; done`
    WAYLAND_PROTOCOLS_OBJECTS_UNSTABLE=`for p in $WAYLAND_PROTOCOLS_UNSTABLE;\
        do echo ; echo \$p | sed\
        "s,^\\([[a-z\\-]]\\+\\)-unstable-\\(v[[0-9]]\+\\)\$,\\\$(objects)/&-protocol.lo: \\$(gen)/&-protocol.c \\$(gen)/&-client-protocol.h\\\\
    \\$(RUN_CMD_CC)\\$(LIBTOOL) --tag=CC --mode=compile \\$(CC) \\$(CFLAGS) \\$(EXTRA_CFLAGS) $DEPENDENCY_TRACKING_OPTIONS -c \\$< -o \\$@," ; done`
    WAYLAND_PROTOCOLS_DEPENDS="
$WAYLAND_CORE_PROTOCOL_SOURCE_DEPENDS
$WAYLAND_CORE_PROTOCOL_HEADER_DEPENDS
$WAYLAND_CORE_PROTOCOL_OBJECT
$WAYLAND_PROTOCOLS_CLIENT_HEADER_UNSTABLE_DEPENDS
$WAYLAND_PROTOCOLS_CODE_UNSTABLE_DEPENDS
$WAYLAND_PROTOCOLS_OBJECTS_UNSTABLE
"
fi
OBJECTS=`echo $SOURCES`
DEPENDS=`echo $SOURCES | tr ' ' '\n'`
for EXT in asm cc m c S; do
@@ -3461,6 +3592,8 @@
\\$(objects)/\\2.lo: \\1/\\2.$EXT\\\\
    \\$(RUN_CMD_CC)\\$(LIBTOOL) --tag=CC --mode=compile \\$(CC) \\$(CFLAGS) \\$(EXTRA_CFLAGS) $DEPENDENCY_TRACKING_OPTIONS -c \\$< -o \\$@,g"`
done
GEN_OBJECTS=`echo "$GEN_SOURCES" | sed 's,[[^ ]]*/\([[^ ]]*\)\.c,$(objects)/\1.lo,g'`
VERSION_OBJECTS=`echo $VERSION_SOURCES`
VERSION_DEPENDS=`echo $VERSION_SOURCES`
@@ -3488,6 +3621,19 @@
if test "x$enable_rpath" = "xyes"; then
  if test $ARCH = bsdi -o $ARCH = freebsd -o $ARCH = linux -o $ARCH = netbsd; then
    SDL_RLD_FLAGS="-Wl,-rpath,\${libdir}"
    AC_MSG_CHECKING(for linker option --enable-new-dtags)
    have_enable_new_dtags=no
    save_LDFLAGS="$LDFLAGS"
    LDFLAGS="$LDFLAGS -Wl,--enable-new-dtags"
    AC_TRY_LINK([
    ],[
    ],[
    have_enable_new_dtags=yes
    SDL_RLD_FLAGS="$SDL_RLD_FLAGS -Wl,--enable-new-dtags"
    ])
    LDFLAGS="$save_LDFLAGS"
    AC_MSG_RESULT($have_enable_new_dtags)
  fi
  if test $ARCH = solaris; then
    SDL_RLD_FLAGS="-R\${libdir}"
@@ -3526,6 +3672,8 @@
AC_SUBST(ac_aux_dir)
AC_SUBST(INCLUDE)
AC_SUBST(OBJECTS)
AC_SUBST(GEN_HEADERS)
AC_SUBST(GEN_OBJECTS)
AC_SUBST(VERSION_OBJECTS)
AC_SUBST(SDLMAIN_OBJECTS)
AC_SUBST(SDLTEST_OBJECTS)
@@ -3534,6 +3682,7 @@
AC_SUBST(BUILD_LDFLAGS)
AC_SUBST(EXTRA_LDFLAGS)
AC_SUBST(WINDRES)
AC_SUBST(WAYLAND_SCANNER)
cat >Makefile.rules <<__EOF__
@@ -3546,6 +3695,7 @@
$VERSION_DEPENDS
$SDLMAIN_DEPENDS
$SDLTEST_DEPENDS
$WAYLAND_PROTOCOLS_DEPENDS
__EOF__
AC_CONFIG_FILES([
@@ -3578,11 +3728,21 @@
else
    SUMMARY="${SUMMARY}Using dbus      : NO\n"
fi
if test x$enable_ime = xyes; then
    SUMMARY="${SUMMARY}Using ime       : YES\n"
else
    SUMMARY="${SUMMARY}Using ime       : NO\n"
fi
if test x$have_ibus_ibus_h_hdr = xyes; then
    SUMMARY="${SUMMARY}Using ibus      : YES\n"
else
    SUMMARY="${SUMMARY}Using ibus      : NO\n"
fi
if test x$have_fcitx_frontend_h_hdr = xyes; then
    SUMMARY="${SUMMARY}Using fcitx     : YES\n"
else
    SUMMARY="${SUMMARY}Using fcitx     : NO\n"
fi
AC_CONFIG_COMMANDS([summary], [echo -en "$SUMMARY"], [SUMMARY="$SUMMARY"])
AC_OUTPUT
source/debian/changelog
@@ -1,3 +1,9 @@
libsdl2 (2.0.4) UNRELEASED; urgency=low
  * Updated SDL to version 2.0.4
 -- Sam Lantinga <slouken@libsdl.org>  Thu, 07 Jan 2016 11:02:39 -0800
libsdl2 (2.0.3) UNRELEASED; urgency=low
  * Updated SDL to version 2.0.3
source/debian/copyright
@@ -31,10 +31,6 @@
           1995 Brown University
License: BrownUn_UnCalifornia_ErikCorry
Files: src/stdlib/SDL_qsort.c
Copyright: 1998 Gareth McCaughan
License: Gareth_McCaughan
Files: src/test/SDL_test_md5.c
Copyright: 1997-2016 Sam Lantinga <slouken@libsdl.org>
           1990 RSA Data Security, Inc.
@@ -269,13 +265,6 @@
  * BASIS, AND BROWN UNIVERSITY HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
  * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  */
License: Gareth_McCaughan
  You may use it in anything you like; you may make money
  out of it; you may distribute it in object form or as
  part of an executable without including source code;
  you don't have to credit me. (But it would be nice if
  you did.)
License: Johnson_M._Hart
  Permission is granted for any and all use providing that this
source/debian/libsdl2-dev.install
@@ -5,4 +5,5 @@
usr/lib/*/libSDL2main.a
usr/lib/*/libSDL2_test.a
usr/lib/*/pkgconfig/sdl2.pc
usr/lib/*/cmake/SDL2/sdl2-config.cmake
usr/share/aclocal/sdl2.m4
source/docs/README-android.md
@@ -1,4 +1,4 @@
Android
Android
================================================================================
Requirements:
@@ -67,13 +67,13 @@
    
1. Copy the android-project directory wherever you want to keep your projects
   and rename it to the name of your project.
2. Move or symlink this SDL directory into the <project>/jni directory
3. Edit <project>/jni/src/Android.mk to include your source files
2. Move or symlink this SDL directory into the "<project>/jni" directory
3. Edit "<project>/jni/src/Android.mk" to include your source files
4. Run 'ndk-build' (a script provided by the NDK). This compiles the C source
If you want to use the Eclipse IDE, skip to the Eclipse section below.
5. Create <project>/local.properties and use that to point to the Android SDK directory, by writing a line with the following form:
5. Create "<project>/local.properties" and use that to point to the Android SDK directory, by writing a line with the following form:
       sdk.dir=PATH_TO_ANDROID_SDK
@@ -121,15 +121,15 @@
Instructions:
1. Copy the android-project directory wherever you want to keep your projects
   and rename it to the name of your project.
2. Rename <project>/jni/src/Android_static.mk to <project>/jni/src/Android.mk
2. Rename "<project>/jni/src/Android_static.mk" to "<project>/jni/src/Android.mk"
   (overwrite the existing one)
3. Edit <project>/jni/src/Android.mk to include your source files
3. Edit "<project>/jni/src/Android.mk" to include your source files
4. create and export an environment variable named NDK_MODULE_PATH that points
   to the parent directory of this SDL directory. e.g.:
       export NDK_MODULE_PATH="$PWD"/..
5. Edit <project>/src/org/libsdl/app/SDLActivity.java and remove the call to
5. Edit "<project>/src/org/libsdl/app/SDLActivity.java" and remove the call to
   System.loadLibrary("SDL2").
6. Run 'ndk-build' (a script provided by the NDK). This compiles the C source
@@ -420,6 +420,19 @@
    adb shell setprop wrap.org.libsdl.app ""
================================================================================
 Graphics debugging
================================================================================
If you are developing on a compatible Tegra-based tablet, NVidia provides
Tegra Graphics Debugger at their website.  Because SDL2 dynamically loads EGL
and GLES libraries, you must follow their instructions for installing the
interposer library on a rooted device.  The non-rooted instructions are not
compatible with applications that use SDL2 for video.
The Tegra Graphics Debugger is available from NVidia here:
https://developer.nvidia.com/tegra-graphics-debugger
================================================================================
 Why is API level 10 the minimum required?
================================================================================
source/docs/README-ios.md
@@ -74,17 +74,17 @@
Retina/high-dpi capable devices. Use the SDL_WINDOW_ALLOW_HIGHDPI flag when
creating your window to enable high-dpi support.
When high-dpi support is enabled, SDL_GetWindowSize and display mode sizes
When high-dpi support is enabled, SDL_GetWindowSize() and display mode sizes
will still be in "screen coordinates" rather than pixels, but the window will
have a much greater pixel density when the device supports it, and the
SDL_GL_GetDrawableSize or SDL_GetRendererOutputSize functions (depending on
SDL_GL_GetDrawableSize() or SDL_GetRendererOutputSize() functions (depending on
whether raw OpenGL or the SDL_Render API is used) can be queried to determine
the size in pixels of the drawable screen framebuffer.
Some OpenGL ES functions such as glViewport expect sizes in pixels rather than
sizes in screen coordinates. When doing 2D rendering with OpenGL ES, an
orthographic projection matrix using the size in screen coordinates
(SDL_GetWindowSize) can be used in order to display content at the same scale
(SDL_GetWindowSize()) can be used in order to display content at the same scale
no matter whether a Retina device is used or not.
==============================================================================
@@ -156,7 +156,7 @@
SDL for iPhone supports polling the built in accelerometer as a joystick device.  For an example on how to do this, see the accelerometer.c in the demos directory.
The main thing to note when using the accelerometer with SDL is that while the iPhone natively reports accelerometer as floating point values in units of g-force, SDL_JoystickGetAxis reports joystick values as signed integers.  Hence, in order to convert between the two, some clamping and scaling is necessary on the part of the iPhone SDL joystick driver.  To convert SDL_JoystickGetAxis reported values BACK to units of g-force, simply multiply the values by SDL_IPHONE_MAX_GFORCE / 0x7FFF.
The main thing to note when using the accelerometer with SDL is that while the iPhone natively reports accelerometer as floating point values in units of g-force, SDL_JoystickGetAxis() reports joystick values as signed integers.  Hence, in order to convert between the two, some clamping and scaling is necessary on the part of the iPhone SDL joystick driver.  To convert SDL_JoystickGetAxis() reported values BACK to units of g-force, simply multiply the values by SDL_IPHONE_MAX_GFORCE / 0x7FFF.
==============================================================================
Notes -- OpenGL ES
@@ -164,7 +164,7 @@
Your SDL application for iOS uses OpenGL ES for video by default.
OpenGL ES for iOS supports several display pixel formats, such as RGBA8 and RGB565, which provide a 32 bit and 16 bit color buffer respectively. By default, the implementation uses RGB565, but you may use RGBA8 by setting each color component to 8 bits in SDL_GL_SetAttribute.
OpenGL ES for iOS supports several display pixel formats, such as RGBA8 and RGB565, which provide a 32 bit and 16 bit color buffer respectively. By default, the implementation uses RGB565, but you may use RGBA8 by setting each color component to 8 bits in SDL_GL_SetAttribute().
If your application doesn't use OpenGL's depth buffer, you may find significant performance improvement by setting SDL_GL_DEPTH_SIZE to 0.
@@ -172,11 +172,11 @@
OpenGL ES on iOS doesn't use the traditional system-framebuffer setup provided in other operating systems. Special care must be taken because of this:
- The drawable Renderbuffer must be bound to the GL_RENDERBUFFER binding point when SDL_GL_SwapWindow is called.
- The drawable Framebuffer Object must be bound while rendering to the screen and when SDL_GL_SwapWindow is called.
- The drawable Renderbuffer must be bound to the GL_RENDERBUFFER binding point when SDL_GL_SwapWindow() is called.
- The drawable Framebuffer Object must be bound while rendering to the screen and when SDL_GL_SwapWindow() is called.
- If multisample antialiasing (MSAA) is used and glReadPixels is used on the screen, the drawable framebuffer must be resolved to the MSAA resolve framebuffer (via glBlitFramebuffer or glResolveMultisampleFramebufferAPPLE), and the MSAA resolve framebuffer must be bound to the GL_READ_FRAMEBUFFER binding point, before glReadPixels is called.
The above objects can be obtained via SDL_GetWindowWMInfo (in SDL_syswm.h).
The above objects can be obtained via SDL_GetWindowWMInfo() (in SDL_syswm.h).
==============================================================================
Notes -- Keyboard
@@ -219,7 +219,7 @@
==============================================================================
Windows:
    Full-size, single window applications only.  You cannot create multi-window SDL applications for iPhone OS.  The application window will fill the display, though you have the option of turning on or off the menu-bar (pass SDL_CreateWindow the flag SDL_WINDOW_BORDERLESS).
    Full-size, single window applications only.  You cannot create multi-window SDL applications for iPhone OS.  The application window will fill the display, though you have the option of turning on or off the menu-bar (pass SDL_CreateWindow() the flag SDL_WINDOW_BORDERLESS).
Textures:
    The optimal texture formats on iOS are SDL_PIXELFORMAT_ABGR8888, SDL_PIXELFORMAT_ABGR8888, SDL_PIXELFORMAT_BGR888, and SDL_PIXELFORMAT_RGB24 pixel formats.
source/docs/README-linux.md
@@ -1,82 +1,86 @@
Linux
================================================================================
By default SDL will only link against glibc, the rest of the features will be
enabled dynamically at runtime depending on the available features on the target
system. So, for example if you built SDL with Xinerama support and the target
system does not have the Xinerama libraries installed, it will be disabled
at runtime, and you won't get a missing library error, at least with the
default configuration parameters.
================================================================================
Build Dependencies
================================================================================
Ubuntu 13.04, all available features enabled:
sudo apt-get install build-essential mercurial make cmake autoconf automake \
libtool libasound2-dev libpulse-dev libaudio-dev libx11-dev libxext-dev \
libxrandr-dev libxcursor-dev libxi-dev libxinerama-dev libxxf86vm-dev \
libxss-dev libgl1-mesa-dev libesd0-dev libdbus-1-dev libudev-dev \
libgles1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libibus-1.0-dev
Ubuntu 14.04 can also add "libwayland-dev libmirclient-dev libxkbcommon-dev"
to that command line for Wayland and Mir support.
NOTES:
- This includes all the audio targets except arts, because Ubuntu pulled the
  artsc0-dev package, but in theory SDL still supports it.
- DirectFB isn't included because the configure script (currently) fails to find
  it at all. You can do "sudo apt-get install libdirectfb-dev" and fix the
  configure script to include DirectFB support. Send patches.  :)
================================================================================
Joystick does not work
================================================================================
If you compiled or are using a version of SDL with udev support (and you should!)
there's a few issues that may cause SDL to fail to detect your joystick. To
debug this, start by installing the evtest utility. On Ubuntu/Debian:
    sudo apt-get install evtest
Then run:
    sudo evtest
You'll hopefully see your joystick listed along with a name like "/dev/input/eventXX"
Now run:
    cat /dev/input/event/XX
If you get a permission error, you need to set a udev rule to change the mode of
your device (see below)
Also, try:
    sudo udevadm info --query=all --name=input/eventXX
If you see a line stating ID_INPUT_JOYSTICK=1, great, if you don't see it,
you need to set up an udev rule to force this variable.
A combined rule for the Saitek Pro Flight Rudder Pedals to fix both issues looks
like:
   SUBSYSTEM=="input", ATTRS{idProduct}=="0763", ATTRS{idVendor}=="06a3", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1"
   SUBSYSTEM=="input", ATTRS{idProduct}=="0764", ATTRS{idVendor}=="06a3", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1"
You can set up similar rules for your device by changing the values listed in
idProduct and idVendor. To obtain these values, try:
    sudo udevadm info -a --name=input/eventXX | grep idVendor
    sudo udevadm info -a --name=input/eventXX | grep idProduct
If multiple values come up for each of these, the one you want is the first one of each.
On other systems which ship with an older udev (such as CentOS), you may need
to set up a rule such as:
    SUBSYSTEM=="input", ENV{ID_CLASS}=="joystick", ENV{ID_INPUT_JOYSTICK}="1"
Linux
================================================================================
By default SDL will only link against glibc, the rest of the features will be
enabled dynamically at runtime depending on the available features on the target
system. So, for example if you built SDL with Xinerama support and the target
system does not have the Xinerama libraries installed, it will be disabled
at runtime, and you won't get a missing library error, at least with the
default configuration parameters.
================================================================================
Build Dependencies
================================================================================
Ubuntu 13.04, all available features enabled:
sudo apt-get install build-essential mercurial make cmake autoconf automake \
libtool libasound2-dev libpulse-dev libaudio-dev libx11-dev libxext-dev \
libxrandr-dev libxcursor-dev libxi-dev libxinerama-dev libxxf86vm-dev \
libxss-dev libgl1-mesa-dev libesd0-dev libdbus-1-dev libudev-dev \
libgles1-mesa-dev libgles2-mesa-dev libegl1-mesa-dev libibus-1.0-dev \
fcitx-libs-dev
Ubuntu 16.04 can also add "libwayland-dev libxkbcommon-dev wayland-protocols"
to that command line for Wayland support.
Ubuntu 16.10 can also add "libmirclient-dev libxkbcommon-dev" to that command
line for Mir support.
NOTES:
- This includes all the audio targets except arts, because Ubuntu pulled the
  artsc0-dev package, but in theory SDL still supports it.
- DirectFB isn't included because the configure script (currently) fails to find
  it at all. You can do "sudo apt-get install libdirectfb-dev" and fix the
  configure script to include DirectFB support. Send patches.  :)
================================================================================
Joystick does not work
================================================================================
If you compiled or are using a version of SDL with udev support (and you should!)
there's a few issues that may cause SDL to fail to detect your joystick. To
debug this, start by installing the evtest utility. On Ubuntu/Debian:
    sudo apt-get install evtest
Then run:
    sudo evtest
You'll hopefully see your joystick listed along with a name like "/dev/input/eventXX"
Now run:
    cat /dev/input/event/XX
If you get a permission error, you need to set a udev rule to change the mode of
your device (see below)
Also, try:
    sudo udevadm info --query=all --name=input/eventXX
If you see a line stating ID_INPUT_JOYSTICK=1, great, if you don't see it,
you need to set up an udev rule to force this variable.
A combined rule for the Saitek Pro Flight Rudder Pedals to fix both issues looks
like:
   SUBSYSTEM=="input", ATTRS{idProduct}=="0763", ATTRS{idVendor}=="06a3", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1"
   SUBSYSTEM=="input", ATTRS{idProduct}=="0764", ATTRS{idVendor}=="06a3", MODE="0666", ENV{ID_INPUT_JOYSTICK}="1"
You can set up similar rules for your device by changing the values listed in
idProduct and idVendor. To obtain these values, try:
    sudo udevadm info -a --name=input/eventXX | grep idVendor
    sudo udevadm info -a --name=input/eventXX | grep idProduct
If multiple values come up for each of these, the one you want is the first one of each.
On other systems which ship with an older udev (such as CentOS), you may need
to set up a rule such as:
    SUBSYSTEM=="input", ENV{ID_CLASS}=="joystick", ENV{ID_INPUT_JOYSTICK}="1"
source/docs/README-macosx.md
@@ -11,9 +11,9 @@
To build SDL using the command line, use the standard configure and make
process:
    ./configure
    make
    sudo make install
    ./configure
    make
    sudo make install
You can also build SDL as a Universal library (a single binary for both
32-bit and 64-bit Intel architectures), on Mac OS X 10.7 and newer, by using
@@ -21,9 +21,9 @@
    mkdir mybuild
    cd mybuild
    CC=$PWD/../build-scripts/gcc-fat.sh CXX=$PWD/../build-scripts/g++fat.sh ../configure
    make
    sudo make install
    CC=$PWD/../build-scripts/gcc-fat.sh CXX=$PWD/../build-scripts/g++-fat.sh ../configure
    make
    sudo make install
This script builds SDL with 10.5 ABI compatibility on i386 and 10.6
ABI compatibility on x86_64 architectures.  For best compatibility you
@@ -86,17 +86,17 @@
To get this build automatically, add something like the following rule to
your Makefile.am:
bundle_contents = APP_NAME.app/Contents
APP_NAME_bundle: EXE_NAME
    mkdir -p $(bundle_contents)/MacOS
    mkdir -p $(bundle_contents)/Resources
    echo "APPL????" > $(bundle_contents)/PkgInfo
    $(INSTALL_PROGRAM) $< $(bundle_contents)/MacOS/
    bundle_contents = APP_NAME.app/Contents
    APP_NAME_bundle: EXE_NAME
        mkdir -p $(bundle_contents)/MacOS
        mkdir -p $(bundle_contents)/Resources
        echo "APPL????" > $(bundle_contents)/PkgInfo
        $(INSTALL_PROGRAM) $< $(bundle_contents)/MacOS/
You should replace EXE_NAME with the name of the executable. APP_NAME is what
will be visible to the user in the Finder. Usually it will be the same
as EXE_NAME but capitalized. E.g. if EXE_NAME is "testgame" then APP_NAME 
usually is "TestGame". You might also want to use @PACKAGE@ to use the package
usually is "TestGame". You might also want to use `@PACKAGE@` to use the package
name as specified in your configure.in file.
If your project builds more than one application, you will have to do a bit
@@ -105,13 +105,13 @@
If you want the created bundles to be installed, you may want to add this
rule to your Makefile.am:
install-exec-hook: APP_NAME_bundle
    rm -rf $(DESTDIR)$(prefix)/Applications/APP_NAME.app
    mkdir -p $(DESTDIR)$(prefix)/Applications/
    cp -r $< /$(DESTDIR)$(prefix)Applications/
    install-exec-hook: APP_NAME_bundle
        rm -rf $(DESTDIR)$(prefix)/Applications/APP_NAME.app
        mkdir -p $(DESTDIR)$(prefix)/Applications/
        cp -r $< /$(DESTDIR)$(prefix)Applications/
This rule takes the Bundle created by the rule from step 3 and installs them
into $(DESTDIR)$(prefix)/Applications/.
into "$(DESTDIR)$(prefix)/Applications/".
Again, if you want to install multiple applications, you will have to augment
the make rule accordingly.
@@ -126,11 +126,16 @@
   unless you also install SDL on that other computer. A good solution
   for this dilemma is to static link against SDL. On OS X, you can
   achieve that by linking against the libraries listed by
     sdl-config --static-libs
       sdl-config --static-libs
   instead of those listed by
     sdl-config --libs
       sdl-config --libs
   Depending on how exactly SDL is integrated into your build systems, the
   way to achieve that varies, so I won't describe it here in detail
2) Add an 'Info.plist' to your application. That is a special XML file which
   contains some meta-information about your application (like some copyright
   information, the version of your app, the name of an optional icon file,
@@ -156,8 +161,10 @@
top level SDL directory (where the Xcode.tar.gz archive resides).
Because Stuffit Expander will unpack the archive into a subdirectory,
you should unpack the archive manually from the command line:
    cd [path_to_SDL_source]
    tar zxf Xcode.tar.gz
    cd [path_to_SDL_source]
    tar zxf Xcode.tar.gz
This will create a new folder called Xcode, which you can browse
normally from the Finder.
@@ -227,4 +234,4 @@
        Functionality may be added in the future to help this.
Known bugs are listed in the file "BUGS"
Known bugs are listed in the file "BUGS.txt".
source/docs/README-porting.md
@@ -1,11 +1,11 @@
Porting
=======
Porting
=======
* Porting To A New Platform
  The first thing you have to do when porting to a new platform, is look at
include/SDL_platform.h and create an entry there for your operating system.
The standard format is __PLATFORM__, where PLATFORM is the name of the OS.
The standard format is "__PLATFORM__", where PLATFORM is the name of the OS.
Ideally SDL_platform.h will be able to auto-detect the system it's building
on based on C preprocessor symbols.
@@ -15,7 +15,9 @@
   If you have a GNUish system, then you might try this.  Edit configure.in,
   take a look at the large section labelled:
    "Set up the configuration based on the host platform!"
   Add a section for your platform, and then re-run autogen.sh and build!
2. Using an IDE:
@@ -27,6 +29,7 @@
   Add the top level include directory to the header search path, and then add
   the following sources to the project:
    src/*.c
    src/atomic/*.c
    src/audio/*.c
source/docs/README-raspberrypi.md
@@ -39,7 +39,7 @@
You'll also need a Rasbian binary image.
Get it from: http://downloads.raspberrypi.org/raspbian_latest 
After unzipping, you'll get file with a name like: <date>-wheezy-raspbian.img
After unzipping, you'll get file with a name like: "<date>-wheezy-raspbian.img"
Let's assume the sysroot will be built in /opt/rpi-sysroot.
    export SYSROOT=/opt/rpi-sysroot
source/docs/README-touch.md
@@ -1,4 +1,4 @@
Touch
Touch
===========================================================================
System Specific Notes
===========================================================================
@@ -42,14 +42,14 @@
===========================================================================
Functions
===========================================================================
SDL provides the ability to access the underlying Finger structures.
SDL provides the ability to access the underlying SDL_Finger structures.
These structures should _never_ be modified.
The following functions are included from SDL_touch.h
To get a SDL_TouchID call SDL_GetTouchDevice(index).
To get a SDL_TouchID call SDL_GetTouchDevice(int index).
This returns a SDL_TouchID.
IMPORTANT: If the touch has been removed, or there is no touch with the given ID, SDL_GetTouchID will return 0. Be sure to check for this!
IMPORTANT: If the touch has been removed, or there is no touch with the given index, SDL_GetTouchDevice() will return 0. Be sure to check for this!
The number of touch devices can be queried with SDL_GetNumTouchDevices().
@@ -64,13 +64,13 @@
To get a SDL_Finger, call SDL_GetTouchFinger(touchID,index), where touchID is a SDL_TouchID, and index is the requested finger.
This returns a SDL_Finger*, or NULL if the finger does not exist, or has been removed.
To get a SDL_Finger, call SDL_GetTouchFinger(SDL_TouchID touchID, int index), where touchID is a SDL_TouchID, and index is the requested finger.
This returns a SDL_Finger *, or NULL if the finger does not exist, or has been removed.
A SDL_Finger is guaranteed to be persistent for the duration of a touch, but it will be de-allocated as soon as the finger is removed. This occurs when the SDL_FINGERUP event is _added_ to the event queue, and thus _before_ the SDL_FINGERUP event is polled.
As a result, be very careful to check for NULL return values.
A SDL_Finger has the following fields:
* x,y,pressure:
* x, y:
    The current coordinates of the touch.
* pressure:
    The pressure of the touch.
source/docs/README-winrt.md
@@ -1,468 +1,478 @@
WinRT
=====
This port allows SDL applications to run on Microsoft's platforms that require
use of "Windows Runtime", aka. "WinRT", APIs.  WinRT apps are currently
full-screen only, and run in what Microsoft sometimes refers to as their
"Modern" (formerly, "Metro"), environment.  For Windows 8.x, Microsoft may also
refer to them as "Windows Store" apps, due to them being distributed,
primarily, via a Microsoft-run online store (of the same name).
Some of the operating systems that include WinRT, are:
* Windows 10, via its Universal Windows Platform (UWP) APIs
* Windows 8.x
* Windows RT 8.x (aka. Windows 8.x for ARM processors)
* Windows Phone 8.x
Requirements
------------
* Microsoft Visual C++ (aka Visual Studio), either 2015, 2013, or 2012
  - Free, "Community" or "Express" editions may be used, so long as they
    include  support for either "Windows Store" or "Windows Phone" apps.
    "Express" versions marked as supporting "Windows Desktop" development
    typically do not include support for creating WinRT apps, to note.
    (The "Community" editions of Visual C++ do, however, support both
    desktop/Win32 and WinRT development).
  - Visual C++ 2012 can only build apps that target versions 8.0 of Windows,
    or  Windows Phone.  8.0-targetted apps will run on devices running 8.1
    editions of Windows, however they will not be able to take advantage of
    8.1-specific features.
  - Visual C++ 2013 cannot create app projects that target Windows 8.0.
    Visual C++ 2013 Update 4, can create app projects for Windows Phone 8.0,
    Windows Phone 8.1, and Windows 8.1, but not Windows 8.0.  An optional
    Visual Studio add-in, "Tools for Maintaining Store apps for Windows 8",
    allows Visual C++ 2013 to load and build Windows 8.0 projects that were
    created with Visual C++ 2012, so long as Visual C++ 2012 is installed
    on the same machine.  More details on targeting different versions of
    Windows can found at the following web pages:
      - [Develop apps by using Visual Studio 2013](http://msdn.microsoft.com/en-us/library/windows/apps/br211384.aspx)
      - [To add the Tools for Maintaining Store apps for Windows 8](http://msdn.microsoft.com/en-us/library/windows/apps/dn263114.aspx#AddMaintenanceTools)
* A valid Microsoft account - This requirement is not imposed by SDL, but
  rather by Microsoft's Visual C++ toolchain.  This is required to launch or
  debug apps.
Status
------
Here is a rough list of what works, and what doens't:
* What works:
  * compilation via Visual C++ 2012 through 2015
  * compile-time platform detection for SDL programs.  The C/C++ #define,
    `__WINRT__`, will be set to 1 (by SDL) when compiling for WinRT.
  * GPU-accelerated 2D rendering, via SDL_Renderer.
  * OpenGL ES 2, via the ANGLE library (included separately from SDL)
  * software rendering, via either SDL_Surface (optionally in conjunction with
    SDL_GetWindowSurface() and SDL_UpdateWindowSurface()) or via the
    SDL_Renderer APIs
  * threads
  * timers (via SDL_GetTicks(), SDL_AddTimer(), SDL_GetPerformanceCounter(),
    SDL_GetPerformanceFrequency(), etc.)
  * file I/O via SDL_RWops
  * mouse input  (unsupported on Windows Phone)
  * audio, via a modified version of SDL's XAudio2 backend
  * .DLL file loading.  Libraries *MUST* be packaged inside applications.  Loading
    anything outside of the app is not supported.
  * system path retrieval via SDL's filesystem APIs
  * game controllers.  Support is provided via the SDL_Joystick and
    SDL_GameController APIs, and is backed by Microsoft's XInput API.
  * multi-touch input
  * app events.  SDL_APP_WILLENTER* and SDL_APP_DIDENTER* events get sent out as
    appropriate.
  * window events
  * using Direct3D 11.x APIs outside of SDL.  Non-XAML / Direct3D-only apps can
    choose to render content directly via Direct3D, using SDL to manage the
    internal WinRT window, as well as input and audio.  (Use
    SDL_GetWindowWMInfo() to get the WinRT 'CoreWindow', and pass it into
    IDXGIFactory2::CreateSwapChainForCoreWindow() as appropriate.)
* What partially works:
  * keyboard input.  Most of WinRT's documented virtual keys are supported, as
    well as many keys with documented hardware scancodes.
  * SDLmain.  WinRT uses a different signature for each app's main() function.
    SDL-based apps that use this port must compile in SDL_winrt_main_NonXAML.cpp
    (in `SDL\src\main\winrt\`) directly in order for their C-style main()
    functions to be called.
* What doesn't work:
  * compilation with anything other than Visual C++
  * programmatically-created custom cursors.  These don't appear to be supported
    by WinRT.  Different OS-provided cursors can, however, be created via
    SDL_CreateSystemCursor() (unsupported on Windows Phone)
  * SDL_WarpMouseInWindow() or SDL_WarpMouseGlobal().  This are not currently
    supported by WinRT itself.
  * joysticks and game controllers that aren't supported by Microsoft's XInput
    API.
  * turning off VSync when rendering on Windows Phone.  Attempts to turn VSync
    off on Windows Phone result either in Direct3D not drawing anything, or it
    forcing VSync back on.  As such, SDL_RENDERER_PRESENTVSYNC will always get
    turned-on on Windows Phone.  This limitation is not present in non-Phone
    WinRT (such as Windows 8.x), where turning off VSync appears to work.
  * probably anything else that's not listed as supported
Upgrade Notes
-------------
#### SDL_GetPrefPath() usage when upgrading WinRT apps from SDL 2.0.3
SDL 2.0.4 fixes two bugs found in the WinRT version of SDL_GetPrefPath().
The fixes may affect older, SDL 2.0.3-based apps' save data.  Please note
that these changes only apply to SDL-based WinRT apps, and not to apps for
any other platform.
1. SDL_GetPrefPath() would return an invalid path, one in which the path's
   directory had not been created.  Attempts to create files there
   (via fopen(), for example), would fail, unless that directory was
   explicitly created beforehand.
2. SDL_GetPrefPath(), for non-WinPhone-based apps, would return a path inside
   a WinRT 'Roaming' folder, the contents of which get automatically
   synchronized across multiple devices.  This process can occur while an
   application runs, and can cause existing save-data to be overwritten
   at unexpected times, with data from other devices.  (Windows Phone apps
   written with SDL 2.0.3 did not utilize a Roaming folder, due to API
   restrictions in Windows Phone 8.0).
SDL_GetPrefPath(), starting with SDL 2.0.4, addresses these by:
1. making sure that SDL_GetPrefPath() returns a directory in which data
   can be written to immediately, without first needing to create directories.
2. basing SDL_GetPrefPath() off of a different, non-Roaming folder, the
   contents of which do not automatically get synchronized across devices
   (and which require less work to use safely, in terms of data integrity).
Apps that wish to get their Roaming folder's path can do so either by using
SDL_WinRTGetFSPathUTF8(), SDL_WinRTGetFSPathUNICODE() (which returns a
UCS-2/wide-char string), or directly through the WinRT class,
Windows.Storage.ApplicationData.
Setup, High-Level Steps
-----------------------
The steps for setting up a project for an SDL/WinRT app looks like the
following, at a high-level:
1. create a new Visual C++ project using Microsoft's template for a,
   "Direct3D App".
2. remove most of the files from the project.
3. make your app's project directly reference SDL/WinRT's own Visual C++
   project file, via use of Visual C++'s "References" dialog.  This will setup
   the linker, and will copy SDL's .dll files to your app's final output.
4. adjust your app's build settings, at minimum, telling it where to find SDL's
   header files.
5. add a file that contains a WinRT-appropriate main function.
6. add SDL-specific app code.
7. build and run your app.
Setup, Detailed Steps
---------------------
### 1. Create a new project ###
Create a new project using one of Visual C++'s templates for a plain, non-XAML,
"Direct3D App" (XAML support for SDL/WinRT is not yet ready for use).  If you
don't see one of these templates, in Visual C++'s 'New Project' dialog, try
using the textbox titled, 'Search Installed Templates' to look for one.
### 2. Remove unneeded files from the project ###
In the new project, delete any file that has one of the following extensions:
- .cpp
- .h
- .hlsl
When you are done, you should be left with a few files, each of which will be a
necessary part of your app's project.  These files will consist of:
- an .appxmanifest file, which contains metadata on your WinRT app.  This is
  similar to an Info.plist file on iOS, or an AndroidManifest.xml on Android.
- a few .png files, one of which is a splash screen (displayed when your app
  launches), others are app icons.
- a .pfx file, used for code signing purposes.
### 3. Add references to SDL's project files ###
SDL/WinRT can be built in multiple variations, spanning across three different
CPU architectures (x86, x64, and ARM) and two different configurations
(Debug and Release).  WinRT and Visual C++ do not currently provide a means
for combining multiple variations of one library into a single file.
Furthermore, it does not provide an easy means for copying pre-built .dll files
into your app's final output (via Post-Build steps, for example).  It does,
however, provide a system whereby an app can reference the MSVC projects of
libraries such that, when the app is built:
1. each library gets built for the appropriate CPU architecture(s) and WinRT
   platform(s).
2. each library's output, such as .dll files, get copied to the app's build
   output.
To set this up for SDL/WinRT, you'll need to run through the following steps:
1. open up the Solution Explorer inside Visual C++ (under the "View" menu, then
   "Solution Explorer")
2. right click on your app's solution.
3. navigate to "Add", then to "Existing Project..."
4. find SDL/WinRT's Visual C++ project file and open it.  Different project
   files exist for different WinRT platforms.  All of them are in SDL's
   source distribution, in the following directories:
    * `VisualC-WinRT/UWP_VS2015/`        - for Windows 10 / UWP apps
    * `VisualC-WinRT/WinPhone81_VS2013/` - for Windows Phone 8.1 apps
    * `VisualC-WinRT/WinRT80_VS2012/`    - for Windows 8.0 apps
    * `VisualC-WinRT/WinRT81_VS2013/`    - for Windows 8.1 apps
5. once the project has been added, right-click on your app's project and
   select, "References..."
6. click on the button titled, "Add New Reference..."
7. check the box next to SDL
8. click OK to close the dialog
9. SDL will now show up in the list of references.  Click OK to close that
   dialog.
Your project is now linked to SDL's project, insofar that when the app is
built, SDL will be built as well, with its build output getting included with
your app.
### 4. Adjust Your App's Build Settings ###
Some build settings need to be changed in your app's project.  This guide will
outline the following:
- making sure that the compiler knows where to find SDL's header files
- **Optional for C++, but NECESSARY for compiling C code:** telling the
  compiler not to use Microsoft's C++ extensions for WinRT development.
- **Optional:** telling the compiler not generate errors due to missing
  precompiled header files.
To change these settings:
1. right-click on the project
2. choose "Properties"
3. in the drop-down box next to "Configuration", choose, "All Configurations"
4. in the drop-down box next to "Platform", choose, "All Platforms"
5. in the left-hand list, expand the "C/C++" section
6. select "General"
7. edit the "Additional Include Directories" setting, and add a path to SDL's
   "include" directory
8. **Optional: to enable compilation of C code:** change the setting for
   "Consume Windows Runtime Extension" from "Yes (/ZW)" to "No".  If you're
   working with a completely C++ based project, this step can usually be
   omitted.
9. **Optional: to disable precompiled headers (which can produce
   'stdafx.h'-related build errors, if setup incorrectly:** in the left-hand
   list, select "Precompiled Headers", then change the setting for "Precompiled
   Header" from "Use (/Yu)" to "Not Using Precompiled Headers".
10. close the dialog, saving settings, by clicking the "OK" button
### 5. Add a WinRT-appropriate main function to the app. ###
C/C++-based WinRT apps do contain a `main` function that the OS will invoke when
the app starts launching. The parameters of WinRT main functions are different
than those found on other platforms, Win32 included.  SDL/WinRT provides a
platform-appropriate main function that will perform these actions, setup key
portions of the app, then invoke a classic, C/C++-style main function (that take
in "argc" and "argv" parameters).  The code for this file is contained inside
SDL's source distribution, under `src/main/winrt/SDL_winrt_main_NonXAML.cpp`.
You'll need to add this file, or a copy of it, to your app's project, and make
sure it gets compiled using a Microsoft-specific set of C++ extensions called
C++/CX.
**NOTE: C++/CX compilation is currently required in at least one file of your
app's project.  This is to make sure that Visual C++'s linker builds a 'Windows
Metadata' file (.winmd) for your app.  Not doing so can lead to build errors.**
To include `SDL_winrt_main_NonXAML.cpp`:
1. right-click on your project (again, in Visual C++'s Solution Explorer),
   navigate to "Add", then choose "Existing Item...".
2. open `SDL_winrt_main_NonXAML.cpp`, which is found inside SDL's source
   distribution, under `src/main/winrt/`.  Make sure that the open-file dialog
   closes, either by double-clicking on the file, or single-clicking on it and
   then clicking Add.
3. right-click on the file (as listed in your project), then click on
   "Properties...".
4. in the drop-down box next to "Configuration", choose, "All Configurations"
5. in the drop-down box next to "Platform", choose, "All Platforms"
6. in the left-hand list, click on "C/C++"
7. change the setting for "Consume Windows Runtime Extension" to "Yes (/ZW)".
8. click the OK button.  This will close the dialog.
### 6. Add app code and assets ###
At this point, you can add in SDL-specific source code.  Be sure to include a
C-style main function (ie: `int main(int argc, char *argv[])`).  From there you
should be able to create a single `SDL_Window` (WinRT apps can only have one
window, at present), as well as an `SDL_Renderer`.  Direct3D will be used to
draw content.  Events are received via SDL's usual event functions
(`SDL_PollEvent`, etc.)  If you have a set of existing source files and assets,
you can start adding them to the project now.  If not, or if you would like to
make sure that you're setup correctly, some short and simple sample code is
provided below.
#### 6.A. ... when creating a new app ####
If you are creating a new app (rather than porting an existing SDL-based app),
or if you would just like a simple app to test SDL/WinRT with before trying to
get existing code working, some working SDL/WinRT code is provided below.  To
set this up:
1. right click on your app's project
2. select Add, then New Item.  An "Add New Item" dialog will show up.
3. from the left-hand list, choose "Visual C++"
4. from the middle/main list, choose "C++ File (.cpp)"
5. near the bottom of the dialog, next to "Name:", type in a name for your
source file, such as, "main.cpp".
6. click on the Add button.  This will close the dialog, add the new file to
your project, and open the file in Visual C++'s text editor.
7. Copy and paste the following code into the new file, then save it.
    #include <SDL.h>
    int main(int argc, char **argv)
    {
        SDL_DisplayMode mode;
        SDL_Window * window = NULL;
        SDL_Renderer * renderer = NULL;
        SDL_Event evt;
        if (SDL_Init(SDL_INIT_VIDEO) != 0) {
            return 1;
        }
        if (SDL_GetCurrentDisplayMode(0, &mode) != 0) {
            return 1;
        }
        if (SDL_CreateWindowAndRenderer(mode.w, mode.h, SDL_WINDOW_FULLSCREEN, &window, &renderer) != 0) {
            return 1;
        }
        while (1) {
            while (SDL_PollEvent(&evt)) {
            }
            SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
            SDL_RenderClear(renderer);
            SDL_RenderPresent(renderer);
        }
    }
#### 6.B. Adding code and assets ####
If you have existing code and assets that you'd like to add, you should be able
to add them now.  The process for adding a set of files is as such.
1. right click on the app's project
2. select Add, then click on "New Item..."
3. open any source, header, or asset files as appropriate.  Support for C and
C++ is available.
Do note that WinRT only supports a subset of the APIs that are available to
Win32-based apps.  Many portions of the Win32 API and the C runtime are not
available.
A list of unsupported C APIs can be found at
<http://msdn.microsoft.com/en-us/library/windows/apps/jj606124.aspx>
General information on using the C runtime in WinRT can be found at
<https://msdn.microsoft.com/en-us/library/hh972425.aspx>
A list of supported Win32 APIs for WinRT apps can be found at
<http://msdn.microsoft.com/en-us/library/windows/apps/br205757.aspx>.  To note,
the list of supported Win32 APIs for Windows Phone 8.0 is different.
That list can be found at
<http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj662956(v=vs.105).aspx>
### 7. Build and run your app ###
Your app project should now be setup, and you should be ready to build your app.
To run it on the local machine, open the Debug menu and choose "Start
Debugging".  This will build your app, then run your app full-screen.  To switch
out of your app, press the Windows key.  Alternatively, you can choose to run
your app in a window.  To do this, before building and running your app, find
the drop-down menu in Visual C++'s toolbar that says, "Local Machine".  Expand
this by clicking on the arrow on the right side of the list, then click on
Simulator.  Once you do that, any time you build and run the app, the app will
launch in window, rather than full-screen.
#### 7.A. Running apps on older, ARM-based, "Windows RT" devices ####
**These instructions do not include Windows Phone, despite Windows Phone
typically running on ARM processors.**  They are specifically for devices
that use the "Windows RT" operating system, which was a modified version of
Windows 8.x that ran primarily on ARM-based tablet computers.
To build and run the app on ARM-based, "Windows RT" devices, you'll need to:
- install Microsoft's "Remote Debugger" on the device.  Visual C++ installs and
  debugs ARM-based apps via IP networks.
- change a few options on the development machine, both to make sure it builds
  for ARM (rather than x86 or x64), and to make sure it knows how to find the
  Windows RT device (on the network).
Microsoft's Remote Debugger can be found at
<https://msdn.microsoft.com/en-us/library/hh441469.aspx>.  Please note
that separate versions of this debugger exist for different versions of Visual
C++, one each for MSVC 2015, 2013, and 2012.
To setup Visual C++ to launch your app on an ARM device:
1. make sure the Remote Debugger is running on your ARM device, and that it's on
   the same IP network as your development machine.
2. from Visual C++'s toolbar, find a drop-down menu that says, "Win32".  Click
   it, then change the value to "ARM".
3. make sure Visual C++ knows the hostname or IP address of the ARM device.  To
   do this:
    1. open the app project's properties
    2. select "Debugging"
    3. next to "Machine Name", enter the hostname or IP address of the ARM
       device
    4. if, and only if, you've turned off authentication in the Remote Debugger,
       then change the setting for "Require Authentication" to No
    5. click "OK"
4. build and run the app (from Visual C++).  The first time you do this, a
   prompt will show up on the ARM device, asking for a Microsoft Account.  You
   do, unfortunately, need to log in here, and will need to follow the
   subsequent registration steps in order to launch the app.  After you do so,
   if the app didn't already launch, try relaunching it again from within Visual
   C++.
Troubleshooting
---------------
#### Build fails with message, "error LNK2038: mismatch detected for 'vccorlib_lib_should_be_specified_before_msvcrt_lib_to_linker'"
Try adding the following to your linker flags.  In MSVC, this can be done by
right-clicking on the app project, navigating to Configuration Properties ->
Linker -> Command Line, then adding them to the Additional Options
section.
* For Release builds / MSVC-Configurations, add:
    /nodefaultlib:vccorlib /nodefaultlib:msvcrt vccorlib.lib msvcrt.lib
* For Debug builds / MSVC-Configurations, add:
    /nodefaultlib:vccorlibd /nodefaultlib:msvcrtd vccorlibd.lib msvcrtd.lib
WinRT
=====
This port allows SDL applications to run on Microsoft's platforms that require
use of "Windows Runtime", aka. "WinRT", APIs.  Microsoft may, in some cases,
refer to them as either "Windows Store", or for Windows 10, "UWP" apps.
Some of the operating systems that include WinRT, are:
* Windows 10, via its Universal Windows Platform (UWP) APIs
* Windows 8.x
* Windows RT 8.x (aka. Windows 8.x for ARM processors)
* Windows Phone 8.x
Requirements
------------
* Microsoft Visual C++ (aka Visual Studio), either 2015, 2013, or 2012
  - Free, "Community" or "Express" editions may be used, so long as they
    include  support for either "Windows Store" or "Windows Phone" apps.
    "Express" versions marked as supporting "Windows Desktop" development
    typically do not include support for creating WinRT apps, to note.
    (The "Community" editions of Visual C++ do, however, support both
    desktop/Win32 and WinRT development).
  - Visual C++ 2012 can only build apps that target versions 8.0 of Windows,
    or  Windows Phone.  8.0-targetted apps will run on devices running 8.1
    editions of Windows, however they will not be able to take advantage of
    8.1-specific features.
  - Visual C++ 2013 cannot create app projects that target Windows 8.0.
    Visual C++ 2013 Update 4, can create app projects for Windows Phone 8.0,
    Windows Phone 8.1, and Windows 8.1, but not Windows 8.0.  An optional
    Visual Studio add-in, "Tools for Maintaining Store apps for Windows 8",
    allows Visual C++ 2013 to load and build Windows 8.0 projects that were
    created with Visual C++ 2012, so long as Visual C++ 2012 is installed
    on the same machine.  More details on targeting different versions of
    Windows can found at the following web pages:
      - [Develop apps by using Visual Studio 2013](http://msdn.microsoft.com/en-us/library/windows/apps/br211384.aspx)
      - [To add the Tools for Maintaining Store apps for Windows 8](http://msdn.microsoft.com/en-us/library/windows/apps/dn263114.aspx#AddMaintenanceTools)
* A valid Microsoft account - This requirement is not imposed by SDL, but
  rather by Microsoft's Visual C++ toolchain.  This is required to launch or
  debug apps.
Status
------
Here is a rough list of what works, and what doens't:
* What works:
  * compilation via Visual C++ 2012 through 2015
  * compile-time platform detection for SDL programs.  The C/C++ #define,
    `__WINRT__`, will be set to 1 (by SDL) when compiling for WinRT.
  * GPU-accelerated 2D rendering, via SDL_Renderer.
  * OpenGL ES 2, via the ANGLE library (included separately from SDL)
  * software rendering, via either SDL_Surface (optionally in conjunction with
    SDL_GetWindowSurface() and SDL_UpdateWindowSurface()) or via the
    SDL_Renderer APIs
  * threads
  * timers (via SDL_GetTicks(), SDL_AddTimer(), SDL_GetPerformanceCounter(),
    SDL_GetPerformanceFrequency(), etc.)
  * file I/O via SDL_RWops
  * mouse input  (unsupported on Windows Phone)
  * audio, via a modified version of SDL's XAudio2 backend
  * .DLL file loading.  Libraries *MUST* be packaged inside applications.  Loading
    anything outside of the app is not supported.
  * system path retrieval via SDL's filesystem APIs
  * game controllers.  Support is provided via the SDL_Joystick and
    SDL_GameController APIs, and is backed by Microsoft's XInput API.
  * multi-touch input
  * app events.  SDL_APP_WILLENTER* and SDL_APP_DIDENTER* events get sent out as
    appropriate.
  * window events
  * using Direct3D 11.x APIs outside of SDL.  Non-XAML / Direct3D-only apps can
    choose to render content directly via Direct3D, using SDL to manage the
    internal WinRT window, as well as input and audio.  (Use
    SDL_GetWindowWMInfo() to get the WinRT 'CoreWindow', and pass it into
    IDXGIFactory2::CreateSwapChainForCoreWindow() as appropriate.)
* What partially works:
  * keyboard input.  Most of WinRT's documented virtual keys are supported, as
    well as many keys with documented hardware scancodes.  Converting
    SDL_Scancodes to or from SDL_Keycodes may not work, due to missing APIs
    (MapVirualKey()) in Microsoft's Windows Store / UWP APIs.
  * SDLmain.  WinRT uses a different signature for each app's main() function.
    SDL-based apps that use this port must compile in SDL_winrt_main_NonXAML.cpp
    (in `SDL\src\main\winrt\`) directly in order for their C-style main()
    functions to be called.
* What doesn't work:
  * compilation with anything other than Visual C++
  * programmatically-created custom cursors.  These don't appear to be supported
    by WinRT.  Different OS-provided cursors can, however, be created via
    SDL_CreateSystemCursor() (unsupported on Windows Phone)
  * SDL_WarpMouseInWindow() or SDL_WarpMouseGlobal().  This are not currently
    supported by WinRT itself.
  * joysticks and game controllers that aren't supported by Microsoft's XInput
    API.
  * turning off VSync when rendering on Windows Phone.  Attempts to turn VSync
    off on Windows Phone result either in Direct3D not drawing anything, or it
    forcing VSync back on.  As such, SDL_RENDERER_PRESENTVSYNC will always get
    turned-on on Windows Phone.  This limitation is not present in non-Phone
    WinRT (such as Windows 8.x), where turning off VSync appears to work.
  * probably anything else that's not listed as supported
Upgrade Notes
-------------
#### SDL_GetPrefPath() usage when upgrading WinRT apps from SDL 2.0.3
SDL 2.0.4 fixes two bugs found in the WinRT version of SDL_GetPrefPath().
The fixes may affect older, SDL 2.0.3-based apps' save data.  Please note
that these changes only apply to SDL-based WinRT apps, and not to apps for
any other platform.
1. SDL_GetPrefPath() would return an invalid path, one in which the path's
   directory had not been created.  Attempts to create files there
   (via fopen(), for example), would fail, unless that directory was
   explicitly created beforehand.
2. SDL_GetPrefPath(), for non-WinPhone-based apps, would return a path inside
   a WinRT 'Roaming' folder, the contents of which get automatically
   synchronized across multiple devices.  This process can occur while an
   application runs, and can cause existing save-data to be overwritten
   at unexpected times, with data from other devices.  (Windows Phone apps
   written with SDL 2.0.3 did not utilize a Roaming folder, due to API
   restrictions in Windows Phone 8.0).
SDL_GetPrefPath(), starting with SDL 2.0.4, addresses these by:
1. making sure that SDL_GetPrefPath() returns a directory in which data
   can be written to immediately, without first needing to create directories.
2. basing SDL_GetPrefPath() off of a different, non-Roaming folder, the
   contents of which do not automatically get synchronized across devices
   (and which require less work to use safely, in terms of data integrity).
Apps that wish to get their Roaming folder's path can do so either by using
SDL_WinRTGetFSPathUTF8(), SDL_WinRTGetFSPathUNICODE() (which returns a
UCS-2/wide-char string), or directly through the WinRT class,
Windows.Storage.ApplicationData.
Setup, High-Level Steps
-----------------------
The steps for setting up a project for an SDL/WinRT app looks like the
following, at a high-level:
1. create a new Visual C++ project using Microsoft's template for a,
   "Direct3D App".
2. remove most of the files from the project.
3. make your app's project directly reference SDL/WinRT's own Visual C++
   project file, via use of Visual C++'s "References" dialog.  This will setup
   the linker, and will copy SDL's .dll files to your app's final output.
4. adjust your app's build settings, at minimum, telling it where to find SDL's
   header files.
5. add files that contains a WinRT-appropriate main function, along with some
   data to make sure mouse-cursor-hiding (via SDL_ShowCursor(SDL_DISABLE) calls)
   work properly.
6. add SDL-specific app code.
7. build and run your app.
Setup, Detailed Steps
---------------------
### 1. Create a new project ###
Create a new project using one of Visual C++'s templates for a plain, non-XAML,
"Direct3D App" (XAML support for SDL/WinRT is not yet ready for use).  If you
don't see one of these templates, in Visual C++'s 'New Project' dialog, try
using the textbox titled, 'Search Installed Templates' to look for one.
### 2. Remove unneeded files from the project ###
In the new project, delete any file that has one of the following extensions:
- .cpp
- .h
- .hlsl
When you are done, you should be left with a few files, each of which will be a
necessary part of your app's project.  These files will consist of:
- an .appxmanifest file, which contains metadata on your WinRT app.  This is
  similar to an Info.plist file on iOS, or an AndroidManifest.xml on Android.
- a few .png files, one of which is a splash screen (displayed when your app
  launches), others are app icons.
- a .pfx file, used for code signing purposes.
### 3. Add references to SDL's project files ###
SDL/WinRT can be built in multiple variations, spanning across three different
CPU architectures (x86, x64, and ARM) and two different configurations
(Debug and Release).  WinRT and Visual C++ do not currently provide a means
for combining multiple variations of one library into a single file.
Furthermore, it does not provide an easy means for copying pre-built .dll files
into your app's final output (via Post-Build steps, for example).  It does,
however, provide a system whereby an app can reference the MSVC projects of
libraries such that, when the app is built:
1. each library gets built for the appropriate CPU architecture(s) and WinRT
   platform(s).
2. each library's output, such as .dll files, get copied to the app's build
   output.
To set this up for SDL/WinRT, you'll need to run through the following steps:
1. open up the Solution Explorer inside Visual C++ (under the "View" menu, then
   "Solution Explorer")
2. right click on your app's solution.
3. navigate to "Add", then to "Existing Project..."
4. find SDL/WinRT's Visual C++ project file and open it.  Different project
   files exist for different WinRT platforms.  All of them are in SDL's
   source distribution, in the following directories:
    * `VisualC-WinRT/UWP_VS2015/`        - for Windows 10 / UWP apps
    * `VisualC-WinRT/WinPhone81_VS2013/` - for Windows Phone 8.1 apps
    * `VisualC-WinRT/WinRT80_VS2012/`    - for Windows 8.0 apps
    * `VisualC-WinRT/WinRT81_VS2013/`    - for Windows 8.1 apps
5. once the project has been added, right-click on your app's project and
   select, "References..."
6. click on the button titled, "Add New Reference..."
7. check the box next to SDL
8. click OK to close the dialog
9. SDL will now show up in the list of references.  Click OK to close that
   dialog.
Your project is now linked to SDL's project, insofar that when the app is
built, SDL will be built as well, with its build output getting included with
your app.
### 4. Adjust Your App's Build Settings ###
Some build settings need to be changed in your app's project.  This guide will
outline the following:
- making sure that the compiler knows where to find SDL's header files
- **Optional for C++, but NECESSARY for compiling C code:** telling the
  compiler not to use Microsoft's C++ extensions for WinRT development.
- **Optional:** telling the compiler not generate errors due to missing
  precompiled header files.
To change these settings:
1. right-click on the project
2. choose "Properties"
3. in the drop-down box next to "Configuration", choose, "All Configurations"
4. in the drop-down box next to "Platform", choose, "All Platforms"
5. in the left-hand list, expand the "C/C++" section
6. select "General"
7. edit the "Additional Include Directories" setting, and add a path to SDL's
   "include" directory
8. **Optional: to enable compilation of C code:** change the setting for
   "Consume Windows Runtime Extension" from "Yes (/ZW)" to "No".  If you're
   working with a completely C++ based project, this step can usually be
   omitted.
9. **Optional: to disable precompiled headers (which can produce
   'stdafx.h'-related build errors, if setup incorrectly:** in the left-hand
   list, select "Precompiled Headers", then change the setting for "Precompiled
   Header" from "Use (/Yu)" to "Not Using Precompiled Headers".
10. close the dialog, saving settings, by clicking the "OK" button
### 5. Add a WinRT-appropriate main function, and a blank-cursor image, to the app. ###
A few files should be included directly in your app's MSVC project, specifically:
1. a WinRT-appropriate main function (which is different than main() functions on
   other platforms)
2. a Win32-style cursor resource, used by SDL_ShowCursor() to hide the mouse cursor
   (if and when the app needs to do so).  *If this cursor resource is not
   included, mouse-position reporting may fail if and when the cursor is
   hidden, due to possible bugs/design-oddities in Windows itself.*
To include these files:
1. right-click on your project (again, in Visual C++'s Solution Explorer),
   navigate to "Add", then choose "Existing Item...".
2. navigate to the directory containing SDL's source code, then into its
   subdirectory, 'src/main/winrt/'.  Select, then add, the following files:
   - `SDL_winrt_main_NonXAML.cpp`
   - `SDL2-WinRTResources.rc`
   - `SDL2-WinRTResource_BlankCursor.cur`
3. right-click on the file `SDL_winrt_main_NonXAML.cpp` (as listed in your
   project), then click on "Properties...".
4. in the drop-down box next to "Configuration", choose, "All Configurations"
5. in the drop-down box next to "Platform", choose, "All Platforms"
6. in the left-hand list, click on "C/C++"
7. change the setting for "Consume Windows Runtime Extension" to "Yes (/ZW)".
8. click the OK button.  This will close the dialog.
**NOTE: C++/CX compilation is currently required in at least one file of your
app's project.  This is to make sure that Visual C++'s linker builds a 'Windows
Metadata' file (.winmd) for your app.  Not doing so can lead to build errors.**
### 6. Add app code and assets ###
At this point, you can add in SDL-specific source code.  Be sure to include a
C-style main function (ie: `int main(int argc, char *argv[])`).  From there you
should be able to create a single `SDL_Window` (WinRT apps can only have one
window, at present), as well as an `SDL_Renderer`.  Direct3D will be used to
draw content.  Events are received via SDL's usual event functions
(`SDL_PollEvent`, etc.)  If you have a set of existing source files and assets,
you can start adding them to the project now.  If not, or if you would like to
make sure that you're setup correctly, some short and simple sample code is
provided below.
#### 6.A. ... when creating a new app ####
If you are creating a new app (rather than porting an existing SDL-based app),
or if you would just like a simple app to test SDL/WinRT with before trying to
get existing code working, some working SDL/WinRT code is provided below.  To
set this up:
1. right click on your app's project
2. select Add, then New Item.  An "Add New Item" dialog will show up.
3. from the left-hand list, choose "Visual C++"
4. from the middle/main list, choose "C++ File (.cpp)"
5. near the bottom of the dialog, next to "Name:", type in a name for your
source file, such as, "main.cpp".
6. click on the Add button.  This will close the dialog, add the new file to
your project, and open the file in Visual C++'s text editor.
7. Copy and paste the following code into the new file, then save it.
    #include <SDL.h>
    int main(int argc, char **argv)
    {
        SDL_DisplayMode mode;
        SDL_Window * window = NULL;
        SDL_Renderer * renderer = NULL;
        SDL_Event evt;
        if (SDL_Init(SDL_INIT_VIDEO) != 0) {
            return 1;
        }
        if (SDL_GetCurrentDisplayMode(0, &mode) != 0) {
            return 1;
        }
        if (SDL_CreateWindowAndRenderer(mode.w, mode.h, SDL_WINDOW_FULLSCREEN, &window, &renderer) != 0) {
            return 1;
        }
        while (1) {
            while (SDL_PollEvent(&evt)) {
            }
            SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
            SDL_RenderClear(renderer);
            SDL_RenderPresent(renderer);
        }
    }
#### 6.B. Adding code and assets ####
If you have existing code and assets that you'd like to add, you should be able
to add them now.  The process for adding a set of files is as such.
1. right click on the app's project
2. select Add, then click on "New Item..."
3. open any source, header, or asset files as appropriate.  Support for C and
C++ is available.
Do note that WinRT only supports a subset of the APIs that are available to
Win32-based apps.  Many portions of the Win32 API and the C runtime are not
available.
A list of unsupported C APIs can be found at
<http://msdn.microsoft.com/en-us/library/windows/apps/jj606124.aspx>
General information on using the C runtime in WinRT can be found at
<https://msdn.microsoft.com/en-us/library/hh972425.aspx>
A list of supported Win32 APIs for WinRT apps can be found at
<http://msdn.microsoft.com/en-us/library/windows/apps/br205757.aspx>.  To note,
the list of supported Win32 APIs for Windows Phone 8.0 is different.
That list can be found at
<http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj662956(v=vs.105).aspx>
### 7. Build and run your app ###
Your app project should now be setup, and you should be ready to build your app.
To run it on the local machine, open the Debug menu and choose "Start
Debugging".  This will build your app, then run your app full-screen.  To switch
out of your app, press the Windows key.  Alternatively, you can choose to run
your app in a window.  To do this, before building and running your app, find
the drop-down menu in Visual C++'s toolbar that says, "Local Machine".  Expand
this by clicking on the arrow on the right side of the list, then click on
Simulator.  Once you do that, any time you build and run the app, the app will
launch in window, rather than full-screen.
#### 7.A. Running apps on older, ARM-based, "Windows RT" devices ####
**These instructions do not include Windows Phone, despite Windows Phone
typically running on ARM processors.**  They are specifically for devices
that use the "Windows RT" operating system, which was a modified version of
Windows 8.x that ran primarily on ARM-based tablet computers.
To build and run the app on ARM-based, "Windows RT" devices, you'll need to:
- install Microsoft's "Remote Debugger" on the device.  Visual C++ installs and
  debugs ARM-based apps via IP networks.
- change a few options on the development machine, both to make sure it builds
  for ARM (rather than x86 or x64), and to make sure it knows how to find the
  Windows RT device (on the network).
Microsoft's Remote Debugger can be found at
<https://msdn.microsoft.com/en-us/library/hh441469.aspx>.  Please note
that separate versions of this debugger exist for different versions of Visual
C++, one each for MSVC 2015, 2013, and 2012.
To setup Visual C++ to launch your app on an ARM device:
1. make sure the Remote Debugger is running on your ARM device, and that it's on
   the same IP network as your development machine.
2. from Visual C++'s toolbar, find a drop-down menu that says, "Win32".  Click
   it, then change the value to "ARM".
3. make sure Visual C++ knows the hostname or IP address of the ARM device.  To
   do this:
    1. open the app project's properties
    2. select "Debugging"
    3. next to "Machine Name", enter the hostname or IP address of the ARM
       device
    4. if, and only if, you've turned off authentication in the Remote Debugger,
       then change the setting for "Require Authentication" to No
    5. click "OK"
4. build and run the app (from Visual C++).  The first time you do this, a
   prompt will show up on the ARM device, asking for a Microsoft Account.  You
   do, unfortunately, need to log in here, and will need to follow the
   subsequent registration steps in order to launch the app.  After you do so,
   if the app didn't already launch, try relaunching it again from within Visual
   C++.
Troubleshooting
---------------
#### Build fails with message, "error LNK2038: mismatch detected for 'vccorlib_lib_should_be_specified_before_msvcrt_lib_to_linker'"
Try adding the following to your linker flags.  In MSVC, this can be done by
right-clicking on the app project, navigating to Configuration Properties ->
Linker -> Command Line, then adding them to the Additional Options
section.
* For Release builds / MSVC-Configurations, add:
    /nodefaultlib:vccorlib /nodefaultlib:msvcrt vccorlib.lib msvcrt.lib
* For Debug builds / MSVC-Configurations, add:
    /nodefaultlib:vccorlibd /nodefaultlib:msvcrtd vccorlibd.lib msvcrtd.lib
#### Mouse-motion events fail to get sent, or SDL_GetMouseState() fails to return updated values
This may be caused by a bug in Windows itself, whereby hiding the mouse
cursor can cause mouse-position reporting to fail.
SDL provides a workaround for this, but it requires that an app links to a
set of Win32-style cursor image-resource files.  A copy of suitable resource
files can be found in `src/main/winrt/`.  Adding them to an app's Visual C++
project file should be sufficient to get the app to use them.
source/include/SDL.h
@@ -72,14 +72,14 @@
 *  specify the subsystems which you will be using in your application.
 */
/* @{ */
#define SDL_INIT_TIMER          0x00000001
#define SDL_INIT_AUDIO          0x00000010
#define SDL_INIT_VIDEO          0x00000020  /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
#define SDL_INIT_JOYSTICK       0x00000200  /**< SDL_INIT_JOYSTICK implies SDL_INIT_EVENTS */
#define SDL_INIT_HAPTIC         0x00001000
#define SDL_INIT_GAMECONTROLLER 0x00002000  /**< SDL_INIT_GAMECONTROLLER implies SDL_INIT_JOYSTICK */
#define SDL_INIT_EVENTS         0x00004000
#define SDL_INIT_NOPARACHUTE    0x00100000  /**< compatibility; this flag is ignored. */
#define SDL_INIT_TIMER          0x00000001u
#define SDL_INIT_AUDIO          0x00000010u
#define SDL_INIT_VIDEO          0x00000020u  /**< SDL_INIT_VIDEO implies SDL_INIT_EVENTS */
#define SDL_INIT_JOYSTICK       0x00000200u  /**< SDL_INIT_JOYSTICK implies SDL_INIT_EVENTS */
#define SDL_INIT_HAPTIC         0x00001000u
#define SDL_INIT_GAMECONTROLLER 0x00002000u  /**< SDL_INIT_GAMECONTROLLER implies SDL_INIT_JOYSTICK */
#define SDL_INIT_EVENTS         0x00004000u
#define SDL_INIT_NOPARACHUTE    0x00100000u  /**< compatibility; this flag is ignored. */
#define SDL_INIT_EVERYTHING ( \
                SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_EVENTS | \
                SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER \
@@ -95,8 +95,8 @@
 *  This function initializes specific SDL subsystems
 *
 *  Subsystem initialization is ref-counted, you must call
 *  SDL_QuitSubSystem for each SDL_InitSubSystem to correctly
 *  shutdown a subsystem manually (or call SDL_Quit to force shutdown).
 *  SDL_QuitSubSystem() for each SDL_InitSubSystem() to correctly
 *  shutdown a subsystem manually (or call SDL_Quit() to force shutdown).
 *  If a subsystem is already loaded then this call will
 *  increase the ref-count and return.
 */
source/include/SDL_audio.h
@@ -278,7 +278,8 @@
 *      protect data structures that it accesses by calling SDL_LockAudio()
 *      and SDL_UnlockAudio() in your code. Alternately, you may pass a NULL
 *      pointer here, and call SDL_QueueAudio() with some frequency, to queue
 *      more audio samples to be played.
 *      more audio samples to be played (or for capture devices, call
 *      SDL_DequeueAudio() with some frequency, to obtain audio samples).
 *    - \c desired->userdata is passed as the first parameter to your callback
 *      function. If you passed a NULL callback, this value is ignored.
 *
@@ -482,6 +483,10 @@
/**
 *  Queue more audio on non-callback devices.
 *
 *  (If you are looking to retrieve queued audio from a non-callback capture
 *  device, you want SDL_DequeueAudio() instead. This will return -1 to
 *  signify an error if you use it with capture devices.)
 *
 *  SDL offers two ways to feed audio to the device: you can either supply a
 *  callback that SDL triggers with some frequency to obtain more audio
 *  (pull method), or you can supply no callback, and then SDL will expect
@@ -517,20 +522,75 @@
extern DECLSPEC int SDLCALL SDL_QueueAudio(SDL_AudioDeviceID dev, const void *data, Uint32 len);
/**
 *  Dequeue more audio on non-callback devices.
 *
 *  (If you are looking to queue audio for output on a non-callback playback
 *  device, you want SDL_QueueAudio() instead. This will always return 0
 *  if you use it with playback devices.)
 *
 *  SDL offers two ways to retrieve audio from a capture device: you can
 *  either supply a callback that SDL triggers with some frequency as the
 *  device records more audio data, (push method), or you can supply no
 *  callback, and then SDL will expect you to retrieve data at regular
 *  intervals (pull method) with this function.
 *
 *  There are no limits on the amount of data you can queue, short of
 *  exhaustion of address space. Data from the device will keep queuing as
 *  necessary without further intervention from you. This means you will
 *  eventually run out of memory if you aren't routinely dequeueing data.
 *
 *  Capture devices will not queue data when paused; if you are expecting
 *  to not need captured audio for some length of time, use
 *  SDL_PauseAudioDevice() to stop the capture device from queueing more
 *  data. This can be useful during, say, level loading times. When
 *  unpaused, capture devices will start queueing data from that point,
 *  having flushed any capturable data available while paused.
 *
 *  This function is thread-safe, but dequeueing from the same device from
 *  two threads at once does not promise which thread will dequeued data
 *  first.
 *
 *  You may not dequeue audio from a device that is using an
 *  application-supplied callback; doing so returns an error. You have to use
 *  the audio callback, or dequeue audio with this function, but not both.
 *
 *  You should not call SDL_LockAudio() on the device before queueing; SDL
 *  handles locking internally for this function.
 *
 *  \param dev The device ID from which we will dequeue audio.
 *  \param data A pointer into where audio data should be copied.
 *  \param len The number of bytes (not samples!) to which (data) points.
 *  \return number of bytes dequeued, which could be less than requested.
 *
 *  \sa SDL_GetQueuedAudioSize
 *  \sa SDL_ClearQueuedAudio
 */
extern DECLSPEC Uint32 SDLCALL SDL_DequeueAudio(SDL_AudioDeviceID dev, void *data, Uint32 len);
/**
 *  Get the number of bytes of still-queued audio.
 *
 *  This is the number of bytes that have been queued for playback with
 *  SDL_QueueAudio(), but have not yet been sent to the hardware.
 *  For playback device:
 *
 *  Once we've sent it to the hardware, this function can not decide the exact
 *  byte boundary of what has been played. It's possible that we just gave the
 *  hardware several kilobytes right before you called this function, but it
 *  hasn't played any of it yet, or maybe half of it, etc.
 *    This is the number of bytes that have been queued for playback with
 *    SDL_QueueAudio(), but have not yet been sent to the hardware. This
 *    number may shrink at any time, so this only informs of pending data.
 *
 *    Once we've sent it to the hardware, this function can not decide the
 *    exact byte boundary of what has been played. It's possible that we just
 *    gave the hardware several kilobytes right before you called this
 *    function, but it hasn't played any of it yet, or maybe half of it, etc.
 *
 *  For capture devices:
 *
 *    This is the number of bytes that have been captured by the device and
 *    are waiting for you to dequeue. This number may grow at any time, so
 *    this only informs of the lower-bound of available data.
 *
 *  You may not queue audio on a device that is using an application-supplied
 *  callback; calling this function on such a device always returns 0.
 *  You have to use the audio callback or queue audio with SDL_QueueAudio(),
 *  but not both.
 *  You have to queue audio with SDL_QueueAudio()/SDL_DequeueAudio(), or use
 *  the audio callback, but not both.
 *
 *  You should not call SDL_LockAudio() on the device before querying; SDL
 *  handles locking internally for this function.
@@ -544,10 +604,17 @@
extern DECLSPEC Uint32 SDLCALL SDL_GetQueuedAudioSize(SDL_AudioDeviceID dev);
/**
 *  Drop any queued audio data waiting to be sent to the hardware.
 *  Drop any queued audio data. For playback devices, this is any queued data
 *  still waiting to be submitted to the hardware. For capture devices, this
 *  is any data that was queued by the device that hasn't yet been dequeued by
 *  the application.
 *
 *  Immediately after this call, SDL_GetQueuedAudioSize() will return 0 and
 *  the hardware will start playing silence if more audio isn't queued.
 *  Immediately after this call, SDL_GetQueuedAudioSize() will return 0. For
 *  playback devices, the hardware will start playing silence if more audio
 *  isn't queued. Unpaused capture devices will start filling the queue again
 *  as soon as they have more data available (which, depending on the state
 *  of the hardware and the thread, could be before this function call
 *  returns!).
 *
 *  This will not prevent playback of queued audio that's already been sent
 *  to the hardware, as we can not undo that, so expect there to be some
@@ -557,8 +624,8 @@
 *
 *  You may not queue audio on a device that is using an application-supplied
 *  callback; calling this function on such a device is always a no-op.
 *  You have to use the audio callback or queue audio with SDL_QueueAudio(),
 *  but not both.
 *  You have to queue audio with SDL_QueueAudio()/SDL_DequeueAudio(), or use
 *  the audio callback, but not both.
 *
 *  You should not call SDL_LockAudio() on the device before clearing the
 *  queue; SDL handles locking internally for this function.
source/include/SDL_config.h.cmake
@@ -81,6 +81,8 @@
#cmakedefine HAVE_PTHREAD_NP_H 1
#cmakedefine HAVE_LIBUDEV_H 1
#cmakedefine HAVE_DBUS_DBUS_H 1
#cmakedefine HAVE_IBUS_IBUS_H 1
#cmakedefine HAVE_FCITX_FRONTEND_H 1
/* C library functions */
#cmakedefine HAVE_MALLOC 1
source/include/SDL_config.h.in
@@ -82,6 +82,7 @@
#undef HAVE_LIBUDEV_H
#undef HAVE_DBUS_DBUS_H
#undef HAVE_IBUS_IBUS_H
#undef HAVE_FCITX_FRONTEND_H
/* C library functions */
#undef HAVE_MALLOC
@@ -356,4 +357,7 @@
#undef SDL_ASSEMBLY_ROUTINES
#undef SDL_ALTIVEC_BLITTERS
/* Enable ime support */
#undef SDL_USE_IME
#endif /* _SDL_config_h */
source/include/SDL_config_android.h
@@ -43,6 +43,7 @@
#define HAVE_STDINT_H   1
#define HAVE_CTYPE_H    1
#define HAVE_MATH_H 1
#define HAVE_SIGNAL_H 1
/* C library functions */
#define HAVE_MALLOC 1
@@ -75,6 +76,7 @@
#define HAVE_STRTOULL   1
#define HAVE_STRTOD 1
#define HAVE_ATOI   1
#define HAVE_ATOF 1
#define HAVE_STRCMP 1
#define HAVE_STRNCMP    1
#define HAVE_STRCASECMP 1
@@ -101,6 +103,7 @@
#define HAVE_SQRTF  1
#define HAVE_TAN    1
#define HAVE_TANF   1
#define HAVE_SIGACTION 1
#define HAVE_SETJMP 1
#define HAVE_NANOSLEEP  1
#define HAVE_SYSCONF    1
source/include/SDL_config_iphoneos.h
@@ -119,11 +119,7 @@
#define SDL_JOYSTICK_MFI 1
/* Enable Unix style SO loading */
/* Technically this works, but violates the iOS dev agreement prior to iOS 8 */
/* #define SDL_LOADSO_DLOPEN 1 */
/* Enable the stub shared object loader (src/loadso/dummy/\*.c) */
#define SDL_LOADSO_DISABLED 1
#define SDL_LOADSO_DLOPEN 1
/* Enable various threading systems */
#define SDL_THREAD_PTHREAD  1
source/include/SDL_events.h
@@ -136,6 +136,9 @@
    /* Drag and drop events */
    SDL_DROPFILE        = 0x1000, /**< The system requests a file open */
    SDL_DROPTEXT,                 /**< text/plain drag-and-drop event */
    SDL_DROPBEGIN,                /**< A new set of drops is beginning (NULL filename) */
    SDL_DROPCOMPLETE,             /**< Current set of drops is now complete (NULL filename) */
    /* Audio hotplug events */
    SDL_AUDIODEVICEADDED = 0x1100, /**< A new audio device is available */
@@ -461,9 +464,10 @@
 */
typedef struct SDL_DropEvent
{
    Uint32 type;        /**< ::SDL_DROPFILE */
    Uint32 type;        /**< ::SDL_DROPBEGIN or ::SDL_DROPFILE or ::SDL_DROPTEXT or ::SDL_DROPCOMPLETE */
    Uint32 timestamp;
    char *file;         /**< The file name, which should be freed with SDL_free() */
    char *file;         /**< The file name, which should be freed with SDL_free(), is NULL on begin/complete */
    Uint32 windowID;    /**< The window that was dropped on, if any */
} SDL_DropEvent;
source/include/SDL_gamecontroller.h
@@ -93,7 +93,7 @@
 *      }
 *  }
 *
 *  Using the SDL_HINT_GAMECONTROLLERCONFIG hint or the SDL_GameControllerAddMapping you can add support for controllers SDL is unaware of or cause an existing controller to have a different binding. The format is:
 *  Using the SDL_HINT_GAMECONTROLLERCONFIG hint or the SDL_GameControllerAddMapping() you can add support for controllers SDL is unaware of or cause an existing controller to have a different binding. The format is:
 *  guid,name,mappings
 *
 *  Where GUID is the string value from SDL_JoystickGetGUIDString(), name is the human readable string for the device and mappings are controller mappings to joystick ones.
@@ -136,14 +136,14 @@
/**
 *  Get a mapping string for a GUID
 *
 *  \return the mapping string.  Must be freed with SDL_free.  Returns NULL if no mapping is available
 *  \return the mapping string.  Must be freed with SDL_free().  Returns NULL if no mapping is available
 */
extern DECLSPEC char * SDLCALL SDL_GameControllerMappingForGUID( SDL_JoystickGUID guid );
/**
 *  Get a mapping string for an open GameController
 *
 *  \return the mapping string.  Must be freed with SDL_free.  Returns NULL if no mapping is available
 *  \return the mapping string.  Must be freed with SDL_free().  Returns NULL if no mapping is available
 */
extern DECLSPEC char * SDLCALL SDL_GameControllerMapping( SDL_GameController * gamecontroller );
source/include/SDL_haptic.h
@@ -149,7 +149,7 @@
 *
 *  \sa SDL_HapticCondition
 */
#define SDL_HAPTIC_CONSTANT   (1<<0)
#define SDL_HAPTIC_CONSTANT   (1u<<0)
/**
 *  \brief Sine wave effect supported.
@@ -158,7 +158,7 @@
 *
 *  \sa SDL_HapticPeriodic
 */
#define SDL_HAPTIC_SINE       (1<<1)
#define SDL_HAPTIC_SINE       (1u<<1)
/**
 *  \brief Left/Right effect supported.
@@ -169,7 +169,7 @@
 * \warning this value was SDL_HAPTIC_SQUARE right before 2.0.0 shipped. Sorry,
 *          we ran out of bits, and this is important for XInput devices.
 */
#define SDL_HAPTIC_LEFTRIGHT     (1<<2)
#define SDL_HAPTIC_LEFTRIGHT     (1u<<2)
/* !!! FIXME: put this back when we have more bits in 2.1 */
/* #define SDL_HAPTIC_SQUARE     (1<<2) */
@@ -181,7 +181,7 @@
 *
 *  \sa SDL_HapticPeriodic
 */
#define SDL_HAPTIC_TRIANGLE   (1<<3)
#define SDL_HAPTIC_TRIANGLE   (1u<<3)
/**
 *  \brief Sawtoothup wave effect supported.
@@ -190,7 +190,7 @@
 *
 *  \sa SDL_HapticPeriodic
 */
#define SDL_HAPTIC_SAWTOOTHUP (1<<4)
#define SDL_HAPTIC_SAWTOOTHUP (1u<<4)
/**
 *  \brief Sawtoothdown wave effect supported.
@@ -199,7 +199,7 @@
 *
 *  \sa SDL_HapticPeriodic
 */
#define SDL_HAPTIC_SAWTOOTHDOWN (1<<5)
#define SDL_HAPTIC_SAWTOOTHDOWN (1u<<5)
/**
 *  \brief Ramp effect supported.
@@ -208,7 +208,7 @@
 *
 *  \sa SDL_HapticRamp
 */
#define SDL_HAPTIC_RAMP       (1<<6)
#define SDL_HAPTIC_RAMP       (1u<<6)
/**
 *  \brief Spring effect supported - uses axes position.
@@ -218,7 +218,7 @@
 *
 *  \sa SDL_HapticCondition
 */
#define SDL_HAPTIC_SPRING     (1<<7)
#define SDL_HAPTIC_SPRING     (1u<<7)
/**
 *  \brief Damper effect supported - uses axes velocity.
@@ -228,7 +228,7 @@
 *
 *  \sa SDL_HapticCondition
 */
#define SDL_HAPTIC_DAMPER     (1<<8)
#define SDL_HAPTIC_DAMPER     (1u<<8)
/**
 *  \brief Inertia effect supported - uses axes acceleration.
@@ -238,7 +238,7 @@
 *
 *  \sa SDL_HapticCondition
 */
#define SDL_HAPTIC_INERTIA    (1<<9)
#define SDL_HAPTIC_INERTIA    (1u<<9)
/**
 *  \brief Friction effect supported - uses axes movement.
@@ -248,14 +248,14 @@
 *
 *  \sa SDL_HapticCondition
 */
#define SDL_HAPTIC_FRICTION   (1<<10)
#define SDL_HAPTIC_FRICTION   (1u<<10)
/**
 *  \brief Custom effect is supported.
 *
 *  User defined custom haptic effect.
 */
#define SDL_HAPTIC_CUSTOM     (1<<11)
#define SDL_HAPTIC_CUSTOM     (1u<<11)
/* @} *//* Haptic effects */
@@ -268,7 +268,7 @@
 *
 *  \sa SDL_HapticSetGain
 */
#define SDL_HAPTIC_GAIN       (1<<12)
#define SDL_HAPTIC_GAIN       (1u<<12)
/**
 *  \brief Device can set autocenter.
@@ -277,7 +277,7 @@
 *
 *  \sa SDL_HapticSetAutocenter
 */
#define SDL_HAPTIC_AUTOCENTER (1<<13)
#define SDL_HAPTIC_AUTOCENTER (1u<<13)
/**
 *  \brief Device can be queried for effect status.
@@ -286,7 +286,7 @@
 *
 *  \sa SDL_HapticGetEffectStatus
 */
#define SDL_HAPTIC_STATUS     (1<<14)
#define SDL_HAPTIC_STATUS     (1u<<14)
/**
 *  \brief Device can be paused.
@@ -294,7 +294,7 @@
 *  \sa SDL_HapticPause
 *  \sa SDL_HapticUnpause
 */
#define SDL_HAPTIC_PAUSE      (1<<15)
#define SDL_HAPTIC_PAUSE      (1u<<15)
/**
source/include/SDL_hints.h
@@ -233,15 +233,26 @@
#define SDL_HINT_GRAB_KEYBOARD              "SDL_GRAB_KEYBOARD"
/**
*  \brief  A variable controlling whether relative mouse mode is implemented using mouse warping
*
*  This variable can be set to the following values:
*    "0"       - Relative mouse mode uses raw input
*    "1"       - Relative mouse mode uses mouse warping
*
*  By default SDL will use raw input for relative mouse mode
*/
 *  \brief  A variable controlling whether relative mouse mode is implemented using mouse warping
 *
 *  This variable can be set to the following values:
 *    "0"       - Relative mouse mode uses raw input
 *    "1"       - Relative mouse mode uses mouse warping
 *
 *  By default SDL will use raw input for relative mouse mode
 */
#define SDL_HINT_MOUSE_RELATIVE_MODE_WARP    "SDL_MOUSE_RELATIVE_MODE_WARP"
/**
 *  \brief Allow mouse click events when clicking to focus an SDL window
 *
 *  This variable can be set to the following values:
 *    "0"       - Ignore mouse clicks that activate a window
 *    "1"       - Generate events for mouse clicks that activate a window
 *
 *  By default SDL will ignore mouse clicks that activate a window
 */
#define SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH "SDL_MOUSE_FOCUS_CLICKTHROUGH"
/**
 *  \brief Minimize your SDL_Window if it loses key focus when in fullscreen mode. Defaults to true.
@@ -257,8 +268,8 @@
 *  this is problematic. This functionality can be disabled by setting this
 *  hint.
 *
 *  As of SDL 2.0.4, SDL_EnableScreenSaver and SDL_DisableScreenSaver accomplish
 *  the same thing on iOS. They should be preferred over this hint.
 *  As of SDL 2.0.4, SDL_EnableScreenSaver() and SDL_DisableScreenSaver()
 *  accomplish the same thing on iOS. They should be preferred over this hint.
 *
 *  This variable can be set to the following values:
 *    "0"       - Enable idle timer
@@ -276,7 +287,35 @@
 *    "LandscapeLeft", "LandscapeRight", "Portrait" "PortraitUpsideDown"
 */
#define SDL_HINT_ORIENTATIONS "SDL_IOS_ORIENTATIONS"
/**
 *  \brief  A variable controlling whether controllers used with the Apple TV
 *  generate UI events.
 *
 * When UI events are generated by controller input, the app will be
 * backgrounded when the Apple TV remote's menu button is pressed, and when the
 * pause or B buttons on gamepads are pressed.
 *
 * More information about properly making use of controllers for the Apple TV
 * can be found here:
 * https://developer.apple.com/tvos/human-interface-guidelines/remote-and-controllers/
 *
 *  This variable can be set to the following values:
 *    "0"       - Controller input does not generate UI events (the default).
 *    "1"       - Controller input generates UI events.
 */
#define SDL_HINT_APPLE_TV_CONTROLLER_UI_EVENTS "SDL_APPLE_TV_CONTROLLER_UI_EVENTS"
/**
 * \brief  A variable controlling whether the Apple TV remote's joystick axes
 *         will automatically match the rotation of the remote.
 *
 *  This variable can be set to the following values:
 *    "0"       - Remote orientation does not affect joystick axes (the default).
 *    "1"       - Joystick axes are based on the orientation of the remote.
 */
#define SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION "SDL_APPLE_TV_REMOTE_ALLOW_ROTATION"
/**
 *  \brief  A variable controlling whether the Android / iOS built-in
 *  accelerometer should be listed as a joystick device, rather than listing
@@ -369,7 +408,7 @@
*  Use this hint in case you need to set SDL's threads stack size to other than the default.
*  This is specially useful if you build SDL against a non glibc libc library (such as musl) which
*  provides a relatively small default thread stack size (a few kilobytes versus the default 8MB glibc uses).
*  Support for this hint is currently available only in the pthread backend.
*  Support for this hint is currently available only in the pthread, Windows, and PSP backend.
*/
#define SDL_HINT_THREAD_STACK_SIZE              "SDL_THREAD_STACK_SIZE"
@@ -431,7 +470,7 @@
 *  privacy policy.
 *
 *  To setup a URL to an app's privacy policy, set SDL_HINT_WINRT_PRIVACY_POLICY_URL
 *  before calling any SDL_Init functions.  The contents of the hint should
 *  before calling any SDL_Init() functions.  The contents of the hint should
 *  be a valid URL.  For example, "http://www.example.com".
 *
 *  The default value is "", which will prevent SDL from adding a privacy policy
@@ -461,7 +500,7 @@
 *  The contents of this hint should be encoded as a UTF8 string.
 *
 *  The default value is "Privacy Policy".  This hint should only be set during app
 *  initialization, preferably before any calls to SDL_Init.
 *  initialization, preferably before any calls to SDL_Init().
 *
 *  For additional information on linking to a privacy policy, see the documentation for
 *  SDL_HINT_WINRT_PRIVACY_POLICY_URL.
@@ -631,6 +670,44 @@
#define SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4    "SDL_WINDOWS_NO_CLOSE_ON_ALT_F4"
/**
 *  \brief Prevent SDL from using version 4 of the bitmap header when saving BMPs.
 *
 * The bitmap header version 4 is required for proper alpha channel support and
 * SDL will use it when required. Should this not be desired, this hint can
 * force the use of the 40 byte header version which is supported everywhere.
 *
 * The variable can be set to the following values:
 *   "0"       - Surfaces with a colorkey or an alpha channel are saved to a
 *               32-bit BMP file with an alpha mask. SDL will use the bitmap
 *               header version 4 and set the alpha mask accordingly.
 *   "1"       - Surfaces with a colorkey or an alpha channel are saved to a
 *               32-bit BMP file without an alpha mask. The alpha channel data
 *               will be in the file, but applications are going to ignore it.
 *
 * The default value is "0".
 */
#define SDL_HINT_BMP_SAVE_LEGACY_FORMAT "SDL_BMP_SAVE_LEGACY_FORMAT"
/**
 * \brief Tell SDL not to name threads on Windows.
 *
 * The variable can be set to the following values:
 *   "0"       - SDL will raise the 0x406D1388 Exception to name threads.
 *               This is the default behavior of SDL <= 2.0.4. (default)
 *   "1"       - SDL will not raise this exception, and threads will be unnamed.
 *               For .NET languages this is required when running under a debugger.
 */
#define SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING "SDL_WINDOWS_DISABLE_THREAD_NAMING"
/**
 * \brief Tell SDL which Dispmanx layer to use on a Raspberry PI
 *
 * Also known as Z-order. The variable can take a negative or positive value.
 * The default is 10000.
 */
#define SDL_HINT_RPI_VIDEO_LAYER           "SDL_RPI_VIDEO_LAYER"
/**
 *  \brief  An enumeration of hint priorities
 */
typedef enum
@@ -670,6 +747,13 @@
extern DECLSPEC const char * SDLCALL SDL_GetHint(const char *name);
/**
 *  \brief Get a hint
 *
 *  \return The boolean value of a hint variable.
 */
extern DECLSPEC SDL_bool SDLCALL SDL_GetHintBoolean(const char *name, SDL_bool default_value);
/**
 *  \brief Add a function to watch a particular hint
 *
 *  \param name The hint to watch
source/include/SDL_joystick.h
@@ -24,7 +24,7 @@
 *
 *  Include file for SDL joystick event handling
 *
 * The term "device_index" identifies currently plugged in joystick devices between 0 and SDL_NumJoysticks, with the exact joystick
 * The term "device_index" identifies currently plugged in joystick devices between 0 and SDL_NumJoysticks(), with the exact joystick
 *   behind a device_index changing as joysticks are plugged and unplugged.
 *
 * The term "instance_id" is the current instantiation of a joystick device in the system, if the joystick is removed and then re-inserted
source/include/SDL_keyboard.h
@@ -136,7 +136,7 @@
 *          copy it.  If the key doesn't have a name, this function returns an
 *          empty string ("").
 *
 *  \sa SDL_Key
 *  \sa SDL_Keycode
 */
extern DECLSPEC const char *SDLCALL SDL_GetKeyName(SDL_Keycode key);
source/include/SDL_main.h
@@ -63,7 +63,7 @@
/* On Android SDL provides a Java class in SDLActivity.java that is the
   main activity entry point.
   See README-android.txt for more details on extending that class.
   See README-android.md for more details on extending that class.
 */
#define SDL_MAIN_NEEDED
source/include/SDL_mouse.h
@@ -41,7 +41,7 @@
typedef struct SDL_Cursor SDL_Cursor;   /* Implementation dependent */
/**
 * \brief Cursor types for SDL_CreateSystemCursor.
 * \brief Cursor types for SDL_CreateSystemCursor().
 */
typedef enum
{
@@ -254,9 +254,11 @@
extern DECLSPEC SDL_Cursor *SDLCALL SDL_GetDefaultCursor(void);
/**
 *  \brief Frees a cursor created with SDL_CreateCursor().
 *  \brief Frees a cursor created with SDL_CreateCursor() or similar functions.
 *
 *  \sa SDL_CreateCursor()
 *  \sa SDL_CreateColorCursor()
 *  \sa SDL_CreateSystemCursor()
 */
extern DECLSPEC void SDLCALL SDL_FreeCursor(SDL_Cursor * cursor);
source/include/SDL_opengles.h
@@ -24,6 +24,7 @@
 *
 *  This is a simple file to encapsulate the OpenGL ES 1.X API headers.
 */
#include "SDL_config.h"
#ifdef __IPHONEOS__
#include <OpenGLES/ES1/gl.h>
source/include/SDL_opengles2.h
@@ -24,6 +24,8 @@
 *
 *  This is a simple file to encapsulate the OpenGL ES 2.0 API headers.
 */
#include "SDL_config.h"
#ifndef _MSC_VER
#ifdef __IPHONEOS__
source/include/SDL_pixels.h
@@ -29,6 +29,7 @@
#define _SDL_pixels_h
#include "SDL_stdinc.h"
#include "SDL_endian.h"
#include "begin_code.h"
/* Set up for C function definitions, even when using C++ */
@@ -260,6 +261,19 @@
        SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ARGB,
                               SDL_PACKEDLAYOUT_2101010, 32, 4),
    /* Aliases for RGBA byte arrays of color data, for the current platform */
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
    SDL_PIXELFORMAT_RGBA32 = SDL_PIXELFORMAT_RGBA8888,
    SDL_PIXELFORMAT_ARGB32 = SDL_PIXELFORMAT_ARGB8888,
    SDL_PIXELFORMAT_BGRA32 = SDL_PIXELFORMAT_BGRA8888,
    SDL_PIXELFORMAT_ABGR32 = SDL_PIXELFORMAT_ABGR8888,
#else
    SDL_PIXELFORMAT_RGBA32 = SDL_PIXELFORMAT_ABGR8888,
    SDL_PIXELFORMAT_ARGB32 = SDL_PIXELFORMAT_BGRA8888,
    SDL_PIXELFORMAT_BGRA32 = SDL_PIXELFORMAT_ARGB8888,
    SDL_PIXELFORMAT_ABGR32 = SDL_PIXELFORMAT_RGBA8888,
#endif
    SDL_PIXELFORMAT_YV12 =      /**< Planar mode: Y + V + U  (3 planes) */
        SDL_DEFINE_PIXELFOURCC('Y', 'V', '1', '2'),
    SDL_PIXELFORMAT_IYUV =      /**< Planar mode: Y + U + V  (3 planes) */
source/include/SDL_platform.h
@@ -70,18 +70,22 @@
/* lets us know what version of Mac OS X we're compiling on */
#include "AvailabilityMacros.h"
#include "TargetConditionals.h"
#if TARGET_OS_TV
#undef __TVOS__
#define __TVOS__ 1
#endif
#if TARGET_OS_IPHONE
/* if compiling for iPhone */
/* if compiling for iOS */
#undef __IPHONEOS__
#define __IPHONEOS__ 1
#undef __MACOSX__
#else
/* if not compiling for iPhone */
/* if not compiling for iOS */
#undef __MACOSX__
#define __MACOSX__  1
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050
# error SDL for Mac OS X only supports deploying on 10.5 and above.
#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < 1050 */
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
# error SDL for Mac OS X only supports deploying on 10.6 and above.
#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < 1060 */
#endif /* TARGET_OS_IPHONE */
#endif /* defined(__APPLE__) */
source/include/SDL_render.h
@@ -500,6 +500,30 @@
extern DECLSPEC void SDLCALL SDL_RenderGetLogicalSize(SDL_Renderer * renderer, int *w, int *h);
/**
 *  \brief Set whether to force integer scales for resolution-independent rendering
 *
 *  \param renderer The renderer for which integer scaling should be set.
 *  \param enable   Enable or disable integer scaling
 *
 *  This function restricts the logical viewport to integer values - that is, when
 *  a resolution is between two multiples of a logical size, the viewport size is
 *  rounded down to the lower multiple.
 *
 *  \sa SDL_RenderSetLogicalSize()
 */
extern DECLSPEC int SDLCALL SDL_RenderSetIntegerScale(SDL_Renderer * renderer,
                                                      SDL_bool enable);
/**
 *  \brief Get whether integer scales are forced for resolution-independent rendering
 *
 *  \param renderer The renderer from which integer scaling should be queried.
 *
 *  \sa SDL_RenderSetIntegerScale()
 */
extern DECLSPEC SDL_bool SDLCALL SDL_RenderGetIntegerScale(SDL_Renderer * renderer);
/**
 *  \brief Set the drawing area for rendering on the current target.
 *
 *  \param renderer The renderer for which the drawing area should be set.
@@ -658,7 +682,8 @@
/**
 *  \brief Clear the current rendering target with the drawing color
 *
 *  This function clears the entire rendering target, ignoring the viewport.
 *  This function clears the entire rendering target, ignoring the viewport and
 *  the clip rectangle.
 *
 *  \return 0 on success, or -1 on error
 */
source/include/SDL_rwops.h
@@ -39,12 +39,12 @@
#endif
/* RWops Types */
#define SDL_RWOPS_UNKNOWN   0   /* Unknown stream type */
#define SDL_RWOPS_WINFILE   1   /* Win32 file */
#define SDL_RWOPS_STDFILE   2   /* Stdio file */
#define SDL_RWOPS_JNIFILE   3   /* Android asset */
#define SDL_RWOPS_MEMORY    4   /* Memory stream */
#define SDL_RWOPS_MEMORY_RO 5   /* Read-Only memory stream */
#define SDL_RWOPS_UNKNOWN   0U  /* Unknown stream type */
#define SDL_RWOPS_WINFILE   1U  /* Win32 file */
#define SDL_RWOPS_STDFILE   2U  /* Stdio file */
#define SDL_RWOPS_JNIFILE   3U  /* Android asset */
#define SDL_RWOPS_MEMORY    4U  /* Memory stream */
#define SDL_RWOPS_MEMORY_RO 5U  /* Read-Only memory stream */
/**
 * This is the read/write operation structure -- very basic.
source/include/SDL_stdinc.h
@@ -83,9 +83,6 @@
#ifdef HAVE_FLOAT_H
# include <float.h>
#endif
#if defined(HAVE_ICONV) && defined(HAVE_ICONV_H)
# include <iconv.h>
#endif
/**
 *  The number of elements in an array.
@@ -94,6 +91,13 @@
#define SDL_TABLESIZE(table)    SDL_arraysize(table)
/**
 *  Macro useful for building other macros with strings in them
 *
 *  e.g. #define LOG_ERROR(X) OutputDebugString(SDL_STRINGIFY_ARG(__FUNCTION__) ": " X "\n")
 */
#define SDL_STRINGIFY_ARG(arg)  #arg
/**
 *  \name Cast operators
 *
 *  Use proper C++ casts when compiled as C++ to be compatible with the option
source/include/SDL_surface.h
@@ -118,6 +118,8 @@
extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurface
    (Uint32 flags, int width, int height, int depth,
     Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask);
extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurfaceWithFormat
    (Uint32 flags, int width, int height, int depth, Uint32 format);
extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurfaceFrom(void *pixels,
                                                              int width,
                                                              int height,
@@ -127,6 +129,8 @@
                                                              Uint32 Gmask,
                                                              Uint32 Bmask,
                                                              Uint32 Amask);
extern DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurfaceWithFormatFrom
    (void *pixels, int width, int height, int depth, int pitch, Uint32 format);
extern DECLSPEC void SDLCALL SDL_FreeSurface(SDL_Surface * surface);
/**
@@ -184,6 +188,12 @@
/**
 *  Save a surface to a seekable SDL data stream (memory or file).
 *
 *  Surfaces with a 24-bit, 32-bit and paletted 8-bit format get saved in the
 *  BMP directly. Other RGB formats with 8-bit or higher get converted to a
 *  24-bit surface or, if they have an alpha mask or a colorkey, to a 32-bit
 *  surface before they are saved. YUV and paletted 1-bit and 4-bit formats are
 *  not supported.
 *
 *  If \c freedst is non-zero, the stream will be closed after being written.
 *
 *  \return 0 if successful or -1 if there was an error.
source/include/SDL_syswm.h
@@ -106,6 +106,10 @@
typedef void *EGLSurface;
#endif
#if defined(SDL_VIDEO_DRIVER_VIVANTE)
#include "SDL_egl.h"
#endif
/**
 *  These are the various supported windowing subsystems
 */
@@ -120,7 +124,8 @@
    SDL_SYSWM_WAYLAND,
    SDL_SYSWM_MIR,
    SDL_SYSWM_WINRT,
    SDL_SYSWM_ANDROID
    SDL_SYSWM_ANDROID,
    SDL_SYSWM_VIVANTE
} SDL_SYSWM_TYPE;
/**
@@ -166,6 +171,13 @@
            int dummy;
            /* No UIKit window events yet */
        } uikit;
#endif
#if defined(SDL_VIDEO_DRIVER_VIVANTE)
        struct
        {
            int dummy;
            /* No Vivante window events yet */
        } vivante;
#endif
        /* Can't have an empty union */
        int dummy;
@@ -259,6 +271,14 @@
        } android;
#endif
#if defined(SDL_VIDEO_DRIVER_VIVANTE)
        struct
        {
            EGLNativeDisplayType display;
            EGLNativeWindowType window;
        } vivante;
#endif
        /* Can't have an empty union */
        int dummy;
    } info;
source/include/SDL_version.h
@@ -59,7 +59,7 @@
*/
#define SDL_MAJOR_VERSION   2
#define SDL_MINOR_VERSION   0
#define SDL_PATCHLEVEL      4
#define SDL_PATCHLEVEL      5
/**
 *  \brief Macro to determine SDL version program was compiled against.
source/include/SDL_video.h
@@ -83,6 +83,7 @@
 *  \sa SDL_SetWindowPosition()
 *  \sa SDL_SetWindowSize()
 *  \sa SDL_SetWindowBordered()
 *  \sa SDL_SetWindowResizable()
 *  \sa SDL_SetWindowTitle()
 *  \sa SDL_ShowWindow()
 */
@@ -95,6 +96,7 @@
 */
typedef enum
{
    /* !!! FIXME: change this to name = (1<<x). */
    SDL_WINDOW_FULLSCREEN = 0x00000001,         /**< fullscreen window */
    SDL_WINDOW_OPENGL = 0x00000002,             /**< window usable with OpenGL context */
    SDL_WINDOW_SHOWN = 0x00000004,              /**< window is visible */
@@ -109,13 +111,18 @@
    SDL_WINDOW_FULLSCREEN_DESKTOP = ( SDL_WINDOW_FULLSCREEN | 0x00001000 ),
    SDL_WINDOW_FOREIGN = 0x00000800,            /**< window not created by SDL */
    SDL_WINDOW_ALLOW_HIGHDPI = 0x00002000,      /**< window should be created in high-DPI mode if supported */
    SDL_WINDOW_MOUSE_CAPTURE = 0x00004000       /**< window has mouse captured (unrelated to INPUT_GRABBED) */
    SDL_WINDOW_MOUSE_CAPTURE = 0x00004000,      /**< window has mouse captured (unrelated to INPUT_GRABBED) */
    SDL_WINDOW_ALWAYS_ON_TOP = 0x00008000,      /**< window should always be above others */
    SDL_WINDOW_SKIP_TASKBAR  = 0x00010000,      /**< window should not be added to the taskbar */
    SDL_WINDOW_UTILITY       = 0x00020000,      /**< window should be treated as a utility window */
    SDL_WINDOW_TOOLTIP       = 0x00040000,      /**< window should be treated as a tooltip */
    SDL_WINDOW_POPUP_MENU    = 0x00080000       /**< window should be treated as a popup menu */
} SDL_WindowFlags;
/**
 *  \brief Used to indicate that you don't care what the window position is.
 */
#define SDL_WINDOWPOS_UNDEFINED_MASK    0x1FFF0000
#define SDL_WINDOWPOS_UNDEFINED_MASK    0x1FFF0000u
#define SDL_WINDOWPOS_UNDEFINED_DISPLAY(X)  (SDL_WINDOWPOS_UNDEFINED_MASK|(X))
#define SDL_WINDOWPOS_UNDEFINED         SDL_WINDOWPOS_UNDEFINED_DISPLAY(0)
#define SDL_WINDOWPOS_ISUNDEFINED(X)    \
@@ -124,7 +131,7 @@
/**
 *  \brief Used to indicate that the window position should be centered.
 */
#define SDL_WINDOWPOS_CENTERED_MASK    0x2FFF0000
#define SDL_WINDOWPOS_CENTERED_MASK    0x2FFF0000u
#define SDL_WINDOWPOS_CENTERED_DISPLAY(X)  (SDL_WINDOWPOS_CENTERED_MASK|(X))
#define SDL_WINDOWPOS_CENTERED         SDL_WINDOWPOS_CENTERED_DISPLAY(0)
#define SDL_WINDOWPOS_ISCENTERED(X)    \
@@ -154,8 +161,9 @@
    SDL_WINDOWEVENT_LEAVE,          /**< Window has lost mouse focus */
    SDL_WINDOWEVENT_FOCUS_GAINED,   /**< Window has gained keyboard focus */
    SDL_WINDOWEVENT_FOCUS_LOST,     /**< Window has lost keyboard focus */
    SDL_WINDOWEVENT_CLOSE           /**< The window manager requests that the
                                         window be closed */
    SDL_WINDOWEVENT_CLOSE,          /**< The window manager requests that the window be closed */
    SDL_WINDOWEVENT_TAKE_FOCUS,     /**< Window is being offered a focus (should SetWindowInputFocus() on itself or a subwindow, or ignore) */
    SDL_WINDOWEVENT_HIT_TEST        /**< Window had a hit test that wasn't SDL_HITTEST_NORMAL. */
} SDL_WindowEventID;
/**
@@ -311,6 +319,25 @@
extern DECLSPEC int SDLCALL SDL_GetDisplayDPI(int displayIndex, float * ddpi, float * hdpi, float * vdpi);
/**
 *  \brief Get the usable desktop area represented by a display, with the
 *         primary display located at 0,0
 *
 *  This is the same area as SDL_GetDisplayBounds() reports, but with portions
 *  reserved by the system removed. For example, on Mac OS X, this subtracts
 *  the area occupied by the menu bar and dock.
 *
 *  Setting a window to be fullscreen generally bypasses these unusable areas,
 *  so these are good guidelines for the maximum space available to a
 *  non-fullscreen window.
 *
 *  \return 0 on success, or -1 if the index is out of range.
 *
 *  \sa SDL_GetDisplayBounds()
 *  \sa SDL_GetNumVideoDisplays()
 */
extern DECLSPEC int SDLCALL SDL_GetDisplayUsableBounds(int displayIndex, SDL_Rect * rect);
/**
 *  \brief Returns the number of available display modes.
 *
 *  \sa SDL_GetDisplayMode()
@@ -423,7 +450,7 @@
 *               ::SDL_WINDOW_MINIMIZED,     ::SDL_WINDOW_INPUT_GRABBED,
 *               ::SDL_WINDOW_ALLOW_HIGHDPI.
 *
 *  \return The id of the window created, or zero if window creation failed.
 *  \return The created window, or NULL if window creation failed.
 *
 *  If the window is created with the SDL_WINDOW_ALLOW_HIGHDPI flag, its size
 *  in pixels may differ from its size in screen coordinates on platforms with
@@ -442,7 +469,7 @@
 *
 *  \param data A pointer to driver-dependent window creation data
 *
 *  \return The id of the window created, or zero if window creation failed.
 *  \return The created window, or NULL if window creation failed.
 *
 *  \sa SDL_DestroyWindow()
 */
@@ -587,6 +614,25 @@
                                               int *h);
/**
 *  \brief Get the size of a window's borders (decorations) around the client area.
 *
 *  \param window The window to query.
 *  \param top Pointer to variable for storing the size of the top border. NULL is permitted.
 *  \param left Pointer to variable for storing the size of the left border. NULL is permitted.
 *  \param bottom Pointer to variable for storing the size of the bottom border. NULL is permitted.
 *  \param right Pointer to variable for storing the size of the right border. NULL is permitted.
 *
 *  \return 0 on success, or -1 if getting this information is not supported.
 *
 *  \note if this function fails (returns -1), the size values will be
 *        initialized to 0, 0, 0, 0 (if a non-NULL pointer is provided), as
 *        if the window in question was borderless.
 */
extern DECLSPEC int SDLCALL SDL_GetWindowBordersSize(SDL_Window * window,
                                                     int *top, int *left,
                                                     int *bottom, int *right);
/**
 *  \brief Set the minimum size of a window's client area.
 *
 *  \param window    The window to set a new minimum size.
@@ -660,6 +706,23 @@
 */
extern DECLSPEC void SDLCALL SDL_SetWindowBordered(SDL_Window * window,
                                                   SDL_bool bordered);
/**
 *  \brief Set the user-resizable state of a window.
 *
 *  This will add or remove the window's SDL_WINDOW_RESIZABLE flag and
 *  allow/disallow user resizing of the window. This is a no-op if the
 *  window's resizable state already matches the requested state.
 *
 *  \param window The window of which to change the resizable state.
 *  \param resizable SDL_TRUE to allow resizing, SDL_FALSE to disallow.
 *
 *  \note You can't change the resizable state of a fullscreen window.
 *
 *  \sa SDL_GetWindowFlags()
 */
extern DECLSPEC void SDLCALL SDL_SetWindowResizable(SDL_Window * window,
                                                    SDL_bool resizable);
/**
 *  \brief Show a window.
@@ -744,7 +807,7 @@
 *  \return 0 on success, or -1 on error.
 *
 *  \sa SDL_GetWindowSurface()
 *  \sa SDL_UpdateWindowSurfaceRect()
 *  \sa SDL_UpdateWindowSurface()
 */
extern DECLSPEC int SDLCALL SDL_UpdateWindowSurfaceRects(SDL_Window * window,
                                                         const SDL_Rect * rects,
@@ -800,6 +863,58 @@
 *  \sa SDL_SetWindowBrightness()
 */
extern DECLSPEC float SDLCALL SDL_GetWindowBrightness(SDL_Window * window);
/**
 *  \brief Set the opacity for a window
 *
 *  \param window The window which will be made transparent or opaque
 *  \param opacity Opacity (0.0f - transparent, 1.0f - opaque) This will be
 *                 clamped internally between 0.0f and 1.0f.
 *
 *  \return 0 on success, or -1 if setting the opacity isn't supported.
 *
 *  \sa SDL_GetWindowOpacity()
 */
extern DECLSPEC int SDLCALL SDL_SetWindowOpacity(SDL_Window * window, float opacity);
/**
 *  \brief Get the opacity of a window.
 *
 *  If transparency isn't supported on this platform, opacity will be reported
 *  as 1.0f without error.
 *
 *  \param window The window in question.
 *  \param out_opacity Opacity (0.0f - transparent, 1.0f - opaque)
 *
 *  \return 0 on success, or -1 on error (invalid window, etc).
 *
 *  \sa SDL_SetWindowOpacity()
 */
extern DECLSPEC int SDLCALL SDL_GetWindowOpacity(SDL_Window * window, float * out_opacity);
/**
 *  \brief Sets the window as a modal for another window (TODO: reconsider this function and/or its name)
 *
 *  \param modal_window The window that should be modal
 *  \param parent_window The parent window
 *
 *  \return 0 on success, or -1 otherwise.
 */
extern DECLSPEC int SDLCALL SDL_SetWindowModalFor(SDL_Window * modal_window, SDL_Window * parent_window);
/**
 *  \brief Explicitly sets input focus to the window.
 *
 *  You almost certainly want SDL_RaiseWindow() instead of this function. Use
 *  this with caution, as you might give focus to a window that's completely
 *  obscured by other windows.
 *
 *  \param window The window that should get the input focus
 *
 *  \return 0 on success, or -1 otherwise.
 *  \sa SDL_RaiseWindow()
 */
extern DECLSPEC int SDLCALL SDL_SetWindowInputFocus(SDL_Window * window);
/**
 *  \brief Set the gamma ramp for a window.
@@ -920,7 +1035,7 @@
/**
 *  \brief Returns whether the screensaver is currently enabled (default on).
 *  \brief Returns whether the screensaver is currently enabled (default off).
 *
 *  \sa SDL_EnableScreenSaver()
 *  \sa SDL_DisableScreenSaver()
source/premake/README-ios.txt
@@ -27,6 +27,7 @@
  -CoreAudio.framework
  -CoreMotion.framework
  -GameController.framework
  -AVFoundation.framework
All of these frameworks are part of the iOS SDK, not part of the core OS X
system.
source/premake/VisualC/VS2008/SDL2/SDL2.vcproj
@@ -419,10 +419,6 @@
                    >
                </File>
                <File
                    RelativePath="..\..\..\..\src\audio\SDL_audiomem.h"
                    >
                </File>
                <File
                    RelativePath="..\..\..\..\src\audio\SDL_audiotypecvt.c"
                    >
                    <FileConfiguration
source/premake/VisualC/VS2010/SDL2/SDL2.vcxproj
@@ -113,7 +113,6 @@
    <ClInclude Include="..\..\..\..\src\SDL_assert_c.h" />
    <ClInclude Include="..\..\..\..\src\SDL_error_c.h" />
    <ClInclude Include="..\..\..\..\src\audio\SDL_audiodev_c.h" />
    <ClInclude Include="..\..\..\..\src\audio\SDL_audiomem.h" />
    <ClInclude Include="..\..\..\..\src\audio\SDL_audio_c.h" />
    <ClInclude Include="..\..\..\..\src\audio\SDL_sysaudio.h" />
    <ClInclude Include="..\..\..\..\src\audio\SDL_wave.h" />
source/premake/VisualC/VS2010/SDL2/SDL2.vcxproj.filters
@@ -123,9 +123,6 @@
    <ClInclude Include="..\..\..\..\src\audio\SDL_audiodev_c.h">
      <Filter>src\audio</Filter>
    </ClInclude>
    <ClInclude Include="..\..\..\..\src\audio\SDL_audiomem.h">
      <Filter>src\audio</Filter>
    </ClInclude>
    <ClInclude Include="..\..\..\..\src\audio\SDL_audio_c.h">
      <Filter>src\audio</Filter>
    </ClInclude>
source/premake/VisualC/VS2012/SDL2/SDL2.vcxproj
@@ -115,7 +115,6 @@
    <ClInclude Include="..\..\..\..\src\SDL_assert_c.h" />
    <ClInclude Include="..\..\..\..\src\SDL_error_c.h" />
    <ClInclude Include="..\..\..\..\src\audio\SDL_audiodev_c.h" />
    <ClInclude Include="..\..\..\..\src\audio\SDL_audiomem.h" />
    <ClInclude Include="..\..\..\..\src\audio\SDL_audio_c.h" />
    <ClInclude Include="..\..\..\..\src\audio\SDL_sysaudio.h" />
    <ClInclude Include="..\..\..\..\src\audio\SDL_wave.h" />
source/premake/VisualC/VS2012/SDL2/SDL2.vcxproj.filters
@@ -123,9 +123,6 @@
    <ClInclude Include="..\..\..\..\src\audio\SDL_audiodev_c.h">
      <Filter>src\audio</Filter>
    </ClInclude>
    <ClInclude Include="..\..\..\..\src\audio\SDL_audiomem.h">
      <Filter>src\audio</Filter>
    </ClInclude>
    <ClInclude Include="..\..\..\..\src\audio\SDL_audio_c.h">
      <Filter>src\audio</Filter>
    </ClInclude>
source/premake/Xcode-iOS/SDL2/SDL2.xcodeproj/project.pbxproj
@@ -127,7 +127,6 @@
        4DBB70D75469728B342373E8 /* SDL_audiocvt.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = "SDL_audiocvt.c"; path = "../../../src/audio/SDL_audiocvt.c"; sourceTree = "<group>"; };
        48886D482B5239D2429E422D /* SDL_audiodev.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = "SDL_audiodev.c"; path = "../../../src/audio/SDL_audiodev.c"; sourceTree = "<group>"; };
        227E138737440F101016545F /* SDL_audiodev_c.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "SDL_audiodev_c.h"; path = "../../../src/audio/SDL_audiodev_c.h"; sourceTree = "<group>"; };
        5C3C744F22823D470BED10D6 /* SDL_audiomem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "SDL_audiomem.h"; path = "../../../src/audio/SDL_audiomem.h"; sourceTree = "<group>"; };
        0F175E65628D4137386B7A6D /* SDL_audiotypecvt.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = "SDL_audiotypecvt.c"; path = "../../../src/audio/SDL_audiotypecvt.c"; sourceTree = "<group>"; };
        77537CFB490A3599736F3830 /* SDL_mixer.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = "SDL_mixer.c"; path = "../../../src/audio/SDL_mixer.c"; sourceTree = "<group>"; };
        591062475F93492D625F7D3B /* SDL_sysaudio.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "SDL_sysaudio.h"; path = "../../../src/audio/SDL_sysaudio.h"; sourceTree = "<group>"; };
@@ -369,7 +368,6 @@
                4DBB70D75469728B342373E8 /* SDL_audiocvt.c */,
                48886D482B5239D2429E422D /* SDL_audiodev.c */,
                227E138737440F101016545F /* SDL_audiodev_c.h */,
                5C3C744F22823D470BED10D6 /* SDL_audiomem.h */,
                0F175E65628D4137386B7A6D /* SDL_audiotypecvt.c */,
                77537CFB490A3599736F3830 /* SDL_mixer.c */,
                591062475F93492D625F7D3B /* SDL_sysaudio.h */,
source/premake/Xcode-iOS/SDL_config_premake.h
@@ -150,8 +150,8 @@
#ifndef SDL_VIDEO_RENDER_OGL_ES2
#define SDL_VIDEO_RENDER_OGL_ES2 1
#endif
#ifndef SDL_LOADSO_DISABLED
#define SDL_LOADSO_DISABLED 1
#ifndef SDL_LOADSO_DLOPEN
#define SDL_LOADSO_DLOPEN 1
#endif
#ifndef SDL_HAPTIC_DISABLED
#define SDL_HAPTIC_DISABLED 1
source/premake/Xcode/Xcode3/SDL2/SDL2.xcodeproj/project.pbxproj
@@ -146,7 +146,6 @@
        2BA37BD372FE166821D80A1E /* SDL_audiocvt.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = "SDL_audiocvt.c"; path = "../../../../src/audio/SDL_audiocvt.c"; sourceTree = "<group>"; };
        5D2936CF698D392735D76E9E /* SDL_audiodev.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = "SDL_audiodev.c"; path = "../../../../src/audio/SDL_audiodev.c"; sourceTree = "<group>"; };
        1F255A29771744AC1DFE48A0 /* SDL_audiodev_c.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "SDL_audiodev_c.h"; path = "../../../../src/audio/SDL_audiodev_c.h"; sourceTree = "<group>"; };
        14AA3D784A5D4B873D657338 /* SDL_audiomem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "SDL_audiomem.h"; path = "../../../../src/audio/SDL_audiomem.h"; sourceTree = "<group>"; };
        76263CFA4F4A3E8E74966406 /* SDL_audiotypecvt.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = "SDL_audiotypecvt.c"; path = "../../../../src/audio/SDL_audiotypecvt.c"; sourceTree = "<group>"; };
        748562A8151756FF3FE91679 /* SDL_mixer.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = "SDL_mixer.c"; path = "../../../../src/audio/SDL_mixer.c"; sourceTree = "<group>"; };
        7B696A2B3C9847A40FD30FA2 /* SDL_sysaudio.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "SDL_sysaudio.h"; path = "../../../../src/audio/SDL_sysaudio.h"; sourceTree = "<group>"; };
@@ -425,7 +424,6 @@
                2BA37BD372FE166821D80A1E /* SDL_audiocvt.c */,
                5D2936CF698D392735D76E9E /* SDL_audiodev.c */,
                1F255A29771744AC1DFE48A0 /* SDL_audiodev_c.h */,
                14AA3D784A5D4B873D657338 /* SDL_audiomem.h */,
                76263CFA4F4A3E8E74966406 /* SDL_audiotypecvt.c */,
                748562A8151756FF3FE91679 /* SDL_mixer.c */,
                7B696A2B3C9847A40FD30FA2 /* SDL_sysaudio.h */,
source/premake/Xcode/Xcode4/SDL2/SDL2.xcodeproj/project.pbxproj
@@ -146,7 +146,6 @@
        07B907294E82663A7E91738C /* SDL_audiocvt.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = "SDL_audiocvt.c"; path = "../../../../src/audio/SDL_audiocvt.c"; sourceTree = "<group>"; };
        5AAD4B726237251050431873 /* SDL_audiodev.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = "SDL_audiodev.c"; path = "../../../../src/audio/SDL_audiodev.c"; sourceTree = "<group>"; };
        15895798549516351860492E /* SDL_audiodev_c.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "SDL_audiodev_c.h"; path = "../../../../src/audio/SDL_audiodev_c.h"; sourceTree = "<group>"; };
        0D3062CE47BF5D5934AB598D /* SDL_audiomem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "SDL_audiomem.h"; path = "../../../../src/audio/SDL_audiomem.h"; sourceTree = "<group>"; };
        5B0759ED16B35B9A6B027892 /* SDL_audiotypecvt.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = "SDL_audiotypecvt.c"; path = "../../../../src/audio/SDL_audiotypecvt.c"; sourceTree = "<group>"; };
        2B8C7A19218A1FFC6D376B1D /* SDL_mixer.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = "SDL_mixer.c"; path = "../../../../src/audio/SDL_mixer.c"; sourceTree = "<group>"; };
        09E4653E4CD964410C0E71BA /* SDL_sysaudio.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "SDL_sysaudio.h"; path = "../../../../src/audio/SDL_sysaudio.h"; sourceTree = "<group>"; };
@@ -425,7 +424,6 @@
                07B907294E82663A7E91738C /* SDL_audiocvt.c */,
                5AAD4B726237251050431873 /* SDL_audiodev.c */,
                15895798549516351860492E /* SDL_audiodev_c.h */,
                0D3062CE47BF5D5934AB598D /* SDL_audiomem.h */,
                5B0759ED16B35B9A6B027892 /* SDL_audiotypecvt.c */,
                2B8C7A19218A1FFC6D376B1D /* SDL_mixer.c */,
                09E4653E4CD964410C0E71BA /* SDL_sysaudio.h */,
source/premake/premake4.lua
@@ -121,7 +121,7 @@
    end
    local genFile = baseLoc .. "/SDL-gen.lua"
    local file = fileopen(genFile, "wt")
    local file = fileopen(genFile, "w")
    print("Generating " .. genFile .. "...")
    -- begin generating the config header file
    startGeneration(premakeConfigHeader, premakeTemplateHeader)
source/premake/projects/SDL2.lua
@@ -369,7 +369,7 @@
            ["SDL_AUDIO_DRIVER_COREAUDIO"] = 1,
            ["SDL_JOYSTICK_MFI"] = 1,
            ["SDL_HAPTIC_DISABLED"] = 1,
            ["SDL_LOADSO_DISABLED"] = 1,
            ["SDL_LOADSO_DLOPEN"] = 1,
            ["SDL_THREAD_PTHREAD"] = 1,
            ["SDL_THREAD_PTHREAD_RECURSIVE_MUTEX"] = 1,
            ["SDL_TIMER_UNIX"] = 1,
@@ -405,5 +405,6 @@
            "$(SDKROOT)/Foundation.framework",
            "$(SDKROOT)/CoreAudio.framework",
            "$(SDKROOT)/CoreMotion.framework",
            "$(SDKROOT)/GameController.framework"
            "$(SDKROOT)/GameController.framework",
            "$(SDKROOT)/AVFoundation.framework",
        }
source/premake/util/sdl_check_compile.lua
@@ -101,6 +101,18 @@
    os.remove("./premakecheck.stdout")
end
local function os_execute(cmd)
    if _ENV then
        -- Lua 5.2 or greater
        local cmdSuccess, textStatus, returnCode = os.execute(cmd)
        return returnCode
    else
        -- Lua 5.1 or lesser
        local returnCode = os.execute(cmd)
        return returnCode
    end
end
-- Check if a source builds, links, and or/runs, where running depends on
-- linking and linking depends on building. The return from this function is
-- a triple, where the first is a boolean value indicating if it successfully
@@ -108,10 +120,10 @@
-- linked, and the third represents nil if it was not run or run correctly, or
-- the output from the program executed (may be empty for no output).
local function check_build_source(source, link, run)
    local file = fileopen("./premakecheck.c", "wt")
    local file = fileopen("./premakecheck.c", "w")
    file:write(source)
    file:close()
    local result = os.execute(build_compile_line())
    local result = os_execute(build_compile_line())
    if not link then
        cleanup_build()
        if result == 0 then
@@ -125,13 +137,13 @@
        cleanup_build()
        return false, false, nil -- no compile, no link, no run
    end
    result = os.execute(build_link_line())
    result = os_execute(build_link_line())
    if not run or result ~= 0 then -- have to link to run
        cleanup_build()
        return true, result == 0, nil -- compile, maybe link, no run
    end
    result = os.execute(build_run_line())
    local output = readfile("./premakecheck.stdout", "rt")
    result = os_execute(build_run_line())
    local output = readfile("./premakecheck.stdout", "r")
    cleanup_build()
    return true, true, output -- compile, link, ran
end
source/premake/util/sdl_gen_config.lua
@@ -33,8 +33,8 @@
-- This function begins config header generation given the name of the generated
-- file and the name of the template file to use.
function startGeneration(file, template)
    configFile = fileopen(file, "wt")
    templateFileContents = readfile(template, "rt")
    configFile = fileopen(file, "w")
    templateFileContents = readfile(template, "r")
    insertLocation = templateFileContents:find(searchKey)
    if insertLocation then
        configFile:write(templateFileContents:sub(1, insertLocation - 1))
source/sdl2-config.cmake.in
@@ -8,3 +8,4 @@
set(SDL2_LIBDIR "@libdir@")
set(SDL2_INCLUDE_DIRS "@includedir@/SDL2")
set(SDL2_LIBRARIES "-L${SDL2_LIBDIR} @SDL_RLD_FLAGS@ @SDL_LIBS@")
string(STRIP "${SDL2_LIBRARIES}" SDL2_LIBRARIES)
source/sdl2.m4
@@ -4,6 +4,9 @@
# stolen back from Frank Belew
# stolen from Manish Singh
# Shamelessly stolen from Owen Taylor
#
# Changelog:
# * also look for SDL2.framework under Mac OS X
# serial 1
@@ -20,6 +23,10 @@
            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)
AC_ARG_ENABLE(sdlframework, [  --disable-sdlframework Do not search for SDL2.framework],
        , search_sdl_framework=yes)
AC_ARG_VAR(SDL2_FRAMEWORK, [Path to SDL2.framework])
  min_sdl_version=ifelse([$1], ,2.0.0,$1)
@@ -53,14 +60,36 @@
    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`
    if test "$SDL2_CONFIG" = "no" -a "x$search_sdl_framework" = "xyes"; then
      AC_MSG_CHECKING(for SDL2.framework)
      if test "x$SDL2_FRAMEWORK" != x; then
        sdl_framework=$SDL2_FRAMEWORK
      else
        for d in / ~/ /System/; do
          if test -d "$dLibrary/Frameworks/SDL2.framework"; then
            sdl_framework="$dLibrary/Frameworks/SDL2.framework"
          fi
        done
      fi
      if test -d $sdl_framework; then
        AC_MSG_RESULT($sdl_framework)
        sdl_framework_dir=`dirname $sdl_framework`
        SDL_CFLAGS="-F$sdl_framework_dir -Wl,-framework,SDL2 -I$sdl_framework/include"
        SDL_LIBS="-F$sdl_framework_dir -Wl,-framework,SDL2"
      else
        no_sdl=yes
      fi
    fi
    if test "$SDL2_CONFIG" != "no"; then
      if test "x$sdl_pc" = "xno"; then
        AC_MSG_CHECKING(for SDL - version >= $min_sdl_version)
        SDL_CFLAGS=`$SDL2_CONFIG $sdl_config_args --cflags`
        SDL_LIBS=`$SDL2_CONFIG $sdl_config_args --libs`
      fi
      sdl_major_version=`$SDL2_CONFIG $sdl_config_args --version | \
             sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
@@ -141,12 +170,15 @@
        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)
      if test "x$sdl_pc" = "xno"; then
        if test "x$no_sdl" = "xyes"; then
          AC_MSG_RESULT(no)
        else
          AC_MSG_RESULT(yes)
        fi
      fi
    fi
  fi
  if test "x$no_sdl" = x ; then
source/src/SDL.c
@@ -115,6 +115,16 @@
    /* Clear the error message */
    SDL_ClearError();
    if ((flags & SDL_INIT_GAMECONTROLLER)) {
        /* game controller implies joystick */
        flags |= SDL_INIT_JOYSTICK;
    }
    if ((flags & (SDL_INIT_VIDEO|SDL_INIT_JOYSTICK))) {
        /* video or joystick implies events */
        flags |= SDL_INIT_EVENTS;
    }
#if SDL_VIDEO_DRIVER_WINDOWS
    if ((flags & (SDL_INIT_HAPTIC|SDL_INIT_JOYSTICK))) {
        if (SDL_HelperWindowCreate() < 0) {
@@ -126,16 +136,6 @@
#if !SDL_TIMERS_DISABLED
    SDL_TicksInit();
#endif
    if ((flags & SDL_INIT_GAMECONTROLLER)) {
        /* game controller implies joystick */
        flags |= SDL_INIT_JOYSTICK;
    }
    if ((flags & (SDL_INIT_VIDEO|SDL_INIT_JOYSTICK))) {
        /* video or joystick implies events */
        flags |= SDL_INIT_EVENTS;
    }
    /* Initialize the event subsystem */
    if ((flags & SDL_INIT_EVENTS)) {
@@ -443,6 +443,8 @@
    return "Windows";
#elif __WINRT__
    return "WinRT";
#elif __TVOS__
    return "tvOS";
#elif __IPHONEOS__
    return "iOS";
#elif __PSP__
source/src/SDL_error.c
@@ -116,6 +116,10 @@
    return -1;
}
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
#endif
/* This function has a bit more overhead than most error functions
   so that it supports internationalization and thread-safe errors.
*/
@@ -216,6 +220,9 @@
    }
    return (errstr);
}
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
/* Available for backwards compatibility */
const char *
source/src/SDL_hints.c
@@ -118,6 +118,19 @@
    return env;
}
SDL_bool
SDL_GetHintBoolean(const char *name, SDL_bool default_value)
{
    const char *hint = SDL_GetHint(name);
    if (!hint) {
        return default_value;
    }
    if (*hint == '0' || SDL_strcasecmp(hint, "false") == 0) {
        return SDL_FALSE;
    }
    return SDL_TRUE;
}
void
SDL_AddHintCallback(const char *name, SDL_HintCallback callback, void *userdata)
{
source/src/SDL_log.c
@@ -324,7 +324,7 @@
        size_t length;
        LPTSTR tstr;
#ifndef __WINRT__
#if !defined(HAVE_STDIO_H) && !defined(__WINRT__)
        BOOL attachResult;
        DWORD attachError;
        unsigned long charsWritten; 
@@ -356,7 +356,7 @@
                        stderrHandle = GetStdHandle(STD_ERROR_HANDLE);
                }
        }
#endif /* ifndef __WINRT__ */
#endif /* !defined(HAVE_STDIO_H) && !defined(__WINRT__) */
        length = SDL_strlen(SDL_priority_prefixes[priority]) + 2 + SDL_strlen(message) + 1 + 1 + 1;
        output = SDL_stack_alloc(char, length);
@@ -366,7 +366,7 @@
        /* Output to debugger */
        OutputDebugString(tstr);
       
#ifndef __WINRT__
#if !defined(HAVE_STDIO_H) && !defined(__WINRT__)
        /* Screen output to stderr, if console was attached. */
        if (consoleAttached == 1) {
                if (!WriteConsole(stderrHandle, tstr, lstrlen(tstr), &charsWritten, NULL)) {
@@ -376,7 +376,7 @@
                    }
                }
        }
#endif /* ifndef __WINRT__ */
#endif /* !defined(HAVE_STDIO_H) && !defined(__WINRT__) */
        SDL_free(tstr);
        SDL_stack_free(output);
source/src/audio/SDL_audio.c
@@ -25,33 +25,29 @@
#include "SDL.h"
#include "SDL_audio.h"
#include "SDL_audio_c.h"
#include "SDL_audiomem.h"
#include "SDL_sysaudio.h"
#include "../thread/SDL_systhread.h"
#define _THIS SDL_AudioDevice *_this
static SDL_AudioDriver current_audio;
static SDL_AudioDevice *open_devices[16];
/* !!! FIXME: These are wordy and unlocalized... */
#define DEFAULT_OUTPUT_DEVNAME "System audio output device"
#define DEFAULT_INPUT_DEVNAME "System audio capture device"
/*
 * Not all of these will be compiled and linked in, but it's convenient
 *  to have a complete list here and saves yet-another block of #ifdefs...
 *  Please see bootstrap[], below, for the actual #ifdef mess.
 */
extern AudioBootStrap PULSEAUDIO_bootstrap;
extern AudioBootStrap ALSA_bootstrap;
extern AudioBootStrap SNDIO_bootstrap;
extern AudioBootStrap BSD_AUDIO_bootstrap;
extern AudioBootStrap DSP_bootstrap;
extern AudioBootStrap ALSA_bootstrap;
extern AudioBootStrap PULSEAUDIO_bootstrap;
extern AudioBootStrap QSAAUDIO_bootstrap;
extern AudioBootStrap SUNAUDIO_bootstrap;
extern AudioBootStrap ARTS_bootstrap;
extern AudioBootStrap ESD_bootstrap;
extern AudioBootStrap NACLAUD_bootstrap;
extern AudioBootStrap NACLAUDIO_bootstrap;
extern AudioBootStrap NAS_bootstrap;
extern AudioBootStrap XAUDIO2_bootstrap;
extern AudioBootStrap DSOUND_bootstrap;
@@ -59,18 +55,13 @@
extern AudioBootStrap PAUDIO_bootstrap;
extern AudioBootStrap HAIKUAUDIO_bootstrap;
extern AudioBootStrap COREAUDIO_bootstrap;
extern AudioBootStrap SNDMGR_bootstrap;
extern AudioBootStrap DISKAUD_bootstrap;
extern AudioBootStrap DUMMYAUD_bootstrap;
extern AudioBootStrap DCAUD_bootstrap;
extern AudioBootStrap DART_bootstrap;
extern AudioBootStrap NDSAUD_bootstrap;
extern AudioBootStrap DISKAUDIO_bootstrap;
extern AudioBootStrap DUMMYAUDIO_bootstrap;
extern AudioBootStrap FUSIONSOUND_bootstrap;
extern AudioBootStrap ANDROIDAUD_bootstrap;
extern AudioBootStrap PSPAUD_bootstrap;
extern AudioBootStrap ANDROIDAUDIO_bootstrap;
extern AudioBootStrap PSPAUDIO_bootstrap;
extern AudioBootStrap SNDIO_bootstrap;
extern AudioBootStrap EmscriptenAudio_bootstrap;
extern AudioBootStrap EMSCRIPTENAUDIO_bootstrap;
/* Available audio drivers */
static const AudioBootStrap *const bootstrap[] = {
@@ -102,7 +93,7 @@
    &ESD_bootstrap,
#endif
#if SDL_AUDIO_DRIVER_NACL
   &NACLAUD_bootstrap,
    &NACLAUDIO_bootstrap,
#endif
#if SDL_AUDIO_DRIVER_NAS
    &NAS_bootstrap,
@@ -126,22 +117,22 @@
    &COREAUDIO_bootstrap,
#endif
#if SDL_AUDIO_DRIVER_DISK
    &DISKAUD_bootstrap,
    &DISKAUDIO_bootstrap,
#endif
#if SDL_AUDIO_DRIVER_DUMMY
    &DUMMYAUD_bootstrap,
    &DUMMYAUDIO_bootstrap,
#endif
#if SDL_AUDIO_DRIVER_FUSIONSOUND
    &FUSIONSOUND_bootstrap,
#endif
#if SDL_AUDIO_DRIVER_ANDROID
    &ANDROIDAUD_bootstrap,
    &ANDROIDAUDIO_bootstrap,
#endif
#if SDL_AUDIO_DRIVER_PSP
    &PSPAUD_bootstrap,
    &PSPAUDIO_bootstrap,
#endif
#if SDL_AUDIO_DRIVER_EMSCRIPTEN
    &EmscriptenAudio_bootstrap,
    &EMSCRIPTENAUDIO_bootstrap,
#endif
    NULL
};
@@ -165,7 +156,7 @@
{
    /* you have to write your own implementation if these assertions fail. */
    SDL_assert(current_audio.impl.OnlyHasDefaultOutputDevice);
    SDL_assert(current_audio.impl.OnlyHasDefaultInputDevice || !current_audio.impl.HasCaptureSupport);
    SDL_assert(current_audio.impl.OnlyHasDefaultCaptureDevice || !current_audio.impl.HasCaptureSupport);
    SDL_AddAudioDevice(SDL_FALSE, DEFAULT_OUTPUT_DEVNAME, (void *) ((size_t) 0x1));
    if (current_audio.impl.HasCaptureSupport) {
@@ -200,8 +191,19 @@
    return NULL;
}
static int
SDL_AudioCaptureFromDevice_Default(_THIS, void *buffer, int buflen)
{
    return -1;  /* just fail immediately. */
}
static void
SDL_AudioWaitDone_Default(_THIS)
SDL_AudioFlushCapture_Default(_THIS)
{                               /* no-op. */
}
static void
SDL_AudioPrepareToClose_Default(_THIS)
{                               /* no-op. */
}
@@ -257,14 +259,27 @@
    }
}
static void
SDL_AudioLockOrUnlockDeviceWithNoMixerLock(SDL_AudioDevice * device)
{
}
static void
finalize_audio_entry_points(void)
finish_audio_entry_points_init(void)
{
    /*
     * Fill in stub functions for unused driver entry points. This lets us
     *  blindly call them without having to check for validity first.
     */
    if (current_audio.impl.SkipMixerLock) {
        if (current_audio.impl.LockDevice == NULL) {
            current_audio.impl.LockDevice = SDL_AudioLockOrUnlockDeviceWithNoMixerLock;
        }
        if (current_audio.impl.UnlockDevice == NULL) {
            current_audio.impl.UnlockDevice = SDL_AudioLockOrUnlockDeviceWithNoMixerLock;
        }
    }
#define FILL_STUB(x) \
        if (current_audio.impl.x == NULL) { \
@@ -277,7 +292,9 @@
    FILL_STUB(PlayDevice);
    FILL_STUB(GetPendingBytes);
    FILL_STUB(GetDeviceBuf);
    FILL_STUB(WaitDone);
    FILL_STUB(CaptureFromDevice);
    FILL_STUB(FlushCapture);
    FILL_STUB(PrepareToClose);
    FILL_STUB(CloseDevice);
    FILL_STUB(LockDevice);
    FILL_STUB(UnlockDevice);
@@ -316,7 +333,7 @@
static SDL_INLINE int
add_capture_device(const char *name, void *handle)
{
    /* !!! FIXME: add this later. SDL_assert(current_audio.impl.HasCaptureSupport);*/
    SDL_assert(current_audio.impl.HasCaptureSupport);
    return add_audio_device(name, handle, &current_audio.inputDevices, &current_audio.inputDeviceCount);
}
@@ -365,14 +382,14 @@
{
    SDL_assert(get_audio_device(device->id) == device);
    if (!device->enabled) {
    if (!SDL_AtomicGet(&device->enabled)) {
        return;
    }
    /* Ends the audio callback and mark the device as STOPPED, but the
       app still needs to close the device to free resources. */
    current_audio.impl.LockDevice(device);
    device->enabled = 0;
    SDL_AtomicSet(&device->enabled, 0);
    current_audio.impl.UnlockDevice(device);
    /* Post the event, if desired */
@@ -404,13 +421,26 @@
void
SDL_RemoveAudioDevice(const int iscapture, void *handle)
{
    int device_index;
    SDL_AudioDevice *device = NULL;
    SDL_LockMutex(current_audio.detectionLock);
    if (iscapture) {
        mark_device_removed(handle, current_audio.inputDevices, &current_audio.captureDevicesRemoved);
    } else {
        mark_device_removed(handle, current_audio.outputDevices, &current_audio.outputDevicesRemoved);
    }
    for (device_index = 0; device_index < SDL_arraysize(open_devices); device_index++)
    {
        device = open_devices[device_index];
        if (device != NULL && device->handle == handle)
        {
            SDL_OpenedAudioDeviceDisconnected(device);
            break;
        }
    }
    SDL_UnlockMutex(current_audio.detectionLock);
    current_audio.impl.FreeDeviceHandle(handle);
}
@@ -420,76 +450,23 @@
/* this expects that you managed thread safety elsewhere. */
static void
free_audio_queue(SDL_AudioBufferQueue *buffer)
free_audio_queue(SDL_AudioBufferQueue *packet)
{
    while (buffer) {
        SDL_AudioBufferQueue *next = buffer->next;
        SDL_free(buffer);
        buffer = next;
    while (packet) {
        SDL_AudioBufferQueue *next = packet->next;
        SDL_free(packet);
        packet = next;
    }
}
static void SDLCALL
SDL_BufferQueueDrainCallback(void *userdata, Uint8 *stream, int _len)
/* NOTE: This assumes you'll hold the mixer lock before calling! */
static int
queue_audio_to_device(SDL_AudioDevice *device, const Uint8 *data, Uint32 len)
{
    /* this function always holds the mixer lock before being called. */
    Uint32 len = (Uint32) _len;
    SDL_AudioDevice *device = (SDL_AudioDevice *) userdata;
    SDL_AudioBufferQueue *buffer;
    SDL_assert(device != NULL);  /* this shouldn't ever happen, right?! */
    SDL_assert(_len >= 0);  /* this shouldn't ever happen, right?! */
    while ((len > 0) && ((buffer = device->buffer_queue_head) != NULL)) {
        const Uint32 avail = buffer->datalen - buffer->startpos;
        const Uint32 cpy = SDL_min(len, avail);
        SDL_assert(device->queued_bytes >= avail);
        SDL_memcpy(stream, buffer->data + buffer->startpos, cpy);
        buffer->startpos += cpy;
        stream += cpy;
        device->queued_bytes -= cpy;
        len -= cpy;
        if (buffer->startpos == buffer->datalen) {  /* packet is done, put it in the pool. */
            device->buffer_queue_head = buffer->next;
            SDL_assert((buffer->next != NULL) || (buffer == device->buffer_queue_tail));
            buffer->next = device->buffer_queue_pool;
            device->buffer_queue_pool = buffer;
        }
    }
    SDL_assert((device->buffer_queue_head != NULL) == (device->queued_bytes != 0));
    if (len > 0) {  /* fill any remaining space in the stream with silence. */
        SDL_assert(device->buffer_queue_head == NULL);
        SDL_memset(stream, device->spec.silence, len);
    }
    if (device->buffer_queue_head == NULL) {
        device->buffer_queue_tail = NULL;  /* in case we drained the queue entirely. */
    }
}
int
SDL_QueueAudio(SDL_AudioDeviceID devid, const void *_data, Uint32 len)
{
    SDL_AudioDevice *device = get_audio_device(devid);
    const Uint8 *data = (const Uint8 *) _data;
    SDL_AudioBufferQueue *orighead;
    SDL_AudioBufferQueue *origtail;
    Uint32 origlen;
    Uint32 datalen;
    if (!device) {
        return -1;  /* get_audio_device() will have set the error state */
    }
    if (device->spec.callback != SDL_BufferQueueDrainCallback) {
        return SDL_SetError("Audio device has a callback, queueing not allowed");
    }
    current_audio.impl.LockDevice(device);
    orighead = device->buffer_queue_head;
    origtail = device->buffer_queue_tail;
@@ -520,8 +497,6 @@
                    device->buffer_queue_tail = origtail;
                    device->buffer_queue_pool = NULL;
                    current_audio.impl.UnlockDevice(device);
                    free_audio_queue(packet);  /* give back what we can. */
                    return SDL_OutOfMemory();
@@ -548,9 +523,121 @@
        device->queued_bytes += datalen;
    }
    current_audio.impl.UnlockDevice(device);
    return 0;
}
/* NOTE: This assumes you'll hold the mixer lock before calling! */
static Uint32
dequeue_audio_from_device(SDL_AudioDevice *device, Uint8 *stream, Uint32 len)
{
    SDL_AudioBufferQueue *packet;
    Uint8 *ptr = stream;
    while ((len > 0) && ((packet = device->buffer_queue_head) != NULL)) {
        const Uint32 avail = packet->datalen - packet->startpos;
        const Uint32 cpy = SDL_min(len, avail);
        SDL_assert(device->queued_bytes >= avail);
        SDL_memcpy(ptr, packet->data + packet->startpos, cpy);
        packet->startpos += cpy;
        ptr += cpy;
        device->queued_bytes -= cpy;
        len -= cpy;
        if (packet->startpos == packet->datalen) {  /* packet is done, put it in the pool. */
            device->buffer_queue_head = packet->next;
            SDL_assert((packet->next != NULL) || (packet == device->buffer_queue_tail));
            packet->next = device->buffer_queue_pool;
            device->buffer_queue_pool = packet;
        }
    }
    SDL_assert((device->buffer_queue_head != NULL) == (device->queued_bytes != 0));
    if (device->buffer_queue_head == NULL) {
        device->buffer_queue_tail = NULL;  /* in case we drained the queue entirely. */
    }
    return (Uint32) (ptr - stream);
}
static void SDLCALL
SDL_BufferQueueDrainCallback(void *userdata, Uint8 *stream, int len)
{
    /* this function always holds the mixer lock before being called. */
    SDL_AudioDevice *device = (SDL_AudioDevice *) userdata;
    Uint32 written;
    SDL_assert(device != NULL);  /* this shouldn't ever happen, right?! */
    SDL_assert(!device->iscapture);  /* this shouldn't ever happen, right?! */
    SDL_assert(len >= 0);  /* this shouldn't ever happen, right?! */
    written = dequeue_audio_from_device(device, stream, (Uint32) len);
    stream += written;
    len -= (int) written;
    if (len > 0) {  /* fill any remaining space in the stream with silence. */
        SDL_assert(device->buffer_queue_head == NULL);
        SDL_memset(stream, device->spec.silence, len);
    }
}
static void SDLCALL
SDL_BufferQueueFillCallback(void *userdata, Uint8 *stream, int len)
{
    /* this function always holds the mixer lock before being called. */
    SDL_AudioDevice *device = (SDL_AudioDevice *) userdata;
    SDL_assert(device != NULL);  /* this shouldn't ever happen, right?! */
    SDL_assert(device->iscapture);  /* this shouldn't ever happen, right?! */
    SDL_assert(len >= 0);  /* this shouldn't ever happen, right?! */
    /* note that if this needs to allocate more space and run out of memory,
       we have no choice but to quietly drop the data and hope it works out
       later, but you probably have bigger problems in this case anyhow. */
    queue_audio_to_device(device, stream, (Uint32) len);
}
int
SDL_QueueAudio(SDL_AudioDeviceID devid, const void *data, Uint32 len)
{
    SDL_AudioDevice *device = get_audio_device(devid);
    int rc = 0;
    if (!device) {
        return -1;  /* get_audio_device() will have set the error state */
    } else if (device->iscapture) {
        return SDL_SetError("This is a capture device, queueing not allowed");
    } else if (device->spec.callback != SDL_BufferQueueDrainCallback) {
        return SDL_SetError("Audio device has a callback, queueing not allowed");
    }
    if (len > 0) {
        current_audio.impl.LockDevice(device);
        rc = queue_audio_to_device(device, data, len);
        current_audio.impl.UnlockDevice(device);
    }
    return rc;
}
Uint32
SDL_DequeueAudio(SDL_AudioDeviceID devid, void *data, Uint32 len)
{
    SDL_AudioDevice *device = get_audio_device(devid);
    Uint32 rc;
    if ( (len == 0) ||  /* nothing to do? */
         (!device) ||  /* called with bogus device id */
         (!device->iscapture) ||  /* playback devices can't dequeue */
         (device->spec.callback != SDL_BufferQueueFillCallback) ) { /* not set for queueing */
        return 0;  /* just report zero bytes dequeued. */
    }
    current_audio.impl.LockDevice(device);
    rc = dequeue_audio_from_device(device, data, len);
    current_audio.impl.UnlockDevice(device);
    return rc;
}
Uint32
@@ -559,10 +646,18 @@
    Uint32 retval = 0;
    SDL_AudioDevice *device = get_audio_device(devid);
    if (!device) {
        return 0;
    }
    /* Nothing to do unless we're set up for queueing. */
    if (device && (device->spec.callback == SDL_BufferQueueDrainCallback)) {
    if (device->spec.callback == SDL_BufferQueueDrainCallback) {
        current_audio.impl.LockDevice(device);
        retval = device->queued_bytes + current_audio.impl.GetPendingBytes(device);
        current_audio.impl.UnlockDevice(device);
    } else if (device->spec.callback == SDL_BufferQueueFillCallback) {
        current_audio.impl.LockDevice(device);
        retval = device->queued_bytes;
        current_audio.impl.UnlockDevice(device);
    }
@@ -573,25 +668,49 @@
SDL_ClearQueuedAudio(SDL_AudioDeviceID devid)
{
    SDL_AudioDevice *device = get_audio_device(devid);
    SDL_AudioBufferQueue *buffer = NULL;
    SDL_AudioBufferQueue *packet;
    if (!device) {
        return;  /* nothing to do. */
    }
    /* Blank out the device and release the mutex. Free it afterwards. */
    current_audio.impl.LockDevice(device);
    buffer = device->buffer_queue_head;
    /* merge the available pool and the current queue into one list. */
    packet = device->buffer_queue_head;
    if (packet) {
        device->buffer_queue_tail->next = device->buffer_queue_pool;
    } else {
        packet = device->buffer_queue_pool;
    }
    /* Remove the queued packets from the device. */
    device->buffer_queue_tail = NULL;
    device->buffer_queue_head = NULL;
    device->queued_bytes = 0;
    device->buffer_queue_pool = packet;
    /* Keep up to two packets in the pool to reduce future malloc pressure. */
    if (packet) {
        if (!packet->next) {
            packet = NULL;  /* one packet (the only one) for the pool. */
        } else {
            SDL_AudioBufferQueue *next = packet->next->next;
            packet->next->next = NULL;  /* two packets for the pool. */
            packet = next;  /* rest will be freed. */
        }
    }
    current_audio.impl.UnlockDevice(device);
    free_audio_queue(buffer);
    /* free any extra packets we didn't keep in the pool. */
    free_audio_queue(packet);
}
/* The general mixing thread function */
int SDLCALL
static int SDLCALL
SDL_RunAudio(void *devicep)
{
    SDL_AudioDevice *device = (SDL_AudioDevice *) devicep;
@@ -600,7 +719,9 @@
    const int stream_len = (device->convert.needed) ? device->convert.len : device->spec.size;
    Uint8 *stream;
    void *udata = device->spec.userdata;
    void (SDLCALL *fill) (void *, Uint8 *, int) = device->spec.callback;
    void (SDLCALL *callback) (void *, Uint8 *, int) = device->spec.callback;
    SDL_assert(!device->iscapture);
    /* The audio mixing is always a high priority thread */
    SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH);
@@ -610,11 +731,11 @@
    current_audio.impl.ThreadInit(device);
    /* Loop, filling the audio buffers */
    while (!device->shutdown) {
    while (!SDL_AtomicGet(&device->shutdown)) {
        /* Fill the current buffer with sound */
        if (device->convert.needed) {
            stream = device->convert.buf;
        } else if (device->enabled) {
        } else if (SDL_AtomicGet(&device->enabled)) {
            stream = current_audio.impl.GetDeviceBuf(device);
        } else {
            /* if the device isn't enabled, we still write to the
@@ -630,16 +751,18 @@
        }
        /* !!! FIXME: this should be LockDevice. */
        SDL_LockMutex(device->mixer_lock);
        if (device->paused) {
            SDL_memset(stream, silence, stream_len);
        } else {
            (*fill) (udata, stream, stream_len);
        if ( SDL_AtomicGet(&device->enabled) ) {
            SDL_LockMutex(device->mixer_lock);
            if (SDL_AtomicGet(&device->paused)) {
                SDL_memset(stream, silence, stream_len);
            } else {
                (*callback) (udata, stream, stream_len);
            }
            SDL_UnlockMutex(device->mixer_lock);
        }
        SDL_UnlockMutex(device->mixer_lock);
        /* Convert the audio if necessary */
        if (device->enabled && device->convert.needed) {
        if (device->convert.needed && SDL_AtomicGet(&device->enabled)) {
            SDL_ConvertAudio(&device->convert);
            stream = current_audio.impl.GetDeviceBuf(device);
            if (stream == NULL) {
@@ -659,8 +782,91 @@
        }
    }
    current_audio.impl.PrepareToClose(device);
    /* Wait for the audio to drain. */
    current_audio.impl.WaitDone(device);
    SDL_Delay(((device->spec.samples * 1000) / device->spec.freq) * 2);
    return 0;
}
/* The general capture thread function */
static int SDLCALL
SDL_CaptureAudio(void *devicep)
{
    SDL_AudioDevice *device = (SDL_AudioDevice *) devicep;
    const int silence = (int) device->spec.silence;
    const Uint32 delay = ((device->spec.samples * 1000) / device->spec.freq);
    const int stream_len = (device->convert.needed) ? device->convert.len : device->spec.size;
    Uint8 *stream;
    void *udata = device->spec.userdata;
    void (SDLCALL *callback) (void *, Uint8 *, int) = device->spec.callback;
    SDL_assert(device->iscapture);
    /* The audio mixing is always a high priority thread */
    SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH);
    /* Perform any thread setup */
    device->threadid = SDL_ThreadID();
    current_audio.impl.ThreadInit(device);
    /* Loop, filling the audio buffers */
    while (!SDL_AtomicGet(&device->shutdown)) {
        int still_need;
        Uint8 *ptr;
        if (!SDL_AtomicGet(&device->enabled) || SDL_AtomicGet(&device->paused)) {
            SDL_Delay(delay);  /* just so we don't cook the CPU. */
            current_audio.impl.FlushCapture(device);  /* dump anything pending. */
            continue;
        }
        /* Fill the current buffer with sound */
        still_need = stream_len;
        if (device->convert.needed) {
            ptr = stream = device->convert.buf;
        } else {
            /* just use the "fake" stream to hold data read from the device. */
            ptr = stream = device->fake_stream;
        }
        /* We still read from the device when "paused" to keep the state sane,
           and block when there isn't data so this thread isn't eating CPU.
           But we don't process it further or call the app's callback. */
        while (still_need > 0) {
            const int rc = current_audio.impl.CaptureFromDevice(device, ptr, still_need);
            SDL_assert(rc <= still_need);  /* device should not overflow buffer. :) */
            if (rc > 0) {
                still_need -= rc;
                ptr += rc;
            } else {  /* uhoh, device failed for some reason! */
                SDL_OpenedAudioDeviceDisconnected(device);
                break;
            }
        }
        if (still_need > 0) {
            /* Keep any data we already read, silence the rest. */
            SDL_memset(ptr, silence, still_need);
        }
        if (device->convert.needed) {
            SDL_ConvertAudio(&device->convert);
        }
        /* !!! FIXME: this should be LockDevice. */
        SDL_LockMutex(device->mixer_lock);
        if (SDL_AtomicGet(&device->paused)) {
            current_audio.impl.FlushCapture(device);  /* one snuck in! */
        } else {
            (*callback)(udata, stream, stream_len);
        }
        SDL_UnlockMutex(device->mixer_lock);
    }
    current_audio.impl.FlushCapture(device);
    return 0;
}
@@ -757,7 +963,7 @@
    current_audio.detectionLock = SDL_CreateMutex();
    finalize_audio_entry_points();
    finish_audio_entry_points_init();
    /* Make sure we have a list of devices available at startup. */
    current_audio.impl.DetectDevices();
@@ -872,27 +1078,38 @@
static void
close_audio_device(SDL_AudioDevice * device)
{
    device->enabled = 0;
    device->shutdown = 1;
    if (!device) {
        return;
    }
    if (device->id > 0) {
        SDL_AudioDevice *opendev = open_devices[device->id - 1];
        SDL_assert((opendev == device) || (opendev == NULL));
        if (opendev == device) {
            open_devices[device->id - 1] = NULL;
        }
    }
    SDL_AtomicSet(&device->shutdown, 1);
    SDL_AtomicSet(&device->enabled, 0);
    if (device->thread != NULL) {
        SDL_WaitThread(device->thread, NULL);
    }
    if (device->mixer_lock != NULL) {
        SDL_DestroyMutex(device->mixer_lock);
    }
    SDL_FreeAudioMem(device->fake_stream);
    SDL_free(device->fake_stream);
    if (device->convert.needed) {
        SDL_FreeAudioMem(device->convert.buf);
        SDL_free(device->convert.buf);
    }
    if (device->opened) {
    if (device->hidden != NULL) {
        current_audio.impl.CloseDevice(device);
        device->opened = 0;
    }
    free_audio_queue(device->buffer_queue_head);
    free_audio_queue(device->buffer_queue_pool);
    SDL_FreeAudioMem(device);
    SDL_free(device);
}
@@ -963,12 +1180,12 @@
                  const SDL_AudioSpec * desired, SDL_AudioSpec * obtained,
                  int allowed_changes, int min_id)
{
    const SDL_bool is_internal_thread = (desired->callback != NULL);
    SDL_AudioDeviceID id = 0;
    SDL_AudioSpec _obtained;
    SDL_AudioDevice *device;
    SDL_bool build_cvt;
    void *handle = NULL;
    Uint32 stream_len;
    int i = 0;
    if (!SDL_WasInit(SDL_INIT_AUDIO)) {
@@ -981,6 +1198,7 @@
        return 0;
    }
    /* !!! FIXME: there is a race condition here if two devices open from two threads at once. */
    /* Find an available device ID... */
    for (id = min_id - 1; id < SDL_arraysize(open_devices); id++) {
        if (open_devices[id] == NULL) {
@@ -1015,7 +1233,7 @@
     *  opens of the default system device.
     */
    if ((iscapture) && (current_audio.impl.OnlyHasDefaultInputDevice)) {
    if ((iscapture) && (current_audio.impl.OnlyHasDefaultCaptureDevice)) {
        if ((devname) && (SDL_strcmp(devname, DEFAULT_INPUT_DEVNAME) != 0)) {
            SDL_SetError("No such device");
            return 0;
@@ -1067,17 +1285,19 @@
        }
    }
    device = (SDL_AudioDevice *) SDL_AllocAudioMem(sizeof(SDL_AudioDevice));
    device = (SDL_AudioDevice *) SDL_calloc(1, sizeof (SDL_AudioDevice));
    if (device == NULL) {
        SDL_OutOfMemory();
        return 0;
    }
    SDL_zerop(device);
    device->id = id + 1;
    device->spec = *obtained;
    device->enabled = 1;
    device->paused = 1;
    device->iscapture = iscapture;
    device->iscapture = iscapture ? SDL_TRUE : SDL_FALSE;
    device->handle = handle;
    SDL_AtomicSet(&device->shutdown, 0);  /* just in case. */
    SDL_AtomicSet(&device->paused, 1);
    SDL_AtomicSet(&device->enabled, 1);
    /* Create a mutex for locking the sound buffers */
    if (!current_audio.impl.SkipMixerLock) {
@@ -1093,7 +1313,10 @@
        close_audio_device(device);
        return 0;
    }
    device->opened = 1;
    /* if your target really doesn't need it, set it to 0x1 or something. */
    /* otherwise, close_audio_device() won't call impl.CloseDevice(). */
    SDL_assert(device->hidden != NULL);
    /* See if we need to do any conversion */
    build_cvt = SDL_FALSE;
@@ -1143,7 +1366,7 @@
                                         device->convert.len_ratio);
            device->convert.buf =
                (Uint8 *) SDL_AllocAudioMem(device->convert.len *
                (Uint8 *) SDL_malloc(device->convert.len *
                                            device->convert.len_mult);
            if (device->convert.buf == NULL) {
                close_audio_device(device);
@@ -1151,19 +1374,6 @@
                return 0;
            }
        }
    }
    /* Allocate a fake audio memory buffer */
    stream_len = (device->convert.needed) ? device->convert.len_cvt : 0;
    if (device->spec.size > stream_len) {
        stream_len = device->spec.size;
    }
    SDL_assert(stream_len > 0);
    device->fake_stream = (Uint8 *)SDL_AllocAudioMem(stream_len);
    if (device->fake_stream == NULL) {
        close_audio_device(device);
        SDL_OutOfMemory();
        return 0;
    }
    if (device->spec.callback == NULL) {  /* use buffer queueing? */
@@ -1181,7 +1391,7 @@
            }
        }
        device->spec.callback = SDL_BufferQueueDrainCallback;
        device->spec.callback = iscapture ? SDL_BufferQueueFillCallback : SDL_BufferQueueDrainCallback;
        device->spec.userdata = device;
    }
@@ -1191,21 +1401,30 @@
    /* Start the audio thread if necessary */
    if (!current_audio.impl.ProvidesOwnCallbackThread) {
        /* Start the audio thread */
        char name[64];
        SDL_snprintf(name, sizeof (name), "SDLAudioDev%d", (int) device->id);
/* !!! FIXME: this is nasty. */
#if defined(__WIN32__) && !defined(HAVE_LIBC)
#undef SDL_CreateThread
#if SDL_DYNAMIC_API
        device->thread = SDL_CreateThread_REAL(SDL_RunAudio, name, device, NULL, NULL);
#else
        device->thread = SDL_CreateThread(SDL_RunAudio, name, device, NULL, NULL);
#endif
#else
        device->thread = SDL_CreateThread(SDL_RunAudio, name, device);
#endif
        /* !!! FIXME: we don't force the audio thread stack size here if it calls into user code, but maybe we should? */
        /* buffer queueing callback only needs a few bytes, so make the stack tiny. */
        const size_t stacksize = is_internal_thread ? 64 * 1024 : 0;
        char threadname[64];
        /* Allocate a fake audio buffer; only used by our internal threads. */
        Uint32 stream_len = (device->convert.needed) ? device->convert.len_cvt : 0;
        if (device->spec.size > stream_len) {
            stream_len = device->spec.size;
        }
        SDL_assert(stream_len > 0);
        device->fake_stream = (Uint8 *) SDL_malloc(stream_len);
        if (device->fake_stream == NULL) {
            close_audio_device(device);
            SDL_OutOfMemory();
            return 0;
        }
        SDL_snprintf(threadname, sizeof (threadname), "SDLAudioDev%d", (int) device->id);
        device->thread = SDL_CreateThreadInternal(iscapture ? SDL_CaptureAudio : SDL_RunAudio, threadname, stacksize, device);
        if (device->thread == NULL) {
            SDL_CloseAudioDevice(device->id);
            close_audio_device(device);
            SDL_SetError("Couldn't create audio thread");
            return 0;
        }
@@ -1258,8 +1477,8 @@
{
    SDL_AudioDevice *device = get_audio_device(devid);
    SDL_AudioStatus status = SDL_AUDIO_STOPPED;
    if (device && device->enabled) {
        if (device->paused) {
    if (device && SDL_AtomicGet(&device->enabled)) {
        if (SDL_AtomicGet(&device->paused)) {
            status = SDL_AUDIO_PAUSED;
        } else {
            status = SDL_AUDIO_PLAYING;
@@ -1281,7 +1500,7 @@
    SDL_AudioDevice *device = get_audio_device(devid);
    if (device) {
        current_audio.impl.LockDevice(device);
        device->paused = pause_on;
        SDL_AtomicSet(&device->paused, pause_on ? 1 : 0);
        current_audio.impl.UnlockDevice(device);
    }
}
@@ -1328,11 +1547,7 @@
void
SDL_CloseAudioDevice(SDL_AudioDeviceID devid)
{
    SDL_AudioDevice *device = get_audio_device(devid);
    if (device) {
        close_audio_device(device);
        open_devices[devid - 1] = NULL;
    }
    close_audio_device(get_audio_device(devid));
}
void
@@ -1351,9 +1566,7 @@
    }
    for (i = 0; i < SDL_arraysize(open_devices); i++) {
        if (open_devices[i] != NULL) {
            SDL_CloseAudioDevice(i+1);
        }
        close_audio_device(open_devices[i]);
    }
    free_device_list(&current_audio.outputDevices, &current_audio.outputDeviceCount);
source/src/audio/SDL_audio_c.h
@@ -29,9 +29,6 @@
/* Function to calculate the size and silence for a SDL_AudioSpec */
extern void SDL_CalculateAudioSpec(SDL_AudioSpec * spec);
/* The actual mixing thread function */
extern int SDLCALL SDL_RunAudio(void *audiop);
/* this is used internally to access some autogenerated code. */
typedef struct
{
source/src/audio/SDL_mixer.c
@@ -202,6 +202,54 @@
        }
        break;
    case AUDIO_U16LSB:
        {
            Uint16 src1, src2;
            int dst_sample;
            const int max_audioval = 0xFFFF;
            len /= 2;
            while (len--) {
                src1 = ((src[1]) << 8 | src[0]);
                ADJUST_VOLUME(src1, volume);
                src2 = ((dst[1]) << 8 | dst[0]);
                src += 2;
                dst_sample = src1 + src2;
                if (dst_sample > max_audioval) {
                    dst_sample = max_audioval;
                }
                dst[0] = dst_sample & 0xFF;
                dst_sample >>= 8;
                dst[1] = dst_sample & 0xFF;
                dst += 2;
            }
        }
        break;
    case AUDIO_U16MSB:
        {
            Uint16 src1, src2;
            int dst_sample;
            const int max_audioval = 0xFFFF;
            len /= 2;
            while (len--) {
                src1 = ((src[0]) << 8 | src[1]);
                ADJUST_VOLUME(src1, volume);
                src2 = ((dst[0]) << 8 | dst[1]);
                src += 2;
                dst_sample = src1 + src2;
                if (dst_sample > max_audioval) {
                    dst_sample = max_audioval;
                }
                dst[1] = dst_sample & 0xFF;
                dst_sample >>= 8;
                dst[0] = dst_sample & 0xFF;
                dst += 2;
            }
        }
        break;
    case AUDIO_S32LSB:
        {
            const Uint32 *src32 = (Uint32 *) src;
@@ -313,7 +361,7 @@
        break;
    default:                   /* If this happens... FIXME! */
        SDL_SetError("SDL_MixAudio(): unknown audio format");
        SDL_SetError("SDL_MixAudioFormat(): unknown audio format");
        return;
    }
}
source/src/audio/SDL_sysaudio.h
@@ -26,6 +26,10 @@
#include "SDL_mutex.h"
#include "SDL_thread.h"
/* !!! FIXME: These are wordy and unlocalized... */
#define DEFAULT_OUTPUT_DEVNAME "System audio output device"
#define DEFAULT_INPUT_DEVNAME "System audio capture device"
/* The SDL audio driver */
typedef struct SDL_AudioDevice SDL_AudioDevice;
#define _THIS   SDL_AudioDevice *_this
@@ -75,7 +79,9 @@
    void (*PlayDevice) (_THIS);
    int (*GetPendingBytes) (_THIS);
    Uint8 *(*GetDeviceBuf) (_THIS);
    void (*WaitDone) (_THIS);
    int (*CaptureFromDevice) (_THIS, void *buffer, int buflen);
    void (*FlushCapture) (_THIS);
    void (*PrepareToClose) (_THIS);  /**< Called between run and draining wait for playback devices */
    void (*CloseDevice) (_THIS);
    void (*LockDevice) (_THIS);
    void (*UnlockDevice) (_THIS);
@@ -87,10 +93,10 @@
    /* Some flags to push duplicate code into the core and reduce #ifdefs. */
    /* !!! FIXME: these should be SDL_bool */
    int ProvidesOwnCallbackThread;
    int SkipMixerLock;  /* !!! FIXME: do we need this anymore? */
    int SkipMixerLock;
    int HasCaptureSupport;
    int OnlyHasDefaultOutputDevice;
    int OnlyHasDefaultInputDevice;
    int OnlyHasDefaultCaptureDevice;
    int AllowsArbitraryDeviceNames;
} SDL_AudioDriverImpl;
@@ -157,12 +163,10 @@
    SDL_AudioStreamer streamer;
    /* Current state flags */
    /* !!! FIXME: should be SDL_bool */
    int iscapture;
    int enabled;  /* true if device is functioning and connected. */
    int shutdown; /* true if we are signaling the play thread to end. */
    int paused;
    int opened;
    SDL_atomic_t shutdown; /* true if we are signaling the play thread to end. */
    SDL_atomic_t enabled;  /* true if device is functioning and connected. */
    SDL_atomic_t paused;
    SDL_bool iscapture;
    /* Fake audio buffer for when the audio hardware is busy */
    Uint8 *fake_stream;
@@ -183,6 +187,8 @@
    /* * * */
    /* Data private to this driver */
    struct SDL_PrivateAudioData *hidden;
    void *handle;
};
#undef _THIS
source/src/audio/SDL_wave.c
@@ -504,7 +504,7 @@
        was_error = 1;
        goto done;
    }
    SDL_memset(spec, 0, (sizeof *spec));
    SDL_zerop(spec);
    spec->freq = SDL_SwapLE32(format->frequency);
    if (IEEE_float_encoded) {
source/src/audio/alsa/SDL_alsa_audio.c
@@ -29,9 +29,9 @@
#include <errno.h>
#include <string.h>
#include "SDL_assert.h"
#include "SDL_timer.h"
#include "SDL_audio.h"
#include "../SDL_audiomem.h"
#include "../SDL_audio_c.h"
#include "SDL_alsa_audio.h"
@@ -42,8 +42,10 @@
static int (*ALSA_snd_pcm_open)
  (snd_pcm_t **, const char *, snd_pcm_stream_t, int);
static int (*ALSA_snd_pcm_close) (snd_pcm_t * pcm);
static snd_pcm_sframes_t(*ALSA_snd_pcm_writei)
static snd_pcm_sframes_t (*ALSA_snd_pcm_writei)
  (snd_pcm_t *, const void *, snd_pcm_uframes_t);
static snd_pcm_sframes_t (*ALSA_snd_pcm_readi)
  (snd_pcm_t *, void *, snd_pcm_uframes_t);
static int (*ALSA_snd_pcm_recover) (snd_pcm_t *, int, int);
static int (*ALSA_snd_pcm_prepare) (snd_pcm_t *);
static int (*ALSA_snd_pcm_drain) (snd_pcm_t *);
@@ -85,6 +87,10 @@
static int (*ALSA_snd_pcm_wait)(snd_pcm_t *, int);
static int (*ALSA_snd_pcm_sw_params_set_avail_min)
  (snd_pcm_t *, snd_pcm_sw_params_t *, snd_pcm_uframes_t);
static int (*ALSA_snd_pcm_reset)(snd_pcm_t *);
static int (*ALSA_snd_device_name_hint) (int, const char *, void ***);
static char* (*ALSA_snd_device_name_get_hint) (const void *, const char *);
static int (*ALSA_snd_device_name_free_hint) (void **);
#ifdef SDL_AUDIO_DRIVER_ALSA_DYNAMIC
#define snd_pcm_hw_params_sizeof ALSA_snd_pcm_hw_params_sizeof
@@ -118,6 +124,7 @@
    SDL_ALSA_SYM(snd_pcm_open);
    SDL_ALSA_SYM(snd_pcm_close);
    SDL_ALSA_SYM(snd_pcm_writei);
    SDL_ALSA_SYM(snd_pcm_readi);
    SDL_ALSA_SYM(snd_pcm_recover);
    SDL_ALSA_SYM(snd_pcm_prepare);
    SDL_ALSA_SYM(snd_pcm_drain);
@@ -144,6 +151,11 @@
    SDL_ALSA_SYM(snd_pcm_nonblock);
    SDL_ALSA_SYM(snd_pcm_wait);
    SDL_ALSA_SYM(snd_pcm_sw_params_set_avail_min);
    SDL_ALSA_SYM(snd_pcm_reset);
    SDL_ALSA_SYM(snd_device_name_hint);
    SDL_ALSA_SYM(snd_device_name_get_hint);
    SDL_ALSA_SYM(snd_device_name_free_hint);
    return 0;
}
@@ -196,25 +208,27 @@
#endif /* SDL_AUDIO_DRIVER_ALSA_DYNAMIC */
static const char *
get_audio_device(int channels)
get_audio_device(void *handle, const int channels)
{
    const char *device;
    device = SDL_getenv("AUDIODEV");    /* Is there a standard variable name? */
    if (device == NULL) {
        switch (channels) {
        case 6:
            device = "plug:surround51";
            break;
        case 4:
            device = "plug:surround40";
            break;
        default:
            device = "default";
            break;
        }
    if (handle != NULL) {
        return (const char *) handle;
    }
    return device;
    /* !!! FIXME: we also check "SDL_AUDIO_DEVICE_NAME" at the higher level. */
    device = SDL_getenv("AUDIODEV");    /* Is there a standard variable name? */
    if (device != NULL) {
        return device;
    }
    if (channels == 6) {
        return "plug:surround51";
    } else if (channels == 4) {
        return "plug:surround40";
    }
    return "default";
}
@@ -232,37 +246,37 @@
 * "For Linux ALSA, this is FL-FR-RL-RR-C-LFE
 *  and for Windows DirectX [and CoreAudio], this is FL-FR-C-LFE-RL-RR"
 */
#define SWIZ6(T) \
    T *ptr = (T *) this->hidden->mixbuf; \
#define SWIZ6(T, buf, numframes) \
    T *ptr = (T *) buf; \
    Uint32 i; \
    for (i = 0; i < this->spec.samples; i++, ptr += 6) { \
    for (i = 0; i < numframes; i++, ptr += 6) { \
        T tmp; \
        tmp = ptr[2]; ptr[2] = ptr[4]; ptr[4] = tmp; \
        tmp = ptr[3]; ptr[3] = ptr[5]; ptr[5] = tmp; \
    }
static SDL_INLINE void
swizzle_alsa_channels_6_64bit(_THIS)
swizzle_alsa_channels_6_64bit(void *buffer, Uint32 bufferlen)
{
    SWIZ6(Uint64);
    SWIZ6(Uint64, buffer, bufferlen);
}
static SDL_INLINE void
swizzle_alsa_channels_6_32bit(_THIS)
swizzle_alsa_channels_6_32bit(void *buffer, Uint32 bufferlen)
{
    SWIZ6(Uint32);
    SWIZ6(Uint32, buffer, bufferlen);
}
static SDL_INLINE void
swizzle_alsa_channels_6_16bit(_THIS)
swizzle_alsa_channels_6_16bit(void *buffer, Uint32 bufferlen)
{
    SWIZ6(Uint16);
    SWIZ6(Uint16, buffer, bufferlen);
}
static SDL_INLINE void
swizzle_alsa_channels_6_8bit(_THIS)
swizzle_alsa_channels_6_8bit(void *buffer, Uint32 bufferlen)
{
    SWIZ6(Uint8);
    SWIZ6(Uint8, buffer, bufferlen);
}
#undef SWIZ6
@@ -273,18 +287,16 @@
 *  channels from Windows/Mac order to the format alsalib will want.
 */
static SDL_INLINE void
swizzle_alsa_channels(_THIS)
swizzle_alsa_channels(_THIS, void *buffer, Uint32 bufferlen)
{
    if (this->spec.channels == 6) {
        const Uint16 fmtsize = (this->spec.format & 0xFF);      /* bits/channel. */
        if (fmtsize == 16)
            swizzle_alsa_channels_6_16bit(this);
        else if (fmtsize == 8)
            swizzle_alsa_channels_6_8bit(this);
        else if (fmtsize == 32)
            swizzle_alsa_channels_6_32bit(this);
        else if (fmtsize == 64)
            swizzle_alsa_channels_6_64bit(this);
        switch (SDL_AUDIO_BITSIZE(this->spec.format)) {
            case 8: swizzle_alsa_channels_6_8bit(buffer, bufferlen); break;
            case 16: swizzle_alsa_channels_6_16bit(buffer, bufferlen); break;
            case 32: swizzle_alsa_channels_6_32bit(buffer, bufferlen); break;
            case 64: swizzle_alsa_channels_6_64bit(buffer, bufferlen); break;
            default: SDL_assert(!"unhandled bitsize"); break;
        }
    }
    /* !!! FIXME: update this for 7.1 if needed, later. */
@@ -294,19 +306,29 @@
static void
ALSA_PlayDevice(_THIS)
{
    int status;
    const Uint8 *sample_buf = (const Uint8 *) this->hidden->mixbuf;
    const int frame_size = (((int) (this->spec.format & 0xFF)) / 8) *
    const int frame_size = (((int) SDL_AUDIO_BITSIZE(this->spec.format)) / 8) *
                                this->spec.channels;
    snd_pcm_uframes_t frames_left = ((snd_pcm_uframes_t) this->spec.samples);
    swizzle_alsa_channels(this);
    swizzle_alsa_channels(this, this->hidden->mixbuf, frames_left);
    while ( frames_left > 0 && this->enabled ) {
        /* !!! FIXME: This works, but needs more testing before going live */
        /* ALSA_snd_pcm_wait(this->hidden->pcm_handle, -1); */
    while ( frames_left > 0 && SDL_AtomicGet(&this->enabled) ) {
        int status;
        /* This wait is a work-around for a hang when USB devices are
           unplugged.  Normally it should not result in any waiting,
           but in the case of a USB unplug, it serves as a way to
           join the playback thread after the timeout occurs */
        status = ALSA_snd_pcm_wait(this->hidden->pcm_handle, 1000);
        if (status == 0) {
            /*fprintf(stderr, "ALSA timeout waiting for available buffer space\n");*/
            SDL_OpenedAudioDeviceDisconnected(this);
            return;
        }
        status = ALSA_snd_pcm_writei(this->hidden->pcm_handle,
                                     sample_buf, frames_left);
                                         sample_buf, frames_left);
        if (status < 0) {
            if (status == -EAGAIN) {
@@ -336,20 +358,71 @@
    return (this->hidden->mixbuf);
}
static int
ALSA_CaptureFromDevice(_THIS, void *buffer, int buflen)
{
    Uint8 *sample_buf = (Uint8 *) buffer;
    const int frame_size = (((int) SDL_AUDIO_BITSIZE(this->spec.format)) / 8) *
                                this->spec.channels;
    const int total_frames = buflen / frame_size;
    snd_pcm_uframes_t frames_left = total_frames;
    SDL_assert((buflen % frame_size) == 0);
    while ( frames_left > 0 && SDL_AtomicGet(&this->enabled) ) {
        /* !!! FIXME: This works, but needs more testing before going live */
        /* ALSA_snd_pcm_wait(this->hidden->pcm_handle, -1); */
        int status = ALSA_snd_pcm_readi(this->hidden->pcm_handle,
                                        sample_buf, frames_left);
        if (status < 0) {
            /*printf("ALSA: capture error %d\n", status);*/
            if (status == -EAGAIN) {
                /* Apparently snd_pcm_recover() doesn't handle this case -
                   does it assume snd_pcm_wait() above? */
                SDL_Delay(1);
                continue;
            }
            status = ALSA_snd_pcm_recover(this->hidden->pcm_handle, status, 0);
            if (status < 0) {
                /* Hmm, not much we can do - abort */
                fprintf(stderr, "ALSA read failed (unrecoverable): %s\n",
                        ALSA_snd_strerror(status));
                return -1;
            }
            continue;
        }
        /*printf("ALSA: captured %d bytes\n", status * frame_size);*/
        sample_buf += status * frame_size;
        frames_left -= status;
    }
    swizzle_alsa_channels(this, buffer, total_frames - frames_left);
    return (total_frames - frames_left) * frame_size;
}
static void
ALSA_FlushCapture(_THIS)
{
    ALSA_snd_pcm_reset(this->hidden->pcm_handle);
}
static void
ALSA_CloseDevice(_THIS)
{
    if (this->hidden != NULL) {
        SDL_FreeAudioMem(this->hidden->mixbuf);
        this->hidden->mixbuf = NULL;
        if (this->hidden->pcm_handle) {
            ALSA_snd_pcm_drain(this->hidden->pcm_handle);
            ALSA_snd_pcm_close(this->hidden->pcm_handle);
            this->hidden->pcm_handle = NULL;
        }
        SDL_free(this->hidden);
        this->hidden = NULL;
    if (this->hidden->pcm_handle) {
    /* Wait for the submitted audio to drain
           ALSA_snd_pcm_drop() can hang, so don't use that.
         */
        Uint32 delay = ((this->spec.samples * 1000) / this->spec.freq) * 2;
        SDL_Delay(delay);
        ALSA_snd_pcm_close(this->hidden->pcm_handle);
    }
    SDL_free(this->hidden->mixbuf);
    SDL_free(this->hidden);
}
static int
@@ -482,16 +555,16 @@
    if (this->hidden == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
    SDL_zerop(this->hidden);
    /* Open the audio device */
    /* Name of device should depend on # channels in spec */
    status = ALSA_snd_pcm_open(&pcm_handle,
                               get_audio_device(this->spec.channels),
                               SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
                get_audio_device(handle, this->spec.channels),
                iscapture ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK,
                SND_PCM_NONBLOCK);
    if (status < 0) {
        ALSA_CloseDevice(this);
        return SDL_SetError("ALSA: Couldn't open audio device: %s",
                            ALSA_snd_strerror(status));
    }
@@ -502,7 +575,6 @@
    snd_pcm_hw_params_alloca(&hwparams);
    status = ALSA_snd_pcm_hw_params_any(pcm_handle, hwparams);
    if (status < 0) {
        ALSA_CloseDevice(this);
        return SDL_SetError("ALSA: Couldn't get hardware config: %s",
                            ALSA_snd_strerror(status));
    }
@@ -511,7 +583,6 @@
    status = ALSA_snd_pcm_hw_params_set_access(pcm_handle, hwparams,
                                               SND_PCM_ACCESS_RW_INTERLEAVED);
    if (status < 0) {
        ALSA_CloseDevice(this);
        return SDL_SetError("ALSA: Couldn't set interleaved access: %s",
                     ALSA_snd_strerror(status));
    }
@@ -565,7 +636,6 @@
        }
    }
    if (status < 0) {
        ALSA_CloseDevice(this);
        return SDL_SetError("ALSA: Couldn't find any hardware audio formats");
    }
    this->spec.format = test_format;
@@ -577,7 +647,6 @@
    if (status < 0) {
        status = ALSA_snd_pcm_hw_params_get_channels(hwparams, &channels);
        if (status < 0) {
            ALSA_CloseDevice(this);
            return SDL_SetError("ALSA: Couldn't set audio channels");
        }
        this->spec.channels = channels;
@@ -588,7 +657,6 @@
    status = ALSA_snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams,
                                                  &rate, NULL);
    if (status < 0) {
        ALSA_CloseDevice(this);
        return SDL_SetError("ALSA: Couldn't set audio frequency: %s",
                            ALSA_snd_strerror(status));
    }
@@ -598,8 +666,8 @@
    if ( ALSA_set_period_size(this, hwparams, 0) < 0 &&
         ALSA_set_buffer_size(this, hwparams, 0) < 0 ) {
        /* Failed to set desired buffer size, do the best you can... */
        if ( ALSA_set_period_size(this, hwparams, 1) < 0 ) {
            ALSA_CloseDevice(this);
        status = ALSA_set_period_size(this, hwparams, 1);
        if (status < 0) {
            return SDL_SetError("Couldn't set hardware audio parameters: %s", ALSA_snd_strerror(status));
        }
    }
@@ -607,26 +675,22 @@
    snd_pcm_sw_params_alloca(&swparams);
    status = ALSA_snd_pcm_sw_params_current(pcm_handle, swparams);
    if (status < 0) {
        ALSA_CloseDevice(this);
        return SDL_SetError("ALSA: Couldn't get software config: %s",
                            ALSA_snd_strerror(status));
    }
    status = ALSA_snd_pcm_sw_params_set_avail_min(pcm_handle, swparams, this->spec.samples);
    if (status < 0) {
        ALSA_CloseDevice(this);
        return SDL_SetError("Couldn't set minimum available samples: %s",
                            ALSA_snd_strerror(status));
    }
    status =
        ALSA_snd_pcm_sw_params_set_start_threshold(pcm_handle, swparams, 1);
    if (status < 0) {
        ALSA_CloseDevice(this);
        return SDL_SetError("ALSA: Couldn't set start threshold: %s",
                            ALSA_snd_strerror(status));
    }
    status = ALSA_snd_pcm_sw_params(pcm_handle, swparams);
    if (status < 0) {
        ALSA_CloseDevice(this);
        return SDL_SetError("Couldn't set software audio parameters: %s",
                            ALSA_snd_strerror(status));
    }
@@ -635,13 +699,14 @@
    SDL_CalculateAudioSpec(&this->spec);
    /* Allocate mixing buffer */
    this->hidden->mixlen = this->spec.size;
    this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
    if (this->hidden->mixbuf == NULL) {
        ALSA_CloseDevice(this);
        return SDL_OutOfMemory();
    if (!iscapture) {
        this->hidden->mixlen = this->spec.size;
        this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen);
        if (this->hidden->mixbuf == NULL) {
            return SDL_OutOfMemory();
        }
        SDL_memset(this->hidden->mixbuf, this->spec.silence, this->hidden->mixlen);
    }
    SDL_memset(this->hidden->mixbuf, this->spec.silence, this->hidden->mixlen);
    /* Switch to blocking mode for playback */
    ALSA_snd_pcm_nonblock(pcm_handle, 0);
@@ -650,9 +715,238 @@
    return 0;
}
typedef struct ALSA_Device
{
    char *name;
    SDL_bool iscapture;
    struct ALSA_Device *next;
} ALSA_Device;
static void
add_device(const int iscapture, const char *name, void *hint, ALSA_Device **pSeen)
{
    ALSA_Device *dev = SDL_malloc(sizeof (ALSA_Device));
    char *desc = ALSA_snd_device_name_get_hint(hint, "DESC");
    char *handle = NULL;
    char *ptr;
    if (!desc) {
        SDL_free(dev);
        return;
    } else if (!dev) {
        free(desc);
        return;
    }
    SDL_assert(name != NULL);
    /* some strings have newlines, like "HDA NVidia, HDMI 0\nHDMI Audio Output".
       just chop the extra lines off, this seems to get a reasonable device
       name without extra details. */
    if ((ptr = strchr(desc, '\n')) != NULL) {
        *ptr = '\0';
    }
    /*printf("ALSA: adding %s device '%s' (%s)\n", iscapture ? "capture" : "output", name, desc);*/
    handle = SDL_strdup(name);
    if (!handle) {
        free(desc);
        SDL_free(dev);
        return;
    }
    SDL_AddAudioDevice(iscapture, desc, handle);
    free(desc);
    dev->name = handle;
    dev->iscapture = iscapture;
    dev->next = *pSeen;
    *pSeen = dev;
}
static SDL_atomic_t ALSA_hotplug_shutdown;
static SDL_Thread *ALSA_hotplug_thread;
static int SDLCALL
ALSA_HotplugThread(void *arg)
{
    SDL_sem *first_run_semaphore = (SDL_sem *) arg;
    ALSA_Device *devices = NULL;
    ALSA_Device *next;
    ALSA_Device *dev;
    Uint32 ticks;
    while (!SDL_AtomicGet(&ALSA_hotplug_shutdown)) {
        void **hints = NULL;
        if (ALSA_snd_device_name_hint(-1, "pcm", &hints) != -1) {
            ALSA_Device *unseen = devices;
            ALSA_Device *seen = NULL;
            ALSA_Device *prev;
            int i, j;
            const char *match = NULL;
            int bestmatch = 0xFFFF;
            size_t match_len = 0;
            int defaultdev = -1;
            static const char * const prefixes[] = {
                "hw:", "sysdefault:", "default:", NULL
            };
            /* Apparently there are several different ways that ALSA lists
               actual hardware. It could be prefixed with "hw:" or "default:"
               or "sysdefault:" and maybe others. Go through the list and see
               if we can find a preferred prefix for the system. */
            for (i = 0; hints[i]; i++) {
                char *name = ALSA_snd_device_name_get_hint(hints[i], "NAME");
                if (!name) {
                    continue;
                }
                /* full name, not a prefix */
                if ((defaultdev == -1) && (SDL_strcmp(name, "default") == 0)) {
                    defaultdev = i;
                }
                for (j = 0; prefixes[j]; j++) {
                    const char *prefix = prefixes[j];
                    const size_t prefixlen = SDL_strlen(prefix);
                    if (SDL_strncmp(name, prefix, prefixlen) == 0) {
                        if (j < bestmatch) {
                            bestmatch = j;
                            match = prefix;
                            match_len = prefixlen;
                        }
                    }
                }
                free(name);
            }
            /* look through the list of device names to find matches */
            for (i = 0; hints[i]; i++) {
                char *name;
                /* if we didn't find a device name prefix we like at all... */
                if ((!match) && (defaultdev != i)) {
                    continue;  /* ...skip anything that isn't the default device. */
                }
                name = ALSA_snd_device_name_get_hint(hints[i], "NAME");
                if (!name) {
                    continue;
                }
                /* only want physical hardware interfaces */
                if (!match || (SDL_strncmp(name, match, match_len) == 0)) {
                    char *ioid = ALSA_snd_device_name_get_hint(hints[i], "IOID");
                    const SDL_bool isoutput = (ioid == NULL) || (SDL_strcmp(ioid, "Output") == 0);
                    const SDL_bool isinput = (ioid == NULL) || (SDL_strcmp(ioid, "Input") == 0);
                    SDL_bool have_output = SDL_FALSE;
                    SDL_bool have_input = SDL_FALSE;
                    free(ioid);
                    if (!isoutput && !isinput) {
                        free(name);
                        continue;
                    }
                    prev = NULL;
                    for (dev = unseen; dev; dev = next) {
                        next = dev->next;
                        if ( (SDL_strcmp(dev->name, name) == 0) && (((isinput) && dev->iscapture) || ((isoutput) && !dev->iscapture)) ) {
                            if (prev) {
                                prev->next = next;
                            } else {
                                unseen = next;
                            }
                            dev->next = seen;
                            seen = dev;
                            if (isinput) have_input = SDL_TRUE;
                            if (isoutput) have_output = SDL_TRUE;
                        } else {
                            prev = dev;
                        }
                    }
                    if (isinput && !have_input) {
                        add_device(SDL_TRUE, name, hints[i], &seen);
                    }
                    if (isoutput && !have_output) {
                        add_device(SDL_FALSE, name, hints[i], &seen);
                    }
                }
                free(name);
            }
            ALSA_snd_device_name_free_hint(hints);
            devices = seen;   /* now we have a known-good list of attached devices. */
            /* report anything still in unseen as removed. */
            for (dev = unseen; dev; dev = next) {
                /*printf("ALSA: removing %s device '%s'\n", dev->iscapture ? "capture" : "output", dev->name);*/
                next = dev->next;
                SDL_RemoveAudioDevice(dev->iscapture, dev->name);
                SDL_free(dev->name);
                SDL_free(dev);
            }
        }
        /* On first run, tell ALSA_DetectDevices() that we have a complete device list so it can return. */
        if (first_run_semaphore) {
            SDL_SemPost(first_run_semaphore);
            first_run_semaphore = NULL;  /* let other thread clean it up. */
        }
        /* Block awhile before checking again, unless we're told to stop. */
        ticks = SDL_GetTicks() + 5000;
        while (!SDL_AtomicGet(&ALSA_hotplug_shutdown) && !SDL_TICKS_PASSED(SDL_GetTicks(), ticks)) {
            SDL_Delay(100);
        }
    }
    /* Shutting down! Clean up any data we've gathered. */
    for (dev = devices; dev; dev = next) {
        /*printf("ALSA: at shutdown, removing %s device '%s'\n", dev->iscapture ? "capture" : "output", dev->name);*/
        next = dev->next;
        SDL_free(dev->name);
        SDL_free(dev);
    }
    return 0;
}
static void
ALSA_DetectDevices(void)
{
    /* Start the device detection thread here, wait for an initial iteration to complete. */
    SDL_sem *semaphore = SDL_CreateSemaphore(0);
    if (!semaphore) {
        return;  /* oh well. */
    }
    SDL_AtomicSet(&ALSA_hotplug_shutdown, 0);
    ALSA_hotplug_thread = SDL_CreateThread(ALSA_HotplugThread, "SDLHotplugALSA", semaphore);
    if (ALSA_hotplug_thread) {
        SDL_SemWait(semaphore);  /* wait for the first iteration to finish. */
    }
    SDL_DestroySemaphore(semaphore);
}
static void
ALSA_Deinitialize(void)
{
    if (ALSA_hotplug_thread != NULL) {
        SDL_AtomicSet(&ALSA_hotplug_shutdown, 1);
        SDL_WaitThread(ALSA_hotplug_thread, NULL);
        ALSA_hotplug_thread = NULL;
    }
    UnloadALSALibrary();
}
@@ -664,13 +958,17 @@
    }
    /* Set the function pointers */
    impl->DetectDevices = ALSA_DetectDevices;
    impl->OpenDevice = ALSA_OpenDevice;
    impl->WaitDevice = ALSA_WaitDevice;
    impl->GetDeviceBuf = ALSA_GetDeviceBuf;
    impl->PlayDevice = ALSA_PlayDevice;
    impl->CloseDevice = ALSA_CloseDevice;
    impl->Deinitialize = ALSA_Deinitialize;
    impl->OnlyHasDefaultOutputDevice = 1;       /* !!! FIXME: Add device enum! */
    impl->CaptureFromDevice = ALSA_CaptureFromDevice;
    impl->FlushCapture = ALSA_FlushCapture;
    impl->HasCaptureSupport = SDL_TRUE;
    return 1;   /* this audio target is available. */
}
source/src/audio/android/SDL_androidaudio.c
@@ -24,6 +24,7 @@
/* Output audio to Android */
#include "SDL_assert.h"
#include "SDL_audio.h"
#include "../SDL_audio_c.h"
#include "SDL_androidaudio.h"
@@ -33,23 +34,22 @@
#include <android/log.h>
static SDL_AudioDevice* audioDevice = NULL;
static SDL_AudioDevice* captureDevice = NULL;
static int
AndroidAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
ANDROIDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
    SDL_AudioFormat test_format;
    SDL_assert((captureDevice == NULL) || !iscapture);
    SDL_assert((audioDevice == NULL) || iscapture);
    if (iscapture) {
        /* TODO: implement capture */
        return SDL_SetError("Capture not supported on Android");
        captureDevice = this;
    } else {
        audioDevice = this;
    }
    if (audioDevice != NULL) {
        return SDL_SetError("Only one audio device at a time please!");
    }
    audioDevice = this;
    this->hidden = (struct SDL_PrivateAudioData *) SDL_calloc(1, (sizeof *this->hidden));
    if (this->hidden == NULL) {
        return SDL_OutOfMemory();
@@ -82,100 +82,137 @@
        this->spec.freq = 48000;
    }
    /* TODO: pass in/return a (Java) device ID, also whether we're opening for input or output */
    this->spec.samples = Android_JNI_OpenAudioDevice(this->spec.freq, this->spec.format == AUDIO_U8 ? 0 : 1, this->spec.channels, this->spec.samples);
    SDL_CalculateAudioSpec(&this->spec);
    /* TODO: pass in/return a (Java) device ID */
    this->spec.samples = Android_JNI_OpenAudioDevice(iscapture, this->spec.freq, this->spec.format == AUDIO_U8 ? 0 : 1, this->spec.channels, this->spec.samples);
    if (this->spec.samples == 0) {
        /* Init failed? */
        return SDL_SetError("Java-side initialization failed!");
    }
    SDL_CalculateAudioSpec(&this->spec);
    return 0;
}
static void
AndroidAUD_PlayDevice(_THIS)
ANDROIDAUDIO_PlayDevice(_THIS)
{
    Android_JNI_WriteAudioBuffer();
}
static Uint8 *
AndroidAUD_GetDeviceBuf(_THIS)
ANDROIDAUDIO_GetDeviceBuf(_THIS)
{
    return Android_JNI_GetAudioBuffer();
}
static int
ANDROIDAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
{
    return Android_JNI_CaptureAudioBuffer(buffer, buflen);
}
static void
AndroidAUD_CloseDevice(_THIS)
ANDROIDAUDIO_FlushCapture(_THIS)
{
    Android_JNI_FlushCapturedAudio();
}
static void
ANDROIDAUDIO_CloseDevice(_THIS)
{
    /* At this point SDL_CloseAudioDevice via close_audio_device took care of terminating the audio thread
       so it's safe to terminate the Java side buffer and AudioTrack
     */
    Android_JNI_CloseAudioDevice();
    if (audioDevice == this) {
        if (audioDevice->hidden != NULL) {
            SDL_free(this->hidden);
            this->hidden = NULL;
        }
    Android_JNI_CloseAudioDevice(this->iscapture);
    if (this->iscapture) {
        SDL_assert(captureDevice == this);
        captureDevice = NULL;
    } else {
        SDL_assert(audioDevice == this);
        audioDevice = NULL;
    }
    SDL_free(this->hidden);
}
static int
AndroidAUD_Init(SDL_AudioDriverImpl * impl)
ANDROIDAUDIO_Init(SDL_AudioDriverImpl * impl)
{
    /* Set the function pointers */
    impl->OpenDevice = AndroidAUD_OpenDevice;
    impl->PlayDevice = AndroidAUD_PlayDevice;
    impl->GetDeviceBuf = AndroidAUD_GetDeviceBuf;
    impl->CloseDevice = AndroidAUD_CloseDevice;
    impl->OpenDevice = ANDROIDAUDIO_OpenDevice;
    impl->PlayDevice = ANDROIDAUDIO_PlayDevice;
    impl->GetDeviceBuf = ANDROIDAUDIO_GetDeviceBuf;
    impl->CloseDevice = ANDROIDAUDIO_CloseDevice;
    impl->CaptureFromDevice = ANDROIDAUDIO_CaptureFromDevice;
    impl->FlushCapture = ANDROIDAUDIO_FlushCapture;
    /* and the capabilities */
    impl->HasCaptureSupport = 0; /* TODO */
    impl->HasCaptureSupport = SDL_TRUE;
    impl->OnlyHasDefaultOutputDevice = 1;
    impl->OnlyHasDefaultInputDevice = 1;
    impl->OnlyHasDefaultCaptureDevice = 1;
    return 1;   /* this audio target is available. */
}
AudioBootStrap ANDROIDAUD_bootstrap = {
    "android", "SDL Android audio driver", AndroidAUD_Init, 0
AudioBootStrap ANDROIDAUDIO_bootstrap = {
    "android", "SDL Android audio driver", ANDROIDAUDIO_Init, 0
};
/* Pause (block) all non already paused audio devices by taking their mixer lock */
void AndroidAUD_PauseDevices(void)
void ANDROIDAUDIO_PauseDevices(void)
{
    /* TODO: Handle multiple devices? */
    struct SDL_PrivateAudioData *private;
    if(audioDevice != NULL && audioDevice->hidden != NULL) {
        private = (struct SDL_PrivateAudioData *) audioDevice->hidden;
        if (audioDevice->paused) {
        if (SDL_AtomicGet(&audioDevice->paused)) {
            /* The device is already paused, leave it alone */
            private->resume = SDL_FALSE;
        }
        else {
            SDL_LockMutex(audioDevice->mixer_lock);
            audioDevice->paused = SDL_TRUE;
            SDL_AtomicSet(&audioDevice->paused, 1);
            private->resume = SDL_TRUE;
        }
    }
    if(captureDevice != NULL && captureDevice->hidden != NULL) {
        private = (struct SDL_PrivateAudioData *) captureDevice->hidden;
        if (SDL_AtomicGet(&captureDevice->paused)) {
            /* The device is already paused, leave it alone */
            private->resume = SDL_FALSE;
        }
        else {
            SDL_LockMutex(captureDevice->mixer_lock);
            SDL_AtomicSet(&captureDevice->paused, 1);
            private->resume = SDL_TRUE;
        }
    }
}
/* Resume (unblock) all non already paused audio devices by releasing their mixer lock */
void AndroidAUD_ResumeDevices(void)
void ANDROIDAUDIO_ResumeDevices(void)
{
    /* TODO: Handle multiple devices? */
    struct SDL_PrivateAudioData *private;
    if(audioDevice != NULL && audioDevice->hidden != NULL) {
        private = (struct SDL_PrivateAudioData *) audioDevice->hidden;
        if (private->resume) {
            audioDevice->paused = SDL_FALSE;
            SDL_AtomicSet(&audioDevice->paused, 0);
            private->resume = SDL_FALSE;
            SDL_UnlockMutex(audioDevice->mixer_lock);
        }
    }
    if(captureDevice != NULL && captureDevice->hidden != NULL) {
        private = (struct SDL_PrivateAudioData *) captureDevice->hidden;
        if (private->resume) {
            SDL_AtomicSet(&captureDevice->paused, 0);
            private->resume = SDL_FALSE;
            SDL_UnlockMutex(captureDevice->mixer_lock);
        }
    }
}
source/src/audio/android/SDL_androidaudio.h
@@ -34,8 +34,6 @@
    int resume;
};
static void AndroidAUD_CloseDevice(_THIS);
#endif /* _SDL_androidaudio_h */
/* vi: set ts=4 sw=4 expandtab: */
source/src/audio/arts/SDL_artsaudio.c
@@ -32,7 +32,6 @@
#include "SDL_timer.h"
#include "SDL_audio.h"
#include "../SDL_audiomem.h"
#include "../SDL_audio_c.h"
#include "SDL_artsaudio.h"
@@ -186,13 +185,6 @@
#endif
}
static void
ARTS_WaitDone(_THIS)
{
    /* !!! FIXME: camp here until buffer drains... SDL_Delay(???); */
}
static Uint8 *
ARTS_GetDeviceBuf(_THIS)
{
@@ -203,17 +195,12 @@
static void
ARTS_CloseDevice(_THIS)
{
    if (this->hidden != NULL) {
        SDL_FreeAudioMem(this->hidden->mixbuf);
        this->hidden->mixbuf = NULL;
        if (this->hidden->stream) {
            SDL_NAME(arts_close_stream) (this->hidden->stream);
            this->hidden->stream = 0;
        }
        SDL_NAME(arts_free) ();
        SDL_free(this->hidden);
        this->hidden = NULL;
    if (this->hidden->stream) {
        SDL_NAME(arts_close_stream) (this->hidden->stream);
    }
    SDL_NAME(arts_free) ();
    SDL_free(this->hidden->mixbuf);
    SDL_free(this->hidden);
}
static int
@@ -241,7 +228,7 @@
    if (this->hidden == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
    SDL_zerop(this->hidden);
    /* Try for a closest match on audio format */
    for (test_format = SDL_FirstAudioFormat(this->spec.format);
@@ -267,19 +254,16 @@
        }
    }
    if (format == 0) {
        ARTS_CloseDevice(this);
        return SDL_SetError("Couldn't find any hardware audio formats");
    }
    this->spec.format = test_format;
    if ((rc = SDL_NAME(arts_init) ()) != 0) {
        ARTS_CloseDevice(this);
        return SDL_SetError("Unable to initialize ARTS: %s",
                            SDL_NAME(arts_error_text) (rc));
    }
    if (!ARTS_Suspend()) {
        ARTS_CloseDevice(this);
        return SDL_SetError("ARTS can not open audio device");
    }
@@ -297,7 +281,6 @@
    /* Determine the power of two of the fragment size */
    for (frag_spec = 0; (0x01 << frag_spec) < this->spec.size; ++frag_spec);
    if ((0x01 << frag_spec) != this->spec.size) {
        ARTS_CloseDevice(this);
        return SDL_SetError("Fragment size must be a power of two");
    }
    frag_spec |= 0x00020000;    /* two fragments, for low latency */
@@ -316,9 +299,8 @@
    /* Allocate mixing buffer */
    this->hidden->mixlen = this->spec.size;
    this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
    this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen);
    if (this->hidden->mixbuf == NULL) {
        ARTS_CloseDevice(this);
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
@@ -367,7 +349,6 @@
    impl->WaitDevice = ARTS_WaitDevice;
    impl->GetDeviceBuf = ARTS_GetDeviceBuf;
    impl->CloseDevice = ARTS_CloseDevice;
    impl->WaitDone = ARTS_WaitDone;
    impl->Deinitialize = ARTS_Deinitialize;
    impl->OnlyHasDefaultOutputDevice = 1;
source/src/audio/bsd/SDL_bsdaudio.c
@@ -38,7 +38,6 @@
#include "SDL_timer.h"
#include "SDL_audio.h"
#include "../SDL_audiomem.h"
#include "../SDL_audio_c.h"
#include "../SDL_audiodev_c.h"
#include "SDL_bsdaudio.h"
@@ -63,13 +62,17 @@
#ifdef DEBUG_AUDIO
    /* *INDENT-OFF* */
    audio_info_t info;
    const audio_prinfo *prinfo;
    if (ioctl(this->hidden->audio_fd, AUDIO_GETINFO, &info) < 0) {
        fprintf(stderr, "AUDIO_GETINFO failed.\n");
        return;
    }
    prinfo = this->iscapture ? &info.play : &info.record;
    fprintf(stderr, "\n"
            "[play/record info]\n"
            "[%s info]\n"
            "buffer size    :   %d bytes\n"
            "sample rate    :   %i Hz\n"
            "channels    :   %i\n"
@@ -83,18 +86,19 @@
            "waiting        :   %s\n"
            "active        :   %s\n"
            "",
            info.play.buffer_size,
            info.play.sample_rate,
            info.play.channels,
            info.play.precision,
            info.play.encoding,
            info.play.seek,
            info.play.samples,
            info.play.eof,
            info.play.pause ? "yes" : "no",
            info.play.error ? "yes" : "no",
            info.play.waiting ? "yes" : "no",
            info.play.active ? "yes" : "no");
            this->iscapture ? "record" : "play",
            prinfo->buffer_size,
            prinfo->sample_rate,
            prinfo->channels,
            prinfo->precision,
            prinfo->encoding,
            prinfo->seek,
            prinfo->samples,
            prinfo->eof,
            prinfo->pause ? "yes" : "no",
            prinfo->error ? "yes" : "no",
            prinfo->waiting ? "yes" : "no",
            prinfo->active ? "yes" : "no");
    fprintf(stderr, "\n"
            "[audio info]\n"
@@ -182,11 +186,15 @@
            break;
        }
        if (p < written
#ifdef DEBUG_AUDIO
        fprintf(stderr, "Wrote %d bytes of audio data\n", written);
#endif
        if (p < this->hidden->mixlen
            || ((written < 0) && ((errno == 0) || (errno == EAGAIN)))) {
            SDL_Delay(1);       /* Let a little CPU time go by */
        }
    } while (p < written);
    } while (p < this->hidden->mixlen);
    /* If timer synchronization is enabled, set the next write frame */
    if (this->hidden->frame_ticks) {
@@ -197,9 +205,6 @@
    if (written < 0) {
        SDL_OpenedAudioDeviceDisconnected(this);
    }
#ifdef DEBUG_AUDIO
    fprintf(stderr, "Wrote %d bytes of audio data\n", written);
#endif
}
static Uint8 *
@@ -208,27 +213,74 @@
    return (this->hidden->mixbuf);
}
static int
BSDAUDIO_CaptureFromDevice(_THIS, void *_buffer, int buflen)
{
    Uint8 *buffer = (Uint8 *) _buffer;
    int br, p = 0;
    /* Write the audio data, checking for EAGAIN on broken audio drivers */
    do {
        br = read(this->hidden->audio_fd, buffer + p, buflen - p);
        if (br > 0)
            p += br;
        if (br == -1 && errno != 0 && errno != EAGAIN && errno != EINTR) {
            /* Non recoverable error has occurred. It should be reported!!! */
            perror("audio");
            return p ? p : -1;
        }
#ifdef DEBUG_AUDIO
        fprintf(stderr, "Captured %d bytes of audio data\n", br);
#endif
        if (p < buflen
            || ((br < 0) && ((errno == 0) || (errno == EAGAIN)))) {
            SDL_Delay(1);       /* Let a little CPU time go by */
        }
    } while (p < buflen);
}
static void
BSDAUDIO_FlushCapture(_THIS)
{
    audio_info_t info;
    size_t remain;
    Uint8 buf[512];
    if (ioctl(this->hidden->audio_fd, AUDIO_GETINFO, &info) < 0) {
        return;  /* oh well. */
    }
    remain = (size_t) (info.record.samples * (SDL_AUDIO_BITSIZE(this->spec.format) / 8));
    while (remain > 0) {
        const size_t len = SDL_min(sizeof (buf), remain);
        const int br = read(this->hidden->audio_fd, buf, len);
        if (br <= 0) {
            return;  /* oh well. */
        }
        remain -= br;
    }
}
static void
BSDAUDIO_CloseDevice(_THIS)
{
    if (this->hidden != NULL) {
        SDL_FreeAudioMem(this->hidden->mixbuf);
        this->hidden->mixbuf = NULL;
        if (this->hidden->audio_fd >= 0) {
            close(this->hidden->audio_fd);
            this->hidden->audio_fd = -1;
        }
        SDL_free(this->hidden);
        this->hidden = NULL;
    if (this->hidden->audio_fd >= 0) {
        close(this->hidden->audio_fd);
    }
    SDL_free(this->hidden->mixbuf);
    SDL_free(this->hidden);
}
static int
BSDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
    const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT);
    const int flags = iscapture ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT;
    SDL_AudioFormat format = 0;
    audio_info_t info;
    audio_prinfo *prinfo = iscapture ? &info.play : &info.record;
    /* We don't care what the devname is...we'll try to open anything. */
    /*  ...but default to first name in the list... */
@@ -245,7 +297,7 @@
    if (this->hidden == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
    SDL_zerop(this->hidden);
    /* Open the audio device */
    this->hidden->audio_fd = open(devname, flags, 0);
@@ -259,9 +311,8 @@
    SDL_CalculateAudioSpec(&this->spec);
    /* Set to play mode */
    info.mode = AUMODE_PLAY;
    info.mode = iscapture ? AUMODE_RECORD : AUMODE_PLAY;
    if (ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info) < 0) {
        BSDAUDIO_CloseDevice(this);
        return SDL_SetError("Couldn't put device into play mode");
    }
@@ -270,28 +321,28 @@
         format; format = SDL_NextAudioFormat()) {
        switch (format) {
        case AUDIO_U8:
            info.play.encoding = AUDIO_ENCODING_ULINEAR;
            info.play.precision = 8;
            prinfo->encoding = AUDIO_ENCODING_ULINEAR;
            prinfo->precision = 8;
            break;
        case AUDIO_S8:
            info.play.encoding = AUDIO_ENCODING_SLINEAR;
            info.play.precision = 8;
            prinfo->encoding = AUDIO_ENCODING_SLINEAR;
            prinfo->precision = 8;
            break;
        case AUDIO_S16LSB:
            info.play.encoding = AUDIO_ENCODING_SLINEAR_LE;
            info.play.precision = 16;
            prinfo->encoding = AUDIO_ENCODING_SLINEAR_LE;
            prinfo->precision = 16;
            break;
        case AUDIO_S16MSB:
            info.play.encoding = AUDIO_ENCODING_SLINEAR_BE;
            info.play.precision = 16;
            prinfo->encoding = AUDIO_ENCODING_SLINEAR_BE;
            prinfo->precision = 16;
            break;
        case AUDIO_U16LSB:
            info.play.encoding = AUDIO_ENCODING_ULINEAR_LE;
            info.play.precision = 16;
            prinfo->encoding = AUDIO_ENCODING_ULINEAR_LE;
            prinfo->precision = 16;
            break;
        case AUDIO_U16MSB:
            info.play.encoding = AUDIO_ENCODING_ULINEAR_BE;
            info.play.precision = 16;
            prinfo->encoding = AUDIO_ENCODING_ULINEAR_BE;
            prinfo->precision = 16;
            break;
        default:
            continue;
@@ -303,33 +354,34 @@
    }
    if (!format) {
        BSDAUDIO_CloseDevice(this);
        return SDL_SetError("No supported encoding for 0x%x", this->spec.format);
    }
    this->spec.format = format;
    AUDIO_INITINFO(&info);
    info.play.channels = this->spec.channels;
    prinfo->channels = this->spec.channels;
    if (ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info) == -1) {
        this->spec.channels = 1;
    }
    AUDIO_INITINFO(&info);
    info.play.sample_rate = this->spec.freq;
    prinfo->sample_rate = this->spec.freq;
    info.blocksize = this->spec.size;
    info.hiwat = 5;
    info.lowat = 3;
    (void) ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info);
    (void) ioctl(this->hidden->audio_fd, AUDIO_GETINFO, &info);
    this->spec.freq = info.play.sample_rate;
    /* Allocate mixing buffer */
    this->hidden->mixlen = this->spec.size;
    this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
    if (this->hidden->mixbuf == NULL) {
        BSDAUDIO_CloseDevice(this);
        return SDL_OutOfMemory();
    this->spec.freq = prinfo->sample_rate;
    if (!iscapture) {
        /* Allocate mixing buffer */
        this->hidden->mixlen = this->spec.size;
        this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen);
        if (this->hidden->mixbuf == NULL) {
            return SDL_OutOfMemory();
        }
        SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
    }
    SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
    BSDAUDIO_Status(this);
@@ -347,7 +399,10 @@
    impl->WaitDevice = BSDAUDIO_WaitDevice;
    impl->GetDeviceBuf = BSDAUDIO_GetDeviceBuf;
    impl->CloseDevice = BSDAUDIO_CloseDevice;
    impl->CaptureFromDevice = BSDAUDIO_CaptureFromDevice;
    impl->FlushCapture = BSDAUDIO_FlushCapture;
    impl->HasCaptureSupport = SDL_TRUE;
    impl->AllowsArbitraryDeviceNames = 1;
    return 1;   /* this audio target is available. */
source/src/audio/coreaudio/SDL_coreaudio.c
File was deleted
source/src/audio/coreaudio/SDL_coreaudio.h
@@ -33,9 +33,11 @@
#include <CoreAudio/CoreAudio.h>
#include <CoreServices/CoreServices.h>
#else
#include <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>
#import <UIKit/UIApplication.h>
#endif
#include <AudioToolbox/AudioToolbox.h>
#include <AudioUnit/AudioUnit.h>
/* Hidden "this" pointer for the audio functions */
@@ -43,13 +45,21 @@
struct SDL_PrivateAudioData
{
    AudioUnit audioUnit;
    int audioUnitOpened;
    SDL_Thread *thread;
    AudioQueueRef audioQueue;
    AudioQueueBufferRef audioBuffer[2];
    void *buffer;
    UInt32 bufferOffset;
    UInt32 bufferSize;
    AudioStreamBasicDescription strdesc;
    SDL_sem *ready_semaphore;
    char *thread_error;
    SDL_atomic_t shutdown;
#if MACOSX_COREAUDIO
    AudioDeviceID deviceID;
#else
    SDL_bool interrupted;
    CFTypeRef interruption_listener;
#endif
};
source/src/audio/coreaudio/SDL_coreaudio.m
New file
@@ -0,0 +1,849 @@
/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
  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"
#if SDL_AUDIO_DRIVER_COREAUDIO
/* !!! FIXME: clean out some of the macro salsa in here. */
#include "SDL_audio.h"
#include "../SDL_audio_c.h"
#include "../SDL_sysaudio.h"
#include "SDL_coreaudio.h"
#include "SDL_assert.h"
#include "../../thread/SDL_systhread.h"
#define DEBUG_COREAUDIO 0
#define CHECK_RESULT(msg) \
    if (result != noErr) { \
        SDL_SetError("CoreAudio error (%s): %d", msg, (int) result); \
        return 0; \
    }
#if MACOSX_COREAUDIO
static const AudioObjectPropertyAddress devlist_address = {
    kAudioHardwarePropertyDevices,
    kAudioObjectPropertyScopeGlobal,
    kAudioObjectPropertyElementMaster
};
typedef void (*addDevFn)(const char *name, const int iscapture, AudioDeviceID devId, void *data);
typedef struct AudioDeviceList
{
    AudioDeviceID devid;
    SDL_bool alive;
    struct AudioDeviceList *next;
} AudioDeviceList;
static AudioDeviceList *output_devs = NULL;
static AudioDeviceList *capture_devs = NULL;
static SDL_bool
add_to_internal_dev_list(const int iscapture, AudioDeviceID devId)
{
    AudioDeviceList *item = (AudioDeviceList *) SDL_malloc(sizeof (AudioDeviceList));
    if (item == NULL) {
        return SDL_FALSE;
    }
    item->devid = devId;
    item->alive = SDL_TRUE;
    item->next = iscapture ? capture_devs : output_devs;
    if (iscapture) {
        capture_devs = item;
    } else {
        output_devs = item;
    }
    return SDL_TRUE;
}
static void
addToDevList(const char *name, const int iscapture, AudioDeviceID devId, void *data)
{
    if (add_to_internal_dev_list(iscapture, devId)) {
        SDL_AddAudioDevice(iscapture, name, (void *) ((size_t) devId));
    }
}
static void
build_device_list(int iscapture, addDevFn addfn, void *addfndata)
{
    OSStatus result = noErr;
    UInt32 size = 0;
    AudioDeviceID *devs = NULL;
    UInt32 i = 0;
    UInt32 max = 0;
    result = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject,
                                            &devlist_address, 0, NULL, &size);
    if (result != kAudioHardwareNoError)
        return;
    devs = (AudioDeviceID *) alloca(size);
    if (devs == NULL)
        return;
    result = AudioObjectGetPropertyData(kAudioObjectSystemObject,
                                        &devlist_address, 0, NULL, &size, devs);
    if (result != kAudioHardwareNoError)
        return;
    max = size / sizeof (AudioDeviceID);
    for (i = 0; i < max; i++) {
        CFStringRef cfstr = NULL;
        char *ptr = NULL;
        AudioDeviceID dev = devs[i];
        AudioBufferList *buflist = NULL;
        int usable = 0;
        CFIndex len = 0;
        const AudioObjectPropertyAddress addr = {
            kAudioDevicePropertyStreamConfiguration,
            iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput,
            kAudioObjectPropertyElementMaster
        };
        const AudioObjectPropertyAddress nameaddr = {
            kAudioObjectPropertyName,
            iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput,
            kAudioObjectPropertyElementMaster
        };
        result = AudioObjectGetPropertyDataSize(dev, &addr, 0, NULL, &size);
        if (result != noErr)
            continue;
        buflist = (AudioBufferList *) SDL_malloc(size);
        if (buflist == NULL)
            continue;
        result = AudioObjectGetPropertyData(dev, &addr, 0, NULL,
                                            &size, buflist);
        if (result == noErr) {
            UInt32 j;
            for (j = 0; j < buflist->mNumberBuffers; j++) {
                if (buflist->mBuffers[j].mNumberChannels > 0) {
                    usable = 1;
                    break;
                }
            }
        }
        SDL_free(buflist);
        if (!usable)
            continue;
        size = sizeof (CFStringRef);
        result = AudioObjectGetPropertyData(dev, &nameaddr, 0, NULL, &size, &cfstr);
        if (result != kAudioHardwareNoError)
            continue;
        len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfstr),
                                                kCFStringEncodingUTF8);
        ptr = (char *) SDL_malloc(len + 1);
        usable = ((ptr != NULL) &&
                  (CFStringGetCString
                   (cfstr, ptr, len + 1, kCFStringEncodingUTF8)));
        CFRelease(cfstr);
        if (usable) {
            len = strlen(ptr);
            /* Some devices have whitespace at the end...trim it. */
            while ((len > 0) && (ptr[len - 1] == ' ')) {
                len--;
            }
            usable = (len > 0);
        }
        if (usable) {
            ptr[len] = '\0';
#if DEBUG_COREAUDIO
            printf("COREAUDIO: Found %s device #%d: '%s' (devid %d)\n",
                   ((iscapture) ? "capture" : "output"),
                   (int) i, ptr, (int) dev);
#endif
            addfn(ptr, iscapture, dev, addfndata);
        }
        SDL_free(ptr);  /* addfn() would have copied the string. */
    }
}
static void
free_audio_device_list(AudioDeviceList **list)
{
    AudioDeviceList *item = *list;
    while (item) {
        AudioDeviceList *next = item->next;
        SDL_free(item);
        item = next;
    }
    *list = NULL;
}
static void
COREAUDIO_DetectDevices(void)
{
    build_device_list(SDL_TRUE, addToDevList, NULL);
    build_device_list(SDL_FALSE, addToDevList, NULL);
}
static void
build_device_change_list(const char *name, const int iscapture, AudioDeviceID devId, void *data)
{
    AudioDeviceList **list = (AudioDeviceList **) data;
    AudioDeviceList *item;
    for (item = *list; item != NULL; item = item->next) {
        if (item->devid == devId) {
            item->alive = SDL_TRUE;
            return;
        }
    }
    add_to_internal_dev_list(iscapture, devId);  /* new device, add it. */
    SDL_AddAudioDevice(iscapture, name, (void *) ((size_t) devId));
}
static void
reprocess_device_list(const int iscapture, AudioDeviceList **list)
{
    AudioDeviceList *item;
    AudioDeviceList *prev = NULL;
    for (item = *list; item != NULL; item = item->next) {
        item->alive = SDL_FALSE;
    }
    build_device_list(iscapture, build_device_change_list, list);
    /* free items in the list that aren't still alive. */
    item = *list;
    while (item != NULL) {
        AudioDeviceList *next = item->next;
        if (item->alive) {
            prev = item;
        } else {
            SDL_RemoveAudioDevice(iscapture, (void *) ((size_t) item->devid));
            if (prev) {
                prev->next = item->next;
            } else {
                *list = item->next;
            }
            SDL_free(item);
        }
        item = next;
    }
}
/* this is called when the system's list of available audio devices changes. */
static OSStatus
device_list_changed(AudioObjectID systemObj, UInt32 num_addr, const AudioObjectPropertyAddress *addrs, void *data)
{
    reprocess_device_list(SDL_TRUE, &capture_devs);
    reprocess_device_list(SDL_FALSE, &output_devs);
    return 0;
}
#endif
static int open_playback_devices = 0;
static int open_capture_devices = 0;
#if !MACOSX_COREAUDIO
static void interruption_begin(_THIS)
{
    if (this != NULL && this->hidden->audioQueue != NULL) {
        this->hidden->interrupted = SDL_TRUE;
        AudioQueuePause(this->hidden->audioQueue);
    }
}
static void interruption_end(_THIS)
{
    if (this != NULL && this->hidden != NULL && this->hidden->audioQueue != NULL
    && this->hidden->interrupted) {
        this->hidden->interrupted = SDL_FALSE;
        AudioQueueStart(this->hidden->audioQueue, NULL);
    }
}
@interface SDLInterruptionListener : NSObject
@property (nonatomic, assign) SDL_AudioDevice *device;
@end
@implementation SDLInterruptionListener
- (void)audioSessionInterruption:(NSNotification *)note
{
    @synchronized (self) {
        NSNumber *type = note.userInfo[AVAudioSessionInterruptionTypeKey];
        if (type.unsignedIntegerValue == AVAudioSessionInterruptionTypeBegan) {
            interruption_begin(self.device);
        } else {
            interruption_end(self.device);
        }
    }
}
- (void)applicationBecameActive:(NSNotification *)note
{
    @synchronized (self) {
        interruption_end(self.device);
    }
}
@end
static BOOL update_audio_session(_THIS, SDL_bool open)
{
    @autoreleasepool {
        AVAudioSession *session = [AVAudioSession sharedInstance];
        NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
        NSString *category;
        NSError *err = nil;
        if (open_playback_devices && open_capture_devices) {
            category = AVAudioSessionCategoryPlayAndRecord;
        } else if (open_capture_devices) {
            category = AVAudioSessionCategoryRecord;
        } else {
            /* Set category to ambient so that other music continues playing.
             You can change this at runtime in your own code if you need different
             behavior. If this is common, we can add an SDL hint for this. */
            category = AVAudioSessionCategoryAmbient;
        }
        if (![session setCategory:category error:&err]) {
            NSString *desc = err.description;
            SDL_SetError("Could not set Audio Session category: %s", desc.UTF8String);
            return NO;
        }
        if (open_playback_devices + open_capture_devices == 1) {
            if (![session setActive:YES error:&err]) {
                NSString *desc = err.description;
                SDL_SetError("Could not activate Audio Session: %s", desc.UTF8String);
                return NO;
            }
        } else if (!open_playback_devices && !open_capture_devices) {
            [session setActive:NO error:nil];
        }
        if (open) {
            SDLInterruptionListener *listener = [SDLInterruptionListener new];
            listener.device = this;
            [center addObserver:listener
                       selector:@selector(audioSessionInterruption:)
                           name:AVAudioSessionInterruptionNotification
                         object:session];
            /* An interruption end notification is not guaranteed to be sent if
             we were previously interrupted... resuming if needed when the app
             becomes active seems to be the way to go. */
            [center addObserver:listener
                       selector:@selector(applicationBecameActive:)
                           name:UIApplicationDidBecomeActiveNotification
                         object:session];
            [center addObserver:listener
                       selector:@selector(applicationBecameActive:)
                           name:UIApplicationWillEnterForegroundNotification
                         object:session];
            this->hidden->interruption_listener = CFBridgingRetain(listener);
        } else {
            if (this->hidden->interruption_listener != NULL) {
                SDLInterruptionListener *listener = nil;
                listener = (SDLInterruptionListener *) CFBridgingRelease(this->hidden->interruption_listener);
                @synchronized (listener) {
                    listener.device = NULL;
                }
                [center removeObserver:listener];
            }
        }
    }
    return YES;
}
#endif
/* The AudioQueue callback */
static void
outputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer)
{
    SDL_AudioDevice *this = (SDL_AudioDevice *) inUserData;
    if (!SDL_AtomicGet(&this->enabled) || SDL_AtomicGet(&this->paused)) {
        /* Supply silence if audio is enabled and not paused */
        SDL_memset(inBuffer->mAudioData, this->spec.silence, inBuffer->mAudioDataBytesCapacity);
    } else {
        UInt32 remaining = inBuffer->mAudioDataBytesCapacity;
        Uint8 *ptr = (Uint8 *) inBuffer->mAudioData;
        while (remaining > 0) {
            UInt32 len;
            if (this->hidden->bufferOffset >= this->hidden->bufferSize) {
                /* Generate the data */
                SDL_LockMutex(this->mixer_lock);
                (*this->spec.callback)(this->spec.userdata,
                            this->hidden->buffer, this->hidden->bufferSize);
                SDL_UnlockMutex(this->mixer_lock);
                this->hidden->bufferOffset = 0;
            }
            len = this->hidden->bufferSize - this->hidden->bufferOffset;
            if (len > remaining) {
                len = remaining;
            }
            SDL_memcpy(ptr, (char *)this->hidden->buffer +
                       this->hidden->bufferOffset, len);
            ptr = ptr + len;
            remaining -= len;
            this->hidden->bufferOffset += len;
        }
    }
    if (!SDL_AtomicGet(&this->hidden->shutdown)) {
        AudioQueueEnqueueBuffer(this->hidden->audioQueue, inBuffer, 0, NULL);
    }
    inBuffer->mAudioDataByteSize = inBuffer->mAudioDataBytesCapacity;
}
static void
inputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer,
              const AudioTimeStamp *inStartTime, UInt32 inNumberPacketDescriptions,
              const AudioStreamPacketDescription *inPacketDescs )
{
    SDL_AudioDevice *this = (SDL_AudioDevice *) inUserData;
    if (SDL_AtomicGet(&this->enabled) && !SDL_AtomicGet(&this->paused)) {  /* ignore unless we're active. */
        const Uint8 *ptr = (const Uint8 *) inBuffer->mAudioData;
        UInt32 remaining = inBuffer->mAudioDataByteSize;
        while (remaining > 0) {
            UInt32 len = this->hidden->bufferSize - this->hidden->bufferOffset;
            if (len > remaining) {
                len = remaining;
            }
            SDL_memcpy((char *)this->hidden->buffer + this->hidden->bufferOffset, ptr, len);
            ptr += len;
            remaining -= len;
            this->hidden->bufferOffset += len;
            if (this->hidden->bufferOffset >= this->hidden->bufferSize) {
                SDL_LockMutex(this->mixer_lock);
                (*this->spec.callback)(this->spec.userdata, this->hidden->buffer, this->hidden->bufferSize);
                SDL_UnlockMutex(this->mixer_lock);
                this->hidden->bufferOffset = 0;
            }
        }
    }
    if (!SDL_AtomicGet(&this->hidden->shutdown)) {
        AudioQueueEnqueueBuffer(this->hidden->audioQueue, inBuffer, 0, NULL);
    }
}
#if MACOSX_COREAUDIO
static const AudioObjectPropertyAddress alive_address =
{
    kAudioDevicePropertyDeviceIsAlive,
    kAudioObjectPropertyScopeGlobal,
    kAudioObjectPropertyElementMaster
};
static OSStatus
device_unplugged(AudioObjectID devid, UInt32 num_addr, const AudioObjectPropertyAddress *addrs, void *data)
{
    SDL_AudioDevice *this = (SDL_AudioDevice *) data;
    SDL_bool dead = SDL_FALSE;
    UInt32 isAlive = 1;
    UInt32 size = sizeof (isAlive);
    OSStatus error;
    if (!SDL_AtomicGet(&this->enabled)) {
        return 0;  /* already known to be dead. */
    }
    error = AudioObjectGetPropertyData(this->hidden->deviceID, &alive_address,
                                       0, NULL, &size, &isAlive);
    if (error == kAudioHardwareBadDeviceError) {
        dead = SDL_TRUE;  /* device was unplugged. */
    } else if ((error == kAudioHardwareNoError) && (!isAlive)) {
        dead = SDL_TRUE;  /* device died in some other way. */
    }
    if (dead) {
        SDL_OpenedAudioDeviceDisconnected(this);
    }
    return 0;
}
#endif
static void
COREAUDIO_CloseDevice(_THIS)
{
    const SDL_bool iscapture = this->iscapture;
    int i;
/* !!! FIXME: what does iOS do when a bluetooth audio device vanishes? Headphones unplugged? */
/* !!! FIXME: (we only do a "default" device on iOS right now...can we do more?) */
#if MACOSX_COREAUDIO
    /* Fire a callback if the device stops being "alive" (disconnected, etc). */
    AudioObjectRemovePropertyListener(this->hidden->deviceID, &alive_address, device_unplugged, this);
#endif
#if !MACOSX_COREAUDIO
    update_audio_session(this, SDL_FALSE);
#endif
    if (this->hidden->thread) {
        SDL_AtomicSet(&this->hidden->shutdown, 1);
        SDL_WaitThread(this->hidden->thread, NULL);
    }
    if (this->hidden->audioQueue) {
        for (i = 0; i < SDL_arraysize(this->hidden->audioBuffer); i++) {
            if (this->hidden->audioBuffer[i]) {
                AudioQueueFreeBuffer(this->hidden->audioQueue, this->hidden->audioBuffer[i]);
            }
        }
        AudioQueueDispose(this->hidden->audioQueue, 1);
    }
    if (this->hidden->ready_semaphore) {
        SDL_DestroySemaphore(this->hidden->ready_semaphore);
    }
    SDL_free(this->hidden->thread_error);
    SDL_free(this->hidden->buffer);
    SDL_free(this->hidden);
    if (iscapture) {
        open_capture_devices--;
    } else {
        open_playback_devices--;
    }
}
#if MACOSX_COREAUDIO
static int
prepare_device(_THIS, void *handle, int iscapture)
{
    AudioDeviceID devid = (AudioDeviceID) ((size_t) handle);
    OSStatus result = noErr;
    UInt32 size = 0;
    UInt32 alive = 0;
    pid_t pid = 0;
    AudioObjectPropertyAddress addr = {
        0,
        kAudioObjectPropertyScopeGlobal,
        kAudioObjectPropertyElementMaster
    };
    if (handle == NULL) {
        size = sizeof (AudioDeviceID);
        addr.mSelector =
            ((iscapture) ? kAudioHardwarePropertyDefaultInputDevice :
            kAudioHardwarePropertyDefaultOutputDevice);
        result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr,
                                            0, NULL, &size, &devid);
        CHECK_RESULT("AudioHardwareGetProperty (default device)");
    }
    addr.mSelector = kAudioDevicePropertyDeviceIsAlive;
    addr.mScope = iscapture ? kAudioDevicePropertyScopeInput :
                    kAudioDevicePropertyScopeOutput;
    size = sizeof (alive);
    result = AudioObjectGetPropertyData(devid, &addr, 0, NULL, &size, &alive);
    CHECK_RESULT
        ("AudioDeviceGetProperty (kAudioDevicePropertyDeviceIsAlive)");
    if (!alive) {
        SDL_SetError("CoreAudio: requested device exists, but isn't alive.");
        return 0;
    }
    addr.mSelector = kAudioDevicePropertyHogMode;
    size = sizeof (pid);
    result = AudioObjectGetPropertyData(devid, &addr, 0, NULL, &size, &pid);
    /* some devices don't support this property, so errors are fine here. */
    if ((result == noErr) && (pid != -1)) {
        SDL_SetError("CoreAudio: requested device is being hogged.");
        return 0;
    }
    this->hidden->deviceID = devid;
    return 1;
}
#endif
static int
prepare_audioqueue(_THIS)
{
    const AudioStreamBasicDescription *strdesc = &this->hidden->strdesc;
    const int iscapture = this->iscapture;
    OSStatus result;
    int i;
    SDL_assert(CFRunLoopGetCurrent() != NULL);
    if (iscapture) {
        result = AudioQueueNewInput(strdesc, inputCallback, this, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode, 0, &this->hidden->audioQueue);
        CHECK_RESULT("AudioQueueNewInput");
    } else {
        result = AudioQueueNewOutput(strdesc, outputCallback, this, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode, 0, &this->hidden->audioQueue);
        CHECK_RESULT("AudioQueueNewOutput");
    }
#if MACOSX_COREAUDIO
{
    const AudioObjectPropertyAddress prop = {
        kAudioDevicePropertyDeviceUID,
        iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput,
        kAudioObjectPropertyElementMaster
    };
    CFStringRef devuid;
    UInt32 devuidsize = sizeof (devuid);
    result = AudioObjectGetPropertyData(this->hidden->deviceID, &prop, 0, NULL, &devuidsize, &devuid);
    CHECK_RESULT("AudioObjectGetPropertyData (kAudioDevicePropertyDeviceUID)");
    result = AudioQueueSetProperty(this->hidden->audioQueue, kAudioQueueProperty_CurrentDevice, &devuid, devuidsize);
    CHECK_RESULT("AudioQueueSetProperty (kAudioQueueProperty_CurrentDevice)");
    /* !!! FIXME: what does iOS do when a bluetooth audio device vanishes? Headphones unplugged? */
    /* !!! FIXME: (we only do a "default" device on iOS right now...can we do more?) */
    /* Fire a callback if the device stops being "alive" (disconnected, etc). */
    AudioObjectAddPropertyListener(this->hidden->deviceID, &alive_address, device_unplugged, this);
}
#endif
    /* Calculate the final parameters for this audio specification */
    SDL_CalculateAudioSpec(&this->spec);
    /* Allocate a sample buffer */
    this->hidden->bufferSize = this->spec.size;
    this->hidden->bufferOffset = iscapture ? 0 : this->hidden->bufferSize;
    this->hidden->buffer = SDL_malloc(this->hidden->bufferSize);
    if (this->hidden->buffer == NULL) {
        SDL_OutOfMemory();
        return 0;
    }
    for (i = 0; i < SDL_arraysize(this->hidden->audioBuffer); i++) {
        result = AudioQueueAllocateBuffer(this->hidden->audioQueue, this->spec.size, &this->hidden->audioBuffer[i]);
        CHECK_RESULT("AudioQueueAllocateBuffer");
        SDL_memset(this->hidden->audioBuffer[i]->mAudioData, this->spec.silence, this->hidden->audioBuffer[i]->mAudioDataBytesCapacity);
        this->hidden->audioBuffer[i]->mAudioDataByteSize = this->hidden->audioBuffer[i]->mAudioDataBytesCapacity;
        result = AudioQueueEnqueueBuffer(this->hidden->audioQueue, this->hidden->audioBuffer[i], 0, NULL);
        CHECK_RESULT("AudioQueueEnqueueBuffer");
    }
    result = AudioQueueStart(this->hidden->audioQueue, NULL);
    CHECK_RESULT("AudioQueueStart");
    /* We're running! */
    return 1;
}
static int
audioqueue_thread(void *arg)
{
    SDL_AudioDevice *this = (SDL_AudioDevice *) arg;
    const int rc = prepare_audioqueue(this);
    if (!rc) {
        this->hidden->thread_error = SDL_strdup(SDL_GetError());
        SDL_SemPost(this->hidden->ready_semaphore);
        return 0;
    }
    /* init was successful, alert parent thread and start running... */
    SDL_SemPost(this->hidden->ready_semaphore);
    while (!SDL_AtomicGet(&this->hidden->shutdown)) {
        CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.10, 1);
    }
    if (this->iscapture) {  /* just stop immediately for capture devices. */
        AudioQueueStop(this->hidden->audioQueue, 1);
    } else {  /* Drain off any pending playback. */
        AudioQueueStop(this->hidden->audioQueue, 0);
        const CFTimeInterval secs = (((this->spec.size / (SDL_AUDIO_BITSIZE(this->spec.format) / 8)) / this->spec.channels) / ((CFTimeInterval) this->spec.freq)) * 2.0;
        CFRunLoopRunInMode(kCFRunLoopDefaultMode, secs, 0);
    }
    return 0;
}
static int
COREAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
    AudioStreamBasicDescription *strdesc;
    SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
    int valid_datatype = 0;
    /* Initialize all variables that we clean on shutdown */
    this->hidden = (struct SDL_PrivateAudioData *)
        SDL_malloc((sizeof *this->hidden));
    if (this->hidden == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_zerop(this->hidden);
    strdesc = &this->hidden->strdesc;
    if (iscapture) {
        open_capture_devices++;
    } else {
        open_playback_devices++;
    }
#if !MACOSX_COREAUDIO
    if (!update_audio_session(this, SDL_TRUE)) {
        return -1;
    }
#endif
    /* Setup a AudioStreamBasicDescription with the requested format */
    SDL_zerop(strdesc);
    strdesc->mFormatID = kAudioFormatLinearPCM;
    strdesc->mFormatFlags = kLinearPCMFormatFlagIsPacked;
    strdesc->mChannelsPerFrame = this->spec.channels;
    strdesc->mSampleRate = this->spec.freq;
    strdesc->mFramesPerPacket = 1;
    while ((!valid_datatype) && (test_format)) {
        this->spec.format = test_format;
        /* Just a list of valid SDL formats, so people don't pass junk here. */
        switch (test_format) {
        case AUDIO_U8:
        case AUDIO_S8:
        case AUDIO_U16LSB:
        case AUDIO_S16LSB:
        case AUDIO_U16MSB:
        case AUDIO_S16MSB:
        case AUDIO_S32LSB:
        case AUDIO_S32MSB:
        case AUDIO_F32LSB:
        case AUDIO_F32MSB:
            valid_datatype = 1;
            strdesc->mBitsPerChannel = SDL_AUDIO_BITSIZE(this->spec.format);
            if (SDL_AUDIO_ISBIGENDIAN(this->spec.format))
                strdesc->mFormatFlags |= kLinearPCMFormatFlagIsBigEndian;
            if (SDL_AUDIO_ISFLOAT(this->spec.format))
                strdesc->mFormatFlags |= kLinearPCMFormatFlagIsFloat;
            else if (SDL_AUDIO_ISSIGNED(this->spec.format))
                strdesc->mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
            break;
        }
    }
    if (!valid_datatype) {      /* shouldn't happen, but just in case... */
        return SDL_SetError("Unsupported audio format");
    }
    strdesc->mBytesPerFrame = strdesc->mBitsPerChannel * strdesc->mChannelsPerFrame / 8;
    strdesc->mBytesPerPacket = strdesc->mBytesPerFrame * strdesc->mFramesPerPacket;
#if MACOSX_COREAUDIO
    if (!prepare_device(this, handle, iscapture)) {
        return -1;
    }
#endif
    /* This has to init in a new thread so it can get its own CFRunLoop. :/ */
    SDL_AtomicSet(&this->hidden->shutdown, 0);
    this->hidden->ready_semaphore = SDL_CreateSemaphore(0);
    if (!this->hidden->ready_semaphore) {
        return -1;  /* oh well. */
    }
    this->hidden->thread = SDL_CreateThreadInternal(audioqueue_thread, "AudioQueue thread", 512 * 1024, this);
    if (!this->hidden->thread) {
        return -1;
    }
    SDL_SemWait(this->hidden->ready_semaphore);
    SDL_DestroySemaphore(this->hidden->ready_semaphore);
    this->hidden->ready_semaphore = NULL;
    if ((this->hidden->thread != NULL) && (this->hidden->thread_error != NULL)) {
        SDL_SetError("%s", this->hidden->thread_error);
        return -1;
    }
    return (this->hidden->thread != NULL) ? 0 : -1;
}
static void
COREAUDIO_Deinitialize(void)
{
#if MACOSX_COREAUDIO
    AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &devlist_address, device_list_changed, NULL);
    free_audio_device_list(&capture_devs);
    free_audio_device_list(&output_devs);
#endif
}
static int
COREAUDIO_Init(SDL_AudioDriverImpl * impl)
{
    /* Set the function pointers */
    impl->OpenDevice = COREAUDIO_OpenDevice;
    impl->CloseDevice = COREAUDIO_CloseDevice;
    impl->Deinitialize = COREAUDIO_Deinitialize;
#if MACOSX_COREAUDIO
    impl->DetectDevices = COREAUDIO_DetectDevices;
    AudioObjectAddPropertyListener(kAudioObjectSystemObject, &devlist_address, device_list_changed, NULL);
#else
    impl->OnlyHasDefaultOutputDevice = 1;
    impl->OnlyHasDefaultCaptureDevice = 1;
#endif
    impl->ProvidesOwnCallbackThread = 1;
    impl->HasCaptureSupport = 1;
    return 1;   /* this audio target is available. */
}
AudioBootStrap COREAUDIO_bootstrap = {
    "coreaudio", "CoreAudio", COREAUDIO_Init, 0
};
#endif /* SDL_AUDIO_DRIVER_COREAUDIO */
/* vi: set ts=4 sw=4 expandtab: */
source/src/audio/directsound/SDL_directsound.c
@@ -24,6 +24,7 @@
/* Allow access to a raw mixing buffer */
#include "SDL_assert.h"
#include "SDL_timer.h"
#include "SDL_loadso.h"
#include "SDL_audio.h"
@@ -36,11 +37,13 @@
/* DirectX function pointers for audio */
static void* DSoundDLL = NULL;
typedef HRESULT(WINAPI*fnDirectSoundCreate8)(LPGUID,LPDIRECTSOUND*,LPUNKNOWN);
typedef HRESULT(WINAPI*fnDirectSoundEnumerateW)(LPDSENUMCALLBACKW, LPVOID);
typedef HRESULT(WINAPI*fnDirectSoundCaptureEnumerateW)(LPDSENUMCALLBACKW,LPVOID);
typedef HRESULT (WINAPI *fnDirectSoundCreate8)(LPGUID,LPDIRECTSOUND*,LPUNKNOWN);
typedef HRESULT (WINAPI *fnDirectSoundEnumerateW)(LPDSENUMCALLBACKW, LPVOID);
typedef HRESULT (WINAPI *fnDirectSoundCaptureCreate8)(LPCGUID,LPDIRECTSOUNDCAPTURE8 *,LPUNKNOWN);
typedef HRESULT (WINAPI *fnDirectSoundCaptureEnumerateW)(LPDSENUMCALLBACKW,LPVOID);
static fnDirectSoundCreate8 pDirectSoundCreate8 = NULL;
static fnDirectSoundEnumerateW pDirectSoundEnumerateW = NULL;
static fnDirectSoundCaptureCreate8 pDirectSoundCaptureCreate8 = NULL;
static fnDirectSoundCaptureEnumerateW pDirectSoundCaptureEnumerateW = NULL;
static void
@@ -48,6 +51,7 @@
{
    pDirectSoundCreate8 = NULL;
    pDirectSoundEnumerateW = NULL;
    pDirectSoundCaptureCreate8 = NULL;
    pDirectSoundCaptureEnumerateW = NULL;
    if (DSoundDLL != NULL) {
@@ -76,6 +80,7 @@
        loaded = 1;  /* will reset if necessary. */
        DSOUNDLOAD(DirectSoundCreate8);
        DSOUNDLOAD(DirectSoundEnumerateW);
        DSOUNDLOAD(DirectSoundCaptureCreate8);
        DSOUNDLOAD(DirectSoundCaptureEnumerateW);
        #undef DSOUNDLOAD
@@ -155,7 +160,7 @@
{
    const int iscapture = (int) ((size_t) data);
    if (guid != NULL) {  /* skip default device */
        char *str = WIN_StringToUTF8(desc);
        char *str = WIN_LookupAudioDeviceName(desc, guid);
        if (str != NULL) {
            LPGUID cpyguid = (LPGUID) SDL_malloc(sizeof (GUID));
            SDL_memcpy(cpyguid, guid, sizeof (GUID));
@@ -197,7 +202,7 @@
        return;
    }
    while ((cursor / this->hidden->mixlen) == this->hidden->lastchunk) {
    while ((cursor / this->spec.size) == this->hidden->lastchunk) {
        /* FIXME: find out how much time is left and sleep that long */
        SDL_Delay(1);
@@ -239,9 +244,8 @@
    if (this->hidden->locked_buf) {
        IDirectSoundBuffer_Unlock(this->hidden->mixbuf,
                                  this->hidden->locked_buf,
                                  this->hidden->mixlen, NULL, 0);
                                  this->spec.size, NULL, 0);
    }
}
static Uint8 *
@@ -265,7 +269,7 @@
        SetDSerror("DirectSound GetCurrentPosition", result);
        return (NULL);
    }
    cursor /= this->hidden->mixlen;
    cursor /= this->spec.size;
#ifdef DEBUG_SOUND
    /* Detect audio dropouts */
    {
@@ -281,17 +285,17 @@
#endif
    this->hidden->lastchunk = cursor;
    cursor = (cursor + 1) % this->hidden->num_buffers;
    cursor *= this->hidden->mixlen;
    cursor *= this->spec.size;
    /* Lock the audio buffer */
    result = IDirectSoundBuffer_Lock(this->hidden->mixbuf, cursor,
                                     this->hidden->mixlen,
                                     this->spec.size,
                                     (LPVOID *) & this->hidden->locked_buf,
                                     &rawlen, NULL, &junk, 0);
    if (result == DSERR_BUFFERLOST) {
        IDirectSoundBuffer_Restore(this->hidden->mixbuf);
        result = IDirectSoundBuffer_Lock(this->hidden->mixbuf, cursor,
                                         this->hidden->mixlen,
                                         this->spec.size,
                                         (LPVOID *) & this->
                                         hidden->locked_buf, &rawlen, NULL,
                                         &junk, 0);
@@ -303,109 +307,106 @@
    return (this->hidden->locked_buf);
}
static void
DSOUND_WaitDone(_THIS)
static int
DSOUND_CaptureFromDevice(_THIS, void *buffer, int buflen)
{
    Uint8 *stream = DSOUND_GetDeviceBuf(this);
    struct SDL_PrivateAudioData *h = this->hidden;
    DWORD junk, cursor, ptr1len, ptr2len;
    VOID *ptr1, *ptr2;
    /* Wait for the playing chunk to finish */
    if (stream != NULL) {
        SDL_memset(stream, this->spec.silence, this->hidden->mixlen);
        DSOUND_PlayDevice(this);
    SDL_assert(buflen == this->spec.size);
    while (SDL_TRUE) {
        if (SDL_AtomicGet(&this->shutdown)) {  /* in case the buffer froze... */
            SDL_memset(buffer, this->spec.silence, buflen);
            return buflen;
        }
        if (IDirectSoundCaptureBuffer_GetCurrentPosition(h->capturebuf, &junk, &cursor) != DS_OK) {
            return -1;
        }
        if ((cursor / this->spec.size) == h->lastchunk) {
            SDL_Delay(1);  /* FIXME: find out how much time is left and sleep that long */
        } else {
            break;
        }
    }
    DSOUND_WaitDevice(this);
    /* Stop the looping sound buffer */
    IDirectSoundBuffer_Stop(this->hidden->mixbuf);
    if (IDirectSoundCaptureBuffer_Lock(h->capturebuf, h->lastchunk * this->spec.size, this->spec.size, &ptr1, &ptr1len, &ptr2, &ptr2len, 0) != DS_OK) {
        return -1;
    }
    SDL_assert(ptr1len == this->spec.size);
    SDL_assert(ptr2 == NULL);
    SDL_assert(ptr2len == 0);
    SDL_memcpy(buffer, ptr1, ptr1len);
    if (IDirectSoundCaptureBuffer_Unlock(h->capturebuf, ptr1, ptr1len, ptr2, ptr2len) != DS_OK) {
        return -1;
    }
    h->lastchunk = (h->lastchunk + 1) % h->num_buffers;
    return ptr1len;
}
static void
DSOUND_FlushCapture(_THIS)
{
    struct SDL_PrivateAudioData *h = this->hidden;
    DWORD junk, cursor;
    if (IDirectSoundCaptureBuffer_GetCurrentPosition(h->capturebuf, &junk, &cursor) == DS_OK) {
        h->lastchunk = cursor / this->spec.size;
    }
}
static void
DSOUND_CloseDevice(_THIS)
{
    if (this->hidden != NULL) {
        if (this->hidden->sound != NULL) {
            if (this->hidden->mixbuf != NULL) {
                /* Clean up the audio buffer */
                IDirectSoundBuffer_Release(this->hidden->mixbuf);
                this->hidden->mixbuf = NULL;
            }
            IDirectSound_Release(this->hidden->sound);
            this->hidden->sound = NULL;
        }
        SDL_free(this->hidden);
        this->hidden = NULL;
    if (this->hidden->mixbuf != NULL) {
        IDirectSoundBuffer_Stop(this->hidden->mixbuf);
        IDirectSoundBuffer_Release(this->hidden->mixbuf);
    }
    if (this->hidden->sound != NULL) {
        IDirectSound_Release(this->hidden->sound);
    }
    if (this->hidden->capturebuf != NULL) {
        IDirectSoundCaptureBuffer_Stop(this->hidden->capturebuf);
        IDirectSoundCaptureBuffer_Release(this->hidden->capturebuf);
    }
    if (this->hidden->capture != NULL) {
        IDirectSoundCapture_Release(this->hidden->capture);
    }
    SDL_free(this->hidden);
}
/* This function tries to create a secondary audio buffer, and returns the
   number of audio chunks available in the created buffer.
   number of audio chunks available in the created buffer. This is for
   playback devices, not capture.
*/
static int
CreateSecondary(_THIS, HWND focus)
CreateSecondary(_THIS, const DWORD bufsize, WAVEFORMATEX *wfmt)
{
    LPDIRECTSOUND sndObj = this->hidden->sound;
    LPDIRECTSOUNDBUFFER *sndbuf = &this->hidden->mixbuf;
    Uint32 chunksize = this->spec.size;
    const int numchunks = 8;
    HRESULT result = DS_OK;
    DSBUFFERDESC format;
    LPVOID pvAudioPtr1, pvAudioPtr2;
    DWORD dwAudioBytes1, dwAudioBytes2;
    WAVEFORMATEX wfmt;
    SDL_zero(wfmt);
    if (SDL_AUDIO_ISFLOAT(this->spec.format)) {
        wfmt.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
    } else {
        wfmt.wFormatTag = WAVE_FORMAT_PCM;
    }
    wfmt.wBitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format);
    wfmt.nChannels = this->spec.channels;
    wfmt.nSamplesPerSec = this->spec.freq;
    wfmt.nBlockAlign = wfmt.nChannels * (wfmt.wBitsPerSample / 8);
    wfmt.nAvgBytesPerSec = wfmt.nSamplesPerSec * wfmt.nBlockAlign;
    /* Update the fragment size as size in bytes */
    SDL_CalculateAudioSpec(&this->spec);
    /* Try to set primary mixing privileges */
    if (focus) {
        result = IDirectSound_SetCooperativeLevel(sndObj,
                                                  focus, DSSCL_PRIORITY);
    } else {
        result = IDirectSound_SetCooperativeLevel(sndObj,
                                                  GetDesktopWindow(),
                                                  DSSCL_NORMAL);
    }
    if (result != DS_OK) {
        return SetDSerror("DirectSound SetCooperativeLevel", result);
    }
    /* Try to create the secondary buffer */
    SDL_zero(format);
    format.dwSize = sizeof(format);
    format.dwFlags = DSBCAPS_GETCURRENTPOSITION2;
    if (!focus) {
        format.dwFlags |= DSBCAPS_GLOBALFOCUS;
    } else {
        format.dwFlags |= DSBCAPS_STICKYFOCUS;
    }
    format.dwBufferBytes = numchunks * chunksize;
    if ((format.dwBufferBytes < DSBSIZE_MIN) ||
        (format.dwBufferBytes > DSBSIZE_MAX)) {
        return SDL_SetError("Sound buffer size must be between %d and %d",
                            DSBSIZE_MIN / numchunks, DSBSIZE_MAX / numchunks);
    }
    format.dwReserved = 0;
    format.lpwfxFormat = &wfmt;
    format.dwFlags |= DSBCAPS_GLOBALFOCUS;
    format.dwBufferBytes = bufsize;
    format.lpwfxFormat = wfmt;
    result = IDirectSound_CreateSoundBuffer(sndObj, &format, sndbuf, NULL);
    if (result != DS_OK) {
        return SetDSerror("DirectSound CreateSoundBuffer", result);
    }
    IDirectSoundBuffer_SetFormat(*sndbuf, &wfmt);
    IDirectSoundBuffer_SetFormat(*sndbuf, wfmt);
    /* Silence the initial audio buffer */
    result = IDirectSoundBuffer_Lock(*sndbuf, 0, format.dwBufferBytes,
@@ -420,31 +421,90 @@
    }
    /* We're ready to go */
    return (numchunks);
    return 0;
}
/* This function tries to create a capture buffer, and returns the
   number of audio chunks available in the created buffer. This is for
   capture devices, not playback.
*/
static int
CreateCaptureBuffer(_THIS, const DWORD bufsize, WAVEFORMATEX *wfmt)
{
    LPDIRECTSOUNDCAPTURE capture = this->hidden->capture;
    LPDIRECTSOUNDCAPTUREBUFFER *capturebuf = &this->hidden->capturebuf;
    DSCBUFFERDESC format;
//    DWORD junk, cursor;
    HRESULT result;
    SDL_zero(format);
    format.dwSize = sizeof (format);
    format.dwFlags = DSCBCAPS_WAVEMAPPED;
    format.dwBufferBytes = bufsize;
    format.lpwfxFormat = wfmt;
    result = IDirectSoundCapture_CreateCaptureBuffer(capture, &format, capturebuf, NULL);
    if (result != DS_OK) {
        return SetDSerror("DirectSound CreateCaptureBuffer", result);
    }
    result = IDirectSoundCaptureBuffer_Start(*capturebuf, DSCBSTART_LOOPING);
    if (result != DS_OK) {
        IDirectSoundCaptureBuffer_Release(*capturebuf);
        return SetDSerror("DirectSound Start", result);
    }
#if 0
    /* presumably this starts at zero, but just in case... */
    result = IDirectSoundCaptureBuffer_GetCurrentPosition(*capturebuf, &junk, &cursor);
    if (result != DS_OK) {
        IDirectSoundCaptureBuffer_Stop(*capturebuf);
        IDirectSoundCaptureBuffer_Release(*capturebuf);
        return SetDSerror("DirectSound GetCurrentPosition", result);
    }
    this->hidden->lastchunk = cursor / this->spec.size;
#endif
    return 0;
}
static int
DSOUND_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
    const DWORD numchunks = 8;
    HRESULT result;
    SDL_bool valid_format = SDL_FALSE;
    SDL_bool tried_format = SDL_FALSE;
    SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
    LPGUID guid = (LPGUID) handle;
    DWORD bufsize;
    /* Initialize all variables that we clean on shutdown */
    this->hidden = (struct SDL_PrivateAudioData *)
        SDL_malloc((sizeof *this->hidden));
    if (this->hidden == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
    SDL_zerop(this->hidden);
    /* Open the audio device */
    result = pDirectSoundCreate8(guid, &this->hidden->sound, NULL);
    if (result != DS_OK) {
        DSOUND_CloseDevice(this);
        return SetDSerror("DirectSoundCreate", result);
    if (iscapture) {
        result = pDirectSoundCaptureCreate8(guid, &this->hidden->capture, NULL);
        if (result != DS_OK) {
            return SetDSerror("DirectSoundCaptureCreate8", result);
        }
    } else {
        result = pDirectSoundCreate8(guid, &this->hidden->sound, NULL);
        if (result != DS_OK) {
            return SetDSerror("DirectSoundCreate8", result);
        }
        result = IDirectSound_SetCooperativeLevel(this->hidden->sound,
                                                  GetDesktopWindow(),
                                                  DSSCL_NORMAL);
        if (result != DS_OK) {
            return SetDSerror("DirectSound SetCooperativeLevel", result);
        }
    }
    while ((!valid_format) && (test_format)) {
@@ -454,10 +514,38 @@
        case AUDIO_S32:
        case AUDIO_F32:
            tried_format = SDL_TRUE;
            this->spec.format = test_format;
            this->hidden->num_buffers = CreateSecondary(this, NULL);
            if (this->hidden->num_buffers > 0) {
                valid_format = SDL_TRUE;
            /* Update the fragment size as size in bytes */
            SDL_CalculateAudioSpec(&this->spec);
            bufsize = numchunks * this->spec.size;
            if ((bufsize < DSBSIZE_MIN) || (bufsize > DSBSIZE_MAX)) {
                SDL_SetError("Sound buffer size must be between %d and %d",
                             (DSBSIZE_MIN < numchunks) ? 1 : DSBSIZE_MIN / numchunks,
                             DSBSIZE_MAX / numchunks);
            } else {
                int rc;
                WAVEFORMATEX wfmt;
                SDL_zero(wfmt);
                if (SDL_AUDIO_ISFLOAT(this->spec.format)) {
                    wfmt.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
                } else {
                    wfmt.wFormatTag = WAVE_FORMAT_PCM;
                }
                wfmt.wBitsPerSample = SDL_AUDIO_BITSIZE(this->spec.format);
                wfmt.nChannels = this->spec.channels;
                wfmt.nSamplesPerSec = this->spec.freq;
                wfmt.nBlockAlign = wfmt.nChannels * (wfmt.wBitsPerSample / 8);
                wfmt.nAvgBytesPerSec = wfmt.nSamplesPerSec * wfmt.nBlockAlign;
                rc = iscapture ? CreateCaptureBuffer(this, bufsize, &wfmt) : CreateSecondary(this, bufsize, &wfmt);
                if (rc == 0) {
                    this->hidden->num_buffers = numchunks;
                    valid_format = SDL_TRUE;
                }
            }
            break;
        }
@@ -465,15 +553,13 @@
    }
    if (!valid_format) {
        DSOUND_CloseDevice(this);
        if (tried_format) {
            return -1;  /* CreateSecondary() should have called SDL_SetError(). */
        }
        return SDL_SetError("DirectSound: Unsupported audio format");
    }
    /* The buffer will auto-start playing in DSOUND_WaitDevice() */
    this->hidden->mixlen = this->spec.size;
    /* Playback buffers will auto-start playing in DSOUND_WaitDevice() */
    return 0;                   /* good to go. */
}
@@ -498,13 +584,15 @@
    impl->OpenDevice = DSOUND_OpenDevice;
    impl->PlayDevice = DSOUND_PlayDevice;
    impl->WaitDevice = DSOUND_WaitDevice;
    impl->WaitDone = DSOUND_WaitDone;
    impl->GetDeviceBuf = DSOUND_GetDeviceBuf;
    impl->CaptureFromDevice = DSOUND_CaptureFromDevice;
    impl->FlushCapture = DSOUND_FlushCapture;
    impl->CloseDevice = DSOUND_CloseDevice;
    impl->FreeDeviceHandle = DSOUND_FreeDeviceHandle;
    impl->Deinitialize = DSOUND_Deinitialize;
    impl->HasCaptureSupport = SDL_TRUE;
    return 1;   /* this audio target is available. */
}
source/src/audio/directsound/SDL_directsound.h
@@ -35,8 +35,9 @@
{
    LPDIRECTSOUND sound;
    LPDIRECTSOUNDBUFFER mixbuf;
    LPDIRECTSOUNDCAPTURE capture;
    LPDIRECTSOUNDCAPTUREBUFFER capturebuf;
    int num_buffers;
    int mixlen;
    DWORD lastchunk;
    Uint8 *locked_buf;
};
source/src/audio/disk/SDL_diskaudio.c
@@ -31,46 +31,33 @@
#include "SDL_rwops.h"
#include "SDL_timer.h"
#include "SDL_audio.h"
#include "../SDL_audiomem.h"
#include "../SDL_audio_c.h"
#include "SDL_diskaudio.h"
/* !!! FIXME: these should be SDL hints, not environment variables. */
/* environment variables and defaults. */
#define DISKENVR_OUTFILE         "SDL_DISKAUDIOFILE"
#define DISKDEFAULT_OUTFILE      "sdlaudio.raw"
#define DISKENVR_WRITEDELAY      "SDL_DISKAUDIODELAY"
#define DISKDEFAULT_WRITEDELAY   150
static const char *
DISKAUD_GetOutputFilename(const char *devname)
{
    if (devname == NULL) {
        devname = SDL_getenv(DISKENVR_OUTFILE);
        if (devname == NULL) {
            devname = DISKDEFAULT_OUTFILE;
        }
    }
    return devname;
}
#define DISKENVR_INFILE         "SDL_DISKAUDIOFILEIN"
#define DISKDEFAULT_INFILE      "sdlaudio-in.raw"
#define DISKENVR_IODELAY      "SDL_DISKAUDIODELAY"
/* This function waits until it is possible to write a full sound buffer */
static void
DISKAUD_WaitDevice(_THIS)
DISKAUDIO_WaitDevice(_THIS)
{
    SDL_Delay(this->hidden->write_delay);
    SDL_Delay(this->hidden->io_delay);
}
static void
DISKAUD_PlayDevice(_THIS)
DISKAUDIO_PlayDevice(_THIS)
{
    size_t written;
    /* Write the audio data */
    written = SDL_RWwrite(this->hidden->output,
                          this->hidden->mixbuf, 1, this->hidden->mixlen);
    const size_t written = SDL_RWwrite(this->hidden->io,
                                       this->hidden->mixbuf,
                                       1, this->spec.size);
    /* If we couldn't write, assume fatal error for now */
    if (written != this->hidden->mixlen) {
    if (written != this->spec.size) {
        SDL_OpenedAudioDeviceDisconnected(this);
    }
#ifdef DEBUG_AUDIO
@@ -79,63 +66,105 @@
}
static Uint8 *
DISKAUD_GetDeviceBuf(_THIS)
DISKAUDIO_GetDeviceBuf(_THIS)
{
    return (this->hidden->mixbuf);
}
static void
DISKAUD_CloseDevice(_THIS)
static int
DISKAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
{
    if (this->hidden != NULL) {
        SDL_FreeAudioMem(this->hidden->mixbuf);
        this->hidden->mixbuf = NULL;
        if (this->hidden->output != NULL) {
            SDL_RWclose(this->hidden->output);
            this->hidden->output = NULL;
    struct SDL_PrivateAudioData *h = this->hidden;
    const int origbuflen = buflen;
    SDL_Delay(h->io_delay);
    if (h->io) {
        const size_t br = SDL_RWread(h->io, buffer, 1, buflen);
        buflen -= (int) br;
        buffer = ((Uint8 *) buffer) + br;
        if (buflen > 0) {  /* EOF (or error, but whatever). */
            SDL_RWclose(h->io);
            h->io = NULL;
        }
        SDL_free(this->hidden);
        this->hidden = NULL;
    }
    /* if we ran out of file, just write silence. */
    SDL_memset(buffer, this->spec.silence, buflen);
    return origbuflen;
}
static void
DISKAUDIO_FlushCapture(_THIS)
{
    /* no op...we don't advance the file pointer or anything. */
}
static void
DISKAUDIO_CloseDevice(_THIS)
{
    if (this->hidden->io != NULL) {
        SDL_RWclose(this->hidden->io);
    }
    SDL_free(this->hidden->mixbuf);
    SDL_free(this->hidden);
}
static const char *
get_filename(const int iscapture, const char *devname)
{
    if (devname == NULL) {
        devname = SDL_getenv(iscapture ? DISKENVR_INFILE : DISKENVR_OUTFILE);
        if (devname == NULL) {
            devname = iscapture ? DISKDEFAULT_INFILE : DISKDEFAULT_OUTFILE;
        }
    }
    return devname;
}
static int
DISKAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
DISKAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
    /* handle != NULL means "user specified the placeholder name on the fake detected device list" */
    const char *fname = DISKAUD_GetOutputFilename(handle ? NULL : devname);
    const char *envr = SDL_getenv(DISKENVR_WRITEDELAY);
    const char *fname = get_filename(iscapture, handle ? NULL : devname);
    const char *envr = SDL_getenv(DISKENVR_IODELAY);
    this->hidden = (struct SDL_PrivateAudioData *)
        SDL_malloc(sizeof(*this->hidden));
    if (this->hidden == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden, 0, sizeof(*this->hidden));
    SDL_zerop(this->hidden);
    this->hidden->mixlen = this->spec.size;
    this->hidden->write_delay =
        (envr) ? SDL_atoi(envr) : DISKDEFAULT_WRITEDELAY;
    if (envr != NULL) {
        this->hidden->io_delay = SDL_atoi(envr);
    } else {
        this->hidden->io_delay = ((this->spec.samples * 1000) / this->spec.freq);
    }
    /* Open the audio device */
    this->hidden->output = SDL_RWFromFile(fname, "wb");
    if (this->hidden->output == NULL) {
        DISKAUD_CloseDevice(this);
    this->hidden->io = SDL_RWFromFile(fname, iscapture ? "rb" : "wb");
    if (this->hidden->io == NULL) {
        return -1;
    }
    /* Allocate mixing buffer */
    this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
    if (this->hidden->mixbuf == NULL) {
        DISKAUD_CloseDevice(this);
        return -1;
    if (!iscapture) {
        this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->spec.size);
        if (this->hidden->mixbuf == NULL) {
            return SDL_OutOfMemory();
        }
        SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
    }
    SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
#if HAVE_STDIO_H
    fprintf(stderr,
            "WARNING: You are using the SDL disk writer audio driver!\n"
            " Writing to file [%s].\n", fname);
            "WARNING: You are using the SDL disk i/o audio driver!\n"
            " %s file [%s].\n", iscapture ? "Reading from" : "Writing to",
            fname);
#endif
    /* We're ready to rock and roll. :-) */
@@ -143,30 +172,34 @@
}
static void
DISKAUD_DetectDevices(void)
DISKAUDIO_DetectDevices(void)
{
    /* !!! FIXME: stole this literal string from DEFAULT_OUTPUT_DEVNAME in SDL_audio.c */
    SDL_AddAudioDevice(SDL_FALSE, "System audio output device", (void *) 0x1);
    SDL_AddAudioDevice(SDL_FALSE, DEFAULT_OUTPUT_DEVNAME, (void *) 0x1);
    SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, (void *) 0x2);
}
static int
DISKAUD_Init(SDL_AudioDriverImpl * impl)
DISKAUDIO_Init(SDL_AudioDriverImpl * impl)
{
    /* Set the function pointers */
    impl->OpenDevice = DISKAUD_OpenDevice;
    impl->WaitDevice = DISKAUD_WaitDevice;
    impl->PlayDevice = DISKAUD_PlayDevice;
    impl->GetDeviceBuf = DISKAUD_GetDeviceBuf;
    impl->CloseDevice = DISKAUD_CloseDevice;
    impl->DetectDevices = DISKAUD_DetectDevices;
    impl->OpenDevice = DISKAUDIO_OpenDevice;
    impl->WaitDevice = DISKAUDIO_WaitDevice;
    impl->PlayDevice = DISKAUDIO_PlayDevice;
    impl->GetDeviceBuf = DISKAUDIO_GetDeviceBuf;
    impl->CaptureFromDevice = DISKAUDIO_CaptureFromDevice;
    impl->FlushCapture = DISKAUDIO_FlushCapture;
    impl->CloseDevice = DISKAUDIO_CloseDevice;
    impl->DetectDevices = DISKAUDIO_DetectDevices;
    impl->AllowsArbitraryDeviceNames = 1;
    impl->HasCaptureSupport = SDL_TRUE;
    return 1;   /* this audio target is available. */
}
AudioBootStrap DISKAUD_bootstrap = {
    "disk", "direct-to-disk audio", DISKAUD_Init, 1
AudioBootStrap DISKAUDIO_bootstrap = {
    "disk", "direct-to-disk audio", DISKAUDIO_Init, 1
};
#endif /* SDL_AUDIO_DRIVER_DISK */
source/src/audio/disk/SDL_diskaudio.h
@@ -32,10 +32,9 @@
struct SDL_PrivateAudioData
{
    /* The file descriptor for the audio device */
    SDL_RWops *output;
    SDL_RWops *io;
    Uint32 io_delay;
    Uint8 *mixbuf;
    Uint32 mixlen;
    Uint32 write_delay;
};
#endif /* _SDL_diskaudio_h */
source/src/audio/dsp/SDL_dspaudio.c
@@ -44,7 +44,6 @@
#include "SDL_timer.h"
#include "SDL_audio.h"
#include "../SDL_audiomem.h"
#include "../SDL_audio_c.h"
#include "../SDL_audiodev_c.h"
#include "SDL_dspaudio.h"
@@ -60,16 +59,11 @@
static void
DSP_CloseDevice(_THIS)
{
    if (this->hidden != NULL) {
        SDL_FreeAudioMem(this->hidden->mixbuf);
        this->hidden->mixbuf = NULL;
        if (this->hidden->audio_fd >= 0) {
            close(this->hidden->audio_fd);
            this->hidden->audio_fd = -1;
        }
        SDL_free(this->hidden);
        this->hidden = NULL;
    if (this->hidden->audio_fd >= 0) {
        close(this->hidden->audio_fd);
    }
    SDL_free(this->hidden->mixbuf);
    SDL_free(this->hidden);
}
@@ -106,23 +100,20 @@
    if (this->hidden == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
    SDL_zerop(this->hidden);
    /* Open the audio device */
    this->hidden->audio_fd = open(devname, flags, 0);
    if (this->hidden->audio_fd < 0) {
        DSP_CloseDevice(this);
        return SDL_SetError("Couldn't open %s: %s", devname, strerror(errno));
    }
    this->hidden->mixbuf = NULL;
    /* Make the file descriptor use blocking writes with fcntl() */
    /* Make the file descriptor use blocking i/o with fcntl() */
    {
        long ctlflags;
        ctlflags = fcntl(this->hidden->audio_fd, F_GETFL);
        ctlflags &= ~O_NONBLOCK;
        if (fcntl(this->hidden->audio_fd, F_SETFL, ctlflags) < 0) {
            DSP_CloseDevice(this);
            return SDL_SetError("Couldn't set audio blocking mode");
        }
    }
@@ -130,7 +121,6 @@
    /* Get a list of supported hardware formats */
    if (ioctl(this->hidden->audio_fd, SNDCTL_DSP_GETFMTS, &value) < 0) {
        perror("SNDCTL_DSP_GETFMTS");
        DSP_CloseDevice(this);
        return SDL_SetError("Couldn't get audio format list");
    }
@@ -187,7 +177,6 @@
        }
    }
    if (format == 0) {
        DSP_CloseDevice(this);
        return SDL_SetError("Couldn't find any hardware audio formats");
    }
    this->spec.format = test_format;
@@ -197,7 +186,6 @@
    if ((ioctl(this->hidden->audio_fd, SNDCTL_DSP_SETFMT, &value) < 0) ||
        (value != format)) {
        perror("SNDCTL_DSP_SETFMT");
        DSP_CloseDevice(this);
        return SDL_SetError("Couldn't set audio format");
    }
@@ -205,7 +193,6 @@
    value = this->spec.channels;
    if (ioctl(this->hidden->audio_fd, SNDCTL_DSP_CHANNELS, &value) < 0) {
        perror("SNDCTL_DSP_CHANNELS");
        DSP_CloseDevice(this);
        return SDL_SetError("Cannot set the number of channels");
    }
    this->spec.channels = value;
@@ -214,7 +201,6 @@
    value = this->spec.freq;
    if (ioctl(this->hidden->audio_fd, SNDCTL_DSP_SPEED, &value) < 0) {
        perror("SNDCTL_DSP_SPEED");
        DSP_CloseDevice(this);
        return SDL_SetError("Couldn't set audio frequency");
    }
    this->spec.freq = value;
@@ -225,7 +211,6 @@
    /* Determine the power of two of the fragment size */
    for (frag_spec = 0; (0x01U << frag_spec) < this->spec.size; ++frag_spec);
    if ((0x01U << frag_spec) != this->spec.size) {
        DSP_CloseDevice(this);
        return SDL_SetError("Fragment size must be a power of two");
    }
    frag_spec |= 0x00020000;    /* two fragments, for low latency */
@@ -250,13 +235,14 @@
#endif
    /* Allocate mixing buffer */
    this->hidden->mixlen = this->spec.size;
    this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
    if (this->hidden->mixbuf == NULL) {
        DSP_CloseDevice(this);
        return SDL_OutOfMemory();
    if (!iscapture) {
        this->hidden->mixlen = this->spec.size;
        this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen);
        if (this->hidden->mixbuf == NULL) {
            return SDL_OutOfMemory();
        }
        SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
    }
    SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
    /* We're ready to rock and roll. :-) */
    return 0;
@@ -266,14 +252,13 @@
static void
DSP_PlayDevice(_THIS)
{
    const Uint8 *mixbuf = this->hidden->mixbuf;
    const int mixlen = this->hidden->mixlen;
    if (write(this->hidden->audio_fd, mixbuf, mixlen) == -1) {
    struct SDL_PrivateAudioData *h = this->hidden;
    if (write(h->audio_fd, h->mixbuf, h->mixlen) == -1) {
        perror("Audio write");
        SDL_OpenedAudioDeviceDisconnected(this);
    }
#ifdef DEBUG_AUDIO
    fprintf(stderr, "Wrote %d bytes of audio data\n", mixlen);
    fprintf(stderr, "Wrote %d bytes of audio data\n", h->mixlen);
#endif
}
@@ -281,6 +266,30 @@
DSP_GetDeviceBuf(_THIS)
{
    return (this->hidden->mixbuf);
}
static int
DSP_CaptureFromDevice(_THIS, void *buffer, int buflen)
{
    return (int) read(this->hidden->audio_fd, buffer, buflen);
}
static void
DSP_FlushCapture(_THIS)
{
    struct SDL_PrivateAudioData *h = this->hidden;
    audio_buf_info info;
    if (ioctl(h->audio_fd, SNDCTL_DSP_GETISPACE, &info) == 0) {
        while (info.bytes > 0) {
            char buf[512];
            const size_t len = SDL_min(sizeof (buf), info.bytes);
            const ssize_t br = read(h->audio_fd, buf, len);
            if (br <= 0) {
                break;
            }
            info.bytes -= br;
        }
    }
}
static int
@@ -292,8 +301,11 @@
    impl->PlayDevice = DSP_PlayDevice;
    impl->GetDeviceBuf = DSP_GetDeviceBuf;
    impl->CloseDevice = DSP_CloseDevice;
    impl->CaptureFromDevice = DSP_CaptureFromDevice;
    impl->FlushCapture = DSP_FlushCapture;
    impl->AllowsArbitraryDeviceNames = 1;
    impl->HasCaptureSupport = SDL_TRUE;
    return 1;   /* this audio target is available. */
}
source/src/audio/dummy/SDL_dummyaudio.c
@@ -22,27 +22,44 @@
/* Output audio to nowhere... */
#include "SDL_timer.h"
#include "SDL_audio.h"
#include "../SDL_audio_c.h"
#include "SDL_dummyaudio.h"
static int
DUMMYAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
DUMMYAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
    return 0;                   /* always succeeds. */
}
static int
DUMMYAUD_Init(SDL_AudioDriverImpl * impl)
DUMMYAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
{
    /* Delay to make this sort of simulate real audio input. */
    SDL_Delay((this->spec.samples * 1000) / this->spec.freq);
    /* always return a full buffer of silence. */
    SDL_memset(buffer, this->spec.silence, buflen);
    return buflen;
}
static int
DUMMYAUDIO_Init(SDL_AudioDriverImpl * impl)
{
    /* Set the function pointers */
    impl->OpenDevice = DUMMYAUD_OpenDevice;
    impl->OpenDevice = DUMMYAUDIO_OpenDevice;
    impl->CaptureFromDevice = DUMMYAUDIO_CaptureFromDevice;
    impl->OnlyHasDefaultOutputDevice = 1;
    impl->OnlyHasDefaultCaptureDevice = 1;
    impl->HasCaptureSupport = SDL_TRUE;
    return 1;   /* this audio target is available. */
}
AudioBootStrap DUMMYAUD_bootstrap = {
    "dummy", "SDL dummy audio driver", DUMMYAUD_Init, 1
AudioBootStrap DUMMYAUDIO_bootstrap = {
    "dummy", "SDL dummy audio driver", DUMMYAUDIO_Init, 1
};
/* vi: set ts=4 sw=4 expandtab: */
source/src/audio/emscripten/SDL_emscriptenaudio.c
@@ -61,16 +61,15 @@
    Uint8 *buf = NULL;
    int byte_len = 0;
    int bytes = SDL_AUDIO_BITSIZE(this->spec.format) / 8;
    int bytes_in = SDL_AUDIO_BITSIZE(this->convert.src_format) / 8;
    /* Only do soemthing if audio is enabled */
    if (!this->enabled)
    /* Only do something if audio is enabled */
    if (!SDL_AtomicGet(&this->enabled) || SDL_AtomicGet(&this->paused)) {
        return;
    if (this->paused)
        return;
    }
    if (this->convert.needed) {
        const int bytes_in = SDL_AUDIO_BITSIZE(this->convert.src_format) / 8;
        if (this->hidden->conv_in_len != 0) {
            this->convert.len = this->hidden->conv_in_len * bytes_in * this->spec.channels;
        }
@@ -128,7 +127,7 @@
                }
                for (var j = 0; j < $1; ++j) {
                    channelData[j] = getValue($0 + (j*numChannels + c)*4, 'float');
                    channelData[j] = HEAPF32[$0 + ((j*numChannels + c) << 2) >> 2];
                }
            }
        }, buf, byte_len / bytes / this->spec.channels);
@@ -136,29 +135,147 @@
}
static void
Emscripten_CloseDevice(_THIS)
HandleCaptureProcess(_THIS)
{
    if (this->hidden != NULL) {
        if (this->hidden->mixbuf != NULL) {
            /* Clean up the audio buffer */
            SDL_free(this->hidden->mixbuf);
            this->hidden->mixbuf = NULL;
        }
    Uint8 *buf;
    int buflen;
        SDL_free(this->hidden);
        this->hidden = NULL;
    /* Only do something if audio is enabled */
    if (!SDL_AtomicGet(&this->enabled) || SDL_AtomicGet(&this->paused)) {
        return;
    }
    if (this->convert.needed) {
        buf = this->convert.buf;
        buflen = this->convert.len_cvt;
    } else {
        if (!this->hidden->mixbuf) {
            this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->spec.size);
            if (!this->hidden->mixbuf) {
                return;  /* oh well. */
            }
        }
        buf = this->hidden->mixbuf;
        buflen = this->spec.size;
    }
    EM_ASM_ARGS({
        var numChannels = SDL2.capture.currentCaptureBuffer.numberOfChannels;
        if (numChannels == 1) {  /* fastpath this a little for the common (mono) case. */
            var channelData = SDL2.capture.currentCaptureBuffer.getChannelData(0);
            if (channelData.length != $1) {
                throw 'Web Audio capture buffer length mismatch! Destination size: ' + channelData.length + ' samples vs expected ' + $1 + ' samples!';
            }
            for (var j = 0; j < $1; ++j) {
                setValue($0 + (j * 4), channelData[j], 'float');
            }
        } else {
            for (var c = 0; c < numChannels; ++c) {
                var channelData = SDL2.capture.currentCaptureBuffer.getChannelData(c);
                if (channelData.length != $1) {
                    throw 'Web Audio capture buffer length mismatch! Destination size: ' + channelData.length + ' samples vs expected ' + $1 + ' samples!';
                }
                for (var j = 0; j < $1; ++j) {
                    setValue($0 + (((j * numChannels) + c) * 4), channelData[j], 'float');
                }
            }
        }
    }, buf, (this->spec.size / sizeof (float)) / this->spec.channels);
    /* okay, we've got an interleaved float32 array in C now. */
    if (this->convert.needed) {
        SDL_ConvertAudio(&this->convert);
    }
    /* Send it to the app. */
    (*this->spec.callback) (this->spec.userdata, buf, buflen);
}
static void
EMSCRIPTENAUDIO_CloseDevice(_THIS)
{
    EM_ASM_({
        if ($0) {
            if (SDL2.capture.silenceTimer !== undefined) {
                clearTimeout(SDL2.capture.silenceTimer);
            }
            if (SDL2.capture.stream !== undefined) {
                var tracks = SDL2.capture.stream.getAudioTracks();
                for (var i = 0; i < tracks.length; i++) {
                    SDL2.capture.stream.removeTrack(tracks[i]);
                }
                SDL2.capture.stream = undefined;
            }
            if (SDL2.capture.scriptProcessorNode !== undefined) {
                SDL2.capture.scriptProcessorNode.onaudioprocess = function(audioProcessingEvent) {};
                SDL2.capture.scriptProcessorNode.disconnect();
                SDL2.capture.scriptProcessorNode = undefined;
            }
            if (SDL2.capture.mediaStreamNode !== undefined) {
                SDL2.capture.mediaStreamNode.disconnect();
                SDL2.capture.mediaStreamNode = undefined;
            }
            if (SDL2.capture.silenceBuffer !== undefined) {
                SDL2.capture.silenceBuffer = undefined
            }
            SDL2.capture = undefined;
        } else {
            if (SDL2.audio.scriptProcessorNode != undefined) {
                SDL2.audio.scriptProcessorNode.disconnect();
                SDL2.audio.scriptProcessorNode = undefined;
            }
            SDL2.audio = undefined;
        }
        if ((SDL2.audioContext !== undefined) && (SDL2.audio === undefined) && (SDL2.capture === undefined)) {
            SDL2.audioContext.close();
            SDL2.audioContext = undefined;
        }
    }, this->iscapture);
    SDL_free(this->hidden->mixbuf);
    SDL_free(this->hidden);
}
static int
Emscripten_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
EMSCRIPTENAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
    SDL_bool valid_format = SDL_FALSE;
    SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
    SDL_AudioFormat test_format;
    int i;
    float f;
    int result;
    /* based on parts of library_sdl.js */
    /* create context (TODO: this puts stuff in the global namespace...)*/
    result = EM_ASM_INT({
        if(typeof(SDL2) === 'undefined') {
            SDL2 = {};
        }
        if (!$0) {
            SDL2.audio = {};
        } else {
            SDL2.capture = {};
        }
        if (!SDL2.audioContext) {
            if (typeof(AudioContext) !== 'undefined') {
                SDL2.audioContext = new AudioContext();
            } else if (typeof(webkitAudioContext) !== 'undefined') {
                SDL2.audioContext = new webkitAudioContext();
            }
        }
        return SDL2.audioContext === undefined ? -1 : 0;
    }, iscapture);
    if (result < 0) {
        return SDL_SetError("Web Audio API is not available!");
    }
    test_format = SDL_FirstAudioFormat(this->spec.format);
    while ((!valid_format) && (test_format)) {
        switch (test_format) {
        case AUDIO_F32: /* web audio only supports floats */
@@ -181,36 +298,11 @@
    if (this->hidden == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
    /* based on parts of library_sdl.js */
    /* create context (TODO: this puts stuff in the global namespace...)*/
    result = EM_ASM_INT_V({
        if(typeof(SDL2) === 'undefined')
            SDL2 = {};
        if(typeof(SDL2.audio) === 'undefined')
            SDL2.audio = {};
        if (!SDL2.audioContext) {
            if (typeof(AudioContext) !== 'undefined') {
                SDL2.audioContext = new AudioContext();
            } else if (typeof(webkitAudioContext) !== 'undefined') {
                SDL2.audioContext = new webkitAudioContext();
            } else {
                return -1;
            }
        }
        return 0;
    });
    if (result < 0) {
        return SDL_SetError("Web Audio API is not available!");
    }
    SDL_zerop(this->hidden);
    /* limit to native freq */
    int sampleRate = EM_ASM_INT_V({
        return SDL2.audioContext['sampleRate'];
    const int sampleRate = EM_ASM_INT_V({
        return SDL2.audioContext.sampleRate;
    });
    if(this->spec.freq != sampleRate) {
@@ -227,26 +319,86 @@
    SDL_CalculateAudioSpec(&this->spec);
    /* setup a ScriptProcessorNode */
    EM_ASM_ARGS({
        SDL2.audio.scriptProcessorNode = SDL2.audioContext['createScriptProcessor']($1, 0, $0);
        SDL2.audio.scriptProcessorNode['onaudioprocess'] = function (e) {
            SDL2.audio.currentOutputBuffer = e['outputBuffer'];
            Runtime.dynCall('vi', $2, [$3]);
        };
        SDL2.audio.scriptProcessorNode['connect'](SDL2.audioContext['destination']);
    }, this->spec.channels, this->spec.samples, HandleAudioProcess, this);
    if (iscapture) {
        /* The idea is to take the capture media stream, hook it up to an
           audio graph where we can pass it through a ScriptProcessorNode
           to access the raw PCM samples and push them to the SDL app's
           callback. From there, we "process" the audio data into silence
           and forget about it. */
        /* This should, strictly speaking, use MediaRecorder for capture, but
           this API is cleaner to use and better supported, and fires a
           callback whenever there's enough data to fire down into the app.
           The downside is that we are spending CPU time silencing a buffer
           that the audiocontext uselessly mixes into any output. On the
           upside, both of those things are not only run in native code in
           the browser, they're probably SIMD code, too. MediaRecorder
           feels like it's a pretty inefficient tapdance in similar ways,
           to be honest. */
        EM_ASM_({
            var have_microphone = function(stream) {
                //console.log('SDL audio capture: we have a microphone! Replacing silence callback.');
                if (SDL2.capture.silenceTimer !== undefined) {
                    clearTimeout(SDL2.capture.silenceTimer);
                    SDL2.capture.silenceTimer = undefined;
                }
                SDL2.capture.mediaStreamNode = SDL2.audioContext.createMediaStreamSource(stream);
                SDL2.capture.scriptProcessorNode = SDL2.audioContext.createScriptProcessor($1, $0, 1);
                SDL2.capture.scriptProcessorNode.onaudioprocess = function(audioProcessingEvent) {
                    if ((SDL2 === undefined) || (SDL2.capture === undefined)) { return; }
                    audioProcessingEvent.outputBuffer.getChannelData(0).fill(0.0);
                    SDL2.capture.currentCaptureBuffer = audioProcessingEvent.inputBuffer;
                    Runtime.dynCall('vi', $2, [$3]);
                };
                SDL2.capture.mediaStreamNode.connect(SDL2.capture.scriptProcessorNode);
                SDL2.capture.scriptProcessorNode.connect(SDL2.audioContext.destination);
                SDL2.capture.stream = stream;
            };
            var no_microphone = function(error) {
                //console.log('SDL audio capture: we DO NOT have a microphone! (' + error.name + ')...leaving silence callback running.');
            };
            /* we write silence to the audio callback until the microphone is available (user approves use, etc). */
            SDL2.capture.silenceBuffer = SDL2.audioContext.createBuffer($0, $1, SDL2.audioContext.sampleRate);
            SDL2.capture.silenceBuffer.getChannelData(0).fill(0.0);
            var silence_callback = function() {
                SDL2.capture.currentCaptureBuffer = SDL2.capture.silenceBuffer;
                Runtime.dynCall('vi', $2, [$3]);
            };
            SDL2.capture.silenceTimer = setTimeout(silence_callback, ($1 / SDL2.audioContext.sampleRate) * 1000);
            if ((navigator.mediaDevices !== undefined) && (navigator.mediaDevices.getUserMedia !== undefined)) {
                navigator.mediaDevices.getUserMedia({ audio: true, video: false }).then(have_microphone).catch(no_microphone);
            } else if (navigator.webkitGetUserMedia !== undefined) {
                navigator.webkitGetUserMedia({ audio: true, video: false }, have_microphone, no_microphone);
            }
        }, this->spec.channels, this->spec.samples, HandleCaptureProcess, this);
    } else {
        /* setup a ScriptProcessorNode */
        EM_ASM_ARGS({
            SDL2.audio.scriptProcessorNode = SDL2.audioContext['createScriptProcessor']($1, 0, $0);
            SDL2.audio.scriptProcessorNode['onaudioprocess'] = function (e) {
                if ((SDL2 === undefined) || (SDL2.audio === undefined)) { return; }
                SDL2.audio.currentOutputBuffer = e['outputBuffer'];
                Runtime.dynCall('vi', $2, [$3]);
            };
            SDL2.audio.scriptProcessorNode['connect'](SDL2.audioContext['destination']);
        }, this->spec.channels, this->spec.samples, HandleAudioProcess, this);
    }
    return 0;
}
static int
Emscripten_Init(SDL_AudioDriverImpl * impl)
EMSCRIPTENAUDIO_Init(SDL_AudioDriverImpl * impl)
{
    /* Set the function pointers */
    impl->OpenDevice = Emscripten_OpenDevice;
    impl->CloseDevice = Emscripten_CloseDevice;
    impl->OpenDevice = EMSCRIPTENAUDIO_OpenDevice;
    impl->CloseDevice = EMSCRIPTENAUDIO_CloseDevice;
    /* only one output */
    impl->OnlyHasDefaultOutputDevice = 1;
    /* no threads here */
@@ -254,7 +406,7 @@
    impl->ProvidesOwnCallbackThread = 1;
    /* check availability */
    int available = EM_ASM_INT_V({
    const int available = EM_ASM_INT_V({
        if (typeof(AudioContext) !== 'undefined') {
            return 1;
        } else if (typeof(webkitAudioContext) !== 'undefined') {
@@ -267,11 +419,23 @@
        SDL_SetError("No audio context available");
    }
    const int capture_available = available && EM_ASM_INT_V({
        if ((typeof(navigator.mediaDevices) !== 'undefined') && (typeof(navigator.mediaDevices.getUserMedia) !== 'undefined')) {
            return 1;
        } else if (typeof(navigator.webkitGetUserMedia) !== 'undefined') {
            return 1;
        }
        return 0;
    });
    impl->HasCaptureSupport = capture_available ? SDL_TRUE : SDL_FALSE;
    impl->OnlyHasDefaultCaptureDevice = capture_available ? SDL_TRUE : SDL_FALSE;
    return available;
}
AudioBootStrap EmscriptenAudio_bootstrap = {
    "emscripten", "SDL emscripten audio driver", Emscripten_Init, 0
AudioBootStrap EMSCRIPTENAUDIO_bootstrap = {
    "emscripten", "SDL emscripten audio driver", EMSCRIPTENAUDIO_Init, 0
};
#endif /* SDL_AUDIO_DRIVER_EMSCRIPTEN */
source/src/audio/esd/SDL_esdaudio.c
@@ -32,7 +32,6 @@
#include "SDL_timer.h"
#include "SDL_audio.h"
#include "../SDL_audiomem.h"
#include "../SDL_audio_c.h"
#include "SDL_esdaudio.h"
@@ -174,17 +173,11 @@
static void
ESD_CloseDevice(_THIS)
{
    if (this->hidden != NULL) {
        SDL_FreeAudioMem(this->hidden->mixbuf);
        this->hidden->mixbuf = NULL;
        if (this->hidden->audio_fd >= 0) {
            SDL_NAME(esd_close) (this->hidden->audio_fd);
            this->hidden->audio_fd = -1;
        }
        SDL_free(this->hidden);
        this->hidden = NULL;
    if (this->hidden->audio_fd >= 0) {
        SDL_NAME(esd_close) (this->hidden->audio_fd);
    }
    SDL_free(this->hidden->mixbuf);
    SDL_free(this->hidden);
}
/* Try to get the name of the program */
@@ -227,7 +220,7 @@
    if (this->hidden == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
    SDL_zerop(this->hidden);
    this->hidden->audio_fd = -1;
    /* Convert audio spec to the ESD audio format */
@@ -252,7 +245,6 @@
    }
    if (!found) {
        ESD_CloseDevice(this);
        return SDL_SetError("Couldn't find any hardware audio formats");
    }
@@ -271,7 +263,6 @@
                                   get_progname());
    if (this->hidden->audio_fd < 0) {
        ESD_CloseDevice(this);
        return SDL_SetError("Couldn't open ESD connection");
    }
@@ -283,9 +274,8 @@
    /* Allocate mixing buffer */
    this->hidden->mixlen = this->spec.size;
    this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
    this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen);
    if (this->hidden->mixbuf == NULL) {
        ESD_CloseDevice(this);
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
source/src/audio/fusionsound/SDL_fsaudio.c
@@ -22,6 +22,8 @@
#if SDL_AUDIO_DRIVER_FUSIONSOUND
/* !!! FIXME: why is this is SDL_FS_* instead of FUSIONSOUND_*? */
/* Allow access to a raw mixing buffer */
#ifdef HAVE_SIGNAL_H
@@ -31,7 +33,6 @@
#include "SDL_timer.h"
#include "SDL_audio.h"
#include "../SDL_audiomem.h"
#include "../SDL_audio_c.h"
#include "SDL_fsaudio.h"
@@ -150,13 +151,6 @@
#endif
}
static void
SDL_FS_WaitDone(_THIS)
{
    this->hidden->stream->Wait(this->hidden->stream,
                               this->hidden->mixsamples * FUSION_BUFFERS);
}
static Uint8 *
SDL_FS_GetDeviceBuf(_THIS)
@@ -168,20 +162,14 @@
static void
SDL_FS_CloseDevice(_THIS)
{
    if (this->hidden != NULL) {
        SDL_FreeAudioMem(this->hidden->mixbuf);
        this->hidden->mixbuf = NULL;
        if (this->hidden->stream) {
            this->hidden->stream->Release(this->hidden->stream);
            this->hidden->stream = NULL;
        }
        if (this->hidden->fs) {
            this->hidden->fs->Release(this->hidden->fs);
            this->hidden->fs = NULL;
        }
        SDL_free(this->hidden);
        this->hidden = NULL;
    if (this->hidden->stream) {
        this->hidden->stream->Release(this->hidden->stream);
    }
    if (this->hidden->fs) {
        this->hidden->fs->Release(this->hidden->fs);
    }
    SDL_free(this->hidden->mixbuf);
    SDL_free(this->hidden);
}
@@ -200,7 +188,7 @@
    if (this->hidden == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
    SDL_zerop(this->hidden);
    /* Try for a closest match on audio format */
    for (test_format = SDL_FirstAudioFormat(this->spec.format);
@@ -239,7 +227,6 @@
    }
    if (format == 0) {
        SDL_FS_CloseDevice(this);
        return SDL_SetError("Couldn't find any hardware audio formats");
    }
    this->spec.format = test_format;
@@ -247,7 +234,6 @@
    /* Retrieve the main sound interface. */
    ret = SDL_NAME(FusionSoundCreate) (&this->hidden->fs);
    if (ret) {
        SDL_FS_CloseDevice(this);
        return SDL_SetError("Unable to initialize FusionSound: %d", ret);
    }
@@ -266,7 +252,6 @@
        this->hidden->fs->CreateStream(this->hidden->fs, &desc,
                                       &this->hidden->stream);
    if (ret) {
        SDL_FS_CloseDevice(this);
        return SDL_SetError("Unable to create FusionSoundStream: %d", ret);
    }
@@ -285,9 +270,8 @@
    /* Allocate mixing buffer */
    this->hidden->mixlen = this->spec.size;
    this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
    this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen);
    if (this->hidden->mixbuf == NULL) {
        SDL_FS_CloseDevice(this);
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
@@ -328,7 +312,6 @@
    impl->WaitDevice = SDL_FS_WaitDevice;
    impl->GetDeviceBuf = SDL_FS_GetDeviceBuf;
    impl->CloseDevice = SDL_FS_CloseDevice;
    impl->WaitDone = SDL_FS_WaitDone;
    impl->Deinitialize = SDL_FS_Deinitialize;
    impl->OnlyHasDefaultOutputDevice = 1;
source/src/audio/haiku/SDL_haikuaudio.cc
@@ -49,10 +49,11 @@
    SDL_AudioDevice *audio = (SDL_AudioDevice *) device;
    /* Only do soemthing if audio is enabled */
    if (!audio->enabled)
    if (!SDL_AtomicGet(&audio->enabled)) {
        return;
    }
    if (!audio->paused) {
    if (!SDL_AtomicGet(&audio->paused)) {
        if (audio->convert.needed) {
            SDL_LockMutex(audio->mixer_lock);
            (*audio->spec.callback) (audio->spec.userdata,
@@ -73,16 +74,11 @@
static void
HAIKUAUDIO_CloseDevice(_THIS)
{
    if (_this->hidden != NULL) {
        if (_this->hidden->audio_obj) {
            _this->hidden->audio_obj->Stop();
            delete _this->hidden->audio_obj;
            _this->hidden->audio_obj = NULL;
        }
        delete _this->hidden;
        _this->hidden = NULL;
    if (_this->hidden->audio_obj) {
        _this->hidden->audio_obj->Stop();
        delete _this->hidden->audio_obj;
    }
    delete _this->hidden;
}
@@ -122,10 +118,10 @@
    if (_this->hidden == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_memset(_this->hidden, 0, (sizeof *_this->hidden));
    SDL_zerop(_this->hidden);
    /* Parse the audio format and fill the Be raw audio format */
    SDL_memset(&format, '\0', sizeof(media_raw_audio_format));
    SDL_zero(format);
    format.byte_order = B_MEDIA_LITTLE_ENDIAN;
    format.frame_rate = (float) _this->spec.freq;
    format.channel_count = _this->spec.channels;        /* !!! FIXME: support > 2? */
@@ -176,7 +172,6 @@
    }
    if (!valid_datatype) {      /* shouldn't happen, but just in case... */
        HAIKUAUDIO_CloseDevice(_this);
        return SDL_SetError("Unsupported audio format");
    }
@@ -195,7 +190,6 @@
    if (_this->hidden->audio_obj->Start() == B_NO_ERROR) {
        _this->hidden->audio_obj->SetHasData(true);
    } else {
        HAIKUAUDIO_CloseDevice(_this);
        return SDL_SetError("Unable to start Be audio");
    }
source/src/audio/nacl/SDL_naclaudio.c
@@ -27,7 +27,6 @@
#include "SDL_audio.h"
#include "SDL_mutex.h"
#include "../SDL_audiomem.h"
#include "../SDL_audio_c.h"
#include "../SDL_audiodev_c.h"
@@ -38,22 +37,20 @@
#include "ppapi_simple/ps_event.h"
/* The tag name used by NACL audio */
#define NACLAUD_DRIVER_NAME         "nacl"
#define NACLAUDIO_DRIVER_NAME         "nacl"
#define SAMPLE_FRAME_COUNT 4096
/* Audio driver functions */
static int NACLAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture);
static void NACLAUD_CloseDevice(_THIS);
static void nacl_audio_callback(void* samples, uint32_t buffer_size, PP_TimeDelta latency, void* data);
/* FIXME: Make use of latency if needed */
static void nacl_audio_callback(void* samples, uint32_t buffer_size, PP_TimeDelta latency, void* data) {
    SDL_AudioDevice* _this = (SDL_AudioDevice*) data;
    
    SDL_LockMutex(private->mutex);
    SDL_LockMutex(private->mutex);  /* !!! FIXME: is this mutex necessary? */
    if (_this->enabled && !_this->paused) {
    if (SDL_AtomicGet(&_this->enabled) && !SDL_AtomicGet(&_this->paused)) {
        if (_this->convert.needed) {
            SDL_LockMutex(_this->mixer_lock);
            (*_this->spec.callback) (_this->spec.userdata,
@@ -68,13 +65,13 @@
            SDL_UnlockMutex(_this->mixer_lock);
        }
    } else {
        SDL_memset(samples, 0, buffer_size);
        SDL_memset(samples, _this->spec.silence, buffer_size);
    }
    
    return;
    SDL_UnlockMutex(private->mutex);
}
static void NACLAUD_CloseDevice(SDL_AudioDevice *device) {
static void NACLAUDIO_CloseDevice(SDL_AudioDevice *device) {
    const PPB_Core *core = PSInterfaceCore();
    const PPB_Audio *ppb_audio = PSInterfaceAudio();
    SDL_PrivateAudioData *hidden = (SDL_PrivateAudioData *) device->hidden;
@@ -85,7 +82,7 @@
}
static int
NACLAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) {
NACLAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) {
    PP_Instance instance = PSGetInstanceId();
    const PPB_Audio *ppb_audio = PSInterfaceAudio();
    const PPB_AudioConfig *ppb_audiocfg = PSInterfaceAudioConfig();
@@ -121,30 +118,30 @@
}
static int
NACLAUD_Init(SDL_AudioDriverImpl * impl)
NACLAUDIO_Init(SDL_AudioDriverImpl * impl)
{
    if (PSGetInstanceId() == 0) {
        return 0;
    }
    
    /* Set the function pointers */
    impl->OpenDevice = NACLAUD_OpenDevice;
    impl->CloseDevice = NACLAUD_CloseDevice;
    impl->OpenDevice = NACLAUDIO_OpenDevice;
    impl->CloseDevice = NACLAUDIO_CloseDevice;
    impl->OnlyHasDefaultOutputDevice = 1;
    impl->ProvidesOwnCallbackThread = 1;
    /*
     *    impl->WaitDevice = NACLAUD_WaitDevice;
     *    impl->GetDeviceBuf = NACLAUD_GetDeviceBuf;
     *    impl->PlayDevice = NACLAUD_PlayDevice;
     *    impl->Deinitialize = NACLAUD_Deinitialize;
     *    impl->WaitDevice = NACLAUDIO_WaitDevice;
     *    impl->GetDeviceBuf = NACLAUDIO_GetDeviceBuf;
     *    impl->PlayDevice = NACLAUDIO_PlayDevice;
     *    impl->Deinitialize = NACLAUDIO_Deinitialize;
     */
    
    return 1;
}
AudioBootStrap NACLAUD_bootstrap = {
    NACLAUD_DRIVER_NAME, "SDL NaCl Audio Driver",
    NACLAUD_Init, 0
AudioBootStrap NACLAUDIO_bootstrap = {
    NACLAUDIO_DRIVER_NAME, "SDL NaCl Audio Driver",
    NACLAUDIO_Init, 0
};
#endif /* SDL_AUDIO_DRIVER_NACL */
source/src/audio/nas/SDL_nasaudio.c
@@ -30,22 +30,21 @@
#include "SDL_timer.h"
#include "SDL_audio.h"
#include "SDL_loadso.h"
#include "../SDL_audiomem.h"
#include "../SDL_audio_c.h"
#include "SDL_nasaudio.h"
static struct SDL_PrivateAudioData *this2 = NULL;
static void (*NAS_AuCloseServer) (AuServer *);
static void (*NAS_AuNextEvent) (AuServer *, AuBool, AuEvent *);
static AuBool(*NAS_AuDispatchEvent) (AuServer *, AuEvent *);
static void (*NAS_AuHandleEvents) (AuServer *);
static AuFlowID(*NAS_AuCreateFlow) (AuServer *, AuStatus *);
static void (*NAS_AuStartFlow) (AuServer *, AuFlowID, AuStatus *);
static void (*NAS_AuSetElements)
  (AuServer *, AuFlowID, AuBool, int, AuElement *, AuStatus *);
static void (*NAS_AuWriteElement)
  (AuServer *, AuFlowID, int, AuUint32, AuPointer, AuBool, AuStatus *);
static AuUint32 (*NAS_AuReadElement)
  (AuServer *, AuFlowID, int, AuUint32, AuPointer, AuStatus *);
static AuServer *(*NAS_AuOpenServer)
  (_AuConst char *, int, _AuConst char *, int, _AuConst char *, char **);
static AuEventHandlerRec *(*NAS_AuRegisterEventHandler)
@@ -80,10 +79,12 @@
    SDL_NAS_SYM(AuCloseServer);
    SDL_NAS_SYM(AuNextEvent);
    SDL_NAS_SYM(AuDispatchEvent);
    SDL_NAS_SYM(AuHandleEvents);
    SDL_NAS_SYM(AuCreateFlow);
    SDL_NAS_SYM(AuStartFlow);
    SDL_NAS_SYM(AuSetElements);
    SDL_NAS_SYM(AuWriteElement);
    SDL_NAS_SYM(AuReadElement);
    SDL_NAS_SYM(AuOpenServer);
    SDL_NAS_SYM(AuRegisterEventHandler);
    return 0;
@@ -187,19 +188,53 @@
    return (this->hidden->mixbuf);
}
static int
NAS_CaptureFromDevice(_THIS, void *buffer, int buflen)
{
    struct SDL_PrivateAudioData *h = this->hidden;
    int retval;
    while (SDL_TRUE) {
        /* just keep the event queue moving and the server chattering. */
        NAS_AuHandleEvents(h->aud);
        retval = (int) NAS_AuReadElement(h->aud, h->flow, 1, buflen, buffer, NULL);
        /*printf("read %d capture bytes\n", (int) retval);*/
        if (retval == 0) {
            SDL_Delay(10);  /* don't burn the CPU if we're waiting for data. */
        } else {
            break;
        }
    }
    return retval;
}
static void
NAS_FlushCapture(_THIS)
{
    struct SDL_PrivateAudioData *h = this->hidden;
    AuUint32 total = 0;
    AuUint32 br;
    Uint8 buf[512];
    do {
        /* just keep the event queue moving and the server chattering. */
        NAS_AuHandleEvents(h->aud);
        br = NAS_AuReadElement(h->aud, h->flow, 1, sizeof (buf), buf, NULL);
        /*printf("flushed %d capture bytes\n", (int) br);*/
        total += br;
    } while ((br == sizeof (buf)) && (total < this->spec.size));
}
static void
NAS_CloseDevice(_THIS)
{
    if (this->hidden != NULL) {
        SDL_FreeAudioMem(this->hidden->mixbuf);
        this->hidden->mixbuf = NULL;
        if (this->hidden->aud) {
            NAS_AuCloseServer(this->hidden->aud);
            this->hidden->aud = 0;
        }
        SDL_free(this->hidden);
        this2 = this->hidden = NULL;
    if (this->hidden->aud) {
        NAS_AuCloseServer(this->hidden->aud);
    }
    SDL_free(this->hidden->mixbuf);
    SDL_free(this->hidden);
}
static unsigned char
@@ -225,6 +260,12 @@
static AuBool
event_handler(AuServer * aud, AuEvent * ev, AuEventHandlerRec * hnd)
{
    SDL_AudioDevice *this = (SDL_AudioDevice *) hnd->data;
    struct SDL_PrivateAudioData *h = this->hidden;
    if (this->iscapture) {
        return AuTrue;  /* we don't (currently) care about any of this for capture devices */
    }
    switch (ev->type) {
    case AuEventTypeElementNotify:
        {
@@ -232,24 +273,24 @@
            switch (event->kind) {
            case AuElementNotifyKindLowWater:
                if (this2->buf_free >= 0) {
                    this2->really += event->num_bytes;
                    gettimeofday(&this2->last_tv, 0);
                    this2->buf_free += event->num_bytes;
                if (h->buf_free >= 0) {
                    h->really += event->num_bytes;
                    gettimeofday(&h->last_tv, 0);
                    h->buf_free += event->num_bytes;
                } else {
                    this2->buf_free = event->num_bytes;
                    h->buf_free = event->num_bytes;
                }
                break;
            case AuElementNotifyKindState:
                switch (event->cur_state) {
                case AuStatePause:
                    if (event->reason != AuReasonUser) {
                        if (this2->buf_free >= 0) {
                            this2->really += event->num_bytes;
                            gettimeofday(&this2->last_tv, 0);
                            this2->buf_free += event->num_bytes;
                        if (h->buf_free >= 0) {
                            h->really += event->num_bytes;
                            gettimeofday(&h->last_tv, 0);
                            h->buf_free += event->num_bytes;
                        } else {
                            this2->buf_free = event->num_bytes;
                            h->buf_free = event->num_bytes;
                        }
                    }
                    break;
@@ -261,15 +302,29 @@
}
static AuDeviceID
find_device(_THIS, int nch)
find_device(_THIS)
{
    /* These "Au" things are all macros, not functions... */
    struct SDL_PrivateAudioData *h = this->hidden;
    const unsigned int devicekind = this->iscapture ? AuComponentKindPhysicalInput : AuComponentKindPhysicalOutput;
    const int numdevs = AuServerNumDevices(h->aud);
    const int nch = this->spec.channels;
    int i;
    for (i = 0; i < AuServerNumDevices(this->hidden->aud); i++) {
        if ((AuDeviceKind(AuServerDevice(this->hidden->aud, i)) ==
             AuComponentKindPhysicalOutput) &&
            AuDeviceNumTracks(AuServerDevice(this->hidden->aud, i)) == nch) {
            return AuDeviceIdentifier(AuServerDevice(this->hidden->aud, i));
    /* Try to find exact match on channels first... */
    for (i = 0; i < numdevs; i++) {
        const AuDeviceAttributes *dev = AuServerDevice(h->aud, i);
        if ((AuDeviceKind(dev) == devicekind) && (AuDeviceNumTracks(dev) == nch)) {
            return AuDeviceIdentifier(dev);
        }
    }
    /* Take anything, then... */
    for (i = 0; i < numdevs; i++) {
        const AuDeviceAttributes *dev = AuServerDevice(h->aud, i);
        if (AuDeviceKind(dev) == devicekind) {
            this->spec.channels = AuDeviceNumTracks(dev);
            return AuDeviceIdentifier(dev);
        }
    }
    return AuNone;
@@ -288,7 +343,7 @@
    if (this->hidden == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
    SDL_zerop(this->hidden);
    /* Try for a closest match on audio format */
    format = 0;
@@ -300,21 +355,18 @@
        }
    }
    if (format == 0) {
        NAS_CloseDevice(this);
        return SDL_SetError("NAS: Couldn't find any hardware audio formats");
    }
    this->spec.format = test_format;
    this->hidden->aud = NAS_AuOpenServer("", 0, NULL, 0, NULL, NULL);
    if (this->hidden->aud == 0) {
        NAS_CloseDevice(this);
        return SDL_SetError("NAS: Couldn't open connection to NAS server");
    }
    this->hidden->dev = find_device(this, this->spec.channels);
    this->hidden->dev = find_device(this);
    if ((this->hidden->dev == AuNone)
        || (!(this->hidden->flow = NAS_AuCreateFlow(this->hidden->aud, 0)))) {
        NAS_CloseDevice(this);
        return SDL_SetError("NAS: Couldn't find a fitting device on NAS server");
    }
@@ -328,29 +380,38 @@
    /* Calculate the final parameters for this audio specification */
    SDL_CalculateAudioSpec(&this->spec);
    this2 = this->hidden;
    if (iscapture) {
        AuMakeElementImportDevice(elms, this->spec.freq, this->hidden->dev,
                                  AuUnlimitedSamples, 0, NULL);
        AuMakeElementExportClient(elms + 1, 0, this->spec.freq, format,
                                  this->spec.channels, AuTrue, buffer_size,
                                  buffer_size, 0, NULL);
    } else {
        AuMakeElementImportClient(elms, this->spec.freq, format,
                                  this->spec.channels, AuTrue, buffer_size,
                                  buffer_size / 4, 0, NULL);
        AuMakeElementExportDevice(elms + 1, 0, this->hidden->dev, this->spec.freq,
                                  AuUnlimitedSamples, 0, NULL);
    }
    AuMakeElementImportClient(elms, this->spec.freq, format,
                              this->spec.channels, AuTrue, buffer_size,
                              buffer_size / 4, 0, NULL);
    AuMakeElementExportDevice(elms + 1, 0, this->hidden->dev, this->spec.freq,
                              AuUnlimitedSamples, 0, NULL);
    NAS_AuSetElements(this->hidden->aud, this->hidden->flow, AuTrue, 2, elms,
                      NULL);
    NAS_AuSetElements(this->hidden->aud, this->hidden->flow, AuTrue,
                      2, elms, NULL);
    NAS_AuRegisterEventHandler(this->hidden->aud, AuEventHandlerIDMask, 0,
                               this->hidden->flow, event_handler,
                               (AuPointer) NULL);
                               (AuPointer) this);
    NAS_AuStartFlow(this->hidden->aud, this->hidden->flow, NULL);
    /* Allocate mixing buffer */
    this->hidden->mixlen = this->spec.size;
    this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
    if (this->hidden->mixbuf == NULL) {
        NAS_CloseDevice(this);
        return SDL_OutOfMemory();
    if (!iscapture) {
        this->hidden->mixlen = this->spec.size;
        this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen);
        if (this->hidden->mixbuf == NULL) {
            return SDL_OutOfMemory();
        }
        SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
    }
    SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
    /* We're ready to rock and roll. :-) */
    return 0;
@@ -381,9 +442,14 @@
    impl->PlayDevice = NAS_PlayDevice;
    impl->WaitDevice = NAS_WaitDevice;
    impl->GetDeviceBuf = NAS_GetDeviceBuf;
    impl->CaptureFromDevice = NAS_CaptureFromDevice;
    impl->FlushCapture = NAS_FlushCapture;
    impl->CloseDevice = NAS_CloseDevice;
    impl->Deinitialize = NAS_Deinitialize;
    impl->OnlyHasDefaultOutputDevice = 1;       /* !!! FIXME: is this true? */
    impl->OnlyHasDefaultOutputDevice = 1;
    impl->OnlyHasDefaultCaptureDevice = 1;
    impl->HasCaptureSupport = SDL_TRUE;
    return 1;   /* this audio target is available. */
}
source/src/audio/paudio/SDL_paudio.c
@@ -35,7 +35,6 @@
#include "SDL_timer.h"
#include "SDL_audio.h"
#include "SDL_stdinc.h"
#include "../SDL_audiomem.h"
#include "../SDL_audio_c.h"
#include "SDL_paudio.h"
@@ -228,16 +227,11 @@
static void
PAUDIO_CloseDevice(_THIS)
{
    if (this->hidden != NULL) {
        SDL_FreeAudioMem(this->hidden->mixbuf);
        this->hidden->mixbuf = NULL;
        if (this->hidden->audio_fd >= 0) {
            close(this->hidden->audio_fd);
            this->hidden->audio_fd = -1;
        }
        SDL_free(this->hidden);
        this->hidden = NULL;
    if (this->hidden->audio_fd >= 0) {
        close(this->hidden->audio_fd);
    }
    SDL_free(this->hidden->mixbuf);
    SDL_free(this->hidden);
}
static int
@@ -262,13 +256,12 @@
    if (this->hidden == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
    SDL_zerop(this->hidden);
    /* Open the audio device */
    fd = OpenAudioPath(audiodev, sizeof(audiodev), OPEN_FLAGS, 0);
    this->hidden->audio_fd = fd;
    if (fd < 0) {
        PAUDIO_CloseDevice(this);
        return SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno));
    }
@@ -277,7 +270,6 @@
     * that we can have.
     */
    if (ioctl(fd, AUDIO_BUFFER, &paud_bufinfo) < 0) {
        PAUDIO_CloseDevice(this);
        return SDL_SetError("Couldn't get audio buffer information");
    }
@@ -391,7 +383,6 @@
#ifdef DEBUG_AUDIO
        fprintf(stderr, "Couldn't find any hardware audio formats\n");
#endif
        PAUDIO_CloseDevice(this);
        return SDL_SetError("Couldn't find any hardware audio formats");
    }
    this->spec.format = test_format;
@@ -449,15 +440,13 @@
    }
    if (err != NULL) {
        PAUDIO_CloseDevice(this);
        return SDL_SetError("Paudio: %s", err);
    }
    /* Allocate mixing buffer */
    this->hidden->mixlen = this->spec.size;
    this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
    this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen);
    if (this->hidden->mixbuf == NULL) {
        PAUDIO_CloseDevice(this);
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
@@ -492,7 +481,6 @@
    paud_control.ioctl_request = AUDIO_START;
    paud_control.position = 0;
    if (ioctl(fd, AUDIO_CONTROL, &paud_control) < 0) {
        PAUDIO_CloseDevice(this);
#ifdef DEBUG_AUDIO
        fprintf(stderr, "Can't start audio play\n");
#endif
source/src/audio/psp/SDL_pspaudio.c
@@ -30,7 +30,6 @@
#include "SDL_audio.h"
#include "SDL_error.h"
#include "SDL_timer.h"
#include "../SDL_audiomem.h"
#include "../SDL_audio_c.h"
#include "../SDL_audiodev_c.h"
#include "../SDL_sysaudio.h"
@@ -40,10 +39,10 @@
#include <pspthreadman.h>
/* The tag name used by PSP audio */
#define PSPAUD_DRIVER_NAME         "psp"
#define PSPAUDIO_DRIVER_NAME         "psp"
static int
PSPAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
PSPAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
    int format, mixlen, i;
    this->hidden = (struct SDL_PrivateAudioData *)
@@ -51,7 +50,7 @@
    if (this->hidden == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden, 0, sizeof(*this->hidden));
    SDL_zerop(this->hidden);
    switch (this->spec.format & 0xff) {
        case 8:
        case 16:
@@ -66,20 +65,7 @@
    this->spec.freq = 44100;
    /* Update the fragment size as size in bytes. */
/*  SDL_CalculateAudioSpec(this->spec); MOD */
    switch (this->spec.format) {
    case AUDIO_U8:
        this->spec.silence = 0x80;
        break;
    default:
        this->spec.silence = 0x00;
        break;
    }
    this->spec.size = SDL_AUDIO_BITSIZE(this->spec.format) / 8;
    this->spec.size *= this->spec.channels;
    this->spec.size *= this->spec.samples;
/* ========================================== */
    SDL_CalculateAudioSpec(&this->spec);
    /* Allocate the mixing buffer.  Its size and starting address must
       be a multiple of 64 bytes.  Our sample count is already a multiple of
@@ -112,7 +98,7 @@
    return 0;
}
static void PSPAUD_PlayDevice(_THIS)
static void PSPAUDIO_PlayDevice(_THIS)
{
    Uint8 *mixbuf = this->hidden->mixbufs[this->hidden->next_buffer];
@@ -126,28 +112,25 @@
}
/* This function waits until it is possible to write a full sound buffer */
static void PSPAUD_WaitDevice(_THIS)
static void PSPAUDIO_WaitDevice(_THIS)
{
    /* Because we block when sending audio, there's no need for this function to do anything. */
}
static Uint8 *PSPAUD_GetDeviceBuf(_THIS)
static Uint8 *PSPAUDIO_GetDeviceBuf(_THIS)
{
    return this->hidden->mixbufs[this->hidden->next_buffer];
}
static void PSPAUD_CloseDevice(_THIS)
static void PSPAUDIO_CloseDevice(_THIS)
{
    if (this->hidden->channel >= 0) {
        sceAudioChRelease(this->hidden->channel);
        this->hidden->channel = -1;
    }
    if (this->hidden->rawbuf != NULL) {
        free(this->hidden->rawbuf);
        this->hidden->rawbuf = NULL;
    }
    free(this->hidden->rawbuf);  /* this uses memalign(), not SDL_malloc(). */
    SDL_free(this->hidden);
}
static void PSPAUD_ThreadInit(_THIS)
static void PSPAUDIO_ThreadInit(_THIS)
{
    /* Increase the priority of this audio thread by 1 to put it
       ahead of other SDL threads. */
@@ -162,24 +145,22 @@
static int
PSPAUD_Init(SDL_AudioDriverImpl * impl)
PSPAUDIO_Init(SDL_AudioDriverImpl * impl)
{
    /* Set the function pointers */
    impl->OpenDevice = PSPAUD_OpenDevice;
    impl->PlayDevice = PSPAUD_PlayDevice;
    impl->WaitDevice = PSPAUD_WaitDevice;
    impl->GetDeviceBuf = PSPAUD_GetDeviceBuf;
    impl->WaitDone = PSPAUD_WaitDevice;
    impl->CloseDevice = PSPAUD_CloseDevice;
    impl->ThreadInit = PSPAUD_ThreadInit;
    impl->OpenDevice = PSPAUDIO_OpenDevice;
    impl->PlayDevice = PSPAUDIO_PlayDevice;
    impl->WaitDevice = PSPAUDIO_WaitDevice;
    impl->GetDeviceBuf = PSPAUDIO_GetDeviceBuf;
    impl->CloseDevice = PSPAUDIO_CloseDevice;
    impl->ThreadInit = PSPAUDIO_ThreadInit;
    /* PSP audio device */
    impl->OnlyHasDefaultOutputDevice = 1;
/*
    impl->HasCaptureSupport = 1;
    impl->OnlyHasDefaultInputDevice = 1;
    impl->OnlyHasDefaultCaptureDevice = 1;
*/
    /*
    impl->DetectDevices = DSOUND_DetectDevices;
@@ -188,8 +169,8 @@
    return 1;   /* this audio target is available. */
}
AudioBootStrap PSPAUD_bootstrap = {
    "psp", "PSP audio driver", PSPAUD_Init, 0
AudioBootStrap PSPAUDIO_bootstrap = {
    "psp", "PSP audio driver", PSPAUDIO_Init, 0
};
 /* SDL_AUDI */
source/src/audio/pulseaudio/SDL_pulseaudio.c
@@ -42,10 +42,10 @@
#include "SDL_timer.h"
#include "SDL_audio.h"
#include "../SDL_audiomem.h"
#include "../SDL_audio_c.h"
#include "SDL_pulseaudio.h"
#include "SDL_loadso.h"
#include "../../thread/SDL_systhread.h"
#if (PA_API_VERSION < 12)
/** Return non-zero if the passed state is one of the connected states */
@@ -99,11 +99,18 @@
    const pa_sample_spec *, const pa_channel_map *);
static int (*PULSEAUDIO_pa_stream_connect_playback) (pa_stream *, const char *,
    const pa_buffer_attr *, pa_stream_flags_t, pa_cvolume *, pa_stream *);
static int (*PULSEAUDIO_pa_stream_connect_record) (pa_stream *, const char *,
    const pa_buffer_attr *, pa_stream_flags_t);
static pa_stream_state_t (*PULSEAUDIO_pa_stream_get_state) (pa_stream *);
static size_t (*PULSEAUDIO_pa_stream_writable_size) (pa_stream *);
static size_t (*PULSEAUDIO_pa_stream_readable_size) (pa_stream *);
static int (*PULSEAUDIO_pa_stream_write) (pa_stream *, const void *, size_t,
    pa_free_cb_t, int64_t, pa_seek_mode_t);
static pa_operation * (*PULSEAUDIO_pa_stream_drain) (pa_stream *,
    pa_stream_success_cb_t, void *);
static int (*PULSEAUDIO_pa_stream_peek) (pa_stream *, const void **, size_t *);
static int (*PULSEAUDIO_pa_stream_drop) (pa_stream *);
static pa_operation * (*PULSEAUDIO_pa_stream_flush)    (pa_stream *,
    pa_stream_success_cb_t, void *);
static int (*PULSEAUDIO_pa_stream_disconnect) (pa_stream *);
static void (*PULSEAUDIO_pa_stream_unref) (pa_stream *);
@@ -205,11 +212,16 @@
    SDL_PULSEAUDIO_SYM(pa_context_unref);
    SDL_PULSEAUDIO_SYM(pa_stream_new);
    SDL_PULSEAUDIO_SYM(pa_stream_connect_playback);
    SDL_PULSEAUDIO_SYM(pa_stream_connect_record);
    SDL_PULSEAUDIO_SYM(pa_stream_get_state);
    SDL_PULSEAUDIO_SYM(pa_stream_writable_size);
    SDL_PULSEAUDIO_SYM(pa_stream_readable_size);
    SDL_PULSEAUDIO_SYM(pa_stream_write);
    SDL_PULSEAUDIO_SYM(pa_stream_drain);
    SDL_PULSEAUDIO_SYM(pa_stream_disconnect);
    SDL_PULSEAUDIO_SYM(pa_stream_peek);
    SDL_PULSEAUDIO_SYM(pa_stream_drop);
    SDL_PULSEAUDIO_SYM(pa_stream_flush);
    SDL_PULSEAUDIO_SYM(pa_stream_unref);
    SDL_PULSEAUDIO_SYM(pa_channel_map_init_auto);
    SDL_PULSEAUDIO_SYM(pa_strerror);
@@ -236,6 +248,12 @@
        }
    }
    return "SDL Application";  /* oh well. */
}
static void
stream_operation_complete_no_op(pa_stream *s, int success, void *userdata)
{
    /* no-op for pa_stream_drain(), etc, to use for callback. */
}
static void
@@ -325,7 +343,7 @@
{
    struct SDL_PrivateAudioData *h = this->hidden;
    while (this->enabled) {
    while (SDL_AtomicGet(&this->enabled)) {
        if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY ||
            PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY ||
            PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
@@ -343,40 +361,12 @@
{
    /* Write the audio data */
    struct SDL_PrivateAudioData *h = this->hidden;
    if (this->enabled) {
    if (SDL_AtomicGet(&this->enabled)) {
        if (PULSEAUDIO_pa_stream_write(h->stream, h->mixbuf, h->mixlen, NULL, 0LL, PA_SEEK_RELATIVE) < 0) {
            SDL_OpenedAudioDeviceDisconnected(this);
        }
    }
}
static void
stream_drain_complete(pa_stream *s, int success, void *userdata)
{
    /* no-op for pa_stream_drain() to use for callback. */
}
static void
PULSEAUDIO_WaitDone(_THIS)
{
    if (this->enabled) {
        struct SDL_PrivateAudioData *h = this->hidden;
        pa_operation *o = PULSEAUDIO_pa_stream_drain(h->stream, stream_drain_complete, NULL);
        if (o) {
            while (PULSEAUDIO_pa_operation_get_state(o) != PA_OPERATION_DONE) {
                if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY ||
                    PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY ||
                    PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
                    PULSEAUDIO_pa_operation_cancel(o);
                    break;
                }
            }
            PULSEAUDIO_pa_operation_unref(o);
        }
    }
}
static Uint8 *
PULSEAUDIO_GetDeviceBuf(_THIS)
@@ -385,24 +375,96 @@
}
static int
PULSEAUDIO_CaptureFromDevice(_THIS, void *buffer, int buflen)
{
    struct SDL_PrivateAudioData *h = this->hidden;
    const void *data = NULL;
    size_t nbytes = 0;
    while (SDL_AtomicGet(&this->enabled)) {
        if (h->capturebuf != NULL) {
            const int cpy = SDL_min(buflen, h->capturelen);
            SDL_memcpy(buffer, h->capturebuf, cpy);
            /*printf("PULSEAUDIO: fed %d captured bytes\n", cpy);*/
            h->capturebuf += cpy;
            h->capturelen -= cpy;
            if (h->capturelen == 0) {
                h->capturebuf = NULL;
                PULSEAUDIO_pa_stream_drop(h->stream);  /* done with this fragment. */
            }
            return cpy;  /* new data, return it. */
        }
        if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY ||
            PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY ||
            PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
            SDL_OpenedAudioDeviceDisconnected(this);
            return -1;  /* uhoh, pulse failed! */
        }
        if (PULSEAUDIO_pa_stream_readable_size(h->stream) == 0) {
            continue;  /* no data available yet. */
        }
        /* a new fragment is available! */
        PULSEAUDIO_pa_stream_peek(h->stream, &data, &nbytes);
        SDL_assert(nbytes > 0);
        if (data == NULL) {  /* NULL==buffer had a hole. Ignore that. */
            PULSEAUDIO_pa_stream_drop(h->stream);  /* drop this fragment. */
        } else {
            /* store this fragment's data, start feeding it to SDL. */
            /*printf("PULSEAUDIO: captured %d new bytes\n", (int) nbytes);*/
            h->capturebuf = (const Uint8 *) data;
            h->capturelen = nbytes;
        }
    }
    return -1;  /* not enabled? */
}
static void
PULSEAUDIO_FlushCapture(_THIS)
{
    struct SDL_PrivateAudioData *h = this->hidden;
    if (h->capturebuf != NULL) {
        PULSEAUDIO_pa_stream_drop(h->stream);
        h->capturebuf = NULL;
        h->capturelen = 0;
    }
    WaitForPulseOperation(h->mainloop, PULSEAUDIO_pa_stream_flush(h->stream, stream_operation_complete_no_op, NULL));
}
static void
PULSEAUDIO_CloseDevice(_THIS)
{
    if (this->hidden != NULL) {
        SDL_FreeAudioMem(this->hidden->mixbuf);
        SDL_free(this->hidden->device_name);
        if (this->hidden->stream) {
            PULSEAUDIO_pa_stream_disconnect(this->hidden->stream);
            PULSEAUDIO_pa_stream_unref(this->hidden->stream);
    if (this->hidden->stream) {
        if (this->hidden->capturebuf != NULL) {
            PULSEAUDIO_pa_stream_drop(this->hidden->stream);
        }
        DisconnectFromPulseServer(this->hidden->mainloop, this->hidden->context);
        SDL_free(this->hidden);
        this->hidden = NULL;
        PULSEAUDIO_pa_stream_disconnect(this->hidden->stream);
        PULSEAUDIO_pa_stream_unref(this->hidden->stream);
    }
    DisconnectFromPulseServer(this->hidden->mainloop, this->hidden->context);
    SDL_free(this->hidden->mixbuf);
    SDL_free(this->hidden->device_name);
    SDL_free(this->hidden);
}
static void
SinkDeviceNameCallback(pa_context *c, const pa_sink_info *i, int is_last, void *data)
{
    if (i) {
        char **devname = (char **) data;
        *devname = SDL_strdup(i->name);
    }
}
static void
DeviceNameCallback(pa_context *c, const pa_sink_info *i, int is_last, void *data)
SourceDeviceNameCallback(pa_context *c, const pa_source_info *i, int is_last, void *data)
{
    if (i) {
        char **devname = (char **) data;
@@ -411,7 +473,7 @@
}
static SDL_bool
FindDeviceName(struct SDL_PrivateAudioData *h, void *handle)
FindDeviceName(struct SDL_PrivateAudioData *h, const int iscapture, void *handle)
{
    const uint32_t idx = ((uint32_t) ((size_t) handle)) - 1;
@@ -419,7 +481,16 @@
        return SDL_TRUE;
    }
    WaitForPulseOperation(h->mainloop, PULSEAUDIO_pa_context_get_sink_info_by_index(h->context, idx, DeviceNameCallback, &h->device_name));
    if (iscapture) {
        WaitForPulseOperation(h->mainloop,
            PULSEAUDIO_pa_context_get_source_info_by_index(h->context, idx,
                SourceDeviceNameCallback, &h->device_name));
    } else {
        WaitForPulseOperation(h->mainloop,
            PULSEAUDIO_pa_context_get_sink_info_by_index(h->context, idx,
                SinkDeviceNameCallback, &h->device_name));
    }
    return (h->device_name != NULL);
}
@@ -433,15 +504,15 @@
    pa_channel_map pacmap;
    pa_stream_flags_t flags = 0;
    int state = 0;
    int rc = 0;
    /* Initialize all variables that we clean on shutdown */
    this->hidden = (struct SDL_PrivateAudioData *)
    h = this->hidden = (struct SDL_PrivateAudioData *)
        SDL_malloc((sizeof *this->hidden));
    if (this->hidden == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
    h = this->hidden;
    SDL_zerop(this->hidden);
    paspec.format = PA_SAMPLE_INVALID;
@@ -482,7 +553,6 @@
        }
    }
    if (paspec.format == PA_SAMPLE_INVALID) {
        PULSEAUDIO_CloseDevice(this);
        return SDL_SetError("Couldn't find any hardware audio formats");
    }
    this->spec.format = test_format;
@@ -494,13 +564,14 @@
    SDL_CalculateAudioSpec(&this->spec);
    /* Allocate mixing buffer */
    h->mixlen = this->spec.size;
    h->mixbuf = (Uint8 *) SDL_AllocAudioMem(h->mixlen);
    if (h->mixbuf == NULL) {
        PULSEAUDIO_CloseDevice(this);
        return SDL_OutOfMemory();
    if (!iscapture) {
        h->mixlen = this->spec.size;
        h->mixbuf = (Uint8 *) SDL_malloc(h->mixlen);
        if (h->mixbuf == NULL) {
            return SDL_OutOfMemory();
        }
        SDL_memset(h->mixbuf, this->spec.silence, this->spec.size);
    }
    SDL_memset(h->mixbuf, this->spec.silence, this->spec.size);
    paspec.channels = this->spec.channels;
    paspec.rate = this->spec.freq;
@@ -522,13 +593,11 @@
#endif
    if (ConnectToPulseServer(&h->mainloop, &h->context) < 0) {
        PULSEAUDIO_CloseDevice(this);
        return SDL_SetError("Could not connect to PulseAudio server");
    }
    if (!FindDeviceName(h, handle)) {
        PULSEAUDIO_CloseDevice(this);
        return SDL_SetError("Requested PulseAudio sink missing?");
    if (!FindDeviceName(h, iscapture, handle)) {
        return SDL_SetError("Requested PulseAudio sink/source missing?");
    }
    /* The SDL ALSA output hints us that we use Windows' channel mapping */
@@ -544,7 +613,6 @@
        );
    if (h->stream == NULL) {
        PULSEAUDIO_CloseDevice(this);
        return SDL_SetError("Could not set up PulseAudio stream");
    }
@@ -554,20 +622,22 @@
        flags |= PA_STREAM_DONT_MOVE;
    }
    if (PULSEAUDIO_pa_stream_connect_playback(h->stream, h->device_name, &paattr, flags,
            NULL, NULL) < 0) {
        PULSEAUDIO_CloseDevice(this);
    if (iscapture) {
        rc = PULSEAUDIO_pa_stream_connect_record(h->stream, h->device_name, &paattr, flags);
    } else {
        rc = PULSEAUDIO_pa_stream_connect_playback(h->stream, h->device_name, &paattr, flags, NULL, NULL);
    }
    if (rc < 0) {
        return SDL_SetError("Could not connect PulseAudio stream");
    }
    do {
        if (PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
            PULSEAUDIO_CloseDevice(this);
            return SDL_SetError("pa_mainloop_iterate() failed");
        }
        state = PULSEAUDIO_pa_stream_get_state(h->stream);
        if (!PA_STREAM_IS_GOOD(state)) {
            PULSEAUDIO_CloseDevice(this);
            return SDL_SetError("Could not connect PulseAudio stream");
        }
    } while (state != PA_STREAM_READY);
@@ -646,7 +716,7 @@
    WaitForPulseOperation(hotplug_mainloop, PULSEAUDIO_pa_context_get_source_info_list(hotplug_context, SourceInfoCallback, NULL));
    /* ok, we have a sane list, let's set up hotplug notifications now... */
    hotplug_thread = SDL_CreateThread(HotplugThread, "PulseHotplug", NULL);
    hotplug_thread = SDL_CreateThreadInternal(HotplugThread, "PulseHotplug", 256 * 1024, NULL);
}
static void
@@ -684,8 +754,11 @@
    impl->WaitDevice = PULSEAUDIO_WaitDevice;
    impl->GetDeviceBuf = PULSEAUDIO_GetDeviceBuf;
    impl->CloseDevice = PULSEAUDIO_CloseDevice;
    impl->WaitDone = PULSEAUDIO_WaitDone;
    impl->Deinitialize = PULSEAUDIO_Deinitialize;
    impl->CaptureFromDevice = PULSEAUDIO_CaptureFromDevice;
    impl->FlushCapture = PULSEAUDIO_FlushCapture;
    impl->HasCaptureSupport = SDL_TRUE;
    return 1;   /* this audio target is available. */
}
source/src/audio/pulseaudio/SDL_pulseaudio.h
@@ -42,6 +42,9 @@
    /* Raw mixing buffer */
    Uint8 *mixbuf;
    int mixlen;
    const Uint8 *capturebuf;
    int capturelen;
};
#endif /* _SDL_pulseaudio_h */
source/src/audio/qsa/SDL_qsa_audio.c
@@ -45,7 +45,6 @@
#include "SDL_timer.h"
#include "SDL_audio.h"
#include "../SDL_audiomem.h"
#include "../SDL_audio_c.h"
#include "SDL_qsa_audio.h"
@@ -138,8 +137,7 @@
static void
QSA_InitAudioParams(snd_pcm_channel_params_t * cpars)
{
    SDL_memset(cpars, 0, sizeof(snd_pcm_channel_params_t));
    SDL_zerop(cpars);
    cpars->channel = SND_PCM_CHANNEL_PLAYBACK;
    cpars->mode = SND_PCM_MODE_BLOCK;
    cpars->start_mode = SND_PCM_START_DATA;
@@ -229,7 +227,7 @@
    int towrite;
    void *pcmbuffer;
    if ((!this->enabled) || (!this->hidden)) {
    if (!SDL_AtomicGet(&this->enabled) || !this->hidden) {
        return;
    }
@@ -262,7 +260,7 @@
                continue;
            } else {
                if ((errno == EINVAL) || (errno == EIO)) {
                    SDL_memset(&cstatus, 0, sizeof(cstatus));
                    SDL_zero(cstatus);
                    if (!this->hidden->iscapture) {
                        cstatus.channel = SND_PCM_CHANNEL_PLAYBACK;
                    } else {
@@ -305,7 +303,7 @@
            towrite -= written;
            pcmbuffer += written * this->spec.channels;
        }
    } while ((towrite > 0) && (this->enabled));
    } while ((towrite > 0) && SDL_AtomicGet(&this->enabled));
    /* If we couldn't write, assume fatal error for now */
    if (towrite != 0) {
@@ -322,27 +320,21 @@
static void
QSA_CloseDevice(_THIS)
{
    if (this->hidden != NULL) {
        if (this->hidden->audio_handle != NULL) {
            if (!this->hidden->iscapture) {
                /* Finish playing available samples */
                snd_pcm_plugin_flush(this->hidden->audio_handle,
                                     SND_PCM_CHANNEL_PLAYBACK);
            } else {
                /* Cancel unread samples during capture */
                snd_pcm_plugin_flush(this->hidden->audio_handle,
                                     SND_PCM_CHANNEL_CAPTURE);
            }
            snd_pcm_close(this->hidden->audio_handle);
            this->hidden->audio_handle = NULL;
    if (this->hidden->audio_handle != NULL) {
        if (!this->hidden->iscapture) {
            /* Finish playing available samples */
            snd_pcm_plugin_flush(this->hidden->audio_handle,
                                 SND_PCM_CHANNEL_PLAYBACK);
        } else {
            /* Cancel unread samples during capture */
            snd_pcm_plugin_flush(this->hidden->audio_handle,
                                 SND_PCM_CHANNEL_CAPTURE);
        }
        SDL_FreeAudioMem(this->hidden->pcm_buf);
        this->hidden->pcm_buf = NULL;
        SDL_free(this->hidden);
        this->hidden = NULL;
        snd_pcm_close(this->hidden->audio_handle);
    }
    SDL_free(this->hidden->pcm_buf);
    SDL_free(this->hidden);
}
static int
@@ -365,13 +357,13 @@
    if (this->hidden == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden, 0, sizeof(struct SDL_PrivateAudioData));
    SDL_zerop(this->hidden);
    /* Initialize channel transfer parameters to default */
    QSA_InitAudioParams(&cparams);
    /* Initialize channel direction: capture or playback */
    this->hidden->iscapture = iscapture;
    this->hidden->iscapture = iscapture ? SDL_TRUE : SDL_FALSE;
    if (device != NULL) {
        /* Open requested audio device */
@@ -391,7 +383,6 @@
    /* Check if requested device is opened */
    if (status < 0) {
        this->hidden->audio_handle = NULL;
        QSA_CloseDevice(this);
        return QSA_SetError("snd_pcm_open", status);
    }
@@ -401,7 +392,6 @@
            snd_pcm_plugin_set_disable(this->hidden->audio_handle,
                                       PLUGIN_DISABLE_MMAP);
        if (status < 0) {
            QSA_CloseDevice(this);
            return QSA_SetError("snd_pcm_plugin_set_disable", status);
        }
    }
@@ -487,7 +477,6 @@
    /* assumes test_format not 0 on success */
    if (test_format == 0) {
        QSA_CloseDevice(this);
        return SDL_SetError("QSA: Couldn't find any hardware audio formats");
    }
@@ -505,12 +494,11 @@
    /* Setup the transfer parameters according to cparams */
    status = snd_pcm_plugin_params(this->hidden->audio_handle, &cparams);
    if (status < 0) {
        QSA_CloseDevice(this);
        return QSA_SetError("snd_pcm_channel_params", status);
    }
    /* Make sure channel is setup right one last time */
    SDL_memset(&csetup, 0, sizeof(csetup));
    SDL_zero(csetup);
    if (!this->hidden->iscapture) {
        csetup.channel = SND_PCM_CHANNEL_PLAYBACK;
    } else {
@@ -519,7 +507,6 @@
    /* Setup an audio channel */
    if (snd_pcm_plugin_setup(this->hidden->audio_handle, &csetup) < 0) {
        QSA_CloseDevice(this);
        return SDL_SetError("QSA: Unable to setup channel");
    }
@@ -540,9 +527,8 @@
     *  closest multiple)
     */
    this->hidden->pcm_buf =
        (Uint8 *) SDL_AllocAudioMem(this->hidden->pcm_len);
        (Uint8 *) SDL_malloc(this->hidden->pcm_len);
    if (this->hidden->pcm_buf == NULL) {
        QSA_CloseDevice(this);
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden->pcm_buf, this->spec.silence,
@@ -560,7 +546,6 @@
    }
    if (this->hidden->audio_fd < 0) {
        QSA_CloseDevice(this);
        return QSA_SetError("snd_pcm_file_descriptor", status);
    }
@@ -578,7 +563,6 @@
    }
    if (status < 0) {
        QSA_CloseDevice(this);
        return QSA_SetError("snd_pcm_plugin_prepare", status);
    }
@@ -725,31 +709,12 @@
}
static void
QSA_WaitDone(_THIS)
{
    if (!this->hidden->iscapture) {
        if (this->hidden->audio_handle != NULL) {
            /* Wait till last fragment is played and stop channel */
            snd_pcm_plugin_flush(this->hidden->audio_handle,
                                 SND_PCM_CHANNEL_PLAYBACK);
        }
    } else {
        if (this->hidden->audio_handle != NULL) {
            /* Discard all unread data and stop channel */
            snd_pcm_plugin_flush(this->hidden->audio_handle,
                                 SND_PCM_CHANNEL_CAPTURE);
        }
    }
}
static void
QSA_Deinitialize(void)
{
    /* Clear devices array on shutdown */
    SDL_memset(qsa_playback_device, 0x00,
               sizeof(QSA_Device) * QSA_MAX_DEVICES);
    SDL_memset(qsa_capture_device, 0x00,
               sizeof(QSA_Device) * QSA_MAX_DEVICES);
    /* !!! FIXME: we zero these on init...any reason to do it here? */
    SDL_zero(qsa_playback_device);
    SDL_zero(qsa_capture_device);
    qsa_playback_devices = 0;
    qsa_capture_devices = 0;
}
@@ -761,10 +726,8 @@
    int32_t status = 0;
    /* Clear devices array */
    SDL_memset(qsa_playback_device, 0x00,
               sizeof(QSA_Device) * QSA_MAX_DEVICES);
    SDL_memset(qsa_capture_device, 0x00,
               sizeof(QSA_Device) * QSA_MAX_DEVICES);
    SDL_zero(qsa_playback_device);
    SDL_zero(qsa_capture_device);
    qsa_playback_devices = 0;
    qsa_capture_devices = 0;
@@ -778,7 +741,6 @@
    impl->PlayDevice = QSA_PlayDevice;
    impl->GetDeviceBuf = QSA_GetDeviceBuf;
    impl->CloseDevice = QSA_CloseDevice;
    impl->WaitDone = QSA_WaitDone;
    impl->Deinitialize = QSA_Deinitialize;
    impl->LockDevice = NULL;
    impl->UnlockDevice = NULL;
@@ -788,7 +750,7 @@
    impl->SkipMixerLock = 0;
    impl->HasCaptureSupport = 1;
    impl->OnlyHasDefaultOutputDevice = 0;
    impl->OnlyHasDefaultInputDevice = 0;
    impl->OnlyHasDefaultCaptureDevice = 0;
    /* Check if io-audio manager is running or not */
    status = snd_cards();
source/src/audio/qsa/SDL_qsa_audio.h
@@ -34,7 +34,7 @@
struct SDL_PrivateAudioData
{
    /* SDL capture state */
    int iscapture;
    SDL_bool iscapture;
    /* The audio device handle */
    int cardno;
source/src/audio/sndio/SDL_sndioaudio.c
@@ -36,7 +36,6 @@
#include <unistd.h>
#include "SDL_audio.h"
#include "../SDL_audiomem.h"
#include "../SDL_audio_c.h"
#include "SDL_sndioaudio.h"
@@ -172,24 +171,14 @@
}
static void
SNDIO_WaitDone(_THIS)
{
    SNDIO_sio_stop(this->hidden->dev);
}
static void
SNDIO_CloseDevice(_THIS)
{
    if (this->hidden != NULL) {
        SDL_FreeAudioMem(this->hidden->mixbuf);
        this->hidden->mixbuf = NULL;
        if ( this->hidden->dev != NULL ) {
            SNDIO_sio_close(this->hidden->dev);
            this->hidden->dev = NULL;
        }
        SDL_free(this->hidden);
        this->hidden = NULL;
    if ( this->hidden->dev != NULL ) {
        SNDIO_sio_stop(this->hidden->dev);
        SNDIO_sio_close(this->hidden->dev);
    }
    SDL_free(this->hidden->mixbuf);
    SDL_free(this->hidden);
}
static int
@@ -204,13 +193,12 @@
    if (this->hidden == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden, 0, sizeof(*this->hidden));
    SDL_zerop(this->hidden);
    this->hidden->mixlen = this->spec.size;
    /* !!! FIXME: SIO_DEVANY can be a specific device... */
    if ((this->hidden->dev = SNDIO_sio_open(SIO_DEVANY, SIO_PLAY, 0)) == NULL) {
        SNDIO_CloseDevice(this);
        return SDL_SetError("sio_open() failed");
    }
@@ -233,7 +221,6 @@
                continue;
            }
            if (SNDIO_sio_getpar(this->hidden->dev, &par) == 0) {
                SNDIO_CloseDevice(this);
                return SDL_SetError("sio_getpar() failed");
            }
            if (par.bps != SIO_BPS(par.bits)) {
@@ -248,7 +235,6 @@
    }
    if (status < 0) {
        SNDIO_CloseDevice(this);
        return SDL_SetError("sndio: Couldn't find any hardware audio formats");
    }
@@ -269,7 +255,6 @@
    else if ((par.bps == 1) && (!par.sig))
        this->spec.format = AUDIO_U8;
    else {
        SNDIO_CloseDevice(this);
        return SDL_SetError("sndio: Got unsupported hardware audio format.");
    }
@@ -282,9 +267,8 @@
    /* Allocate mixing buffer */
    this->hidden->mixlen = this->spec.size;
    this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
    this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->hidden->mixlen);
    if (this->hidden->mixbuf == NULL) {
        SNDIO_CloseDevice(this);
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden->mixbuf, this->spec.silence, this->hidden->mixlen);
@@ -315,7 +299,6 @@
    impl->WaitDevice = SNDIO_WaitDevice;
    impl->PlayDevice = SNDIO_PlayDevice;
    impl->GetDeviceBuf = SNDIO_GetDeviceBuf;
    impl->WaitDone = SNDIO_WaitDone;
    impl->CloseDevice = SNDIO_CloseDevice;
    impl->Deinitialize = SNDIO_Deinitialize;
    impl->OnlyHasDefaultOutputDevice = 1;  /* !!! FIXME: sndio can handle multiple devices. */
source/src/audio/sun/SDL_sunaudio.c
@@ -40,7 +40,6 @@
#include "SDL_timer.h"
#include "SDL_audio.h"
#include "../SDL_audiomem.h"
#include "../SDL_audio_c.h"
#include "../SDL_audiodev_c.h"
#include "SDL_sunaudio.h"
@@ -183,18 +182,12 @@
static void
SUNAUDIO_CloseDevice(_THIS)
{
    if (this->hidden != NULL) {
        SDL_FreeAudioMem(this->hidden->mixbuf);
        this->hidden->mixbuf = NULL;
        SDL_free(this->hidden->ulaw_buf);
        this->hidden->ulaw_buf = NULL;
        if (this->hidden->audio_fd >= 0) {
            close(this->hidden->audio_fd);
            this->hidden->audio_fd = -1;
        }
        SDL_free(this->hidden);
        this->hidden = NULL;
    SDL_free(this->hidden->ulaw_buf);
    if (this->hidden->audio_fd >= 0) {
        close(this->hidden->audio_fd);
    }
    SDL_free(this->hidden->mixbuf);
    SDL_free(this->hidden);
}
static int
@@ -219,7 +212,7 @@
    if (this->hidden == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
    SDL_zerop(this->hidden);
    /* Open the audio device */
    this->hidden->audio_fd = open(devname, flags, 0);
@@ -340,7 +333,7 @@
    SDL_CalculateAudioSpec(&this->spec);
    /* Allocate mixing buffer */
    this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->spec.size);
    this->hidden->mixbuf = (Uint8 *) SDL_malloc(this->spec.size);
    if (this->hidden->mixbuf == NULL) {
        return SDL_OutOfMemory();
    }
source/src/audio/winmm/SDL_winmm.c
@@ -27,6 +27,7 @@
#include "../../core/windows/SDL_windows.h"
#include <mmsystem.h>
#include "SDL_assert.h"
#include "SDL_timer.h"
#include "SDL_audio.h"
#include "../SDL_audio_c.h"
@@ -40,11 +41,11 @@
static void DetectWave##typ##Devs(void) { \
    const UINT iscapture = iscap ? 1 : 0; \
    const UINT devcount = wave##typ##GetNumDevs(); \
    capstyp caps; \
    capstyp##2W caps; \
    UINT i; \
    for (i = 0; i < devcount; i++) { \
        if (wave##typ##GetDevCaps(i,&caps,sizeof(caps))==MMSYSERR_NOERROR) { \
            char *name = WIN_StringToUTF8(caps.szPname); \
    if (wave##typ##GetDevCaps(i,(LP##capstyp##W)&caps,sizeof(caps))==MMSYSERR_NOERROR) { \
            char *name = WIN_LookupAudioDeviceName(caps.szPname,&caps.NameGuid); \
            if (name != NULL) { \
                SDL_AddAudioDevice((int) iscapture, name, (void *) ((size_t) i+1)); \
                SDL_free(name); \
@@ -134,63 +135,87 @@
    this->hidden->next_buffer = (this->hidden->next_buffer + 1) % NUM_BUFFERS;
}
static void
WINMM_WaitDone(_THIS)
static int
WINMM_CaptureFromDevice(_THIS, void *buffer, int buflen)
{
    int i, left;
    const int nextbuf = this->hidden->next_buffer;
    MMRESULT result;
    do {
        left = NUM_BUFFERS;
        for (i = 0; i < NUM_BUFFERS; ++i) {
            if (this->hidden->wavebuf[i].dwFlags & WHDR_DONE) {
                --left;
            }
        }
        if (left > 0) {
            SDL_Delay(100);
        }
    } while (left > 0);
    SDL_assert(buflen == this->spec.size);
    /* Wait for an audio chunk to finish */
    WaitForSingleObject(this->hidden->audio_sem, INFINITE);
    /* Copy it to caller's buffer... */
    SDL_memcpy(buffer, this->hidden->wavebuf[nextbuf].lpData, this->spec.size);
    /* requeue the buffer that just finished. */
    result = waveInAddBuffer(this->hidden->hin,
                             &this->hidden->wavebuf[nextbuf],
                             sizeof (this->hidden->wavebuf[nextbuf]));
    if (result != MMSYSERR_NOERROR) {
        return -1;  /* uhoh! Disable the device. */
    }
    /* queue the next buffer in sequence, next time. */
    this->hidden->next_buffer = (nextbuf + 1) % NUM_BUFFERS;
    return this->spec.size;
}
static void
WINMM_FlushCapture(_THIS)
{
    /* Wait for an audio chunk to finish */
    if (WaitForSingleObject(this->hidden->audio_sem, 0) == WAIT_OBJECT_0) {
        const int nextbuf = this->hidden->next_buffer;
        /* requeue the buffer that just finished without reading from it. */
        waveInAddBuffer(this->hidden->hin,
                        &this->hidden->wavebuf[nextbuf],
                        sizeof (this->hidden->wavebuf[nextbuf]));
        this->hidden->next_buffer = (nextbuf + 1) % NUM_BUFFERS;
    }
}
static void
WINMM_CloseDevice(_THIS)
{
    /* Close up audio */
    if (this->hidden != NULL) {
        int i;
    int i;
        if (this->hidden->audio_sem) {
            CloseHandle(this->hidden->audio_sem);
            this->hidden->audio_sem = 0;
        }
    if (this->hidden->hout) {
        waveOutReset(this->hidden->hout);
        /* Clean up mixing buffers */
        for (i = 0; i < NUM_BUFFERS; ++i) {
            if (this->hidden->wavebuf[i].dwUser != 0xFFFF) {
                waveOutUnprepareHeader(this->hidden->hout,
                                       &this->hidden->wavebuf[i],
                                       sizeof(this->hidden->wavebuf[i]));
                this->hidden->wavebuf[i].dwUser = 0xFFFF;
                                       sizeof (this->hidden->wavebuf[i]));
            }
        }
        /* Free raw mixing buffer */
        SDL_free(this->hidden->mixbuf);
        this->hidden->mixbuf = NULL;
        if (this->hidden->hin) {
            waveInClose(this->hidden->hin);
            this->hidden->hin = 0;
        }
        if (this->hidden->hout) {
            waveOutClose(this->hidden->hout);
            this->hidden->hout = 0;
        }
        SDL_free(this->hidden);
        this->hidden = NULL;
        waveOutClose(this->hidden->hout);
    }
    if (this->hidden->hin) {
        waveInReset(this->hidden->hin);
        /* Clean up mixing buffers */
        for (i = 0; i < NUM_BUFFERS; ++i) {
            if (this->hidden->wavebuf[i].dwUser != 0xFFFF) {
                waveInUnprepareHeader(this->hidden->hin,
                                       &this->hidden->wavebuf[i],
                                       sizeof (this->hidden->wavebuf[i]));
            }
        }
        waveInClose(this->hidden->hin);
    }
    if (this->hidden->audio_sem) {
        CloseHandle(this->hidden->audio_sem);
    }
    SDL_free(this->hidden->mixbuf);
    SDL_free(this->hidden);
}
static SDL_bool
@@ -239,7 +264,7 @@
    if (this->hidden == NULL) {
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
    SDL_zerop(this->hidden);
    /* Initialize the wavebuf structures for closing */
    for (i = 0; i < NUM_BUFFERS; ++i)
@@ -269,7 +294,6 @@
    }
    if (!valid_datatype) {
        WINMM_CloseDevice(this);
        return SDL_SetError("Unsupported audio format");
    }
@@ -281,36 +305,45 @@
        result = waveInOpen(&this->hidden->hin, devId, &waveformat,
                             (DWORD_PTR) CaptureSound, (DWORD_PTR) this,
                             CALLBACK_FUNCTION);
        if (result != MMSYSERR_NOERROR) {
            return SetMMerror("waveInOpen()", result);
        }
    } else {
        result = waveOutOpen(&this->hidden->hout, devId, &waveformat,
                             (DWORD_PTR) FillSound, (DWORD_PTR) this,
                             CALLBACK_FUNCTION);
        if (result != MMSYSERR_NOERROR) {
            return SetMMerror("waveOutOpen()", result);
        }
    }
    if (result != MMSYSERR_NOERROR) {
        WINMM_CloseDevice(this);
        return SetMMerror("waveOutOpen()", result);
    }
#ifdef SOUND_DEBUG
    /* Check the sound device we retrieved */
    {
        WAVEOUTCAPS caps;
        result = waveOutGetDevCaps((UINT) this->hidden->hout,
                                   &caps, sizeof(caps));
        if (result != MMSYSERR_NOERROR) {
            WINMM_CloseDevice(this);
            return SetMMerror("waveOutGetDevCaps()", result);
        if (iscapture) {
            WAVEINCAPS caps;
            result = waveInGetDevCaps((UINT) this->hidden->hout,
                                      &caps, sizeof (caps));
            if (result != MMSYSERR_NOERROR) {
                return SetMMerror("waveInGetDevCaps()", result);
            }
            printf("Audio device: %s\n", caps.szPname);
        } else {
            WAVEOUTCAPS caps;
            result = waveOutGetDevCaps((UINT) this->hidden->hout,
                                       &caps, sizeof(caps));
            if (result != MMSYSERR_NOERROR) {
                return SetMMerror("waveOutGetDevCaps()", result);
            }
            printf("Audio device: %s\n", caps.szPname);
        }
        printf("Audio device: %s\n", caps.szPname);
    }
#endif
    /* Create the audio buffer semaphore */
    this->hidden->audio_sem =
        CreateSemaphore(NULL, NUM_BUFFERS - 1, NUM_BUFFERS, NULL);
        CreateSemaphore(NULL, iscapture ? 0 : NUM_BUFFERS - 1, NUM_BUFFERS, NULL);
    if (this->hidden->audio_sem == NULL) {
        WINMM_CloseDevice(this);
        return SDL_SetError("Couldn't create semaphore");
    }
@@ -318,22 +351,44 @@
    this->hidden->mixbuf =
        (Uint8 *) SDL_malloc(NUM_BUFFERS * this->spec.size);
    if (this->hidden->mixbuf == NULL) {
        WINMM_CloseDevice(this);
        return SDL_OutOfMemory();
    }
    SDL_zero(this->hidden->wavebuf);
    for (i = 0; i < NUM_BUFFERS; ++i) {
        SDL_memset(&this->hidden->wavebuf[i], 0,
                   sizeof(this->hidden->wavebuf[i]));
        this->hidden->wavebuf[i].dwBufferLength = this->spec.size;
        this->hidden->wavebuf[i].dwFlags = WHDR_DONE;
        this->hidden->wavebuf[i].lpData =
            (LPSTR) & this->hidden->mixbuf[i * this->spec.size];
        result = waveOutPrepareHeader(this->hidden->hout,
                                      &this->hidden->wavebuf[i],
                                      sizeof(this->hidden->wavebuf[i]));
        if (iscapture) {
            result = waveInPrepareHeader(this->hidden->hin,
                                          &this->hidden->wavebuf[i],
                                          sizeof(this->hidden->wavebuf[i]));
            if (result != MMSYSERR_NOERROR) {
                return SetMMerror("waveInPrepareHeader()", result);
            }
            result = waveInAddBuffer(this->hidden->hin,
                                     &this->hidden->wavebuf[i],
                                     sizeof(this->hidden->wavebuf[i]));
            if (result != MMSYSERR_NOERROR) {
                return SetMMerror("waveInAddBuffer()", result);
            }
        } else {
            result = waveOutPrepareHeader(this->hidden->hout,
                                          &this->hidden->wavebuf[i],
                                          sizeof(this->hidden->wavebuf[i]));
            if (result != MMSYSERR_NOERROR) {
                return SetMMerror("waveOutPrepareHeader()", result);
            }
        }
    }
    if (iscapture) {
        result = waveInStart(this->hidden->hin);
        if (result != MMSYSERR_NOERROR) {
            WINMM_CloseDevice(this);
            return SetMMerror("waveOutPrepareHeader()", result);
            return SetMMerror("waveInStart()", result);
        }
    }
@@ -349,10 +404,13 @@
    impl->OpenDevice = WINMM_OpenDevice;
    impl->PlayDevice = WINMM_PlayDevice;
    impl->WaitDevice = WINMM_WaitDevice;
    impl->WaitDone = WINMM_WaitDone;
    impl->GetDeviceBuf = WINMM_GetDeviceBuf;
    impl->CaptureFromDevice = WINMM_CaptureFromDevice;
    impl->FlushCapture = WINMM_FlushCapture;
    impl->CloseDevice = WINMM_CloseDevice;
    impl->HasCaptureSupport = SDL_TRUE;
    return 1;   /* this audio target is available. */
}
source/src/audio/xaudio2/SDL_xaudio2.c
@@ -195,7 +195,7 @@
    IXAudio2SourceVoice *source = this->hidden->source;
    HRESULT result = S_OK;
    if (!this->enabled) { /* shutting down? */
    if (!SDL_AtomicGet(&this->enabled)) { /* shutting down? */
        return;
    }
@@ -226,64 +226,47 @@
static void
XAUDIO2_WaitDevice(_THIS)
{
    if (this->enabled) {
    if (SDL_AtomicGet(&this->enabled)) {
        SDL_SemWait(this->hidden->semaphore);
    }
}
static void
XAUDIO2_WaitDone(_THIS)
XAUDIO2_PrepareToClose(_THIS)
{
    IXAudio2SourceVoice *source = this->hidden->source;
    XAUDIO2_VOICE_STATE state;
    SDL_assert(!this->enabled);  /* flag that stops playing. */
    IXAudio2SourceVoice_Discontinuity(source);
#if SDL_XAUDIO2_WIN8
    IXAudio2SourceVoice_GetState(source, &state, XAUDIO2_VOICE_NOSAMPLESPLAYED);
#else
    IXAudio2SourceVoice_GetState(source, &state);
#endif
    while (state.BuffersQueued > 0) {
        SDL_SemWait(this->hidden->semaphore);
#if SDL_XAUDIO2_WIN8
        IXAudio2SourceVoice_GetState(source, &state, XAUDIO2_VOICE_NOSAMPLESPLAYED);
#else
        IXAudio2SourceVoice_GetState(source, &state);
#endif
    if (source) {
        IXAudio2SourceVoice_Discontinuity(source);
    }
}
static void
XAUDIO2_CloseDevice(_THIS)
{
    if (this->hidden != NULL) {
        IXAudio2 *ixa2 = this->hidden->ixa2;
        IXAudio2SourceVoice *source = this->hidden->source;
        IXAudio2MasteringVoice *mastering = this->hidden->mastering;
    IXAudio2 *ixa2 = this->hidden->ixa2;
    IXAudio2SourceVoice *source = this->hidden->source;
    IXAudio2MasteringVoice *mastering = this->hidden->mastering;
        if (source != NULL) {
            IXAudio2SourceVoice_Stop(source, 0, XAUDIO2_COMMIT_NOW);
            IXAudio2SourceVoice_FlushSourceBuffers(source);
            IXAudio2SourceVoice_DestroyVoice(source);
        }
        if (ixa2 != NULL) {
            IXAudio2_StopEngine(ixa2);
        }
        if (mastering != NULL) {
            IXAudio2MasteringVoice_DestroyVoice(mastering);
        }
        if (ixa2 != NULL) {
            IXAudio2_Release(ixa2);
        }
        SDL_free(this->hidden->mixbuf);
        if (this->hidden->semaphore != NULL) {
            SDL_DestroySemaphore(this->hidden->semaphore);
        }
        SDL_free(this->hidden);
        this->hidden = NULL;
    if (source != NULL) {
        IXAudio2SourceVoice_Stop(source, 0, XAUDIO2_COMMIT_NOW);
        IXAudio2SourceVoice_FlushSourceBuffers(source);
        IXAudio2SourceVoice_DestroyVoice(source);
    }
    if (ixa2 != NULL) {
        IXAudio2_StopEngine(ixa2);
    }
    if (mastering != NULL) {
        IXAudio2MasteringVoice_DestroyVoice(mastering);
    }
    if (ixa2 != NULL) {
        IXAudio2_Release(ixa2);
    }
    if (this->hidden->semaphore != NULL) {
        SDL_DestroySemaphore(this->hidden->semaphore);
    }
    SDL_free(this->hidden->mixbuf);
    SDL_free(this->hidden);
}
static int
@@ -345,12 +328,11 @@
        IXAudio2_Release(ixa2);
        return SDL_OutOfMemory();
    }
    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
    SDL_zerop(this->hidden);
    this->hidden->ixa2 = ixa2;
    this->hidden->semaphore = SDL_CreateSemaphore(1);
    if (this->hidden->semaphore == NULL) {
        XAUDIO2_CloseDevice(this);
        return SDL_SetError("XAudio2: CreateSemaphore() failed!");
    }
@@ -368,7 +350,6 @@
    }
    if (!valid_format) {
        XAUDIO2_CloseDevice(this);
        return SDL_SetError("XAudio2: Unsupported audio format");
    }
@@ -379,11 +360,10 @@
    this->hidden->mixlen = this->spec.size;
    this->hidden->mixbuf = (Uint8 *) SDL_malloc(2 * this->hidden->mixlen);
    if (this->hidden->mixbuf == NULL) {
        XAUDIO2_CloseDevice(this);
        return SDL_OutOfMemory();
    }
    this->hidden->nextbuf = this->hidden->mixbuf;
    SDL_memset(this->hidden->mixbuf, 0, 2 * this->hidden->mixlen);
    SDL_memset(this->hidden->mixbuf, this->spec.silence, 2 * this->hidden->mixlen);
    /* We use XAUDIO2_DEFAULT_CHANNELS instead of this->spec.channels. On
       Xbox360, this means 5.1 output, but on Windows, it means "figure out
@@ -401,7 +381,6 @@
                                           this->spec.freq, 0, devId, NULL);
#endif
    if (result != S_OK) {
        XAUDIO2_CloseDevice(this);
        return SDL_SetError("XAudio2: Couldn't create mastering voice");
    }
@@ -436,7 +415,6 @@
#endif
    if (result != S_OK) {
        XAUDIO2_CloseDevice(this);
        return SDL_SetError("XAudio2: Couldn't create source voice");
    }
    this->hidden->source = source;
@@ -444,13 +422,11 @@
    /* Start everything playing! */
    result = IXAudio2_StartEngine(ixa2);
    if (result != S_OK) {
        XAUDIO2_CloseDevice(this);
        return SDL_SetError("XAudio2: Couldn't start engine");
    }
    result = IXAudio2SourceVoice_Start(source, 0, XAUDIO2_COMMIT_NOW);
    if (result != S_OK) {
        XAUDIO2_CloseDevice(this);
        return SDL_SetError("XAudio2: Couldn't start source voice");
    }
@@ -499,7 +475,7 @@
    impl->OpenDevice = XAUDIO2_OpenDevice;
    impl->PlayDevice = XAUDIO2_PlayDevice;
    impl->WaitDevice = XAUDIO2_WaitDevice;
    impl->WaitDone = XAUDIO2_WaitDone;
    impl->PrepareToClose = XAUDIO2_PrepareToClose;
    impl->GetDeviceBuf = XAUDIO2_GetDeviceBuf;
    impl->CloseDevice = XAUDIO2_CloseDevice;
    impl->Deinitialize = XAUDIO2_Deinitialize;
source/src/core/android/SDL_android.c
@@ -71,10 +71,14 @@
/* method signatures */
static jmethodID midGetNativeSurface;
static jmethodID midAudioInit;
static jmethodID midAudioOpen;
static jmethodID midAudioWriteShortBuffer;
static jmethodID midAudioWriteByteBuffer;
static jmethodID midAudioQuit;
static jmethodID midAudioClose;
static jmethodID midCaptureOpen;
static jmethodID midCaptureReadShortBuffer;
static jmethodID midCaptureReadByteBuffer;
static jmethodID midCaptureClose;
static jmethodID midPollInputDevices;
/* Accelerometer data storage */
@@ -118,34 +122,45 @@
    midGetNativeSurface = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
                                "getNativeSurface","()Landroid/view/Surface;");
    midAudioInit = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
                                "audioInit", "(IZZI)I");
    midAudioOpen = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
                                "audioOpen", "(IZZI)I");
    midAudioWriteShortBuffer = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
                                "audioWriteShortBuffer", "([S)V");
    midAudioWriteByteBuffer = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
                                "audioWriteByteBuffer", "([B)V");
    midAudioQuit = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
                                "audioQuit", "()V");
    midAudioClose = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
                                "audioClose", "()V");
    midCaptureOpen = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
                                "captureOpen", "(IZZI)I");
    midCaptureReadShortBuffer = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
                                "captureReadShortBuffer", "([SZ)I");
    midCaptureReadByteBuffer = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
                                "captureReadByteBuffer", "([BZ)I");
    midCaptureClose = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
                                "captureClose", "()V");
    midPollInputDevices = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
                                "pollInputDevices", "()V");
    bHasNewData = SDL_FALSE;
    if (!midGetNativeSurface || !midAudioInit ||
       !midAudioWriteShortBuffer || !midAudioWriteByteBuffer || !midAudioQuit || !midPollInputDevices) {
    if (!midGetNativeSurface ||
       !midAudioOpen || !midAudioWriteShortBuffer || !midAudioWriteByteBuffer || !midAudioClose ||
       !midCaptureOpen || !midCaptureReadShortBuffer || !midCaptureReadByteBuffer || !midCaptureClose ||
       !midPollInputDevices) {
        __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL: Couldn't locate Java callbacks, check that they're named and typed correctly");
    }
    __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL_Android_Init() finished!");
}
/* Drop file */
void Java_org_libsdl_app_SDLActivity_onNativeDropFile(
JNIEXPORT void JNICALL Java_org_libsdl_app_SDLActivity_onNativeDropFile(
                                    JNIEnv* env, jclass jcls,
                                    jstring filename)
{
    const char *path = (*env)->GetStringUTFChars(env, filename, NULL);
    SDL_SendDropFile(path);
    SDL_SendDropFile(NULL, path);
    (*env)->ReleaseStringUTFChars(env, filename, path);
    SDL_SendDropComplete(NULL);
}
/* Resize */
@@ -555,11 +570,15 @@
static jboolean audioBuffer16Bit = JNI_FALSE;
static jobject audioBuffer = NULL;
static void* audioBufferPinned = NULL;
static jboolean captureBuffer16Bit = JNI_FALSE;
static jobject captureBuffer = NULL;
int Android_JNI_OpenAudioDevice(int sampleRate, int is16Bit, int channelCount, int desiredBufferFrames)
int Android_JNI_OpenAudioDevice(int iscapture, int sampleRate, int is16Bit, int channelCount, int desiredBufferFrames)
{
    jboolean audioBufferStereo;
    int audioBufferFrames;
    jobject jbufobj = NULL;
    jboolean isCopy;
    JNIEnv *env = Android_JNI_GetEnv();
@@ -568,14 +587,24 @@
    }
    Android_JNI_SetupThread();
    __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device");
    audioBuffer16Bit = is16Bit;
    audioBufferStereo = channelCount > 1;
    if ((*env)->CallStaticIntMethod(env, mActivityClass, midAudioInit, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames) != 0) {
        /* Error during audio initialization */
        __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: error on AudioTrack initialization!");
        return 0;
    if (iscapture) {
        __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device for capture");
        captureBuffer16Bit = is16Bit;
        if ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureOpen, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames) != 0) {
            /* Error during audio initialization */
            __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: error on AudioRecord initialization!");
            return 0;
        }
    } else {
        __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device for output");
        audioBuffer16Bit = is16Bit;
        if ((*env)->CallStaticIntMethod(env, mActivityClass, midAudioOpen, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames) != 0) {
            /* Error during audio initialization */
            __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: error on AudioTrack initialization!");
            return 0;
        }
    }
    /* Allocating the audio buffer from the Java side and passing it as the return value for audioInit no longer works on
@@ -584,31 +613,43 @@
    if (is16Bit) {
        jshortArray audioBufferLocal = (*env)->NewShortArray(env, desiredBufferFrames * (audioBufferStereo ? 2 : 1));
        if (audioBufferLocal) {
            audioBuffer = (*env)->NewGlobalRef(env, audioBufferLocal);
            jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal);
            (*env)->DeleteLocalRef(env, audioBufferLocal);
        }
    }
    else {
        jbyteArray audioBufferLocal = (*env)->NewByteArray(env, desiredBufferFrames * (audioBufferStereo ? 2 : 1));
        if (audioBufferLocal) {
            audioBuffer = (*env)->NewGlobalRef(env, audioBufferLocal);
            jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal);
            (*env)->DeleteLocalRef(env, audioBufferLocal);
        }
    }
    if (audioBuffer == NULL) {
    if (jbufobj == NULL) {
        __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: could not allocate an audio buffer!");
        return 0;
    }
    jboolean isCopy = JNI_FALSE;
    if (audioBuffer16Bit) {
        audioBufferPinned = (*env)->GetShortArrayElements(env, (jshortArray)audioBuffer, &isCopy);
    if (iscapture) {
        captureBuffer = jbufobj;
    } else {
        audioBuffer = jbufobj;
    }
    isCopy = JNI_FALSE;
    if (is16Bit) {
        if (!iscapture) {
            audioBufferPinned = (*env)->GetShortArrayElements(env, (jshortArray)audioBuffer, &isCopy);
        }
        audioBufferFrames = (*env)->GetArrayLength(env, (jshortArray)audioBuffer);
    } else {
        audioBufferPinned = (*env)->GetByteArrayElements(env, (jbyteArray)audioBuffer, &isCopy);
        if (!iscapture) {
            audioBufferPinned = (*env)->GetByteArrayElements(env, (jbyteArray)audioBuffer, &isCopy);
        }
        audioBufferFrames = (*env)->GetArrayLength(env, (jbyteArray)audioBuffer);
    }
    if (audioBufferStereo) {
        audioBufferFrames /= 2;
    }
@@ -636,16 +677,71 @@
    /* JNI_COMMIT means the changes are committed to the VM but the buffer remains pinned */
}
void Android_JNI_CloseAudioDevice(void)
int Android_JNI_CaptureAudioBuffer(void *buffer, int buflen)
{
    JNIEnv *env = Android_JNI_GetEnv();
    jboolean isCopy = JNI_FALSE;
    jint br;
    if (captureBuffer16Bit) {
        SDL_assert((*env)->GetArrayLength(env, (jshortArray)captureBuffer) == (buflen / 2));
        br = (*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_TRUE);
        if (br > 0) {
            jshort *ptr = (*env)->GetShortArrayElements(env, (jshortArray)captureBuffer, &isCopy);
            br *= 2;
            SDL_memcpy(buffer, ptr, br);
            (*env)->ReleaseShortArrayElements(env, (jshortArray)captureBuffer, (jshort *)ptr, JNI_ABORT);
        }
    } else {
        SDL_assert((*env)->GetArrayLength(env, (jshortArray)captureBuffer) == buflen);
        br = (*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_TRUE);
        if (br > 0) {
            jbyte *ptr = (*env)->GetByteArrayElements(env, (jbyteArray)captureBuffer, &isCopy);
            SDL_memcpy(buffer, ptr, br);
            (*env)->ReleaseByteArrayElements(env, (jbyteArray)captureBuffer, (jbyte *)ptr, JNI_ABORT);
        }
    }
    return (int) br;
}
void Android_JNI_FlushCapturedAudio(void)
{
    JNIEnv *env = Android_JNI_GetEnv();
    #if 0  /* !!! FIXME: this needs API 23, or it'll do blocking reads and never end. */
    if (captureBuffer16Bit) {
        const jint len = (*env)->GetArrayLength(env, (jshortArray)captureBuffer);
        while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE) == len) { /* spin */ }
    } else {
        const jint len = (*env)->GetArrayLength(env, (jbyteArray)captureBuffer);
        while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_FALSE) == len) { /* spin */ }
    }
    #else
    if (captureBuffer16Bit) {
        (*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE);
    } else {
        (*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_FALSE);
    }
    #endif
}
void Android_JNI_CloseAudioDevice(const int iscapture)
{
    JNIEnv *env = Android_JNI_GetEnv();
    (*env)->CallStaticVoidMethod(env, mActivityClass, midAudioQuit);
    if (audioBuffer) {
        (*env)->DeleteGlobalRef(env, audioBuffer);
        audioBuffer = NULL;
        audioBufferPinned = NULL;
    if (iscapture) {
        (*env)->CallStaticVoidMethod(env, mActivityClass, midCaptureClose);
        if (captureBuffer) {
            (*env)->DeleteGlobalRef(env, captureBuffer);
            captureBuffer = NULL;
        }
    } else {
        (*env)->CallStaticVoidMethod(env, mActivityClass, midAudioClose);
        if (audioBuffer) {
            (*env)->DeleteGlobalRef(env, audioBuffer);
            audioBuffer = NULL;
            audioBufferPinned = NULL;
        }
    }
}
@@ -653,10 +749,12 @@
/* If the parameter silent is truthy then SDL_SetError() will not be called. */
static SDL_bool Android_JNI_ExceptionOccurred(SDL_bool silent)
{
    SDL_assert(LocalReferenceHolder_IsActive());
    JNIEnv *mEnv = Android_JNI_GetEnv();
    jthrowable exception;
    jthrowable exception = (*mEnv)->ExceptionOccurred(mEnv);
    SDL_assert(LocalReferenceHolder_IsActive());
    exception = (*mEnv)->ExceptionOccurred(mEnv);
    if (exception != NULL) {
        jmethodID mid;
@@ -666,13 +764,16 @@
        if (!silent) {
            jclass exceptionClass = (*mEnv)->GetObjectClass(mEnv, exception);
            jclass classClass = (*mEnv)->FindClass(mEnv, "java/lang/Class");
            jstring exceptionName;
            const char* exceptionNameUTF8;
            jstring exceptionMessage;
            mid = (*mEnv)->GetMethodID(mEnv, classClass, "getName", "()Ljava/lang/String;");
            jstring exceptionName = (jstring)(*mEnv)->CallObjectMethod(mEnv, exceptionClass, mid);
            const char* exceptionNameUTF8 = (*mEnv)->GetStringUTFChars(mEnv, exceptionName, 0);
            exceptionName = (jstring)(*mEnv)->CallObjectMethod(mEnv, exceptionClass, mid);
            exceptionNameUTF8 = (*mEnv)->GetStringUTFChars(mEnv, exceptionName, 0);
            mid = (*mEnv)->GetMethodID(mEnv, exceptionClass, "getMessage", "()Ljava/lang/String;");
            jstring exceptionMessage = (jstring)(*mEnv)->CallObjectMethod(mEnv, exception, mid);
            exceptionMessage = (jstring)(*mEnv)->CallObjectMethod(mEnv, exception, mid);
            if (exceptionMessage != NULL) {
                const char* exceptionMessageUTF8 = (*mEnv)->GetStringUTFChars(mEnv, exceptionMessage, 0);
@@ -855,6 +956,7 @@
    struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
    JNIEnv *mEnv = Android_JNI_GetEnv();
    int retval;
    jstring fileNameJString;
    if (!LocalReferenceHolder_Init(&refs, mEnv)) {
        LocalReferenceHolder_Cleanup(&refs);        
@@ -866,7 +968,7 @@
        return -1;
    }
    jstring fileNameJString = (*mEnv)->NewStringUTF(mEnv, fileName);
    fileNameJString = (*mEnv)->NewStringUTF(mEnv, fileName);
    ctx->hidden.androidio.fileNameRef = (*mEnv)->NewGlobalRef(mEnv, fileNameJString);
    ctx->hidden.androidio.inputStreamRef = NULL;
    ctx->hidden.androidio.readableByteChannelRef = NULL;
@@ -885,10 +987,11 @@
    if (ctx->hidden.androidio.assetFileDescriptorRef) {
        size_t bytesMax = size * maxnum;
        size_t result;
        if (ctx->hidden.androidio.size != -1 /* UNKNOWN_LENGTH */ && ctx->hidden.androidio.position + bytesMax > ctx->hidden.androidio.size) {
            bytesMax = ctx->hidden.androidio.size - ctx->hidden.androidio.position;
        }
        size_t result = read(ctx->hidden.androidio.fd, buffer, bytesMax );
        result = read(ctx->hidden.androidio.fd, buffer, bytesMax );
        if (result > 0) {
            ctx->hidden.androidio.position += result;
            LocalReferenceHolder_Cleanup(&refs);
@@ -900,19 +1003,23 @@
        jlong bytesRemaining = (jlong) (size * maxnum);
        jlong bytesMax = (jlong) (ctx->hidden.androidio.size -  ctx->hidden.androidio.position);
        int bytesRead = 0;
        JNIEnv *mEnv;
        jobject readableByteChannel;
        jmethodID readMethod;
        jobject byteBuffer;
        /* Don't read more bytes than those that remain in the file, otherwise we get an exception */
        if (bytesRemaining >  bytesMax) bytesRemaining = bytesMax;
        JNIEnv *mEnv = Android_JNI_GetEnv();
        mEnv = Android_JNI_GetEnv();
        if (!LocalReferenceHolder_Init(&refs, mEnv)) {
            LocalReferenceHolder_Cleanup(&refs);            
            return 0;
        }
        jobject readableByteChannel = (jobject)ctx->hidden.androidio.readableByteChannelRef;
        jmethodID readMethod = (jmethodID)ctx->hidden.androidio.readMethod;
        jobject byteBuffer = (*mEnv)->NewDirectByteBuffer(mEnv, buffer, bytesRemaining);
        readableByteChannel = (jobject)ctx->hidden.androidio.readableByteChannelRef;
        readMethod = (jmethodID)ctx->hidden.androidio.readMethod;
        byteBuffer = (*mEnv)->NewDirectByteBuffer(mEnv, buffer, bytesRemaining);
        while (bytesRemaining > 0) {
            /* result = readableByteChannel.read(...); */
@@ -1002,6 +1109,7 @@
Sint64 Android_JNI_FileSeek(SDL_RWops* ctx, Sint64 offset, int whence)
{
    if (ctx->hidden.androidio.assetFileDescriptorRef) {
        off_t ret;
        switch (whence) {
            case RW_SEEK_SET:
                if (ctx->hidden.androidio.size != -1 /* UNKNOWN_LENGTH */ && offset > ctx->hidden.androidio.size) offset = ctx->hidden.androidio.size;
@@ -1020,11 +1128,12 @@
        }
        whence = SEEK_SET;
        off_t ret = lseek(ctx->hidden.androidio.fd, (off_t)offset, SEEK_SET);
        ret = lseek(ctx->hidden.androidio.fd, (off_t)offset, SEEK_SET);
        if (ret == -1) return -1;
        ctx->hidden.androidio.position = ret - ctx->hidden.androidio.offset;
    } else {
        Sint64 newPosition;
        Sint64 movement;
        switch (whence) {
            case RW_SEEK_SET:
@@ -1048,17 +1157,18 @@
            newPosition = ctx->hidden.androidio.size;
        }
        Sint64 movement = newPosition - ctx->hidden.androidio.position;
        movement = newPosition - ctx->hidden.androidio.position;
        if (movement > 0) {
            unsigned char buffer[4096];
            /* The easy case where we're seeking forwards */
            while (movement > 0) {
                Sint64 amount = sizeof (buffer);
                size_t result;
                if (amount > movement) {
                    amount = movement;
                }
                size_t result = Android_JNI_FileRead(ctx, buffer, 1, amount);
                result = Android_JNI_FileRead(ctx, buffer, 1, amount);
                if (result <= 0) {
                    /* Failed to read/skip the required amount, so fail */
                    return -1;
@@ -1091,21 +1201,23 @@
    struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
    JNIEnv* env = Android_JNI_GetEnv();
    jobject retval = NULL;
    jstring service;
    jmethodID mid;
    jobject context;
    jobject manager;
    if (!LocalReferenceHolder_Init(&refs, env)) {
        LocalReferenceHolder_Cleanup(&refs);
        return NULL;
    }
    jstring service = (*env)->NewStringUTF(env, name);
    jmethodID mid;
    service = (*env)->NewStringUTF(env, name);
    mid = (*env)->GetStaticMethodID(env, mActivityClass, "getContext", "()Landroid/content/Context;");
    jobject context = (*env)->CallStaticObjectMethod(env, mActivityClass, mid);
    context = (*env)->CallStaticObjectMethod(env, mActivityClass, mid);
    mid = (*env)->GetMethodID(env, mActivityClass, "getSystemServiceFromUiThread", "(Ljava/lang/String;)Ljava/lang/Object;");
    jobject manager = (*env)->CallObjectMethod(env, context, mid, service);
    manager = (*env)->CallObjectMethod(env, context, mid, service);
    (*env)->DeleteLocalRef(env, service);
@@ -1117,11 +1229,12 @@
#define SETUP_CLIPBOARD(error) \
    struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); \
    JNIEnv* env = Android_JNI_GetEnv(); \
    jobject clipboard; \
    if (!LocalReferenceHolder_Init(&refs, env)) { \
        LocalReferenceHolder_Cleanup(&refs); \
        return error; \
    } \
    jobject clipboard = Android_JNI_GetSystemServiceObject("clipboard"); \
    clipboard = Android_JNI_GetSystemServiceObject("clipboard"); \
    if (!clipboard) { \
        LocalReferenceHolder_Cleanup(&refs); \
        return error; \
@@ -1132,14 +1245,17 @@
int Android_JNI_SetClipboardText(const char* text)
{
    /* Watch out for C89 scoping rules because of the macro */
    SETUP_CLIPBOARD(-1)
    jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, clipboard), "setText", "(Ljava/lang/CharSequence;)V");
    jstring string = (*env)->NewStringUTF(env, text);
    (*env)->CallVoidMethod(env, clipboard, mid, string);
    (*env)->DeleteGlobalRef(env, clipboard);
    (*env)->DeleteLocalRef(env, string);
    /* Nest the following in a scope to avoid C89 declaration rules triggered by the macro */
    {
        jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, clipboard), "setText", "(Ljava/lang/CharSequence;)V");
        jstring string = (*env)->NewStringUTF(env, text);
        (*env)->CallVoidMethod(env, clipboard, mid, string);
        (*env)->DeleteGlobalRef(env, clipboard);
        (*env)->DeleteLocalRef(env, string);
    }
    CLEANUP_CLIPBOARD();
    return 0;
@@ -1147,25 +1263,30 @@
char* Android_JNI_GetClipboardText(void)
{
    /* Watch out for C89 scoping rules because of the macro */
    SETUP_CLIPBOARD(SDL_strdup(""))
    jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, clipboard), "getText", "()Ljava/lang/CharSequence;");
    jobject sequence = (*env)->CallObjectMethod(env, clipboard, mid);
    (*env)->DeleteGlobalRef(env, clipboard);
    if (sequence) {
        mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, sequence), "toString", "()Ljava/lang/String;");
        jstring string = (jstring)((*env)->CallObjectMethod(env, sequence, mid));
        const char* utf = (*env)->GetStringUTFChars(env, string, 0);
        if (utf) {
            char* text = SDL_strdup(utf);
            (*env)->ReleaseStringUTFChars(env, string, utf);
    /* Nest the following in a scope to avoid C89 declaration rules triggered by the macro */
    {
        jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, clipboard), "getText", "()Ljava/lang/CharSequence;");
        jobject sequence = (*env)->CallObjectMethod(env, clipboard, mid);
        (*env)->DeleteGlobalRef(env, clipboard);
        if (sequence) {
            jstring string;
            const char* utf;
            mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, sequence), "toString", "()Ljava/lang/String;");
            string = (jstring)((*env)->CallObjectMethod(env, sequence, mid));
            utf = (*env)->GetStringUTFChars(env, string, 0);
            if (utf) {
                char* text = SDL_strdup(utf);
                (*env)->ReleaseStringUTFChars(env, string, utf);
            CLEANUP_CLIPBOARD();
                CLEANUP_CLIPBOARD();
            return text;
                return text;
            }
        }
    }
    CLEANUP_CLIPBOARD();    
    return SDL_strdup("");
@@ -1173,10 +1294,13 @@
SDL_bool Android_JNI_HasClipboardText(void)
{
    jmethodID mid;
    jboolean has;
    /* Watch out for C89 scoping rules because of the macro */
    SETUP_CLIPBOARD(SDL_FALSE)
    jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, clipboard), "hasText", "()Z");
    jboolean has = (*env)->CallBooleanMethod(env, clipboard, mid);
    mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, clipboard), "hasText", "()Z");
    has = (*env)->CallBooleanMethod(env, clipboard, mid);
    (*env)->DeleteGlobalRef(env, clipboard);
    CLEANUP_CLIPBOARD();
@@ -1193,49 +1317,61 @@
{
    struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
    JNIEnv* env = Android_JNI_GetEnv();
    jmethodID mid;
    jobject context;
    jstring action;
    jclass cls;
    jobject filter;
    jobject intent;
    jstring iname;
    jmethodID imid;
    jstring bname;
    jmethodID bmid;
    if (!LocalReferenceHolder_Init(&refs, env)) {
        LocalReferenceHolder_Cleanup(&refs);
        return -1;
    }
    jmethodID mid;
    mid = (*env)->GetStaticMethodID(env, mActivityClass, "getContext", "()Landroid/content/Context;");
    jobject context = (*env)->CallStaticObjectMethod(env, mActivityClass, mid);
    context = (*env)->CallStaticObjectMethod(env, mActivityClass, mid);
    jstring action = (*env)->NewStringUTF(env, "android.intent.action.BATTERY_CHANGED");
    action = (*env)->NewStringUTF(env, "android.intent.action.BATTERY_CHANGED");
    jclass cls = (*env)->FindClass(env, "android/content/IntentFilter");
    cls = (*env)->FindClass(env, "android/content/IntentFilter");
    mid = (*env)->GetMethodID(env, cls, "<init>", "(Ljava/lang/String;)V");
    jobject filter = (*env)->NewObject(env, cls, mid, action);
    filter = (*env)->NewObject(env, cls, mid, action);
    (*env)->DeleteLocalRef(env, action);
    mid = (*env)->GetMethodID(env, mActivityClass, "registerReceiver", "(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent;");
    jobject intent = (*env)->CallObjectMethod(env, context, mid, NULL, filter);
    intent = (*env)->CallObjectMethod(env, context, mid, NULL, filter);
    (*env)->DeleteLocalRef(env, filter);
    cls = (*env)->GetObjectClass(env, intent);
    jstring iname;
    jmethodID imid = (*env)->GetMethodID(env, cls, "getIntExtra", "(Ljava/lang/String;I)I");
    imid = (*env)->GetMethodID(env, cls, "getIntExtra", "(Ljava/lang/String;I)I");
    /* Watch out for C89 scoping rules because of the macro */
#define GET_INT_EXTRA(var, key) \
    int var; \
    iname = (*env)->NewStringUTF(env, key); \
    int var = (*env)->CallIntMethod(env, intent, imid, iname, -1); \
    var = (*env)->CallIntMethod(env, intent, imid, iname, -1); \
    (*env)->DeleteLocalRef(env, iname);
    jstring bname;
    jmethodID bmid = (*env)->GetMethodID(env, cls, "getBooleanExtra", "(Ljava/lang/String;Z)Z");
    bmid = (*env)->GetMethodID(env, cls, "getBooleanExtra", "(Ljava/lang/String;Z)Z");
    /* Watch out for C89 scoping rules because of the macro */
#define GET_BOOL_EXTRA(var, key) \
    int var; \
    bname = (*env)->NewStringUTF(env, key); \
    int var = (*env)->CallBooleanMethod(env, intent, bmid, bname, JNI_FALSE); \
    var = (*env)->CallBooleanMethod(env, intent, bmid, bname, JNI_FALSE); \
    (*env)->DeleteLocalRef(env, bname);
    if (plugged) {
        /* Watch out for C89 scoping rules because of the macro */
        GET_INT_EXTRA(plug, "plugged") /* == BatteryManager.EXTRA_PLUGGED (API 5) */
        if (plug == -1) {
            LocalReferenceHolder_Cleanup(&refs);
@@ -1247,6 +1383,7 @@
    }
    if (charged) {
        /* Watch out for C89 scoping rules because of the macro */
        GET_INT_EXTRA(status, "status") /* == BatteryManager.EXTRA_STATUS (API 5) */
        if (status == -1) {
            LocalReferenceHolder_Cleanup(&refs);
@@ -1266,8 +1403,20 @@
    }
    if (percent) {
        GET_INT_EXTRA(level, "level") /* == BatteryManager.EXTRA_LEVEL (API 5) */
        GET_INT_EXTRA(scale, "scale") /* == BatteryManager.EXTRA_SCALE (API 5) */
        int level;
        int scale;
        /* Watch out for C89 scoping rules because of the macro */
        {
            GET_INT_EXTRA(level_temp, "level") /* == BatteryManager.EXTRA_LEVEL (API 5) */
            level = level_temp;
        }
        /* Watch out for C89 scoping rules because of the macro */
        {
            GET_INT_EXTRA(scale_temp, "scale") /* == BatteryManager.EXTRA_SCALE (API 5) */
            scale = scale_temp;
        }
        if ((level == -1) || (scale == -1)) {
            LocalReferenceHolder_Cleanup(&refs);
            return -1;
@@ -1320,14 +1469,16 @@
int Android_JNI_SendMessage(int command, int param)
{
    JNIEnv *env = Android_JNI_GetEnv();
    jmethodID mid;
    jboolean success;
    if (!env) {
        return -1;
    }
    jmethodID mid = (*env)->GetStaticMethodID(env, mActivityClass, "sendMessage", "(II)Z");
    mid = (*env)->GetStaticMethodID(env, mActivityClass, "sendMessage", "(II)Z");
    if (!mid) {
        return -1;
    }
    jboolean success = (*env)->CallStaticBooleanMethod(env, mActivityClass, mid, command, param);
    success = (*env)->CallStaticBooleanMethod(env, mActivityClass, mid, command, param);
    return success ? 0 : -1;
}
@@ -1339,11 +1490,12 @@
void Android_JNI_ShowTextInput(SDL_Rect *inputRect)
{
    JNIEnv *env = Android_JNI_GetEnv();
    jmethodID mid;
    if (!env) {
        return;
    }
    jmethodID mid = (*env)->GetStaticMethodID(env, mActivityClass, "showTextInput", "(IIII)Z");
    mid = (*env)->GetStaticMethodID(env, mActivityClass, "showTextInput", "(IIII)Z");
    if (!mid) {
        return;
    }
source/src/core/android/SDL_android.h
@@ -40,10 +40,12 @@
extern ANativeWindow* Android_JNI_GetNativeWindow(void);
/* Audio support */
extern int Android_JNI_OpenAudioDevice(int sampleRate, int is16Bit, int channelCount, int desiredBufferFrames);
extern int Android_JNI_OpenAudioDevice(int iscapture, int sampleRate, int is16Bit, int channelCount, int desiredBufferFrames);
extern void* Android_JNI_GetAudioBuffer(void);
extern void Android_JNI_WriteAudioBuffer(void);
extern void Android_JNI_CloseAudioDevice(void);
extern int Android_JNI_CaptureAudioBuffer(void *buffer, int buflen);
extern void Android_JNI_FlushCapturedAudio(void);
extern void Android_JNI_CloseAudioDevice(const int iscapture);
#include "SDL_rwops.h"
source/src/core/linux/SDL_dbus.c
@@ -27,7 +27,7 @@
static const char *dbus_library = "libdbus-1.so.3";
static void *dbus_handle = NULL;
static unsigned int screensaver_cookie = 0;
static SDL_DBusContext dbus = {0};
static SDL_DBusContext dbus;
static int
LoadDBUSSyms(void)
source/src/core/linux/SDL_evdev.c
@@ -29,10 +29,7 @@
 *             The evtest application is also useful to debug the protocol
 */
#include "SDL_evdev.h"
#define _THIS SDL_EVDEV_PrivateData *_this
static _THIS = NULL;
#include <sys/stat.h>
#include <unistd.h>
@@ -43,18 +40,8 @@
#ifdef SDL_INPUT_LINUXKD
#include <linux/kd.h>
#include <linux/keyboard.h>
#endif
/* We need this to prevent keystrokes from appear in the console */
#ifndef KDSKBMUTE
#define KDSKBMUTE 0x4B51
#endif
#ifndef KDSKBMODE
#define KDSKBMODE 0x4B45
#endif
#ifndef K_OFF
#define K_OFF 0x04
#include <linux/vt.h>
#include <linux/tiocl.h> /* for TIOCL_GETSHIFTSTATE */
#endif
#include "SDL.h"
@@ -63,272 +50,70 @@
#include "../../core/linux/SDL_udev.h"
#include "SDL_scancode.h"
#include "../../events/SDL_events_c.h"
#include "../../events/scancodes_linux.h" /* adds linux_scancode_table */
/* This isn't defined in older Linux kernel headers */
#ifndef SYN_DROPPED
#define SYN_DROPPED 3
#endif
typedef struct SDL_evdevlist_item
{
    char *path;
    int fd;
    /* TODO: use this for every device, not just touchscreen */
    int out_of_sync;
    /* TODO: expand on this to have data for every possible class (mouse,
       keyboard, touchpad, etc.). Also there's probably some things in here we
       can pull out to the SDL_evdevlist_item i.e. name */
    int is_touchscreen;
    struct {
        char* name;
        int min_x, max_x, range_x;
        int min_y, max_y, range_y;
        int max_slots;
        int current_slot;
        struct {
            enum {
                EVDEV_TOUCH_SLOTDELTA_NONE = 0,
                EVDEV_TOUCH_SLOTDELTA_DOWN,
                EVDEV_TOUCH_SLOTDELTA_UP,
                EVDEV_TOUCH_SLOTDELTA_MOVE
            } delta;
            int tracking_id;
            int x, y;
        } * slots;
    } * touchscreen_data;
    struct SDL_evdevlist_item *next;
} SDL_evdevlist_item;
typedef struct SDL_EVDEV_PrivateData
{
    SDL_evdevlist_item *first;
    SDL_evdevlist_item *last;
    int num_devices;
    int ref_count;
    int console_fd;
    int kb_mode;
} SDL_EVDEV_PrivateData;
#define _THIS SDL_EVDEV_PrivateData *_this
static _THIS = NULL;
static SDL_Scancode SDL_EVDEV_translate_keycode(int keycode);
static void SDL_EVDEV_sync_device(SDL_evdevlist_item *item);
static int SDL_EVDEV_device_removed(const char *devpath);
static int SDL_EVDEV_device_removed(const char *dev_path);
#if SDL_USE_LIBUDEV
static int SDL_EVDEV_device_added(const char *devpath);
void SDL_EVDEV_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath);
static int SDL_EVDEV_device_added(const char *dev_path, int udev_class);
void SDL_EVDEV_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class,
    const char *dev_path);
#endif /* SDL_USE_LIBUDEV */
static SDL_Scancode EVDEV_Keycodes[] = {
    SDL_SCANCODE_UNKNOWN,       /*  KEY_RESERVED        0 */
    SDL_SCANCODE_ESCAPE,        /*  KEY_ESC         1 */
    SDL_SCANCODE_1,             /*  KEY_1           2 */
    SDL_SCANCODE_2,             /*  KEY_2           3 */
    SDL_SCANCODE_3,             /*  KEY_3           4 */
    SDL_SCANCODE_4,             /*  KEY_4           5 */
    SDL_SCANCODE_5,             /*  KEY_5           6 */
    SDL_SCANCODE_6,             /*  KEY_6           7 */
    SDL_SCANCODE_7,             /*  KEY_7           8 */
    SDL_SCANCODE_8,             /*  KEY_8           9 */
    SDL_SCANCODE_9,             /*  KEY_9           10 */
    SDL_SCANCODE_0,             /*  KEY_0           11 */
    SDL_SCANCODE_MINUS,         /*  KEY_MINUS       12 */
    SDL_SCANCODE_EQUALS,        /*  KEY_EQUAL       13 */
    SDL_SCANCODE_BACKSPACE,     /*  KEY_BACKSPACE       14 */
    SDL_SCANCODE_TAB,           /*  KEY_TAB         15 */
    SDL_SCANCODE_Q,             /*  KEY_Q           16 */
    SDL_SCANCODE_W,             /*  KEY_W           17 */
    SDL_SCANCODE_E,             /*  KEY_E           18 */
    SDL_SCANCODE_R,             /*  KEY_R           19 */
    SDL_SCANCODE_T,             /*  KEY_T           20 */
    SDL_SCANCODE_Y,             /*  KEY_Y           21 */
    SDL_SCANCODE_U,             /*  KEY_U           22 */
    SDL_SCANCODE_I,             /*  KEY_I           23 */
    SDL_SCANCODE_O,             /*  KEY_O           24 */
    SDL_SCANCODE_P,             /*  KEY_P           25 */
    SDL_SCANCODE_LEFTBRACKET,   /*  KEY_LEFTBRACE       26 */
    SDL_SCANCODE_RIGHTBRACKET,  /*  KEY_RIGHTBRACE      27 */
    SDL_SCANCODE_RETURN,        /*  KEY_ENTER       28 */
    SDL_SCANCODE_LCTRL,         /*  KEY_LEFTCTRL        29 */
    SDL_SCANCODE_A,             /*  KEY_A           30 */
    SDL_SCANCODE_S,             /*  KEY_S           31 */
    SDL_SCANCODE_D,             /*  KEY_D           32 */
    SDL_SCANCODE_F,             /*  KEY_F           33 */
    SDL_SCANCODE_G,             /*  KEY_G           34 */
    SDL_SCANCODE_H,             /*  KEY_H           35 */
    SDL_SCANCODE_J,             /*  KEY_J           36 */
    SDL_SCANCODE_K,             /*  KEY_K           37 */
    SDL_SCANCODE_L,             /*  KEY_L           38 */
    SDL_SCANCODE_SEMICOLON,     /*  KEY_SEMICOLON       39 */
    SDL_SCANCODE_APOSTROPHE,    /*  KEY_APOSTROPHE      40 */
    SDL_SCANCODE_GRAVE,         /*  KEY_GRAVE       41 */
    SDL_SCANCODE_LSHIFT,        /*  KEY_LEFTSHIFT       42 */
    SDL_SCANCODE_BACKSLASH,     /*  KEY_BACKSLASH       43 */
    SDL_SCANCODE_Z,             /*  KEY_Z           44 */
    SDL_SCANCODE_X,             /*  KEY_X           45 */
    SDL_SCANCODE_C,             /*  KEY_C           46 */
    SDL_SCANCODE_V,             /*  KEY_V           47 */
    SDL_SCANCODE_B,             /*  KEY_B           48 */
    SDL_SCANCODE_N,             /*  KEY_N           49 */
    SDL_SCANCODE_M,             /*  KEY_M           50 */
    SDL_SCANCODE_COMMA,         /*  KEY_COMMA       51 */
    SDL_SCANCODE_PERIOD,        /*  KEY_DOT         52 */
    SDL_SCANCODE_SLASH,         /*  KEY_SLASH       53 */
    SDL_SCANCODE_RSHIFT,        /*  KEY_RIGHTSHIFT      54 */
    SDL_SCANCODE_KP_MULTIPLY,   /*  KEY_KPASTERISK      55 */
    SDL_SCANCODE_LALT,          /*  KEY_LEFTALT     56 */
    SDL_SCANCODE_SPACE,         /*  KEY_SPACE       57 */
    SDL_SCANCODE_CAPSLOCK,      /*  KEY_CAPSLOCK        58 */
    SDL_SCANCODE_F1,            /*  KEY_F1          59 */
    SDL_SCANCODE_F2,            /*  KEY_F2          60 */
    SDL_SCANCODE_F3,            /*  KEY_F3          61 */
    SDL_SCANCODE_F4,            /*  KEY_F4          62 */
    SDL_SCANCODE_F5,            /*  KEY_F5          63 */
    SDL_SCANCODE_F6,            /*  KEY_F6          64 */
    SDL_SCANCODE_F7,            /*  KEY_F7          65 */
    SDL_SCANCODE_F8,            /*  KEY_F8          66 */
    SDL_SCANCODE_F9,            /*  KEY_F9          67 */
    SDL_SCANCODE_F10,           /*  KEY_F10         68 */
    SDL_SCANCODE_NUMLOCKCLEAR,  /*  KEY_NUMLOCK     69 */
    SDL_SCANCODE_SCROLLLOCK,    /*  KEY_SCROLLLOCK      70 */
    SDL_SCANCODE_KP_7,          /*  KEY_KP7         71 */
    SDL_SCANCODE_KP_8,          /*  KEY_KP8         72 */
    SDL_SCANCODE_KP_9,          /*  KEY_KP9         73 */
    SDL_SCANCODE_KP_MINUS,      /*  KEY_KPMINUS     74 */
    SDL_SCANCODE_KP_4,          /*  KEY_KP4         75 */
    SDL_SCANCODE_KP_5,          /*  KEY_KP5         76 */
    SDL_SCANCODE_KP_6,          /*  KEY_KP6         77 */
    SDL_SCANCODE_KP_PLUS,       /*  KEY_KPPLUS      78 */
    SDL_SCANCODE_KP_1,          /*  KEY_KP1         79 */
    SDL_SCANCODE_KP_2,          /*  KEY_KP2         80 */
    SDL_SCANCODE_KP_3,          /*  KEY_KP3         81 */
    SDL_SCANCODE_KP_0,          /*  KEY_KP0         82 */
    SDL_SCANCODE_KP_PERIOD,     /*  KEY_KPDOT       83 */
    SDL_SCANCODE_UNKNOWN,       /*  84 */
    SDL_SCANCODE_LANG5,         /*  KEY_ZENKAKUHANKAKU  85 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_102ND       86 */
    SDL_SCANCODE_F11,           /*  KEY_F11         87 */
    SDL_SCANCODE_F12,           /*  KEY_F12         88 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_RO          89 */
    SDL_SCANCODE_LANG3,         /*  KEY_KATAKANA        90 */
    SDL_SCANCODE_LANG4,         /*  KEY_HIRAGANA        91 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_HENKAN      92 */
    SDL_SCANCODE_LANG3,         /*  KEY_KATAKANAHIRAGANA    93 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_MUHENKAN        94 */
    SDL_SCANCODE_KP_COMMA,      /*  KEY_KPJPCOMMA       95 */
    SDL_SCANCODE_KP_ENTER,      /*  KEY_KPENTER     96 */
    SDL_SCANCODE_RCTRL,         /*  KEY_RIGHTCTRL       97 */
    SDL_SCANCODE_KP_DIVIDE,     /*  KEY_KPSLASH     98 */
    SDL_SCANCODE_SYSREQ,        /*  KEY_SYSRQ       99 */
    SDL_SCANCODE_RALT,          /*  KEY_RIGHTALT        100 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_LINEFEED        101 */
    SDL_SCANCODE_HOME,          /*  KEY_HOME        102 */
    SDL_SCANCODE_UP,            /*  KEY_UP          103 */
    SDL_SCANCODE_PAGEUP,        /*  KEY_PAGEUP      104 */
    SDL_SCANCODE_LEFT,          /*  KEY_LEFT        105 */
    SDL_SCANCODE_RIGHT,         /*  KEY_RIGHT       106 */
    SDL_SCANCODE_END,           /*  KEY_END         107 */
    SDL_SCANCODE_DOWN,          /*  KEY_DOWN        108 */
    SDL_SCANCODE_PAGEDOWN,      /*  KEY_PAGEDOWN        109 */
    SDL_SCANCODE_INSERT,        /*  KEY_INSERT      110 */
    SDL_SCANCODE_DELETE,        /*  KEY_DELETE      111 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_MACRO       112 */
    SDL_SCANCODE_MUTE,          /*  KEY_MUTE        113 */
    SDL_SCANCODE_VOLUMEDOWN,    /*  KEY_VOLUMEDOWN      114 */
    SDL_SCANCODE_VOLUMEUP,      /*  KEY_VOLUMEUP        115 */
    SDL_SCANCODE_POWER,         /*  KEY_POWER       116 SC System Power Down */
    SDL_SCANCODE_KP_EQUALS,     /*  KEY_KPEQUAL     117 */
    SDL_SCANCODE_KP_MINUS,      /*  KEY_KPPLUSMINUS     118 */
    SDL_SCANCODE_PAUSE,         /*  KEY_PAUSE       119 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_SCALE       120 AL Compiz Scale (Expose) */
    SDL_SCANCODE_KP_COMMA,      /*  KEY_KPCOMMA     121 */
    SDL_SCANCODE_LANG1,         /*  KEY_HANGEUL,KEY_HANGUEL 122 */
    SDL_SCANCODE_LANG2,         /*  KEY_HANJA       123 */
    SDL_SCANCODE_INTERNATIONAL3,/*  KEY_YEN         124 */
    SDL_SCANCODE_LGUI,          /*  KEY_LEFTMETA        125 */
    SDL_SCANCODE_RGUI,          /*  KEY_RIGHTMETA       126 */
    SDL_SCANCODE_APPLICATION,   /*  KEY_COMPOSE     127 */
    SDL_SCANCODE_STOP,          /*  KEY_STOP        128 AC Stop */
    SDL_SCANCODE_AGAIN,         /*  KEY_AGAIN       129 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_PROPS       130 AC Properties */
    SDL_SCANCODE_UNDO,          /*  KEY_UNDO        131 AC Undo */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_FRONT       132 */
    SDL_SCANCODE_COPY,          /*  KEY_COPY        133 AC Copy */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_OPEN        134 AC Open */
    SDL_SCANCODE_PASTE,         /*  KEY_PASTE       135 AC Paste */
    SDL_SCANCODE_FIND,          /*  KEY_FIND        136 AC Search */
    SDL_SCANCODE_CUT,           /*  KEY_CUT         137 AC Cut */
    SDL_SCANCODE_HELP,          /*  KEY_HELP        138 AL Integrated Help Center */
    SDL_SCANCODE_MENU,          /*  KEY_MENU        139 Menu (show menu) */
    SDL_SCANCODE_CALCULATOR,    /*  KEY_CALC        140 AL Calculator */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_SETUP       141 */
    SDL_SCANCODE_SLEEP,         /*  KEY_SLEEP       142 SC System Sleep */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_WAKEUP      143 System Wake Up */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_FILE        144 AL Local Machine Browser */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_SENDFILE        145 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_DELETEFILE      146 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_XFER        147 */
    SDL_SCANCODE_APP1,          /*  KEY_PROG1       148 */
    SDL_SCANCODE_APP1,          /*  KEY_PROG2       149 */
    SDL_SCANCODE_WWW,           /*  KEY_WWW         150 AL Internet Browser */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_MSDOS       151 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_COFFEE,KEY_SCREENLOCK      152 AL Terminal Lock/Screensaver */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_DIRECTION       153 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_CYCLEWINDOWS    154 */
    SDL_SCANCODE_MAIL,          /*  KEY_MAIL        155 */
    SDL_SCANCODE_AC_BOOKMARKS,  /*  KEY_BOOKMARKS       156 AC Bookmarks */
    SDL_SCANCODE_COMPUTER,      /*  KEY_COMPUTER        157 */
    SDL_SCANCODE_AC_BACK,       /*  KEY_BACK        158 AC Back */
    SDL_SCANCODE_AC_FORWARD,    /*  KEY_FORWARD     159 AC Forward */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_CLOSECD     160 */
    SDL_SCANCODE_EJECT,         /*  KEY_EJECTCD     161 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_EJECTCLOSECD    162 */
    SDL_SCANCODE_AUDIONEXT,     /*  KEY_NEXTSONG        163 */
    SDL_SCANCODE_AUDIOPLAY,     /*  KEY_PLAYPAUSE       164 */
    SDL_SCANCODE_AUDIOPREV,     /*  KEY_PREVIOUSSONG    165 */
    SDL_SCANCODE_AUDIOSTOP,     /*  KEY_STOPCD      166 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_RECORD      167 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_REWIND      168 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_PHONE       169 Media Select Telephone */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_ISO         170 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_CONFIG      171 AL Consumer Control Configuration */
    SDL_SCANCODE_AC_HOME,       /*  KEY_HOMEPAGE        172 AC Home */
    SDL_SCANCODE_AC_REFRESH,    /*  KEY_REFRESH     173 AC Refresh */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_EXIT        174 AC Exit */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_MOVE        175 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_EDIT        176 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_SCROLLUP        177 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_SCROLLDOWN      178 */
    SDL_SCANCODE_KP_LEFTPAREN,  /*  KEY_KPLEFTPAREN     179 */
    SDL_SCANCODE_KP_RIGHTPAREN, /*  KEY_KPRIGHTPAREN    180 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_NEW         181 AC New */
    SDL_SCANCODE_AGAIN,         /*  KEY_REDO        182 AC Redo/Repeat */
    SDL_SCANCODE_F13,           /*  KEY_F13         183 */
    SDL_SCANCODE_F14,           /*  KEY_F14         184 */
    SDL_SCANCODE_F15,           /*  KEY_F15         185 */
    SDL_SCANCODE_F16,           /*  KEY_F16         186 */
    SDL_SCANCODE_F17,           /*  KEY_F17         187 */
    SDL_SCANCODE_F18,           /*  KEY_F18         188 */
    SDL_SCANCODE_F19,           /*  KEY_F19         189 */
    SDL_SCANCODE_F20,           /*  KEY_F20         190 */
    SDL_SCANCODE_F21,           /*  KEY_F21         191 */
    SDL_SCANCODE_F22,           /*  KEY_F22         192 */
    SDL_SCANCODE_F23,           /*  KEY_F23         193 */
    SDL_SCANCODE_F24,           /*  KEY_F24         194 */
    SDL_SCANCODE_UNKNOWN,       /*  195 */
    SDL_SCANCODE_UNKNOWN,       /*  196 */
    SDL_SCANCODE_UNKNOWN,       /*  197 */
    SDL_SCANCODE_UNKNOWN,       /*  198 */
    SDL_SCANCODE_UNKNOWN,       /*  199 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_PLAYCD      200 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_PAUSECD     201 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_PROG3       202 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_PROG4       203 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_DASHBOARD       204 AL Dashboard */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_SUSPEND     205 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_CLOSE       206 AC Close */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_PLAY        207 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_FASTFORWARD     208 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_BASSBOOST       209 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_PRINT       210 AC Print */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_HP          211 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_CAMERA      212 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_SOUND       213 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_QUESTION        214 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_EMAIL       215 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_CHAT        216 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_SEARCH      217 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_CONNECT     218 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_FINANCE     219 AL Checkbook/Finance */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_SPORT       220 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_SHOP        221 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_ALTERASE        222 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_CANCEL      223 AC Cancel */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_BRIGHTNESSDOWN  224 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_BRIGHTNESSUP    225 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_MEDIA       226 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_SWITCHVIDEOMODE 227 Cycle between available video outputs (Monitor/LCD/TV-out/etc) */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_KBDILLUMTOGGLE  228 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_KBDILLUMDOWN    229 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_KBDILLUMUP      230 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_SEND        231 AC Send */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_REPLY       232 AC Reply */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_FORWARDMAIL     233 AC Forward Msg */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_SAVE        234 AC Save */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_DOCUMENTS       235 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_BATTERY     236  */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_BLUETOOTH       237 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_WLAN        238 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_UWB         239 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_UNKNOWN     240 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_VIDEO_NEXT      241 drive next video source */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_VIDEO_PREV      242 drive previous video source */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_BRIGHTNESS_CYCLE    243 brightness up, after max is min */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_BRIGHTNESS_ZERO 244 brightness off, use ambient */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_DISPLAY_OFF     245 display device to off state */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_WIMAX       246 */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_RFKILL      247 Key that controls all radios */
    SDL_SCANCODE_UNKNOWN,       /*  KEY_MICMUTE     248 Mute / unmute the microphone */
};
static Uint8 EVDEV_MouseButtons[] = {
    SDL_BUTTON_LEFT,            /*  BTN_LEFT        0x110 */
@@ -342,121 +127,98 @@
};
static const char* EVDEV_consoles[] = {
    "/proc/self/fd/0",
    /* "/proc/self/fd/0",
    "/dev/tty",
    "/dev/tty0",
    "/dev/tty0", */ /* the tty ioctl's prohibit these */
    "/dev/tty1",
    "/dev/tty2",
    "/dev/tty3",
    "/dev/tty4",
    "/dev/tty5",
    "/dev/tty6",
    "/dev/tty7", /* usually X is spawned in tty7 */
    "/dev/vc/0",
    "/dev/console"
};
#define IS_CONSOLE(fd) isatty (fd) && ioctl(fd, KDGKBTYPE, &arg) == 0 && ((arg == KB_101) || (arg == KB_84))
static int SDL_EVDEV_get_console_fd(void)
{
    int fd, i;
    char arg = 0;
static int SDL_EVDEV_is_console(int fd) {
    int type;
    
    /* Try a few consoles to see which one we have read access to */
    for(i = 0; i < SDL_arraysize(EVDEV_consoles); i++) {
        fd = open(EVDEV_consoles[i], O_RDONLY);
        if (fd >= 0) {
            if (IS_CONSOLE(fd)) return fd;
            close(fd);
        }
    }
    /* Try stdin, stdout, stderr */
    for(fd = 0; fd < 3; fd++) {
        if (IS_CONSOLE(fd)) return fd;
    }
    /* We won't be able to send SDL_TEXTINPUT events */
    return -1;
    return isatty(fd) && ioctl(fd, KDGKBTYPE, &type) == 0 &&
        (type == KB_101 || type == KB_84);
}
/* Prevent keystrokes from reaching the tty */
static int SDL_EVDEV_mute_keyboard(int tty, int *kb_mode)
static int SDL_EVDEV_mute_keyboard(int tty_fd, int* old_kb_mode)
{
    char arg;
    *kb_mode = 0; /* FIXME: Is this a sane default in case KDGKBMODE fails? */
    if (!IS_CONSOLE(tty)) {
    if (!SDL_EVDEV_is_console(tty_fd)) {
        return SDL_SetError("Tried to mute an invalid tty");
    }
    ioctl(tty, KDGKBMODE, kb_mode); /* It's not fatal if this fails */
    if (ioctl(tty, KDSKBMUTE, 1) && ioctl(tty, KDSKBMODE, K_OFF)) {
        return SDL_SetError("EVDEV: Failed muting keyboard");
    if (ioctl(tty_fd, KDGKBMODE, old_kb_mode) < 0) {
        return SDL_SetError("Failed to get keyboard mode during muting");
    }
    /* FIXME: atm this absolutely ruins the vt, and KDSKBMUTE isn't implemented
       in the kernel */
    /*
    if (ioctl(tty_fd, KDSKBMODE, K_OFF) < 0) {
        return SDL_SetError("Failed to set keyboard mode during muting");
    }
    */
    
    return 0;  
}
/* Restore the keyboard mode for given tty */
static void SDL_EVDEV_unmute_keyboard(int tty, int kb_mode)
static void SDL_EVDEV_unmute_keyboard(int tty_fd, int kb_mode)
{
    if (ioctl(tty, KDSKBMUTE, 0) && ioctl(tty, KDSKBMODE, kb_mode)) {
        SDL_Log("EVDEV: Failed restoring keyboard mode");
    /* read above */
    /*
    if (ioctl(tty_fd, KDSKBMODE, kb_mode) < 0) {
        SDL_Log("Failed to unmute keyboard");
    }
    */
}
/* Read /sys/class/tty/tty0/active and open the tty */
static int SDL_EVDEV_get_active_tty()
{
    int fd, len;
    char ttyname[NAME_MAX + 1];
    char ttypath[PATH_MAX+1] = "/dev/";
    char arg;
{
    int i, fd, ret, tty = 0;
    char tiocl;
    struct vt_stat vt_state;
    char path[PATH_MAX + 1];
    
    fd = open("/sys/class/tty/tty0/active", O_RDONLY);
    if (fd < 0) {
        return SDL_SetError("Could not determine which tty is active");
    }
    len = read(fd, ttyname, NAME_MAX);
    close(fd);
    if (len <= 0) {
        return SDL_SetError("Could not read which tty is active");
    }
    if (ttyname[len-1] == '\n') {
        ttyname[len-1] = '\0';
    }
    else {
        ttyname[len] = '\0';
    }
    SDL_strlcat(ttypath, ttyname, PATH_MAX);
    fd = open(ttypath, O_RDWR | O_NOCTTY);
    if (fd < 0) {
        return SDL_SetError("Could not open tty: %s", ttypath);
    }
    if (!IS_CONSOLE(fd)) {
    for(i = 0; i < SDL_arraysize(EVDEV_consoles); i++) {
        fd = open(EVDEV_consoles[i], O_RDONLY);
        if (fd < 0 && !SDL_EVDEV_is_console(fd))
            break;
        tiocl = TIOCL_GETFGCONSOLE;
        if ((ret = ioctl(fd, TIOCLINUX, &tiocl)) >= 0)
            tty = ret + 1;
        else if (ioctl(fd, VT_GETSTATE, &vt_state) == 0)
            tty = vt_state.v_active;
        close(fd);
        return SDL_SetError("Invalid tty obtained: %s", ttypath);
        if (tty) {
            sprintf(path, "/dev/tty%u", tty);
            fd = open(path, O_RDONLY);
            if (fd >= 0 && SDL_EVDEV_is_console(fd))
                return fd;
        }
    }
    return fd;
    return SDL_SetError("Failed to determine active tty");
}
int
SDL_EVDEV_Init(void)
{
    int retval = 0;
    if (_this == NULL) {
        _this = (SDL_EVDEV_PrivateData *) SDL_calloc(1, sizeof(*_this));
        if(_this == NULL) {
        _this = (SDL_EVDEV_PrivateData*)SDL_calloc(1, sizeof(*_this));
        if (_this == NULL) {
            return SDL_OutOfMemory();
        }
@@ -469,7 +231,9 @@
        /* Set up the udev callback */
        if (SDL_UDEV_AddCallback(SDL_EVDEV_udev_callback) < 0) {
            SDL_EVDEV_Quit();
            SDL_UDEV_Quit();
            SDL_free(_this);
            _this = NULL;
            return -1;
        }
        
@@ -479,26 +243,18 @@
        /* TODO: Scan the devices manually, like a caveman */
#endif /* SDL_USE_LIBUDEV */
        
        /* We need a physical terminal (not PTS) to be able to translate key code to symbols via the kernel tables */
        _this->console_fd = SDL_EVDEV_get_console_fd();
        /* We need a physical terminal (not PTS) to be able to translate key
           code to symbols via the kernel tables */
        _this->console_fd = SDL_EVDEV_get_active_tty();
        
        /* Mute the keyboard so keystrokes only generate evdev events and do not leak through to the console */
        _this->tty = STDIN_FILENO;
        if (SDL_EVDEV_mute_keyboard(_this->tty, &_this->kb_mode) < 0) {
            /* stdin is not a tty, probably we were launched remotely, so we try to disable the active tty */
            _this->tty = SDL_EVDEV_get_active_tty();
            if (_this->tty >= 0) {
                if (SDL_EVDEV_mute_keyboard(_this->tty, &_this->kb_mode) < 0) {
                    close(_this->tty);
                    _this->tty = -1;
                }
            }
        }
        /* Mute the keyboard so keystrokes only generate evdev events and do not
           leak through to the console */
        SDL_EVDEV_mute_keyboard(_this->console_fd, &_this->kb_mode);
    }
    
    _this->ref_count += 1;
    
    return retval;
    return 0;
}
void
@@ -511,19 +267,14 @@
    _this->ref_count -= 1;
    
    if (_this->ref_count < 1) {
#if SDL_USE_LIBUDEV
        SDL_UDEV_DelCallback(SDL_EVDEV_udev_callback);
        SDL_UDEV_Quit();
#endif /* SDL_USE_LIBUDEV */
       
        if (_this->console_fd >= 0) {
            SDL_EVDEV_unmute_keyboard(_this->console_fd, _this->kb_mode);
            close(_this->console_fd);
        }
        if (_this->tty >= 0) {
            SDL_EVDEV_unmute_keyboard(_this->tty, _this->kb_mode);
            close(_this->tty);
        }
        
        /* Remove existing devices */
@@ -533,7 +284,7 @@
        
        SDL_assert(_this->first == NULL);
        SDL_assert(_this->last == NULL);
        SDL_assert(_this->numdevices == 0);
        SDL_assert(_this->num_devices == 0);
        
        SDL_free(_this);
        _this = NULL;
@@ -541,47 +292,116 @@
}
#if SDL_USE_LIBUDEV
void SDL_EVDEV_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath)
void SDL_EVDEV_udev_callback(SDL_UDEV_deviceevent udev_event, int udev_class,
    const char* dev_path)
{
    if (devpath == NULL) {
    if (dev_path == NULL) {
        return;
    }
    
    switch(udev_type) {
    switch(udev_event) {
    case SDL_UDEV_DEVICEADDED:
        if (!(udev_class & (SDL_UDEV_DEVICE_MOUSE|SDL_UDEV_DEVICE_KEYBOARD))) {
        if (!(udev_class & (SDL_UDEV_DEVICE_MOUSE | SDL_UDEV_DEVICE_KEYBOARD |
            SDL_UDEV_DEVICE_TOUCHSCREEN)))
            return;
        }
        SDL_EVDEV_device_added(devpath);
        break;
        SDL_EVDEV_device_added(dev_path, udev_class);
        break;
    case SDL_UDEV_DEVICEREMOVED:
        SDL_EVDEV_device_removed(devpath);
        SDL_EVDEV_device_removed(dev_path);
        break;
    default:
        break;
    }
}
#endif /* SDL_USE_LIBUDEV */
#ifdef SDL_INPUT_LINUXKD
/* this logic is pulled from kbd_keycode() in drivers/tty/vt/keyboard.c in the
   Linux kernel source */
static void SDL_EVDEV_do_text_input(unsigned short keycode) {
    char shift_state;
    int locks_state;
    struct kbentry kbe;
    unsigned char type;
    char text[2] = { 0 };
    if (_this->console_fd < 0)
        return;
    shift_state = TIOCL_GETSHIFTSTATE;
    if (ioctl(_this->console_fd, TIOCLINUX, &shift_state) < 0) {
        /* TODO: error */
        return;
    }
    kbe.kb_table = shift_state;
    kbe.kb_index = keycode;
    if (ioctl(_this->console_fd, KDGKBENT, &kbe) < 0) {
        /* TODO: error */
        return;
    }
    type = KTYP(kbe.kb_value);
    if (type < 0xf0) {
        /*
         * FIXME: keysyms with a type below 0xf0 represent a unicode character
         * which requires special handling due to dead characters, diacritics,
         * etc. For perfect input a proper way to deal with such characters
         * should be implemented.
         *
         * For reference, the only place I was able to find out about this
         * special 0xf0 value was in an unused? couple of patches listed below.
         *
         * http://ftp.tc.edu.tw/pub/docs/Unicode/utf8/linux-2.3.12-keyboard.diff
         * http://ftp.tc.edu.tw/pub/docs/Unicode/utf8/linux-2.3.12-console.diff
         */
        return;
    }
    type -= 0xf0;
    /* if type is KT_LETTER then it can be affected by Caps Lock */
    if (type == KT_LETTER) {
        type = KT_LATIN;
        if (ioctl(_this->console_fd, KDGKBLED, &locks_state) < 0) {
            /* TODO: error */
            return;
        }
        if (locks_state & K_CAPSLOCK) {
            kbe.kb_table = shift_state ^ (1 << KG_SHIFT);
            if (ioctl(_this->console_fd, KDGKBENT, &kbe) < 0) {
                /* TODO: error */
                return;
            }
        }
    }
    /* TODO: convert values >= 0x80 from ISO-8859-1? to UTF-8 */
    if (type != KT_LATIN || KVAL(kbe.kb_value) >= 0x80)
        return;
    *text = KVAL(kbe.kb_value);
    SDL_SendKeyboardText(text);
}
#endif /* SDL_INPUT_LINUXKD */
void 
SDL_EVDEV_Poll(void)
{
    struct input_event events[32];
    int i, len;
    int i, j, len;
    SDL_evdevlist_item *item;
    SDL_Scancode scan_code;
    int mouse_button;
    SDL_Mouse *mouse;
#ifdef SDL_INPUT_LINUXKD
    Uint16 modstate;
    struct kbentry kbe;
    static char keysym[8];
    char *end;
    Uint32 kval;
#endif
    float norm_x, norm_y;
    if (!_this) {
        return;
@@ -597,6 +417,13 @@
        while ((len = read(item->fd, events, (sizeof events))) > 0) {
            len /= sizeof(events[0]);
            for (i = 0; i < len; ++i) {
                /* special handling for touchscreen, that should eventually be
                   used for all devices */
                if (item->out_of_sync && item->is_touchscreen &&
                    events[i].type == EV_SYN && events[i].code != SYN_REPORT) {
                    break;
                }
                switch (events[i].type) {
                case EV_KEY:
                    if (events[i].code >= BTN_MOUSE && events[i].code < BTN_MOUSE + SDL_arraysize(EVDEV_MouseButtons)) {
@@ -614,57 +441,55 @@
                    if (scan_code != SDL_SCANCODE_UNKNOWN) {
                        if (events[i].value == 0) {
                            SDL_SendKeyboardKey(SDL_RELEASED, scan_code);
                        } else if (events[i].value == 1 || events[i].value == 2 /* Key repeated */) {
                        } else if (events[i].value == 1 || events[i].value == 2 /* key repeated */) {
                            SDL_SendKeyboardKey(SDL_PRESSED, scan_code);
#ifdef SDL_INPUT_LINUXKD
                            if (_this->console_fd >= 0) {
                                kbe.kb_index = events[i].code;
                                /* Convert the key to an UTF-8 char */
                                /* Ref: http://www.linuxjournal.com/article/2783 */
                                modstate = SDL_GetModState();
                                kbe.kb_table = 0;
                                /* Ref: http://graphics.stanford.edu/~seander/bithacks.html#ConditionalSetOrClearBitsWithoutBranching */
                                kbe.kb_table |= -((modstate & KMOD_LCTRL) != 0) & (1 << KG_CTRLL | 1 << KG_CTRL);
                                kbe.kb_table |= -((modstate & KMOD_RCTRL) != 0) & (1 << KG_CTRLR | 1 << KG_CTRL);
                                kbe.kb_table |= -((modstate & KMOD_LSHIFT) != 0) & (1 << KG_SHIFTL | 1 << KG_SHIFT);
                                kbe.kb_table |= -((modstate & KMOD_RSHIFT) != 0) & (1 << KG_SHIFTR | 1 << KG_SHIFT);
                                kbe.kb_table |= -((modstate & KMOD_LALT) != 0) & (1 << KG_ALT);
                                kbe.kb_table |= -((modstate & KMOD_RALT) != 0) & (1 << KG_ALTGR);
                                if (ioctl(_this->console_fd, KDGKBENT, (unsigned long)&kbe) == 0 &&
                                    ((KTYP(kbe.kb_value) == KT_LATIN) || (KTYP(kbe.kb_value) == KT_ASCII) || (KTYP(kbe.kb_value) == KT_LETTER)))
                                {
                                    kval = KVAL(kbe.kb_value);
                                    /* While there's a KG_CAPSSHIFT symbol, it's not useful to build the table index with it
                                     * because 1 << KG_CAPSSHIFT overflows the 8 bits of kb_table
                                     * So, we do the CAPS LOCK logic here. Note that isalpha depends on the locale!
                                     */
                                    if (modstate & KMOD_CAPS && isalpha(kval)) {
                                        if (isupper(kval)) {
                                            kval = tolower(kval);
                                        } else {
                                            kval = toupper(kval);
                                        }
                                    }
                                    /* Convert to UTF-8 and send */
                                    end = SDL_UCS4ToUTF8(kval, keysym);
                                    *end = '\0';
                                    SDL_SendKeyboardText(keysym);
                                }
                            }
                            SDL_EVDEV_do_text_input(events[i].code);
#endif /* SDL_INPUT_LINUXKD */
                        }
                    }
                    break;
                case EV_ABS:
                    switch(events[i].code) {
                    case ABS_MT_SLOT:
                        if (!item->is_touchscreen) /* FIXME: temp hack */
                            break;
                        item->touchscreen_data->current_slot = events[i].value;
                        break;
                    case ABS_MT_TRACKING_ID:
                        if (!item->is_touchscreen) /* FIXME: temp hack */
                            break;
                        if (events[i].value >= 0) {
                            item->touchscreen_data->slots[item->touchscreen_data->current_slot].tracking_id = events[i].value;
                            item->touchscreen_data->slots[item->touchscreen_data->current_slot].delta = EVDEV_TOUCH_SLOTDELTA_DOWN;
                        } else {
                            item->touchscreen_data->slots[item->touchscreen_data->current_slot].delta = EVDEV_TOUCH_SLOTDELTA_UP;
                        }
                        break;
                    case ABS_MT_POSITION_X:
                        if (!item->is_touchscreen) /* FIXME: temp hack */
                            break;
                        item->touchscreen_data->slots[item->touchscreen_data->current_slot].x = events[i].value;
                        if (item->touchscreen_data->slots[item->touchscreen_data->current_slot].delta == EVDEV_TOUCH_SLOTDELTA_NONE) {
                            item->touchscreen_data->slots[item->touchscreen_data->current_slot].delta = EVDEV_TOUCH_SLOTDELTA_MOVE;
                        }
                        break;
                    case ABS_MT_POSITION_Y:
                        if (!item->is_touchscreen) /* FIXME: temp hack */
                            break;
                        item->touchscreen_data->slots[item->touchscreen_data->current_slot].y = events[i].value;
                        if (item->touchscreen_data->slots[item->touchscreen_data->current_slot].delta == EVDEV_TOUCH_SLOTDELTA_NONE) {
                            item->touchscreen_data->slots[item->touchscreen_data->current_slot].delta = EVDEV_TOUCH_SLOTDELTA_MOVE;
                        }
                        break;
                    case ABS_X:
                        if (item->is_touchscreen) /* FIXME: temp hack */
                            break;
                        SDL_SendMouseMotion(mouse->focus, mouse->mouseID, SDL_FALSE, events[i].value, mouse->y);
                        break;
                    case ABS_Y:
                        if (item->is_touchscreen) /* FIXME: temp hack */
                            break;
                        SDL_SendMouseMotion(mouse->focus, mouse->mouseID, SDL_FALSE, mouse->x, events[i].value);
                        break;
                    default:
@@ -691,7 +516,41 @@
                    break;
                case EV_SYN:
                    switch (events[i].code) {
                    case SYN_REPORT:
                        if (!item->is_touchscreen) /* FIXME: temp hack */
                            break;
                        for(j = 0; j < item->touchscreen_data->max_slots; j++) {
                            norm_x = (float)(item->touchscreen_data->slots[j].x - item->touchscreen_data->min_x) /
                                (float)item->touchscreen_data->range_x;
                            norm_y = (float)(item->touchscreen_data->slots[j].y - item->touchscreen_data->min_y) /
                                (float)item->touchscreen_data->range_y;
                            switch(item->touchscreen_data->slots[j].delta) {
                            case EVDEV_TOUCH_SLOTDELTA_DOWN:
                                SDL_SendTouch(item->fd, item->touchscreen_data->slots[j].tracking_id, SDL_TRUE, norm_x, norm_y, 1.0f);
                                item->touchscreen_data->slots[j].delta = EVDEV_TOUCH_SLOTDELTA_NONE;
                                break;
                            case EVDEV_TOUCH_SLOTDELTA_UP:
                                SDL_SendTouch(item->fd, item->touchscreen_data->slots[j].tracking_id, SDL_FALSE, norm_x, norm_y, 1.0f);
                                item->touchscreen_data->slots[j].tracking_id = -1;
                                item->touchscreen_data->slots[j].delta = EVDEV_TOUCH_SLOTDELTA_NONE;
                                break;
                            case EVDEV_TOUCH_SLOTDELTA_MOVE:
                                SDL_SendTouchMotion(item->fd, item->touchscreen_data->slots[j].tracking_id, norm_x, norm_y, 1.0f);
                                item->touchscreen_data->slots[j].delta = EVDEV_TOUCH_SLOTDELTA_NONE;
                                break;
                            default:
                                break;
                            }
                        }
                        if (item->out_of_sync)
                            item->out_of_sync = 0;
                        break;
                    case SYN_DROPPED:
                        if (item->is_touchscreen)
                            item->out_of_sync = 1;
                        SDL_EVDEV_sync_device(item);
                        break;
                    default:
@@ -709,30 +568,227 @@
{
    SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN;
    if (keycode < SDL_arraysize(EVDEV_Keycodes)) {
        scancode = EVDEV_Keycodes[keycode];
    }
    if (keycode < SDL_arraysize(linux_scancode_table))
        scancode = linux_scancode_table[keycode];
    if (scancode == SDL_SCANCODE_UNKNOWN) {
        SDL_Log("The key you just pressed is not recognized by SDL. To help get this fixed, please report this to the SDL mailing list <sdl@libsdl.org> EVDEV KeyCode %d \n", keycode);
        SDL_Log("The key you just pressed is not recognized by SDL. To help "
            "get this fixed, please report this to the SDL mailing list "
            "<sdl@libsdl.org> EVDEV KeyCode %d\n", keycode);
    }
    return scancode;
}
#ifdef SDL_USE_LIBUDEV
static int
SDL_EVDEV_init_touchscreen(SDL_evdevlist_item* item)
{
    int ret, i;
    char name[64];
    struct input_absinfo abs_info;
    if (!item->is_touchscreen)
        return 0;
    item->touchscreen_data = SDL_calloc(1, sizeof(*item->touchscreen_data));
    if (item->touchscreen_data == NULL)
        return SDL_OutOfMemory();
    ret = ioctl(item->fd, EVIOCGNAME(sizeof(name)), name);
    if (ret < 0) {
        SDL_free(item->touchscreen_data);
        return SDL_SetError("Failed to get evdev touchscreen name");
    }
    item->touchscreen_data->name = SDL_strdup(name);
    if (item->touchscreen_data->name == NULL) {
        SDL_free(item->touchscreen_data);
        return SDL_OutOfMemory();
    }
    ret = ioctl(item->fd, EVIOCGABS(ABS_MT_POSITION_X), &abs_info);
    if (ret < 0) {
        SDL_free(item->touchscreen_data->name);
        SDL_free(item->touchscreen_data);
        return SDL_SetError("Failed to get evdev touchscreen limits");
    }
    item->touchscreen_data->min_x = abs_info.minimum;
    item->touchscreen_data->max_x = abs_info.maximum;
    item->touchscreen_data->range_x = abs_info.maximum - abs_info.minimum;
    ret = ioctl(item->fd, EVIOCGABS(ABS_MT_POSITION_Y), &abs_info);
    if (ret < 0) {
        SDL_free(item->touchscreen_data->name);
        SDL_free(item->touchscreen_data);
        return SDL_SetError("Failed to get evdev touchscreen limits");
    }
    item->touchscreen_data->min_y = abs_info.minimum;
    item->touchscreen_data->max_y = abs_info.maximum;
    item->touchscreen_data->range_y = abs_info.maximum - abs_info.minimum;
    ret = ioctl(item->fd, EVIOCGABS(ABS_MT_SLOT), &abs_info);
    if (ret < 0) {
        SDL_free(item->touchscreen_data->name);
        SDL_free(item->touchscreen_data);
        return SDL_SetError("Failed to get evdev touchscreen limits");
    }
    item->touchscreen_data->max_slots = abs_info.maximum + 1;
    item->touchscreen_data->slots = SDL_calloc(
        item->touchscreen_data->max_slots,
        sizeof(*item->touchscreen_data->slots));
    if (item->touchscreen_data->slots == NULL) {
        SDL_free(item->touchscreen_data->name);
        SDL_free(item->touchscreen_data);
        return SDL_OutOfMemory();
    }
    for(i = 0; i < item->touchscreen_data->max_slots; i++) {
        item->touchscreen_data->slots[i].tracking_id = -1;
    }
    ret = SDL_AddTouch(item->fd, /* I guess our fd is unique enough */
        item->touchscreen_data->name);
    if (ret < 0) {
        SDL_free(item->touchscreen_data->slots);
        SDL_free(item->touchscreen_data->name);
        SDL_free(item->touchscreen_data);
        return ret;
    }
    return 0;
}
#endif /* SDL_USE_LIBUDEV */
static void
SDL_EVDEV_destroy_touchscreen(SDL_evdevlist_item* item) {
    if (!item->is_touchscreen)
        return;
    SDL_DelTouch(item->fd);
    SDL_free(item->touchscreen_data->slots);
    SDL_free(item->touchscreen_data->name);
    SDL_free(item->touchscreen_data);
}
static void
SDL_EVDEV_sync_device(SDL_evdevlist_item *item) 
{
    /* TODO: get full state of device and report whatever is required */
#ifdef EVIOCGMTSLOTS
    int i, ret;
    struct input_absinfo abs_info;
    /*
     * struct input_mt_request_layout {
     *     __u32 code;
     *     __s32 values[num_slots];
     * };
     *
     * this is the structure we're trying to emulate
     */
    __u32* mt_req_code;
    __s32* mt_req_values;
    size_t mt_req_size;
    /* TODO: sync devices other than touchscreen */
    if (!item->is_touchscreen)
        return;
    mt_req_size = sizeof(*mt_req_code) +
        sizeof(*mt_req_values) * item->touchscreen_data->max_slots;
    mt_req_code = SDL_calloc(1, mt_req_size);
    if (mt_req_code == NULL) {
        return;
    }
    mt_req_values = (__s32*)mt_req_code + 1;
    *mt_req_code = ABS_MT_TRACKING_ID;
    ret = ioctl(item->fd, EVIOCGMTSLOTS(mt_req_size), mt_req_code);
    if (ret < 0) {
        SDL_free(mt_req_code);
        return;
    }
    for(i = 0; i < item->touchscreen_data->max_slots; i++) {
        /*
         * This doesn't account for the very edge case of the user removing their
         * finger and replacing it on the screen during the time we're out of sync,
         * which'll mean that we're not going from down -> up or up -> down, we're
         * going from down -> down but with a different tracking id, meaning we'd
         * have to tell SDL of the two events, but since we wait till SYN_REPORT in
         * SDL_EVDEV_Poll to tell SDL, the current structure of this code doesn't
         * allow it. Lets just pray to God it doesn't happen.
         */
        if (item->touchscreen_data->slots[i].tracking_id < 0 &&
            mt_req_values[i] >= 0) {
            item->touchscreen_data->slots[i].tracking_id = mt_req_values[i];
            item->touchscreen_data->slots[i].delta = EVDEV_TOUCH_SLOTDELTA_DOWN;
        } else if (item->touchscreen_data->slots[i].tracking_id >= 0 &&
            mt_req_values[i] < 0) {
            item->touchscreen_data->slots[i].tracking_id = -1;
            item->touchscreen_data->slots[i].delta = EVDEV_TOUCH_SLOTDELTA_UP;
        }
    }
    *mt_req_code = ABS_MT_POSITION_X;
    ret = ioctl(item->fd, EVIOCGMTSLOTS(mt_req_size), mt_req_code);
    if (ret < 0) {
        SDL_free(mt_req_code);
        return;
    }
    for(i = 0; i < item->touchscreen_data->max_slots; i++) {
        if (item->touchscreen_data->slots[i].tracking_id >= 0 &&
            item->touchscreen_data->slots[i].x != mt_req_values[i]) {
            item->touchscreen_data->slots[i].x = mt_req_values[i];
            if (item->touchscreen_data->slots[i].delta ==
                EVDEV_TOUCH_SLOTDELTA_NONE) {
                item->touchscreen_data->slots[i].delta =
                    EVDEV_TOUCH_SLOTDELTA_MOVE;
            }
        }
    }
    *mt_req_code = ABS_MT_POSITION_Y;
    ret = ioctl(item->fd, EVIOCGMTSLOTS(mt_req_size), mt_req_code);
    if (ret < 0) {
        SDL_free(mt_req_code);
        return;
    }
    for(i = 0; i < item->touchscreen_data->max_slots; i++) {
        if (item->touchscreen_data->slots[i].tracking_id >= 0 &&
            item->touchscreen_data->slots[i].y != mt_req_values[i]) {
            item->touchscreen_data->slots[i].y = mt_req_values[i];
            if (item->touchscreen_data->slots[i].delta ==
                EVDEV_TOUCH_SLOTDELTA_NONE) {
                item->touchscreen_data->slots[i].delta =
                    EVDEV_TOUCH_SLOTDELTA_MOVE;
            }
        }
    }
    ret = ioctl(item->fd, EVIOCGABS(ABS_MT_SLOT), &abs_info);
    if (ret < 0) {
        SDL_free(mt_req_code);
        return;
    }
    item->touchscreen_data->current_slot = abs_info.value;
    SDL_free(mt_req_code);
#endif /* EVIOCGMTSLOTS */
}
#if SDL_USE_LIBUDEV
static int
SDL_EVDEV_device_added(const char *devpath)
SDL_EVDEV_device_added(const char *dev_path, int udev_class)
{
    int ret;
    SDL_evdevlist_item *item;
    /* Check to make sure it's not already in list. */
    for (item = _this->first; item != NULL; item = item->next) {
        if (SDL_strcmp(devpath, item->path) == 0) {
        if (SDL_strcmp(dev_path, item->path) == 0) {
            return -1;  /* already have this one */
        }
    }
@@ -742,21 +798,28 @@
        return SDL_OutOfMemory();
    }
    item->fd = open(devpath, O_RDONLY, 0);
    item->fd = open(dev_path, O_RDONLY | O_NONBLOCK);
    if (item->fd < 0) {
        SDL_free(item);
        return SDL_SetError("Unable to open %s", devpath);
        return SDL_SetError("Unable to open %s", dev_path);
    }
    
    item->path = SDL_strdup(devpath);
    item->path = SDL_strdup(dev_path);
    if (item->path == NULL) {
        close(item->fd);
        SDL_free(item);
        return SDL_OutOfMemory();
    }
    
    /* Non blocking read mode */
    fcntl(item->fd, F_SETFL, O_NONBLOCK);
    if (udev_class & SDL_UDEV_DEVICE_TOUCHSCREEN) {
        item->is_touchscreen = 1;
        if ((ret = SDL_EVDEV_init_touchscreen(item)) < 0) {
            close(item->fd);
            SDL_free(item);
            return ret;
        }
    }
    
    if (_this->last == NULL) {
        _this->first = _this->last = item;
@@ -767,19 +830,19 @@
    
    SDL_EVDEV_sync_device(item);
    
    return _this->numdevices++;
    return _this->num_devices++;
}
#endif /* SDL_USE_LIBUDEV */
static int
SDL_EVDEV_device_removed(const char *devpath)
SDL_EVDEV_device_removed(const char *dev_path)
{
    SDL_evdevlist_item *item;
    SDL_evdevlist_item *prev = NULL;
    for (item = _this->first; item != NULL; item = item->next) {
        /* found it, remove it. */
        if (SDL_strcmp(devpath, item->path) == 0) {
        if (SDL_strcmp(dev_path, item->path) == 0) {
            if (prev != NULL) {
                prev->next = item->next;
            } else {
@@ -789,10 +852,13 @@
            if (item == _this->last) {
                _this->last = prev;
            }
            if (item->is_touchscreen) {
                SDL_EVDEV_destroy_touchscreen(item);
            }
            close(item->fd);
            SDL_free(item->path);
            SDL_free(item);
            _this->numdevices--;
            _this->num_devices--;
            return 0;
        }
        prev = item;
@@ -805,4 +871,3 @@
#endif /* SDL_INPUT_LINUXEV */
/* vi: set ts=4 sw=4 expandtab: */
source/src/core/linux/SDL_evdev.h
@@ -27,30 +27,10 @@
#ifdef SDL_INPUT_LINUXEV
#include "SDL_events.h"
#include <sys/stat.h>
typedef struct SDL_evdevlist_item
{
    char *path;
    int fd;
    struct SDL_evdevlist_item *next;
} SDL_evdevlist_item;
typedef struct SDL_EVDEV_PrivateData
{
    SDL_evdevlist_item *first;
    SDL_evdevlist_item *last;
    int numdevices;
    int ref_count;
    int console_fd;
    int kb_mode;
    int tty;
} SDL_EVDEV_PrivateData;
extern int SDL_EVDEV_Init(void);
extern void SDL_EVDEV_Quit(void);
extern void SDL_EVDEV_Poll(void);
#endif /* SDL_INPUT_LINUXEV */
source/src/core/linux/SDL_fcitx.c
New file
@@ -0,0 +1,553 @@
/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
  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"
#ifdef HAVE_FCITX_FRONTEND_H
#include <fcitx/frontend.h>
#include <unistd.h>
#include "SDL_fcitx.h"
#include "SDL_keycode.h"
#include "SDL_keyboard.h"
#include "../../events/SDL_keyboard_c.h"
#include "SDL_dbus.h"
#include "SDL_syswm.h"
#if SDL_VIDEO_DRIVER_X11
#  include "../../video/x11/SDL_x11video.h"
#endif
#include "SDL_hints.h"
#define FCITX_DBUS_SERVICE "org.fcitx.Fcitx"
#define FCITX_IM_DBUS_PATH "/inputmethod"
#define FCITX_IC_DBUS_PATH "/inputcontext_%d"
#define FCITX_IM_DBUS_INTERFACE "org.fcitx.Fcitx.InputMethod"
#define FCITX_IC_DBUS_INTERFACE "org.fcitx.Fcitx.InputContext"
#define IC_NAME_MAX 64
#define DBUS_TIMEOUT 500
typedef struct _FcitxClient
{
    SDL_DBusContext *dbus;
    char servicename[IC_NAME_MAX];
    char icname[IC_NAME_MAX];
    int id;
    SDL_Rect cursor_rect;
} FcitxClient;
static FcitxClient fcitx_client;
static int
GetDisplayNumber()
{
    const char *display = SDL_getenv("DISPLAY");
    const char *p = NULL;
    int number = 0;
    if (display == NULL)
        return 0;
    display = SDL_strchr(display, ':');
    if (display == NULL)
        return 0;
    display++;
    p = SDL_strchr(display, '.');
    if (p == NULL && display != NULL) {
        number = SDL_strtod(display, NULL);
    } else {
        char *buffer = SDL_strdup(display);
        buffer[p - display] = '\0';
        number = SDL_strtod(buffer, NULL);
        SDL_free(buffer);
    }
    return number;
}
static char*
GetAppName()
{
#if defined(__LINUX__) || defined(__FREEBSD__)
    char *spot;
    char procfile[1024];
    char linkfile[1024];
    int linksize;
#if defined(__LINUX__)
    SDL_snprintf(procfile, sizeof(procfile), "/proc/%d/exe", getpid());
#elif defined(__FREEBSD__)
    SDL_snprintf(procfile, sizeof(procfile), "/proc/%d/file", getpid());
#endif
    linksize = readlink(procfile, linkfile, sizeof(linkfile) - 1);
    if (linksize > 0) {
        linkfile[linksize] = '\0';
        spot = SDL_strrchr(linkfile, '/');
        if (spot) {
            return SDL_strdup(spot + 1);
        } else {
            return SDL_strdup(linkfile);
        }
    }
#endif /* __LINUX__ || __FREEBSD__ */
    return SDL_strdup("SDL_App");
}
/*
 * Copied from fcitx source
 */
#define CONT(i)   ISUTF8_CB(in[i])
#define VAL(i, s) ((in[i]&0x3f) << s)
static char *
_fcitx_utf8_get_char(const char *i, uint32_t *chr)
{
    const unsigned char* in = (const unsigned char *)i;
    if (!(in[0] & 0x80)) {
        *(chr) = *(in);
        return (char *)in + 1;
    }
    /* 2-byte, 0x80-0x7ff */
    if ((in[0] & 0xe0) == 0xc0 && CONT(1)) {
        *chr = ((in[0] & 0x1f) << 6) | VAL(1, 0);
        return (char *)in + 2;
    }
    /* 3-byte, 0x800-0xffff */
    if ((in[0] & 0xf0) == 0xe0 && CONT(1) && CONT(2)) {
        *chr = ((in[0] & 0xf) << 12) | VAL(1, 6) | VAL(2, 0);
        return (char *)in + 3;
    }
    /* 4-byte, 0x10000-0x1FFFFF */
    if ((in[0] & 0xf8) == 0xf0 && CONT(1) && CONT(2) && CONT(3)) {
        *chr = ((in[0] & 0x7) << 18) | VAL(1, 12) | VAL(2, 6) | VAL(3, 0);
        return (char *)in + 4;
    }
    /* 5-byte, 0x200000-0x3FFFFFF */
    if ((in[0] & 0xfc) == 0xf8 && CONT(1) && CONT(2) && CONT(3) && CONT(4)) {
        *chr = ((in[0] & 0x3) << 24) | VAL(1, 18) | VAL(2, 12) | VAL(3, 6) | VAL(4, 0);
        return (char *)in + 5;
    }
    /* 6-byte, 0x400000-0x7FFFFFF */
    if ((in[0] & 0xfe) == 0xfc && CONT(1) && CONT(2) && CONT(3) && CONT(4) && CONT(5)) {
        *chr = ((in[0] & 0x1) << 30) | VAL(1, 24) | VAL(2, 18) | VAL(3, 12) | VAL(4, 6) | VAL(5, 0);
        return (char *)in + 6;
    }
    *chr = *in;
    return (char *)in + 1;
}
static size_t
_fcitx_utf8_strlen(const char *s)
{
    unsigned int l = 0;
    while (*s) {
        uint32_t chr;
        s = _fcitx_utf8_get_char(s, &chr);
        l++;
    }
    return l;
}
static DBusHandlerResult
DBus_MessageFilter(DBusConnection *conn, DBusMessage *msg, void *data)
{
    SDL_DBusContext *dbus = (SDL_DBusContext *)data;
    if (dbus->message_is_signal(msg, FCITX_IC_DBUS_INTERFACE, "CommitString")) {
        DBusMessageIter iter;
        const char *text = NULL;
        dbus->message_iter_init(msg, &iter);
        dbus->message_iter_get_basic(&iter, &text);
        if (text)
            SDL_SendKeyboardText(text);
        return DBUS_HANDLER_RESULT_HANDLED;
    }
    if (dbus->message_is_signal(msg, FCITX_IC_DBUS_INTERFACE, "UpdatePreedit")) {
        DBusMessageIter iter;
        const char *text;
        dbus->message_iter_init(msg, &iter);
        dbus->message_iter_get_basic(&iter, &text);
        if (text && *text) {
            char buf[SDL_TEXTEDITINGEVENT_TEXT_SIZE];
            size_t text_bytes = SDL_strlen(text), i = 0;
            size_t cursor = 0;
            while (i < text_bytes) {
                size_t sz = SDL_utf8strlcpy(buf, text + i, sizeof(buf));
                size_t chars = _fcitx_utf8_strlen(buf);
                SDL_SendEditingText(buf, cursor, chars);
                i += sz;
                cursor += chars;
            }
        }
        SDL_Fcitx_UpdateTextRect(NULL);
        return DBUS_HANDLER_RESULT_HANDLED;
    }
    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
static DBusMessage*
FcitxClientICNewMethod(FcitxClient *client,
        const char *method)
{
    SDL_DBusContext *dbus = client->dbus;
    return dbus->message_new_method_call(
            client->servicename,
            client->icname,
            FCITX_IC_DBUS_INTERFACE,
            method);
}
static void
FcitxClientICCallMethod(FcitxClient *client,
        const char *method)
{
    SDL_DBusContext *dbus = client->dbus;
    DBusMessage *msg = FcitxClientICNewMethod(client, method);
    if (msg == NULL)
        return ;
    if (dbus->connection_send(dbus->session_conn, msg, NULL)) {
        dbus->connection_flush(dbus->session_conn);
    }
    dbus->message_unref(msg);
}
static void
Fcitx_SetCapabilities(void *data,
        const char *name,
        const char *old_val,
        const char *internal_editing)
{
    FcitxClient *client = (FcitxClient *)data;
    SDL_DBusContext *dbus = client->dbus;
    Uint32 caps = CAPACITY_NONE;
    DBusMessage *msg = FcitxClientICNewMethod(client, "SetCapacity");
    if (msg == NULL)
        return ;
    if (!(internal_editing && *internal_editing == '1')) {
        caps |= CAPACITY_PREEDIT;
    }
    dbus->message_append_args(msg,
            DBUS_TYPE_UINT32, &caps,
            DBUS_TYPE_INVALID);
    if (dbus->connection_send(dbus->session_conn, msg, NULL)) {
        dbus->connection_flush(dbus->session_conn);
    }
    dbus->message_unref(msg);
}
static void
FcitxClientCreateIC(FcitxClient *client)
{
    char *appname = NULL;
    pid_t pid = 0;
    int id = 0;
    SDL_bool enable;
    Uint32 arg1, arg2, arg3, arg4;
    SDL_DBusContext *dbus = client->dbus;
    DBusMessage *reply = NULL;
    DBusMessage *msg = dbus->message_new_method_call(
            client->servicename,
            FCITX_IM_DBUS_PATH,
            FCITX_IM_DBUS_INTERFACE,
            "CreateICv3"
            );
    if (msg == NULL)
        return ;
    appname = GetAppName();
    pid = getpid();
    dbus->message_append_args(msg,
            DBUS_TYPE_STRING, &appname,
            DBUS_TYPE_INT32, &pid,
            DBUS_TYPE_INVALID);
    do {
        reply = dbus->connection_send_with_reply_and_block(
                dbus->session_conn,
                msg,
                DBUS_TIMEOUT,
                NULL);
        if (!reply)
            break;
        if (!dbus->message_get_args(reply, NULL,
                DBUS_TYPE_INT32, &id,
                DBUS_TYPE_BOOLEAN, &enable,
                DBUS_TYPE_UINT32, &arg1,
                DBUS_TYPE_UINT32, &arg2,
                DBUS_TYPE_UINT32, &arg3,
                DBUS_TYPE_UINT32, &arg4,
                DBUS_TYPE_INVALID))
            break;
        if (id < 0)
            break;
        client->id = id;
        SDL_snprintf(client->icname, IC_NAME_MAX,
                FCITX_IC_DBUS_PATH, client->id);
        dbus->bus_add_match(dbus->session_conn,
                "type='signal', interface='org.fcitx.Fcitx.InputContext'",
                NULL);
        dbus->connection_add_filter(dbus->session_conn,
                &DBus_MessageFilter, dbus,
                NULL);
        dbus->connection_flush(dbus->session_conn);
        SDL_AddHintCallback(SDL_HINT_IME_INTERNAL_EDITING, &Fcitx_SetCapabilities, client);
    }
    while (0);
    if (reply)
        dbus->message_unref(reply);
    dbus->message_unref(msg);
    SDL_free(appname);
}
static Uint32
Fcitx_ModState(void)
{
    Uint32 fcitx_mods = 0;
    SDL_Keymod sdl_mods = SDL_GetModState();
    if (sdl_mods & KMOD_SHIFT) fcitx_mods |= FcitxKeyState_Shift;
    if (sdl_mods & KMOD_CAPS)   fcitx_mods |= FcitxKeyState_CapsLock;
    if (sdl_mods & KMOD_CTRL)  fcitx_mods |= FcitxKeyState_Ctrl;
    if (sdl_mods & KMOD_ALT)   fcitx_mods |= FcitxKeyState_Alt;
    if (sdl_mods & KMOD_NUM)    fcitx_mods |= FcitxKeyState_NumLock;
    if (sdl_mods & KMOD_LGUI)   fcitx_mods |= FcitxKeyState_Super;
    if (sdl_mods & KMOD_RGUI)   fcitx_mods |= FcitxKeyState_Meta;
    return fcitx_mods;
}
SDL_bool
SDL_Fcitx_Init()
{
    fcitx_client.dbus = SDL_DBus_GetContext();
    fcitx_client.cursor_rect.x = -1;
    fcitx_client.cursor_rect.y = -1;
    fcitx_client.cursor_rect.w = 0;
    fcitx_client.cursor_rect.h = 0;
    SDL_snprintf(fcitx_client.servicename, IC_NAME_MAX,
            "%s-%d",
            FCITX_DBUS_SERVICE, GetDisplayNumber());
    FcitxClientCreateIC(&fcitx_client);
    return SDL_TRUE;
}
void
SDL_Fcitx_Quit()
{
    FcitxClientICCallMethod(&fcitx_client, "DestroyIC");
}
void
SDL_Fcitx_SetFocus(SDL_bool focused)
{
    if (focused) {
        FcitxClientICCallMethod(&fcitx_client, "FocusIn");
    } else {
        FcitxClientICCallMethod(&fcitx_client, "FocusOut");
    }
}
void
SDL_Fcitx_Reset(void)
{
    FcitxClientICCallMethod(&fcitx_client, "Reset");
    FcitxClientICCallMethod(&fcitx_client, "CloseIC");
}
SDL_bool
SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode)
{
    DBusMessage *msg = NULL;
    DBusMessage *reply = NULL;
    SDL_DBusContext *dbus = fcitx_client.dbus;
    Uint32 state = 0;
    SDL_bool handled = SDL_FALSE;
    int type = FCITX_PRESS_KEY;
    Uint32 event_time = 0;
    msg = FcitxClientICNewMethod(&fcitx_client, "ProcessKeyEvent");
    if (msg == NULL)
        return SDL_FALSE;
    state = Fcitx_ModState();
    dbus->message_append_args(msg,
            DBUS_TYPE_UINT32, &keysym,
            DBUS_TYPE_UINT32, &keycode,
            DBUS_TYPE_UINT32, &state,
            DBUS_TYPE_INT32, &type,
            DBUS_TYPE_UINT32, &event_time,
            DBUS_TYPE_INVALID);
    reply = dbus->connection_send_with_reply_and_block(dbus->session_conn,
            msg,
            -1,
            NULL);
    if (reply) {
        dbus->message_get_args(reply,
                NULL,
                DBUS_TYPE_INT32, &handled,
                DBUS_TYPE_INVALID);
        dbus->message_unref(reply);
    }
    if (handled) {
        SDL_Fcitx_UpdateTextRect(NULL);
    }
    return handled;
}
void
SDL_Fcitx_UpdateTextRect(SDL_Rect *rect)
{
    SDL_Window *focused_win = NULL;
    SDL_SysWMinfo info;
    int x = 0, y = 0;
    SDL_Rect *cursor = &fcitx_client.cursor_rect;
    SDL_DBusContext *dbus = fcitx_client.dbus;
    DBusMessage *msg = NULL;
    DBusConnection *conn;
    if (rect) {
        SDL_memcpy(cursor, rect, sizeof(SDL_Rect));
    }
    focused_win = SDL_GetKeyboardFocus();
    if (!focused_win) {
        return ;
    }
    SDL_VERSION(&info.version);
    if (!SDL_GetWindowWMInfo(focused_win, &info)) {
        return;
    }
    SDL_GetWindowPosition(focused_win, &x, &y);
#if SDL_VIDEO_DRIVER_X11
    if (info.subsystem == SDL_SYSWM_X11) {
        SDL_DisplayData *displaydata = (SDL_DisplayData *) SDL_GetDisplayForWindow(focused_win)->driverdata;
        Display *x_disp = info.info.x11.display;
        Window x_win = info.info.x11.window;
        int x_screen = displaydata->screen;
        Window unused;
        X11_XTranslateCoordinates(x_disp, x_win, RootWindow(x_disp, x_screen), 0, 0, &x, &y, &unused);
    }
#endif
    if (cursor->x == -1 && cursor->y == -1 && cursor->w == 0 && cursor->h == 0) {
        // move to bottom left
        int w = 0, h = 0;
        SDL_GetWindowSize(focused_win, &w, &h);
        cursor->x = 0;
        cursor->y = h;
    }
    x += cursor->x;
    y += cursor->y;
    msg = FcitxClientICNewMethod(&fcitx_client, "SetCursorRect");
    if (msg == NULL)
        return ;
    dbus->message_append_args(msg,
            DBUS_TYPE_INT32, &x,
            DBUS_TYPE_INT32, &y,
            DBUS_TYPE_INT32, &cursor->w,
            DBUS_TYPE_INT32, &cursor->h,
            DBUS_TYPE_INVALID);
    conn = dbus->session_conn;
    if (dbus->connection_send(conn, msg, NULL))
        dbus->connection_flush(conn);
    dbus->message_unref(msg);
}
void
SDL_Fcitx_PumpEvents()
{
    SDL_DBusContext *dbus = fcitx_client.dbus;
    DBusConnection *conn = dbus->session_conn;
    dbus->connection_read_write(conn, 0);
    while (dbus->connection_dispatch(conn) == DBUS_DISPATCH_DATA_REMAINS) {
        /* Do nothing, actual work happens in DBus_MessageFilter */
        usleep(10);
    }
}
#endif /* HAVE_FCITX_FRONTEND_H */
/* vi: set ts=4 sw=4 expandtab: */
source/src/core/linux/SDL_fcitx.h
copy from source/src/audio/SDL_audiomem.h copy to source/src/core/linux/SDL_fcitx.h
File was copied from source/src/audio/SDL_audiomem.h
@@ -18,8 +18,23 @@
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
*/
#include "../SDL_internal.h"
#define SDL_AllocAudioMem   SDL_malloc
#define SDL_FreeAudioMem    SDL_free
#ifndef _SDL_fcitx_h
#define _SDL_fcitx_h
#include "../../SDL_internal.h"
#include "SDL_stdinc.h"
#include "SDL_rect.h"
extern SDL_bool SDL_Fcitx_Init(void);
extern void SDL_Fcitx_Quit(void);
extern void SDL_Fcitx_SetFocus(SDL_bool focused);
extern void SDL_Fcitx_Reset(void);
extern SDL_bool SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode);
extern void SDL_Fcitx_UpdateTextRect(SDL_Rect *rect);
extern void SDL_Fcitx_PumpEvents();
#endif /* _SDL_fcitx_h */
/* vi: set ts=4 sw=4 expandtab: */
source/src/core/linux/SDL_ibus.c
@@ -42,7 +42,7 @@
static const char IBUS_INPUT_INTERFACE[] = "org.freedesktop.IBus.InputContext";
static char *input_ctx_path = NULL;
static SDL_Rect ibus_cursor_rect = {0};
static SDL_Rect ibus_cursor_rect = { 0, 0, 0, 0 };
static DBusConnection *ibus_conn = NULL;
static char *ibus_addr_file = NULL;
int inotify_fd = -1, inotify_wd = -1;
@@ -341,7 +341,9 @@
    const char *path = NULL;
    SDL_bool result = SDL_FALSE;
    DBusMessage *msg;
    DBusObjectPathVTable ibus_vtable = {0};
    DBusObjectPathVTable ibus_vtable;
    SDL_zero(ibus_vtable);
    ibus_vtable.message_function = &IBus_MessageHandler;
    ibus_conn = dbus->connection_open_private(addr, NULL);
source/src/core/linux/SDL_ime.c
New file
@@ -0,0 +1,138 @@
/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
  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_ime.h"
#include "SDL_ibus.h"
#include "SDL_fcitx.h"
typedef SDL_bool (*_SDL_IME_Init)();
typedef void (*_SDL_IME_Quit)();
typedef void (*_SDL_IME_SetFocus)(SDL_bool);
typedef void (*_SDL_IME_Reset)();
typedef SDL_bool (*_SDL_IME_ProcessKeyEvent)(Uint32, Uint32);
typedef void (*_SDL_IME_UpdateTextRect)(SDL_Rect *);
typedef void (*_SDL_IME_PumpEvents)();
static _SDL_IME_Init SDL_IME_Init_Real = NULL;
static _SDL_IME_Quit SDL_IME_Quit_Real = NULL;
static _SDL_IME_SetFocus SDL_IME_SetFocus_Real = NULL;
static _SDL_IME_Reset SDL_IME_Reset_Real = NULL;
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 SDL_bool inited = SDL_FALSE;
#ifdef HAVE_FCITX_FRONTEND_H
    const char *im_module = SDL_getenv("SDL_IM_MODULE");
    const char *xmodifiers = SDL_getenv("XMODIFIERS");
#endif
    if (inited == SDL_TRUE)
        return;
    inited = SDL_TRUE;
    /* See if fcitx IME support is being requested */
#ifdef HAVE_FCITX_FRONTEND_H
    if (!SDL_IME_Init_Real &&
        ((im_module && SDL_strcmp(im_module, "fcitx") == 0) ||
         (!im_module && xmodifiers && SDL_strstr(xmodifiers, "@im=fcitx") != NULL))) {
        SDL_IME_Init_Real = SDL_Fcitx_Init;
        SDL_IME_Quit_Real = SDL_Fcitx_Quit;
        SDL_IME_SetFocus_Real = SDL_Fcitx_SetFocus;
        SDL_IME_Reset_Real = SDL_Fcitx_Reset;
        SDL_IME_ProcessKeyEvent_Real = SDL_Fcitx_ProcessKeyEvent;
        SDL_IME_UpdateTextRect_Real = SDL_Fcitx_UpdateTextRect;
        SDL_IME_PumpEvents_Real = SDL_Fcitx_PumpEvents;
    }
#endif /* HAVE_FCITX_FRONTEND_H */
    /* default to IBus */
#ifdef HAVE_IBUS_IBUS_H
    if (!SDL_IME_Init_Real) {
        SDL_IME_Init_Real = SDL_IBus_Init;
        SDL_IME_Quit_Real = SDL_IBus_Quit;
        SDL_IME_SetFocus_Real = SDL_IBus_SetFocus;
        SDL_IME_Reset_Real = SDL_IBus_Reset;
        SDL_IME_ProcessKeyEvent_Real = SDL_IBus_ProcessKeyEvent;
        SDL_IME_UpdateTextRect_Real = SDL_IBus_UpdateTextRect;
        SDL_IME_PumpEvents_Real = SDL_IBus_PumpEvents;
    }
#endif /* HAVE_IBUS_IBUS_H */
}
SDL_bool
SDL_IME_Init(void)
{
    InitIME();
    if (SDL_IME_Init_Real)
        return SDL_IME_Init_Real();
    return SDL_FALSE;
}
void
SDL_IME_Quit(void)
{
    if (SDL_IME_Quit_Real)
        SDL_IME_Quit_Real();
}
void
SDL_IME_SetFocus(SDL_bool focused)
{
    if (SDL_IME_SetFocus_Real)
        SDL_IME_SetFocus_Real(focused);
}
void
SDL_IME_Reset(void)
{
    if (SDL_IME_Reset_Real)
        SDL_IME_Reset_Real();
}
SDL_bool
SDL_IME_ProcessKeyEvent(Uint32 keysym, Uint32 keycode)
{
    if (SDL_IME_ProcessKeyEvent_Real)
        return SDL_IME_ProcessKeyEvent_Real(keysym, keycode);
    return SDL_FALSE;
}
void
SDL_IME_UpdateTextRect(SDL_Rect *rect)
{
    if (SDL_IME_UpdateTextRect_Real)
        SDL_IME_UpdateTextRect_Real(rect);
}
void
SDL_IME_PumpEvents()
{
    if (SDL_IME_PumpEvents_Real)
        SDL_IME_PumpEvents_Real();
}
source/src/core/linux/SDL_ime.h
copy from source/src/audio/SDL_audiomem.h copy to source/src/core/linux/SDL_ime.h
File was copied from source/src/audio/SDL_audiomem.h
@@ -18,8 +18,21 @@
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
*/
#include "../SDL_internal.h"
#define SDL_AllocAudioMem   SDL_malloc
#define SDL_FreeAudioMem    SDL_free
/* vi: set ts=4 sw=4 expandtab: */
#ifndef _SDL_ime_h
#define _SDL_ime_h
#include "../../SDL_internal.h"
#include "SDL_stdinc.h"
#include "SDL_rect.h"
extern SDL_bool SDL_IME_Init();
extern void SDL_IME_Quit();
extern void SDL_IME_SetFocus(SDL_bool focused);
extern void SDL_IME_Reset();
extern SDL_bool SDL_IME_ProcessKeyEvent(Uint32 keysym, Uint32 keycode);
extern void SDL_IME_UpdateTextRect(SDL_Rect *rect);
extern void SDL_IME_PumpEvents();
#endif /* _SDL_ime_h */
source/src/core/linux/SDL_udev.c
@@ -349,7 +349,9 @@
        } else if (test_bit(BTN_MOUSE, bitmask_key)) {
            devclass |= SDL_UDEV_DEVICE_MOUSE; /* ID_INPUT_MOUSE */
        } else if (test_bit(BTN_TOUCH, bitmask_key)) {
            ; /* ID_INPUT_TOUCHSCREEN */
            /* TODO: better determining between touchscreen and multitouch touchpad,
               see https://github.com/systemd/systemd/blob/master/src/udev/udev-builtin-input_id.c */
            devclass |= SDL_UDEV_DEVICE_TOUCHSCREEN; /* ID_INPUT_TOUCHSCREEN */
        }
        if (test_bit(BTN_TRIGGER, bitmask_key) ||
@@ -411,6 +413,11 @@
        if (val != NULL && SDL_strcmp(val, "1") == 0 ) {
            devclass |= SDL_UDEV_DEVICE_MOUSE;
        }
        val = _this->udev_device_get_property_value(dev, "ID_INPUT_TOUCHSCREEN");
        if (val != NULL && SDL_strcmp(val, "1") == 0 ) {
            devclass |= SDL_UDEV_DEVICE_TOUCHSCREEN;
        }
        /* The undocumented rule is:
           - All devices with keys get ID_INPUT_KEY
source/src/core/linux/SDL_udev.h
@@ -42,17 +42,19 @@
typedef enum
{
    SDL_UDEV_DEVICEADDED = 0x0001,
    SDL_UDEV_DEVICEADDED = 1,
    SDL_UDEV_DEVICEREMOVED
} SDL_UDEV_deviceevent;
/* A device can be any combination of these classes */
typedef enum
{
    SDL_UDEV_DEVICE_UNKNOWN     = 0x0000,
    SDL_UDEV_DEVICE_MOUSE       = 0x0001,
    SDL_UDEV_DEVICE_KEYBOARD    = 0x0002,
    SDL_UDEV_DEVICE_JOYSTICK    = 0x0004,
    SDL_UDEV_DEVICE_SOUND       = 0x0008
    SDL_UDEV_DEVICE_SOUND       = 0x0008,
    SDL_UDEV_DEVICE_TOUCHSCREEN = 0x0010
} SDL_UDEV_deviceclass;
typedef void (*SDL_UDEV_Callback)(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath);
source/src/core/windows/SDL_windows.c
@@ -124,6 +124,84 @@
#endif
}
/*
WAVExxxCAPS gives you 31 bytes for the device name, and just truncates if it's
longer. However, since WinXP, you can use the WAVExxxCAPS2 structure, which
will give you a name GUID. The full name is in the Windows Registry under
that GUID, located here: HKLM\System\CurrentControlSet\Control\MediaCategories
Note that drivers can report GUID_NULL for the name GUID, in which case,
Windows makes a best effort to fill in those 31 bytes in the usual place.
This info summarized from MSDN:
http://web.archive.org/web/20131027093034/http://msdn.microsoft.com/en-us/library/windows/hardware/ff536382(v=vs.85).aspx
Always look this up in the registry if possible, because the strings are
different! At least on Win10, I see "Yeti Stereo Microphone" in the
Registry, and a unhelpful "Microphone(Yeti Stereo Microph" in winmm. Sigh.
(Also, DirectSound shouldn't be limited to 32 chars, but its device enum
has the same problem.)
*/
char *
WIN_LookupAudioDeviceName(const WCHAR *name, const GUID *guid)
{
#if __WINRT__
    return WIN_StringToUTF8(name);  /* No registry access on WinRT/UWP, go with what we've got. */
#else
    static const GUID nullguid = { 0 };
    const unsigned char *ptr;
    char keystr[128];
    WCHAR *strw = NULL;
    SDL_bool rc;
    HKEY hkey;
    DWORD len = 0;
    char *retval = NULL;
    if (SDL_memcmp(guid, &nullguid, sizeof (*guid)) == 0) {
        return WIN_StringToUTF8(name);  /* No GUID, go with what we've got. */
    }
    ptr = (const unsigned char *) guid;
    SDL_snprintf(keystr, sizeof (keystr),
        "System\\CurrentControlSet\\Control\\MediaCategories\\{%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
        ptr[3], ptr[2], ptr[1], ptr[0], ptr[5], ptr[4], ptr[7], ptr[6],
        ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13], ptr[14], ptr[15]);
    strw = WIN_UTF8ToString(keystr);
    rc = (RegOpenKeyExW(HKEY_LOCAL_MACHINE, strw, 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS);
    SDL_free(strw);
    if (!rc) {
        return WIN_StringToUTF8(name);  /* oh well. */
    }
    rc = (RegQueryValueExW(hkey, L"Name", NULL, NULL, NULL, &len) == ERROR_SUCCESS);
    if (!rc) {
        RegCloseKey(hkey);
        return WIN_StringToUTF8(name);  /* oh well. */
    }
    strw = (WCHAR *) SDL_malloc(len + sizeof (WCHAR));
    if (!strw) {
        RegCloseKey(hkey);
        return WIN_StringToUTF8(name);  /* oh well. */
    }
    rc = (RegQueryValueExW(hkey, L"Name", NULL, NULL, (LPBYTE) strw, &len) == ERROR_SUCCESS);
    RegCloseKey(hkey);
    if (!rc) {
        SDL_free(strw);
        return WIN_StringToUTF8(name);  /* oh well. */
    }
    strw[len / 2] = 0;  /* make sure it's null-terminated. */
    retval = WIN_StringToUTF8(strw);
    SDL_free(strw);
    return retval ? retval : WIN_StringToUTF8(name);
#endif /* if __WINRT__ / else */
}
#endif /* __WIN32__ || __WINRT__ */
/* vi: set ts=4 sw=4 expandtab: */
source/src/core/windows/SDL_windows.h
@@ -59,6 +59,9 @@
/* Returns SDL_TRUE if we're running on Windows Vista and newer */
extern BOOL WIN_IsWindowsVistaOrGreater();
/* You need to SDL_free() the result of this call. */
extern char *WIN_LookupAudioDeviceName(const WCHAR *name, const GUID *guid);
#endif /* _INCLUDED_WINDOWS_H */
/* vi: set ts=4 sw=4 expandtab: */
source/src/core/winrt/SDL_winrtapp_direct3d.cpp
@@ -254,6 +254,18 @@
    CoreApplication::Exiting +=
        ref new EventHandler<Platform::Object^>(this, &SDL_WinRTApp::OnExiting);
#if NTDDI_VERSION >= NTDDI_WIN10
    /* HACK ALERT!  Xbox One doesn't seem to detect gamepads unless something
       gets registered to receive Win10's Windows.Gaming.Input.Gamepad.GamepadAdded
       events.  We'll register an event handler for these events here, to make
       sure that gamepad detection works later on, if requested.
    */
    Windows::Gaming::Input::Gamepad::GamepadAdded +=
        ref new Windows::Foundation::EventHandler<Windows::Gaming::Input::Gamepad^>(
            this, &SDL_WinRTApp::OnGamepadAdded
        );
#endif
}
#if NTDDI_VERSION > NTDDI_WIN8
@@ -810,11 +822,8 @@
    SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_AC_BACK);
    SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_AC_BACK);
    const char *hint = SDL_GetHint(SDL_HINT_WINRT_HANDLE_BACK_BUTTON);
    if (hint) {
        if (*hint == '1') {
            args->Handled = true;
        }
    if (SDL_GetHintBoolean(SDL_HINT_WINRT_HANDLE_BACK_BUTTON, SDL_FALSE)) {
        args->Handled = true;
    }
}
@@ -832,3 +841,15 @@
}
#endif
#if NTDDI_VERSION >= NTDDI_WIN10
void SDL_WinRTApp::OnGamepadAdded(Platform::Object ^sender, Windows::Gaming::Input::Gamepad ^gamepad)
{
    /* HACK ALERT: Nothing needs to be done here, as this method currently
       only exists to allow something to be registered with Win10's
       GamepadAdded event, an operation that seems to be necessary to get
       Xinput-based detection to work on Xbox One.
    */
}
#endif
/* vi: set ts=4 sw=4 expandtab: */
source/src/core/winrt/SDL_winrtapp_direct3d.h
@@ -80,6 +80,10 @@
    void OnBackButtonPressed(Platform::Object^ sender, Windows::Phone::UI::Input::BackPressedEventArgs^ args);
#endif
#if NTDDI_VERSION >= NTDDI_WIN10
    void OnGamepadAdded(Platform::Object ^sender, Windows::Gaming::Input::Gamepad ^gamepad);
#endif
private:
    bool m_windowClosed;
    bool m_windowVisible;
source/src/dynapi/SDL_dynapi.c
@@ -293,7 +293,7 @@
     *  SDL_CreateThread() would also call this function before building the
     *  new thread).
     */
    static volatile SDL_bool already_initialized = SDL_FALSE;
    static SDL_bool already_initialized = SDL_FALSE;
    /* SDL_AtomicLock calls SDL mutex functions to emulate if
       SDL_ATOMIC_DISABLED, which we can't do here, so in such a
source/src/dynapi/SDL_dynapi.h
@@ -43,9 +43,15 @@
#include "TargetConditionals.h"
#endif
#if TARGET_OS_IPHONE || __native_client__ || __EMSCRIPTEN__  /* probably not useful on iOS, NACL or Emscripten. */
#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE  /* probably not useful on iOS. */
#define SDL_DYNAMIC_API 0
#elif SDL_BUILDING_WINRT /* probaly not useful on WinRT, given current .dll loading restrictions */
#elif defined(__native_client__) && __native_client__  /* probably not useful on NACL. */
#define SDL_DYNAMIC_API 0
#elif defined(__EMSCRIPTEN__) && __EMSCRIPTEN__  /* probably not useful on Emscripten. */
#define SDL_DYNAMIC_API 0
#elif defined(SDL_BUILDING_WINRT) && SDL_BUILDING_WINRT  /* probably not useful on WinRT, given current .dll loading restrictions */
#define SDL_DYNAMIC_API 0
#elif defined(__PSP__) && __PSP__
#define SDL_DYNAMIC_API 0
#elif defined(__clang_analyzer__)
#define SDL_DYNAMIC_API 0  /* Turn off for static analysis, so reports are more clear. */
source/src/dynapi/SDL_dynapi_overrides.h
@@ -445,6 +445,8 @@
#define SDL_iconv_close SDL_iconv_close_REAL
#define SDL_iconv SDL_iconv_REAL
#define SDL_iconv_string SDL_iconv_string_REAL
#define SDL_CreateRGBSurfaceWithFormat SDL_CreateRGBSurfaceWithFormat_REAL
#define SDL_CreateRGBSurfaceWithFormatFrom SDL_CreateRGBSurfaceWithFormatFrom_REAL
#define SDL_CreateRGBSurface SDL_CreateRGBSurface_REAL
#define SDL_CreateRGBSurfaceFrom SDL_CreateRGBSurfaceFrom_REAL
#define SDL_FreeSurface SDL_FreeSurface_REAL
@@ -597,3 +599,16 @@
#define SDL_JoystickCurrentPowerLevel SDL_JoystickCurrentPowerLevel_REAL
#define SDL_GameControllerFromInstanceID SDL_GameControllerFromInstanceID_REAL
#define SDL_JoystickFromInstanceID SDL_JoystickFromInstanceID_REAL
#define SDL_GetDisplayUsableBounds SDL_GetDisplayUsableBounds_REAL
#define SDL_GetWindowBordersSize SDL_GetWindowBordersSize_REAL
#define SDL_SetWindowOpacity SDL_SetWindowOpacity_REAL
#define SDL_GetWindowOpacity SDL_GetWindowOpacity_REAL
#define SDL_SetWindowInputFocus SDL_SetWindowInputFocus_REAL
#define SDL_SetWindowModalFor SDL_SetWindowModalFor_REAL
#define SDL_RenderSetIntegerScale SDL_RenderSetIntegerScale_REAL
#define SDL_RenderGetIntegerScale SDL_RenderGetIntegerScale_REAL
#define SDL_DequeueAudio SDL_DequeueAudio_REAL
#define SDL_SetWindowResizable SDL_SetWindowResizable_REAL
#define SDL_CreateRGBSurfaceWithFormat SDL_CreateRGBSurfaceWithFormat_REAL
#define SDL_CreateRGBSurfaceWithFormatFrom SDL_CreateRGBSurfaceWithFormatFrom_REAL
#define SDL_GetHintBoolean SDL_GetHintBoolean_REAL
source/src/dynapi/SDL_dynapi_procs.h
@@ -631,3 +631,16 @@
SDL_DYNAPI_PROC(SDL_JoystickPowerLevel,SDL_JoystickCurrentPowerLevel,(SDL_Joystick *a),(a),return)
SDL_DYNAPI_PROC(SDL_GameController*,SDL_GameControllerFromInstanceID,(SDL_JoystickID a),(a),return)
SDL_DYNAPI_PROC(SDL_Joystick*,SDL_JoystickFromInstanceID,(SDL_JoystickID a),(a),return)
SDL_DYNAPI_PROC(int,SDL_GetDisplayUsableBounds,(int a, SDL_Rect *b),(a,b),return)
SDL_DYNAPI_PROC(int,SDL_GetWindowBordersSize,(SDL_Window *a, int *b, int *c, int *d, int *e),(a,b,c,d,e),return)
SDL_DYNAPI_PROC(int,SDL_SetWindowOpacity,(SDL_Window *a, float b),(a,b),return)
SDL_DYNAPI_PROC(int,SDL_GetWindowOpacity,(SDL_Window *a, float *b),(a,b),return)
SDL_DYNAPI_PROC(int,SDL_SetWindowInputFocus,(SDL_Window *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_SetWindowModalFor,(SDL_Window *a, SDL_Window *b),(a,b),return)
SDL_DYNAPI_PROC(int,SDL_RenderSetIntegerScale,(SDL_Renderer *a, SDL_bool b),(a,b),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_RenderGetIntegerScale,(SDL_Renderer *a),(a),return)
SDL_DYNAPI_PROC(Uint32,SDL_DequeueAudio,(SDL_AudioDeviceID a, void *b, Uint32 c),(a,b,c),return)
SDL_DYNAPI_PROC(void,SDL_SetWindowResizable,(SDL_Window *a, SDL_bool b),(a,b),)
SDL_DYNAPI_PROC(SDL_Surface*,SDL_CreateRGBSurfaceWithFormat,(Uint32 a, int b, int c, int d, Uint32 e),(a,b,c,d,e),return)
SDL_DYNAPI_PROC(SDL_Surface*,SDL_CreateRGBSurfaceWithFormatFrom,(void *a, int b, int c, int d, int e, Uint32 f),(a,b,c,d,e,f),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_GetHintBoolean,(const char *a, SDL_bool b),(a,b),return)
source/src/events/SDL_dropevents.c
@@ -26,21 +26,73 @@
#include "SDL_events_c.h"
#include "SDL_dropevents_c.h"
#include "../video/SDL_sysvideo.h"  /* for SDL_Window internals. */
int
SDL_SendDropFile(const char *file)
static int
SDL_SendDrop(SDL_Window *window, const SDL_EventType evtype, const char *data)
{
    int posted;
    static SDL_bool app_is_dropping = SDL_FALSE;
    int posted = 0;
    /* Post the event, if desired */
    posted = 0;
    if (SDL_GetEventState(SDL_DROPFILE) == SDL_ENABLE) {
    if (SDL_GetEventState(evtype) == SDL_ENABLE) {
        const SDL_bool need_begin = window ? !window->is_dropping : !app_is_dropping;
        SDL_Event event;
        event.type = SDL_DROPFILE;
        event.drop.file = SDL_strdup(file);
        if (need_begin) {
            SDL_zero(event);
            event.type = SDL_DROPBEGIN;
            if (window) {
                event.drop.windowID = window->id;
            }
            posted = (SDL_PushEvent(&event) > 0);
            if (!posted) {
                return 0;
            }
            if (window) {
                window->is_dropping = SDL_TRUE;
            } else {
                app_is_dropping = SDL_TRUE;
            }
        }
        SDL_zero(event);
        event.type = evtype;
        event.drop.file = data ? SDL_strdup(data) : NULL;
        event.drop.windowID = window ? window->id : 0;
        posted = (SDL_PushEvent(&event) > 0);
        if (posted && (evtype == SDL_DROPCOMPLETE)) {
            if (window) {
                window->is_dropping = SDL_FALSE;
            } else {
                app_is_dropping = SDL_FALSE;
            }
        }
    }
    return (posted);
    return posted;
}
int
SDL_SendDropFile(SDL_Window *window, const char *file)
{
    return SDL_SendDrop(window, SDL_DROPFILE, file);
}
int
SDL_SendDropText(SDL_Window *window, const char *text)
{
    return SDL_SendDrop(window, SDL_DROPTEXT, text);
}
int
SDL_SendDropComplete(SDL_Window *window)
{
    return SDL_SendDrop(window, SDL_DROPCOMPLETE, NULL);
}
/* vi: set ts=4 sw=4 expandtab: */
source/src/events/SDL_dropevents_c.h
@@ -23,7 +23,9 @@
#ifndef _SDL_dropevents_c_h
#define _SDL_dropevents_c_h
extern int SDL_SendDropFile(const char *file);
extern int SDL_SendDropFile(SDL_Window *window, const char *file);
extern int SDL_SendDropText(SDL_Window *window, const char *text);
extern int SDL_SendDropComplete(SDL_Window *window);
#endif /* _SDL_dropevents_c_h */
source/src/events/SDL_events.c
@@ -73,15 +73,15 @@
static struct
{
    SDL_mutex *lock;
    volatile SDL_bool active;
    volatile int count;
    volatile int max_events_seen;
    SDL_atomic_t active;
    SDL_atomic_t count;
    int max_events_seen;
    SDL_EventEntry *head;
    SDL_EventEntry *tail;
    SDL_EventEntry *free;
    SDL_SysWMEntry *wmmsg_used;
    SDL_SysWMEntry *wmmsg_free;
} SDL_EventQ = { NULL, SDL_TRUE, 0, 0, NULL, NULL, NULL, NULL, NULL };
} SDL_EventQ = { NULL, { 1 }, { 0 }, 0, NULL, NULL, NULL, NULL, NULL };
/* Public functions */
@@ -98,7 +98,7 @@
        SDL_LockMutex(SDL_EventQ.lock);
    }
    SDL_EventQ.active = SDL_FALSE;
    SDL_AtomicSet(&SDL_EventQ.active, 0);
    if (report && SDL_atoi(report)) {
        SDL_Log("SDL EVENT QUEUE: Maximum events in-flight: %d\n",
@@ -127,7 +127,7 @@
        wmmsg = next;
    }
    SDL_EventQ.count = 0;
    SDL_AtomicSet(&SDL_EventQ.count, 0);
    SDL_EventQ.max_events_seen = 0;
    SDL_EventQ.head = NULL;
    SDL_EventQ.tail = NULL;
@@ -171,7 +171,7 @@
        SDL_EventQ.lock = SDL_CreateMutex();
    }
    if (SDL_EventQ.lock == NULL) {
        return (-1);
        return -1;
    }
#endif /* !SDL_THREADS_DISABLED */
@@ -180,9 +180,9 @@
    SDL_EventState(SDL_TEXTEDITING, SDL_DISABLE);
    SDL_EventState(SDL_SYSWMEVENT, SDL_DISABLE);
    SDL_EventQ.active = SDL_TRUE;
    SDL_AtomicSet(&SDL_EventQ.active, 1);
    return (0);
    return 0;
}
@@ -191,9 +191,11 @@
SDL_AddEvent(SDL_Event * event)
{
    SDL_EventEntry *entry;
    const int initial_count = SDL_AtomicGet(&SDL_EventQ.count);
    int final_count;
    if (SDL_EventQ.count >= SDL_MAX_QUEUED_EVENTS) {
        SDL_SetError("Event queue is full (%d events)", SDL_EventQ.count);
    if (initial_count >= SDL_MAX_QUEUED_EVENTS) {
        SDL_SetError("Event queue is full (%d events)", initial_count);
        return 0;
    }
@@ -225,10 +227,10 @@
        entry->prev = NULL;
        entry->next = NULL;
    }
    ++SDL_EventQ.count;
    if (SDL_EventQ.count > SDL_EventQ.max_events_seen) {
        SDL_EventQ.max_events_seen = SDL_EventQ.count;
    final_count = SDL_AtomicAdd(&SDL_EventQ.count, 1) + 1;
    if (final_count > SDL_EventQ.max_events_seen) {
        SDL_EventQ.max_events_seen = final_count;
    }
    return 1;
@@ -256,8 +258,8 @@
    entry->next = SDL_EventQ.free;
    SDL_EventQ.free = entry;
    SDL_assert(SDL_EventQ.count > 0);
    --SDL_EventQ.count;
    SDL_assert(SDL_AtomicGet(&SDL_EventQ.count) > 0);
    SDL_AtomicAdd(&SDL_EventQ.count, -1);
}
/* Lock the event queue, take a peep at it, and unlock it */
@@ -268,7 +270,7 @@
    int i, used;
    /* Don't look after we've quit */
    if (!SDL_EventQ.active) {
    if (!SDL_AtomicGet(&SDL_EventQ.active)) {
        /* We get a few spurious events at shutdown, so don't warn then */
        if (action != SDL_ADDEVENT) {
            SDL_SetError("The event system has been shut down");
@@ -285,56 +287,54 @@
        } else {
            SDL_EventEntry *entry, *next;
            SDL_SysWMEntry *wmmsg, *wmmsg_next;
            SDL_Event tmpevent;
            Uint32 type;
            /* If 'events' is NULL, just see if they exist */
            if (events == NULL) {
                action = SDL_PEEKEVENT;
                numevents = 1;
                events = &tmpevent;
            if (action == SDL_GETEVENT) {
                /* Clean out any used wmmsg data
                   FIXME: Do we want to retain the data for some period of time?
                 */
                for (wmmsg = SDL_EventQ.wmmsg_used; wmmsg; wmmsg = wmmsg_next) {
                    wmmsg_next = wmmsg->next;
                    wmmsg->next = SDL_EventQ.wmmsg_free;
                    SDL_EventQ.wmmsg_free = wmmsg;
                }
                SDL_EventQ.wmmsg_used = NULL;
            }
            /* Clean out any used wmmsg data
               FIXME: Do we want to retain the data for some period of time?
             */
            for (wmmsg = SDL_EventQ.wmmsg_used; wmmsg; wmmsg = wmmsg_next) {
                wmmsg_next = wmmsg->next;
                wmmsg->next = SDL_EventQ.wmmsg_free;
                SDL_EventQ.wmmsg_free = wmmsg;
            }
            SDL_EventQ.wmmsg_used = NULL;
            for (entry = SDL_EventQ.head; entry && used < numevents; entry = next) {
            for (entry = SDL_EventQ.head; entry && (!events || used < numevents); entry = next) {
                next = entry->next;
                type = entry->event.type;
                if (minType <= type && type <= maxType) {
                    events[used] = entry->event;
                    if (entry->event.type == SDL_SYSWMEVENT) {
                        /* We need to copy the wmmsg somewhere safe.
                           For now we'll guarantee it's valid at least until
                           the next call to SDL_PeepEvents()
                         */
                        if (SDL_EventQ.wmmsg_free) {
                            wmmsg = SDL_EventQ.wmmsg_free;
                            SDL_EventQ.wmmsg_free = wmmsg->next;
                        } else {
                            wmmsg = (SDL_SysWMEntry *)SDL_malloc(sizeof(*wmmsg));
                    if (events) {
                        events[used] = entry->event;
                        if (entry->event.type == SDL_SYSWMEVENT) {
                            /* We need to copy the wmmsg somewhere safe.
                               For now we'll guarantee it's valid at least until
                               the next call to SDL_PeepEvents()
                             */
                            if (SDL_EventQ.wmmsg_free) {
                                wmmsg = SDL_EventQ.wmmsg_free;
                                SDL_EventQ.wmmsg_free = wmmsg->next;
                            } else {
                                wmmsg = (SDL_SysWMEntry *)SDL_malloc(sizeof(*wmmsg));
                            }
                            wmmsg->msg = *entry->event.syswm.msg;
                            wmmsg->next = SDL_EventQ.wmmsg_used;
                            SDL_EventQ.wmmsg_used = wmmsg;
                            events[used].syswm.msg = &wmmsg->msg;
                        }
                        wmmsg->msg = *entry->event.syswm.msg;
                        wmmsg->next = SDL_EventQ.wmmsg_used;
                        SDL_EventQ.wmmsg_used = wmmsg;
                        events[used].syswm.msg = &wmmsg->msg;
                        if (action == SDL_GETEVENT) {
                            SDL_CutEvent(entry);
                        }
                    }
                    ++used;
                    if (action == SDL_GETEVENT) {
                        SDL_CutEvent(entry);
                    }
                }
            }
        }
        SDL_UnlockMutex(SDL_EventQ.lock);
        if (SDL_EventQ.lock) {
            SDL_UnlockMutex(SDL_EventQ.lock);
        }
    } else {
        return SDL_SetError("Couldn't lock event queue");
    }
@@ -363,7 +363,7 @@
SDL_FlushEvents(Uint32 minType, Uint32 maxType)
{
    /* Don't look after we've quit */
    if (!SDL_EventQ.active) {
    if (!SDL_AtomicGet(&SDL_EventQ.active)) {
        return;
    }
@@ -376,7 +376,7 @@
#endif
    /* Lock the event queue */
    if (SDL_LockMutex(SDL_EventQ.lock) == 0) {
    if (SDL_EventQ.lock && SDL_LockMutex(SDL_EventQ.lock) == 0) {
        SDL_EventEntry *entry, *next;
        Uint32 type;
        for (entry = SDL_EventQ.head; entry; entry = next) {
@@ -437,8 +437,6 @@
        switch (SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) {
        case -1:
            return 0;
        case 1:
            return 1;
        case 0:
            if (timeout == 0) {
                /* Polling and no events, just return */
@@ -450,6 +448,9 @@
            }
            SDL_Delay(10);
            break;
        default:
            /* Has events */
            return 1;
        }
    }
}
source/src/events/SDL_gesture.c
@@ -21,7 +21,7 @@
#include "../SDL_internal.h"
/* General mouse handling code for SDL */
/* General gesture handling code for SDL */
#include "SDL_events.h"
#include "SDL_endian.h"
source/src/events/SDL_mouse.c
@@ -322,15 +322,13 @@
    return &mouse->clickstate[button];
}
int
SDL_SendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8 button)
static int
SDL_PrivateSendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8 button, int clicks)
{
    SDL_Mouse *mouse = SDL_GetMouse();
    int posted;
    Uint32 type;
    Uint32 buttonstate = mouse->buttonstate;
    SDL_MouseClickState *clickstate = GetMouseClickState(mouse, button);
    Uint8 click_count;
    /* Figure out which event to perform */
    switch (state) {
@@ -358,25 +356,28 @@
    }
    mouse->buttonstate = buttonstate;
    if (clickstate) {
        if (state == SDL_PRESSED) {
            Uint32 now = SDL_GetTicks();
    if (clicks < 0) {
        SDL_MouseClickState *clickstate = GetMouseClickState(mouse, button);
        if (clickstate) {
            if (state == SDL_PRESSED) {
                Uint32 now = SDL_GetTicks();
            if (SDL_TICKS_PASSED(now, clickstate->last_timestamp + SDL_double_click_time) ||
                SDL_abs(mouse->x - clickstate->last_x) > SDL_double_click_radius ||
                SDL_abs(mouse->y - clickstate->last_y) > SDL_double_click_radius) {
                clickstate->click_count = 0;
                if (SDL_TICKS_PASSED(now, clickstate->last_timestamp + SDL_double_click_time) ||
                    SDL_abs(mouse->x - clickstate->last_x) > SDL_double_click_radius ||
                    SDL_abs(mouse->y - clickstate->last_y) > SDL_double_click_radius) {
                    clickstate->click_count = 0;
                }
                clickstate->last_timestamp = now;
                clickstate->last_x = mouse->x;
                clickstate->last_y = mouse->y;
                if (clickstate->click_count < 255) {
                    ++clickstate->click_count;
                }
            }
            clickstate->last_timestamp = now;
            clickstate->last_x = mouse->x;
            clickstate->last_y = mouse->y;
            if (clickstate->click_count < 255) {
                ++clickstate->click_count;
            }
            clicks = clickstate->click_count;
        } else {
            clicks = 1;
        }
        click_count = clickstate->click_count;
    } else {
        click_count = 1;
    }
    /* Post the event, if desired */
@@ -388,7 +389,7 @@
        event.button.which = mouseID;
        event.button.state = state;
        event.button.button = button;
        event.button.clicks = click_count;
        event.button.clicks = (Uint8) SDL_min(clicks, 255);
        event.button.x = mouse->x;
        event.button.y = mouse->y;
        posted = (SDL_PushEvent(&event) > 0);
@@ -398,8 +399,21 @@
    if (window && state == SDL_RELEASED) {
        SDL_UpdateMouseFocus(window, mouse->x, mouse->y, buttonstate);
    }
    return posted;
}
int
SDL_SendMouseButtonClicks(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8 button, int clicks)
{
    clicks = SDL_max(clicks, 0);
    return SDL_PrivateSendMouseButton(window, mouseID, state, button, clicks);
}
int
SDL_SendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8 button)
{
    return SDL_PrivateSendMouseButton(window, mouseID, state, button, -1);
}
int
@@ -550,21 +564,11 @@
static SDL_bool
ShouldUseRelativeModeWarp(SDL_Mouse *mouse)
{
    const char *hint;
    if (!mouse->SetRelativeMouseMode) {
        return SDL_TRUE;
    }
    hint = SDL_GetHint(SDL_HINT_MOUSE_RELATIVE_MODE_WARP);
    if (hint) {
        if (*hint == '0') {
            return SDL_FALSE;
        } else {
            return SDL_TRUE;
        }
    }
    return SDL_FALSE;
    return SDL_GetHintBoolean(SDL_HINT_MOUSE_RELATIVE_MODE_WARP, SDL_FALSE);
}
int
source/src/events/SDL_mouse_c.h
@@ -119,6 +119,9 @@
/* Send a mouse button event */
extern int SDL_SendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8 button);
/* Send a mouse button event with a click count */
extern int SDL_SendMouseButtonClicks(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8 button, int clicks);
/* Send a mouse wheel event */
extern int SDL_SendMouseWheel(SDL_Window * window, SDL_MouseID mouseID, int x, int y, SDL_MouseWheelDirection direction);
source/src/events/SDL_quit.c
@@ -91,9 +91,7 @@
int
SDL_QuitInit(void)
{
    const char *hint = SDL_GetHint(SDL_HINT_NO_SIGNAL_HANDLERS);
    disable_signals = hint && (SDL_atoi(hint) == 1);
    if (!disable_signals) {
    if (!SDL_GetHintBoolean(SDL_HINT_NO_SIGNAL_HANDLERS, SDL_FALSE)) {
        return SDL_QuitInit_Internal();
    }
    return 0;
source/src/events/SDL_windowevents.c
@@ -70,6 +70,20 @@
    return 1;
}
static int
RemovePendingExposedEvents(void * userdata, SDL_Event *event)
{
    SDL_Event *new_event = (SDL_Event *)userdata;
    if (event->type == SDL_WINDOWEVENT &&
        event->window.event == SDL_WINDOWEVENT_EXPOSED &&
        event->window.windowID == new_event->window.windowID) {
        /* We're about to post a new exposed event, drop the old one */
        return 0;
    }
    return 1;
}
int
SDL_SendWindowEvent(SDL_Window * window, Uint8 windowevent, int data1,
                    int data2)
@@ -195,7 +209,9 @@
        if (windowevent == SDL_WINDOWEVENT_MOVED) {
            SDL_FilterEvents(RemovePendingMoveEvents, &event);
        }
        if (windowevent == SDL_WINDOWEVENT_EXPOSED) {
            SDL_FilterEvents(RemovePendingExposedEvents, &event);
        }
        posted = (SDL_PushEvent(&event) > 0);
    }
source/src/events/scancodes_linux.h
@@ -111,7 +111,7 @@
    /*  82 */    SDL_SCANCODE_KP_0,
    /*  83 */    SDL_SCANCODE_KP_PERIOD,
    0,
    /*  85 */    SDL_SCANCODE_UNKNOWN, /* KEY_ZENKAKUHANKAKU */
    /*  85 */    SDL_SCANCODE_LANG5, /* KEY_ZENKAKUHANKAKU */
    /*  86 */    SDL_SCANCODE_NONUSBACKSLASH, /* KEY_102ND */
    /*  87 */    SDL_SCANCODE_F11,
    /*  88 */    SDL_SCANCODE_F12,
@@ -153,7 +153,7 @@
    /*  124 */    SDL_SCANCODE_INTERNATIONAL3, /* KEY_YEN */
    /*  125 */    SDL_SCANCODE_LGUI,
    /*  126 */    SDL_SCANCODE_RGUI,
    /*  127 */    SDL_SCANCODE_UNKNOWN, /* KEY_COMPOSE */
    /*  127 */    SDL_SCANCODE_APPLICATION, /* KEY_COMPOSE */
    /*  128 */    SDL_SCANCODE_STOP,
    /*  129 */    SDL_SCANCODE_AGAIN,
    /*  130 */    SDL_SCANCODE_UNKNOWN, /* KEY_PROPS */
@@ -174,9 +174,9 @@
    /*  145 */    SDL_SCANCODE_UNKNOWN, /* KEY_SENDFILE */
    /*  146 */    SDL_SCANCODE_UNKNOWN, /* KEY_DELETEFILE */
    /*  147 */    SDL_SCANCODE_UNKNOWN, /* KEY_XFER */
    /*  148 */    SDL_SCANCODE_UNKNOWN, /* KEY_PROG1 */
    /*  149 */    SDL_SCANCODE_UNKNOWN, /* KEY_PROG2 */
    /*  150 */    SDL_SCANCODE_UNKNOWN, /* KEY_WWW */
    /*  148 */    SDL_SCANCODE_APP1, /* KEY_PROG1 */
    /*  149 */    SDL_SCANCODE_APP2, /* KEY_PROG2 */
    /*  150 */    SDL_SCANCODE_WWW, /* KEY_WWW */
    /*  151 */    SDL_SCANCODE_UNKNOWN, /* KEY_MSDOS */
    /*  152 */    SDL_SCANCODE_UNKNOWN, /* KEY_COFFEE */
    /*  153 */    SDL_SCANCODE_UNKNOWN, /* KEY_DIRECTION */
@@ -192,7 +192,7 @@
    /*  163 */    SDL_SCANCODE_AUDIONEXT, /* KEY_NEXTSONG */
    /*  164 */    SDL_SCANCODE_AUDIOPLAY, /* KEY_PLAYPAUSE */
    /*  165 */    SDL_SCANCODE_AUDIOPREV, /* KEY_PREVIOUSSONG */
    /*  166 */    SDL_SCANCODE_UNKNOWN, /* KEY_STOPCD */
    /*  166 */    SDL_SCANCODE_AUDIOSTOP, /* KEY_STOPCD */
    /*  167 */    SDL_SCANCODE_UNKNOWN, /* KEY_RECORD */
    /*  168 */    SDL_SCANCODE_UNKNOWN, /* KEY_REWIND */
    /*  169 */    SDL_SCANCODE_UNKNOWN, /* KEY_PHONE */
@@ -221,7 +221,7 @@
    /*  192 */    SDL_SCANCODE_F22,
    /*  193 */    SDL_SCANCODE_F23,
    /*  194 */    SDL_SCANCODE_F24,
    0, 0, 0, 0,
    0, 0, 0, 0, 0,
    /*  200 */    SDL_SCANCODE_UNKNOWN, /* KEY_PLAYCD */
    /*  201 */    SDL_SCANCODE_UNKNOWN, /* KEY_PAUSECD */
    /*  202 */    SDL_SCANCODE_UNKNOWN, /* KEY_PROG3 */
source/src/events/scancodes_xfree86.h
@@ -418,4 +418,89 @@
    /* 238 */   SDL_SCANCODE_UNKNOWN,   /* XF86WLAN */
};
/* Xvnc / Xtightvnc scancodes from xmodmap -pk */
static const SDL_Scancode xvnc_scancode_table[] = {
    /*  0 */    SDL_SCANCODE_LCTRL,
    /*  1 */    SDL_SCANCODE_RCTRL,
    /*  2 */    SDL_SCANCODE_LSHIFT,
    /*  3 */    SDL_SCANCODE_RSHIFT,
    /*  4 */    SDL_SCANCODE_UNKNOWN, /* Meta_L */
    /*  5 */    SDL_SCANCODE_UNKNOWN, /* Meta_R */
    /*  6 */    SDL_SCANCODE_LALT,
    /*  7 */    SDL_SCANCODE_RALT,
    /*  8 */    SDL_SCANCODE_SPACE,
    /*  9 */    SDL_SCANCODE_0,
    /*  10 */   SDL_SCANCODE_1,
    /*  11 */   SDL_SCANCODE_2,
    /*  12 */   SDL_SCANCODE_3,
    /*  13 */   SDL_SCANCODE_4,
    /*  14 */   SDL_SCANCODE_5,
    /*  15 */   SDL_SCANCODE_6,
    /*  16 */   SDL_SCANCODE_7,
    /*  17 */   SDL_SCANCODE_8,
    /*  18 */   SDL_SCANCODE_9,
    /*  19 */   SDL_SCANCODE_MINUS,
    /*  20 */   SDL_SCANCODE_EQUALS,
    /*  21 */   SDL_SCANCODE_LEFTBRACKET,
    /*  22 */   SDL_SCANCODE_RIGHTBRACKET,
    /*  23 */   SDL_SCANCODE_SEMICOLON,
    /*  24 */   SDL_SCANCODE_APOSTROPHE,
    /*  25 */   SDL_SCANCODE_GRAVE,
    /*  26 */   SDL_SCANCODE_COMMA,
    /*  27 */   SDL_SCANCODE_PERIOD,
    /*  28 */   SDL_SCANCODE_SLASH,
    /*  29 */   SDL_SCANCODE_BACKSLASH,
    /*  30 */   SDL_SCANCODE_A,
    /*  31 */   SDL_SCANCODE_B,
    /*  32 */   SDL_SCANCODE_C,
    /*  33 */   SDL_SCANCODE_D,
    /*  34 */   SDL_SCANCODE_E,
    /*  35 */   SDL_SCANCODE_F,
    /*  36 */   SDL_SCANCODE_G,
    /*  37 */   SDL_SCANCODE_H,
    /*  38 */   SDL_SCANCODE_I,
    /*  39 */   SDL_SCANCODE_J,
    /*  40 */   SDL_SCANCODE_K,
    /*  41 */   SDL_SCANCODE_L,
    /*  42 */   SDL_SCANCODE_M,
    /*  43 */   SDL_SCANCODE_N,
    /*  44 */   SDL_SCANCODE_O,
    /*  45 */   SDL_SCANCODE_P,
    /*  46 */   SDL_SCANCODE_Q,
    /*  47 */   SDL_SCANCODE_R,
    /*  48 */   SDL_SCANCODE_S,
    /*  49 */   SDL_SCANCODE_T,
    /*  50 */   SDL_SCANCODE_U,
    /*  51 */   SDL_SCANCODE_V,
    /*  52 */   SDL_SCANCODE_W,
    /*  53 */   SDL_SCANCODE_X,
    /*  54 */   SDL_SCANCODE_Y,
    /*  55 */   SDL_SCANCODE_Z,
    /*  56 */   SDL_SCANCODE_BACKSPACE,
    /*  57 */   SDL_SCANCODE_RETURN,
    /*  58 */   SDL_SCANCODE_TAB,
    /*  59 */   SDL_SCANCODE_ESCAPE,
    /*  60 */   SDL_SCANCODE_DELETE,
    /*  61 */   SDL_SCANCODE_HOME,
    /*  62 */   SDL_SCANCODE_END,
    /*  63 */   SDL_SCANCODE_PAGEUP,
    /*  64 */   SDL_SCANCODE_PAGEDOWN,
    /*  65 */   SDL_SCANCODE_UP,
    /*  66 */   SDL_SCANCODE_DOWN,
    /*  67 */   SDL_SCANCODE_LEFT,
    /*  68 */   SDL_SCANCODE_RIGHT,
    /*  69 */   SDL_SCANCODE_F1,
    /*  70 */   SDL_SCANCODE_F2,
    /*  71 */   SDL_SCANCODE_F3,
    /*  72 */   SDL_SCANCODE_F4,
    /*  73 */   SDL_SCANCODE_F5,
    /*  74 */   SDL_SCANCODE_F6,
    /*  75 */   SDL_SCANCODE_F7,
    /*  76 */   SDL_SCANCODE_F8,
    /*  77 */   SDL_SCANCODE_F9,
    /*  78 */   SDL_SCANCODE_F10,
    /*  79 */   SDL_SCANCODE_F11,
    /*  80 */   SDL_SCANCODE_F12,
};
/* *INDENT-ON* */
source/src/filesystem/dummy/SDL_sysfilesystem.c
@@ -20,7 +20,7 @@
*/
#include "../../SDL_internal.h"
#ifdef SDL_FILESYSTEM_DUMMY
#if defined(SDL_FILESYSTEM_DUMMY) || defined(SDL_FILESYSTEM_DISABLED)
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* System dependent filesystem routines                                */
@@ -42,6 +42,6 @@
    return NULL;
}
#endif /* SDL_FILESYSTEM_DUMMY */
#endif /* SDL_FILESYSTEM_DUMMY || SDL_FILESYSTEM_DISABLED */
/* vi: set ts=4 sw=4 expandtab: */
source/src/filesystem/unix/SDL_sysfilesystem.c
@@ -33,7 +33,7 @@
#include <sys/types.h>
#include <limits.h>
#ifdef __FREEBSD__
#if defined(__FREEBSD__) || defined(__OPENBSD__)
#include <sys/sysctl.h>
#endif
@@ -90,7 +90,26 @@
            return NULL;
        }
    }
#elif defined(__SOLARIS__)
#endif
#if defined(__OPENBSD__)
    char **retvalargs;
    size_t len;
    const int mib[] = { CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ARGV };
    if (sysctl(mib, 4, NULL, &len, NULL, 0) != -1) {
        retvalargs = SDL_malloc(len);
        if (!retvalargs) {
            SDL_OutOfMemory();
            return NULL;
        }
        sysctl(mib, 4, retvalargs, &len, NULL, 0);
        retval = SDL_malloc(PATH_MAX + 1);
        if (retval)
            realpath(retvalargs[0], retval);
        SDL_free(retvalargs);
    }
#endif
#if defined(__SOLARIS__)
    const char *path = getexecname();
    if ((path != NULL) && (path[0] == '/')) { /* must be absolute path... */
        retval = SDL_strdup(path);
source/src/haptic/linux/SDL_syshaptic.c
@@ -609,7 +609,7 @@
        /* Opened and not closed haptics are leaked, this is on purpose.
         * Close your haptic devices after usage. */
        SDL_free(item->fname);
        item->fname = NULL;
        SDL_free(item);
    }
#if SDL_USE_LIBUDEV
@@ -690,7 +690,7 @@
        else if (!src->dir[0])
            *dest = (src->dir[1] >= 0 ? 0x8000 : 0);
        else {
            float f = atan2(src->dir[1], src->dir[0]);    /* Ideally we'd use fixed point math instead of floats... */
            float f = SDL_atan2(src->dir[1], src->dir[0]);    /* Ideally we'd use fixed point math instead of floats... */
                    /*
                      atan2 takes the parameters: Y-axis-value and X-axis-value (in that order)
                       - Y-axis-value is the second coordinate (from center to SOUTH)
source/src/haptic/windows/SDL_dinputhaptic.c
@@ -325,20 +325,12 @@
        /* Set data format. */
        ret = IDirectInputDevice8_SetDataFormat(haptic->hwdata->device,
                                                &c_dfDIJoystick2);
                                                &SDL_c_dfDIJoystick2);
        if (FAILED(ret)) {
            DI_SetError("Setting data format", ret);
            goto acquire_err;
        }
        /* Get number of axes. */
        ret = IDirectInputDevice8_EnumObjects(haptic->hwdata->device,
                                              DI_DeviceObjectCallback,
                                              haptic, DIDFT_AXIS);
        if (FAILED(ret)) {
            DI_SetError("Getting device axes", ret);
            goto acquire_err;
        }
        /* Acquire the device. */
        ret = IDirectInputDevice8_Acquire(haptic->hwdata->device);
@@ -348,6 +340,15 @@
        }
    }
    /* Get number of axes. */
    ret = IDirectInputDevice8_EnumObjects(haptic->hwdata->device,
                                          DI_DeviceObjectCallback,
                                          haptic, DIDFT_AXIS);
    if (FAILED(ret)) {
        DI_SetError("Getting device axes", ret);
        goto acquire_err;
    }
    /* Reset all actuators - just in case. */
    ret = IDirectInputDevice8_SendForceFeedbackCommand(haptic->hwdata->device,
                                                       DISFFC_RESET);
source/src/haptic/windows/SDL_windowshaptic.c
@@ -255,7 +255,7 @@
    for (hapticitem = SDL_haptics; hapticitem; hapticitem = hapticitem->next) {
        if ((hapticitem->hwdata->bXInputHaptic) && (hapticitem->hwdata->thread)) {
            /* we _have_ to stop the thread before we free the XInput DLL! */
            hapticitem->hwdata->stopThread = 1;
            SDL_AtomicSet(&hapticitem->hwdata->stopThread, 1);
            SDL_WaitThread(hapticitem->hwdata->thread, NULL);
            hapticitem->hwdata->thread = NULL;
        }
source/src/haptic/windows/SDL_windowshaptic_c.h
@@ -42,8 +42,8 @@
    Uint8 userid; /* XInput userid index for this joystick */
    SDL_Thread *thread;
    SDL_mutex *mutex;
    volatile Uint32 stopTicks;
    volatile int stopThread;
    Uint32 stopTicks;
    SDL_atomic_t stopThread;
};
source/src/haptic/windows/SDL_xinputhaptic.c
@@ -33,6 +33,7 @@
#include "SDL_xinputhaptic_c.h"
#include "../../core/windows/SDL_xinput.h"
#include "../../joystick/windows/SDL_windowsjoystick_c.h"
#include "../../thread/SDL_systhread.h"
/*
 * Internal stuff.
@@ -43,8 +44,7 @@
int
SDL_XINPUT_HapticInit(void)
{
    const char *env = SDL_GetHint(SDL_HINT_XINPUT_ENABLED);
    if (!env || SDL_atoi(env)) {
    if (SDL_GetHintBoolean(SDL_HINT_XINPUT_ENABLED, SDL_TRUE)) {
        loaded_xinput = (WIN_LoadXInputDLL() == 0);
    }
@@ -146,7 +146,7 @@
{
    struct haptic_hwdata *hwdata = (struct haptic_hwdata *) arg;
    while (!hwdata->stopThread) {
    while (!SDL_AtomicGet(&hwdata->stopThread)) {
        SDL_Delay(50);
        SDL_LockMutex(hwdata->mutex);
        /* If we're currently running and need to stop... */
@@ -205,17 +205,8 @@
    }
    SDL_snprintf(threadName, sizeof(threadName), "SDLXInputDev%d", (int)userid);
    haptic->hwdata->thread = SDL_CreateThreadInternal(SDL_RunXInputHaptic, threadName, 64 * 1024, haptic->hwdata);
#if defined(__WIN32__) && !defined(HAVE_LIBC)  /* !!! FIXME: this is nasty. */
#undef SDL_CreateThread
#if SDL_DYNAMIC_API
    haptic->hwdata->thread = SDL_CreateThread_REAL(SDL_RunXInputHaptic, threadName, haptic->hwdata, NULL, NULL);
#else
    haptic->hwdata->thread = SDL_CreateThread(SDL_RunXInputHaptic, threadName, haptic->hwdata, NULL, NULL);
#endif
#else
    haptic->hwdata->thread = SDL_CreateThread(SDL_RunXInputHaptic, threadName, haptic->hwdata);
#endif
    if (haptic->hwdata->thread == NULL) {
        SDL_DestroyMutex(haptic->hwdata->mutex);
        SDL_free(haptic->effects);
@@ -261,7 +252,7 @@
void
SDL_XINPUT_HapticClose(SDL_Haptic * haptic)
{
    haptic->hwdata->stopThread = 1;
    SDL_AtomicSet(&haptic->hwdata->stopThread, 1);
    SDL_WaitThread(haptic->hwdata->thread, NULL);
    SDL_DestroyMutex(haptic->hwdata->mutex);
}
source/src/joystick/SDL_gamecontroller.c
@@ -45,7 +45,8 @@
    Uint8 mask;
};
#define k_nMaxReverseEntries 20
/* We need 36 entries for Android (as of SDL v2.0.4) */
#define k_nMaxReverseEntries 48
/**
 * We are encoding the "HAT" as 0xhm. where h == hat ID and m == mask
@@ -106,6 +107,35 @@
int SDL_PrivateGameControllerButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button, Uint8 state);
/*
 * If there is an existing add event in the queue, it needs to be modified
 * to have the right value for which, because the number of controllers in
 * the system is now one less.
 */
static void UpdateEventsForDeviceRemoval()
{
    int i, num_events;
    SDL_Event *events;
    num_events = SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, SDL_CONTROLLERDEVICEADDED, SDL_CONTROLLERDEVICEADDED);
    if (num_events <= 0) {
        return;
    }
    events = SDL_stack_alloc(SDL_Event, num_events);
    if (!events) {
        return;
    }
    num_events = SDL_PeepEvents(events, num_events, SDL_GETEVENT, SDL_CONTROLLERDEVICEADDED, SDL_CONTROLLERDEVICEADDED);
    for (i = 0; i < num_events; ++i) {
        --events[i].cdevice.which;
    }
    SDL_PeepEvents(events, num_events, SDL_ADDEVENT, 0, 0);
    SDL_stack_free(events);
}
/*
 * Event filter to fire controller events from joystick ones
 */
int SDL_GameControllerEventWatcher(void *userdata, SDL_Event * event)
@@ -115,7 +145,11 @@
        {
            SDL_GameController *controllerlist;
            if (event->jaxis.axis >= k_nMaxReverseEntries) break;
            if (event->jaxis.axis >= k_nMaxReverseEntries)
            {
                SDL_SetError("SDL_GameControllerEventWatcher: Axis index %d too large, ignoring motion", (int)event->jaxis.axis);
                break;
            }
            controllerlist = SDL_gamecontrollers;
            while (controllerlist) {
@@ -126,8 +160,8 @@
                        switch (axis) {
                            case SDL_CONTROLLER_AXIS_TRIGGERLEFT:
                            case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
                                /* Shift it to be 0 - 32767. */
                                value = value / 2 + 16384;
                                break;
                            default:
                                break;
                        }
@@ -146,7 +180,11 @@
        {
            SDL_GameController *controllerlist;
            if (event->jbutton.button >= k_nMaxReverseEntries) break;
            if (event->jbutton.button >= k_nMaxReverseEntries)
            {
                SDL_SetError("SDL_GameControllerEventWatcher: Button index %d too large, ignoring update", (int)event->jbutton.button);
                break;
            }
            controllerlist = SDL_gamecontrollers;
            while (controllerlist) {
@@ -223,9 +261,12 @@
            while (controllerlist) {
                if (controllerlist->joystick->instance_id == event->jdevice.which) {
                    SDL_Event deviceevent;
                    deviceevent.type = SDL_CONTROLLERDEVICEREMOVED;
                    deviceevent.cdevice.which = event->jdevice.which;
                    SDL_PushEvent(&deviceevent);
                    UpdateEventsForDeviceRemoval();
                    break;
                }
                controllerlist = controllerlist->next;
@@ -861,7 +902,6 @@
{
    int i = 0;
    const char *pMappingString = NULL;
    s_pSupportedControllers = NULL;
    pMappingString = s_ControllerMappings[i];
    while (pMappingString) {
        SDL_GameControllerAddMapping(pMappingString);
@@ -971,6 +1011,20 @@
    SDL_PrivateLoadButtonMapping(&gamecontroller->mapping, pSupportedController->guid, pSupportedController->name, pSupportedController->mapping);
    /* The triggers are mapped from -32768 to 32767, where -32768 is the 'unpressed' value */
    {
        int leftTriggerMapping = gamecontroller->mapping.axes[SDL_CONTROLLER_AXIS_TRIGGERLEFT];
        int rightTriggerMapping = gamecontroller->mapping.axes[SDL_CONTROLLER_AXIS_TRIGGERRIGHT];
        if (leftTriggerMapping >= 0) {
            gamecontroller->joystick->axes[leftTriggerMapping] =
            gamecontroller->joystick->axes_zero[leftTriggerMapping] = (Sint16)-32768;
        }
        if (rightTriggerMapping >= 0) {
            gamecontroller->joystick->axes[rightTriggerMapping] =
            gamecontroller->joystick->axes_zero[rightTriggerMapping] = (Sint16)-32768;
        }
    }
    /* Add joystick to list */
    ++gamecontroller->ref_count;
    /* Link the joystick in the list */
@@ -1007,7 +1061,7 @@
        switch (axis) {
            case SDL_CONTROLLER_AXIS_TRIGGERLEFT:
            case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
                /* Shift it to be 0 - 32767. */
                /* Shift it to be 0 - 32767 */
                value = value / 2 + 16384;
            default:
                break;
source/src/joystick/SDL_gamecontrollerdb.h
@@ -35,6 +35,7 @@
    "xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
#endif
#if SDL_JOYSTICK_DINPUT
    "10280900000000000000504944564944,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,",
    "341a3608000000000000504944564944,Afterglow 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,",
    "e8206058000000000000504944564944,Cideko AK08b,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,",
    "ffff0000000000000000504944564944,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,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,",
@@ -48,6 +49,7 @@
    "4c05c405000000000000504944564944,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
#endif
#if defined(__MACOSX__)
    "10280000000000000900000000000000,8Bitdo SFC30 GamePad Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,",
    "830500000000000031b0000000000000,Cideko AK08b,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,",
    "0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,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,",
    "6d0400000000000016c2000000000000,Logitech F310 Gamepad (DInput),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,", /* Guide button doesn't seem to be sent in DInput mode. */
@@ -56,11 +58,14 @@
    "6d0400000000000019c2000000000000,Logitech Wireless Gamepad (DInput),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,", /* This includes F710 in DInput mode and the "Logitech Cordless RumblePad 2", at the very least. */
    "4c050000000000006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,",
    "4c05000000000000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
    "351200000000000021ab000000000000,SFC30 Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,",
    "11010000000000002014000000000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,",
    "11010000000000001714000000000000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,",
    "5e040000000000008e02000000000000,X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,",
#endif
#if defined(__LINUX__)
    "05000000102800000900000000010000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,",
    "03000000100000008200000011010000,Akishop Customs PS360+ v1.66,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,",
    "03000000e82000006058000001010000,Cideko AK08b,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,",
    "0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,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,",
    "030000006f0e00000104000000010000,Gamestop Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
@@ -71,6 +76,12 @@
    "030000006d04000019c2000011010000,Logitech F710 Gamepad (DInput),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,", /* Guide button doesn't seem to be sent in DInput mode. */
    "030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
    "030000006d04000018c2000010010000,Logitech RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
    "03000000380700008433000011010000,Mad Catz FightStick TE S+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
    "03000000380700008483000011010000,Mad Catz FightStick TE S+ PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
    "03000000380700003847000090040000,Mad Catz Wired Xbox 360 Controller (SFIV),a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
    "03000000380700008034000011010000,Mad Catz fightstick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
    "03000000380700008084000011010000,Mad Catz fightstick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
    "03000000380700001888000010010000,MadCatz PC USB Wired Stick 8818,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
    "03000000550900001072000011010000,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,",
    "050000007e0500003003000001000000,Nintendo Wii Remote Pro Controller,a:b1,b:b0,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
    "050000003620000100000002010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,",
@@ -78,12 +89,15 @@
    "03000000341a00003608000011010000,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,",
    "030000004c050000c405000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
    "050000004c050000c405000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
    "030000004c050000cc09000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
    "050000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
    "03000000c6240000045d000025010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
    "03000000321500000009000011010000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,",
    "050000003215000000090000163a0000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,",
    "03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
    "03000000de280000ff11000001000000,Valve Streaming Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
    "xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
    "050000005e040000e002000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
    "030000005e040000d102000001010000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
#endif
#if defined(__ANDROID__)
source/src/joystick/SDL_joystick.c
@@ -142,8 +142,8 @@
        joystick->name = NULL;
    if (joystick->naxes > 0) {
        joystick->axes = (Sint16 *) SDL_malloc
            (joystick->naxes * sizeof(Sint16));
        joystick->axes = (Sint16 *) SDL_malloc(joystick->naxes * sizeof(Sint16));
        joystick->axes_zero = (Sint16 *) SDL_malloc(joystick->naxes * sizeof(Sint16));
    }
    if (joystick->nhats > 0) {
        joystick->hats = (Uint8 *) SDL_malloc
@@ -167,6 +167,7 @@
    }
    if (joystick->axes) {
        SDL_memset(joystick->axes, 0, joystick->naxes * sizeof(Sint16));
        SDL_memset(joystick->axes_zero, 0, joystick->naxes * sizeof(Sint16));
    }
    if (joystick->hats) {
        SDL_memset(joystick->hats, 0, joystick->nhats * sizeof(Uint8));
@@ -497,6 +498,71 @@
/* These are global for SDL_sysjoystick.c and SDL_events.c */
void SDL_PrivateJoystickAdded(int device_index)
{
#if !SDL_EVENTS_DISABLED
    SDL_Event event;
    event.type = SDL_JOYDEVICEADDED;
    if (SDL_GetEventState(event.type) == SDL_ENABLE) {
        event.jdevice.which = device_index;
        if ( (SDL_EventOK == NULL) ||
             (*SDL_EventOK) (SDL_EventOKParam, &event) ) {
            SDL_PushEvent(&event);
        }
    }
#endif /* !SDL_EVENTS_DISABLED */
}
/*
 * If there is an existing add event in the queue, it needs to be modified
 * to have the right value for which, because the number of controllers in
 * the system is now one less.
 */
static void UpdateEventsForDeviceRemoval()
{
    int i, num_events;
    SDL_Event *events;
    num_events = SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, SDL_JOYDEVICEADDED, SDL_JOYDEVICEADDED);
    if (num_events <= 0) {
        return;
    }
    events = SDL_stack_alloc(SDL_Event, num_events);
    if (!events) {
        return;
    }
    num_events = SDL_PeepEvents(events, num_events, SDL_GETEVENT, SDL_JOYDEVICEADDED, SDL_JOYDEVICEADDED);
    for (i = 0; i < num_events; ++i) {
        --events[i].jdevice.which;
    }
    SDL_PeepEvents(events, num_events, SDL_ADDEVENT, 0, 0);
    SDL_stack_free(events);
}
void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance)
{
#if !SDL_EVENTS_DISABLED
    SDL_Event event;
    event.type = SDL_JOYDEVICEREMOVED;
    if (SDL_GetEventState(event.type) == SDL_ENABLE) {
        event.jdevice.which = device_instance;
        if ( (SDL_EventOK == NULL) ||
             (*SDL_EventOK) (SDL_EventOKParam, &event) ) {
            SDL_PushEvent(&event);
        }
    }
    UpdateEventsForDeviceRemoval();
#endif /* !SDL_EVENTS_DISABLED */
}
int
SDL_PrivateJoystickAxis(SDL_Joystick * joystick, Uint8 axis, Sint16 value)
{
@@ -514,8 +580,8 @@
     * events.
     */
    if (SDL_PrivateJoystickShouldIgnoreEvent()) {
        if ((value > 0 && value >= joystick->axes[axis]) ||
            (value < 0 && value <= joystick->axes[axis])) {
        if ((value > joystick->axes_zero[axis] && value >= joystick->axes[axis]) ||
            (value < joystick->axes_zero[axis] && value <= joystick->axes[axis])) {
            return 0;
        }
    }
@@ -688,7 +754,7 @@
            /* Tell the app that everything is centered/unpressed...  */
            for (i = 0; i < joystick->naxes; i++) {
                SDL_PrivateJoystickAxis(joystick, i, 0);
                SDL_PrivateJoystickAxis(joystick, i, joystick->axes_zero[i]);
            }
            for (i = 0; i < joystick->nbuttons; i++) {
source/src/joystick/SDL_joystick_c.h
@@ -33,6 +33,8 @@
/* Internal event queueing functions */
extern void SDL_PrivateJoystickAdded(int device_index);
extern void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance);
extern int SDL_PrivateJoystickAxis(SDL_Joystick * joystick,
                                   Uint8 axis, Sint16 value);
extern int SDL_PrivateJoystickBall(SDL_Joystick * joystick,
@@ -41,8 +43,8 @@
                                  Uint8 hat, Uint8 value);
extern int SDL_PrivateJoystickButton(SDL_Joystick * joystick,
                                     Uint8 button, Uint8 state);
extern void SDL_PrivateJoystickBatteryLevel( SDL_Joystick * joystick,
    SDL_JoystickPowerLevel ePowerLevel );
extern void SDL_PrivateJoystickBatteryLevel(SDL_Joystick * joystick,
                                            SDL_JoystickPowerLevel ePowerLevel);
/* Internal sanity checking functions */
extern int SDL_PrivateJoystickValid(SDL_Joystick * joystick);
source/src/joystick/SDL_sysjoystick.h
@@ -36,6 +36,7 @@
    int naxes;                  /* Number of axis controls on the joystick */
    Sint16 *axes;               /* Current axis states */
    Sint16 *axes_zero;          /* Zero point on the axis (-32768 for triggers) */
    int nhats;                  /* Number of hats on the joystick */
    Uint8 *hats;                /* Current hat states */
source/src/joystick/android/SDL_sysjoystick.c
@@ -27,10 +27,6 @@
#include "SDL_error.h"
#include "SDL_events.h"
#if !SDL_EVENTS_DISABLED
#include "../../events/SDL_events_c.h"
#endif
#include "SDL_joystick.h"
#include "SDL_hints.h"
#include "SDL_assert.h"
@@ -191,8 +187,8 @@
        item = JoystickByDeviceId(device_id);
        if (item && item->joystick) {
            SDL_PrivateJoystickButton(item->joystick, button , SDL_PRESSED);
            return 0;
        }
        return 0;
    }
    
    return -1;
@@ -207,8 +203,8 @@
        item = JoystickByDeviceId(device_id);
        if (item && item->joystick) {
            SDL_PrivateJoystickButton(item->joystick, button, SDL_RELEASED);
            return 0;
        }
        return 0;
    }
    
    return -1;
@@ -252,9 +248,6 @@
{
    SDL_JoystickGUID guid;
    SDL_joylist_item *item;
#if !SDL_EVENTS_DISABLED
    SDL_Event event;
#endif
    
    if(JoystickByDeviceId(device_id) != NULL || name == NULL) {
        return -1;
@@ -299,17 +292,7 @@
    /* Need to increment the joystick count before we post the event */
    ++numjoysticks;
#if !SDL_EVENTS_DISABLED
    event.type = SDL_JOYDEVICEADDED;
    if (SDL_GetEventState(event.type) == SDL_ENABLE) {
        event.jdevice.which = (numjoysticks - 1);
        if ( (SDL_EventOK == NULL) ||
             (*SDL_EventOK) (SDL_EventOKParam, &event) ) {
            SDL_PushEvent(&event);
        }
    }
#endif /* !SDL_EVENTS_DISABLED */
    SDL_PrivateJoystickAdded(numjoysticks - 1);
#ifdef DEBUG_JOYSTICK
    SDL_Log("Added joystick %s with device_id %d", name, device_id);
@@ -323,9 +306,6 @@
{
    SDL_joylist_item *item = SDL_joylist;
    SDL_joylist_item *prev = NULL;
#if !SDL_EVENTS_DISABLED
    SDL_Event event;
#endif
    
    /* Don't call JoystickByDeviceId here or there'll be an infinite loop! */
    while (item != NULL) {
@@ -340,7 +320,6 @@
        return -1;
    }
    const int retval = item->device_instance;
    if (item->joystick) {
        item->joystick->hwdata = NULL;
    }
@@ -358,17 +337,7 @@
    /* Need to decrement the joystick count before we post the event */
    --numjoysticks;
#if !SDL_EVENTS_DISABLED
    event.type = SDL_JOYDEVICEREMOVED;
    if (SDL_GetEventState(event.type) == SDL_ENABLE) {
        event.jdevice.which = item->device_instance;
        if ( (SDL_EventOK == NULL) ||
             (*SDL_EventOK) (SDL_EventOKParam, &event) ) {
            SDL_PushEvent(&event);
        }
    }
#endif /* !SDL_EVENTS_DISABLED */
    SDL_PrivateJoystickRemoved(item->device_instance);
#ifdef DEBUG_JOYSTICK
    SDL_Log("Removed joystick with device_id %d", device_id);
@@ -376,18 +345,16 @@
    
    SDL_free(item->name);
    SDL_free(item);
    return retval;
    return numjoysticks;
}
int
SDL_SYS_JoystickInit(void)
{
    const char *hint;
    SDL_SYS_JoystickDetect();
    
    hint = SDL_GetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK);
    if (!hint || SDL_atoi(hint)) {
    if (SDL_GetHintBoolean(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, SDL_TRUE)) {
        /* Default behavior, accelerometer as joystick */
        Android_AddJoystick(ANDROID_ACCELEROMETER_DEVICE_ID, ANDROID_ACCELEROMETER_NAME, SDL_TRUE, 0, 3, 0, 0);
    }
@@ -539,6 +506,10 @@
void
SDL_SYS_JoystickClose(SDL_Joystick * joystick)
{
    SDL_joylist_item *item = (SDL_joylist_item *) joystick->hwdata;
    if (item) {
        item->joystick = NULL;
    }
}
/* Function to perform any system-specific joystick related cleanup */
source/src/joystick/android/SDL_sysjoystick_c.h
@@ -1,23 +1,23 @@
/*
 Simple DirectMedia Layer
 Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
 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.
 */
  Simple DirectMedia Layer
  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
  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"
source/src/joystick/bsd/SDL_sysjoystick.c
@@ -179,7 +179,7 @@
        SDL_snprintf(s, SDL_arraysize(s), "/dev/uhid%d", i);
        joynames[SDL_SYS_numjoysticks] = strdup(s);
        joynames[SDL_SYS_numjoysticks] = SDL_strdup(s);
        if (SDL_SYS_JoystickOpen(&nj, SDL_SYS_numjoysticks) == 0) {
            SDL_SYS_JoystickClose(&nj);
@@ -193,7 +193,7 @@
        SDL_snprintf(s, SDL_arraysize(s), "/dev/joy%d", i);
        fd = open(s, O_RDONLY);
        if (fd != -1) {
            joynames[SDL_SYS_numjoysticks++] = strdup(s);
            joynames[SDL_SYS_numjoysticks++] = SDL_strdup(s);
            close(fd);
        }
    }
@@ -304,14 +304,14 @@
    }
    joy->hwdata = hw;
    hw->fd = fd;
    hw->path = strdup(path);
    hw->path = SDL_strdup(path);
    if (!SDL_strncmp(path, "/dev/joy", 8)) {
        hw->type = BSDJOY_JOY;
        joy->naxes = 2;
        joy->nbuttons = 2;
        joy->nhats = 0;
        joy->nballs = 0;
        joydevnames[device_index] = strdup("Gameport joystick");
        joydevnames[device_index] = SDL_strdup("Gameport joystick");
        goto usbend;
    } else {
        hw->type = BSDJOY_UHID;
@@ -363,7 +363,7 @@
        str[i] = '\0';
        asprintf(&new_name, "%s @ %s", str, path);
        if (new_name != NULL) {
            free(joydevnames[SDL_SYS_numjoysticks]);
            SDL_free(joydevnames[SDL_SYS_numjoysticks]);
            joydevnames[SDL_SYS_numjoysticks] = new_name;
        }
    }
source/src/joystick/darwin/SDL_sysjoystick.c
@@ -34,9 +34,6 @@
#include "SDL_sysjoystick_c.h"
#include "SDL_events.h"
#include "../../haptic/darwin/SDL_syshaptic_c.h"    /* For haptic hot plugging */
#if !SDL_EVENTS_DISABLED
#include "../../events/SDL_events_c.h"
#endif
#define SDL_JOYSTICK_RUNLOOP_MODE CFSTR("SDLJoystick")
@@ -154,21 +151,7 @@
    MacHaptic_MaybeRemoveDevice(device->ffservice);
#endif
/* !!! FIXME: why isn't there an SDL_PrivateJoyDeviceRemoved()? */
#if !SDL_EVENTS_DISABLED
    {
        SDL_Event event;
        event.type = SDL_JOYDEVICEREMOVED;
        if (SDL_GetEventState(event.type) == SDL_ENABLE) {
            event.jdevice.which = device->instance_id;
            if ((SDL_EventOK == NULL)
                || (*SDL_EventOK) (SDL_EventOKParam, &event)) {
                SDL_PushEvent(&event);
            }
        }
    }
#endif /* !SDL_EVENTS_DISABLED */
    SDL_PrivateJoystickRemoved(device->instance_id);
}
@@ -249,6 +232,7 @@
                            case kHIDUsage_GD_DPadLeft:
                            case kHIDUsage_GD_Start:
                            case kHIDUsage_GD_Select:
                            case kHIDUsage_GD_SystemMainMenu:
                                if (!ElementAlreadyAdded(cookie, pDevice->firstButton)) {
                                    element = (recElement *) SDL_calloc(1, sizeof (recElement));
                                    if (element) {
@@ -422,6 +406,7 @@
{
    recDevice *device;
    int device_index = 0;
    io_service_t ioservice;
    if (res != kIOReturnSuccess) {
        return;
@@ -451,20 +436,11 @@
    device->instance_id = ++s_joystick_instance_id;
    /* We have to do some storage of the io_service_t for SDL_HapticOpenFromJoystick */
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
    if (IOHIDDeviceGetService != NULL) {  /* weak reference: available in 10.6 and later. */
#endif
        const io_service_t ioservice = IOHIDDeviceGetService(ioHIDDeviceObject);
    ioservice = IOHIDDeviceGetService(ioHIDDeviceObject);
#if SDL_HAPTIC_IOKIT
        if ((ioservice) && (FFIsForceFeedback(ioservice) == FF_OK)) {
            device->ffservice = ioservice;
            MacHaptic_MaybeAddDevice(ioservice);
        }
#endif
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
    if ((ioservice) && (FFIsForceFeedback(ioservice) == FF_OK)) {
        device->ffservice = ioservice;
        MacHaptic_MaybeAddDevice(ioservice);
    }
#endif
@@ -483,21 +459,7 @@
        ++device_index;  /* bump by one since we counted by pNext. */
    }
/* !!! FIXME: why isn't there an SDL_PrivateJoyDeviceAdded()? */
#if !SDL_EVENTS_DISABLED
    {
        SDL_Event event;
        event.type = SDL_JOYDEVICEADDED;
        if (SDL_GetEventState(event.type) == SDL_ENABLE) {
            event.jdevice.which = device_index;
            if ((SDL_EventOK == NULL)
                || (*SDL_EventOK) (SDL_EventOKParam, &event)) {
                SDL_PushEvent(&event);
            }
        }
    }
#endif /* !SDL_EVENTS_DISABLED */
    SDL_PrivateJoystickAdded(device_index);
}
static SDL_bool
Diff truncated after the above file
source/src/joystick/emscripten/SDL_sysjoystick.c source/src/joystick/emscripten/SDL_sysjoystick_c.h source/src/joystick/haiku/SDL_haikujoystick.cc source/src/joystick/iphoneos/SDL_sysjoystick.m source/src/joystick/linux/SDL_sysjoystick.c source/src/joystick/psp/SDL_sysjoystick.c source/src/joystick/windows/SDL_dinputjoystick.c source/src/joystick/windows/SDL_windowsjoystick.c source/src/joystick/windows/SDL_windowsjoystick_c.h source/src/joystick/windows/SDL_xinputjoystick.c source/src/loadso/dlopen/SDL_sysloadso.c source/src/main/android/SDL_android_main.c source/src/main/haiku/SDL_BApp.h source/src/main/haiku/SDL_BeApp.cc source/src/main/windows/SDL_windows_main.c source/src/main/windows/version.rc source/src/main/winrt/SDL2-WinRTResource_BlankCursor.cur source/src/main/winrt/SDL2-WinRTResources.rc source/src/power/uikit/SDL_syspower.m source/src/render/SDL_render.c source/src/render/SDL_sysrender.h source/src/render/direct3d/SDL_render_d3d.c source/src/render/direct3d11/SDL_render_d3d11.c source/src/render/opengl/SDL_render_gl.c source/src/render/opengles/SDL_render_gles.c source/src/render/opengles2/SDL_render_gles2.c source/src/render/psp/SDL_render_psp.c source/src/render/software/SDL_render_sw.c source/src/render/software/SDL_rotate.c source/src/stdlib/SDL_iconv.c source/src/stdlib/SDL_qsort.c source/src/stdlib/SDL_stdlib.c source/src/stdlib/SDL_string.c source/src/test/SDL_test_assert.c source/src/test/SDL_test_common.c source/src/test/SDL_test_compare.c source/src/test/SDL_test_harness.c source/src/test/SDL_test_log.c source/src/thread/SDL_systhread.h source/src/thread/SDL_thread.c source/src/thread/SDL_thread_c.h source/src/thread/psp/SDL_systhread.c source/src/thread/pthread/SDL_systhread.c source/src/thread/stdcpp/SDL_systhread.cpp source/src/thread/windows/SDL_systhread.c source/src/timer/SDL_timer.c source/src/timer/windows/SDL_systimer.c source/src/video/SDL_blit_copy.c source/src/video/SDL_blit_slow.c source/src/video/SDL_bmp.c source/src/video/SDL_egl.c source/src/video/SDL_surface.c source/src/video/SDL_sysvideo.h source/src/video/SDL_video.c source/src/video/android/SDL_androidevents.c source/src/video/android/SDL_androidkeyboard.c source/src/video/android/SDL_androidmouse.c source/src/video/android/SDL_androidmouse.h source/src/video/android/SDL_androidtouch.c source/src/video/android/SDL_androidvideo.c source/src/video/cocoa/SDL_cocoaclipboard.m source/src/video/cocoa/SDL_cocoaevents.m source/src/video/cocoa/SDL_cocoakeyboard.m source/src/video/cocoa/SDL_cocoamodes.h source/src/video/cocoa/SDL_cocoamodes.m source/src/video/cocoa/SDL_cocoamouse.m source/src/video/cocoa/SDL_cocoamousetap.m source/src/video/cocoa/SDL_cocoaopengl.m source/src/video/cocoa/SDL_cocoashape.m source/src/video/cocoa/SDL_cocoavideo.m source/src/video/cocoa/SDL_cocoawindow.h source/src/video/cocoa/SDL_cocoawindow.m source/src/video/directfb/SDL_DirectFB_video.c source/src/video/directfb/SDL_DirectFB_window.c source/src/video/directfb/SDL_DirectFB_window.h source/src/video/emscripten/SDL_emscriptenevents.c source/src/video/emscripten/SDL_emscriptenevents.h source/src/video/emscripten/SDL_emscriptenframebuffer.c source/src/video/emscripten/SDL_emscriptenmouse.c source/src/video/emscripten/SDL_emscriptenvideo.c source/src/video/emscripten/SDL_emscriptenvideo.h source/src/video/haiku/SDL_BWin.h source/src/video/haiku/SDL_bvideo.cc source/src/video/haiku/SDL_bwindow.cc source/src/video/haiku/SDL_bwindow.h source/src/video/mir/SDL_mirdyn.c source/src/video/mir/SDL_mirdyn.h source/src/video/mir/SDL_mirevents.c source/src/video/mir/SDL_mirevents.h source/src/video/mir/SDL_mirframebuffer.c source/src/video/mir/SDL_mirmouse.c source/src/video/mir/SDL_mirsym.h source/src/video/mir/SDL_mirvideo.c source/src/video/mir/SDL_mirvideo.h source/src/video/mir/SDL_mirwindow.c source/src/video/mir/SDL_mirwindow.h source/src/video/pandora/SDL_pandora.c source/src/video/pandora/SDL_pandora.h source/src/video/psp/SDL_pspevents.c source/src/video/psp/SDL_pspvideo.c source/src/video/raspberry/SDL_rpimouse.c source/src/video/raspberry/SDL_rpivideo.c source/src/video/uikit/SDL_uikitappdelegate.h source/src/video/uikit/SDL_uikitappdelegate.m source/src/video/uikit/SDL_uikitclipboard.h source/src/video/uikit/SDL_uikitclipboard.m source/src/video/uikit/SDL_uikitevents.m source/src/video/uikit/SDL_uikitmodes.h source/src/video/uikit/SDL_uikitmodes.m source/src/video/uikit/SDL_uikitopengles.h source/src/video/uikit/SDL_uikitopengles.m source/src/video/uikit/SDL_uikitopenglview.m source/src/video/uikit/SDL_uikitvideo.h source/src/video/uikit/SDL_uikitvideo.m source/src/video/uikit/SDL_uikitview.m source/src/video/uikit/SDL_uikitviewcontroller.h source/src/video/uikit/SDL_uikitviewcontroller.m source/src/video/uikit/SDL_uikitwindow.m source/src/video/vivante/SDL_vivantevideo.c source/src/video/wayland/SDL_waylanddyn.c source/src/video/wayland/SDL_waylanddyn.h source/src/video/wayland/SDL_waylandevents.c source/src/video/wayland/SDL_waylandevents_c.h source/src/video/wayland/SDL_waylandmouse.c source/src/video/wayland/SDL_waylandsym.h source/src/video/wayland/SDL_waylandvideo.c source/src/video/wayland/SDL_waylandvideo.h source/src/video/wayland/SDL_waylandwindow.c source/src/video/wayland/SDL_waylandwindow.h source/src/video/windows/SDL_windowsevents.c source/src/video/windows/SDL_windowskeyboard.c source/src/video/windows/SDL_windowskeyboard.h source/src/video/windows/SDL_windowsmessagebox.c source/src/video/windows/SDL_windowsmodes.c source/src/video/windows/SDL_windowsmodes.h source/src/video/windows/SDL_windowsvideo.c source/src/video/windows/SDL_windowswindow.c source/src/video/windows/SDL_windowswindow.h source/src/video/winrt/SDL_winrtevents.cpp source/src/video/winrt/SDL_winrtevents_c.h source/src/video/winrt/SDL_winrtgamebar.cpp source/src/video/winrt/SDL_winrtgamebar_cpp.h source/src/video/winrt/SDL_winrtkeyboard.cpp source/src/video/winrt/SDL_winrtmouse.cpp source/src/video/winrt/SDL_winrtvideo.cpp source/src/video/winrt/SDL_winrtvideo_cpp.h source/src/video/x11/SDL_x11dyn.c source/src/video/x11/SDL_x11dyn.h source/src/video/x11/SDL_x11events.c source/src/video/x11/SDL_x11keyboard.c source/src/video/x11/SDL_x11keyboard.h source/src/video/x11/SDL_x11modes.c source/src/video/x11/SDL_x11modes.h source/src/video/x11/SDL_x11mouse.c source/src/video/x11/SDL_x11opengl.c source/src/video/x11/SDL_x11sym.h source/src/video/x11/SDL_x11video.c source/src/video/x11/SDL_x11video.h source/src/video/x11/SDL_x11window.c source/src/video/x11/SDL_x11window.h source/src/video/x11/SDL_x11xinput2.c source/src/video/x11/edid-parse.c source/src/video/x11/imKStoUCS.c source/src/video/x11/imKStoUCS.h source/test/Makefile.in source/test/controllermap.c source/test/testatomic.c source/test/testaudiocapture.c source/test/testaudiohotplug.c source/test/testaudioinfo.c source/test/testautomation_events.c source/test/testautomation_keyboard.c source/test/testautomation_main.c source/test/testautomation_sdltest.c source/test/testautomation_stdlib.c source/test/testbounds.c source/test/testcustomcursor.c source/test/testdisplayinfo.c source/test/testdrawchessboard.c source/test/testdropfile.c source/test/testfilesystem.c source/test/testgamecontroller.c source/test/testgles.c source/test/testgles2.c source/test/testime.c source/test/testlock.c source/test/testmultiaudio.c source/test/testqsort.c source/test/testrendercopyex.c source/test/testshape.c source/test/testwm2.c source/test/torturethread.c