resync'd overscan patch with SDL mainline.

This commit is contained in:
Eric Wing 2015-04-17 21:25:19 -07:00
commit 7d5147bad3
267 changed files with 9193 additions and 4098 deletions

View File

@ -8,6 +8,9 @@ Makefile
sdl-config sdl-config
SDL2.spec SDL2.spec
build build
Build
*xcuserdata*
*xcworkspacedata*
# for Xcode # for Xcode
*.orig *.orig
@ -72,20 +75,26 @@ test/config.status
test/Makefile test/Makefile
test/SDL2.dll test/SDL2.dll
test/checkkeys test/checkkeys
test/controllermap
test/loopwave test/loopwave
test/loopwavequeue test/loopwavequeue
test/testatomic test/testatomic
test/testaudiohotplug
test/testaudioinfo test/testaudioinfo
test/testautomation test/testautomation
test/testdraw2 test/testdraw2
test/testdrawchessboard
test/testdropfile
test/testerror test/testerror
test/testfile test/testfile
test/testgamecontroller test/testgamecontroller
test/testgesture test/testgesture
test/testgl2 test/testgl2
test/testgles test/testgles
test/testgles2
test/testhaptic test/testhaptic
test/testhittesting test/testhittesting
test/testhotplug
test/testiconv test/testiconv
test/testime test/testime
test/testintersections test/testintersections
@ -115,6 +124,7 @@ test/teststreaming
test/testthread test/testthread
test/testtimer test/testtimer
test/testver test/testver
test/testviewport
test/testwm2 test/testwm2
test/torturethread test/torturethread
test/*.exe test/*.exe

View File

@ -2,7 +2,7 @@ if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
message(FATAL_ERROR "Prevented in-tree built. Please create a build directory outside of the SDL source code and call cmake from there") message(FATAL_ERROR "Prevented in-tree built. Please create a build directory outside of the SDL source code and call cmake from there")
endif() endif()
cmake_minimum_required(VERSION 2.6) cmake_minimum_required(VERSION 2.8)
project(SDL2 C) project(SDL2 C)
include(CheckFunctionExists) include(CheckFunctionExists)
include(CheckLibraryExists) include(CheckLibraryExists)
@ -117,6 +117,12 @@ else()
set(UNIX_OR_MAC_SYS OFF) set(UNIX_OR_MAC_SYS OFF)
endif() endif()
if (UNIX_OR_MAC_SYS AND NOT EMSCRIPTEN) # JavaScript does not yet have threading support, so disable pthreads when building for Emscripten.
set(SDL_PTHREADS_ENABLED_BY_DEFAULT ON)
else()
set(SDL_PTHREADS_ENABLED_BY_DEFAULT OFF)
endif()
# Default option knobs # Default option knobs
if(APPLE OR ARCH_64) if(APPLE OR ARCH_64)
set(OPT_DEF_SSEMATH ON) set(OPT_DEF_SSEMATH ON)
@ -144,7 +150,7 @@ if("$ENV{CFLAGS}" STREQUAL "")
if(USE_GCC OR USE_CLANG) if(USE_GCC OR USE_CLANG)
set(CMAKE_C_FLAGS "-g -O3") set(CMAKE_C_FLAGS "-g -O3")
endif() endif()
else("$ENV{CFLAGS}" STREQUAL "") else()
set(CMAKE_C_FLAGS "$ENV{CFLAGS}") set(CMAKE_C_FLAGS "$ENV{CFLAGS}")
list(APPEND EXTRA_CFLAGS "$ENV{CFLAGS}") list(APPEND EXTRA_CFLAGS "$ENV{CFLAGS}")
endif() endif()
@ -161,7 +167,7 @@ if(MSVC)
if(${flag_var} MATCHES "/MD") if(${flag_var} MATCHES "/MD")
string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
endif() endif()
endforeach(flag_var) endforeach()
endif() endif()
endif() endif()
@ -170,13 +176,19 @@ endif()
set(SDL_LIBS "-lSDL2") set(SDL_LIBS "-lSDL2")
set(SDL_CFLAGS "") set(SDL_CFLAGS "")
# Emscripten toolchain has a nonempty default value for this, and the checks
# in this file need to change that, so remember the original value, and
# restore back to that afterwards. For check_function_exists() to work in
# Emscripten, this value must be at its default value.
set(ORIG_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
if(CYGWIN) if(CYGWIN)
# We build SDL on cygwin without the UNIX emulation layer # We build SDL on cygwin without the UNIX emulation layer
include_directories("-I/usr/include/mingw") include_directories("-I/usr/include/mingw")
set(CMAKE_REQUIRED_FLAGS "-mno-cygwin") set(CMAKE_REQUIRED_FLAGS "-mno-cygwin")
check_c_source_compiles("int main(int argc, char **argv) {}" check_c_source_compiles("int main(int argc, char **argv) {}"
HAVE_GCC_NO_CYGWIN) HAVE_GCC_NO_CYGWIN)
set(CMAKE_REQUIRED_FLAGS) set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
if(HAVE_GCC_NO_CYGWIN) if(HAVE_GCC_NO_CYGWIN)
list(APPEND EXTRA_LDFLAGS "-mno-cygwin") list(APPEND EXTRA_LDFLAGS "-mno-cygwin")
list(APPEND SDL_LIBS "-mno-cygwin") list(APPEND SDL_LIBS "-mno-cygwin")
@ -188,12 +200,31 @@ add_definitions(-DUSING_GENERATED_CONFIG_H)
# General includes # General includes
include_directories(${SDL2_BINARY_DIR}/include ${SDL2_SOURCE_DIR}/include) include_directories(${SDL2_BINARY_DIR}/include ${SDL2_SOURCE_DIR}/include)
# All these ENABLED_BY_DEFAULT vars will default to ON if not specified, so
# you only need to have a platform override them if they are disabling.
set(OPT_DEF_ASM TRUE)
if(EMSCRIPTEN)
# Set up default values for the currently supported set of subsystems:
# Emscripten/Javascript does not have assembly support, a dynamic library
# loading architecture, low-level CPU inspection or multithreading.
set(OPT_DEF_ASM FALSE)
set(SDL_SHARED_ENABLED_BY_DEFAULT OFF)
set(SDL_ATOMIC_ENABLED_BY_DEFAULT OFF)
set(SDL_THREADS_ENABLED_BY_DEFAULT OFF)
set(SDL_LOADSO_ENABLED_BY_DEFAULT OFF)
set(SDL_CPUINFO_ENABLED_BY_DEFAULT OFF)
set(SDL_DLOPEN_ENABLED_BY_DEFAULT OFF)
endif()
set(SDL_SUBSYSTEMS set(SDL_SUBSYSTEMS
Atomic Audio Video Render Events Joystick Haptic Power Threads Timers Atomic Audio Video Render Events Joystick Haptic Power Threads Timers
File Loadso CPUinfo Filesystem) File Loadso CPUinfo Filesystem Dlopen)
foreach(_SUB ${SDL_SUBSYSTEMS}) foreach(_SUB ${SDL_SUBSYSTEMS})
string(TOUPPER ${_SUB} _OPT) string(TOUPPER ${_SUB} _OPT)
option(SDL_${_OPT} "Enable the ${_SUB} subsystem" ON) if (NOT DEFINED SDL_${_OPT}_ENABLED_BY_DEFAULT)
set(SDL_${_OPT}_ENABLED_BY_DEFAULT ON)
endif()
option(SDL_${_OPT} "Enable the ${_SUB} subsystem" ${SDL_${_OPT}_ENABLED_BY_DEFAULT})
endforeach() endforeach()
option_string(ASSERTIONS "Enable internal sanity checks (auto/disabled/release/enabled/paranoid)" "auto") option_string(ASSERTIONS "Enable internal sanity checks (auto/disabled/release/enabled/paranoid)" "auto")
@ -212,13 +243,13 @@ set_option(DUMMYAUDIO "Support the dummy audio driver" ON)
set_option(VIDEO_DIRECTFB "Use DirectFB video driver" OFF) set_option(VIDEO_DIRECTFB "Use DirectFB video driver" OFF)
dep_option(DIRECTFB_SHARED "Dynamically load directfb support" ON "VIDEO_DIRECTFB" OFF) dep_option(DIRECTFB_SHARED "Dynamically load directfb support" ON "VIDEO_DIRECTFB" OFF)
set_option(FUSIONSOUND "Use FusionSound audio driver" OFF) set_option(FUSIONSOUND "Use FusionSound audio driver" OFF)
dep_option(FUSIONSOUND_SHARED "Dynamically load fusionsound audio support" ON "FUSIONSOUND_SHARED" OFF) dep_option(FUSIONSOUND_SHARED "Dynamically load fusionsound audio support" ON "FUSIONSOUND" OFF)
set_option(VIDEO_DUMMY "Use dummy video driver" ON) set_option(VIDEO_DUMMY "Use dummy video driver" ON)
set_option(VIDEO_OPENGL "Include OpenGL support" ON) set_option(VIDEO_OPENGL "Include OpenGL support" ON)
set_option(VIDEO_OPENGLES "Include OpenGL ES support" ON) set_option(VIDEO_OPENGLES "Include OpenGL ES support" ON)
set_option(PTHREADS "Use POSIX threads for multi-threading" ${UNIX_OR_MAC_SYS}) set_option(PTHREADS "Use POSIX threads for multi-threading" ${SDL_PTHREADS_ENABLED_BY_DEFAULT})
dep_option(PTHREADS_SEM "Use pthread semaphores" ON "PTHREADS" OFF) dep_option(PTHREADS_SEM "Use pthread semaphores" ON "PTHREADS" OFF)
set_option(SDL_DLOPEN "Use dlopen for shared object loading" ON) set_option(SDL_DLOPEN "Use dlopen for shared object loading" ${SDL_DLOPEN_ENABLED_BY_DEFAULT})
set_option(OSS "Support the OSS audio API" ${UNIX_SYS}) set_option(OSS "Support the OSS audio API" ${UNIX_SYS})
set_option(ALSA "Support the ALSA audio API" ${UNIX_SYS}) set_option(ALSA "Support the ALSA audio API" ${UNIX_SYS})
dep_option(ALSA_SHARED "Dynamically load ALSA audio support" ON "ALSA" OFF) dep_option(ALSA_SHARED "Dynamically load ALSA audio support" ON "ALSA" OFF)
@ -236,7 +267,10 @@ set_option(CLOCK_GETTIME "Use clock_gettime() instead of gettimeofday()" O
set_option(INPUT_TSLIB "Use the Touchscreen library for input" ${UNIX_SYS}) set_option(INPUT_TSLIB "Use the Touchscreen library for input" ${UNIX_SYS})
set_option(VIDEO_X11 "Use X11 video driver" ${UNIX_SYS}) set_option(VIDEO_X11 "Use X11 video driver" ${UNIX_SYS})
set_option(VIDEO_WAYLAND "Use Wayland video driver" ${UNIX_SYS}) set_option(VIDEO_WAYLAND "Use Wayland video driver" ${UNIX_SYS})
dep_option(WAYLAND_SHARED "Dynamically load Wayland support" ON "VIDEO_WAYLAND" OFF)
dep_option(VIDEO_WAYLAND_QT_TOUCH "QtWayland server support for Wayland video driver" ON "VIDEO_WAYLAND" OFF)
set_option(VIDEO_MIR "Use Mir video driver" ${UNIX_SYS}) set_option(VIDEO_MIR "Use Mir video driver" ${UNIX_SYS})
dep_option(MIR_SHARED "Dynamically load Mir support" ON "VIDEO_MIR" OFF)
set_option(VIDEO_RPI "Use Raspberry Pi video driver" ${UNIX_SYS}) set_option(VIDEO_RPI "Use Raspberry Pi video driver" ${UNIX_SYS})
dep_option(X11_SHARED "Dynamically load X11 support" ON "VIDEO_X11" OFF) dep_option(X11_SHARED "Dynamically load X11 support" ON "VIDEO_X11" OFF)
set(SDL_X11_OPTIONS Xcursor Xinerama XInput Xrandr Xscrnsaver XShape Xvm) set(SDL_X11_OPTIONS Xcursor Xinerama XInput Xrandr Xscrnsaver XShape Xvm)
@ -251,7 +285,7 @@ set_option(VIDEO_VIVANTE "Use Vivante EGL video driver" ${UNIX_SYS})
# TODO: We should (should we?) respect cmake's ${BUILD_SHARED_LIBS} flag here # TODO: We should (should we?) respect cmake's ${BUILD_SHARED_LIBS} flag here
# The options below are for compatibility to configure's default behaviour. # The options below are for compatibility to configure's default behaviour.
set(SDL_SHARED ON CACHE BOOL "Build a shared version of the library") 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") set(SDL_STATIC ON CACHE BOOL "Build a static version of the library")
# General source files # General source files
@ -317,7 +351,7 @@ if(USE_GCC OR USE_CLANG)
set(CMAKE_REQUIRED_FLAGS "-mpreferred-stack-boundary=2") set(CMAKE_REQUIRED_FLAGS "-mpreferred-stack-boundary=2")
check_c_source_compiles("int x = 0; int main(int argc, char **argv) {}" check_c_source_compiles("int x = 0; int main(int argc, char **argv) {}"
HAVE_GCC_PREFERRED_STACK_BOUNDARY) HAVE_GCC_PREFERRED_STACK_BOUNDARY)
set(CMAKE_REQUIRED_FLAGS) set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
set(CMAKE_REQUIRED_FLAGS "-fvisibility=hidden -Werror") set(CMAKE_REQUIRED_FLAGS "-fvisibility=hidden -Werror")
check_c_source_compiles(" check_c_source_compiles("
@ -328,7 +362,7 @@ if(USE_GCC OR USE_CLANG)
if(HAVE_GCC_FVISIBILITY) if(HAVE_GCC_FVISIBILITY)
list(APPEND EXTRA_CFLAGS "-fvisibility=hidden") list(APPEND EXTRA_CFLAGS "-fvisibility=hidden")
endif() endif()
set(CMAKE_REQUIRED_FLAGS) set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
check_c_compiler_flag(-Wall HAVE_GCC_WALL) check_c_compiler_flag(-Wall HAVE_GCC_WALL)
if(HAVE_GCC_WALL) if(HAVE_GCC_WALL)
@ -376,7 +410,7 @@ if(ASSEMBLY)
if(HAVE_MMX) if(HAVE_MMX)
list(APPEND EXTRA_CFLAGS "-mmmx") list(APPEND EXTRA_CFLAGS "-mmmx")
endif() endif()
set(CMAKE_REQUIRED_FLAGS) set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
endif() endif()
if(3DNOW) if(3DNOW)
@ -393,7 +427,7 @@ if(ASSEMBLY)
if(HAVE_3DNOW) if(HAVE_3DNOW)
list(APPEND EXTRA_CFLAGS "-m3dnow") list(APPEND EXTRA_CFLAGS "-m3dnow")
endif() endif()
set(CMAKE_REQUIRED_FLAGS) set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
endif() endif()
if(SSE) if(SSE)
@ -416,7 +450,7 @@ if(ASSEMBLY)
if(HAVE_SSE) if(HAVE_SSE)
list(APPEND EXTRA_CFLAGS "-msse") list(APPEND EXTRA_CFLAGS "-msse")
endif() endif()
set(CMAKE_REQUIRED_FLAGS) set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
endif() endif()
if(SSE2) if(SSE2)
@ -439,7 +473,7 @@ if(ASSEMBLY)
if(HAVE_SSE2) if(HAVE_SSE2)
list(APPEND EXTRA_CFLAGS "-msse2") list(APPEND EXTRA_CFLAGS "-msse2")
endif() endif()
set(CMAKE_REQUIRED_FLAGS) set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
endif() endif()
if(SSEMATH) if(SSEMATH)
@ -464,7 +498,7 @@ if(ASSEMBLY)
return vec_splat_u32(0); return vec_splat_u32(0);
} }
int main(int argc, char **argv) { }" HAVE_ALTIVEC) int main(int argc, char **argv) { }" HAVE_ALTIVEC)
set(CMAKE_REQUIRED_FLAGS) set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
if(HAVE_ALTIVEC OR HAVE_ALTIVEC_H_HDR) if(HAVE_ALTIVEC OR HAVE_ALTIVEC_H_HDR)
set(HAVE_ALTIVEC TRUE) # if only HAVE_ALTIVEC_H_HDR is set set(HAVE_ALTIVEC TRUE) # if only HAVE_ALTIVEC_H_HDR is set
list(APPEND EXTRA_CFLAGS "-maltivec") list(APPEND EXTRA_CFLAGS "-maltivec")
@ -486,7 +520,7 @@ if(ASSEMBLY)
set(SDL_ASSEMBLY_ROUTINES 1) set(SDL_ASSEMBLY_ROUTINES 1)
endif() endif()
# TODO: # TODO:
#else(ASSEMBLY) #else()
# if(USE_GCC OR USE_CLANG) # if(USE_GCC OR USE_CLANG)
# list(APPEND EXTRA_CFLAGS "-mno-sse" "-mno-sse2" "-mno-mmx") # list(APPEND EXTRA_CFLAGS "-mno-sse" "-mno-sse2" "-mno-mmx")
# endif() # endif()
@ -518,7 +552,7 @@ if(LIBC)
set(HAVE_M_PI 1) set(HAVE_M_PI 1)
add_definitions(-D_USE_MATH_DEFINES) # needed for M_PI add_definitions(-D_USE_MATH_DEFINES) # needed for M_PI
set(STDC_HEADERS 1) set(STDC_HEADERS 1)
else(WINDOWS AND NOT MINGW) else()
set(HAVE_LIBC TRUE) set(HAVE_LIBC TRUE)
check_include_file(sys/types.h HAVE_SYS_TYPES_H) check_include_file(sys/types.h HAVE_SYS_TYPES_H)
foreach(_HEADER foreach(_HEADER
@ -555,7 +589,7 @@ if(LIBC)
set(CMAKE_REQUIRED_LIBRARIES m) set(CMAKE_REQUIRED_LIBRARIES m)
foreach(_FN foreach(_FN
atan atan2 ceil copysign cos cosf fabs floor log pow scalbn sin atan atan2 ceil copysign cos cosf fabs floor log pow scalbn sin
sinf sqrt sqrtf tan tanf) sinf sqrt sqrtf tan tanf acos asin)
string(TOUPPER ${_FN} _UPPER) string(TOUPPER ${_FN} _UPPER)
set(_HAVEVAR "HAVE_${_UPPER}") set(_HAVEVAR "HAVE_${_UPPER}")
check_function_exists("${_FN}" ${_HAVEVAR}) check_function_exists("${_FN}" ${_HAVEVAR})
@ -567,11 +601,20 @@ if(LIBC)
check_library_exists(iconv iconv_open "" HAVE_LIBICONV) check_library_exists(iconv iconv_open "" HAVE_LIBICONV)
if(HAVE_LIBICONV) if(HAVE_LIBICONV)
list(APPEND EXTRA_LIBS iconv) list(APPEND EXTRA_LIBS iconv)
set(HAVE_ICONV 1)
endif()
if(NOT APPLE)
check_include_file(alloca.h HAVE_ALLOCA_H)
check_function_exists(alloca HAVE_ALLOCA)
else()
set(HAVE_ALLOCA_H 1)
set(HAVE_ALLOCA 1)
endif() endif()
check_struct_has_member("struct sigaction" "sa_sigaction" "signal.h" HAVE_SA_SIGACTION) check_struct_has_member("struct sigaction" "sa_sigaction" "signal.h" HAVE_SA_SIGACTION)
endif() endif()
else(LIBC) else()
if(WINDOWS) if(WINDOWS)
set(HAVE_STDARG_H 1) set(HAVE_STDARG_H 1)
set(HAVE_STDDEF_H 1) set(HAVE_STDDEF_H 1)
@ -642,7 +685,49 @@ if(SDL_VIDEO)
endif() endif()
# Platform-specific options and settings # Platform-specific options and settings
if(UNIX AND NOT APPLE) if(EMSCRIPTEN)
# Hide noisy warnings that intend to aid mostly during initial stages of porting a new
# project. Uncomment at will for verbose cross-compiling -I/../ path info.
add_definitions(-Wno-warn-absolute-paths)
if(SDL_AUDIO)
set(SDL_AUDIO_DRIVER_EMSCRIPTEN 1)
file(GLOB EM_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/emscripten/*.c)
set(SOURCE_FILES ${SOURCE_FILES} ${EM_AUDIO_SOURCES})
set(HAVE_SDL_AUDIO TRUE)
endif()
if(SDL_FILESYSTEM)
set(SDL_FILESYSTEM_EMSCRIPTEN 1)
file(GLOB EM_FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/emscripten/*.c)
set(SOURCE_FILES ${SOURCE_FILES} ${EM_FILESYSTEM_SOURCES})
set(HAVE_SDL_FILESYSTEM TRUE)
endif()
if(SDL_JOYSTICK)
set(SDL_JOYSTICK_EMSCRIPTEN 1)
file(GLOB EM_JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/emscripten/*.c)
set(SOURCE_FILES ${SOURCE_FILES} ${EM_JOYSTICK_SOURCES})
set(HAVE_SDL_JOYSTICK TRUE)
endif()
if(SDL_POWER)
set(SDL_POWER_EMSCRIPTEN 1)
file(GLOB EM_POWER_SOURCES ${SDL2_SOURCE_DIR}/src/power/emscripten/*.c)
set(SOURCE_FILES ${SOURCE_FILES} ${EM_POWER_SOURCES})
set(HAVE_SDL_POWER TRUE)
endif()
if(SDL_VIDEO)
set(SDL_VIDEO_DRIVER_EMSCRIPTEN 1)
file(GLOB EM_VIDEO_SOURCES ${SDL2_SOURCE_DIR}/src/video/emscripten/*.c)
set(SOURCE_FILES ${SOURCE_FILES} ${EM_VIDEO_SOURCES})
set(HAVE_SDL_VIDEO TRUE)
#enable gles
if(VIDEO_OPENGLES)
set(SDL_VIDEO_OPENGL_EGL 1)
set(HAVE_VIDEO_OPENGLES TRUE)
set(SDL_VIDEO_OPENGL_ES2 1)
set(SDL_VIDEO_RENDER_OGL_ES2 1)
endif()
endif()
elseif(UNIX AND NOT APPLE)
if(SDL_AUDIO) if(SDL_AUDIO)
if(SYSV5 OR SOLARIS OR HPUX) if(SYSV5 OR SOLARIS OR HPUX)
set(SDL_AUDIO_DRIVER_SUNAUDIO 1) set(SDL_AUDIO_DRIVER_SUNAUDIO 1)
@ -752,7 +837,7 @@ if(UNIX AND NOT APPLE)
if(FOUND_CLOCK_GETTIME) if(FOUND_CLOCK_GETTIME)
list(APPEND EXTRA_LIBS rt) list(APPEND EXTRA_LIBS rt)
set(HAVE_CLOCK_GETTIME 1) set(HAVE_CLOCK_GETTIME 1)
else(FOUND_CLOCK_GETTIME) else()
check_library_exists(c clock_gettime "" FOUND_CLOCK_GETTIME) check_library_exists(c clock_gettime "" FOUND_CLOCK_GETTIME)
if(FOUND_CLOCK_GETTIME) if(FOUND_CLOCK_GETTIME)
set(HAVE_CLOCK_GETTIME 1) set(HAVE_CLOCK_GETTIME 1)
@ -829,7 +914,7 @@ elseif(WINDOWS)
link_directories($ENV{DXSDK_DIR}\\lib\\${PROCESSOR_ARCH}) link_directories($ENV{DXSDK_DIR}\\lib\\${PROCESSOR_ARCH})
include_directories($ENV{DXSDK_DIR}\\Include) include_directories($ENV{DXSDK_DIR}\\Include)
endif() endif()
set(CMAKE_REQUIRED_FLAGS) set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
endif() endif()
if(SDL_AUDIO) if(SDL_AUDIO)
@ -978,7 +1063,7 @@ elseif(APPLE)
endif() endif()
if(SDL_AUDIO) if(SDL_AUDIO)
set(MACOSX_COREAUDIO 1) 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/*.c)
set(SOURCE_FILES ${SOURCE_FILES} ${AUDIO_SOURCES}) set(SOURCE_FILES ${SOURCE_FILES} ${AUDIO_SOURCES})
set(HAVE_SDL_AUDIO TRUE) set(HAVE_SDL_AUDIO TRUE)
@ -1068,10 +1153,6 @@ elseif(APPLE)
set(SDL_VIDEO_OPENGL 1) set(SDL_VIDEO_OPENGL 1)
set(SDL_VIDEO_OPENGL_CGL 1) set(SDL_VIDEO_OPENGL_CGL 1)
set(SDL_VIDEO_RENDER_OGL 1) set(SDL_VIDEO_RENDER_OGL 1)
if(DARWIN)
find_library(OpenGL_LIBRARY OpenGL)
list(APPEND EXTRA_LIBRARIES ${OpenGL_LIBRARY})
endif()
set(HAVE_VIDEO_OPENGL TRUE) set(HAVE_VIDEO_OPENGL TRUE)
endif() endif()
endif() endif()
@ -1193,14 +1274,14 @@ if(NOT WINDOWS OR CYGWIN)
if(SDL_STATIC) if(SDL_STATIC)
set(ENABLE_STATIC_TRUE "") set(ENABLE_STATIC_TRUE "")
set(ENABLE_STATIC_FALSE "#") set(ENABLE_STATIC_FALSE "#")
else(SDL_STATIC) else()
set(ENABLE_STATIC_TRUE "#") set(ENABLE_STATIC_TRUE "#")
set(ENABLE_STATIC_FALSE "") set(ENABLE_STATIC_FALSE "")
endif() endif()
if(SDL_SHARED) if(SDL_SHARED)
set(ENABLE_SHARED_TRUE "") set(ENABLE_SHARED_TRUE "")
set(ENABLE_SHARED_FALSE "#") set(ENABLE_SHARED_FALSE "#")
else(SDL_SHARED) else()
set(ENABLE_SHARED_TRUE "#") set(ENABLE_SHARED_TRUE "#")
set(ENABLE_SHARED_FALSE "") set(ENABLE_SHARED_FALSE "")
endif() endif()
@ -1281,7 +1362,7 @@ if(SDL_SHARED)
VERSION ${LT_VERSION} VERSION ${LT_VERSION}
SOVERSION ${LT_REVISION} SOVERSION ${LT_REVISION}
OUTPUT_NAME "SDL2-${LT_RELEASE}") OUTPUT_NAME "SDL2-${LT_RELEASE}")
else(UNIX) else()
set_target_properties(SDL2 PROPERTIES set_target_properties(SDL2 PROPERTIES
VERSION ${SDL_VERSION} VERSION ${SDL_VERSION}
SOVERSION ${LT_REVISION} SOVERSION ${LT_REVISION}
@ -1330,7 +1411,7 @@ if(NOT WINDOWS OR CYGWIN)
if(FREEBSD) if(FREEBSD)
# FreeBSD uses ${PREFIX}/libdata/pkgconfig # FreeBSD uses ${PREFIX}/libdata/pkgconfig
install(FILES ${SDL2_BINARY_DIR}/sdl2.pc DESTINATION "libdata/pkgconfig") install(FILES ${SDL2_BINARY_DIR}/sdl2.pc DESTINATION "libdata/pkgconfig")
else(FREEBSD) else()
install(FILES ${SDL2_BINARY_DIR}/sdl2.pc install(FILES ${SDL2_BINARY_DIR}/sdl2.pc
DESTINATION "lib${LIB_SUFFIX}/pkgconfig") DESTINATION "lib${LIB_SUFFIX}/pkgconfig")
endif() endif()

View File

@ -1,7 +1,7 @@
Summary: Simple DirectMedia Layer Summary: Simple DirectMedia Layer
Name: SDL2 Name: SDL2
Version: @SDL_VERSION@ Version: @SDL_VERSION@
Release: 1 Release: 2
Source: http://www.libsdl.org/release/%{name}-%{version}.tar.gz Source: http://www.libsdl.org/release/%{name}-%{version}.tar.gz
URL: http://www.libsdl.org/ URL: http://www.libsdl.org/
License: zlib License: zlib
@ -63,12 +63,12 @@ rm -rf $RPM_BUILD_ROOT
%files %files
%{__defattr} %{__defattr}
%doc README-SDL.txt COPYING.txt CREDITS.txt BUGS.txt %doc README*.txt COPYING.txt CREDITS.txt BUGS.txt
%{_libdir}/lib*.%{__soext}.* %{_libdir}/lib*.%{__soext}.*
%files devel %files devel
%{__defattr} %{__defattr}
%doc README README-SDL.txt COPYING CREDITS BUGS WhatsNew %doc README*.txt COPYING.txt CREDITS.txt BUGS.txt WhatsNew.txt
%{_bindir}/*-config %{_bindir}/*-config
%{_libdir}/lib*.a %{_libdir}/lib*.a
%{_libdir}/lib*.la %{_libdir}/lib*.la
@ -78,13 +78,16 @@ rm -rf $RPM_BUILD_ROOT
%{_datadir}/aclocal/* %{_datadir}/aclocal/*
%changelog %changelog
* Sun Dec 07 2014 Simone Contini <s.contini@oltrelinux.com>
- Fixed changelog date issue and docs filenames
* Sun Jan 22 2012 Sam Lantinga <slouken@libsdl.org> * Sun Jan 22 2012 Sam Lantinga <slouken@libsdl.org>
- Updated for SDL 2.0 - Updated for SDL 2.0
* Tue May 16 2006 Sam Lantinga <slouken@libsdl.org> * Tue May 16 2006 Sam Lantinga <slouken@libsdl.org>
- Removed support for Darwin, due to build problems on ps2linux - Removed support for Darwin, due to build problems on ps2linux
* Mon Jan 03 2004 Anders Bjorklund <afb@algonet.se> * Sat Jan 03 2004 Anders Bjorklund <afb@algonet.se>
- Added support for Darwin, updated spec file - Added support for Darwin, updated spec file
* Wed Jan 19 2000 Sam Lantinga <slouken@libsdl.org> * Wed Jan 19 2000 Sam Lantinga <slouken@libsdl.org>

View File

@ -387,6 +387,9 @@ main(int argc, char *argv[])
SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 0); SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 0);
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1); SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
/* create main window and renderer */ /* create main window and renderer */
window = SDL_CreateWindow(NULL, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, window = SDL_CreateWindow(NULL, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT,
SDL_WINDOW_OPENGL | SDL_WINDOW_OPENGL |

View File

@ -1274,8 +1274,14 @@
FD6526640DE8FCCB002AD96B /* Debug */ = { FD6526640DE8FCCB002AD96B /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
IPHONEOS_DEPLOYMENT_TARGET = 5.1.1; IPHONEOS_DEPLOYMENT_TARGET = 5.1.1;
GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = YES;
GCC_WARN_STRICT_SELECTOR_MATCH = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
PRODUCT_NAME = SDL2; PRODUCT_NAME = SDL2;
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
}; };
@ -1284,8 +1290,14 @@
FD6526650DE8FCCB002AD96B /* Release */ = { FD6526650DE8FCCB002AD96B /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
COPY_PHASE_STRIP = YES; COPY_PHASE_STRIP = YES;
IPHONEOS_DEPLOYMENT_TARGET = 5.1.1; IPHONEOS_DEPLOYMENT_TARGET = 5.1.1;
GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = YES;
GCC_WARN_STRICT_SELECTOR_MATCH = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
PRODUCT_NAME = SDL2; PRODUCT_NAME = SDL2;
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
}; };

View File

@ -8,6 +8,15 @@
android:versionName="1.0" android:versionName="1.0"
android:installLocation="auto"> android:installLocation="auto">
<!-- Android 2.3.3 -->
<uses-sdk android:minSdkVersion="10" android:targetSdkVersion="12" />
<!-- OpenGL ES 2.0 -->
<uses-feature android:glEsVersion="0x00020000" />
<!-- Allow writing to external storage -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- Create a Java class extending SDLActivity and place it in a <!-- Create a Java class extending SDLActivity and place it in a
directory under src matching the package, e.g. directory under src matching the package, e.g.
src/com/gamemaker/game/MyGame.java src/com/gamemaker/game/MyGame.java
@ -33,12 +42,4 @@
</activity> </activity>
</application> </application>
<!-- Android 2.3.3 -->
<uses-sdk android:minSdkVersion="10" android:targetSdkVersion="12" />
<!-- OpenGL ES 2.0 -->
<uses-feature android:glEsVersion="0x00020000" />
<!-- Allow writing to external storage -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest> </manifest>

View File

@ -41,6 +41,10 @@ public class SDLActivity extends Activity {
/** If shared libraries (e.g. SDL or the native application) could not be loaded. */ /** If shared libraries (e.g. SDL or the native application) could not be loaded. */
public static boolean mBrokenLibraries; public static boolean mBrokenLibraries;
// If we want to separate mouse and touch events.
// This is only toggled in native code when a hint is set!
public static boolean mSeparateMouseAndTouch;
// Main components // Main components
protected static SDLActivity mSingleton; protected static SDLActivity mSingleton;
protected static SDLSurface mSurface; protected static SDLSurface mSurface;
@ -81,7 +85,6 @@ public class SDLActivity extends Activity {
} }
/** /**
* This method is called by SDL using JNI.
* This method is called by SDL before starting the native application thread. * This method is called by SDL before starting the native application thread.
* It can be overridden to provide the arguments after the application name. * It can be overridden to provide the arguments after the application name.
* The default implementation returns an empty array. It never returns null. * The default implementation returns an empty array. It never returns null.
@ -111,6 +114,8 @@ public class SDLActivity extends Activity {
// Setup // Setup
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
Log.v("SDL", "Device: " + android.os.Build.DEVICE);
Log.v("SDL", "Model: " + android.os.Build.MODEL);
Log.v("SDL", "onCreate():" + mSingleton); Log.v("SDL", "onCreate():" + mSingleton);
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -392,7 +397,7 @@ public class SDLActivity extends Activity {
public static native void nativeQuit(); public static native void nativeQuit();
public static native void nativePause(); public static native void nativePause();
public static native void nativeResume(); public static native void nativeResume();
public static native void onNativeResize(int x, int y, int format); public static native void onNativeResize(int x, int y, int format, float rate);
public static native int onNativePadDown(int device_id, int keycode); public static native int onNativePadDown(int device_id, int keycode);
public static native int onNativePadUp(int device_id, int keycode); public static native int onNativePadUp(int device_id, int keycode);
public static native void onNativeJoy(int device_id, int axis, public static native void onNativeJoy(int device_id, int axis,
@ -402,6 +407,7 @@ public class SDLActivity extends Activity {
public static native void onNativeKeyDown(int keycode); public static native void onNativeKeyDown(int keycode);
public static native void onNativeKeyUp(int keycode); public static native void onNativeKeyUp(int keycode);
public static native void onNativeKeyboardFocusLost(); public static native void onNativeKeyboardFocusLost();
public static native void onNativeMouse(int button, int action, float x, float y);
public static native void onNativeTouch(int touchDevId, int pointerFingerId, public static native void onNativeTouch(int touchDevId, int pointerFingerId,
int action, float x, int action, float x,
float y, float p); float y, float p);
@ -1041,7 +1047,7 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
mWidth = width; mWidth = width;
mHeight = height; mHeight = height;
SDLActivity.onNativeResize(width, height, sdlFormat); SDLActivity.onNativeResize(width, height, sdlFormat, mDisplay.getRefreshRate());
Log.v("SDL", "Window size:" + width + "x"+height); Log.v("SDL", "Window size:" + width + "x"+height);
// Set mIsSurfaceReady to 'true' *before* making a call to handleResume // Set mIsSurfaceReady to 'true' *before* making a call to handleResume
@ -1088,8 +1094,8 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
// Dispatch the different events depending on where they come from // Dispatch the different events depending on where they come from
// Some SOURCE_DPAD or SOURCE_GAMEPAD are also SOURCE_KEYBOARD // 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 // So, we try to process them as DPAD or GAMEPAD events first, if that fails we try them as KEYBOARD
if ( (event.getSource() & 0x00000401) != 0 || /* API 12: SOURCE_GAMEPAD */ if ( (event.getSource() & InputDevice.SOURCE_GAMEPAD) != 0 ||
(event.getSource() & InputDevice.SOURCE_DPAD) != 0 ) { (event.getSource() & InputDevice.SOURCE_DPAD) != 0 ) {
if (event.getAction() == KeyEvent.ACTION_DOWN) { if (event.getAction() == KeyEvent.ACTION_DOWN) {
if (SDLActivity.onNativePadDown(event.getDeviceId(), keyCode) == 0) { if (SDLActivity.onNativePadDown(event.getDeviceId(), keyCode) == 0) {
@ -1126,50 +1132,65 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
final int pointerCount = event.getPointerCount(); final int pointerCount = event.getPointerCount();
int action = event.getActionMasked(); int action = event.getActionMasked();
int pointerFingerId; int pointerFingerId;
int mouseButton;
int i = -1; int i = -1;
float x,y,p; float x,y,p;
switch(action) { // !!! FIXME: dump this SDK check after 2.0.4 ships and require API14.
case MotionEvent.ACTION_MOVE: if (event.getSource() == InputDevice.SOURCE_MOUSE && SDLActivity.mSeparateMouseAndTouch) {
for (i = 0; i < pointerCount; i++) { if (Build.VERSION.SDK_INT < 14) {
mouseButton = 1; // For Android==12 all mouse buttons are the left button
} else {
try {
mouseButton = (Integer) event.getClass().getMethod("getButtonState").invoke(event);
} catch(Exception e) {
mouseButton = 1; // oh well.
}
}
SDLActivity.onNativeMouse(mouseButton, action, event.getX(0), event.getY(0));
} else {
switch(action) {
case MotionEvent.ACTION_MOVE:
for (i = 0; i < pointerCount; i++) {
pointerFingerId = event.getPointerId(i);
x = event.getX(i) / mWidth;
y = event.getY(i) / mHeight;
p = event.getPressure(i);
SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, p);
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_DOWN:
// Primary pointer up/down, the index is always zero
i = 0;
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_POINTER_DOWN:
// Non primary pointer up/down
if (i == -1) {
i = event.getActionIndex();
}
pointerFingerId = event.getPointerId(i); pointerFingerId = event.getPointerId(i);
x = event.getX(i) / mWidth; x = event.getX(i) / mWidth;
y = event.getY(i) / mHeight; y = event.getY(i) / mHeight;
p = event.getPressure(i); p = event.getPressure(i);
SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, p); SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, p);
} break;
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_DOWN:
// Primary pointer up/down, the index is always zero
i = 0;
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_POINTER_DOWN:
// Non primary pointer up/down
if (i == -1) {
i = event.getActionIndex();
}
pointerFingerId = event.getPointerId(i); case MotionEvent.ACTION_CANCEL:
x = event.getX(i) / mWidth; for (i = 0; i < pointerCount; i++) {
y = event.getY(i) / mHeight; pointerFingerId = event.getPointerId(i);
p = event.getPressure(i); x = event.getX(i) / mWidth;
SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, p); y = event.getY(i) / mHeight;
break; p = event.getPressure(i);
SDLActivity.onNativeTouch(touchDevId, pointerFingerId, MotionEvent.ACTION_UP, x, y, p);
case MotionEvent.ACTION_CANCEL: }
for (i = 0; i < pointerCount; i++) { break;
pointerFingerId = event.getPointerId(i);
x = event.getX(i) / mWidth;
y = event.getY(i) / mHeight;
p = event.getPressure(i);
SDLActivity.onNativeTouch(touchDevId, pointerFingerId, MotionEvent.ACTION_UP, x, y, p);
}
break;
default: default:
break; break;
}
} }
return true; return true;
@ -1500,9 +1521,44 @@ class SDLJoystickHandler_API12 extends SDLJoystickHandler {
class SDLGenericMotionListener_API12 implements View.OnGenericMotionListener { class SDLGenericMotionListener_API12 implements View.OnGenericMotionListener {
// Generic Motion (mouse hover, joystick...) events go here // Generic Motion (mouse hover, joystick...) events go here
// We only have joysticks yet
@Override @Override
public boolean onGenericMotion(View v, MotionEvent event) { public boolean onGenericMotion(View v, MotionEvent event) {
return SDLActivity.handleJoystickMotionEvent(event); float x, y;
int mouseButton;
int action;
switch ( event.getSource() ) {
case InputDevice.SOURCE_JOYSTICK:
case InputDevice.SOURCE_GAMEPAD:
case InputDevice.SOURCE_DPAD:
SDLActivity.handleJoystickMotionEvent(event);
return true;
case InputDevice.SOURCE_MOUSE:
action = event.getActionMasked();
switch (action) {
case MotionEvent.ACTION_SCROLL:
x = event.getAxisValue(MotionEvent.AXIS_HSCROLL, 0);
y = event.getAxisValue(MotionEvent.AXIS_VSCROLL, 0);
SDLActivity.onNativeMouse(0, action, x, y);
return true;
case MotionEvent.ACTION_HOVER_MOVE:
x = event.getX(0);
y = event.getY(0);
SDLActivity.onNativeMouse(0, action, x, y);
return true;
default:
break;
}
default:
break;
}
// Event was not managed
return false;
} }
} }

View File

@ -898,6 +898,7 @@ EOF
else else
case `sed -n '/^Hardware/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in case `sed -n '/^Hardware/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
BCM2708) MANUFACTURER=raspberry;; BCM2708) MANUFACTURER=raspberry;;
BCM2709) MANUFACTURER=raspberry;;
*) MANUFACTURER=unknown;; *) MANUFACTURER=unknown;;
esac esac
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \

View File

@ -1534,6 +1534,8 @@ case $os in
-pnacl*) -pnacl*)
os=-pnacl os=-pnacl
;; ;;
-emscripten*)
;;
-none) -none)
;; ;;
*) *)

View File

@ -0,0 +1,72 @@
#!/bin/bash
SDKDIR="/emsdk_portable"
ENVSCRIPT="$SDKDIR/emsdk_env.sh"
if [ ! -f "$ENVSCRIPT" ]; then
echo "ERROR: This script expects the Emscripten SDK to be in '$SDKDIR'." 1>&2
exit 1
fi
TARBALL="$1"
if [ -z $1 ]; then
TARBALL=sdl-emscripten.tar.xz
fi
cd `dirname "$0"`
cd ..
SDLBASE=`pwd`
if [ -z "$MAKE" ]; then
OSTYPE=`uname -s`
if [ "$OSTYPE" == "Linux" ]; then
NCPU=`cat /proc/cpuinfo |grep vendor_id |wc -l`
let NCPU=$NCPU+1
elif [ "$OSTYPE" = "Darwin" ]; then
NCPU=`sysctl -n hw.ncpu`
elif [ "$OSTYPE" = "SunOS" ]; then
NCPU=`/usr/sbin/psrinfo |wc -l |sed -e 's/^ *//g;s/ *$//g'`
else
NCPU=1
fi
if [ -z "$NCPU" ]; then
NCPU=1
elif [ "$NCPU" = "0" ]; then
NCPU=1
fi
MAKE="make -j$NCPU"
fi
echo "\$MAKE is '$MAKE'"
echo "Setting up Emscripten SDK environment..."
source "$ENVSCRIPT"
echo "Setting up..."
set -x
cd "$SDLBASE"
rm -rf buildbot
mkdir buildbot
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"
echo "Building..."
emmake $MAKE
echo "Moving things around..."
emmake $MAKE install
# 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
mv ./emscripten-sdl2-installed ./usr/local
popd
tar -cJvvf $TARBALL -C buildbot usr
rm -rf buildbot
exit 0
# end of emscripten-buildbot.sh ...

View File

@ -0,0 +1,31 @@
@echo off
rem just a helper batch file for collecting up files and zipping them.
rem usage: windows-buildbot-zipper.bat <zipfilename>
rem must be run from root of SDL source tree.
IF EXIST VisualC\Win32\Release GOTO okaydir
echo Please run from root of source tree after doing a Release build.
GOTO done
:okaydir
erase /q /f /s zipper
IF EXIST zipper GOTO zippermade
mkdir zipper
:zippermade
cd zipper
mkdir SDL
cd SDL
mkdir include
mkdir lib
mkdir lib\win32
copy ..\..\include\*.h include\
copy ..\..\VisualC\Win32\Release\SDL2.dll lib\win32\
copy ..\..\VisualC\Win32\Release\SDL2.lib lib\win32\
copy ..\..\VisualC\Win32\Release\SDL2main.lib lib\win32\
cd ..
zip -9r ..\%1 SDL
cd ..
erase /q /f /s zipper
:done

View File

@ -66,7 +66,7 @@ endmacro()
macro(CHECK_OBJC_SOURCE_COMPILES SOURCE VAR) macro(CHECK_OBJC_SOURCE_COMPILES SOURCE VAR)
set(PREV_REQUIRED_DEFS "${CMAKE_REQUIRED_DEFINITIONS}") set(PREV_REQUIRED_DEFS "${CMAKE_REQUIRED_DEFINITIONS}")
set(CMAKE_REQUIRED_DEFINITIONS "-ObjC ${PREV_REQUIRED_DEFS}") set(CMAKE_REQUIRED_DEFINITIONS "-x objective-c ${PREV_REQUIRED_DEFS}")
CHECK_C_SOURCE_COMPILES(${SOURCE} ${VAR}) CHECK_C_SOURCE_COMPILES(${SOURCE} ${VAR})
set(CMAKE_REQUIRED_DEFINITIONS "${PREV_REQUIRED_DEFS}") set(CMAKE_REQUIRED_DEFINITIONS "${PREV_REQUIRED_DEFS}")
endmacro() endmacro()

View File

@ -39,7 +39,7 @@ macro(CheckDLOPEN)
set(_DLLIB ${_LIBNAME}) set(_DLLIB ${_LIBNAME})
set(HAVE_DLOPEN TRUE) set(HAVE_DLOPEN TRUE)
break() break()
endif(DLOPEN_LIB) endif()
endforeach() endforeach()
endif() endif()
@ -63,7 +63,7 @@ macro(CheckDLOPEN)
set(SOURCE_FILES ${SOURCE_FILES} ${DLOPEN_SOURCES}) set(SOURCE_FILES ${SOURCE_FILES} ${DLOPEN_SOURCES})
set(HAVE_SDL_LOADSO TRUE) set(HAVE_SDL_LOADSO TRUE)
endif() endif()
endmacro(CheckDLOPEN) endmacro()
# Requires: # Requires:
# - n/a # - n/a
@ -78,23 +78,23 @@ macro(CheckOSS)
check_c_source_compiles(" check_c_source_compiles("
#include <soundcard.h> #include <soundcard.h>
int main() { int arg = SNDCTL_DSP_SETFRAGMENT; }" OSS_FOUND) int main() { int arg = SNDCTL_DSP_SETFRAGMENT; }" OSS_FOUND)
endif(NOT OSS_FOUND) endif()
if(OSS_FOUND) if(OSS_FOUND)
set(HAVE_OSS TRUE) set(HAVE_OSS TRUE)
file(GLOB OSS_SOURCES ${SDL2_SOURCE_DIR}/src/audio/dsp/*.c) file(GLOB OSS_SOURCES ${SDL2_SOURCE_DIR}/src/audio/dsp/*.c)
if(OSS_HEADER_FILE STREQUAL "soundcard.h") if(OSS_HEADER_FILE STREQUAL "soundcard.h")
set(SDL_AUDIO_DRIVER_OSS_SOUNDCARD_H 1) set(SDL_AUDIO_DRIVER_OSS_SOUNDCARD_H 1)
endif(OSS_HEADER_FILE STREQUAL "soundcard.h") endif()
set(SDL_AUDIO_DRIVER_OSS 1) set(SDL_AUDIO_DRIVER_OSS 1)
set(SOURCE_FILES ${SOURCE_FILES} ${OSS_SOURCES}) set(SOURCE_FILES ${SOURCE_FILES} ${OSS_SOURCES})
if(NETBSD OR OPENBSD) if(NETBSD OR OPENBSD)
list(APPEND EXTRA_LIBS ossaudio) list(APPEND EXTRA_LIBS ossaudio)
endif(NETBSD OR OPENBSD) endif()
set(HAVE_SDL_AUDIO TRUE) set(HAVE_SDL_AUDIO TRUE)
endif(OSS_FOUND) endif()
endif(OSS) endif()
endmacro(CheckOSS) endmacro()
# Requires: # Requires:
# - n/a # - n/a
@ -117,14 +117,14 @@ macro(CheckALSA)
FindLibraryAndSONAME("asound") FindLibraryAndSONAME("asound")
set(SDL_AUDIO_DRIVER_ALSA_DYNAMIC "\"${ASOUND_LIB_SONAME}\"") set(SDL_AUDIO_DRIVER_ALSA_DYNAMIC "\"${ASOUND_LIB_SONAME}\"")
set(HAVE_ALSA_SHARED TRUE) set(HAVE_ALSA_SHARED TRUE)
endif(NOT HAVE_DLOPEN) endif()
else(ALSA_SHARED) else()
list(APPEND EXTRA_LIBS asound) list(APPEND EXTRA_LIBS asound)
endif(ALSA_SHARED) endif()
set(HAVE_SDL_AUDIO TRUE) set(HAVE_SDL_AUDIO TRUE)
endif(HAVE_ASOUNDLIB_H) endif()
endif(ALSA) endif()
endmacro(CheckALSA) endmacro()
# Requires: # Requires:
# - PkgCheckModules # - PkgCheckModules
@ -147,14 +147,14 @@ macro(CheckPulseAudio)
FindLibraryAndSONAME("pulse-simple") FindLibraryAndSONAME("pulse-simple")
set(SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC "\"${PULSE_SIMPLE_LIB_SONAME}\"") set(SDL_AUDIO_DRIVER_PULSEAUDIO_DYNAMIC "\"${PULSE_SIMPLE_LIB_SONAME}\"")
set(HAVE_PULSEAUDIO_SHARED TRUE) set(HAVE_PULSEAUDIO_SHARED TRUE)
endif(NOT HAVE_DLOPEN) endif()
else(PULSEAUDIO_SHARED) else()
list(APPEND EXTRA_LDFLAGS ${PKG_PULSEAUDIO_LDFLAGS}) list(APPEND EXTRA_LDFLAGS ${PKG_PULSEAUDIO_LDFLAGS})
endif(PULSEAUDIO_SHARED) endif()
set(HAVE_SDL_AUDIO TRUE) set(HAVE_SDL_AUDIO TRUE)
endif(PKG_PULSEAUDIO_FOUND) endif()
endif(PULSEAUDIO) endif()
endmacro(CheckPulseAudio) endmacro()
# Requires: # Requires:
# - PkgCheckModules # - PkgCheckModules
@ -177,14 +177,14 @@ macro(CheckESD)
FindLibraryAndSONAME(esd) FindLibraryAndSONAME(esd)
set(SDL_AUDIO_DRIVER_ESD_DYNAMIC "\"${ESD_LIB_SONAME}\"") set(SDL_AUDIO_DRIVER_ESD_DYNAMIC "\"${ESD_LIB_SONAME}\"")
set(HAVE_ESD_SHARED TRUE) set(HAVE_ESD_SHARED TRUE)
endif(NOT HAVE_DLOPEN) endif()
else(ESD_SHARED) else()
list(APPEND EXTRA_LDFLAGS ${PKG_ESD_LDFLAGS}) list(APPEND EXTRA_LDFLAGS ${PKG_ESD_LDFLAGS})
endif(ESD_SHARED) endif()
set(HAVE_SDL_AUDIO TRUE) set(HAVE_SDL_AUDIO TRUE)
endif(PKG_ESD_FOUND) endif()
endif(ESD) endif()
endmacro(CheckESD) endmacro()
# Requires: # Requires:
# - n/a # - n/a
@ -212,14 +212,14 @@ macro(CheckARTS)
FindLibraryAndSONAME(artsc) FindLibraryAndSONAME(artsc)
set(SDL_AUDIO_DRIVER_ARTS_DYNAMIC "\"${ARTSC_LIB_SONAME}\"") set(SDL_AUDIO_DRIVER_ARTS_DYNAMIC "\"${ARTSC_LIB_SONAME}\"")
set(HAVE_ARTS_SHARED TRUE) set(HAVE_ARTS_SHARED TRUE)
endif(NOT HAVE_DLOPEN) endif()
else(ARTS_SHARED) else()
list(APPEND EXTRA_LDFLAGS ${ARTS_LIBS}) list(APPEND EXTRA_LDFLAGS ${ARTS_LIBS})
endif(ARTS_SHARED) endif()
set(HAVE_SDL_AUDIO TRUE) set(HAVE_SDL_AUDIO TRUE)
endif(ARTS_CONFIG) endif()
endif(ARTS) endif()
endmacro(CheckARTS) endmacro()
# Requires: # Requires:
# - n/a # - n/a
@ -243,14 +243,14 @@ macro(CheckNAS)
FindLibraryAndSONAME("audio") FindLibraryAndSONAME("audio")
set(SDL_AUDIO_DRIVER_NAS_DYNAMIC "\"${AUDIO_LIB_SONAME}\"") set(SDL_AUDIO_DRIVER_NAS_DYNAMIC "\"${AUDIO_LIB_SONAME}\"")
set(HAVE_NAS_SHARED TRUE) set(HAVE_NAS_SHARED TRUE)
endif(NOT HAVE_DLOPEN) endif()
else(NAS_SHARED) else()
list(APPEND EXTRA_LIBS ${D_NAS_LIB}) list(APPEND EXTRA_LIBS ${D_NAS_LIB})
endif(NAS_SHARED) endif()
set(HAVE_SDL_AUDIO TRUE) set(HAVE_SDL_AUDIO TRUE)
endif(HAVE_NAS_H AND D_NAS_LIB) endif()
endif(NAS) endif()
endmacro(CheckNAS) endmacro()
# Requires: # Requires:
# - n/a # - n/a
@ -274,14 +274,14 @@ macro(CheckSNDIO)
FindLibraryAndSONAME("sndio") FindLibraryAndSONAME("sndio")
set(SDL_AUDIO_DRIVER_SNDIO_DYNAMIC "\"${SNDIO_LIB_SONAME}\"") set(SDL_AUDIO_DRIVER_SNDIO_DYNAMIC "\"${SNDIO_LIB_SONAME}\"")
set(HAVE_SNDIO_SHARED TRUE) set(HAVE_SNDIO_SHARED TRUE)
endif(NOT HAVE_DLOPEN) endif()
else(SNDIO_SHARED) else()
list(APPEND EXTRA_LIBS ${D_SNDIO_LIB}) list(APPEND EXTRA_LIBS ${D_SNDIO_LIB})
endif(SNDIO_SHARED) endif()
set(HAVE_SDL_AUDIO TRUE) set(HAVE_SDL_AUDIO TRUE)
endif(HAVE_SNDIO_H AND D_SNDIO_LIB) endif()
endif(SNDIO) endif()
endmacro(CheckSNDIO) endmacro()
# Requires: # Requires:
# - PkgCheckModules # - PkgCheckModules
@ -304,14 +304,14 @@ macro(CheckFusionSound)
FindLibraryAndSONAME("fusionsound") FindLibraryAndSONAME("fusionsound")
set(SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC "\"${FUSIONSOUND_LIB_SONAME}\"") set(SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC "\"${FUSIONSOUND_LIB_SONAME}\"")
set(HAVE_FUSIONSOUND_SHARED TRUE) set(HAVE_FUSIONSOUND_SHARED TRUE)
endif(NOT HAVE_DLOPEN) endif()
else(FUSIONSOUND_SHARED) else()
list(APPEND EXTRA_LDFLAGS ${PKG_FUSIONSOUND_LDFLAGS}) list(APPEND EXTRA_LDFLAGS ${PKG_FUSIONSOUND_LDFLAGS})
endif(FUSIONSOUND_SHARED) endif()
set(HAVE_SDL_AUDIO TRUE) set(HAVE_SDL_AUDIO TRUE)
endif(PKG_FUSIONSOUND_FOUND) endif()
endif(FUSIONSOUND) endif()
endmacro(CheckFusionSound) endmacro()
# Requires: # Requires:
# - n/a # - n/a
@ -353,34 +353,34 @@ macro(CheckX11)
if(APPLE) if(APPLE)
set(X11_SHARED OFF) set(X11_SHARED OFF)
endif(APPLE) endif()
check_function_exists("shmat" HAVE_SHMAT) check_function_exists("shmat" HAVE_SHMAT)
if(NOT HAVE_SHMAT) if(NOT HAVE_SHMAT)
check_library_exists(ipc shmat "" HAVE_SHMAT) check_library_exists(ipc shmat "" HAVE_SHMAT)
if(HAVE_SHMAT) if(HAVE_SHMAT)
list(APPEND EXTRA_LIBS ipc) list(APPEND EXTRA_LIBS ipc)
endif(HAVE_SHMAT) endif()
if(NOT HAVE_SHMAT) if(NOT HAVE_SHMAT)
add_definitions(-DNO_SHARED_MEMORY) add_definitions(-DNO_SHARED_MEMORY)
set(X_CFLAGS "${X_CFLAGS} -DNO_SHARED_MEMORY") set(X_CFLAGS "${X_CFLAGS} -DNO_SHARED_MEMORY")
endif(NOT HAVE_SHMAT) endif()
endif(NOT HAVE_SHMAT) endif()
if(X11_SHARED) if(X11_SHARED)
if(NOT HAVE_DLOPEN) if(NOT HAVE_DLOPEN)
message_warn("You must have SDL_LoadObject() support for dynamic X11 loading") message_warn("You must have SDL_LoadObject() support for dynamic X11 loading")
set(HAVE_X11_SHARED FALSE) set(HAVE_X11_SHARED FALSE)
else(NOT HAVE_DLOPEN) else()
set(HAVE_X11_SHARED TRUE) set(HAVE_X11_SHARED TRUE)
endif() endif()
if(HAVE_X11_SHARED) if(HAVE_X11_SHARED)
set(SDL_VIDEO_DRIVER_X11_DYNAMIC "\"${X11_LIB_SONAME}\"") set(SDL_VIDEO_DRIVER_X11_DYNAMIC "\"${X11_LIB_SONAME}\"")
set(SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT "\"${XEXT_LIB_SONAME}\"") set(SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT "\"${XEXT_LIB_SONAME}\"")
else(HAVE_X11_SHARED) else()
list(APPEND EXTRA_LIBS ${X11_LIB} ${XEXT_LIB}) list(APPEND EXTRA_LIBS ${X11_LIB} ${XEXT_LIB})
endif(HAVE_X11_SHARED) endif()
endif(X11_SHARED) endif()
set(SDL_CFLAGS "${SDL_CFLAGS} ${X_CFLAGS}") set(SDL_CFLAGS "${SDL_CFLAGS} ${X_CFLAGS}")
@ -394,7 +394,7 @@ macro(CheckX11)
int main(int argc, char **argv) {}" HAVE_CONST_XEXT_ADDDISPLAY) int main(int argc, char **argv) {}" HAVE_CONST_XEXT_ADDDISPLAY)
if(HAVE_CONST_XEXT_ADDDISPLAY) if(HAVE_CONST_XEXT_ADDDISPLAY)
set(SDL_VIDEO_DRIVER_X11_CONST_PARAM_XEXTADDDISPLAY 1) set(SDL_VIDEO_DRIVER_X11_CONST_PARAM_XEXTADDDISPLAY 1)
endif(HAVE_CONST_XEXT_ADDDISPLAY) endif()
check_c_source_compiles(" check_c_source_compiles("
#include <X11/Xlib.h> #include <X11/Xlib.h>
@ -407,7 +407,7 @@ macro(CheckX11)
XFreeEventData(display, cookie); }" HAVE_XGENERICEVENT) XFreeEventData(display, cookie); }" HAVE_XGENERICEVENT)
if(HAVE_XGENERICEVENT) if(HAVE_XGENERICEVENT)
set(SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS 1) set(SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS 1)
endif(HAVE_XGENERICEVENT) endif()
check_c_source_compiles(" check_c_source_compiles("
#include <X11/Xlibint.h> #include <X11/Xlibint.h>
@ -415,7 +415,7 @@ macro(CheckX11)
int main(int argc, char **argv) {}" HAVE_CONST_XDATA32) int main(int argc, char **argv) {}" HAVE_CONST_XDATA32)
if(HAVE_CONST_XDATA32) if(HAVE_CONST_XDATA32)
set(SDL_VIDEO_DRIVER_X11_CONST_PARAM_XDATA32 1) set(SDL_VIDEO_DRIVER_X11_CONST_PARAM_XDATA32 1)
endif(HAVE_CONST_XDATA32) endif()
check_function_exists(XkbKeycodeToKeysym SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM) check_function_exists(XkbKeycodeToKeysym SDL_VIDEO_DRIVER_X11_HAS_XKBKEYCODETOKEYSYM)
@ -423,29 +423,29 @@ macro(CheckX11)
set(HAVE_VIDEO_X11_XCURSOR TRUE) set(HAVE_VIDEO_X11_XCURSOR TRUE)
if(HAVE_X11_SHARED AND XCURSOR_LIB) if(HAVE_X11_SHARED AND XCURSOR_LIB)
set(SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR "\"${XCURSOR_LIB_SONAME}\"") set(SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR "\"${XCURSOR_LIB_SONAME}\"")
else(HAVE_X11_SHARED AND XCURSOR_LIB) else()
list(APPEND EXTRA_LIBS ${XCURSOR_LIB}) list(APPEND EXTRA_LIBS ${XCURSOR_LIB})
endif(HAVE_X11_SHARED AND XCURSOR_LIB) endif()
set(SDL_VIDEO_DRIVER_X11_XCURSOR 1) set(SDL_VIDEO_DRIVER_X11_XCURSOR 1)
endif(VIDEO_X11_XCURSOR AND HAVE_XCURSOR_H) endif()
if(VIDEO_X11_XINERAMA AND HAVE_XINERAMA_H) if(VIDEO_X11_XINERAMA AND HAVE_XINERAMA_H)
set(HAVE_VIDEO_X11_XINERAMA TRUE) set(HAVE_VIDEO_X11_XINERAMA TRUE)
if(HAVE_X11_SHARED AND XINERAMA_LIB) if(HAVE_X11_SHARED AND XINERAMA_LIB)
set(SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA "\"${XINERAMA_LIB_SONAME}\"") set(SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA "\"${XINERAMA_LIB_SONAME}\"")
else(HAVE_X11_SHARED AND XINERAMA_LIB) else()
list(APPEND EXTRA_LIBS ${XINERAMA_LIB}) list(APPEND EXTRA_LIBS ${XINERAMA_LIB})
endif(HAVE_X11_SHARED AND XINERAMA_LIB) endif()
set(SDL_VIDEO_DRIVER_X11_XINERAMA 1) set(SDL_VIDEO_DRIVER_X11_XINERAMA 1)
endif(VIDEO_X11_XINERAMA AND HAVE_XINERAMA_H) endif()
if(VIDEO_X11_XINPUT AND HAVE_XINPUT_H) if(VIDEO_X11_XINPUT AND HAVE_XINPUT_H)
set(HAVE_VIDEO_X11_XINPUT TRUE) set(HAVE_VIDEO_X11_XINPUT TRUE)
if(HAVE_X11_SHARED AND XI_LIB) if(HAVE_X11_SHARED AND XI_LIB)
set(SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 "\"${XI_LIB_SONAME}\"") set(SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 "\"${XI_LIB_SONAME}\"")
else(HAVE_X11_SHARED AND XI_LIB) else()
list(APPEND EXTRA_LIBS ${XI_LIB}) list(APPEND EXTRA_LIBS ${XI_LIB})
endif(HAVE_X11_SHARED AND XI_LIB) endif()
set(SDL_VIDEO_DRIVER_X11_XINPUT2 1) set(SDL_VIDEO_DRIVER_X11_XINPUT2 1)
# Check for multitouch # Check for multitouch
@ -462,51 +462,56 @@ macro(CheckX11)
int main(int argc, char **argv) {}" HAVE_XINPUT2_MULTITOUCH) int main(int argc, char **argv) {}" HAVE_XINPUT2_MULTITOUCH)
if(HAVE_XINPUT2_MULTITOUCH) if(HAVE_XINPUT2_MULTITOUCH)
set(SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH 1) set(SDL_VIDEO_DRIVER_X11_XINPUT2_SUPPORTS_MULTITOUCH 1)
endif(HAVE_XINPUT2_MULTITOUCH) endif()
endif(VIDEO_X11_XINPUT AND HAVE_XINPUT_H) endif()
if(VIDEO_X11_XRANDR AND HAVE_XRANDR_H) if(VIDEO_X11_XRANDR AND HAVE_XRANDR_H)
if(HAVE_X11_SHARED AND XRANDR_LIB) if(HAVE_X11_SHARED AND XRANDR_LIB)
set(SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR "\"${XRANDR_LIB_SONAME}\"") set(SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR "\"${XRANDR_LIB_SONAME}\"")
else(HAVE_X11_SHARED AND XRANDR_LIB) else()
list(APPEND EXTRA_LIBS ${XRANDR_LIB}) list(APPEND EXTRA_LIBS ${XRANDR_LIB})
endif(HAVE_X11_SHARED AND XRANDR_LIB) endif()
set(SDL_VIDEO_DRIVER_X11_XRANDR 1) set(SDL_VIDEO_DRIVER_X11_XRANDR 1)
set(HAVE_VIDEO_X11_XRANDR TRUE) set(HAVE_VIDEO_X11_XRANDR TRUE)
endif(VIDEO_X11_XRANDR AND HAVE_XRANDR_H) endif()
if(VIDEO_X11_XSCRNSAVER AND HAVE_XSS_H) if(VIDEO_X11_XSCRNSAVER AND HAVE_XSS_H)
if(HAVE_X11_SHARED AND XSS_LIB) if(HAVE_X11_SHARED AND XSS_LIB)
set(SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS "\"${XSS_LIB_SONAME}\"") set(SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS "\"${XSS_LIB_SONAME}\"")
else(HAVE_X11_SHARED AND XSS_LIB) else()
list(APPEND EXTRA_LIBS ${XSS_LIB}) list(APPEND EXTRA_LIBS ${XSS_LIB})
endif(HAVE_X11_SHARED AND XSS_LIB) endif()
set(SDL_VIDEO_DRIVER_X11_XSCRNSAVER 1) set(SDL_VIDEO_DRIVER_X11_XSCRNSAVER 1)
set(HAVE_VIDEO_X11_XSCRNSAVER TRUE) set(HAVE_VIDEO_X11_XSCRNSAVER TRUE)
endif(VIDEO_X11_XSCRNSAVER AND HAVE_XSS_H) endif()
if(VIDEO_X11_XSHAPE AND HAVE_XSHAPE_H) if(VIDEO_X11_XSHAPE AND HAVE_XSHAPE_H)
set(SDL_VIDEO_DRIVER_X11_XSHAPE 1) set(SDL_VIDEO_DRIVER_X11_XSHAPE 1)
set(HAVE_VIDEO_X11_XSHAPE TRUE) set(HAVE_VIDEO_X11_XSHAPE TRUE)
endif(VIDEO_X11_XSHAPE AND HAVE_XSHAPE_H) endif()
if(VIDEO_X11_XVM AND HAVE_XF86VM_H) if(VIDEO_X11_XVM AND HAVE_XF86VM_H)
if(HAVE_X11_SHARED AND XXF86VM_LIB) if(HAVE_X11_SHARED AND XXF86VM_LIB)
set(SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE "\"${XXF86VM_LIB_SONAME}\"") set(SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE "\"${XXF86VM_LIB_SONAME}\"")
else(HAVE_X11_SHARED AND XXF86VM_LIB) else()
list(APPEND EXTRA_LIBS ${XXF86VM_LIB}) list(APPEND EXTRA_LIBS ${XXF86VM_LIB})
endif(HAVE_X11_SHARED AND XXF86VM_LIB) endif()
set(SDL_VIDEO_DRIVER_X11_XVIDMODE 1) set(SDL_VIDEO_DRIVER_X11_XVIDMODE 1)
set(HAVE_VIDEO_X11_XVM TRUE) set(HAVE_VIDEO_X11_XVM TRUE)
endif(VIDEO_X11_XVM AND HAVE_XF86VM_H) endif()
set(CMAKE_REQUIRED_LIBRARIES) set(CMAKE_REQUIRED_LIBRARIES)
endif(X11_LIB) endif()
endif(VIDEO_X11) endif()
endmacro(CheckX11) endmacro()
# Requires:
# - EGL
# - PkgCheckModules
# Optional:
# - MIR_SHARED opt
# - HAVE_DLOPEN opt
macro(CheckMir) macro(CheckMir)
# !!! FIXME: hook up dynamic loading here.
if(VIDEO_MIR) if(VIDEO_MIR)
find_library(MIR_LIB mirclient mircommon egl) find_library(MIR_LIB mirclient mircommon egl)
pkg_check_modules(MIR_TOOLKIT mirclient mircommon) pkg_check_modules(MIR_TOOLKIT mirclient mircommon)
@ -522,15 +527,31 @@ macro(CheckMir)
set(SDL_VIDEO_DRIVER_MIR 1) set(SDL_VIDEO_DRIVER_MIR 1)
list(APPEND EXTRA_CFLAGS ${MIR_TOOLKIT_CFLAGS} ${EGL_CLFAGS} ${XKB_CLFLAGS}) list(APPEND EXTRA_CFLAGS ${MIR_TOOLKIT_CFLAGS} ${EGL_CLFAGS} ${XKB_CLFLAGS})
list(APPEND EXTRA_LDFLAGS ${MIR_TOOLKIT_LDFLAGS} ${EGL_LDLAGS} ${XKB_LDLAGS})
endif (MIR_LIB AND MIR_TOOLKIT_FOUND AND EGL_FOUND AND XKB_FOUND) if(MIR_SHARED)
endif(VIDEO_MIR) if(NOT HAVE_DLOPEN)
endmacro(CheckMir) message_warn("You must have SDL_LoadObject() support for dynamic Mir loading")
else()
FindLibraryAndSONAME(mirclient)
FindLibraryAndSONAME(xkbcommon)
set(SDL_VIDEO_DRIVER_MIR_DYNAMIC "\"${MIRCLIENT_LIB_SONAME}\"")
set(SDL_VIDEO_DRIVER_MIR_DYNAMIC_XKBCOMMON "\"${XKBCOMMON_LIB_SONAME}\"")
set(HAVE_MIR_SHARED TRUE)
endif()
else()
set(EXTRA_LIBS ${MIR_TOOLKIT_LIBRARIES} ${EXTRA_LIBS})
endif()
endif()
endif()
endmacro()
# Requires: # Requires:
# - EGL # - EGL
# - PkgCheckModules
# Optional:
# - WAYLAND_SHARED opt
# - HAVE_DLOPEN opt
macro(CheckWayland) macro(CheckWayland)
# !!! FIXME: hook up dynamic loading here.
if(VIDEO_WAYLAND) if(VIDEO_WAYLAND)
pkg_check_modules(WAYLAND wayland-client wayland-cursor wayland-egl egl xkbcommon) pkg_check_modules(WAYLAND wayland-client wayland-cursor wayland-egl egl xkbcommon)
if(WAYLAND_FOUND) if(WAYLAND_FOUND)
@ -540,16 +561,38 @@ macro(CheckWayland)
include_directories( include_directories(
${WAYLAND_INCLUDE_DIRS} ${WAYLAND_INCLUDE_DIRS}
) )
set(EXTRA_LIBS ${WAYLAND_LIBRARIES} ${EXTRA_LIBS})
set(HAVE_VIDEO_WAYLAND TRUE) set(HAVE_VIDEO_WAYLAND TRUE)
set(HAVE_SDL_VIDEO TRUE) set(HAVE_SDL_VIDEO TRUE)
file(GLOB WAYLAND_SOURCES ${SDL2_SOURCE_DIR}/src/video/wayland/*.c) file(GLOB WAYLAND_SOURCES ${SDL2_SOURCE_DIR}/src/video/wayland/*.c)
set(SOURCE_FILES ${SOURCE_FILES} ${WAYLAND_SOURCES}) set(SOURCE_FILES ${SOURCE_FILES} ${WAYLAND_SOURCES})
if(VIDEO_WAYLAND_QT_TOUCH)
set(SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH 1)
endif()
if(WAYLAND_SHARED)
if(NOT HAVE_DLOPEN)
message_warn("You must have SDL_LoadObject() support for dynamic Wayland loading")
else()
FindLibraryAndSONAME(wayland-client)
FindLibraryAndSONAME(wayland-egl)
FindLibraryAndSONAME(wayland-cursor)
FindLibraryAndSONAME(xkbcommon)
set(SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC "\"${WAYLAND_CLIENT_LIB_SONAME}\"")
set(SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL "\"${WAYLAND_EGL_LIB_SONAME}\"")
set(SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR "\"${WAYLAND_CURSOR_LIB_SONAME}\"")
set(SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON "\"${XKBCOMMON_LIB_SONAME}\"")
set(HAVE_WAYLAND_SHARED TRUE)
endif()
else()
set(EXTRA_LIBS ${WAYLAND_LIBRARIES} ${EXTRA_LIBS})
endif()
set(SDL_VIDEO_DRIVER_WAYLAND 1) set(SDL_VIDEO_DRIVER_WAYLAND 1)
endif(WAYLAND_FOUND) endif()
endif(VIDEO_WAYLAND) endif()
endmacro(CheckWayland) endmacro()
# Requires: # Requires:
# - n/a # - n/a
@ -558,16 +601,16 @@ macro(CheckCOCOA)
if(VIDEO_COCOA) if(VIDEO_COCOA)
if(APPLE) # Apple always has Cocoa. if(APPLE) # Apple always has Cocoa.
set(HAVE_VIDEO_COCOA TRUE) set(HAVE_VIDEO_COCOA TRUE)
endif(APPLE) endif()
if(HAVE_VIDEO_COCOA) if(HAVE_VIDEO_COCOA)
file(GLOB COCOA_SOURCES ${SDL2_SOURCE_DIR}/src/video/cocoa/*.m) file(GLOB COCOA_SOURCES ${SDL2_SOURCE_DIR}/src/video/cocoa/*.m)
set_source_files_properties(${COCOA_SOURCES} PROPERTIES LANGUAGE C) set_source_files_properties(${COCOA_SOURCES} PROPERTIES LANGUAGE C)
set(SOURCE_FILES ${SOURCE_FILES} ${COCOA_SOURCES}) set(SOURCE_FILES ${SOURCE_FILES} ${COCOA_SOURCES})
set(SDL_VIDEO_DRIVER_COCOA 1) set(SDL_VIDEO_DRIVER_COCOA 1)
set(HAVE_SDL_VIDEO TRUE) set(HAVE_SDL_VIDEO TRUE)
endif(HAVE_VIDEO_COCOA) endif()
endif(VIDEO_COCOA) endif()
endmacro(CheckCOCOA) endmacro()
# Requires: # Requires:
# - PkgCheckModules # - PkgCheckModules
@ -591,14 +634,14 @@ macro(CheckDirectFB)
FindLibraryAndSONAME("directfb") FindLibraryAndSONAME("directfb")
set(SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC "\"${DIRECTFB_LIB_SONAME}\"") set(SDL_VIDEO_DRIVER_DIRECTFB_DYNAMIC "\"${DIRECTFB_LIB_SONAME}\"")
set(HAVE_DIRECTFB_SHARED TRUE) set(HAVE_DIRECTFB_SHARED TRUE)
endif(NOT HAVE_DLOPEN) endif()
else(DIRECTFB_SHARED) else()
list(APPEND EXTRA_LDFLAGS ${PKG_DIRECTFB_LDFLAGS}) list(APPEND EXTRA_LDFLAGS ${PKG_DIRECTFB_LDFLAGS})
endif(DIRECTFB_SHARED) endif()
set(HAVE_SDL_VIDEO TRUE) set(HAVE_SDL_VIDEO TRUE)
endif(PKG_DIRECTFB_FOUND) endif()
endif(VIDEO_DIRECTFB) endif()
endmacro(CheckDirectFB) endmacro()
# Requires: # Requires:
# - n/a # - n/a
@ -645,9 +688,9 @@ macro(CheckOpenGLX11)
set(SDL_VIDEO_OPENGL_GLX 1) set(SDL_VIDEO_OPENGL_GLX 1)
set(SDL_VIDEO_RENDER_OGL 1) set(SDL_VIDEO_RENDER_OGL 1)
list(APPEND EXTRA_LIBS GL) list(APPEND EXTRA_LIBS GL)
endif(HAVE_VIDEO_OPENGL) endif()
endif(VIDEO_OPENGL) endif()
endmacro(CheckOpenGLX11) endmacro()
# Requires: # Requires:
# - nada # - nada
@ -659,7 +702,7 @@ macro(CheckOpenGLESX11)
int main (int argc, char** argv) {}" HAVE_VIDEO_OPENGL_EGL) int main (int argc, char** argv) {}" HAVE_VIDEO_OPENGL_EGL)
if(HAVE_VIDEO_OPENGL_EGL) if(HAVE_VIDEO_OPENGL_EGL)
set(SDL_VIDEO_OPENGL_EGL 1) set(SDL_VIDEO_OPENGL_EGL 1)
endif(HAVE_VIDEO_OPENGL_EGL) endif()
check_c_source_compiles(" check_c_source_compiles("
#include <GLES/gl.h> #include <GLES/gl.h>
#include <GLES/glext.h> #include <GLES/glext.h>
@ -668,7 +711,7 @@ macro(CheckOpenGLESX11)
set(HAVE_VIDEO_OPENGLES TRUE) set(HAVE_VIDEO_OPENGLES TRUE)
set(SDL_VIDEO_OPENGL_ES 1) set(SDL_VIDEO_OPENGL_ES 1)
set(SDL_VIDEO_RENDER_OGL_ES 1) set(SDL_VIDEO_RENDER_OGL_ES 1)
endif(HAVE_VIDEO_OPENGLES_V1) endif()
check_c_source_compiles(" check_c_source_compiles("
#include <GLES2/gl2.h> #include <GLES2/gl2.h>
#include <GLES2/gl2ext.h> #include <GLES2/gl2ext.h>
@ -677,12 +720,12 @@ macro(CheckOpenGLESX11)
set(HAVE_VIDEO_OPENGLES TRUE) set(HAVE_VIDEO_OPENGLES TRUE)
set(SDL_VIDEO_OPENGL_ES2 1) set(SDL_VIDEO_OPENGL_ES2 1)
set(SDL_VIDEO_RENDER_OGL_ES2 1) set(SDL_VIDEO_RENDER_OGL_ES2 1)
endif(HAVE_VIDEO_OPENGLES_V2) endif()
endif(VIDEO_OPENGLES) endif()
endmacro(CheckOpenGLESX11) endmacro()
# Rquires: # Requires:
# - nada # - nada
# Optional: # Optional:
# - THREADS opt # - THREADS opt
@ -729,17 +772,21 @@ macro(CheckPTHREAD)
else() else()
set(PTHREAD_CFLAGS "-D_REENTRANT") set(PTHREAD_CFLAGS "-D_REENTRANT")
set(PTHREAD_LDFLAGS "-lpthread") set(PTHREAD_LDFLAGS "-lpthread")
endif(LINUX) endif()
# Run some tests # Run some tests
set(CMAKE_REQUIRED_FLAGS "${PTHREAD_CFLAGS} ${PTHREAD_LDFLAGS}") set(CMAKE_REQUIRED_FLAGS "${PTHREAD_CFLAGS} ${PTHREAD_LDFLAGS}")
check_c_source_runs(" if(CMAKE_CROSSCOMPILING)
set(HAVE_PTHREADS 1)
else()
check_c_source_runs("
#include <pthread.h> #include <pthread.h>
int main(int argc, char** argv) { int main(int argc, char** argv) {
pthread_attr_t type; pthread_attr_t type;
pthread_attr_init(&type); pthread_attr_init(&type);
return 0; return 0;
}" HAVE_PTHREADS) }" HAVE_PTHREADS)
endif()
if(HAVE_PTHREADS) if(HAVE_PTHREADS)
set(SDL_THREAD_PTHREAD 1) set(SDL_THREAD_PTHREAD 1)
list(APPEND EXTRA_CFLAGS ${PTHREAD_CFLAGS}) list(APPEND EXTRA_CFLAGS ${PTHREAD_CFLAGS})
@ -756,7 +803,7 @@ macro(CheckPTHREAD)
}" HAVE_RECURSIVE_MUTEXES) }" HAVE_RECURSIVE_MUTEXES)
if(HAVE_RECURSIVE_MUTEXES) if(HAVE_RECURSIVE_MUTEXES)
set(SDL_THREAD_PTHREAD_RECURSIVE_MUTEX 1) set(SDL_THREAD_PTHREAD_RECURSIVE_MUTEX 1)
else(HAVE_RECURSIVE_MUTEXES) else()
check_c_source_compiles(" check_c_source_compiles("
#include <pthread.h> #include <pthread.h>
int main(int argc, char **argv) { int main(int argc, char **argv) {
@ -766,8 +813,8 @@ macro(CheckPTHREAD)
}" HAVE_RECURSIVE_MUTEXES_NP) }" HAVE_RECURSIVE_MUTEXES_NP)
if(HAVE_RECURSIVE_MUTEXES_NP) if(HAVE_RECURSIVE_MUTEXES_NP)
set(SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP 1) set(SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP 1)
endif(HAVE_RECURSIVE_MUTEXES_NP) endif()
endif(HAVE_RECURSIVE_MUTEXES) endif()
if(PTHREADS_SEM) if(PTHREADS_SEM)
check_c_source_compiles("#include <pthread.h> check_c_source_compiles("#include <pthread.h>
@ -781,15 +828,15 @@ macro(CheckPTHREAD)
sem_timedwait(NULL, NULL); sem_timedwait(NULL, NULL);
return 0; return 0;
}" HAVE_SEM_TIMEDWAIT) }" HAVE_SEM_TIMEDWAIT)
endif(HAVE_PTHREADS_SEM) endif()
endif(PTHREADS_SEM) endif()
check_c_source_compiles(" check_c_source_compiles("
#include <pthread.h> #include <pthread.h>
#include <pthread_np.h> #include <pthread_np.h>
int main(int argc, char** argv) { return 0; }" HAVE_PTHREAD_NP_H) 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_setname_np HAVE_PTHREAD_SETNAME_NP)
check_function_exists(pthread_set_name_np HAVE_PTHREAD_set_NAME_NP) check_function_exists(pthread_set_name_np HAVE_PTHREAD_SET_NAME_NP)
set(CMAKE_REQUIRED_FLAGS) set(CMAKE_REQUIRED_FLAGS)
set(SOURCE_FILES ${SOURCE_FILES} set(SOURCE_FILES ${SOURCE_FILES}
@ -801,14 +848,14 @@ macro(CheckPTHREAD)
if(HAVE_PTHREADS_SEM) if(HAVE_PTHREADS_SEM)
set(SOURCE_FILES ${SOURCE_FILES} set(SOURCE_FILES ${SOURCE_FILES}
${SDL2_SOURCE_DIR}/src/thread/pthread/SDL_syssem.c) ${SDL2_SOURCE_DIR}/src/thread/pthread/SDL_syssem.c)
else(HAVE_PTHREADS_SEM) else()
set(SOURCE_FILES ${SOURCE_FILES} set(SOURCE_FILES ${SOURCE_FILES}
${SDL2_SOURCE_DIR}/src/thread/generic/SDL_syssem.c) ${SDL2_SOURCE_DIR}/src/thread/generic/SDL_syssem.c)
endif(HAVE_PTHREADS_SEM) endif()
set(HAVE_SDL_THREADS TRUE) set(HAVE_SDL_THREADS TRUE)
endif(HAVE_PTHREADS) endif()
endif(PTHREADS) endif()
endmacro(CheckPTHREAD) endmacro()
# Requires # Requires
# - nada # - nada
@ -822,27 +869,27 @@ macro(CheckUSBHID)
check_include_file(usbhid.h HAVE_USBHID_H) check_include_file(usbhid.h HAVE_USBHID_H)
if(HAVE_USBHID_H) if(HAVE_USBHID_H)
set(USB_CFLAGS "-DHAVE_USBHID_H") set(USB_CFLAGS "-DHAVE_USBHID_H")
endif(HAVE_USBHID_H) endif()
check_include_file(libusbhid.h HAVE_LIBUSBHID_H) check_include_file(libusbhid.h HAVE_LIBUSBHID_H)
if(HAVE_LIBUSBHID_H) if(HAVE_LIBUSBHID_H)
set(USB_CFLAGS "${USB_CFLAGS} -DHAVE_LIBUSBHID_H") set(USB_CFLAGS "${USB_CFLAGS} -DHAVE_LIBUSBHID_H")
endif(HAVE_LIBUSBHID_H) endif()
set(USB_LIBS ${USB_LIBS} usbhid) set(USB_LIBS ${USB_LIBS} usbhid)
else(LIBUSBHID) else()
check_include_file(usb.h HAVE_USB_H) check_include_file(usb.h HAVE_USB_H)
if(HAVE_USB_H) if(HAVE_USB_H)
set(USB_CFLAGS "-DHAVE_USB_H") set(USB_CFLAGS "-DHAVE_USB_H")
endif(HAVE_USB_H) endif()
check_include_file(libusb.h HAVE_LIBUSB_H) check_include_file(libusb.h HAVE_LIBUSB_H)
if(HAVE_LIBUSB_H) if(HAVE_LIBUSB_H)
set(USB_CFLAGS "${USB_CFLAGS} -DHAVE_LIBUSB_H") set(USB_CFLAGS "${USB_CFLAGS} -DHAVE_LIBUSB_H")
endif(HAVE_LIBUSB_H) endif()
check_library_exists(usb hid_init "" LIBUSB) check_library_exists(usb hid_init "" LIBUSB)
if(LIBUSB) if(LIBUSB)
set(USB_LIBS ${USB_LIBS} usb) set(USB_LIBS ${USB_LIBS} usb)
endif(LIBUSB) endif()
endif(LIBUSBHID) endif()
set(CMAKE_REQUIRED_FLAGS "${USB_CFLAGS}") set(CMAKE_REQUIRED_FLAGS "${USB_CFLAGS}")
set(CMAKE_REQUIRED_LIBRARIES "${USB_LIBS}") set(CMAKE_REQUIRED_LIBRARIES "${USB_LIBS}")
@ -898,7 +945,7 @@ macro(CheckUSBHID)
}" HAVE_USBHID_UCR_DATA) }" HAVE_USBHID_UCR_DATA)
if(HAVE_USBHID_UCR_DATA) if(HAVE_USBHID_UCR_DATA)
set(USB_CFLAGS "${USB_CFLAGS} -DUSBHID_UCR_DATA") set(USB_CFLAGS "${USB_CFLAGS} -DUSBHID_UCR_DATA")
endif(HAVE_USBHID_UCR_DATA) endif()
check_c_source_compiles(" check_c_source_compiles("
#include <sys/types.h> #include <sys/types.h>
@ -926,7 +973,7 @@ macro(CheckUSBHID)
}" HAVE_USBHID_NEW) }" HAVE_USBHID_NEW)
if(HAVE_USBHID_NEW) if(HAVE_USBHID_NEW)
set(USB_CFLAGS "${USB_CFLAGS} -DUSBHID_NEW") set(USB_CFLAGS "${USB_CFLAGS} -DUSBHID_NEW")
endif(HAVE_USBHID_NEW) endif()
check_c_source_compiles(" check_c_source_compiles("
#include <machine/joystick.h> #include <machine/joystick.h>
@ -936,7 +983,7 @@ macro(CheckUSBHID)
}" HAVE_MACHINE_JOYSTICK) }" HAVE_MACHINE_JOYSTICK)
if(HAVE_MACHINE_JOYSTICK) if(HAVE_MACHINE_JOYSTICK)
set(SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H 1) set(SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H 1)
endif(HAVE_MACHINE_JOYSTICK) endif()
set(SDL_JOYSTICK_USBHID 1) set(SDL_JOYSTICK_USBHID 1)
file(GLOB BSD_JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/bsd/*.c) file(GLOB BSD_JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/bsd/*.c)
set(SOURCE_FILES ${SOURCE_FILES} ${BSD_JOYSTICK_SOURCES}) set(SOURCE_FILES ${SOURCE_FILES} ${BSD_JOYSTICK_SOURCES})
@ -946,8 +993,8 @@ macro(CheckUSBHID)
set(CMAKE_REQUIRED_LIBRARIES) set(CMAKE_REQUIRED_LIBRARIES)
set(CMAKE_REQUIRED_FLAGS) set(CMAKE_REQUIRED_FLAGS)
endif(HAVE_USBHID) endif()
endmacro(CheckUSBHID) endmacro()
# Requires: # Requires:
# - n/a # - n/a

163
configure vendored
View File

@ -21385,6 +21385,78 @@ $as_echo "#define SDL_VIDEO_RENDER_OGL 1" >>confdefs.h
fi fi
} }
CheckEmscriptenGLES()
{
if test x$enable_video = xyes -a x$enable_video_opengles = xyes; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for EGL support" >&5
$as_echo_n "checking for EGL support... " >&6; }
video_opengl_egl=no
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <EGL/egl.h>
int
main ()
{
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
video_opengl_egl=yes
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $video_opengl_egl" >&5
$as_echo "$video_opengl_egl" >&6; }
if test x$video_opengl_egl = xyes; then
$as_echo "#define SDL_VIDEO_OPENGL_EGL 1" >>confdefs.h
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenGL ES v2 headers" >&5
$as_echo_n "checking for OpenGL ES v2 headers... " >&6; }
video_opengles_v2=no
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
int
main ()
{
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
video_opengles_v2=yes
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $video_opengles_v2" >&5
$as_echo "$video_opengles_v2" >&6; }
if test x$video_opengles_v2 = xyes; then
$as_echo "#define SDL_VIDEO_OPENGL_ES2 1" >>confdefs.h
$as_echo "#define SDL_VIDEO_RENDER_OGL_ES2 1" >>confdefs.h
SUMMARY_video="${SUMMARY_video} opengl_es2"
fi
fi
}
CheckInputEvents() CheckInputEvents()
{ {
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Linux 2.4 unified input interface" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Linux 2.4 unified input interface" >&5
@ -21844,6 +21916,7 @@ $as_echo_n "checking for recursive mutexes... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */ /* end confdefs.h. */
#define _GNU_SOURCE 1
#include <pthread.h> #include <pthread.h>
int int
@ -21857,7 +21930,7 @@ main ()
return 0; return 0;
} }
_ACEOF _ACEOF
if ac_fn_c_try_compile "$LINENO"; then : if ac_fn_c_try_link "$LINENO"; then :
has_recursive_mutexes=yes has_recursive_mutexes=yes
@ -21865,12 +21938,14 @@ $as_echo "#define SDL_THREAD_PTHREAD_RECURSIVE_MUTEX 1" >>confdefs.h
fi fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
fi fi
if test x$has_recursive_mutexes = xno; then if test x$has_recursive_mutexes = xno; then
cat confdefs.h - <<_ACEOF >conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */ /* end confdefs.h. */
#define _GNU_SOURCE 1
#include <pthread.h> #include <pthread.h>
int int
@ -21884,7 +21959,7 @@ main ()
return 0; return 0;
} }
_ACEOF _ACEOF
if ac_fn_c_try_compile "$LINENO"; then : if ac_fn_c_try_link "$LINENO"; then :
has_recursive_mutexes=yes has_recursive_mutexes=yes
@ -21892,7 +21967,8 @@ $as_echo "#define SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP 1" >>confdefs.h
fi fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
fi fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $has_recursive_mutexes" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $has_recursive_mutexes" >&5
$as_echo "$has_recursive_mutexes" >&6; } $as_echo "$has_recursive_mutexes" >&6; }
@ -22865,7 +22941,9 @@ case "$host" in
if test x$enable_video = xyes; then if test x$enable_video = xyes; then
SOURCES="$SOURCES $srcdir/src/video/raspberry/*.c" SOURCES="$SOURCES $srcdir/src/video/raspberry/*.c"
# FIXME: confdefs? Not AC_DEFINE?
$as_echo "#define SDL_VIDEO_DRIVER_RPI 1" >>confdefs.h $as_echo "#define SDL_VIDEO_DRIVER_RPI 1" >>confdefs.h
SUMMARY_video="${SUMMARY_video} rpi"
fi fi
;; ;;
*-*-androideabi*) *-*-androideabi*)
@ -22879,6 +22957,7 @@ case "$host" in
if test x$enable_video = xyes; then if test x$enable_video = xyes; then
SOURCES="$SOURCES $srcdir/src/core/android/*.c $srcdir/src/video/android/*.c" SOURCES="$SOURCES $srcdir/src/core/android/*.c $srcdir/src/video/android/*.c"
# FIXME: confdefs? Not AC_DEFINE?
$as_echo "#define SDL_VIDEO_DRIVER_ANDROID 1" >>confdefs.h $as_echo "#define SDL_VIDEO_DRIVER_ANDROID 1" >>confdefs.h
SUMMARY_video="${SUMMARY_video} android" SUMMARY_video="${SUMMARY_video} android"
fi fi
@ -23019,11 +23098,22 @@ $as_echo "#define SDL_POWER_ANDROID 1" >>confdefs.h
fi fi
# Set up files for the filesystem library # Set up files for the filesystem library
if test x$enable_filesystem = xyes; then if test x$enable_filesystem = xyes; then
case $ARCH in
android)
$as_echo "#define SDL_FILESYSTEM_ANDROID 1" >>confdefs.h
SOURCES="$SOURCES $srcdir/src/filesystem/android/*.c"
have_filesystem=yes
;;
*)
$as_echo "#define SDL_FILESYSTEM_UNIX 1" >>confdefs.h $as_echo "#define SDL_FILESYSTEM_UNIX 1" >>confdefs.h
SOURCES="$SOURCES $srcdir/src/filesystem/unix/*.c" SOURCES="$SOURCES $srcdir/src/filesystem/unix/*.c"
have_filesystem=yes have_filesystem=yes
;;
esac
fi fi
# Set up files for the timer library # Set up files for the timer library
if test x$enable_timers = xyes; then if test x$enable_timers = xyes; then
@ -23483,7 +23573,68 @@ $as_echo "#define SDL_FILESYSTEM_NACL 1" >>confdefs.h
SOURCES="$SOURCES $srcdir/src/filesystem/nacl/*.c" SOURCES="$SOURCES $srcdir/src/filesystem/nacl/*.c"
have_filesystem=yes have_filesystem=yes
fi fi
;;
*-*-emscripten* )
if test x$enable_video = xyes; then
$as_echo "#define SDL_VIDEO_DRIVER_EMSCRIPTEN 1" >>confdefs.h
SOURCES="$SOURCES $srcdir/src/video/emscripten/*.c"
have_video=yes
SUMMARY_video="${SUMMARY_video} emscripten"
fi
if test x$enable_audio = xyes; then
$as_echo "#define SDL_AUDIO_DRIVER_EMSCRIPTEN 1" >>confdefs.h
SOURCES="$SOURCES $srcdir/src/audio/emscripten/*.c"
have_audio=yes
SUMMARY_audio="${SUMMARY_audio} emscripten"
fi
CheckVisibilityHidden
CheckDummyVideo
CheckDiskAudio
CheckDummyAudio
CheckDLOPEN
CheckClockGettime
CheckEmscriptenGLES
# Set up files for the power library
if test x$enable_power = xyes; then
$as_echo "#define SDL_POWER_EMSCRIPTEN 1" >>confdefs.h
SOURCES="$SOURCES $srcdir/src/power/emscripten/*.c"
have_power=yes
fi
# Set up files for the power library
if test x$enable_joystick = xyes; then
$as_echo "#define SDL_JOYSTICK_EMSCRIPTEN 1" >>confdefs.h
SOURCES="$SOURCES $srcdir/src/joystick/emscripten/*.c"
have_joystick=yes
fi
# Set up files for the filesystem library
if test x$enable_filesystem = xyes; then
$as_echo "#define SDL_FILESYSTEM_EMSCRIPTEN 1" >>confdefs.h
SOURCES="$SOURCES $srcdir/src/filesystem/emscripten/*.c"
have_filesystem=yes
fi
# Set up files for the timer library
if test x$enable_timers = xyes; then
$as_echo "#define SDL_TIMER_UNIX 1" >>confdefs.h
SOURCES="$SOURCES $srcdir/src/timer/unix/*.c"
have_timers=yes
fi
;; ;;
*) *)
as_fn_error $? " as_fn_error $? "

View File

@ -2130,6 +2130,40 @@ CheckMacGL()
fi fi
} }
CheckEmscriptenGLES()
{
if test x$enable_video = xyes -a x$enable_video_opengles = xyes; then
AC_MSG_CHECKING(for EGL support)
video_opengl_egl=no
AC_TRY_COMPILE([
#include <EGL/egl.h>
],[
],[
video_opengl_egl=yes
])
AC_MSG_RESULT($video_opengl_egl)
if test x$video_opengl_egl = xyes; then
AC_DEFINE(SDL_VIDEO_OPENGL_EGL, 1, [ ])
fi
AC_MSG_CHECKING(for OpenGL ES v2 headers)
video_opengles_v2=no
AC_TRY_COMPILE([
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
],[
],[
video_opengles_v2=yes
])
AC_MSG_RESULT($video_opengles_v2)
if test x$video_opengles_v2 = xyes; then
AC_DEFINE(SDL_VIDEO_OPENGL_ES2, 1, [ ])
AC_DEFINE(SDL_VIDEO_RENDER_OGL_ES2, 1, [ ])
SUMMARY_video="${SUMMARY_video} opengl_es2"
fi
fi
}
dnl See if we can use the new unified event interface in Linux 2.4 dnl See if we can use the new unified event interface in Linux 2.4
CheckInputEvents() CheckInputEvents()
{ {
@ -2390,7 +2424,8 @@ AC_HELP_STRING([--enable-pthread-sem], [use pthread semaphores [[default=yes]]])
AC_MSG_CHECKING(for recursive mutexes) AC_MSG_CHECKING(for recursive mutexes)
has_recursive_mutexes=no has_recursive_mutexes=no
if test x$has_recursive_mutexes = xno; then if test x$has_recursive_mutexes = xno; then
AC_TRY_COMPILE([ AC_TRY_LINK([
#define _GNU_SOURCE 1
#include <pthread.h> #include <pthread.h>
],[ ],[
pthread_mutexattr_t attr; pthread_mutexattr_t attr;
@ -2401,7 +2436,8 @@ AC_HELP_STRING([--enable-pthread-sem], [use pthread semaphores [[default=yes]]])
]) ])
fi fi
if test x$has_recursive_mutexes = xno; then if test x$has_recursive_mutexes = xno; then
AC_TRY_COMPILE([ AC_TRY_LINK([
#define _GNU_SOURCE 1
#include <pthread.h> #include <pthread.h>
],[ ],[
pthread_mutexattr_t attr; pthread_mutexattr_t attr;
@ -2801,7 +2837,9 @@ case "$host" in
if test x$enable_video = xyes; then if test x$enable_video = xyes; then
SOURCES="$SOURCES $srcdir/src/video/raspberry/*.c" SOURCES="$SOURCES $srcdir/src/video/raspberry/*.c"
# FIXME: confdefs? Not AC_DEFINE?
$as_echo "#define SDL_VIDEO_DRIVER_RPI 1" >>confdefs.h $as_echo "#define SDL_VIDEO_DRIVER_RPI 1" >>confdefs.h
SUMMARY_video="${SUMMARY_video} rpi"
fi fi
;; ;;
*-*-androideabi*) *-*-androideabi*)
@ -2815,6 +2853,7 @@ case "$host" in
if test x$enable_video = xyes; then if test x$enable_video = xyes; then
SOURCES="$SOURCES $srcdir/src/core/android/*.c $srcdir/src/video/android/*.c" SOURCES="$SOURCES $srcdir/src/core/android/*.c $srcdir/src/video/android/*.c"
# FIXME: confdefs? Not AC_DEFINE?
$as_echo "#define SDL_VIDEO_DRIVER_ANDROID 1" >>confdefs.h $as_echo "#define SDL_VIDEO_DRIVER_ANDROID 1" >>confdefs.h
SUMMARY_video="${SUMMARY_video} android" SUMMARY_video="${SUMMARY_video} android"
fi fi
@ -2937,9 +2976,18 @@ case "$host" in
fi fi
# Set up files for the filesystem library # Set up files for the filesystem library
if test x$enable_filesystem = xyes; then if test x$enable_filesystem = xyes; then
AC_DEFINE(SDL_FILESYSTEM_UNIX, 1, [ ]) case $ARCH in
SOURCES="$SOURCES $srcdir/src/filesystem/unix/*.c" android)
have_filesystem=yes AC_DEFINE(SDL_FILESYSTEM_ANDROID, 1, [ ])
SOURCES="$SOURCES $srcdir/src/filesystem/android/*.c"
have_filesystem=yes
;;
*)
AC_DEFINE(SDL_FILESYSTEM_UNIX, 1, [ ])
SOURCES="$SOURCES $srcdir/src/filesystem/unix/*.c"
have_filesystem=yes
;;
esac
fi fi
# Set up files for the timer library # Set up files for the timer library
if test x$enable_timers = xyes; then if test x$enable_timers = xyes; then
@ -3302,7 +3350,56 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau
SOURCES="$SOURCES $srcdir/src/filesystem/nacl/*.c" SOURCES="$SOURCES $srcdir/src/filesystem/nacl/*.c"
have_filesystem=yes have_filesystem=yes
fi fi
;;
*-*-emscripten* )
if test x$enable_video = xyes; then
AC_DEFINE(SDL_VIDEO_DRIVER_EMSCRIPTEN, 1, [ ])
SOURCES="$SOURCES $srcdir/src/video/emscripten/*.c"
have_video=yes
SUMMARY_video="${SUMMARY_video} emscripten"
fi
if test x$enable_audio = xyes; then
AC_DEFINE(SDL_AUDIO_DRIVER_EMSCRIPTEN, 1, [ ])
SOURCES="$SOURCES $srcdir/src/audio/emscripten/*.c"
have_audio=yes
SUMMARY_audio="${SUMMARY_audio} emscripten"
fi
CheckVisibilityHidden
CheckDummyVideo
CheckDiskAudio
CheckDummyAudio
CheckDLOPEN
CheckClockGettime
CheckEmscriptenGLES
# Set up files for the power library
if test x$enable_power = xyes; then
AC_DEFINE(SDL_POWER_EMSCRIPTEN, 1, [ ])
SOURCES="$SOURCES $srcdir/src/power/emscripten/*.c"
have_power=yes
fi
# Set up files for the power library
if test x$enable_joystick = xyes; then
AC_DEFINE(SDL_JOYSTICK_EMSCRIPTEN, 1, [ ])
SOURCES="$SOURCES $srcdir/src/joystick/emscripten/*.c"
have_joystick=yes
fi
# Set up files for the filesystem library
if test x$enable_filesystem = xyes; then
AC_DEFINE(SDL_FILESYSTEM_EMSCRIPTEN, 1, [ ])
SOURCES="$SOURCES $srcdir/src/filesystem/emscripten/*.c"
have_filesystem=yes
fi
# Set up files for the timer library
if test x$enable_timers = xyes; then
AC_DEFINE(SDL_TIMER_UNIX, 1, [ ])
SOURCES="$SOURCES $srcdir/src/timer/unix/*.c"
have_timers=yes
fi
;; ;;
*) *)
AC_MSG_ERROR([ AC_MSG_ERROR([

33
docs/README-emscripten.md Normal file
View File

@ -0,0 +1,33 @@
Emscripten
================================================================================
Build:
$ emconfigure ./configure --host=asmjs-unknown-emscripten --disable-assembly --disable-threads --enable-cpuinfo=false CFLAGS="-O2"
$ emmake make
Or with cmake:
$ emconfigure cmake ..
$ make
To build one of the tests:
$ cd test/
$ emcc -O2 --js-opts 0 -g4 testdraw2.c -I../include ../build/.libs/libSDL2.a ../build/libSDL2_test.a -o a.html
Uses GLES2 renderer or software
tests: https://dl.dropboxusercontent.com/u/17360362/SDL2-em/index.html
Some other SDL2 libraries can be easily built (assuming SDL2 is installed somewhere):
SDL_mixer (http://www.libsdl.org/projects/SDL_mixer/)
$ EMCONFIGURE_JS=1 emconfigure ../configure
build as usual...
SDL_gfx (http://cms.ferzkopp.net/index.php/software/13-sdl-gfx):
$ EMCONFIGURE_JS=1 emconfigure ../configure --disable-mmx
build as usual...

View File

@ -1,6 +1,6 @@
Dollar Gestures Dollar Gestures
=========================================================================== ===========================================================================
SDL Provides an implementation of the $1 gesture recognition system. This allows for recording, saving, loading, and performing single stroke gestures. SDL provides an implementation of the $1 gesture recognition system. This allows for recording, saving, loading, and performing single stroke gestures.
Gestures can be performed with any number of fingers (the centroid of the fingers must follow the path of the gesture), but the number of fingers must be constant (a finger cannot go down in the middle of a gesture). The path of a gesture is considered the path from the time when the final finger went down, to the first time any finger comes up. Gestures can be performed with any number of fingers (the centroid of the fingers must follow the path of the gesture), but the number of fingers must be constant (a finger cannot go down in the middle of a gesture). The path of a gesture is considered the path from the time when the final finger went down, to the first time any finger comes up.

View File

@ -1,34 +1,8 @@
Platforms Platforms
========= =========
We maintain the list of supported platforms on our wiki now, and how to
This is a list of the platforms SDL supports, and who maintains them. build and install SDL for those platforms:
Officially supported platforms https://wiki.libsdl.org/Installation
==============================
(code compiles, and thoroughly tested for release)
==============================
* Windows XP/Vista/7/8
* Mac OS X 10.5+
* Linux 2.6+
* iOS 5.1.1+
* Android 2.3.3+
Unofficially supported platforms
================================
(code compiles, but not thoroughly tested)
================================
* FreeBSD
* NetBSD
* OpenBSD
* Solaris
Platforms supported by volunteers
=================================
* Haiku - maintained by Axel Dörfler <axeld@pinc-software.de>
* PSP - maintained by 527721088@qq.com
* Pandora - maintained by Scott Smith <pickle136@sbcglobal.net>
* NaCl - maintained by Gabriel Jacobo <gabomdq@gmail.com>
Platforms that need maintainers
===============================

View File

@ -15,7 +15,7 @@ There are two basic ways of building SDL at the moment:
If you have a GNUish system, then you might try this. Edit configure.in, If you have a GNUish system, then you might try this. Edit configure.in,
take a look at the large section labelled: take a look at the large section labelled:
"Set up the configuration based on the target platform!" "Set up the configuration based on the host platform!"
Add a section for your platform, and then re-run autogen.sh and build! Add a section for your platform, and then re-run autogen.sh and build!
2. Using an IDE: 2. Using an IDE:

View File

@ -90,10 +90,12 @@ Here is a rough list of what works, and what doens't:
* keyboard input. Most of WinRT's documented virtual keys are supported, as * keyboard input. Most of WinRT's documented virtual keys are supported, as
well as many keys with documented hardware scancodes. well as many keys with documented hardware scancodes.
* OpenGL. Experimental support for OpenGL ES 2 is available via the ANGLE * OpenGL. Experimental support for OpenGL ES 2 is available via the ANGLE
project, using either MS Open Technologies' repository, at project, using either:
https://github.com/msopentech/angle (both the "winrt" and "future-dev" * MS Open Technologies' "ms-master" repository, at https://github.com/MSOpenTech/angle
branches are supported), or the official ANGLE repository, at (for use with Windows 8.1+ or Windows Phone 8.1+)
https://chromium.googlesource.com/angle/angle * MS Open Technologies' "angle-win8.0" repository, at https://github.com/MSOpenTech/angle-win8.0
(for Windows 8.0 only!)
* Google's main ANGLE repository, at https://chromium.googlesource.com/angle/angle
* SDLmain. WinRT uses a different signature for each app's main() function. * 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 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() (in `SDL\src\main\winrt\`) directly in order for their C-style main()
@ -112,6 +114,11 @@ Here is a rough list of what works, and what doens't:
supported by WinRT itself. supported by WinRT itself.
* joysticks and game controllers that aren't supported by Microsoft's XInput * joysticks and game controllers that aren't supported by Microsoft's XInput
API. 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 * probably anything else that's not listed as supported

View File

@ -33,6 +33,7 @@ More documentation and FAQs are available online at [the wiki](http://wiki.libsd
- [CMake](README-cmake.md) - [CMake](README-cmake.md)
- [DirectFB](README-directfb.md) - [DirectFB](README-directfb.md)
- [DynAPI](README-dynapi.md) - [DynAPI](README-dynapi.md)
- [Emscripten](README-emscripten.md)
- [Gesture](README-gesture.md) - [Gesture](README-gesture.md)
- [Mercurial](README-hg.md) - [Mercurial](README-hg.md)
- [iOS](README-ios.md) - [iOS](README-ios.md)

View File

@ -86,8 +86,10 @@ This also solves the problem of...
disable assertions. disable assertions.
*/ */
/* "while (0,0)" fools Microsoft's compiler's /W4 warning level into thinking
this condition isn't constant. And looks like an owl's face! */
#ifdef _MSC_VER /* stupid /W4 warnings. */ #ifdef _MSC_VER /* stupid /W4 warnings. */
#define SDL_NULL_WHILE_LOOP_CONDITION (-1 == __LINE__) #define SDL_NULL_WHILE_LOOP_CONDITION (0,0)
#else #else
#define SDL_NULL_WHILE_LOOP_CONDITION (0) #define SDL_NULL_WHILE_LOOP_CONDITION (0)
#endif #endif
@ -102,9 +104,9 @@ typedef enum
SDL_ASSERTION_ABORT, /**< Terminate the program. */ SDL_ASSERTION_ABORT, /**< Terminate the program. */
SDL_ASSERTION_IGNORE, /**< Ignore the assert. */ SDL_ASSERTION_IGNORE, /**< Ignore the assert. */
SDL_ASSERTION_ALWAYS_IGNORE /**< Ignore the assert from now on. */ SDL_ASSERTION_ALWAYS_IGNORE /**< Ignore the assert from now on. */
} SDL_assert_state; } SDL_AssertState;
typedef struct SDL_assert_data typedef struct SDL_AssertData
{ {
int always_ignore; int always_ignore;
unsigned int trigger_count; unsigned int trigger_count;
@ -112,13 +114,13 @@ typedef struct SDL_assert_data
const char *filename; const char *filename;
int linenum; int linenum;
const char *function; const char *function;
const struct SDL_assert_data *next; const struct SDL_AssertData *next;
} SDL_assert_data; } SDL_AssertData;
#if (SDL_ASSERT_LEVEL > 0) #if (SDL_ASSERT_LEVEL > 0)
/* Never call this directly. Use the SDL_assert* macros. */ /* Never call this directly. Use the SDL_assert* macros. */
extern DECLSPEC SDL_assert_state SDLCALL SDL_ReportAssertion(SDL_assert_data *, extern DECLSPEC SDL_AssertState SDLCALL SDL_ReportAssertion(SDL_AssertData *,
const char *, const char *,
const char *, int) const char *, int)
#if defined(__clang__) #if defined(__clang__)
@ -141,10 +143,10 @@ extern DECLSPEC SDL_assert_state SDLCALL SDL_ReportAssertion(SDL_assert_data *,
#define SDL_enabled_assert(condition) \ #define SDL_enabled_assert(condition) \
do { \ do { \
while ( !(condition) ) { \ while ( !(condition) ) { \
static struct SDL_assert_data sdl_assert_data = { \ static struct SDL_AssertData sdl_assert_data = { \
0, 0, #condition, 0, 0, 0, 0 \ 0, 0, #condition, 0, 0, 0, 0 \
}; \ }; \
const SDL_assert_state sdl_assert_state = SDL_ReportAssertion(&sdl_assert_data, SDL_FUNCTION, SDL_FILE, SDL_LINE); \ const SDL_AssertState sdl_assert_state = SDL_ReportAssertion(&sdl_assert_data, SDL_FUNCTION, SDL_FILE, SDL_LINE); \
if (sdl_assert_state == SDL_ASSERTION_RETRY) { \ if (sdl_assert_state == SDL_ASSERTION_RETRY) { \
continue; /* go again. */ \ continue; /* go again. */ \
} else if (sdl_assert_state == SDL_ASSERTION_BREAK) { \ } else if (sdl_assert_state == SDL_ASSERTION_BREAK) { \
@ -181,8 +183,8 @@ extern DECLSPEC SDL_assert_state SDLCALL SDL_ReportAssertion(SDL_assert_data *,
#define SDL_assert_always(condition) SDL_enabled_assert(condition) #define SDL_assert_always(condition) SDL_enabled_assert(condition)
typedef SDL_assert_state (SDLCALL *SDL_AssertionHandler)( typedef SDL_AssertState (SDLCALL *SDL_AssertionHandler)(
const SDL_assert_data* data, void* userdata); const SDL_AssertData* data, void* userdata);
/** /**
* \brief Set an application-defined assertion handler. * \brief Set an application-defined assertion handler.
@ -199,7 +201,7 @@ typedef SDL_assert_state (SDLCALL *SDL_AssertionHandler)(
* *
* This callback is NOT reset to SDL's internal handler upon SDL_Quit()! * This callback is NOT reset to SDL's internal handler upon SDL_Quit()!
* *
* \return SDL_assert_state value of how to handle the assertion failure. * \return SDL_AssertState value of how to handle the assertion failure.
* *
* \param handler Callback function, called when an assertion fails. * \param handler Callback function, called when an assertion fails.
* \param userdata A pointer passed to the callback as-is. * \param userdata A pointer passed to the callback as-is.
@ -246,7 +248,7 @@ extern DECLSPEC SDL_AssertionHandler SDLCALL SDL_GetAssertionHandler(void **puse
* The proper way to examine this data looks something like this: * The proper way to examine this data looks something like this:
* *
* <code> * <code>
* const SDL_assert_data *item = SDL_GetAssertionReport(); * const SDL_AssertData *item = SDL_GetAssertionReport();
* while (item) { * while (item) {
* printf("'%s', %s (%s:%d), triggered %u times, always ignore: %s.\n", * printf("'%s', %s (%s:%d), triggered %u times, always ignore: %s.\n",
* item->condition, item->function, item->filename, * item->condition, item->function, item->filename,
@ -259,7 +261,7 @@ extern DECLSPEC SDL_AssertionHandler SDLCALL SDL_GetAssertionHandler(void **puse
* \return List of all assertions. * \return List of all assertions.
* \sa SDL_ResetAssertionReport * \sa SDL_ResetAssertionReport
*/ */
extern DECLSPEC const SDL_assert_data * SDLCALL SDL_GetAssertionReport(void); extern DECLSPEC const SDL_AssertData * SDLCALL SDL_GetAssertionReport(void);
/** /**
* \brief Reset the list of all assertion failures. * \brief Reset the list of all assertion failures.
@ -270,6 +272,12 @@ extern DECLSPEC const SDL_assert_data * SDLCALL SDL_GetAssertionReport(void);
*/ */
extern DECLSPEC void SDLCALL SDL_ResetAssertionReport(void); extern DECLSPEC void SDLCALL SDL_ResetAssertionReport(void);
/* these had wrong naming conventions until 2.0.4. Please update your app! */
#define SDL_assert_state SDL_AssertState
#define SDL_assert_data SDL_AssertData
/* Ends C function definitions when using C++ */ /* Ends C function definitions when using C++ */
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -122,7 +122,7 @@ extern DECLSPEC void SDLCALL SDL_AtomicUnlock(SDL_SpinLock *lock);
void _ReadWriteBarrier(void); void _ReadWriteBarrier(void);
#pragma intrinsic(_ReadWriteBarrier) #pragma intrinsic(_ReadWriteBarrier)
#define SDL_CompilerBarrier() _ReadWriteBarrier() #define SDL_CompilerBarrier() _ReadWriteBarrier()
#elif defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x5120)) #elif (defined(__GNUC__) && !defined(__EMSCRIPTEN__)) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x5120))
/* This is correct for all CPUs when using GCC or Solaris Studio 12.1+. */ /* This is correct for all CPUs when using GCC or Solaris Studio 12.1+. */
#define SDL_CompilerBarrier() __asm__ __volatile__ ("" : : : "memory") #define SDL_CompilerBarrier() __asm__ __volatile__ ("" : : : "memory")
#else #else

View File

@ -217,6 +217,7 @@
#cmakedefine SDL_AUDIO_DRIVER_WINMM @SDL_AUDIO_DRIVER_WINMM@ #cmakedefine SDL_AUDIO_DRIVER_WINMM @SDL_AUDIO_DRIVER_WINMM@
#cmakedefine SDL_AUDIO_DRIVER_FUSIONSOUND @SDL_AUDIO_DRIVER_FUSIONSOUND@ #cmakedefine SDL_AUDIO_DRIVER_FUSIONSOUND @SDL_AUDIO_DRIVER_FUSIONSOUND@
#cmakedefine SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC @SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC@ #cmakedefine SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC @SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC@
#cmakedefine SDL_AUDIO_DRIVER_EMSCRIPTEN @SDL_AUDIO_DRIVER_EMSCRIPTEN@
/* Enable various input drivers */ /* Enable various input drivers */
#cmakedefine SDL_INPUT_LINUXEV @SDL_INPUT_LINUXEV@ #cmakedefine SDL_INPUT_LINUXEV @SDL_INPUT_LINUXEV@
@ -230,6 +231,7 @@
#cmakedefine SDL_JOYSTICK_WINMM @SDL_JOYSTICK_WINMM@ #cmakedefine SDL_JOYSTICK_WINMM @SDL_JOYSTICK_WINMM@
#cmakedefine SDL_JOYSTICK_USBHID @SDL_JOYSTICK_USBHID@ #cmakedefine SDL_JOYSTICK_USBHID @SDL_JOYSTICK_USBHID@
#cmakedefine SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H @SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H@ #cmakedefine SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H @SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H@
#cmakedefine SDL_JOYSTICK_EMSCRIPTEN @SDL_JOYSTICK_EMSCRIPTEN@
#cmakedefine SDL_HAPTIC_DUMMY @SDL_HAPTIC_DUMMY@ #cmakedefine SDL_HAPTIC_DUMMY @SDL_HAPTIC_DUMMY@
#cmakedefine SDL_HAPTIC_LINUX @SDL_HAPTIC_LINUX@ #cmakedefine SDL_HAPTIC_LINUX @SDL_HAPTIC_LINUX@
#cmakedefine SDL_HAPTIC_IOKIT @SDL_HAPTIC_IOKIT@ #cmakedefine SDL_HAPTIC_IOKIT @SDL_HAPTIC_IOKIT@
@ -267,18 +269,16 @@
#cmakedefine SDL_VIDEO_DRIVER_VIVANTE @SDL_VIDEO_DRIVER_VIVANTE@ #cmakedefine SDL_VIDEO_DRIVER_VIVANTE @SDL_VIDEO_DRIVER_VIVANTE@
#cmakedefine SDL_VIDEO_DRIVER_VIVANTE_VDK @SDL_VIDEO_DRIVER_VIVANTE_VDK@ #cmakedefine SDL_VIDEO_DRIVER_VIVANTE_VDK @SDL_VIDEO_DRIVER_VIVANTE_VDK@
#if 0 #cmakedefine SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH @SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH@
/* !!! FIXME: in configure script version, missing here: */ #cmakedefine SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC @SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC@
#undef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH #cmakedefine SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL @SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL@
#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC #cmakedefine SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR @SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR@
#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL #cmakedefine SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON @SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON@
#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR
#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON
#endif
#cmakedefine SDL_VIDEO_DRIVER_MIR @SDL_VIDEO_DRIVER_MIR@ #cmakedefine SDL_VIDEO_DRIVER_MIR @SDL_VIDEO_DRIVER_MIR@
#cmakedefine SDL_VIDEO_DRIVER_MIR_DYNAMIC @SDL_VIDEO_DRIVER_MIR_DYNAMIC@ #cmakedefine SDL_VIDEO_DRIVER_MIR_DYNAMIC @SDL_VIDEO_DRIVER_MIR_DYNAMIC@
#cmakedefine SDL_VIDEO_DRIVER_MIR_DYNAMIC_XKBCOMMON @SDL_VIDEO_DRIVER_MIR_DYNAMIC_XKBCOMMON@ #cmakedefine SDL_VIDEO_DRIVER_MIR_DYNAMIC_XKBCOMMON @SDL_VIDEO_DRIVER_MIR_DYNAMIC_XKBCOMMON@
#cmakedefine SDL_VIDEO_DRIVER_EMSCRIPTEN @SDL_VIDEO_DRIVER_EMSCRIPTEN@
#cmakedefine SDL_VIDEO_DRIVER_X11 @SDL_VIDEO_DRIVER_X11@ #cmakedefine SDL_VIDEO_DRIVER_X11 @SDL_VIDEO_DRIVER_X11@
#cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC @SDL_VIDEO_DRIVER_X11_DYNAMIC@ #cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC @SDL_VIDEO_DRIVER_X11_DYNAMIC@
#cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT @SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT@ #cmakedefine SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT @SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT@
@ -325,6 +325,7 @@
#cmakedefine SDL_POWER_WINDOWS @SDL_POWER_WINDOWS@ #cmakedefine SDL_POWER_WINDOWS @SDL_POWER_WINDOWS@
#cmakedefine SDL_POWER_MACOSX @SDL_POWER_MACOSX@ #cmakedefine SDL_POWER_MACOSX @SDL_POWER_MACOSX@
#cmakedefine SDL_POWER_HAIKU @SDL_POWER_HAIKU@ #cmakedefine SDL_POWER_HAIKU @SDL_POWER_HAIKU@
#cmakedefine SDL_POWER_EMSCRIPTEN @SDL_POWER_EMSCRIPTEN@
#cmakedefine SDL_POWER_HARDWIRED @SDL_POWER_HARDWIRED@ #cmakedefine SDL_POWER_HARDWIRED @SDL_POWER_HARDWIRED@
/* Enable system filesystem support */ /* Enable system filesystem support */
@ -333,6 +334,7 @@
#cmakedefine SDL_FILESYSTEM_DUMMY @SDL_FILESYSTEM_DUMMY@ #cmakedefine SDL_FILESYSTEM_DUMMY @SDL_FILESYSTEM_DUMMY@
#cmakedefine SDL_FILESYSTEM_UNIX @SDL_FILESYSTEM_UNIX@ #cmakedefine SDL_FILESYSTEM_UNIX @SDL_FILESYSTEM_UNIX@
#cmakedefine SDL_FILESYSTEM_WINDOWS @SDL_FILESYSTEM_WINDOWS@ #cmakedefine SDL_FILESYSTEM_WINDOWS @SDL_FILESYSTEM_WINDOWS@
#cmakedefine SDL_FILESYSTEM_EMSCRIPTEN @SDL_FILESYSTEM_EMSCRIPTEN@
/* Enable assembly routines */ /* Enable assembly routines */
#cmakedefine SDL_ASSEMBLY_ROUTINES @SDL_ASSEMBLY_ROUTINES@ #cmakedefine SDL_ASSEMBLY_ROUTINES @SDL_ASSEMBLY_ROUTINES@

View File

@ -228,6 +228,7 @@
#undef SDL_AUDIO_DRIVER_WINMM #undef SDL_AUDIO_DRIVER_WINMM
#undef SDL_AUDIO_DRIVER_FUSIONSOUND #undef SDL_AUDIO_DRIVER_FUSIONSOUND
#undef SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC #undef SDL_AUDIO_DRIVER_FUSIONSOUND_DYNAMIC
#undef SDL_AUDIO_DRIVER_EMSCRIPTEN
/* Enable various input drivers */ /* Enable various input drivers */
#undef SDL_INPUT_LINUXEV #undef SDL_INPUT_LINUXEV
@ -243,6 +244,7 @@
#undef SDL_JOYSTICK_WINMM #undef SDL_JOYSTICK_WINMM
#undef SDL_JOYSTICK_USBHID #undef SDL_JOYSTICK_USBHID
#undef SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H #undef SDL_JOYSTICK_USBHID_MACHINE_JOYSTICK_H
#undef SDL_JOYSTICK_EMSCRIPTEN
#undef SDL_HAPTIC_DUMMY #undef SDL_HAPTIC_DUMMY
#undef SDL_HAPTIC_LINUX #undef SDL_HAPTIC_LINUX
#undef SDL_HAPTIC_IOKIT #undef SDL_HAPTIC_IOKIT
@ -287,6 +289,7 @@
#undef SDL_VIDEO_DRIVER_X11 #undef SDL_VIDEO_DRIVER_X11
#undef SDL_VIDEO_DRIVER_RPI #undef SDL_VIDEO_DRIVER_RPI
#undef SDL_VIDEO_DRIVER_ANDROID #undef SDL_VIDEO_DRIVER_ANDROID
#undef SDL_VIDEO_DRIVER_EMSCRIPTEN
#undef SDL_VIDEO_DRIVER_X11_DYNAMIC #undef SDL_VIDEO_DRIVER_X11_DYNAMIC
#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT
#undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR #undef SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR
@ -336,6 +339,7 @@
#undef SDL_POWER_MACOSX #undef SDL_POWER_MACOSX
#undef SDL_POWER_HAIKU #undef SDL_POWER_HAIKU
#undef SDL_POWER_ANDROID #undef SDL_POWER_ANDROID
#undef SDL_POWER_EMSCRIPTEN
#undef SDL_POWER_HARDWIRED #undef SDL_POWER_HARDWIRED
/* Enable system filesystem support */ /* Enable system filesystem support */
@ -345,6 +349,8 @@
#undef SDL_FILESYSTEM_UNIX #undef SDL_FILESYSTEM_UNIX
#undef SDL_FILESYSTEM_WINDOWS #undef SDL_FILESYSTEM_WINDOWS
#undef SDL_FILESYSTEM_NACL #undef SDL_FILESYSTEM_NACL
#undef SDL_FILESYSTEM_ANDROID
#undef SDL_FILESYSTEM_EMSCRIPTEN
/* Enable assembly routines */ /* Enable assembly routines */
#undef SDL_ASSEMBLY_ROUTINES #undef SDL_ASSEMBLY_ROUTINES

View File

@ -145,6 +145,9 @@
/* enable iPhone keyboard support */ /* enable iPhone keyboard support */
#define SDL_IPHONE_KEYBOARD 1 #define SDL_IPHONE_KEYBOARD 1
/* enable iOS extended launch screen */
#define SDL_IPHONE_LAUNCHSCREEN 1
/* enable joystick subsystem */ /* enable joystick subsystem */
#define SDL_JOYSTICK_DISABLED 0 #define SDL_JOYSTICK_DISABLED 0

View File

@ -1,6 +1,6 @@
/* /*
Simple DirectMedia Layer Simple DirectMedia Layer
Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org> Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages

View File

@ -134,6 +134,10 @@ typedef enum
/* Drag and drop events */ /* Drag and drop events */
SDL_DROPFILE = 0x1000, /**< The system requests a file open */ SDL_DROPFILE = 0x1000, /**< The system requests a file open */
/* Audio hotplug events */
SDL_AUDIODEVICEADDED = 0x1100, /**< A new audio device is available */
SDL_AUDIODEVICEREMOVED, /**< An audio device has been removed. */
/* Render events */ /* Render events */
SDL_RENDER_TARGETS_RESET = 0x2000, /**< The render targets have been reset and their contents need to be updated */ SDL_RENDER_TARGETS_RESET = 0x2000, /**< The render targets have been reset and their contents need to be updated */
SDL_RENDER_DEVICE_RESET, /**< The device has been reset and all textures need to be recreated */ SDL_RENDER_DEVICE_RESET, /**< The device has been reset and all textures need to be recreated */
@ -260,6 +264,7 @@ typedef struct SDL_MouseWheelEvent
Uint32 which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */ Uint32 which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */
Sint32 x; /**< The amount scrolled horizontally, positive to the right and negative to the left */ Sint32 x; /**< The amount scrolled horizontally, positive to the right and negative to the left */
Sint32 y; /**< The amount scrolled vertically, positive away from the user and negative toward the user */ Sint32 y; /**< The amount scrolled vertically, positive away from the user and negative toward the user */
Uint32 direction; /**< Set to one of the SDL_MOUSEWHEEL_* defines. When FLIPPED the values in X and Y will be opposite. Multiply by -1 to change them back */
} SDL_MouseWheelEvent; } SDL_MouseWheelEvent;
/** /**
@ -381,6 +386,20 @@ typedef struct SDL_ControllerDeviceEvent
Sint32 which; /**< The joystick device index for the ADDED event, instance id for the REMOVED or REMAPPED event */ Sint32 which; /**< The joystick device index for the ADDED event, instance id for the REMOVED or REMAPPED event */
} SDL_ControllerDeviceEvent; } SDL_ControllerDeviceEvent;
/**
* \brief Audio device event structure (event.adevice.*)
*/
typedef struct SDL_AudioDeviceEvent
{
Uint32 type; /**< ::SDL_AUDIODEVICEADDED, or ::SDL_AUDIODEVICEREMOVED */
Uint32 timestamp;
Uint32 which; /**< The audio device index for the ADDED event (valid until next SDL_GetNumAudioDevices() call), SDL_AudioDeviceID for the REMOVED event */
Uint8 iscapture; /**< zero if an output device, non-zero if a capture device. */
Uint8 padding1;
Uint8 padding2;
Uint8 padding3;
} SDL_AudioDeviceEvent;
/** /**
* \brief Touch finger event structure (event.tfinger.*) * \brief Touch finger event structure (event.tfinger.*)
@ -421,7 +440,7 @@ typedef struct SDL_MultiGestureEvent
*/ */
typedef struct SDL_DollarGestureEvent typedef struct SDL_DollarGestureEvent
{ {
Uint32 type; /**< ::SDL_DOLLARGESTURE */ Uint32 type; /**< ::SDL_DOLLARGESTURE or ::SDL_DOLLARRECORD */
Uint32 timestamp; Uint32 timestamp;
SDL_TouchID touchId; /**< The touch device id */ SDL_TouchID touchId; /**< The touch device id */
SDL_GestureID gestureId; SDL_GestureID gestureId;
@ -515,6 +534,7 @@ typedef union SDL_Event
SDL_ControllerAxisEvent caxis; /**< Game Controller axis event data */ SDL_ControllerAxisEvent caxis; /**< Game Controller axis event data */
SDL_ControllerButtonEvent cbutton; /**< Game Controller button event data */ SDL_ControllerButtonEvent cbutton; /**< Game Controller button event data */
SDL_ControllerDeviceEvent cdevice; /**< Game Controller device event data */ SDL_ControllerDeviceEvent cdevice; /**< Game Controller device event data */
SDL_AudioDeviceEvent adevice; /**< Audio device event data */
SDL_QuitEvent quit; /**< Quit request event data */ SDL_QuitEvent quit; /**< Quit request event data */
SDL_UserEvent user; /**< Custom event data */ SDL_UserEvent user; /**< Custom event data */
SDL_SysWMEvent syswm; /**< System dependent window event data */ SDL_SysWMEvent syswm; /**< System dependent window event data */

View File

@ -241,7 +241,8 @@ SDL_GameControllerGetBindForAxis(SDL_GameController *gamecontroller,
/** /**
* Get the current state of an axis control on a game controller. * Get the current state of an axis control on a game controller.
* *
* The state is a value ranging from -32768 to 32767. * The state is a value ranging from -32768 to 32767 (except for the triggers,
* which range from 0 to 32767).
* *
* The axis indices start at index 0. * The axis indices start at index 0.
*/ */

View File

@ -272,8 +272,9 @@ extern "C" {
#define SDL_HINT_ORIENTATIONS "SDL_IOS_ORIENTATIONS" #define SDL_HINT_ORIENTATIONS "SDL_IOS_ORIENTATIONS"
/** /**
* \brief A variable controlling whether an Android built-in accelerometer should be * \brief A variable controlling whether the Android / iOS built-in
* listed as a joystick device, rather than listing actual joysticks only. * accelerometer should be listed as a joystick device, rather than listing
* actual joysticks only.
* *
* This variable can be set to the following values: * This variable can be set to the following values:
* "0" - List only real joysticks and accept input from them * "0" - List only real joysticks and accept input from them
@ -356,7 +357,7 @@ extern "C" {
/** /**
* \brief If set to 1, then do not allow high-DPI windows. ("Retina" on Mac) * \brief If set to 1, then do not allow high-DPI windows. ("Retina" on Mac and iOS)
*/ */
#define SDL_HINT_VIDEO_HIGHDPI_DISABLED "SDL_VIDEO_HIGHDPI_DISABLED" #define SDL_HINT_VIDEO_HIGHDPI_DISABLED "SDL_VIDEO_HIGHDPI_DISABLED"
@ -543,6 +544,44 @@ extern "C" {
*/ */
#define SDL_HINT_IME_INTERNAL_EDITING "SDL_IME_INTERNAL_EDITING" #define SDL_HINT_IME_INTERNAL_EDITING "SDL_IME_INTERNAL_EDITING"
/**
* \brief A variable to control whether mouse and touch events are to be treated together or separately
*
* The variable can be set to the following values:
* "0" - Mouse events will be handled as touch events, and touch will raise fake mouse
* events. This is the behaviour of SDL <= 2.0.3. (default)
* "1" - Mouse events will be handled separately from pure touch events.
*
* The value of this hint is used at runtime, so it can be changed at any time.
*/
#define SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH "SDL_ANDROID_SEPARATE_MOUSE_AND_TOUCH"
/**
* \brief override the binding element for keyboard inputs for Emscripten builds
*
* This hint only applies to the emscripten platform
*
* The variable can be one of
* "#window" - The javascript window object (this is the default)
* "#document" - The javascript document object
* "#screen" - the javascript window.screen object
* "#canvas" - the WebGL canvas element
* any other string without a leading # sign applies to the element on the page with that ID.
*/
#define SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT "SDL_EMSCRIPTEN_KEYBOARD_ELEMENT"
/**
* \brief Tell SDL not to catch the SIGINT or SIGTERM signals.
*
* This hint only applies to Unix-like platforms.
*
* The variable can be set to the following values:
* "0" - SDL will install a SIGINT and SIGTERM handler, and when it
* catches a signal, convert it into an SDL_QUIT event.
* "1" - SDL will not install a signal handler at all.
*/
#define SDL_HINT_NO_SIGNAL_HANDLERS "SDL_NO_SIGNAL_HANDLERS"
/** /**
* \brief An enumeration of hint priorities * \brief An enumeration of hint priorities
*/ */

View File

@ -142,14 +142,11 @@ extern DECLSPEC void SDLCALL SDL_UnregisterApp(void);
* \brief Initializes and launches an SDL/WinRT application. * \brief Initializes and launches an SDL/WinRT application.
* *
* \param mainFunction The SDL app's C-style main(). * \param mainFunction The SDL app's C-style main().
* \param xamlBackgroundPanel An optional, XAML-based, background panel. * \param reserved Reserved for future use; should be NULL
* For Non-XAML apps, this value must be set to NULL. For XAML apps,
* pass in a pointer to a SwapChainBackgroundPanel, casted to an
* IInspectable (via reinterpret_cast).
* \ret 0 on success, -1 on failure. On failure, use SDL_GetError to retrieve more * \ret 0 on success, -1 on failure. On failure, use SDL_GetError to retrieve more
* information on the failure. * information on the failure.
*/ */
extern DECLSPEC int SDLCALL SDL_WinRTRunApp(int (*mainFunction)(int, char **), void * xamlBackgroundPanel); extern DECLSPEC int SDLCALL SDL_WinRTRunApp(int (*mainFunction)(int, char **), void * reserved);
#endif /* __WINRT__ */ #endif /* __WINRT__ */

View File

@ -60,6 +60,15 @@ typedef enum
SDL_NUM_SYSTEM_CURSORS SDL_NUM_SYSTEM_CURSORS
} SDL_SystemCursor; } SDL_SystemCursor;
/**
* \brief Scroll direction types for the Scroll event
*/
typedef enum
{
SDL_MOUSEWHEEL_NORMAL, /**< The scroll direction is normal */
SDL_MOUSEWHEEL_FLIPPED /**< The scroll direction is flipped / natural */
} SDL_MouseWheelDirection;
/* Function prototypes */ /* Function prototypes */
/** /**

View File

@ -2988,6 +2988,11 @@ GLAPI GLboolean APIENTRY glIsProgramARB (GLuint program);
#define GL_ARB_framebuffer_sRGB 1 #define GL_ARB_framebuffer_sRGB 1
#endif /* GL_ARB_framebuffer_sRGB */ #endif /* GL_ARB_framebuffer_sRGB */
#ifndef GL_KHR_context_flush_control
#define GL_CONTEXT_RELEASE_BEHAVIOR 0x82FB
#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82FC
#endif /* GL_KHR_context_flush_control */
#ifndef GL_ARB_geometry_shader4 #ifndef GL_ARB_geometry_shader4
#define GL_ARB_geometry_shader4 1 #define GL_ARB_geometry_shader4 1
#define GL_LINES_ADJACENCY_ARB 0x000A #define GL_LINES_ADJACENCY_ARB 0x000A

View File

@ -81,8 +81,8 @@ typedef struct SDL_RendererInfo
Uint32 flags; /**< Supported ::SDL_RendererFlags */ Uint32 flags; /**< Supported ::SDL_RendererFlags */
Uint32 num_texture_formats; /**< The number of available texture formats */ Uint32 num_texture_formats; /**< The number of available texture formats */
Uint32 texture_formats[16]; /**< The available texture formats */ Uint32 texture_formats[16]; /**< The available texture formats */
int max_texture_width; /**< The maximimum texture width */ int max_texture_width; /**< The maximum texture width */
int max_texture_height; /**< The maximimum texture height */ int max_texture_height; /**< The maximum texture height */
} SDL_RendererInfo; } SDL_RendererInfo;
/** /**
@ -792,7 +792,7 @@ extern DECLSPEC int SDLCALL SDL_RenderCopy(SDL_Renderer * renderer,
* \param dstrect A pointer to the destination rectangle, or NULL for the * \param dstrect A pointer to the destination rectangle, or NULL for the
* entire rendering target. * entire rendering target.
* \param angle An angle in degrees that indicates the rotation that will be applied to dstrect * \param angle An angle in degrees that indicates the rotation that will be applied to dstrect
* \param center A pointer to a point indicating the point around which dstrect will be rotated (if NULL, rotation will be done aroud dstrect.w/2, dstrect.h/2) * \param center A pointer to a point indicating the point around which dstrect will be rotated (if NULL, rotation will be done around dstrect.w/2, dstrect.h/2).
* \param flip An SDL_RendererFlip value stating which flipping actions should be performed on the texture * \param flip An SDL_RendererFlip value stating which flipping actions should be performed on the texture
* *
* \return 0 on success, or -1 on error * \return 0 on success, or -1 on error

View File

@ -172,7 +172,9 @@ typedef uint64_t Uint64;
#ifdef PRIs64 #ifdef PRIs64
#define SDL_PRIs64 PRIs64 #define SDL_PRIs64 PRIs64
#elif defined(__WIN32__) #elif defined(__WIN32__)
#define SDL_PRIs64 "I64" #define SDL_PRIs64 "I64d"
#elif defined(__LINUX__) && defined(__LP64__)
#define SDL_PRIs64 "ld"
#else #else
#define SDL_PRIs64 "lld" #define SDL_PRIs64 "lld"
#endif #endif
@ -182,10 +184,34 @@ typedef uint64_t Uint64;
#define SDL_PRIu64 PRIu64 #define SDL_PRIu64 PRIu64
#elif defined(__WIN32__) #elif defined(__WIN32__)
#define SDL_PRIu64 "I64u" #define SDL_PRIu64 "I64u"
#elif defined(__LINUX__) && defined(__LP64__)
#define SDL_PRIu64 "lu"
#else #else
#define SDL_PRIu64 "llu" #define SDL_PRIu64 "llu"
#endif #endif
#endif #endif
#ifndef SDL_PRIx64
#ifdef PRIx64
#define SDL_PRIx64 PRIx64
#elif defined(__WIN32__)
#define SDL_PRIx64 "I64x"
#elif defined(__LINUX__) && defined(__LP64__)
#define SDL_PRIx64 "lx"
#else
#define SDL_PRIx64 "llx"
#endif
#endif
#ifndef SDL_PRIX64
#ifdef PRIX64
#define SDL_PRIX64 PRIX64
#elif defined(__WIN32__)
#define SDL_PRIX64 "I64X"
#elif defined(__LINUX__) && defined(__LP64__)
#define SDL_PRIX64 "lX"
#else
#define SDL_PRIX64 "llX"
#endif
#endif
/* Annotations to help code analysis tools */ /* Annotations to help code analysis tools */
#ifdef SDL_DISABLE_ANALYZE_MACROS #ifdef SDL_DISABLE_ANALYZE_MACROS
@ -200,7 +226,7 @@ typedef uint64_t Uint64;
#define SDL_PRINTF_VARARG_FUNC( fmtargnumber ) #define SDL_PRINTF_VARARG_FUNC( fmtargnumber )
#define SDL_SCANF_VARARG_FUNC( fmtargnumber ) #define SDL_SCANF_VARARG_FUNC( fmtargnumber )
#else #else
#if _MSC_VER >= 1600 /* VS 2010 and above */ #if defined(_MSC_VER) && (_MSC_VER >= 1600) /* VS 2010 and above */
#include <sal.h> #include <sal.h>
#define SDL_IN_BYTECAP(x) _In_bytecount_(x) #define SDL_IN_BYTECAP(x) _In_bytecount_(x)
@ -361,11 +387,6 @@ SDL_FORCE_INLINE void SDL_memset4(void *dst, Uint32 val, size_t dwords)
extern DECLSPEC void *SDLCALL SDL_memcpy(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len); extern DECLSPEC void *SDLCALL SDL_memcpy(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len);
SDL_FORCE_INLINE void *SDL_memcpy4(SDL_OUT_BYTECAP(dwords*4) void *dst, SDL_IN_BYTECAP(dwords*4) const void *src, size_t dwords)
{
return SDL_memcpy(dst, src, dwords * 4);
}
extern DECLSPEC void *SDLCALL SDL_memmove(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len); extern DECLSPEC void *SDLCALL SDL_memmove(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len);
extern DECLSPEC int SDLCALL SDL_memcmp(const void *s1, const void *s2, size_t len); extern DECLSPEC int SDLCALL SDL_memcmp(const void *s1, const void *s2, size_t len);
@ -462,6 +483,39 @@ extern DECLSPEC char *SDLCALL SDL_iconv_string(const char *tocode,
#define SDL_iconv_utf8_ucs2(S) (Uint16 *)SDL_iconv_string("UCS-2-INTERNAL", "UTF-8", S, SDL_strlen(S)+1) #define SDL_iconv_utf8_ucs2(S) (Uint16 *)SDL_iconv_string("UCS-2-INTERNAL", "UTF-8", S, SDL_strlen(S)+1)
#define SDL_iconv_utf8_ucs4(S) (Uint32 *)SDL_iconv_string("UCS-4-INTERNAL", "UTF-8", S, SDL_strlen(S)+1) #define SDL_iconv_utf8_ucs4(S) (Uint32 *)SDL_iconv_string("UCS-4-INTERNAL", "UTF-8", S, SDL_strlen(S)+1)
/* force builds using Clang's static analysis tools to use literal C runtime
here, since there are possibly tests that are ineffective otherwise. */
#if defined(__clang_analyzer__) && !defined(SDL_DISABLE_ANALYZE_MACROS)
#define SDL_malloc malloc
#define SDL_calloc calloc
#define SDL_realloc realloc
#define SDL_free free
#define SDL_memset memset
#define SDL_memcpy memcpy
#define SDL_memmove memmove
#define SDL_memcmp memcmp
#define SDL_strlen strlen
#define SDL_strlcpy strlcpy
#define SDL_strlcat strlcat
#define SDL_strdup strdup
#define SDL_strchr strchr
#define SDL_strrchr strrchr
#define SDL_strstr strstr
#define SDL_strcmp strcmp
#define SDL_strncmp strncmp
#define SDL_strcasecmp strcasecmp
#define SDL_strncasecmp strncasecmp
#define SDL_sscanf sscanf
#define SDL_vsscanf vsscanf
#define SDL_snprintf snprintf
#define SDL_vsnprintf vsnprintf
#endif
SDL_FORCE_INLINE void *SDL_memcpy4(SDL_OUT_BYTECAP(dwords*4) void *dst, SDL_IN_BYTECAP(dwords*4) const void *src, size_t dwords)
{
return SDL_memcpy(dst, src, dwords * 4);
}
/* Ends C function definitions when using C++ */ /* Ends C function definitions when using C++ */
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -43,19 +43,25 @@ extern "C" {
/* Platform specific functions for Windows */ /* Platform specific functions for Windows */
#ifdef __WIN32__ #ifdef __WIN32__
/* Returns the D3D9 adapter index that matches the specified display index. /**
\brief Returns the D3D9 adapter index that matches the specified display index.
This adapter index can be passed to IDirect3D9::CreateDevice and controls This adapter index can be passed to IDirect3D9::CreateDevice and controls
on which monitor a full screen application will appear. on which monitor a full screen application will appear.
*/ */
extern DECLSPEC int SDLCALL SDL_Direct3D9GetAdapterIndex( int displayIndex ); extern DECLSPEC int SDLCALL SDL_Direct3D9GetAdapterIndex( int displayIndex );
/* Returns the D3D device associated with a renderer, or NULL if it's not a D3D renderer. typedef struct IDirect3DDevice9 IDirect3DDevice9;
/**
\brief Returns the D3D device associated with a renderer, or NULL if it's not a D3D renderer.
Once you are done using the device, you should release it to avoid a resource leak. Once you are done using the device, you should release it to avoid a resource leak.
*/ */
typedef struct IDirect3DDevice9 IDirect3DDevice9;
extern DECLSPEC IDirect3DDevice9* SDLCALL SDL_RenderGetD3D9Device(SDL_Renderer * renderer); extern DECLSPEC IDirect3DDevice9* SDLCALL SDL_RenderGetD3D9Device(SDL_Renderer * renderer);
/* Returns the DXGI Adapter and Output indices for the specified display index. /**
\brief Returns the DXGI Adapter and Output indices for the specified display index.
These can be passed to EnumAdapters and EnumOutputs respectively to get the objects These can be passed to EnumAdapters and EnumOutputs respectively to get the objects
required to create a DX10 or DX11 device and swap chain. required to create a DX10 or DX11 device and swap chain.
*/ */
@ -67,7 +73,10 @@ extern DECLSPEC SDL_bool SDLCALL SDL_DXGIGetOutputInfo( int displayIndex, int *a
/* Platform specific functions for iOS */ /* Platform specific functions for iOS */
#if defined(__IPHONEOS__) && __IPHONEOS__ #if defined(__IPHONEOS__) && __IPHONEOS__
#define SDL_iOSSetAnimationCallback(window, interval, callback, callbackParam) SDL_iPhoneSetAnimationCallback(window, interval, callback, callbackParam)
extern DECLSPEC int SDLCALL SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam); extern DECLSPEC int SDLCALL SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam);
#define SDL_iOSSetEventPump(enabled) SDL_iPhoneSetEventPump(enabled)
extern DECLSPEC void SDLCALL SDL_iPhoneSetEventPump(SDL_bool enabled); extern DECLSPEC void SDLCALL SDL_iPhoneSetEventPump(SDL_bool enabled);
#endif /* __IPHONEOS__ */ #endif /* __IPHONEOS__ */
@ -76,12 +85,16 @@ extern DECLSPEC void SDLCALL SDL_iPhoneSetEventPump(SDL_bool enabled);
/* Platform specific functions for Android */ /* Platform specific functions for Android */
#if defined(__ANDROID__) && __ANDROID__ #if defined(__ANDROID__) && __ANDROID__
/* Get the JNI environment for the current thread /**
\brief Get the JNI environment for the current thread
This returns JNIEnv*, but the prototype is void* so we don't need jni.h This returns JNIEnv*, but the prototype is void* so we don't need jni.h
*/ */
extern DECLSPEC void * SDLCALL SDL_AndroidGetJNIEnv(); extern DECLSPEC void * SDLCALL SDL_AndroidGetJNIEnv();
/* Get the SDL Activity object for the application /**
\brief Get the SDL Activity object for the application
This returns jobject, but the prototype is void* so we don't need jni.h This returns jobject, but the prototype is void* so we don't need jni.h
The jobject returned by SDL_AndroidGetActivity is a local reference. The jobject returned by SDL_AndroidGetActivity is a local reference.
It is the caller's responsibility to properly release it It is the caller's responsibility to properly release it
@ -89,26 +102,33 @@ extern DECLSPEC void * SDLCALL SDL_AndroidGetJNIEnv();
*/ */
extern DECLSPEC void * SDLCALL SDL_AndroidGetActivity(); extern DECLSPEC void * SDLCALL SDL_AndroidGetActivity();
/* See the official Android developer guide for more information: /**
See the official Android developer guide for more information:
http://developer.android.com/guide/topics/data/data-storage.html http://developer.android.com/guide/topics/data/data-storage.html
*/ */
#define SDL_ANDROID_EXTERNAL_STORAGE_READ 0x01 #define SDL_ANDROID_EXTERNAL_STORAGE_READ 0x01
#define SDL_ANDROID_EXTERNAL_STORAGE_WRITE 0x02 #define SDL_ANDROID_EXTERNAL_STORAGE_WRITE 0x02
/* Get the path used for internal storage for this application. /**
\brief Get the path used for internal storage for this application.
This path is unique to your application and cannot be written to This path is unique to your application and cannot be written to
by other applications. by other applications.
*/ */
extern DECLSPEC const char * SDLCALL SDL_AndroidGetInternalStoragePath(); extern DECLSPEC const char * SDLCALL SDL_AndroidGetInternalStoragePath();
/* Get the current state of external storage, a bitmask of these values: /**
\brief Get the current state of external storage, a bitmask of these values:
SDL_ANDROID_EXTERNAL_STORAGE_READ SDL_ANDROID_EXTERNAL_STORAGE_READ
SDL_ANDROID_EXTERNAL_STORAGE_WRITE SDL_ANDROID_EXTERNAL_STORAGE_WRITE
If external storage is currently unavailable, this will return 0. If external storage is currently unavailable, this will return 0.
*/ */
extern DECLSPEC int SDLCALL SDL_AndroidGetExternalStorageState(); extern DECLSPEC int SDLCALL SDL_AndroidGetExternalStorageState();
/* Get the path used for external storage for this application. /**
\brief Get the path used for external storage for this application.
This path is unique to your application, but is public and can be This path is unique to your application, but is public and can be
written to by other applications. written to by other applications.
*/ */
@ -151,7 +171,7 @@ typedef enum
* http://msdn.microsoft.com/en-us/library/windows/apps/hh464917.aspx * http://msdn.microsoft.com/en-us/library/windows/apps/hh464917.aspx
* *
* \param pathType The type of path to retrieve. * \param pathType The type of path to retrieve.
* \ret A UCS-2 string (16-bit, wide-char) containing the path, or NULL * \return A UCS-2 string (16-bit, wide-char) containing the path, or NULL
* if the path is not available for any reason. Not all paths are * if the path is not available for any reason. Not all paths are
* available on all versions of Windows. This is especially true on * available on all versions of Windows. This is especially true on
* Windows Phone. Check the documentation for the given * Windows Phone. Check the documentation for the given
@ -168,7 +188,7 @@ extern DECLSPEC const wchar_t * SDLCALL SDL_WinRTGetFSPathUNICODE(SDL_WinRT_Path
* http://msdn.microsoft.com/en-us/library/windows/apps/hh464917.aspx * http://msdn.microsoft.com/en-us/library/windows/apps/hh464917.aspx
* *
* \param pathType The type of path to retrieve. * \param pathType The type of path to retrieve.
* \ret A UTF-8 string (8-bit, multi-byte) containing the path, or NULL * \return A UTF-8 string (8-bit, multi-byte) containing the path, or NULL
* if the path is not available for any reason. Not all paths are * if the path is not available for any reason. Not all paths are
* available on all versions of Windows. This is especially true on * available on all versions of Windows. This is especially true on
* Windows Phone. Check the documentation for the given * Windows Phone. Check the documentation for the given

View File

@ -98,6 +98,7 @@ typedef struct _NSWindow NSWindow;
typedef struct _UIWindow UIWindow; typedef struct _UIWindow UIWindow;
typedef struct _UIViewController UIViewController; typedef struct _UIViewController UIViewController;
#endif #endif
typedef Uint32 GLuint;
#endif #endif
#if defined(SDL_VIDEO_DRIVER_ANDROID) #if defined(SDL_VIDEO_DRIVER_ANDROID)
@ -186,6 +187,7 @@ struct SDL_SysWMinfo
struct struct
{ {
HWND window; /**< The window handle */ HWND window; /**< The window handle */
HDC hdc; /**< The window device context */
} win; } win;
#endif #endif
#if defined(SDL_VIDEO_DRIVER_WINRT) #if defined(SDL_VIDEO_DRIVER_WINRT)
@ -227,6 +229,8 @@ struct SDL_SysWMinfo
#else #else
UIWindow *window; /* The UIKit window */ UIWindow *window; /* The UIKit window */
#endif #endif
GLuint framebuffer; /* The GL view's Framebuffer Object. It must be bound when rendering to the screen using GL. */
GLuint colorbuffer; /* The GL view's color Renderbuffer Object. It must be bound when SDL_GL_SwapWindow is called. */
} uikit; } uikit;
#endif #endif
#if defined(SDL_VIDEO_DRIVER_WAYLAND) #if defined(SDL_VIDEO_DRIVER_WAYLAND)

View File

@ -189,7 +189,8 @@ typedef enum
SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FLAGS,
SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_MASK,
SDL_GL_SHARE_WITH_CURRENT_CONTEXT, SDL_GL_SHARE_WITH_CURRENT_CONTEXT,
SDL_GL_FRAMEBUFFER_SRGB_CAPABLE SDL_GL_FRAMEBUFFER_SRGB_CAPABLE,
SDL_GL_CONTEXT_RELEASE_BEHAVIOR
} SDL_GLattr; } SDL_GLattr;
typedef enum typedef enum
@ -207,6 +208,12 @@ typedef enum
SDL_GL_CONTEXT_RESET_ISOLATION_FLAG = 0x0008 SDL_GL_CONTEXT_RESET_ISOLATION_FLAG = 0x0008
} SDL_GLcontextFlag; } SDL_GLcontextFlag;
typedef enum
{
SDL_GL_CONTEXT_RELEASE_BEHAVIOR_NONE = 0x0000,
SDL_GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH = 0x0001
} SDL_GLcontextReleaseFlag;
/* Function prototypes */ /* Function prototypes */
@ -715,6 +722,9 @@ extern DECLSPEC int SDLCALL SDL_UpdateWindowSurfaceRects(SDL_Window * window,
* \param window The window for which the input grab mode should be set. * \param window The window for which the input grab mode should be set.
* \param grabbed This is SDL_TRUE to grab input, and SDL_FALSE to release input. * \param grabbed This is SDL_TRUE to grab input, and SDL_FALSE to release input.
* *
* If the caller enables a grab while another window is currently grabbed,
* the other window loses its grab in favor of the caller's window.
*
* \sa SDL_GetWindowGrab() * \sa SDL_GetWindowGrab()
*/ */
extern DECLSPEC void SDLCALL SDL_SetWindowGrab(SDL_Window * window, extern DECLSPEC void SDLCALL SDL_SetWindowGrab(SDL_Window * window,
@ -729,6 +739,15 @@ extern DECLSPEC void SDLCALL SDL_SetWindowGrab(SDL_Window * window,
*/ */
extern DECLSPEC SDL_bool SDLCALL SDL_GetWindowGrab(SDL_Window * window); extern DECLSPEC SDL_bool SDLCALL SDL_GetWindowGrab(SDL_Window * window);
/**
* \brief Get the window that currently has an input grab enabled.
*
* \return This returns the window if input is grabbed, and NULL otherwise.
*
* \sa SDL_SetWindowGrab()
*/
extern DECLSPEC SDL_Window * SDLCALL SDL_GetGrabbedWindow(void);
/** /**
* \brief Set the brightness (gamma correction) for a window. * \brief Set the brightness (gamma correction) for a window.
* *

View File

@ -126,6 +126,9 @@
#ifndef SDL_IPHONE_KEYBOARD #ifndef SDL_IPHONE_KEYBOARD
#define SDL_IPHONE_KEYBOARD 1 #define SDL_IPHONE_KEYBOARD 1
#endif #endif
#ifndef SDL_IPHONE_LAUNCHSCREEN
#define SDL_IPHONE_LAUNCHSCREEN 1
#endif
#ifndef SDL_POWER_UIKIT #ifndef SDL_POWER_UIKIT
#define SDL_POWER_UIKIT 1 #define SDL_POWER_UIKIT 1
#endif #endif

View File

@ -405,6 +405,8 @@ SDL_GetPlatform()
return "BSDI"; return "BSDI";
#elif __DREAMCAST__ #elif __DREAMCAST__
return "Dreamcast"; return "Dreamcast";
#elif __EMSCRIPTEN__
return "Emscripten";
#elif __FREEBSD__ #elif __FREEBSD__
return "FreeBSD"; return "FreeBSD";
#elif __HAIKU__ #elif __HAIKU__

View File

@ -120,7 +120,7 @@ SDL_SetError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
so that it supports internationalization and thread-safe errors. so that it supports internationalization and thread-safe errors.
*/ */
static char * static char *
SDL_GetErrorMsg(char *errstr, unsigned int maxlen) SDL_GetErrorMsg(char *errstr, int maxlen)
{ {
SDL_error *error; SDL_error *error;
@ -163,37 +163,55 @@ SDL_GetErrorMsg(char *errstr, unsigned int maxlen)
len = len =
SDL_snprintf(msg, maxlen, tmp, SDL_snprintf(msg, maxlen, tmp,
error->args[argi++].value_i); error->args[argi++].value_i);
msg += len; if (len > 0) {
maxlen -= len; msg += len;
maxlen -= len;
}
break; break;
case 'f': case 'f':
len = len =
SDL_snprintf(msg, maxlen, tmp, SDL_snprintf(msg, maxlen, tmp,
error->args[argi++].value_f); error->args[argi++].value_f);
msg += len; if (len > 0) {
maxlen -= len; msg += len;
maxlen -= len;
}
break; break;
case 'p': case 'p':
len = len =
SDL_snprintf(msg, maxlen, tmp, SDL_snprintf(msg, maxlen, tmp,
error->args[argi++].value_ptr); error->args[argi++].value_ptr);
msg += len; if (len > 0) {
maxlen -= len; msg += len;
maxlen -= len;
}
break; break;
case 's': case 's':
len = len =
SDL_snprintf(msg, maxlen, tmp, SDL_snprintf(msg, maxlen, tmp,
SDL_LookupString(error->args[argi++]. SDL_LookupString(error->args[argi++].
buf)); buf));
msg += len; if (len > 0) {
maxlen -= len; msg += len;
maxlen -= len;
}
break; break;
} }
} else { } else {
*msg++ = *fmt++; *msg++ = *fmt++;
maxlen -= 1; maxlen -= 1;
} }
} }
/* slide back if we've overshot the end of our buffer. */
if (maxlen < 0) {
msg -= (-maxlen) + 1;
}
*msg = 0; /* NULL terminate the string */ *msg = 0; /* NULL terminate the string */
} }
return (errstr); return (errstr);

View File

@ -51,9 +51,7 @@ extern AudioBootStrap QSAAUDIO_bootstrap;
extern AudioBootStrap SUNAUDIO_bootstrap; extern AudioBootStrap SUNAUDIO_bootstrap;
extern AudioBootStrap ARTS_bootstrap; extern AudioBootStrap ARTS_bootstrap;
extern AudioBootStrap ESD_bootstrap; extern AudioBootStrap ESD_bootstrap;
#if SDL_AUDIO_DRIVER_NACL
extern AudioBootStrap NACLAUD_bootstrap; extern AudioBootStrap NACLAUD_bootstrap;
#endif
extern AudioBootStrap NAS_bootstrap; extern AudioBootStrap NAS_bootstrap;
extern AudioBootStrap XAUDIO2_bootstrap; extern AudioBootStrap XAUDIO2_bootstrap;
extern AudioBootStrap DSOUND_bootstrap; extern AudioBootStrap DSOUND_bootstrap;
@ -71,6 +69,7 @@ extern AudioBootStrap FUSIONSOUND_bootstrap;
extern AudioBootStrap ANDROIDAUD_bootstrap; extern AudioBootStrap ANDROIDAUD_bootstrap;
extern AudioBootStrap PSPAUD_bootstrap; extern AudioBootStrap PSPAUD_bootstrap;
extern AudioBootStrap SNDIO_bootstrap; extern AudioBootStrap SNDIO_bootstrap;
extern AudioBootStrap EmscriptenAudio_bootstrap;
/* Available audio drivers */ /* Available audio drivers */
@ -140,6 +139,9 @@ static const AudioBootStrap *const bootstrap[] = {
#endif #endif
#if SDL_AUDIO_DRIVER_PSP #if SDL_AUDIO_DRIVER_PSP
&PSPAUD_bootstrap, &PSPAUD_bootstrap,
#endif
#if SDL_AUDIO_DRIVER_EMSCRIPTEN
&EmscriptenAudio_bootstrap,
#endif #endif
NULL NULL
}; };
@ -159,8 +161,16 @@ get_audio_device(SDL_AudioDeviceID id)
/* stubs for audio drivers that don't need a specific entry point... */ /* stubs for audio drivers that don't need a specific entry point... */
static void static void
SDL_AudioDetectDevices_Default(int iscapture, SDL_AddAudioDevice addfn) SDL_AudioDetectDevices_Default(void)
{ /* no-op. */ {
/* 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_AddAudioDevice(SDL_FALSE, DEFAULT_OUTPUT_DEVNAME, (void *) ((size_t) 0x1));
if (current_audio.impl.HasCaptureSupport) {
SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, (void *) ((size_t) 0x2));
}
} }
static void static void
@ -205,10 +215,16 @@ SDL_AudioDeinitialize_Default(void)
{ /* no-op. */ { /* no-op. */
} }
static void
SDL_AudioFreeDeviceHandle_Default(void *handle)
{ /* no-op. */
}
static int static int
SDL_AudioOpenDevice_Default(_THIS, const char *devname, int iscapture) SDL_AudioOpenDevice_Default(_THIS, void *handle, const char *devname, int iscapture)
{ {
return -1; return SDL_Unsupported();
} }
static SDL_INLINE SDL_bool static SDL_INLINE SDL_bool
@ -265,71 +281,139 @@ finalize_audio_entry_points(void)
FILL_STUB(CloseDevice); FILL_STUB(CloseDevice);
FILL_STUB(LockDevice); FILL_STUB(LockDevice);
FILL_STUB(UnlockDevice); FILL_STUB(UnlockDevice);
FILL_STUB(FreeDeviceHandle);
FILL_STUB(Deinitialize); FILL_STUB(Deinitialize);
#undef FILL_STUB #undef FILL_STUB
} }
#if 0 /* !!! FIXME: rewrite/remove this streamer code. */
/* Streaming functions (for when the input and output buffer sizes are different) */
/* Write [length] bytes from buf into the streamer */
static void
SDL_StreamWrite(SDL_AudioStreamer * stream, Uint8 * buf, int length)
{
int i;
for (i = 0; i < length; ++i) { /* device hotplug support... */
stream->buffer[stream->write_pos] = buf[i];
++stream->write_pos;
}
}
/* Read [length] bytes out of the streamer into buf */
static void
SDL_StreamRead(SDL_AudioStreamer * stream, Uint8 * buf, int length)
{
int i;
for (i = 0; i < length; ++i) {
buf[i] = stream->buffer[stream->read_pos];
++stream->read_pos;
}
}
static int static int
SDL_StreamLength(SDL_AudioStreamer * stream) add_audio_device(const char *name, void *handle, SDL_AudioDeviceItem **devices, int *devCount)
{ {
return (stream->write_pos - stream->read_pos) % stream->max_len; int retval = -1;
} const size_t size = sizeof (SDL_AudioDeviceItem) + SDL_strlen(name) + 1;
SDL_AudioDeviceItem *item = (SDL_AudioDeviceItem *) SDL_malloc(size);
/* Initialize the stream by allocating the buffer and setting the read/write heads to the beginning */ if (item == NULL) {
#if 0
static int
SDL_StreamInit(SDL_AudioStreamer * stream, int max_len, Uint8 silence)
{
/* First try to allocate the buffer */
stream->buffer = (Uint8 *) SDL_malloc(max_len);
if (stream->buffer == NULL) {
return -1; return -1;
} }
stream->max_len = max_len; SDL_assert(handle != NULL); /* we reserve NULL, audio backends can't use it. */
stream->read_pos = 0;
stream->write_pos = 0;
/* Zero out the buffer */ item->handle = handle;
SDL_memset(stream->buffer, silence, max_len); SDL_strlcpy(item->name, name, size - sizeof (SDL_AudioDeviceItem));
return 0; SDL_LockMutex(current_audio.detectionLock);
item->next = *devices;
*devices = item;
retval = (*devCount)++;
SDL_UnlockMutex(current_audio.detectionLock);
return retval;
} }
#endif
/* Deinitialize the stream simply by freeing the buffer */ static SDL_INLINE int
static void add_capture_device(const char *name, void *handle)
SDL_StreamDeinit(SDL_AudioStreamer * stream)
{ {
SDL_free(stream->buffer); /* !!! FIXME: add this later. SDL_assert(current_audio.impl.HasCaptureSupport);*/
return add_audio_device(name, handle, &current_audio.inputDevices, &current_audio.inputDeviceCount);
} }
#endif
static SDL_INLINE int
add_output_device(const char *name, void *handle)
{
return add_audio_device(name, handle, &current_audio.outputDevices, &current_audio.outputDeviceCount);
}
static void
free_device_list(SDL_AudioDeviceItem **devices, int *devCount)
{
SDL_AudioDeviceItem *item, *next;
for (item = *devices; item != NULL; item = next) {
next = item->next;
if (item->handle != NULL) {
current_audio.impl.FreeDeviceHandle(item->handle);
}
SDL_free(item);
}
*devices = NULL;
*devCount = 0;
}
/* The audio backends call this when a new device is plugged in. */
void
SDL_AddAudioDevice(const int iscapture, const char *name, void *handle)
{
const int device_index = iscapture ? add_capture_device(name, handle) : add_output_device(name, handle);
if (device_index != -1) {
/* Post the event, if desired */
if (SDL_GetEventState(SDL_AUDIODEVICEADDED) == SDL_ENABLE) {
SDL_Event event;
SDL_zero(event);
event.adevice.type = SDL_AUDIODEVICEADDED;
event.adevice.which = device_index;
event.adevice.iscapture = iscapture;
SDL_PushEvent(&event);
}
}
}
/* The audio backends call this when a currently-opened device is lost. */
void SDL_OpenedAudioDeviceDisconnected(SDL_AudioDevice *device)
{
SDL_assert(get_audio_device(device->id) == device);
if (!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;
current_audio.impl.UnlockDevice(device);
/* Post the event, if desired */
if (SDL_GetEventState(SDL_AUDIODEVICEREMOVED) == SDL_ENABLE) {
SDL_Event event;
SDL_zero(event);
event.adevice.type = SDL_AUDIODEVICEREMOVED;
event.adevice.which = device->id;
event.adevice.iscapture = device->iscapture ? 1 : 0;
SDL_PushEvent(&event);
}
}
static void
mark_device_removed(void *handle, SDL_AudioDeviceItem *devices, SDL_bool *removedFlag)
{
SDL_AudioDeviceItem *item;
SDL_assert(handle != NULL);
for (item = devices; item != NULL; item = item->next) {
if (item->handle == handle) {
item->handle = NULL;
*removedFlag = SDL_TRUE;
return;
}
}
}
/* The audio backends call this when a device is removed from the system. */
void
SDL_RemoveAudioDevice(const int iscapture, void *handle)
{
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);
}
SDL_UnlockMutex(current_audio.detectionLock);
current_audio.impl.FreeDeviceHandle(handle);
}
/* buffer queueing support... */ /* buffer queueing support... */
@ -506,26 +590,17 @@ SDL_ClearQueuedAudio(SDL_AudioDeviceID devid)
} }
#if defined(__ANDROID__)
#include <android/log.h>
#endif
/* The general mixing thread function */ /* The general mixing thread function */
int SDLCALL int SDLCALL
SDL_RunAudio(void *devicep) SDL_RunAudio(void *devicep)
{ {
SDL_AudioDevice *device = (SDL_AudioDevice *) 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; Uint8 *stream;
int stream_len; void *udata = device->spec.userdata;
void *udata; void (SDLCALL *fill) (void *, Uint8 *, int) = device->spec.callback;
void (SDLCALL * fill) (void *userdata, Uint8 * stream, int len);
Uint32 delay;
#if 0 /* !!! FIXME: rewrite/remove this streamer code. */
/* For streaming when the buffer sizes don't match up */
Uint8 *istream;
int istream_len = 0;
#endif
/* The audio mixing is always a high priority thread */ /* The audio mixing is always a high priority thread */
SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH); SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH);
@ -534,197 +609,60 @@ SDL_RunAudio(void *devicep)
device->threadid = SDL_ThreadID(); device->threadid = SDL_ThreadID();
current_audio.impl.ThreadInit(device); current_audio.impl.ThreadInit(device);
/* Set up the mixing function */ /* Loop, filling the audio buffers */
fill = device->spec.callback; while (!device->shutdown) {
udata = device->spec.userdata; /* Fill the current buffer with sound */
if (device->convert.needed) {
/* By default do not stream */ stream = device->convert.buf;
device->use_streamer = 0; } else if (device->enabled) {
stream = current_audio.impl.GetDeviceBuf(device);
if (device->convert.needed) { } else {
#if 0 /* !!! FIXME: I took len_div out of the structure. Use rate_incr instead? */ /* if the device isn't enabled, we still write to the
/* If the result of the conversion alters the length, i.e. resampling is being used, use the streamer */ fake_stream, so the app's callback will fire with
if (device->convert.len_mult != 1 || device->convert.len_div != 1) { a regular frequency, in case they depend on that
/* The streamer's maximum length should be twice whichever is larger: spec.size or len_cvt */ for timing or progress. They can use hotplug
stream_max_len = 2 * device->spec.size; now to know if the device failed. */
if (device->convert.len_mult > device->convert.len_div) { stream = NULL;
stream_max_len *= device->convert.len_mult;
stream_max_len /= device->convert.len_div;
}
if (SDL_StreamInit(&device->streamer, stream_max_len, silence) <
0)
return -1;
device->use_streamer = 1;
/* istream_len should be the length of what we grab from the callback and feed to conversion,
so that we get close to spec_size. I.e. we want device.spec_size = istream_len * u / d
*/
istream_len =
device->spec.size * device->convert.len_div /
device->convert.len_mult;
} }
#endif
stream_len = device->convert.len;
} else {
stream_len = device->spec.size;
}
/* Calculate the delay while paused */
delay = ((device->spec.samples * 1000) / device->spec.freq);
/* Determine if the streamer is necessary here */
#if 0 /* !!! FIXME: rewrite/remove this streamer code. */
if (device->use_streamer == 1) {
/* This code is almost the same as the old code. The difference is, instead of reading
directly from the callback into "stream", then converting and sending the audio off,
we go: callback -> "istream" -> (conversion) -> streamer -> stream -> device.
However, reading and writing with streamer are done separately:
- We only call the callback and write to the streamer when the streamer does not
contain enough samples to output to the device.
- We only read from the streamer and tell the device to play when the streamer
does have enough samples to output.
This allows us to perform resampling in the conversion step, where the output of the
resampling process can be any number. We will have to see what a good size for the
stream's maximum length is, but I suspect 2*max(len_cvt, stream_len) is a good figure.
*/
while (device->enabled) {
if (device->paused) {
SDL_Delay(delay);
continue;
}
/* Only read in audio if the streamer doesn't have enough already (if it does not have enough samples to output) */
if (SDL_StreamLength(&device->streamer) < stream_len) {
/* Set up istream */
if (device->convert.needed) {
if (device->convert.buf) {
istream = device->convert.buf;
} else {
continue;
}
} else {
/* FIXME: Ryan, this is probably wrong. I imagine we don't want to get
* a device buffer both here and below in the stream output.
*/
istream = current_audio.impl.GetDeviceBuf(device);
if (istream == NULL) {
istream = device->fake_stream;
}
}
/* Read from the callback into the _input_ stream */
SDL_LockMutex(device->mixer_lock);
(*fill) (udata, istream, istream_len);
SDL_UnlockMutex(device->mixer_lock);
/* Convert the audio if necessary and write to the streamer */
if (device->convert.needed) {
SDL_ConvertAudio(&device->convert);
if (istream == NULL) {
istream = device->fake_stream;
}
/* SDL_memcpy(istream, device->convert.buf, device->convert.len_cvt); */
SDL_StreamWrite(&device->streamer, device->convert.buf,
device->convert.len_cvt);
} else {
SDL_StreamWrite(&device->streamer, istream, istream_len);
}
}
/* Only output audio if the streamer has enough to output */
if (SDL_StreamLength(&device->streamer) >= stream_len) {
/* Set up the output stream */
if (device->convert.needed) {
if (device->convert.buf) {
stream = device->convert.buf;
} else {
continue;
}
} else {
stream = current_audio.impl.GetDeviceBuf(device);
if (stream == NULL) {
stream = device->fake_stream;
}
}
/* Now read from the streamer */
SDL_StreamRead(&device->streamer, stream, stream_len);
/* Ready current buffer for play and change current buffer */
if (stream != device->fake_stream) {
current_audio.impl.PlayDevice(device);
/* Wait for an audio buffer to become available */
current_audio.impl.WaitDevice(device);
} else {
SDL_Delay(delay);
}
}
if (stream == NULL) {
stream = device->fake_stream;
} }
} else
#endif
{
/* Otherwise, do not use the streamer. This is the old code. */
const int silence = (int) device->spec.silence;
/* Loop, filling the audio buffers */ /* !!! FIXME: this should be LockDevice. */
while (device->enabled) { SDL_LockMutex(device->mixer_lock);
if (device->paused) {
SDL_memset(stream, silence, stream_len);
} else {
(*fill) (udata, stream, stream_len);
}
SDL_UnlockMutex(device->mixer_lock);
/* Fill the current buffer with sound */ /* Convert the audio if necessary */
if (device->convert.needed) { if (device->enabled && device->convert.needed) {
if (device->convert.buf) { SDL_ConvertAudio(&device->convert);
stream = device->convert.buf; stream = current_audio.impl.GetDeviceBuf(device);
} else { if (stream == NULL) {
continue; stream = device->fake_stream;
}
} else { } else {
stream = current_audio.impl.GetDeviceBuf(device);
if (stream == NULL) {
stream = device->fake_stream;
}
}
SDL_LockMutex(device->mixer_lock);
if (device->paused) {
SDL_memset(stream, silence, stream_len);
} else {
(*fill) (udata, stream, stream_len);
}
SDL_UnlockMutex(device->mixer_lock);
/* Convert the audio if necessary */
if (device->convert.needed) {
SDL_ConvertAudio(&device->convert);
stream = current_audio.impl.GetDeviceBuf(device);
if (stream == NULL) {
stream = device->fake_stream;
}
SDL_memcpy(stream, device->convert.buf, SDL_memcpy(stream, device->convert.buf,
device->convert.len_cvt); device->convert.len_cvt);
} }
}
/* Ready current buffer for play and change current buffer */ /* Ready current buffer for play and change current buffer */
if (stream != device->fake_stream) { if (stream == device->fake_stream) {
current_audio.impl.PlayDevice(device); SDL_Delay(delay);
/* Wait for an audio buffer to become available */ } else {
current_audio.impl.WaitDevice(device); current_audio.impl.PlayDevice(device);
} else { current_audio.impl.WaitDevice(device);
SDL_Delay(delay);
}
} }
} }
/* Wait for the audio to drain.. */ /* Wait for the audio to drain. */
current_audio.impl.WaitDone(device); current_audio.impl.WaitDone(device);
/* If necessary, deinit the streamer */ return 0;
#if 0 /* !!! FIXME: rewrite/remove this streamer code. */
if (device->use_streamer == 1)
SDL_StreamDeinit(&device->streamer);
#endif
return (0);
} }
@ -757,16 +695,16 @@ SDL_ParseAudioFormat(const char *string)
int int
SDL_GetNumAudioDrivers(void) SDL_GetNumAudioDrivers(void)
{ {
return (SDL_arraysize(bootstrap) - 1); return SDL_arraysize(bootstrap) - 1;
} }
const char * const char *
SDL_GetAudioDriver(int index) SDL_GetAudioDriver(int index)
{ {
if (index >= 0 && index < SDL_GetNumAudioDrivers()) { if (index >= 0 && index < SDL_GetNumAudioDrivers()) {
return (bootstrap[index]->name); return bootstrap[index]->name;
} }
return (NULL); return NULL;
} }
int int
@ -780,8 +718,8 @@ SDL_AudioInit(const char *driver_name)
SDL_AudioQuit(); /* shutdown driver if already running. */ SDL_AudioQuit(); /* shutdown driver if already running. */
} }
SDL_memset(&current_audio, '\0', sizeof(current_audio)); SDL_zero(current_audio);
SDL_memset(open_devices, '\0', sizeof(open_devices)); SDL_zero(open_devices);
/* Select the proper audio driver */ /* Select the proper audio driver */
if (driver_name == NULL) { if (driver_name == NULL) {
@ -797,7 +735,7 @@ SDL_AudioInit(const char *driver_name)
} }
tried_to_init = 1; tried_to_init = 1;
SDL_memset(&current_audio, 0, sizeof(current_audio)); SDL_zero(current_audio);
current_audio.name = backend->name; current_audio.name = backend->name;
current_audio.desc = backend->desc; current_audio.desc = backend->desc;
initialized = backend->init(&current_audio.impl); initialized = backend->init(&current_audio.impl);
@ -813,13 +751,18 @@ SDL_AudioInit(const char *driver_name)
} }
} }
SDL_memset(&current_audio, 0, sizeof(current_audio)); SDL_zero(current_audio);
return (-1); /* No driver was available, so fail. */ return -1; /* No driver was available, so fail. */
} }
current_audio.detectionLock = SDL_CreateMutex();
finalize_audio_entry_points(); finalize_audio_entry_points();
return (0); /* Make sure we have a list of devices available at startup. */
current_audio.impl.DetectDevices();
return 0;
} }
/* /*
@ -831,50 +774,32 @@ SDL_GetCurrentAudioDriver()
return current_audio.name; return current_audio.name;
} }
/* Clean out devices that we've removed but had to keep around for stability. */
static void static void
free_device_list(char ***devices, int *devCount) clean_out_device_list(SDL_AudioDeviceItem **devices, int *devCount, SDL_bool *removedFlag)
{ {
int i = *devCount; SDL_AudioDeviceItem *item = *devices;
if ((i > 0) && (*devices != NULL)) { SDL_AudioDeviceItem *prev = NULL;
while (i--) { int total = 0;
SDL_free((*devices)[i]);
while (item) {
SDL_AudioDeviceItem *next = item->next;
if (item->handle != NULL) {
total++;
prev = item;
} else {
if (prev) {
prev->next = next;
} else {
*devices = next;
}
SDL_free(item);
} }
item = next;
} }
SDL_free(*devices); *devCount = total;
*removedFlag = SDL_FALSE;
*devices = NULL;
*devCount = 0;
}
static
void SDL_AddCaptureAudioDevice(const char *_name)
{
char *name = NULL;
void *ptr = SDL_realloc(current_audio.inputDevices,
(current_audio.inputDeviceCount+1) * sizeof(char*));
if (ptr == NULL) {
return; /* oh well. */
}
current_audio.inputDevices = (char **) ptr;
name = SDL_strdup(_name); /* if this returns NULL, that's okay. */
current_audio.inputDevices[current_audio.inputDeviceCount++] = name;
}
static
void SDL_AddOutputAudioDevice(const char *_name)
{
char *name = NULL;
void *ptr = SDL_realloc(current_audio.outputDevices,
(current_audio.outputDeviceCount+1) * sizeof(char*));
if (ptr == NULL) {
return; /* oh well. */
}
current_audio.outputDevices = (char **) ptr;
name = SDL_strdup(_name); /* if this returns NULL, that's okay. */
current_audio.outputDevices[current_audio.outputDeviceCount++] = name;
} }
@ -887,29 +812,18 @@ SDL_GetNumAudioDevices(int iscapture)
return -1; return -1;
} }
if ((iscapture) && (!current_audio.impl.HasCaptureSupport)) { SDL_LockMutex(current_audio.detectionLock);
return 0; if (iscapture && current_audio.captureDevicesRemoved) {
clean_out_device_list(&current_audio.inputDevices, &current_audio.inputDeviceCount, &current_audio.captureDevicesRemoved);
} }
if ((iscapture) && (current_audio.impl.OnlyHasDefaultInputDevice)) { if (!iscapture && current_audio.outputDevicesRemoved) {
return 1; clean_out_device_list(&current_audio.outputDevices, &current_audio.outputDeviceCount, &current_audio.outputDevicesRemoved);
current_audio.outputDevicesRemoved = SDL_FALSE;
} }
if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) { retval = iscapture ? current_audio.inputDeviceCount : current_audio.outputDeviceCount;
return 1; SDL_UnlockMutex(current_audio.detectionLock);
}
if (iscapture) {
free_device_list(&current_audio.inputDevices,
&current_audio.inputDeviceCount);
current_audio.impl.DetectDevices(iscapture, SDL_AddCaptureAudioDevice);
retval = current_audio.inputDeviceCount;
} else {
free_device_list(&current_audio.outputDevices,
&current_audio.outputDeviceCount);
current_audio.impl.DetectDevices(iscapture, SDL_AddOutputAudioDevice);
retval = current_audio.outputDeviceCount;
}
return retval; return retval;
} }
@ -918,6 +832,8 @@ SDL_GetNumAudioDevices(int iscapture)
const char * const char *
SDL_GetAudioDeviceName(int index, int iscapture) SDL_GetAudioDeviceName(int index, int iscapture)
{ {
const char *retval = NULL;
if (!SDL_WasInit(SDL_INIT_AUDIO)) { if (!SDL_WasInit(SDL_INIT_AUDIO)) {
SDL_SetError("Audio subsystem is not initialized"); SDL_SetError("Audio subsystem is not initialized");
return NULL; return NULL;
@ -928,39 +844,28 @@ SDL_GetAudioDeviceName(int index, int iscapture)
return NULL; return NULL;
} }
if (index < 0) { if (index >= 0) {
goto no_such_device; SDL_AudioDeviceItem *item;
int i;
SDL_LockMutex(current_audio.detectionLock);
item = iscapture ? current_audio.inputDevices : current_audio.outputDevices;
i = iscapture ? current_audio.inputDeviceCount : current_audio.outputDeviceCount;
if (index < i) {
for (i--; i > index; i--, item = item->next) {
SDL_assert(item != NULL);
}
SDL_assert(item != NULL);
retval = item->name;
}
SDL_UnlockMutex(current_audio.detectionLock);
} }
if ((iscapture) && (current_audio.impl.OnlyHasDefaultInputDevice)) { if (retval == NULL) {
if (index > 0) { SDL_SetError("No such device");
goto no_such_device;
}
return DEFAULT_INPUT_DEVNAME;
} }
if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) { return retval;
if (index > 0) {
goto no_such_device;
}
return DEFAULT_OUTPUT_DEVNAME;
}
if (iscapture) {
if (index >= current_audio.inputDeviceCount) {
goto no_such_device;
}
return current_audio.inputDevices[index];
} else {
if (index >= current_audio.outputDeviceCount) {
goto no_such_device;
}
return current_audio.outputDevices[index];
}
no_such_device:
SDL_SetError("No such device");
return NULL;
} }
@ -968,6 +873,7 @@ static void
close_audio_device(SDL_AudioDevice * device) close_audio_device(SDL_AudioDevice * device)
{ {
device->enabled = 0; device->enabled = 0;
device->shutdown = 1;
if (device->thread != NULL) { if (device->thread != NULL) {
SDL_WaitThread(device->thread, NULL); SDL_WaitThread(device->thread, NULL);
} }
@ -1061,6 +967,8 @@ open_audio_device(const char *devname, int iscapture,
SDL_AudioSpec _obtained; SDL_AudioSpec _obtained;
SDL_AudioDevice *device; SDL_AudioDevice *device;
SDL_bool build_cvt; SDL_bool build_cvt;
void *handle = NULL;
Uint32 stream_len;
int i = 0; int i = 0;
if (!SDL_WasInit(SDL_INIT_AUDIO)) { if (!SDL_WasInit(SDL_INIT_AUDIO)) {
@ -1073,6 +981,18 @@ open_audio_device(const char *devname, int iscapture,
return 0; return 0;
} }
/* Find an available device ID... */
for (id = min_id - 1; id < SDL_arraysize(open_devices); id++) {
if (open_devices[id] == NULL) {
break;
}
}
if (id == SDL_arraysize(open_devices)) {
SDL_SetError("Too many open audio devices");
return 0;
}
if (!obtained) { if (!obtained) {
obtained = &_obtained; obtained = &_obtained;
} }
@ -1108,9 +1028,7 @@ open_audio_device(const char *devname, int iscapture,
return 0; return 0;
} }
} }
} } else if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) {
if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) {
if ((devname) && (SDL_strcmp(devname, DEFAULT_OUTPUT_DEVNAME) != 0)) { if ((devname) && (SDL_strcmp(devname, DEFAULT_OUTPUT_DEVNAME) != 0)) {
SDL_SetError("No such device"); SDL_SetError("No such device");
return 0; return 0;
@ -1123,6 +1041,30 @@ open_audio_device(const char *devname, int iscapture,
return 0; return 0;
} }
} }
} else if (devname != NULL) {
/* if the app specifies an exact string, we can pass the backend
an actual device handle thingey, which saves them the effort of
figuring out what device this was (such as, reenumerating
everything again to find the matching human-readable name).
It might still need to open a device based on the string for,
say, a network audio server, but this optimizes some cases. */
SDL_AudioDeviceItem *item;
SDL_LockMutex(current_audio.detectionLock);
for (item = iscapture ? current_audio.inputDevices : current_audio.outputDevices; item; item = item->next) {
if ((item->handle != NULL) && (SDL_strcmp(item->name, devname) == 0)) {
handle = item->handle;
break;
}
}
SDL_UnlockMutex(current_audio.detectionLock);
}
if (!current_audio.impl.AllowsArbitraryDeviceNames) {
/* has to be in our device list, or the default device. */
if ((handle == NULL) && (devname != NULL)) {
SDL_SetError("No such device.");
return 0;
}
} }
device = (SDL_AudioDevice *) SDL_AllocAudioMem(sizeof(SDL_AudioDevice)); device = (SDL_AudioDevice *) SDL_AllocAudioMem(sizeof(SDL_AudioDevice));
@ -1131,12 +1073,13 @@ open_audio_device(const char *devname, int iscapture,
return 0; return 0;
} }
SDL_zerop(device); SDL_zerop(device);
device->id = id + 1;
device->spec = *obtained; device->spec = *obtained;
device->enabled = 1; device->enabled = 1;
device->paused = 1; device->paused = 1;
device->iscapture = iscapture; device->iscapture = iscapture;
/* Create a semaphore for locking the sound buffers */ /* Create a mutex for locking the sound buffers */
if (!current_audio.impl.SkipMixerLock) { if (!current_audio.impl.SkipMixerLock) {
device->mixer_lock = SDL_CreateMutex(); device->mixer_lock = SDL_CreateMutex();
if (device->mixer_lock == NULL) { if (device->mixer_lock == NULL) {
@ -1146,26 +1089,12 @@ open_audio_device(const char *devname, int iscapture,
} }
} }
/* force a device detection if we haven't done one yet. */ if (current_audio.impl.OpenDevice(device, handle, devname, iscapture) < 0) {
if ( ((iscapture) && (current_audio.inputDevices == NULL)) ||
((!iscapture) && (current_audio.outputDevices == NULL)) ) {
SDL_GetNumAudioDevices(iscapture);
}
if (current_audio.impl.OpenDevice(device, devname, iscapture) < 0) {
close_audio_device(device); close_audio_device(device);
return 0; return 0;
} }
device->opened = 1; device->opened = 1;
/* Allocate a fake audio memory buffer */
device->fake_stream = (Uint8 *)SDL_AllocAudioMem(device->spec.size);
if (device->fake_stream == NULL) {
close_audio_device(device);
SDL_OutOfMemory();
return 0;
}
/* See if we need to do any conversion */ /* See if we need to do any conversion */
build_cvt = SDL_FALSE; build_cvt = SDL_FALSE;
if (obtained->freq != device->spec.freq) { if (obtained->freq != device->spec.freq) {
@ -1224,6 +1153,19 @@ open_audio_device(const char *devname, int iscapture,
} }
} }
/* 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? */ if (device->spec.callback == NULL) { /* use buffer queueing? */
/* pool a few packets to start. Enough for two callbacks. */ /* pool a few packets to start. Enough for two callbacks. */
const int packetlen = SDL_AUDIOBUFFERQUEUE_PACKETLEN; const int packetlen = SDL_AUDIOBUFFERQUEUE_PACKETLEN;
@ -1243,25 +1185,14 @@ open_audio_device(const char *devname, int iscapture,
device->spec.userdata = device; device->spec.userdata = device;
} }
/* Find an available device ID and store the structure... */ /* add it to our list of open devices. */
for (id = min_id - 1; id < SDL_arraysize(open_devices); id++) { open_devices[id] = device;
if (open_devices[id] == NULL) {
open_devices[id] = device;
break;
}
}
if (id == SDL_arraysize(open_devices)) {
SDL_SetError("Too many open audio devices");
close_audio_device(device);
return 0;
}
/* Start the audio thread if necessary */ /* Start the audio thread if necessary */
if (!current_audio.impl.ProvidesOwnCallbackThread) { if (!current_audio.impl.ProvidesOwnCallbackThread) {
/* Start the audio thread */ /* Start the audio thread */
char name[64]; char name[64];
SDL_snprintf(name, sizeof (name), "SDLAudioDev%d", (int) (id + 1)); SDL_snprintf(name, sizeof (name), "SDLAudioDev%d", (int) device->id);
/* !!! FIXME: this is nasty. */ /* !!! FIXME: this is nasty. */
#if defined(__WIN32__) && !defined(HAVE_LIBC) #if defined(__WIN32__) && !defined(HAVE_LIBC)
#undef SDL_CreateThread #undef SDL_CreateThread
@ -1274,13 +1205,13 @@ open_audio_device(const char *devname, int iscapture,
device->thread = SDL_CreateThread(SDL_RunAudio, name, device); device->thread = SDL_CreateThread(SDL_RunAudio, name, device);
#endif #endif
if (device->thread == NULL) { if (device->thread == NULL) {
SDL_CloseAudioDevice(id + 1); SDL_CloseAudioDevice(device->id);
SDL_SetError("Couldn't create audio thread"); SDL_SetError("Couldn't create audio thread");
return 0; return 0;
} }
} }
return id + 1; return device->id;
} }
@ -1292,14 +1223,14 @@ SDL_OpenAudio(SDL_AudioSpec * desired, SDL_AudioSpec * obtained)
/* Start up the audio driver, if necessary. This is legacy behaviour! */ /* Start up the audio driver, if necessary. This is legacy behaviour! */
if (!SDL_WasInit(SDL_INIT_AUDIO)) { if (!SDL_WasInit(SDL_INIT_AUDIO)) {
if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) { if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
return (-1); return -1;
} }
} }
/* SDL_OpenAudio() is legacy and can only act on Device ID #1. */ /* SDL_OpenAudio() is legacy and can only act on Device ID #1. */
if (open_devices[0] != NULL) { if (open_devices[0] != NULL) {
SDL_SetError("Audio device is already opened"); SDL_SetError("Audio device is already opened");
return (-1); return -1;
} }
if (obtained) { if (obtained) {
@ -1310,7 +1241,7 @@ SDL_OpenAudio(SDL_AudioSpec * desired, SDL_AudioSpec * obtained)
} }
SDL_assert((id == 0) || (id == 1)); SDL_assert((id == 0) || (id == 1));
return ((id == 0) ? -1 : 0); return (id == 0) ? -1 : 0;
} }
SDL_AudioDeviceID SDL_AudioDeviceID
@ -1334,7 +1265,7 @@ SDL_GetAudioDeviceStatus(SDL_AudioDeviceID devid)
status = SDL_AUDIO_PLAYING; status = SDL_AUDIO_PLAYING;
} }
} }
return (status); return status;
} }
@ -1425,14 +1356,16 @@ SDL_AudioQuit(void)
} }
} }
free_device_list(&current_audio.outputDevices, &current_audio.outputDeviceCount);
free_device_list(&current_audio.inputDevices, &current_audio.inputDeviceCount);
/* Free the driver data */ /* Free the driver data */
current_audio.impl.Deinitialize(); current_audio.impl.Deinitialize();
free_device_list(&current_audio.outputDevices,
&current_audio.outputDeviceCount); SDL_DestroyMutex(current_audio.detectionLock);
free_device_list(&current_audio.inputDevices,
&current_audio.inputDeviceCount); SDL_zero(current_audio);
SDL_memset(&current_audio, '\0', sizeof(current_audio)); SDL_zero(open_devices);
SDL_memset(open_devices, '\0', sizeof(open_devices));
} }
#define NUM_FORMATS 10 #define NUM_FORMATS 10
@ -1470,16 +1403,16 @@ SDL_FirstAudioFormat(SDL_AudioFormat format)
} }
} }
format_idx_sub = 0; format_idx_sub = 0;
return (SDL_NextAudioFormat()); return SDL_NextAudioFormat();
} }
SDL_AudioFormat SDL_AudioFormat
SDL_NextAudioFormat(void) SDL_NextAudioFormat(void)
{ {
if ((format_idx == NUM_FORMATS) || (format_idx_sub == NUM_FORMATS)) { if ((format_idx == NUM_FORMATS) || (format_idx_sub == NUM_FORMATS)) {
return (0); return 0;
} }
return (format_list[format_idx][format_idx_sub++]); return format_list[format_idx][format_idx_sub++];
} }
void void

View File

@ -46,18 +46,21 @@
#define _PATH_DEV_AUDIO "/dev/audio" #define _PATH_DEV_AUDIO "/dev/audio"
#endif #endif
static SDL_INLINE void static void
test_device(const char *fname, int flags, int (*test) (int fd), test_device(const int iscapture, const char *fname, int flags, int (*test) (int fd))
SDL_AddAudioDevice addfn)
{ {
struct stat sb; struct stat sb;
if ((stat(fname, &sb) == 0) && (S_ISCHR(sb.st_mode))) { if ((stat(fname, &sb) == 0) && (S_ISCHR(sb.st_mode))) {
const int audio_fd = open(fname, flags, 0); const int audio_fd = open(fname, flags, 0);
if (audio_fd >= 0) { if (audio_fd >= 0) {
if (test(audio_fd)) { const int okay = test(audio_fd);
addfn(fname);
}
close(audio_fd); close(audio_fd);
if (okay) {
static size_t dummyhandle = 0;
dummyhandle++;
SDL_assert(dummyhandle != 0);
SDL_AddAudioDevice(iscapture, fname, (void *) dummyhandle);
}
} }
} }
} }
@ -68,11 +71,10 @@ test_stub(int fd)
return 1; return 1;
} }
void static void
SDL_EnumUnixAudioDevices(int iscapture, int classic, int (*test)(int fd), SDL_EnumUnixAudioDevices_Internal(const int iscapture, const int classic, int (*test)(int))
SDL_AddAudioDevice addfn)
{ {
const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT); const int flags = iscapture ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT;
const char *audiodev; const char *audiodev;
char audiopath[1024]; char audiopath[1024];
@ -97,17 +99,25 @@ SDL_EnumUnixAudioDevices(int iscapture, int classic, int (*test)(int fd),
} }
} }
} }
test_device(audiodev, flags, test, addfn); test_device(iscapture, audiodev, flags, test);
if (SDL_strlen(audiodev) < (sizeof(audiopath) - 3)) { if (SDL_strlen(audiodev) < (sizeof(audiopath) - 3)) {
int instance = 0; int instance = 0;
while (instance++ <= 64) { while (instance++ <= 64) {
SDL_snprintf(audiopath, SDL_arraysize(audiopath), SDL_snprintf(audiopath, SDL_arraysize(audiopath),
"%s%d", audiodev, instance); "%s%d", audiodev, instance);
test_device(audiopath, flags, test, addfn); test_device(iscapture, audiopath, flags, test);
} }
} }
} }
void
SDL_EnumUnixAudioDevices(const int classic, int (*test)(int))
{
SDL_EnumUnixAudioDevices_Internal(SDL_TRUE, classic, test);
SDL_EnumUnixAudioDevices_Internal(SDL_FALSE, classic, test);
}
#endif /* Audio driver selection */ #endif /* Audio driver selection */
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */

View File

@ -33,7 +33,6 @@
#define OPEN_FLAGS_INPUT (O_RDONLY|O_NONBLOCK) #define OPEN_FLAGS_INPUT (O_RDONLY|O_NONBLOCK)
#endif #endif
void SDL_EnumUnixAudioDevices(int iscapture, int classic, extern void SDL_EnumUnixAudioDevices(const int classic, int (*test)(int));
int (*test) (int fd), SDL_AddAudioDevice addfn);
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */

View File

@ -30,8 +30,21 @@
typedef struct SDL_AudioDevice SDL_AudioDevice; typedef struct SDL_AudioDevice SDL_AudioDevice;
#define _THIS SDL_AudioDevice *_this #define _THIS SDL_AudioDevice *_this
/* Used by audio targets during DetectDevices() */ /* Audio targets should call this as devices are added to the system (such as
typedef void (*SDL_AddAudioDevice)(const char *name); a USB headset being plugged in), and should also be called for
for every device found during DetectDevices(). */
extern void SDL_AddAudioDevice(const int iscapture, const char *name, void *handle);
/* Audio targets should call this as devices are removed, so SDL can update
its list of available devices. */
extern void SDL_RemoveAudioDevice(const int iscapture, void *handle);
/* Audio targets should call this if an opened audio device is lost while
being used. This can happen due to i/o errors, or a device being unplugged,
etc. If the device is totally gone, please also call SDL_RemoveAudioDevice()
as appropriate so SDL's list of devices is accurate. */
extern void SDL_OpenedAudioDeviceDisconnected(SDL_AudioDevice *device);
/* This is the size of a packet when using SDL_QueueAudio(). We allocate /* This is the size of a packet when using SDL_QueueAudio(). We allocate
these as necessary and pool them, under the assumption that we'll these as necessary and pool them, under the assumption that we'll
@ -55,8 +68,8 @@ typedef struct SDL_AudioBufferQueue
typedef struct SDL_AudioDriverImpl typedef struct SDL_AudioDriverImpl
{ {
void (*DetectDevices) (int iscapture, SDL_AddAudioDevice addfn); void (*DetectDevices) (void);
int (*OpenDevice) (_THIS, const char *devname, int iscapture); int (*OpenDevice) (_THIS, void *handle, const char *devname, int iscapture);
void (*ThreadInit) (_THIS); /* Called by audio thread at start */ void (*ThreadInit) (_THIS); /* Called by audio thread at start */
void (*WaitDevice) (_THIS); void (*WaitDevice) (_THIS);
void (*PlayDevice) (_THIS); void (*PlayDevice) (_THIS);
@ -66,19 +79,34 @@ typedef struct SDL_AudioDriverImpl
void (*CloseDevice) (_THIS); void (*CloseDevice) (_THIS);
void (*LockDevice) (_THIS); void (*LockDevice) (_THIS);
void (*UnlockDevice) (_THIS); void (*UnlockDevice) (_THIS);
void (*FreeDeviceHandle) (void *handle); /**< SDL is done with handle from SDL_AddAudioDevice() */
void (*Deinitialize) (void); void (*Deinitialize) (void);
/* !!! FIXME: add pause(), so we can optimize instead of mixing silence. */ /* !!! FIXME: add pause(), so we can optimize instead of mixing silence. */
/* Some flags to push duplicate code into the core and reduce #ifdefs. */ /* Some flags to push duplicate code into the core and reduce #ifdefs. */
/* !!! FIXME: these should be SDL_bool */
int ProvidesOwnCallbackThread; int ProvidesOwnCallbackThread;
int SkipMixerLock; /* !!! FIXME: do we need this anymore? */ int SkipMixerLock; /* !!! FIXME: do we need this anymore? */
int HasCaptureSupport; int HasCaptureSupport;
int OnlyHasDefaultOutputDevice; int OnlyHasDefaultOutputDevice;
int OnlyHasDefaultInputDevice; int OnlyHasDefaultInputDevice;
int AllowsArbitraryDeviceNames;
} SDL_AudioDriverImpl; } SDL_AudioDriverImpl;
typedef struct SDL_AudioDeviceItem
{
void *handle;
struct SDL_AudioDeviceItem *next;
#if (defined(__GNUC__) && (__GNUC__ <= 2))
char name[1]; /* actually variable length. */
#else
char name[];
#endif
} SDL_AudioDeviceItem;
typedef struct SDL_AudioDriver typedef struct SDL_AudioDriver
{ {
/* * * */ /* * * */
@ -91,11 +119,14 @@ typedef struct SDL_AudioDriver
SDL_AudioDriverImpl impl; SDL_AudioDriverImpl impl;
char **outputDevices; /* A mutex for device detection */
SDL_mutex *detectionLock;
SDL_bool captureDevicesRemoved;
SDL_bool outputDevicesRemoved;
int outputDeviceCount; int outputDeviceCount;
char **inputDevices;
int inputDeviceCount; int inputDeviceCount;
SDL_AudioDeviceItem *outputDevices;
SDL_AudioDeviceItem *inputDevices;
} SDL_AudioDriver; } SDL_AudioDriver;
@ -113,6 +144,7 @@ struct SDL_AudioDevice
{ {
/* * * */ /* * * */
/* Data common to all devices */ /* Data common to all devices */
SDL_AudioDeviceID id;
/* The current audio specification (shared with audio thread) */ /* The current audio specification (shared with audio thread) */
SDL_AudioSpec spec; SDL_AudioSpec spec;
@ -125,15 +157,17 @@ struct SDL_AudioDevice
SDL_AudioStreamer streamer; SDL_AudioStreamer streamer;
/* Current state flags */ /* Current state flags */
/* !!! FIXME: should be SDL_bool */
int iscapture; int iscapture;
int enabled; int enabled; /* true if device is functioning and connected. */
int shutdown; /* true if we are signaling the play thread to end. */
int paused; int paused;
int opened; int opened;
/* Fake audio buffer for when the audio hardware is busy */ /* Fake audio buffer for when the audio hardware is busy */
Uint8 *fake_stream; Uint8 *fake_stream;
/* A semaphore for locking the mixing buffers */ /* A mutex for locking the mixing buffers */
SDL_mutex *mixer_lock; SDL_mutex *mixer_lock;
/* A thread to feed the audio device */ /* A thread to feed the audio device */

View File

@ -320,7 +320,7 @@ ALSA_PlayDevice(_THIS)
/* Hmm, not much we can do - abort */ /* Hmm, not much we can do - abort */
fprintf(stderr, "ALSA write failed (unrecoverable): %s\n", fprintf(stderr, "ALSA write failed (unrecoverable): %s\n",
ALSA_snd_strerror(status)); ALSA_snd_strerror(status));
this->enabled = 0; SDL_OpenedAudioDeviceDisconnected(this);
return; return;
} }
continue; continue;
@ -465,7 +465,7 @@ ALSA_set_buffer_size(_THIS, snd_pcm_hw_params_t *params, int override)
} }
static int static int
ALSA_OpenDevice(_THIS, const char *devname, int iscapture) ALSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{ {
int status = 0; int status = 0;
snd_pcm_t *pcm_handle = NULL; snd_pcm_t *pcm_handle = NULL;

View File

@ -35,7 +35,7 @@
static SDL_AudioDevice* audioDevice = NULL; static SDL_AudioDevice* audioDevice = NULL;
static int static int
AndroidAUD_OpenDevice(_THIS, const char *devname, int iscapture) AndroidAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{ {
SDL_AudioFormat test_format; SDL_AudioFormat test_format;

View File

@ -151,7 +151,7 @@ ARTS_WaitDevice(_THIS)
/* Check every 10 loops */ /* Check every 10 loops */
if (this->hidden->parent && (((++cnt) % 10) == 0)) { if (this->hidden->parent && (((++cnt) % 10) == 0)) {
if (kill(this->hidden->parent, 0) < 0 && errno == ESRCH) { if (kill(this->hidden->parent, 0) < 0 && errno == ESRCH) {
this->enabled = 0; SDL_OpenedAudioDeviceDisconnected(this);
} }
} }
} }
@ -179,7 +179,7 @@ ARTS_PlayDevice(_THIS)
/* If we couldn't write, assume fatal error for now */ /* If we couldn't write, assume fatal error for now */
if (written < 0) { if (written < 0) {
this->enabled = 0; SDL_OpenedAudioDeviceDisconnected(this);
} }
#ifdef DEBUG_AUDIO #ifdef DEBUG_AUDIO
fprintf(stderr, "Wrote %d bytes of audio data\n", written); fprintf(stderr, "Wrote %d bytes of audio data\n", written);
@ -229,7 +229,7 @@ ARTS_Suspend(void)
} }
static int static int
ARTS_OpenDevice(_THIS, const char *devname, int iscapture) ARTS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{ {
int rc = 0; int rc = 0;
int bits = 0, frag_spec = 0; int bits = 0, frag_spec = 0;

View File

@ -51,9 +51,9 @@
static void static void
BSDAUDIO_DetectDevices(int iscapture, SDL_AddAudioDevice addfn) BSDAUDIO_DetectDevices(void)
{ {
SDL_EnumUnixAudioDevices(iscapture, 0, NULL, addfn); SDL_EnumUnixAudioDevices(0, NULL);
} }
@ -150,7 +150,7 @@ BSDAUDIO_WaitDevice(_THIS)
the user know what happened. the user know what happened.
*/ */
fprintf(stderr, "SDL: %s\n", message); fprintf(stderr, "SDL: %s\n", message);
this->enabled = 0; SDL_OpenedAudioDeviceDisconnected(this);
/* Don't try to close - may hang */ /* Don't try to close - may hang */
this->hidden->audio_fd = -1; this->hidden->audio_fd = -1;
#ifdef DEBUG_AUDIO #ifdef DEBUG_AUDIO
@ -195,7 +195,7 @@ BSDAUDIO_PlayDevice(_THIS)
/* If we couldn't write, assume fatal error for now */ /* If we couldn't write, assume fatal error for now */
if (written < 0) { if (written < 0) {
this->enabled = 0; SDL_OpenedAudioDeviceDisconnected(this);
} }
#ifdef DEBUG_AUDIO #ifdef DEBUG_AUDIO
fprintf(stderr, "Wrote %d bytes of audio data\n", written); fprintf(stderr, "Wrote %d bytes of audio data\n", written);
@ -224,7 +224,7 @@ BSDAUDIO_CloseDevice(_THIS)
} }
static int static int
BSDAUDIO_OpenDevice(_THIS, const char *devname, int iscapture) 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; SDL_AudioFormat format = 0;
@ -348,6 +348,8 @@ BSDAUDIO_Init(SDL_AudioDriverImpl * impl)
impl->GetDeviceBuf = BSDAUDIO_GetDeviceBuf; impl->GetDeviceBuf = BSDAUDIO_GetDeviceBuf;
impl->CloseDevice = BSDAUDIO_CloseDevice; impl->CloseDevice = BSDAUDIO_CloseDevice;
impl->AllowsArbitraryDeviceNames = 1;
return 1; /* this audio target is available. */ return 1; /* this audio target is available. */
} }

View File

@ -19,6 +19,9 @@
3. This notice may not be removed or altered from any source distribution. 3. This notice may not be removed or altered from any source distribution.
*/ */
#include "../../SDL_internal.h" #include "../../SDL_internal.h"
#if SDL_AUDIO_DRIVER_COREAUDIO
#include "SDL_audio.h" #include "SDL_audio.h"
#include "../SDL_audio_c.h" #include "../SDL_audio_c.h"
#include "../SDL_sysaudio.h" #include "../SDL_sysaudio.h"
@ -37,31 +40,48 @@ static void COREAUDIO_CloseDevice(_THIS);
} }
#if MACOSX_COREAUDIO #if MACOSX_COREAUDIO
typedef void (*addDevFn)(const char *name, AudioDeviceID devId, void *data); static const AudioObjectPropertyAddress devlist_address = {
kAudioHardwarePropertyDevices,
kAudioObjectPropertyScopeGlobal,
kAudioObjectPropertyElementMaster
};
static void typedef void (*addDevFn)(const char *name, const int iscapture, AudioDeviceID devId, void *data);
addToDevList(const char *name, AudioDeviceID devId, void *data)
typedef struct AudioDeviceList
{ {
SDL_AddAudioDevice addfn = (SDL_AddAudioDevice) data; AudioDeviceID devid;
addfn(name); 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;
} }
typedef struct
{
const char *findname;
AudioDeviceID devId;
int found;
} FindDevIdData;
static void static void
findDevId(const char *name, AudioDeviceID devId, void *_data) addToDevList(const char *name, const int iscapture, AudioDeviceID devId, void *data)
{ {
FindDevIdData *data = (FindDevIdData *) _data; if (add_to_internal_dev_list(iscapture, devId)) {
if (!data->found) { SDL_AddAudioDevice(iscapture, name, (void *) ((size_t) devId));
if (SDL_strcmp(name, data->findname) == 0) {
data->found = 1;
data->devId = devId;
}
} }
} }
@ -74,14 +94,8 @@ build_device_list(int iscapture, addDevFn addfn, void *addfndata)
UInt32 i = 0; UInt32 i = 0;
UInt32 max = 0; UInt32 max = 0;
AudioObjectPropertyAddress addr = { result = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject,
kAudioHardwarePropertyDevices, &devlist_address, 0, NULL, &size);
kAudioObjectPropertyScopeGlobal,
kAudioObjectPropertyElementMaster
};
result = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &addr,
0, NULL, &size);
if (result != kAudioHardwareNoError) if (result != kAudioHardwareNoError)
return; return;
@ -89,8 +103,8 @@ build_device_list(int iscapture, addDevFn addfn, void *addfndata)
if (devs == NULL) if (devs == NULL)
return; return;
result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr, result = AudioObjectGetPropertyData(kAudioObjectSystemObject,
0, NULL, &size, devs); &devlist_address, 0, NULL, &size, devs);
if (result != kAudioHardwareNoError) if (result != kAudioHardwareNoError)
return; return;
@ -102,10 +116,17 @@ build_device_list(int iscapture, addDevFn addfn, void *addfndata)
AudioBufferList *buflist = NULL; AudioBufferList *buflist = NULL;
int usable = 0; int usable = 0;
CFIndex len = 0; CFIndex len = 0;
const AudioObjectPropertyAddress addr = {
kAudioDevicePropertyStreamConfiguration,
iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput,
kAudioObjectPropertyElementMaster
};
addr.mScope = iscapture ? kAudioDevicePropertyScopeInput : const AudioObjectPropertyAddress nameaddr = {
kAudioDevicePropertyScopeOutput; kAudioObjectPropertyName,
addr.mSelector = kAudioDevicePropertyStreamConfiguration; iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput,
kAudioObjectPropertyElementMaster
};
result = AudioObjectGetPropertyDataSize(dev, &addr, 0, NULL, &size); result = AudioObjectGetPropertyDataSize(dev, &addr, 0, NULL, &size);
if (result != noErr) if (result != noErr)
@ -133,9 +154,9 @@ build_device_list(int iscapture, addDevFn addfn, void *addfndata)
if (!usable) if (!usable)
continue; continue;
addr.mSelector = kAudioObjectPropertyName;
size = sizeof (CFStringRef); size = sizeof (CFStringRef);
result = AudioObjectGetPropertyData(dev, &addr, 0, NULL, &size, &cfstr); result = AudioObjectGetPropertyData(dev, &nameaddr, 0, NULL, &size, &cfstr);
if (result != kAudioHardwareNoError) if (result != kAudioHardwareNoError)
continue; continue;
@ -166,79 +187,84 @@ build_device_list(int iscapture, addDevFn addfn, void *addfndata)
((iscapture) ? "capture" : "output"), ((iscapture) ? "capture" : "output"),
(int) *devCount, ptr, (int) dev); (int) *devCount, ptr, (int) dev);
#endif #endif
addfn(ptr, dev, addfndata); addfn(ptr, iscapture, dev, addfndata);
} }
SDL_free(ptr); /* addfn() would have copied the string. */ SDL_free(ptr); /* addfn() would have copied the string. */
} }
} }
static void static void
COREAUDIO_DetectDevices(int iscapture, SDL_AddAudioDevice addfn) free_audio_device_list(AudioDeviceList **list)
{ {
build_device_list(iscapture, addToDevList, addfn); AudioDeviceList *item = *list;
while (item) {
AudioDeviceList *next = item->next;
SDL_free(item);
item = next;
}
*list = NULL;
} }
static int static void
find_device_by_name(_THIS, const char *devname, int iscapture) COREAUDIO_DetectDevices(void)
{ {
AudioDeviceID devid = 0; build_device_list(SDL_TRUE, addToDevList, NULL);
OSStatus result = noErr; build_device_list(SDL_FALSE, addToDevList, NULL);
UInt32 size = 0; }
UInt32 alive = 0;
pid_t pid = 0;
AudioObjectPropertyAddress addr = { static void
0, build_device_change_list(const char *name, const int iscapture, AudioDeviceID devId, void *data)
kAudioObjectPropertyScopeGlobal, {
kAudioObjectPropertyElementMaster AudioDeviceList **list = (AudioDeviceList **) data;
}; AudioDeviceList *item;
for (item = *list; item != NULL; item = item->next) {
if (devname == NULL) { if (item->devid == devId) {
size = sizeof (AudioDeviceID); item->alive = SDL_TRUE;
addr.mSelector = return;
((iscapture) ? kAudioHardwarePropertyDefaultInputDevice :
kAudioHardwarePropertyDefaultOutputDevice);
result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr,
0, NULL, &size, &devid);
CHECK_RESULT("AudioHardwareGetProperty (default device)");
} else {
FindDevIdData data;
SDL_zero(data);
data.findname = devname;
build_device_list(iscapture, findDevId, &data);
if (!data.found) {
SDL_SetError("CoreAudio: No such audio device.");
return 0;
} }
devid = data.devId;
} }
addr.mSelector = kAudioDevicePropertyDeviceIsAlive; add_to_internal_dev_list(iscapture, devId); /* new device, add it. */
addr.mScope = iscapture ? kAudioDevicePropertyScopeInput : SDL_AddAudioDevice(iscapture, name, (void *) ((size_t) devId));
kAudioDevicePropertyScopeOutput; }
size = sizeof (alive); static void
result = AudioObjectGetPropertyData(devid, &addr, 0, NULL, &size, &alive); reprocess_device_list(const int iscapture, AudioDeviceList **list)
CHECK_RESULT {
("AudioDeviceGetProperty (kAudioDevicePropertyDeviceIsAlive)"); AudioDeviceList *item;
AudioDeviceList *prev = NULL;
if (!alive) { for (item = *list; item != NULL; item = item->next) {
SDL_SetError("CoreAudio: requested device exists, but isn't alive."); item->alive = SDL_FALSE;
return 0;
} }
addr.mSelector = kAudioDevicePropertyHogMode; build_device_list(iscapture, build_device_change_list, list);
size = sizeof (pid);
result = AudioObjectGetPropertyData(devid, &addr, 0, NULL, &size, &pid);
/* some devices don't support this property, so errors are fine here. */ /* free items in the list that aren't still alive. */
if ((result == noErr) && (pid != -1)) { item = *list;
SDL_SetError("CoreAudio: requested device is being hogged."); while (item != NULL) {
return 0; 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->hidden->deviceID = devid; /* this is called when the system's list of available audio devices changes. */
return 1; 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 #endif
@ -314,11 +340,54 @@ inputCallback(void *inRefCon,
} }
#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 (!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 static void
COREAUDIO_CloseDevice(_THIS) COREAUDIO_CloseDevice(_THIS)
{ {
if (this->hidden != NULL) { if (this->hidden != NULL) {
if (this->hidden->audioUnitOpened) { if (this->hidden->audioUnitOpened) {
#if MACOSX_COREAUDIO
/* Unregister our disconnect callback. */
AudioObjectRemovePropertyListener(this->hidden->deviceID, &alive_address, device_unplugged, this);
#endif
AURenderCallbackStruct callback; AURenderCallbackStruct callback;
const AudioUnitElement output_bus = 0; const AudioUnitElement output_bus = 0;
const AudioUnitElement input_bus = 1; const AudioUnitElement input_bus = 1;
@ -352,9 +421,63 @@ COREAUDIO_CloseDevice(_THIS)
} }
} }
#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 static int
prepare_audiounit(_THIS, const char *devname, int iscapture, prepare_audiounit(_THIS, void *handle, int iscapture,
const AudioStreamBasicDescription * strdesc) const AudioStreamBasicDescription * strdesc)
{ {
OSStatus result = noErr; OSStatus result = noErr;
@ -373,8 +496,7 @@ prepare_audiounit(_THIS, const char *devname, int iscapture,
kAudioUnitScope_Input); kAudioUnitScope_Input);
#if MACOSX_COREAUDIO #if MACOSX_COREAUDIO
if (!find_device_by_name(this, devname, iscapture)) { if (!prepare_device(this, handle, iscapture)) {
SDL_SetError("Couldn't find requested CoreAudio device");
return 0; return 0;
} }
#endif #endif
@ -451,13 +573,18 @@ prepare_audiounit(_THIS, const char *devname, int iscapture,
result = AudioOutputUnitStart(this->hidden->audioUnit); result = AudioOutputUnitStart(this->hidden->audioUnit);
CHECK_RESULT("AudioOutputUnitStart"); CHECK_RESULT("AudioOutputUnitStart");
#if MACOSX_COREAUDIO
/* Fire a callback if the device stops being "alive" (disconnected, etc). */
AudioObjectAddPropertyListener(this->hidden->deviceID, &alive_address, device_unplugged, this);
#endif
/* We're running! */ /* We're running! */
return 1; return 1;
} }
static int static int
COREAUDIO_OpenDevice(_THIS, const char *devname, int iscapture) COREAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{ {
AudioStreamBasicDescription strdesc; AudioStreamBasicDescription strdesc;
SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format); SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
@ -516,7 +643,7 @@ COREAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
strdesc.mBytesPerPacket = strdesc.mBytesPerPacket =
strdesc.mBytesPerFrame * strdesc.mFramesPerPacket; strdesc.mBytesPerFrame * strdesc.mFramesPerPacket;
if (!prepare_audiounit(this, devname, iscapture, &strdesc)) { if (!prepare_audiounit(this, handle, iscapture, &strdesc)) {
COREAUDIO_CloseDevice(this); COREAUDIO_CloseDevice(this);
return -1; /* prepare_audiounit() will call SDL_SetError()... */ return -1; /* prepare_audiounit() will call SDL_SetError()... */
} }
@ -524,15 +651,27 @@ COREAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
return 0; /* good to go. */ return 0; /* good to go. */
} }
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 static int
COREAUDIO_Init(SDL_AudioDriverImpl * impl) COREAUDIO_Init(SDL_AudioDriverImpl * impl)
{ {
/* Set the function pointers */ /* Set the function pointers */
impl->OpenDevice = COREAUDIO_OpenDevice; impl->OpenDevice = COREAUDIO_OpenDevice;
impl->CloseDevice = COREAUDIO_CloseDevice; impl->CloseDevice = COREAUDIO_CloseDevice;
impl->Deinitialize = COREAUDIO_Deinitialize;
#if MACOSX_COREAUDIO #if MACOSX_COREAUDIO
impl->DetectDevices = COREAUDIO_DetectDevices; impl->DetectDevices = COREAUDIO_DetectDevices;
AudioObjectAddPropertyListener(kAudioObjectSystemObject, &devlist_address, device_list_changed, NULL);
#else #else
impl->OnlyHasDefaultOutputDevice = 1; impl->OnlyHasDefaultOutputDevice = 1;
@ -554,4 +693,6 @@ AudioBootStrap COREAUDIO_bootstrap = {
"coreaudio", "CoreAudio", COREAUDIO_Init, 0 "coreaudio", "CoreAudio", COREAUDIO_Init, 0
}; };
#endif /* SDL_AUDIO_DRIVER_COREAUDIO */
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */

View File

@ -144,15 +144,22 @@ SetDSerror(const char *function, int code)
return SDL_SetError("%s", errbuf); return SDL_SetError("%s", errbuf);
} }
static void
DSOUND_FreeDeviceHandle(void *handle)
{
SDL_free(handle);
}
static BOOL CALLBACK static BOOL CALLBACK
FindAllDevs(LPGUID guid, LPCWSTR desc, LPCWSTR module, LPVOID data) FindAllDevs(LPGUID guid, LPCWSTR desc, LPCWSTR module, LPVOID data)
{ {
SDL_AddAudioDevice addfn = (SDL_AddAudioDevice) data; const int iscapture = (int) ((size_t) data);
if (guid != NULL) { /* skip default device */ if (guid != NULL) { /* skip default device */
char *str = WIN_StringToUTF8(desc); char *str = WIN_StringToUTF8(desc);
if (str != NULL) { if (str != NULL) {
addfn(str); LPGUID cpyguid = (LPGUID) SDL_malloc(sizeof (GUID));
SDL_memcpy(cpyguid, guid, sizeof (GUID));
SDL_AddAudioDevice(iscapture, str, cpyguid);
SDL_free(str); /* addfn() makes a copy of this string. */ SDL_free(str); /* addfn() makes a copy of this string. */
} }
} }
@ -160,13 +167,10 @@ FindAllDevs(LPGUID guid, LPCWSTR desc, LPCWSTR module, LPVOID data)
} }
static void static void
DSOUND_DetectDevices(int iscapture, SDL_AddAudioDevice addfn) DSOUND_DetectDevices(void)
{ {
if (iscapture) { pDirectSoundCaptureEnumerateW(FindAllDevs, (void *) ((size_t) 1));
pDirectSoundCaptureEnumerateW(FindAllDevs, addfn); pDirectSoundEnumerateW(FindAllDevs, (void *) ((size_t) 0));
} else {
pDirectSoundEnumerateW(FindAllDevs, addfn);
}
} }
@ -419,53 +423,14 @@ CreateSecondary(_THIS, HWND focus)
return (numchunks); return (numchunks);
} }
typedef struct FindDevGUIDData
{
const char *devname;
GUID guid;
int found;
} FindDevGUIDData;
static BOOL CALLBACK
FindDevGUID(LPGUID guid, LPCWSTR desc, LPCWSTR module, LPVOID _data)
{
if (guid != NULL) { /* skip the default device. */
FindDevGUIDData *data = (FindDevGUIDData *) _data;
char *str = WIN_StringToUTF8(desc);
const int match = (SDL_strcmp(str, data->devname) == 0);
SDL_free(str);
if (match) {
data->found = 1;
SDL_memcpy(&data->guid, guid, sizeof (data->guid));
return FALSE; /* found it! stop enumerating. */
}
}
return TRUE; /* keep enumerating. */
}
static int static int
DSOUND_OpenDevice(_THIS, const char *devname, int iscapture) DSOUND_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{ {
HRESULT result; HRESULT result;
SDL_bool valid_format = SDL_FALSE; SDL_bool valid_format = SDL_FALSE;
SDL_bool tried_format = SDL_FALSE; SDL_bool tried_format = SDL_FALSE;
SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format); SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
FindDevGUIDData devguid; LPGUID guid = (LPGUID) handle;
LPGUID guid = NULL;
if (devname != NULL) {
devguid.found = 0;
devguid.devname = devname;
if (iscapture)
pDirectSoundCaptureEnumerateW(FindDevGUID, &devguid);
else
pDirectSoundEnumerateW(FindDevGUID, &devguid);
if (!devguid.found) {
return SDL_SetError("DirectSound: Requested device not found");
}
guid = &devguid.guid;
}
/* Initialize all variables that we clean on shutdown */ /* Initialize all variables that we clean on shutdown */
this->hidden = (struct SDL_PrivateAudioData *) this->hidden = (struct SDL_PrivateAudioData *)
@ -536,6 +501,8 @@ DSOUND_Init(SDL_AudioDriverImpl * impl)
impl->WaitDone = DSOUND_WaitDone; impl->WaitDone = DSOUND_WaitDone;
impl->GetDeviceBuf = DSOUND_GetDeviceBuf; impl->GetDeviceBuf = DSOUND_GetDeviceBuf;
impl->CloseDevice = DSOUND_CloseDevice; impl->CloseDevice = DSOUND_CloseDevice;
impl->FreeDeviceHandle = DSOUND_FreeDeviceHandle;
impl->Deinitialize = DSOUND_Deinitialize; impl->Deinitialize = DSOUND_Deinitialize;
return 1; /* this audio target is available. */ return 1; /* this audio target is available. */

View File

@ -71,7 +71,7 @@ DISKAUD_PlayDevice(_THIS)
/* If we couldn't write, assume fatal error for now */ /* If we couldn't write, assume fatal error for now */
if (written != this->hidden->mixlen) { if (written != this->hidden->mixlen) {
this->enabled = 0; SDL_OpenedAudioDeviceDisconnected(this);
} }
#ifdef DEBUG_AUDIO #ifdef DEBUG_AUDIO
fprintf(stderr, "Wrote %d bytes of audio data\n", written); fprintf(stderr, "Wrote %d bytes of audio data\n", written);
@ -100,7 +100,7 @@ DISKAUD_CloseDevice(_THIS)
} }
static int static int
DISKAUD_OpenDevice(_THIS, const char *devname, int iscapture) DISKAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{ {
const char *envr = SDL_getenv(DISKENVR_WRITEDELAY); const char *envr = SDL_getenv(DISKENVR_WRITEDELAY);
const char *fname = DISKAUD_GetOutputFilename(devname); const char *fname = DISKAUD_GetOutputFilename(devname);
@ -151,6 +151,8 @@ DISKAUD_Init(SDL_AudioDriverImpl * impl)
impl->GetDeviceBuf = DISKAUD_GetDeviceBuf; impl->GetDeviceBuf = DISKAUD_GetDeviceBuf;
impl->CloseDevice = DISKAUD_CloseDevice; impl->CloseDevice = DISKAUD_CloseDevice;
impl->AllowsArbitraryDeviceNames = 1;
return 1; /* this audio target is available. */ return 1; /* this audio target is available. */
} }

View File

@ -51,9 +51,9 @@
static void static void
DSP_DetectDevices(int iscapture, SDL_AddAudioDevice addfn) DSP_DetectDevices(void)
{ {
SDL_EnumUnixAudioDevices(iscapture, 0, NULL, addfn); SDL_EnumUnixAudioDevices(0, NULL);
} }
@ -74,7 +74,7 @@ DSP_CloseDevice(_THIS)
static int static int
DSP_OpenDevice(_THIS, const char *devname, int iscapture) DSP_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);
int format; int format;
@ -270,7 +270,7 @@ DSP_PlayDevice(_THIS)
const int mixlen = this->hidden->mixlen; const int mixlen = this->hidden->mixlen;
if (write(this->hidden->audio_fd, mixbuf, mixlen) == -1) { if (write(this->hidden->audio_fd, mixbuf, mixlen) == -1) {
perror("Audio write"); perror("Audio write");
this->enabled = 0; SDL_OpenedAudioDeviceDisconnected(this);
} }
#ifdef DEBUG_AUDIO #ifdef DEBUG_AUDIO
fprintf(stderr, "Wrote %d bytes of audio data\n", mixlen); fprintf(stderr, "Wrote %d bytes of audio data\n", mixlen);
@ -293,6 +293,8 @@ DSP_Init(SDL_AudioDriverImpl * impl)
impl->GetDeviceBuf = DSP_GetDeviceBuf; impl->GetDeviceBuf = DSP_GetDeviceBuf;
impl->CloseDevice = DSP_CloseDevice; impl->CloseDevice = DSP_CloseDevice;
impl->AllowsArbitraryDeviceNames = 1;
return 1; /* this audio target is available. */ return 1; /* this audio target is available. */
} }

View File

@ -27,7 +27,7 @@
#include "SDL_dummyaudio.h" #include "SDL_dummyaudio.h"
static int static int
DUMMYAUD_OpenDevice(_THIS, const char *devname, int iscapture) DUMMYAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{ {
return 0; /* always succeeds. */ return 0; /* always succeeds. */
} }

View File

@ -0,0 +1,275 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2014 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_EMSCRIPTEN
#include "SDL_audio.h"
#include "SDL_log.h"
#include "../SDL_audio_c.h"
#include "SDL_emscriptenaudio.h"
#include <emscripten/emscripten.h>
static int
copyData(_THIS)
{
int byte_len;
if (this->hidden->write_off + this->convert.len_cvt > this->hidden->mixlen) {
if (this->hidden->write_off > this->hidden->read_off) {
SDL_memmove(this->hidden->mixbuf,
this->hidden->mixbuf + this->hidden->read_off,
this->hidden->mixlen - this->hidden->read_off);
this->hidden->write_off = this->hidden->write_off - this->hidden->read_off;
} else {
this->hidden->write_off = 0;
}
this->hidden->read_off = 0;
}
SDL_memcpy(this->hidden->mixbuf + this->hidden->write_off,
this->convert.buf,
this->convert.len_cvt);
this->hidden->write_off += this->convert.len_cvt;
byte_len = this->hidden->write_off - this->hidden->read_off;
return byte_len;
}
static void
HandleAudioProcess(_THIS)
{
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)
return;
if (this->paused)
return;
if (this->convert.needed) {
if (this->hidden->conv_in_len != 0) {
this->convert.len = this->hidden->conv_in_len * bytes_in * this->spec.channels;
}
(*this->spec.callback) (this->spec.userdata,
this->convert.buf,
this->convert.len);
SDL_ConvertAudio(&this->convert);
buf = this->convert.buf;
byte_len = this->convert.len_cvt;
/* size mismatch*/
if (byte_len != this->spec.size) {
if (!this->hidden->mixbuf) {
this->hidden->mixlen = this->spec.size > byte_len ? this->spec.size * 2 : byte_len * 2;
this->hidden->mixbuf = SDL_malloc(this->hidden->mixlen);
}
/* copy existing data */
byte_len = copyData(this);
/* read more data*/
while (byte_len < this->spec.size) {
(*this->spec.callback) (this->spec.userdata,
this->convert.buf,
this->convert.len);
SDL_ConvertAudio(&this->convert);
byte_len = copyData(this);
}
byte_len = this->spec.size;
buf = this->hidden->mixbuf + this->hidden->read_off;
this->hidden->read_off += byte_len;
}
} else {
if (!this->hidden->mixbuf) {
this->hidden->mixlen = this->spec.size;
this->hidden->mixbuf = SDL_malloc(this->hidden->mixlen);
}
(*this->spec.callback) (this->spec.userdata,
this->hidden->mixbuf,
this->hidden->mixlen);
buf = this->hidden->mixbuf;
byte_len = this->hidden->mixlen;
}
if (buf) {
EM_ASM_ARGS({
var numChannels = SDL2.audio.currentOutputBuffer['numberOfChannels'];
for (var c = 0; c < numChannels; ++c) {
var channelData = SDL2.audio.currentOutputBuffer['getChannelData'](c);
if (channelData.length != $1) {
throw 'Web Audio output buffer length mismatch! Destination size: ' + channelData.length + ' samples vs expected ' + $1 + ' samples!';
}
for (var j = 0; j < $1; ++j) {
channelData[j] = getValue($0 + (j*numChannels + c)*4, 'float');
}
}
}, buf, byte_len / bytes / this->spec.channels);
}
}
static void
Emscripten_CloseDevice(_THIS)
{
if (this->hidden != NULL) {
if (this->hidden->mixbuf != NULL) {
/* Clean up the audio buffer */
SDL_free(this->hidden->mixbuf);
this->hidden->mixbuf = NULL;
}
SDL_free(this->hidden);
this->hidden = NULL;
}
}
static int
Emscripten_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{
SDL_bool valid_format = SDL_FALSE;
SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
int i;
float f;
int result;
while ((!valid_format) && (test_format)) {
switch (test_format) {
case AUDIO_F32: /* web audio only supports floats */
this->spec.format = test_format;
valid_format = SDL_TRUE;
break;
}
test_format = SDL_NextAudioFormat();
}
if (!valid_format) {
/* Didn't find a compatible format :( */
return SDL_SetError("No compatible audio format!");
}
/* 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));
/* 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!");
}
/* limit to native freq */
int sampleRate = EM_ASM_INT_V({
return SDL2.audioContext['sampleRate'];
});
if(this->spec.freq != sampleRate) {
for (i = this->spec.samples; i > 0; i--) {
f = (float)i / (float)sampleRate * (float)this->spec.freq;
if (SDL_floor(f) == f) {
this->hidden->conv_in_len = SDL_floor(f);
break;
}
}
this->spec.freq = sampleRate;
}
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);
return 0;
}
static int
Emscripten_Init(SDL_AudioDriverImpl * impl)
{
/* Set the function pointers */
impl->OpenDevice = Emscripten_OpenDevice;
impl->CloseDevice = Emscripten_CloseDevice;
/* only one output */
impl->OnlyHasDefaultOutputDevice = 1;
/* no threads here */
impl->SkipMixerLock = 1;
impl->ProvidesOwnCallbackThread = 1;
/* check availability */
int available = EM_ASM_INT_V({
if (typeof(AudioContext) !== 'undefined') {
return 1;
} else if (typeof(webkitAudioContext) !== 'undefined') {
return 1;
}
return 0;
});
return available;
}
AudioBootStrap EmscriptenAudio_bootstrap = {
"emscripten", "SDL emscripten audio driver", Emscripten_Init, 0
};
#endif /* SDL_AUDIO_DRIVER_EMSCRIPTEN */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -0,0 +1,42 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2014 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"
#ifndef _SDL_emscriptenaudio_h
#define _SDL_emscriptenaudio_h
#include "../SDL_sysaudio.h"
/* Hidden "this" pointer for the audio functions */
#define _THIS SDL_AudioDevice *this
struct SDL_PrivateAudioData
{
Uint8 *mixbuf;
Uint32 mixlen;
Uint32 conv_in_len;
Uint32 write_off, read_off;
};
#endif /* _SDL_emscriptenaudio_h */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -129,7 +129,7 @@ ESD_WaitDevice(_THIS)
/* Check every 10 loops */ /* Check every 10 loops */
if (this->hidden->parent && (((++cnt) % 10) == 0)) { if (this->hidden->parent && (((++cnt) % 10) == 0)) {
if (kill(this->hidden->parent, 0) < 0 && errno == ESRCH) { if (kill(this->hidden->parent, 0) < 0 && errno == ESRCH) {
this->enabled = 0; SDL_OpenedAudioDeviceDisconnected(this);
} }
} }
} }
@ -161,7 +161,7 @@ ESD_PlayDevice(_THIS)
/* If we couldn't write, assume fatal error for now */ /* If we couldn't write, assume fatal error for now */
if (written < 0) { if (written < 0) {
this->enabled = 0; SDL_OpenedAudioDeviceDisconnected(this);
} }
} }
@ -215,7 +215,7 @@ get_progname(void)
static int static int
ESD_OpenDevice(_THIS, const char *devname, int iscapture) ESD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{ {
esd_format_t format = (ESD_STREAM | ESD_PLAY); esd_format_t format = (ESD_STREAM | ESD_PLAY);
SDL_AudioFormat test_format = 0; SDL_AudioFormat test_format = 0;

View File

@ -143,7 +143,7 @@ SDL_FS_PlayDevice(_THIS)
this->hidden->mixsamples); this->hidden->mixsamples);
/* If we couldn't write, assume fatal error for now */ /* If we couldn't write, assume fatal error for now */
if (ret) { if (ret) {
this->enabled = 0; SDL_OpenedAudioDeviceDisconnected(this);
} }
#ifdef DEBUG_AUDIO #ifdef DEBUG_AUDIO
fprintf(stderr, "Wrote %d bytes of audio data\n", this->hidden->mixlen); fprintf(stderr, "Wrote %d bytes of audio data\n", this->hidden->mixlen);
@ -186,7 +186,7 @@ SDL_FS_CloseDevice(_THIS)
static int static int
SDL_FS_OpenDevice(_THIS, const char *devname, int iscapture) SDL_FS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{ {
int bytes; int bytes;
SDL_AudioFormat test_format = 0, format = 0; SDL_AudioFormat test_format = 0, format = 0;

View File

@ -111,7 +111,7 @@ UnmaskSignals(sigset_t * omask)
static int static int
HAIKUAUDIO_OpenDevice(_THIS, const char *devname, int iscapture) HAIKUAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{ {
int valid_datatype = 0; int valid_datatype = 0;
media_raw_audio_format format; media_raw_audio_format format;

View File

@ -20,6 +20,9 @@
*/ */
#include "../../SDL_internal.h" #include "../../SDL_internal.h"
#if SDL_AUDIO_DRIVER_NACL
#include "SDL_naclaudio.h" #include "SDL_naclaudio.h"
#include "SDL_audio.h" #include "SDL_audio.h"
@ -40,7 +43,7 @@
#define SAMPLE_FRAME_COUNT 4096 #define SAMPLE_FRAME_COUNT 4096
/* Audio driver functions */ /* Audio driver functions */
static int NACLAUD_OpenDevice(_THIS, const char *devname, int iscapture); static int NACLAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture);
static void NACLAUD_CloseDevice(_THIS); static void NACLAUD_CloseDevice(_THIS);
static void nacl_audio_callback(void* samples, uint32_t buffer_size, PP_TimeDelta latency, void* data); static void nacl_audio_callback(void* samples, uint32_t buffer_size, PP_TimeDelta latency, void* data);
@ -82,7 +85,7 @@ static void NACLAUD_CloseDevice(SDL_AudioDevice *device) {
} }
static int static int
NACLAUD_OpenDevice(_THIS, const char *devname, int iscapture) { NACLAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) {
PP_Instance instance = PSGetInstanceId(); PP_Instance instance = PSGetInstanceId();
const PPB_Audio *ppb_audio = PSInterfaceAudio(); const PPB_Audio *ppb_audio = PSInterfaceAudio();
const PPB_AudioConfig *ppb_audiocfg = PSInterfaceAudioConfig(); const PPB_AudioConfig *ppb_audiocfg = PSInterfaceAudioConfig();
@ -127,9 +130,7 @@ NACLAUD_Init(SDL_AudioDriverImpl * impl)
/* Set the function pointers */ /* Set the function pointers */
impl->OpenDevice = NACLAUD_OpenDevice; impl->OpenDevice = NACLAUD_OpenDevice;
impl->CloseDevice = NACLAUD_CloseDevice; impl->CloseDevice = NACLAUD_CloseDevice;
impl->HasCaptureSupport = 0;
impl->OnlyHasDefaultOutputDevice = 1; impl->OnlyHasDefaultOutputDevice = 1;
impl->OnlyHasDefaultInputDevice = 1;
impl->ProvidesOwnCallbackThread = 1; impl->ProvidesOwnCallbackThread = 1;
/* /*
* impl->WaitDevice = NACLAUD_WaitDevice; * impl->WaitDevice = NACLAUD_WaitDevice;
@ -145,3 +146,7 @@ AudioBootStrap NACLAUD_bootstrap = {
NACLAUD_DRIVER_NAME, "SDL NaCl Audio Driver", NACLAUD_DRIVER_NAME, "SDL NaCl Audio Driver",
NACLAUD_Init, 0 NACLAUD_Init, 0
}; };
#endif /* SDL_AUDIO_DRIVER_NACL */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -276,7 +276,7 @@ find_device(_THIS, int nch)
} }
static int static int
NAS_OpenDevice(_THIS, const char *devname, int iscapture) NAS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{ {
AuElement elms[3]; AuElement elms[3];
int buffer_size; int buffer_size;

View File

@ -176,7 +176,7 @@ PAUDIO_WaitDevice(_THIS)
* the user know what happened. * the user know what happened.
*/ */
fprintf(stderr, "SDL: %s - %s\n", strerror(errno), message); fprintf(stderr, "SDL: %s - %s\n", strerror(errno), message);
this->enabled = 0; SDL_OpenedAudioDeviceDisconnected(this);
/* Don't try to close - may hang */ /* Don't try to close - may hang */
this->hidden->audio_fd = -1; this->hidden->audio_fd = -1;
#ifdef DEBUG_AUDIO #ifdef DEBUG_AUDIO
@ -212,7 +212,7 @@ PAUDIO_PlayDevice(_THIS)
/* If we couldn't write, assume fatal error for now */ /* If we couldn't write, assume fatal error for now */
if (written < 0) { if (written < 0) {
this->enabled = 0; SDL_OpenedAudioDeviceDisconnected(this);
} }
#ifdef DEBUG_AUDIO #ifdef DEBUG_AUDIO
fprintf(stderr, "Wrote %d bytes of audio data\n", written); fprintf(stderr, "Wrote %d bytes of audio data\n", written);
@ -241,7 +241,7 @@ PAUDIO_CloseDevice(_THIS)
} }
static int static int
PAUDIO_OpenDevice(_THIS, const char *devname, int iscapture) PAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{ {
const char *workaround = SDL_getenv("SDL_DSP_NOSELECT"); const char *workaround = SDL_getenv("SDL_DSP_NOSELECT");
char audiodev[1024]; char audiodev[1024];

View File

@ -18,6 +18,9 @@
misrepresented as being the original software. misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution. 3. This notice may not be removed or altered from any source distribution.
*/ */
#include "../../SDL_internal.h"
#if SDL_AUDIO_DRIVER_PSP
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -40,7 +43,7 @@
#define PSPAUD_DRIVER_NAME "psp" #define PSPAUD_DRIVER_NAME "psp"
static int static int
PSPAUD_OpenDevice(_THIS, const char *devname, int iscapture) PSPAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{ {
int format, mixlen, i; int format, mixlen, i;
this->hidden = (struct SDL_PrivateAudioData *) this->hidden = (struct SDL_PrivateAudioData *)
@ -191,5 +194,6 @@ AudioBootStrap PSPAUD_bootstrap = {
/* SDL_AUDI */ /* SDL_AUDI */
#endif /* SDL_AUDIO_DRIVER_PSP */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -24,7 +24,7 @@
#include "../SDL_sysaudio.h" #include "../SDL_sysaudio.h"
/* Hidden "this" pointer for the video functions */ /* Hidden "this" pointer for the audio functions */
#define _THIS SDL_AudioDevice *this #define _THIS SDL_AudioDevice *this
#define NUM_BUFFERS 2 #define NUM_BUFFERS 2

View File

@ -26,6 +26,7 @@
Stéphan Kochen: stephan .a.t. kochen.nl Stéphan Kochen: stephan .a.t. kochen.nl
*/ */
#include "../../SDL_internal.h" #include "../../SDL_internal.h"
#include "SDL_assert.h"
#if SDL_AUDIO_DRIVER_PULSEAUDIO #if SDL_AUDIO_DRIVER_PULSEAUDIO
@ -38,7 +39,6 @@
#include <sys/types.h> #include <sys/types.h>
#include <errno.h> #include <errno.h>
#include <pulse/pulseaudio.h> #include <pulse/pulseaudio.h>
#include <pulse/simple.h>
#include "SDL_timer.h" #include "SDL_timer.h"
#include "SDL_audio.h" #include "SDL_audio.h"
@ -66,16 +66,14 @@ static SDL_INLINE int PA_STREAM_IS_GOOD(pa_stream_state_t x) {
static const char *(*PULSEAUDIO_pa_get_library_version) (void); static const char *(*PULSEAUDIO_pa_get_library_version) (void);
static pa_simple *(*PULSEAUDIO_pa_simple_new) (const char *, const char *,
pa_stream_direction_t, const char *, const char *, const pa_sample_spec *,
const pa_channel_map *, const pa_buffer_attr *, int *);
static void (*PULSEAUDIO_pa_simple_free) (pa_simple *);
static pa_channel_map *(*PULSEAUDIO_pa_channel_map_init_auto) ( static pa_channel_map *(*PULSEAUDIO_pa_channel_map_init_auto) (
pa_channel_map *, unsigned, pa_channel_map_def_t); pa_channel_map *, unsigned, pa_channel_map_def_t);
static const char * (*PULSEAUDIO_pa_strerror) (int); static const char * (*PULSEAUDIO_pa_strerror) (int);
static pa_mainloop * (*PULSEAUDIO_pa_mainloop_new) (void); static pa_mainloop * (*PULSEAUDIO_pa_mainloop_new) (void);
static pa_mainloop_api * (*PULSEAUDIO_pa_mainloop_get_api) (pa_mainloop *); static pa_mainloop_api * (*PULSEAUDIO_pa_mainloop_get_api) (pa_mainloop *);
static int (*PULSEAUDIO_pa_mainloop_iterate) (pa_mainloop *, int, int *); static int (*PULSEAUDIO_pa_mainloop_iterate) (pa_mainloop *, int, int *);
static int (*PULSEAUDIO_pa_mainloop_run) (pa_mainloop *, int *);
static void (*PULSEAUDIO_pa_mainloop_quit) (pa_mainloop *, int);
static void (*PULSEAUDIO_pa_mainloop_free) (pa_mainloop *); static void (*PULSEAUDIO_pa_mainloop_free) (pa_mainloop *);
static pa_operation_state_t (*PULSEAUDIO_pa_operation_get_state) ( static pa_operation_state_t (*PULSEAUDIO_pa_operation_get_state) (
@ -87,7 +85,13 @@ static pa_context * (*PULSEAUDIO_pa_context_new) (pa_mainloop_api *,
const char *); const char *);
static int (*PULSEAUDIO_pa_context_connect) (pa_context *, const char *, static int (*PULSEAUDIO_pa_context_connect) (pa_context *, const char *,
pa_context_flags_t, const pa_spawn_api *); pa_context_flags_t, const pa_spawn_api *);
static pa_operation * (*PULSEAUDIO_pa_context_get_sink_info_list) (pa_context *, pa_sink_info_cb_t, void *);
static pa_operation * (*PULSEAUDIO_pa_context_get_source_info_list) (pa_context *, pa_source_info_cb_t, void *);
static pa_operation * (*PULSEAUDIO_pa_context_get_sink_info_by_index) (pa_context *, uint32_t, pa_sink_info_cb_t, void *);
static pa_operation * (*PULSEAUDIO_pa_context_get_source_info_by_index) (pa_context *, uint32_t, pa_source_info_cb_t, void *);
static pa_context_state_t (*PULSEAUDIO_pa_context_get_state) (pa_context *); static pa_context_state_t (*PULSEAUDIO_pa_context_get_state) (pa_context *);
static pa_operation * (*PULSEAUDIO_pa_context_subscribe) (pa_context *, pa_subscription_mask_t, pa_context_success_cb_t, void *);
static void (*PULSEAUDIO_pa_context_set_subscribe_callback) (pa_context *, pa_context_subscribe_cb_t, void *);
static void (*PULSEAUDIO_pa_context_disconnect) (pa_context *); static void (*PULSEAUDIO_pa_context_disconnect) (pa_context *);
static void (*PULSEAUDIO_pa_context_unref) (pa_context *); static void (*PULSEAUDIO_pa_context_unref) (pa_context *);
@ -179,18 +183,24 @@ static int
load_pulseaudio_syms(void) load_pulseaudio_syms(void)
{ {
SDL_PULSEAUDIO_SYM(pa_get_library_version); SDL_PULSEAUDIO_SYM(pa_get_library_version);
SDL_PULSEAUDIO_SYM(pa_simple_new);
SDL_PULSEAUDIO_SYM(pa_simple_free);
SDL_PULSEAUDIO_SYM(pa_mainloop_new); SDL_PULSEAUDIO_SYM(pa_mainloop_new);
SDL_PULSEAUDIO_SYM(pa_mainloop_get_api); SDL_PULSEAUDIO_SYM(pa_mainloop_get_api);
SDL_PULSEAUDIO_SYM(pa_mainloop_iterate); SDL_PULSEAUDIO_SYM(pa_mainloop_iterate);
SDL_PULSEAUDIO_SYM(pa_mainloop_run);
SDL_PULSEAUDIO_SYM(pa_mainloop_quit);
SDL_PULSEAUDIO_SYM(pa_mainloop_free); SDL_PULSEAUDIO_SYM(pa_mainloop_free);
SDL_PULSEAUDIO_SYM(pa_operation_get_state); SDL_PULSEAUDIO_SYM(pa_operation_get_state);
SDL_PULSEAUDIO_SYM(pa_operation_cancel); SDL_PULSEAUDIO_SYM(pa_operation_cancel);
SDL_PULSEAUDIO_SYM(pa_operation_unref); SDL_PULSEAUDIO_SYM(pa_operation_unref);
SDL_PULSEAUDIO_SYM(pa_context_new); SDL_PULSEAUDIO_SYM(pa_context_new);
SDL_PULSEAUDIO_SYM(pa_context_connect); SDL_PULSEAUDIO_SYM(pa_context_connect);
SDL_PULSEAUDIO_SYM(pa_context_get_sink_info_list);
SDL_PULSEAUDIO_SYM(pa_context_get_source_info_list);
SDL_PULSEAUDIO_SYM(pa_context_get_sink_info_by_index);
SDL_PULSEAUDIO_SYM(pa_context_get_source_info_by_index);
SDL_PULSEAUDIO_SYM(pa_context_get_state); SDL_PULSEAUDIO_SYM(pa_context_get_state);
SDL_PULSEAUDIO_SYM(pa_context_subscribe);
SDL_PULSEAUDIO_SYM(pa_context_set_subscribe_callback);
SDL_PULSEAUDIO_SYM(pa_context_disconnect); SDL_PULSEAUDIO_SYM(pa_context_disconnect);
SDL_PULSEAUDIO_SYM(pa_context_unref); SDL_PULSEAUDIO_SYM(pa_context_unref);
SDL_PULSEAUDIO_SYM(pa_stream_new); SDL_PULSEAUDIO_SYM(pa_stream_new);
@ -206,122 +216,6 @@ load_pulseaudio_syms(void)
return 0; return 0;
} }
/* Check to see if we can connect to PulseAudio */
static SDL_bool
CheckPulseAudioAvailable()
{
pa_simple *s;
pa_sample_spec ss;
ss.format = PA_SAMPLE_S16NE;
ss.channels = 1;
ss.rate = 22050;
s = PULSEAUDIO_pa_simple_new(NULL, "SDL", PA_STREAM_PLAYBACK, NULL,
"Test", &ss, NULL, NULL, NULL);
if (s) {
PULSEAUDIO_pa_simple_free(s);
return SDL_TRUE;
} else {
return SDL_FALSE;
}
}
/* This function waits until it is possible to write a full sound buffer */
static void
PULSEAUDIO_WaitDevice(_THIS)
{
struct SDL_PrivateAudioData *h = this->hidden;
while(1) {
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) {
this->enabled = 0;
return;
}
if (PULSEAUDIO_pa_stream_writable_size(h->stream) >= h->mixlen) {
return;
}
}
}
static void
PULSEAUDIO_PlayDevice(_THIS)
{
/* Write the audio data */
struct SDL_PrivateAudioData *h = this->hidden;
if (PULSEAUDIO_pa_stream_write(h->stream, h->mixbuf, h->mixlen, NULL, 0LL,
PA_SEEK_RELATIVE) < 0) {
this->enabled = 0;
}
}
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)
{
struct SDL_PrivateAudioData *h = this->hidden;
pa_operation *o;
o = PULSEAUDIO_pa_stream_drain(h->stream, stream_drain_complete, NULL);
if (!o) {
return;
}
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)
{
return (this->hidden->mixbuf);
}
static void
PULSEAUDIO_CloseDevice(_THIS)
{
if (this->hidden != NULL) {
SDL_FreeAudioMem(this->hidden->mixbuf);
this->hidden->mixbuf = NULL;
if (this->hidden->stream) {
PULSEAUDIO_pa_stream_disconnect(this->hidden->stream);
PULSEAUDIO_pa_stream_unref(this->hidden->stream);
this->hidden->stream = NULL;
}
if (this->hidden->context != NULL) {
PULSEAUDIO_pa_context_disconnect(this->hidden->context);
PULSEAUDIO_pa_context_unref(this->hidden->context);
this->hidden->context = NULL;
}
if (this->hidden->mainloop != NULL) {
PULSEAUDIO_pa_mainloop_free(this->hidden->mainloop);
this->hidden->mainloop = NULL;
}
SDL_free(this->hidden);
this->hidden = NULL;
}
}
static SDL_INLINE int static SDL_INLINE int
squashVersion(const int major, const int minor, const int patch) squashVersion(const int major, const int minor, const int patch)
{ {
@ -344,8 +238,193 @@ getAppName(void)
return "SDL Application"; /* oh well. */ return "SDL Application"; /* oh well. */
} }
static void
WaitForPulseOperation(pa_mainloop *mainloop, pa_operation *o)
{
/* This checks for NO errors currently. Either fix that, check results elsewhere, or do things you don't care about. */
if (mainloop && o) {
SDL_bool okay = SDL_TRUE;
while (okay && (PULSEAUDIO_pa_operation_get_state(o) == PA_OPERATION_RUNNING)) {
okay = (PULSEAUDIO_pa_mainloop_iterate(mainloop, 1, NULL) >= 0);
}
PULSEAUDIO_pa_operation_unref(o);
}
}
static void
DisconnectFromPulseServer(pa_mainloop *mainloop, pa_context *context)
{
if (context) {
PULSEAUDIO_pa_context_disconnect(context);
PULSEAUDIO_pa_context_unref(context);
}
if (mainloop != NULL) {
PULSEAUDIO_pa_mainloop_free(mainloop);
}
}
static int static int
PULSEAUDIO_OpenDevice(_THIS, const char *devname, int iscapture) ConnectToPulseServer_Internal(pa_mainloop **_mainloop, pa_context **_context)
{
pa_mainloop *mainloop = NULL;
pa_context *context = NULL;
pa_mainloop_api *mainloop_api = NULL;
int state = 0;
*_mainloop = NULL;
*_context = NULL;
/* Set up a new main loop */
if (!(mainloop = PULSEAUDIO_pa_mainloop_new())) {
return SDL_SetError("pa_mainloop_new() failed");
}
*_mainloop = mainloop;
mainloop_api = PULSEAUDIO_pa_mainloop_get_api(mainloop);
SDL_assert(mainloop_api); /* this never fails, right? */
context = PULSEAUDIO_pa_context_new(mainloop_api, getAppName());
if (!context) {
return SDL_SetError("pa_context_new() failed");
}
*_context = context;
/* Connect to the PulseAudio server */
if (PULSEAUDIO_pa_context_connect(context, NULL, 0, NULL) < 0) {
return SDL_SetError("Could not setup connection to PulseAudio");
}
do {
if (PULSEAUDIO_pa_mainloop_iterate(mainloop, 1, NULL) < 0) {
return SDL_SetError("pa_mainloop_iterate() failed");
}
state = PULSEAUDIO_pa_context_get_state(context);
if (!PA_CONTEXT_IS_GOOD(state)) {
return SDL_SetError("Could not connect to PulseAudio");
}
} while (state != PA_CONTEXT_READY);
return 0; /* connected and ready! */
}
static int
ConnectToPulseServer(pa_mainloop **_mainloop, pa_context **_context)
{
const int retval = ConnectToPulseServer_Internal(_mainloop, _context);
if (retval < 0) {
DisconnectFromPulseServer(*_mainloop, *_context);
}
return retval;
}
/* This function waits until it is possible to write a full sound buffer */
static void
PULSEAUDIO_WaitDevice(_THIS)
{
struct SDL_PrivateAudioData *h = this->hidden;
while (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) {
SDL_OpenedAudioDeviceDisconnected(this);
return;
}
if (PULSEAUDIO_pa_stream_writable_size(h->stream) >= h->mixlen) {
return;
}
}
}
static void
PULSEAUDIO_PlayDevice(_THIS)
{
/* Write the audio data */
struct SDL_PrivateAudioData *h = this->hidden;
if (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)
{
return (this->hidden->mixbuf);
}
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);
}
DisconnectFromPulseServer(this->hidden->mainloop, this->hidden->context);
SDL_free(this->hidden);
this->hidden = NULL;
}
}
static void
DeviceNameCallback(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 SDL_bool
FindDeviceName(struct SDL_PrivateAudioData *h, void *handle)
{
const uint32_t idx = ((uint32_t) ((size_t) handle)) - 1;
if (handle == NULL) { /* NULL == default device. */
return SDL_TRUE;
}
WaitForPulseOperation(h->mainloop, PULSEAUDIO_pa_context_get_sink_info_by_index(h->context, idx, DeviceNameCallback, &h->device_name));
return (h->device_name != NULL);
}
static int
PULSEAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{ {
struct SDL_PrivateAudioData *h = NULL; struct SDL_PrivateAudioData *h = NULL;
Uint16 test_format = 0; Uint16 test_format = 0;
@ -442,42 +521,21 @@ PULSEAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
paattr.minreq = h->mixlen; paattr.minreq = h->mixlen;
#endif #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?");
}
/* The SDL ALSA output hints us that we use Windows' channel mapping */ /* The SDL ALSA output hints us that we use Windows' channel mapping */
/* http://bugzilla.libsdl.org/show_bug.cgi?id=110 */ /* http://bugzilla.libsdl.org/show_bug.cgi?id=110 */
PULSEAUDIO_pa_channel_map_init_auto(&pacmap, this->spec.channels, PULSEAUDIO_pa_channel_map_init_auto(&pacmap, this->spec.channels,
PA_CHANNEL_MAP_WAVEEX); PA_CHANNEL_MAP_WAVEEX);
/* Set up a new main loop */
if (!(h->mainloop = PULSEAUDIO_pa_mainloop_new())) {
PULSEAUDIO_CloseDevice(this);
return SDL_SetError("pa_mainloop_new() failed");
}
h->mainloop_api = PULSEAUDIO_pa_mainloop_get_api(h->mainloop);
h->context = PULSEAUDIO_pa_context_new(h->mainloop_api, getAppName());
if (!h->context) {
PULSEAUDIO_CloseDevice(this);
return SDL_SetError("pa_context_new() failed");
}
/* Connect to the PulseAudio server */
if (PULSEAUDIO_pa_context_connect(h->context, NULL, 0, NULL) < 0) {
PULSEAUDIO_CloseDevice(this);
return SDL_SetError("Could not setup connection to PulseAudio");
}
do {
if (PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
PULSEAUDIO_CloseDevice(this);
return SDL_SetError("pa_mainloop_iterate() failed");
}
state = PULSEAUDIO_pa_context_get_state(h->context);
if (!PA_CONTEXT_IS_GOOD(state)) {
PULSEAUDIO_CloseDevice(this);
return SDL_SetError("Could not connect to PulseAudio");
}
} while (state != PA_CONTEXT_READY);
h->stream = PULSEAUDIO_pa_stream_new( h->stream = PULSEAUDIO_pa_stream_new(
h->context, h->context,
"Simple DirectMedia Layer", /* stream description */ "Simple DirectMedia Layer", /* stream description */
@ -490,7 +548,13 @@ PULSEAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
return SDL_SetError("Could not set up PulseAudio stream"); return SDL_SetError("Could not set up PulseAudio stream");
} }
if (PULSEAUDIO_pa_stream_connect_playback(h->stream, NULL, &paattr, flags, /* now that we have multi-device support, don't move a stream from
a device that was unplugged to something else, unless we're default. */
if (h->device_name != NULL) {
flags |= PA_STREAM_DONT_MOVE;
}
if (PULSEAUDIO_pa_stream_connect_playback(h->stream, h->device_name, &paattr, flags,
NULL, NULL) < 0) { NULL, NULL) < 0) {
PULSEAUDIO_CloseDevice(this); PULSEAUDIO_CloseDevice(this);
return SDL_SetError("Could not connect PulseAudio stream"); return SDL_SetError("Could not connect PulseAudio stream");
@ -504,7 +568,7 @@ PULSEAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
state = PULSEAUDIO_pa_stream_get_state(h->stream); state = PULSEAUDIO_pa_stream_get_state(h->stream);
if (!PA_STREAM_IS_GOOD(state)) { if (!PA_STREAM_IS_GOOD(state)) {
PULSEAUDIO_CloseDevice(this); PULSEAUDIO_CloseDevice(this);
return SDL_SetError("Could not create to PulseAudio stream"); return SDL_SetError("Could not connect PulseAudio stream");
} }
} while (state != PA_STREAM_READY); } while (state != PA_STREAM_READY);
@ -512,10 +576,92 @@ PULSEAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
return 0; return 0;
} }
static pa_mainloop *hotplug_mainloop = NULL;
static pa_context *hotplug_context = NULL;
static SDL_Thread *hotplug_thread = NULL;
/* device handles are device index + 1, cast to void*, so we never pass a NULL. */
/* This is called when PulseAudio adds an output ("sink") device. */
static void
SinkInfoCallback(pa_context *c, const pa_sink_info *i, int is_last, void *data)
{
if (i) {
SDL_AddAudioDevice(SDL_FALSE, i->description, (void *) ((size_t) i->index+1));
}
}
/* This is called when PulseAudio adds a capture ("source") device. */
static void
SourceInfoCallback(pa_context *c, const pa_source_info *i, int is_last, void *data)
{
if (i) {
/* Skip "monitor" sources. These are just output from other sinks. */
if (i->monitor_of_sink == PA_INVALID_INDEX) {
SDL_AddAudioDevice(SDL_TRUE, i->description, (void *) ((size_t) i->index+1));
}
}
}
/* This is called when PulseAudio has a device connected/removed/changed. */
static void
HotplugCallback(pa_context *c, pa_subscription_event_type_t t, uint32_t idx, void *data)
{
const SDL_bool added = ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW);
const SDL_bool removed = ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE);
if (added || removed) { /* we only care about add/remove events. */
const SDL_bool sink = ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK);
const SDL_bool source = ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SOURCE);
/* adds need sink details from the PulseAudio server. Another callback... */
if (added && sink) {
PULSEAUDIO_pa_context_get_sink_info_by_index(hotplug_context, idx, SinkInfoCallback, NULL);
} else if (added && source) {
PULSEAUDIO_pa_context_get_source_info_by_index(hotplug_context, idx, SourceInfoCallback, NULL);
} else if (removed && (sink || source)) {
/* removes we can handle just with the device index. */
SDL_RemoveAudioDevice(source != 0, (void *) ((size_t) idx+1));
}
}
}
/* this runs as a thread while the Pulse target is initialized to catch hotplug events. */
static int SDLCALL
HotplugThread(void *data)
{
pa_operation *o;
SDL_SetThreadPriority(SDL_THREAD_PRIORITY_LOW);
PULSEAUDIO_pa_context_set_subscribe_callback(hotplug_context, HotplugCallback, NULL);
o = PULSEAUDIO_pa_context_subscribe(hotplug_context, PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SOURCE, NULL, NULL);
PULSEAUDIO_pa_operation_unref(o); /* don't wait for it, just do our thing. */
PULSEAUDIO_pa_mainloop_run(hotplug_mainloop, NULL);
return 0;
}
static void
PULSEAUDIO_DetectDevices()
{
WaitForPulseOperation(hotplug_mainloop, PULSEAUDIO_pa_context_get_sink_info_list(hotplug_context, SinkInfoCallback, NULL));
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);
}
static void static void
PULSEAUDIO_Deinitialize(void) PULSEAUDIO_Deinitialize(void)
{ {
if (hotplug_thread) {
PULSEAUDIO_pa_mainloop_quit(hotplug_mainloop, 0);
SDL_WaitThread(hotplug_thread, NULL);
hotplug_thread = NULL;
}
DisconnectFromPulseServer(hotplug_mainloop, hotplug_context);
hotplug_mainloop = NULL;
hotplug_context = NULL;
UnloadPulseAudioLibrary(); UnloadPulseAudioLibrary();
} }
@ -526,12 +672,13 @@ PULSEAUDIO_Init(SDL_AudioDriverImpl * impl)
return 0; return 0;
} }
if (!CheckPulseAudioAvailable()) { if (ConnectToPulseServer(&hotplug_mainloop, &hotplug_context) < 0) {
UnloadPulseAudioLibrary(); UnloadPulseAudioLibrary();
return 0; return 0;
} }
/* Set the function pointers */ /* Set the function pointers */
impl->DetectDevices = PULSEAUDIO_DetectDevices;
impl->OpenDevice = PULSEAUDIO_OpenDevice; impl->OpenDevice = PULSEAUDIO_OpenDevice;
impl->PlayDevice = PULSEAUDIO_PlayDevice; impl->PlayDevice = PULSEAUDIO_PlayDevice;
impl->WaitDevice = PULSEAUDIO_WaitDevice; impl->WaitDevice = PULSEAUDIO_WaitDevice;
@ -539,12 +686,10 @@ PULSEAUDIO_Init(SDL_AudioDriverImpl * impl)
impl->CloseDevice = PULSEAUDIO_CloseDevice; impl->CloseDevice = PULSEAUDIO_CloseDevice;
impl->WaitDone = PULSEAUDIO_WaitDone; impl->WaitDone = PULSEAUDIO_WaitDone;
impl->Deinitialize = PULSEAUDIO_Deinitialize; impl->Deinitialize = PULSEAUDIO_Deinitialize;
impl->OnlyHasDefaultOutputDevice = 1;
return 1; /* this audio target is available. */ return 1; /* this audio target is available. */
} }
AudioBootStrap PULSEAUDIO_bootstrap = { AudioBootStrap PULSEAUDIO_bootstrap = {
"pulseaudio", "PulseAudio", PULSEAUDIO_Init, 0 "pulseaudio", "PulseAudio", PULSEAUDIO_Init, 0
}; };

View File

@ -32,9 +32,10 @@
struct SDL_PrivateAudioData struct SDL_PrivateAudioData
{ {
char *device_name;
/* pulseaudio structures */ /* pulseaudio structures */
pa_mainloop *mainloop; pa_mainloop *mainloop;
pa_mainloop_api *mainloop_api;
pa_context *context; pa_context *context;
pa_stream *stream; pa_stream *stream;

View File

@ -19,6 +19,15 @@
3. This notice may not be removed or altered from any source distribution. 3. This notice may not be removed or altered from any source distribution.
*/ */
/*
* !!! FIXME: streamline this a little by removing all the
* !!! FIXME: if (capture) {} else {} sections that are identical
* !!! FIXME: except for one flag.
*/
/* !!! FIXME: can this target support hotplugging? */
/* !!! FIXME: ...does SDL2 even support QNX? */
#include "../../SDL_internal.h" #include "../../SDL_internal.h"
#if SDL_AUDIO_DRIVER_QSA #if SDL_AUDIO_DRIVER_QSA
@ -300,7 +309,7 @@ QSA_PlayDevice(_THIS)
/* If we couldn't write, assume fatal error for now */ /* If we couldn't write, assume fatal error for now */
if (towrite != 0) { if (towrite != 0) {
this->enabled = 0; SDL_OpenedAudioDeviceDisconnected(this);
} }
} }
@ -337,8 +346,9 @@ QSA_CloseDevice(_THIS)
} }
static int static int
QSA_OpenDevice(_THIS, const char *devname, int iscapture) QSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{ {
const QSA_Device *device = (const QSA_Device *) handle;
int status = 0; int status = 0;
int format = 0; int format = 0;
SDL_AudioFormat test_format = 0; SDL_AudioFormat test_format = 0;
@ -363,80 +373,19 @@ QSA_OpenDevice(_THIS, const char *devname, int iscapture)
/* Initialize channel direction: capture or playback */ /* Initialize channel direction: capture or playback */
this->hidden->iscapture = iscapture; this->hidden->iscapture = iscapture;
/* Find deviceid and cardid by device name for playback */ if (device != NULL) {
if ((!this->hidden->iscapture) && (devname != NULL)) {
uint32_t device;
int32_t status;
/* Search in the playback devices */
device = 0;
do {
status = SDL_strcmp(qsa_playback_device[device].name, devname);
if (status == 0) {
/* Found requested device */
this->hidden->deviceno = qsa_playback_device[device].deviceno;
this->hidden->cardno = qsa_playback_device[device].cardno;
break;
}
device++;
if (device >= qsa_playback_devices) {
QSA_CloseDevice(this);
return SDL_SetError("No such playback device");
}
} while (1);
}
/* Find deviceid and cardid by device name for capture */
if ((this->hidden->iscapture) && (devname != NULL)) {
/* Search in the capture devices */
uint32_t device;
int32_t status;
/* Searching in the playback devices */
device = 0;
do {
status = SDL_strcmp(qsa_capture_device[device].name, devname);
if (status == 0) {
/* Found requested device */
this->hidden->deviceno = qsa_capture_device[device].deviceno;
this->hidden->cardno = qsa_capture_device[device].cardno;
break;
}
device++;
if (device >= qsa_capture_devices) {
QSA_CloseDevice(this);
return SDL_SetError("No such capture device");
}
} while (1);
}
/* Check if SDL requested default audio device */
if (devname == NULL) {
/* Open system default audio device */
if (!this->hidden->iscapture) {
status = snd_pcm_open_preferred(&this->hidden->audio_handle,
&this->hidden->cardno,
&this->hidden->deviceno,
SND_PCM_OPEN_PLAYBACK);
} else {
status = snd_pcm_open_preferred(&this->hidden->audio_handle,
&this->hidden->cardno,
&this->hidden->deviceno,
SND_PCM_OPEN_CAPTURE);
}
} else {
/* Open requested audio device */ /* Open requested audio device */
if (!this->hidden->iscapture) { this->hidden->deviceno = device->deviceno;
status = this->hidden->cardno = device->cardno;
snd_pcm_open(&this->hidden->audio_handle, status = snd_pcm_open(&this->hidden->audio_handle,
this->hidden->cardno, this->hidden->deviceno, device->cardno, device->deviceno,
SND_PCM_OPEN_PLAYBACK); iscapture ? SND_PCM_OPEN_PLAYBACK : SND_PCM_OPEN_CAPTURE);
} else { } else {
status = /* Open system default audio device */
snd_pcm_open(&this->hidden->audio_handle, status = snd_pcm_open_preferred(&this->hidden->audio_handle,
this->hidden->cardno, this->hidden->deviceno, &this->hidden->cardno,
SND_PCM_OPEN_CAPTURE); &this->hidden->deviceno,
} iscapture ? SND_PCM_OPEN_PLAYBACK : SND_PCM_OPEN_CAPTURE);
} }
/* Check if requested device is opened */ /* Check if requested device is opened */
@ -638,7 +587,7 @@ QSA_OpenDevice(_THIS, const char *devname, int iscapture)
} }
static void static void
QSA_DetectDevices(int iscapture, SDL_AddAudioDevice addfn) QSA_DetectDevices(void)
{ {
uint32_t it; uint32_t it;
uint32_t cards; uint32_t cards;
@ -656,8 +605,9 @@ QSA_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
return; return;
} }
/* !!! FIXME: code duplication */
/* Find requested devices by type */ /* Find requested devices by type */
if (!iscapture) { { /* output devices */
/* Playback devices enumeration requested */ /* Playback devices enumeration requested */
for (it = 0; it < cards; it++) { for (it = 0; it < cards; it++) {
devices = 0; devices = 0;
@ -688,7 +638,7 @@ QSA_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
devices; devices;
status = snd_pcm_close(handle); status = snd_pcm_close(handle);
if (status == EOK) { if (status == EOK) {
addfn(qsa_playback_device[qsa_playback_devices].name); SDL_AddAudioDevice(SDL_FALSE, qsa_playback_device[qsa_playback_devices].name, &qsa_playback_device[qsa_playback_devices]);
qsa_playback_devices++; qsa_playback_devices++;
} }
} else { } else {
@ -713,7 +663,9 @@ QSA_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
break; break;
} }
} }
} else { }
{ /* capture devices */
/* Capture devices enumeration requested */ /* Capture devices enumeration requested */
for (it = 0; it < cards; it++) { for (it = 0; it < cards; it++) {
devices = 0; devices = 0;
@ -744,7 +696,7 @@ QSA_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
devices; devices;
status = snd_pcm_close(handle); status = snd_pcm_close(handle);
if (status == EOK) { if (status == EOK) {
addfn(qsa_capture_device[qsa_capture_devices].name); SDL_AddAudioDevice(SDL_TRUE, qsa_capture_device[qsa_capture_devices].name, &qsa_capture_device[qsa_capture_devices]);
qsa_capture_devices++; qsa_capture_devices++;
} }
} else { } else {

View File

@ -158,7 +158,7 @@ SNDIO_PlayDevice(_THIS)
/* If we couldn't write, assume fatal error for now */ /* If we couldn't write, assume fatal error for now */
if ( written == 0 ) { if ( written == 0 ) {
this->enabled = 0; SDL_OpenedAudioDeviceDisconnected(this);
} }
#ifdef DEBUG_AUDIO #ifdef DEBUG_AUDIO
fprintf(stderr, "Wrote %d bytes of audio data\n", written); fprintf(stderr, "Wrote %d bytes of audio data\n", written);
@ -193,7 +193,7 @@ SNDIO_CloseDevice(_THIS)
} }
static int static int
SNDIO_OpenDevice(_THIS, const char *devname, int iscapture) SNDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{ {
SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format); SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
struct sio_par par; struct sio_par par;

View File

@ -56,9 +56,9 @@ static Uint8 snd2au(int sample);
/* Audio driver bootstrap functions */ /* Audio driver bootstrap functions */
static void static void
SUNAUDIO_DetectDevices(int iscapture, SDL_AddAudioDevice addfn) SUNAUDIO_DetectDevices(void)
{ {
SDL_EnumUnixAudioDevices(iscapture, 1, (int (*)(int fd)) NULL, addfn); SDL_EnumUnixAudioDevices(1, (int (*)(int)) NULL);
} }
#ifdef DEBUG_AUDIO #ifdef DEBUG_AUDIO
@ -158,7 +158,7 @@ SUNAUDIO_PlayDevice(_THIS)
if (write(this->hidden->audio_fd, this->hidden->ulaw_buf, if (write(this->hidden->audio_fd, this->hidden->ulaw_buf,
this->hidden->fragsize) < 0) { this->hidden->fragsize) < 0) {
/* Assume fatal error, for now */ /* Assume fatal error, for now */
this->enabled = 0; SDL_OpenedAudioDeviceDisconnected(this);
} }
this->hidden->written += this->hidden->fragsize; this->hidden->written += this->hidden->fragsize;
} else { } else {
@ -168,7 +168,7 @@ SUNAUDIO_PlayDevice(_THIS)
if (write(this->hidden->audio_fd, this->hidden->mixbuf, if (write(this->hidden->audio_fd, this->hidden->mixbuf,
this->spec.size) < 0) { this->spec.size) < 0) {
/* Assume fatal error, for now */ /* Assume fatal error, for now */
this->enabled = 0; SDL_OpenedAudioDeviceDisconnected(this);
} }
this->hidden->written += this->hidden->fragsize; this->hidden->written += this->hidden->fragsize;
} }
@ -198,7 +198,7 @@ SUNAUDIO_CloseDevice(_THIS)
} }
static int static int
SUNAUDIO_OpenDevice(_THIS, const char *devname, int iscapture) SUNAUDIO_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; SDL_AudioFormat format = 0;
@ -414,6 +414,8 @@ SUNAUDIO_Init(SDL_AudioDriverImpl * impl)
impl->GetDeviceBuf = SUNAUDIO_GetDeviceBuf; impl->GetDeviceBuf = SUNAUDIO_GetDeviceBuf;
impl->CloseDevice = SUNAUDIO_CloseDevice; impl->CloseDevice = SUNAUDIO_CloseDevice;
impl->AllowsArbitraryDeviceNames = 1;
return 1; /* this audio target is available. */ return 1; /* this audio target is available. */
} }

View File

@ -36,8 +36,9 @@
#define WAVE_FORMAT_IEEE_FLOAT 0x0003 #define WAVE_FORMAT_IEEE_FLOAT 0x0003
#endif #endif
#define DETECT_DEV_IMPL(typ, capstyp) \ #define DETECT_DEV_IMPL(iscap, typ, capstyp) \
static void DetectWave##typ##Devs(SDL_AddAudioDevice addfn) { \ static void DetectWave##typ##Devs(void) { \
const UINT iscapture = iscap ? 1 : 0; \
const UINT devcount = wave##typ##GetNumDevs(); \ const UINT devcount = wave##typ##GetNumDevs(); \
capstyp caps; \ capstyp caps; \
UINT i; \ UINT i; \
@ -45,24 +46,21 @@ static void DetectWave##typ##Devs(SDL_AddAudioDevice addfn) { \
if (wave##typ##GetDevCaps(i,&caps,sizeof(caps))==MMSYSERR_NOERROR) { \ if (wave##typ##GetDevCaps(i,&caps,sizeof(caps))==MMSYSERR_NOERROR) { \
char *name = WIN_StringToUTF8(caps.szPname); \ char *name = WIN_StringToUTF8(caps.szPname); \
if (name != NULL) { \ if (name != NULL) { \
addfn(name); \ SDL_AddAudioDevice((int) iscapture, name, (void *) ((size_t) i+1)); \
SDL_free(name); \ SDL_free(name); \
} \ } \
} \ } \
} \ } \
} }
DETECT_DEV_IMPL(Out, WAVEOUTCAPS) DETECT_DEV_IMPL(SDL_FALSE, Out, WAVEOUTCAPS)
DETECT_DEV_IMPL(In, WAVEINCAPS) DETECT_DEV_IMPL(SDL_TRUE, In, WAVEINCAPS)
static void static void
WINMM_DetectDevices(int iscapture, SDL_AddAudioDevice addfn) WINMM_DetectDevices(void)
{ {
if (iscapture) { DetectWaveInDevs();
DetectWaveInDevs(addfn); DetectWaveOutDevs();
} else {
DetectWaveOutDevs(addfn);
}
} }
static void CALLBACK static void CALLBACK
@ -220,48 +218,19 @@ PrepWaveFormat(_THIS, UINT devId, WAVEFORMATEX *pfmt, const int iscapture)
} }
static int static int
WINMM_OpenDevice(_THIS, const char *devname, int iscapture) WINMM_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{ {
SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format); SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
int valid_datatype = 0; int valid_datatype = 0;
MMRESULT result; MMRESULT result;
WAVEFORMATEX waveformat; WAVEFORMATEX waveformat;
UINT devId = WAVE_MAPPER; /* WAVE_MAPPER == choose system's default */ UINT devId = WAVE_MAPPER; /* WAVE_MAPPER == choose system's default */
char *utf8 = NULL;
UINT i; UINT i;
if (devname != NULL) { /* specific device requested? */ if (handle != NULL) { /* specific device requested? */
if (iscapture) { /* -1 because we increment the original value to avoid NULL. */
const UINT devcount = waveInGetNumDevs(); const size_t val = ((size_t) handle) - 1;
WAVEINCAPS caps; devId = (UINT) val;
for (i = 0; (i < devcount) && (devId == WAVE_MAPPER); i++) {
result = waveInGetDevCaps(i, &caps, sizeof (caps));
if (result != MMSYSERR_NOERROR)
continue;
else if ((utf8 = WIN_StringToUTF8(caps.szPname)) == NULL)
continue;
else if (SDL_strcmp(devname, utf8) == 0)
devId = i;
SDL_free(utf8);
}
} else {
const UINT devcount = waveOutGetNumDevs();
WAVEOUTCAPS caps;
for (i = 0; (i < devcount) && (devId == WAVE_MAPPER); i++) {
result = waveOutGetDevCaps(i, &caps, sizeof (caps));
if (result != MMSYSERR_NOERROR)
continue;
else if ((utf8 = WIN_StringToUTF8(caps.szPname)) == NULL)
continue;
else if (SDL_strcmp(devname, utf8) == 0)
devId = i;
SDL_free(utf8);
}
}
if (devId == WAVE_MAPPER) {
return SDL_SetError("Requested device not found");
}
} }
/* Initialize all variables that we clean on shutdown */ /* Initialize all variables that we clean on shutdown */
@ -279,10 +248,6 @@ WINMM_OpenDevice(_THIS, const char *devname, int iscapture)
if (this->spec.channels > 2) if (this->spec.channels > 2)
this->spec.channels = 2; /* !!! FIXME: is this right? */ this->spec.channels = 2; /* !!! FIXME: is this right? */
/* Check the buffer size -- minimum of 1/4 second (word aligned) */
if (this->spec.samples < (this->spec.freq / 4))
this->spec.samples = ((this->spec.freq / 4) + 3) & ~3;
while ((!valid_datatype) && (test_format)) { while ((!valid_datatype) && (test_format)) {
switch (test_format) { switch (test_format) {
case AUDIO_U8: case AUDIO_U8:

View File

@ -126,16 +126,13 @@ struct SDL_PrivateAudioData
static void static void
XAUDIO2_DetectDevices(int iscapture, SDL_AddAudioDevice addfn) XAUDIO2_DetectDevices(void)
{ {
IXAudio2 *ixa2 = NULL; IXAudio2 *ixa2 = NULL;
UINT32 devcount = 0; UINT32 devcount = 0;
UINT32 i = 0; UINT32 i = 0;
if (iscapture) { if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) {
SDL_SetError("XAudio2: capture devices unsupported.");
return;
} else if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) {
SDL_SetError("XAudio2: XAudio2Create() failed at detection."); SDL_SetError("XAudio2: XAudio2Create() failed at detection.");
return; return;
} else if (IXAudio2_GetDeviceCount(ixa2, &devcount) != S_OK) { } else if (IXAudio2_GetDeviceCount(ixa2, &devcount) != S_OK) {
@ -149,8 +146,8 @@ XAUDIO2_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
if (IXAudio2_GetDeviceDetails(ixa2, i, &details) == S_OK) { if (IXAudio2_GetDeviceDetails(ixa2, i, &details) == S_OK) {
char *str = WIN_StringToUTF8(details.DisplayName); char *str = WIN_StringToUTF8(details.DisplayName);
if (str != NULL) { if (str != NULL) {
addfn(str); SDL_AddAudioDevice(SDL_FALSE, str, (void *) ((size_t) i+1));
SDL_free(str); /* addfn() made a copy of the string. */ SDL_free(str); /* SDL_AddAudioDevice made a copy of the string. */
} }
} }
} }
@ -169,8 +166,8 @@ VoiceCBOnBufferEnd(THIS_ void *data)
static void STDMETHODCALLTYPE static void STDMETHODCALLTYPE
VoiceCBOnVoiceError(THIS_ void *data, HRESULT Error) VoiceCBOnVoiceError(THIS_ void *data, HRESULT Error)
{ {
/* !!! FIXME: attempt to recover, or mark device disconnected. */ SDL_AudioDevice *this = (SDL_AudioDevice *) data;
SDL_assert(0 && "write me!"); SDL_OpenedAudioDeviceDisconnected(this);
} }
/* no-op callbacks... */ /* no-op callbacks... */
@ -221,7 +218,7 @@ XAUDIO2_PlayDevice(_THIS)
if (result != S_OK) { /* uhoh, panic! */ if (result != S_OK) { /* uhoh, panic! */
IXAudio2SourceVoice_FlushSourceBuffers(source); IXAudio2SourceVoice_FlushSourceBuffers(source);
this->enabled = 0; SDL_OpenedAudioDeviceDisconnected(this);
} }
} }
@ -289,7 +286,7 @@ XAUDIO2_CloseDevice(_THIS)
} }
static int static int
XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture) XAUDIO2_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
{ {
HRESULT result = S_OK; HRESULT result = S_OK;
WAVEFORMATEX waveformat; WAVEFORMATEX waveformat;
@ -315,9 +312,17 @@ XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture)
static IXAudio2VoiceCallback callbacks = { &callbacks_vtable }; static IXAudio2VoiceCallback callbacks = { &callbacks_vtable };
if (iscapture) { #if defined(SDL_XAUDIO2_WIN8)
return SDL_SetError("XAudio2: capture devices unsupported."); /* !!! FIXME: hook up hotplugging. */
} else if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) { #else
if (handle != NULL) { /* specific device requested? */
/* -1 because we increment the original value to avoid NULL. */
const size_t val = ((size_t) handle) - 1;
devId = (UINT32) val;
}
#endif
if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) {
return SDL_SetError("XAudio2: XAudio2Create() failed at open."); return SDL_SetError("XAudio2: XAudio2Create() failed at open.");
} }
@ -332,37 +337,6 @@ XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture)
ixa2->SetDebugConfiguration(&debugConfig); ixa2->SetDebugConfiguration(&debugConfig);
*/ */
#if ! defined(__WINRT__)
if (devname != NULL) {
UINT32 devcount = 0;
UINT32 i = 0;
if (IXAudio2_GetDeviceCount(ixa2, &devcount) != S_OK) {
IXAudio2_Release(ixa2);
return SDL_SetError("XAudio2: IXAudio2_GetDeviceCount() failed.");
}
for (i = 0; i < devcount; i++) {
XAUDIO2_DEVICE_DETAILS details;
if (IXAudio2_GetDeviceDetails(ixa2, i, &details) == S_OK) {
char *str = WIN_StringToUTF8(details.DisplayName);
if (str != NULL) {
const int match = (SDL_strcmp(str, devname) == 0);
SDL_free(str);
if (match) {
devId = i;
break;
}
}
}
}
if (i == devcount) {
IXAudio2_Release(ixa2);
return SDL_SetError("XAudio2: Requested device not found.");
}
}
#endif
/* Initialize all variables that we clean on shutdown */ /* Initialize all variables that we clean on shutdown */
this->hidden = (struct SDL_PrivateAudioData *) this->hidden = (struct SDL_PrivateAudioData *)
SDL_malloc((sizeof *this->hidden)); SDL_malloc((sizeof *this->hidden));
@ -529,6 +503,16 @@ XAUDIO2_Init(SDL_AudioDriverImpl * impl)
impl->CloseDevice = XAUDIO2_CloseDevice; impl->CloseDevice = XAUDIO2_CloseDevice;
impl->Deinitialize = XAUDIO2_Deinitialize; impl->Deinitialize = XAUDIO2_Deinitialize;
/* !!! FIXME: We can apparently use a C++ interface on Windows 8
* !!! FIXME: (Windows::Devices::Enumeration::DeviceInformation) for device
* !!! FIXME: detection, but it's not implemented here yet.
* !!! FIXME: see http://blogs.msdn.com/b/chuckw/archive/2012/04/02/xaudio2-and-windows-8-consumer-preview.aspx
* !!! FIXME: for now, force the default device.
*/
#if defined(SDL_XAUDIO2_WIN8) || defined(__WINRT__)
impl->OnlyHasDefaultOutputDevice = 1;
#endif
return 1; /* this audio target is available. */ return 1; /* this audio target is available. */
#endif #endif
} }

View File

@ -32,6 +32,7 @@
#include "../../events/SDL_events_c.h" #include "../../events/SDL_events_c.h"
#include "../../video/android/SDL_androidkeyboard.h" #include "../../video/android/SDL_androidkeyboard.h"
#include "../../video/android/SDL_androidmouse.h"
#include "../../video/android/SDL_androidtouch.h" #include "../../video/android/SDL_androidtouch.h"
#include "../../video/android/SDL_androidvideo.h" #include "../../video/android/SDL_androidvideo.h"
#include "../../video/android/SDL_androidwindow.h" #include "../../video/android/SDL_androidwindow.h"
@ -44,8 +45,8 @@
#define LOG_TAG "SDL_android" #define LOG_TAG "SDL_android"
/* #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) */ /* #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) */
/* #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) */ /* #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) */
#define LOGI(...) do {} while (false) #define LOGI(...) do {} while (0)
#define LOGE(...) do {} while (false) #define LOGE(...) do {} while (0)
/* Uncomment this to log messages entering and exiting methods in this file */ /* Uncomment this to log messages entering and exiting methods in this file */
/* #define DEBUG_JNI */ /* #define DEBUG_JNI */
@ -57,7 +58,6 @@ static void Android_JNI_ThreadDestroyed(void*);
*******************************************************************************/ *******************************************************************************/
#include <jni.h> #include <jni.h>
#include <android/log.h> #include <android/log.h>
#include <stdbool.h>
/******************************************************************************* /*******************************************************************************
@ -80,7 +80,7 @@ static jmethodID midPollInputDevices;
/* Accelerometer data storage */ /* Accelerometer data storage */
static float fLastAccelerometer[3]; static float fLastAccelerometer[3];
static bool bHasNewData; static SDL_bool bHasNewData;
/******************************************************************************* /*******************************************************************************
Functions called by JNI Functions called by JNI
@ -132,7 +132,7 @@ JNIEXPORT void JNICALL SDL_Android_Init(JNIEnv* mEnv, jclass cls)
midPollInputDevices = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, midPollInputDevices = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
"pollInputDevices", "()V"); "pollInputDevices", "()V");
bHasNewData = false; bHasNewData = SDL_FALSE;
if(!midGetNativeSurface || !midFlipBuffers || !midAudioInit || if(!midGetNativeSurface || !midFlipBuffers || !midAudioInit ||
!midAudioWriteShortBuffer || !midAudioWriteByteBuffer || !midAudioQuit || !midPollInputDevices) { !midAudioWriteShortBuffer || !midAudioWriteByteBuffer || !midAudioQuit || !midPollInputDevices) {
@ -144,9 +144,9 @@ JNIEXPORT void JNICALL SDL_Android_Init(JNIEnv* mEnv, jclass cls)
/* Resize */ /* Resize */
JNIEXPORT void JNICALL Java_org_libsdl_app_SDLActivity_onNativeResize( JNIEXPORT void JNICALL Java_org_libsdl_app_SDLActivity_onNativeResize(
JNIEnv* env, jclass jcls, JNIEnv* env, jclass jcls,
jint width, jint height, jint format) jint width, jint height, jint format, jfloat rate)
{ {
Android_SetScreenResolution(width, height, format); Android_SetScreenResolution(width, height, format, rate);
} }
/* Paddown */ /* Paddown */
@ -294,6 +294,14 @@ JNIEXPORT void JNICALL Java_org_libsdl_app_SDLActivity_onNativeTouch(
Android_OnTouch(touch_device_id_in, pointer_finger_id_in, action, x, y, p); Android_OnTouch(touch_device_id_in, pointer_finger_id_in, action, x, y, p);
} }
/* Mouse */
JNIEXPORT void JNICALL Java_org_libsdl_app_SDLActivity_onNativeMouse(
JNIEnv* env, jclass jcls,
jint button, jint action, jfloat x, jfloat y)
{
Android_OnMouse(button, action, x, y);
}
/* Accelerometer */ /* Accelerometer */
JNIEXPORT void JNICALL Java_org_libsdl_app_SDLActivity_onNativeAccel( JNIEXPORT void JNICALL Java_org_libsdl_app_SDLActivity_onNativeAccel(
JNIEnv* env, jclass jcls, JNIEnv* env, jclass jcls,
@ -302,7 +310,7 @@ JNIEXPORT void JNICALL Java_org_libsdl_app_SDLActivity_onNativeAccel(
fLastAccelerometer[0] = x; fLastAccelerometer[0] = x;
fLastAccelerometer[1] = y; fLastAccelerometer[1] = y;
fLastAccelerometer[2] = z; fLastAccelerometer[2] = z;
bHasNewData = true; bHasNewData = SDL_TRUE;
} }
/* Low memory */ /* Low memory */
@ -386,7 +394,7 @@ JNIEXPORT void JNICALL Java_org_libsdl_app_SDLInputConnection_nativeSetComposing
(*env)->ReleaseStringUTFChars(env, text, utftext); (*env)->ReleaseStringUTFChars(env, text, utftext);
} }
jstring Java_org_libsdl_app_SDLActivity_nativeGetHint(JNIEnv* env, jclass cls, jstring name) { JNIEXPORT jstring JNICALL Java_org_libsdl_app_SDLActivity_nativeGetHint(JNIEnv* env, jclass cls, jstring name) {
const char *utfname = (*env)->GetStringUTFChars(env, name, NULL); const char *utfname = (*env)->GetStringUTFChars(env, name, NULL);
const char *hint = SDL_GetHint(utfname); const char *hint = SDL_GetHint(utfname);
@ -487,7 +495,7 @@ SDL_bool Android_JNI_GetAccelerometerValues(float values[3])
for (i = 0; i < 3; ++i) { for (i = 0; i < 3; ++i) {
values[i] = fLastAccelerometer[i]; values[i] = fLastAccelerometer[i];
} }
bHasNewData = false; bHasNewData = SDL_FALSE;
retval = SDL_TRUE; retval = SDL_TRUE;
} }
@ -549,12 +557,12 @@ int Android_JNI_SetupThread(void)
* Audio support * Audio support
*/ */
static jboolean audioBuffer16Bit = JNI_FALSE; static jboolean audioBuffer16Bit = JNI_FALSE;
static jboolean audioBufferStereo = JNI_FALSE;
static jobject audioBuffer = NULL; static jobject audioBuffer = NULL;
static void* audioBufferPinned = NULL; static void* audioBufferPinned = NULL;
int Android_JNI_OpenAudioDevice(int sampleRate, int is16Bit, int channelCount, int desiredBufferFrames) int Android_JNI_OpenAudioDevice(int sampleRate, int is16Bit, int channelCount, int desiredBufferFrames)
{ {
jboolean audioBufferStereo;
int audioBufferFrames; int audioBufferFrames;
JNIEnv *env = Android_JNI_GetEnv(); JNIEnv *env = Android_JNI_GetEnv();
@ -647,7 +655,7 @@ void Android_JNI_CloseAudioDevice()
/* Test for an exception and call SDL_SetError with its detail if one occurs */ /* Test for an exception and call SDL_SetError with its detail if one occurs */
/* If the parameter silent is truthy then SDL_SetError() will not be called. */ /* If the parameter silent is truthy then SDL_SetError() will not be called. */
static bool Android_JNI_ExceptionOccurred(bool silent) static SDL_bool Android_JNI_ExceptionOccurred(SDL_bool silent)
{ {
SDL_assert(LocalReferenceHolder_IsActive()); SDL_assert(LocalReferenceHolder_IsActive());
JNIEnv *mEnv = Android_JNI_GetEnv(); JNIEnv *mEnv = Android_JNI_GetEnv();
@ -681,10 +689,10 @@ static bool Android_JNI_ExceptionOccurred(bool silent)
(*mEnv)->ReleaseStringUTFChars(mEnv, exceptionName, exceptionNameUTF8); (*mEnv)->ReleaseStringUTFChars(mEnv, exceptionName, exceptionNameUTF8);
} }
return true; return SDL_TRUE;
} }
return false; return SDL_FALSE;
} }
static int Internal_Android_JNI_FileOpen(SDL_RWops* ctx) static int Internal_Android_JNI_FileOpen(SDL_RWops* ctx)
@ -728,19 +736,19 @@ static int Internal_Android_JNI_FileOpen(SDL_RWops* ctx)
*/ */
mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, assetManager), "openFd", "(Ljava/lang/String;)Landroid/content/res/AssetFileDescriptor;"); mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, assetManager), "openFd", "(Ljava/lang/String;)Landroid/content/res/AssetFileDescriptor;");
inputStream = (*mEnv)->CallObjectMethod(mEnv, assetManager, mid, fileNameJString); inputStream = (*mEnv)->CallObjectMethod(mEnv, assetManager, mid, fileNameJString);
if (Android_JNI_ExceptionOccurred(true)) { if (Android_JNI_ExceptionOccurred(SDL_TRUE)) {
goto fallback; goto fallback;
} }
mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, inputStream), "getStartOffset", "()J"); mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, inputStream), "getStartOffset", "()J");
ctx->hidden.androidio.offset = (*mEnv)->CallLongMethod(mEnv, inputStream, mid); ctx->hidden.androidio.offset = (*mEnv)->CallLongMethod(mEnv, inputStream, mid);
if (Android_JNI_ExceptionOccurred(true)) { if (Android_JNI_ExceptionOccurred(SDL_TRUE)) {
goto fallback; goto fallback;
} }
mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, inputStream), "getDeclaredLength", "()J"); mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, inputStream), "getDeclaredLength", "()J");
ctx->hidden.androidio.size = (*mEnv)->CallLongMethod(mEnv, inputStream, mid); ctx->hidden.androidio.size = (*mEnv)->CallLongMethod(mEnv, inputStream, mid);
if (Android_JNI_ExceptionOccurred(true)) { if (Android_JNI_ExceptionOccurred(SDL_TRUE)) {
goto fallback; goto fallback;
} }
@ -754,7 +762,7 @@ static int Internal_Android_JNI_FileOpen(SDL_RWops* ctx)
/* Seek to the correct offset in the file. */ /* Seek to the correct offset in the file. */
lseek(ctx->hidden.androidio.fd, (off_t)ctx->hidden.androidio.offset, SEEK_SET); lseek(ctx->hidden.androidio.fd, (off_t)ctx->hidden.androidio.offset, SEEK_SET);
if (false) { if (0) {
fallback: fallback:
/* Disabled log message because of spam on the Nexus 7 */ /* Disabled log message because of spam on the Nexus 7 */
/* __android_log_print(ANDROID_LOG_DEBUG, "SDL", "Falling back to legacy InputStream method for opening file"); */ /* __android_log_print(ANDROID_LOG_DEBUG, "SDL", "Falling back to legacy InputStream method for opening file"); */
@ -766,13 +774,13 @@ fallback:
mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, assetManager), mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, assetManager),
"open", "(Ljava/lang/String;I)Ljava/io/InputStream;"); "open", "(Ljava/lang/String;I)Ljava/io/InputStream;");
inputStream = (*mEnv)->CallObjectMethod(mEnv, assetManager, mid, fileNameJString, 1 /* ACCESS_RANDOM */); inputStream = (*mEnv)->CallObjectMethod(mEnv, assetManager, mid, fileNameJString, 1 /* ACCESS_RANDOM */);
if (Android_JNI_ExceptionOccurred(false)) { if (Android_JNI_ExceptionOccurred(SDL_FALSE)) {
// Try fallback to APK Extension files // Try fallback to APK Extension files
mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, context), mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, context),
"openAPKExtensionInputStream", "(Ljava/lang/String;)Ljava/io/InputStream;"); "openAPKExtensionInputStream", "(Ljava/lang/String;)Ljava/io/InputStream;");
inputStream = (*mEnv)->CallObjectMethod(mEnv, context, mid, fileNameJString); inputStream = (*mEnv)->CallObjectMethod(mEnv, context, mid, fileNameJString);
if (Android_JNI_ExceptionOccurred(false)) { if (Android_JNI_ExceptionOccurred(SDL_FALSE)) {
goto failure; goto failure;
} }
} }
@ -790,7 +798,7 @@ fallback:
mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, inputStream), mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, inputStream),
"available", "()I"); "available", "()I");
ctx->hidden.androidio.size = (long)(*mEnv)->CallIntMethod(mEnv, inputStream, mid); ctx->hidden.androidio.size = (long)(*mEnv)->CallIntMethod(mEnv, inputStream, mid);
if (Android_JNI_ExceptionOccurred(false)) { if (Android_JNI_ExceptionOccurred(SDL_FALSE)) {
goto failure; goto failure;
} }
@ -801,7 +809,7 @@ fallback:
"(Ljava/io/InputStream;)Ljava/nio/channels/ReadableByteChannel;"); "(Ljava/io/InputStream;)Ljava/nio/channels/ReadableByteChannel;");
readableByteChannel = (*mEnv)->CallStaticObjectMethod( readableByteChannel = (*mEnv)->CallStaticObjectMethod(
mEnv, channels, mid, inputStream); mEnv, channels, mid, inputStream);
if (Android_JNI_ExceptionOccurred(false)) { if (Android_JNI_ExceptionOccurred(SDL_FALSE)) {
goto failure; goto failure;
} }
@ -814,7 +822,7 @@ fallback:
ctx->hidden.androidio.readMethod = mid; ctx->hidden.androidio.readMethod = mid;
} }
if (false) { if (0) {
failure: failure:
result = -1; result = -1;
@ -907,7 +915,7 @@ size_t Android_JNI_FileRead(SDL_RWops* ctx, void* buffer,
/* result = readableByteChannel.read(...); */ /* result = readableByteChannel.read(...); */
int result = (*mEnv)->CallIntMethod(mEnv, readableByteChannel, readMethod, byteBuffer); int result = (*mEnv)->CallIntMethod(mEnv, readableByteChannel, readMethod, byteBuffer);
if (Android_JNI_ExceptionOccurred(false)) { if (Android_JNI_ExceptionOccurred(SDL_FALSE)) {
LocalReferenceHolder_Cleanup(&refs); LocalReferenceHolder_Cleanup(&refs);
return 0; return 0;
} }
@ -932,7 +940,7 @@ size_t Android_JNI_FileWrite(SDL_RWops* ctx, const void* buffer,
return 0; return 0;
} }
static int Internal_Android_JNI_FileClose(SDL_RWops* ctx, bool release) static int Internal_Android_JNI_FileClose(SDL_RWops* ctx, SDL_bool release)
{ {
struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
@ -955,7 +963,7 @@ static int Internal_Android_JNI_FileClose(SDL_RWops* ctx, bool release)
"close", "()V"); "close", "()V");
(*mEnv)->CallVoidMethod(mEnv, inputStream, mid); (*mEnv)->CallVoidMethod(mEnv, inputStream, mid);
(*mEnv)->DeleteGlobalRef(mEnv, (jobject)ctx->hidden.androidio.assetFileDescriptorRef); (*mEnv)->DeleteGlobalRef(mEnv, (jobject)ctx->hidden.androidio.assetFileDescriptorRef);
if (Android_JNI_ExceptionOccurred(false)) { if (Android_JNI_ExceptionOccurred(SDL_FALSE)) {
result = -1; result = -1;
} }
} }
@ -968,7 +976,7 @@ static int Internal_Android_JNI_FileClose(SDL_RWops* ctx, bool release)
(*mEnv)->CallVoidMethod(mEnv, inputStream, mid); (*mEnv)->CallVoidMethod(mEnv, inputStream, mid);
(*mEnv)->DeleteGlobalRef(mEnv, (jobject)ctx->hidden.androidio.inputStreamRef); (*mEnv)->DeleteGlobalRef(mEnv, (jobject)ctx->hidden.androidio.inputStreamRef);
(*mEnv)->DeleteGlobalRef(mEnv, (jobject)ctx->hidden.androidio.readableByteChannelRef); (*mEnv)->DeleteGlobalRef(mEnv, (jobject)ctx->hidden.androidio.readableByteChannelRef);
if (Android_JNI_ExceptionOccurred(false)) { if (Android_JNI_ExceptionOccurred(SDL_FALSE)) {
result = -1; result = -1;
} }
} }
@ -1059,7 +1067,7 @@ Sint64 Android_JNI_FileSeek(SDL_RWops* ctx, Sint64 offset, int whence)
} else if (movement < 0) { } else if (movement < 0) {
/* We can't seek backwards so we have to reopen the file and seek */ /* We can't seek backwards so we have to reopen the file and seek */
/* forwards which obviously isn't very efficient */ /* forwards which obviously isn't very efficient */
Internal_Android_JNI_FileClose(ctx, false); Internal_Android_JNI_FileClose(ctx, SDL_FALSE);
Internal_Android_JNI_FileOpen(ctx); Internal_Android_JNI_FileOpen(ctx);
Android_JNI_FileSeek(ctx, newPosition, RW_SEEK_SET); Android_JNI_FileSeek(ctx, newPosition, RW_SEEK_SET);
} }
@ -1071,7 +1079,7 @@ Sint64 Android_JNI_FileSeek(SDL_RWops* ctx, Sint64 offset, int whence)
int Android_JNI_FileClose(SDL_RWops* ctx) int Android_JNI_FileClose(SDL_RWops* ctx)
{ {
return Internal_Android_JNI_FileClose(ctx, true); return Internal_Android_JNI_FileClose(ctx, SDL_TRUE);
} }
/* returns a new global reference which needs to be released later */ /* returns a new global reference which needs to be released later */
@ -1602,6 +1610,11 @@ const char * SDL_AndroidGetExternalStoragePath()
return s_AndroidExternalFilesPath; return s_AndroidExternalFilesPath;
} }
jclass Android_JNI_GetActivityClass(void)
{
return mActivityClass;
}
#endif /* __ANDROID__ */ #endif /* __ANDROID__ */
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */

View File

@ -78,6 +78,7 @@ int Android_JNI_GetTouchDeviceIds(int **ids);
#include <jni.h> #include <jni.h>
JNIEnv *Android_JNI_GetEnv(void); JNIEnv *Android_JNI_GetEnv(void);
int Android_JNI_SetupThread(void); int Android_JNI_SetupThread(void);
jclass Android_JNI_GetActivityClass(void);
/* Generic messages */ /* Generic messages */
int Android_JNI_SendMessage(int command, int param); int Android_JNI_SendMessage(int command, int param);

View File

@ -681,10 +681,10 @@ SDL_EVDEV_Poll(void)
SDL_SendMouseMotion(mouse->focus, mouse->mouseID, SDL_TRUE, 0, events[i].value); SDL_SendMouseMotion(mouse->focus, mouse->mouseID, SDL_TRUE, 0, events[i].value);
break; break;
case REL_WHEEL: case REL_WHEEL:
SDL_SendMouseWheel(mouse->focus, mouse->mouseID, 0, events[i].value); SDL_SendMouseWheel(mouse->focus, mouse->mouseID, 0, events[i].value, SDL_MOUSEWHEEL_NORMAL);
break; break;
case REL_HWHEEL: case REL_HWHEEL:
SDL_SendMouseWheel(mouse->focus, mouse->mouseID, events[i].value, 0); SDL_SendMouseWheel(mouse->focus, mouse->mouseID, events[i].value, 0, SDL_MOUSEWHEEL_NORMAL);
break; break;
default: default:
break; break;

View File

@ -462,6 +462,9 @@ SDL_IBus_Init(void)
ibus_addr_file = SDL_strdup(addr_file); ibus_addr_file = SDL_strdup(addr_file);
addr = IBus_ReadAddressFromFile(addr_file); addr = IBus_ReadAddressFromFile(addr_file);
if (!addr) {
return SDL_FALSE;
}
if (inotify_fd < 0) { if (inotify_fd < 0) {
inotify_fd = inotify_init(); inotify_fd = inotify_init();
@ -476,8 +479,10 @@ SDL_IBus_Init(void)
inotify_wd = inotify_add_watch(inotify_fd, addr_file, IN_CREATE | IN_MODIFY); inotify_wd = inotify_add_watch(inotify_fd, addr_file, IN_CREATE | IN_MODIFY);
SDL_free(addr_file); SDL_free(addr_file);
result = IBus_SetupConnection(dbus, addr); if (addr) {
SDL_free(addr); result = IBus_SetupConnection(dbus, addr);
SDL_free(addr);
}
} }
return result; return result;

View File

@ -350,17 +350,19 @@ guess_device_class(struct udev_device *dev)
devclass |= SDL_UDEV_DEVICE_MOUSE; /* ID_INPUT_MOUSE */ devclass |= SDL_UDEV_DEVICE_MOUSE; /* ID_INPUT_MOUSE */
} else if (test_bit(BTN_TOUCH, bitmask_key)) { } else if (test_bit(BTN_TOUCH, bitmask_key)) {
; /* ID_INPUT_TOUCHSCREEN */ ; /* ID_INPUT_TOUCHSCREEN */
} else if (test_bit(BTN_TRIGGER, bitmask_key) || }
test_bit(BTN_A, bitmask_key) ||
test_bit(BTN_1, bitmask_key) || if (test_bit(BTN_TRIGGER, bitmask_key) ||
test_bit(ABS_RX, bitmask_abs) || test_bit(BTN_A, bitmask_key) ||
test_bit(ABS_RY, bitmask_abs) || test_bit(BTN_1, bitmask_key) ||
test_bit(ABS_RZ, bitmask_abs) || test_bit(ABS_RX, bitmask_abs) ||
test_bit(ABS_THROTTLE, bitmask_abs) || test_bit(ABS_RY, bitmask_abs) ||
test_bit(ABS_RUDDER, bitmask_abs) || test_bit(ABS_RZ, bitmask_abs) ||
test_bit(ABS_WHEEL, bitmask_abs) || test_bit(ABS_THROTTLE, bitmask_abs) ||
test_bit(ABS_GAS, bitmask_abs) || test_bit(ABS_RUDDER, bitmask_abs) ||
test_bit(ABS_BRAKE, bitmask_abs)) { test_bit(ABS_WHEEL, bitmask_abs) ||
test_bit(ABS_GAS, bitmask_abs) ||
test_bit(ABS_BRAKE, bitmask_abs)) {
devclass |= SDL_UDEV_DEVICE_JOYSTICK; /* ID_INPUT_JOYSTICK */ devclass |= SDL_UDEV_DEVICE_JOYSTICK; /* ID_INPUT_JOYSTICK */
} }
} }
@ -371,10 +373,10 @@ guess_device_class(struct udev_device *dev)
devclass |= SDL_UDEV_DEVICE_MOUSE; /* ID_INPUT_MOUSE */ devclass |= SDL_UDEV_DEVICE_MOUSE; /* ID_INPUT_MOUSE */
} }
/* the first 32 bits are ESC, numbers, and Q to D; if we have all of /* the first 32 bits are ESC, numbers, and Q to D; if we have any of
* those, consider it a full keyboard; do not test KEY_RESERVED, though */ * those, consider it a keyboard device; do not test KEY_RESERVED, though */
keyboard_mask = 0xFFFFFFFE; keyboard_mask = 0xFFFFFFFE;
if ((bitmask_key[0] & keyboard_mask) == keyboard_mask) if ((bitmask_key[0] & keyboard_mask) != 0)
devclass |= SDL_UDEV_DEVICE_KEYBOARD; /* ID_INPUT_KEYBOARD */ devclass |= SDL_UDEV_DEVICE_KEYBOARD; /* ID_INPUT_KEYBOARD */
return devclass; return devclass;

View File

@ -126,6 +126,16 @@ static void WINRT_SetDisplayOrientationsPreference(void *userdata, const char *n
{ {
SDL_assert(SDL_strcmp(name, SDL_HINT_ORIENTATIONS) == 0); SDL_assert(SDL_strcmp(name, SDL_HINT_ORIENTATIONS) == 0);
/* HACK: prevent SDL from altering an app's .appxmanifest-set orientation
* from being changed on startup, by detecting when SDL_HINT_ORIENTATIONS
* is getting registered.
*
* TODO, WinRT: consider reading in an app's .appxmanifest file, and apply its orientation when 'newValue == NULL'.
*/
if ((oldValue == NULL) && (newValue == NULL)) {
return;
}
// Start with no orientation flags, then add each in as they're parsed // Start with no orientation flags, then add each in as they're parsed
// from newValue. // from newValue.
unsigned int orientationFlags = 0; unsigned int orientationFlags = 0;

View File

@ -23,7 +23,7 @@
#ifndef _SDL_winrtapp_xaml_h #ifndef _SDL_winrtapp_xaml_h
#define _SDL_winrtapp_xaml_h #define _SDL_winrtapp_xaml_h
#include "SDL_types.h" #include "SDL_stdinc.h"
#ifdef __cplusplus #ifdef __cplusplus
extern SDL_bool WINRT_XAMLWasEnabled; extern SDL_bool WINRT_XAMLWasEnabled;

View File

@ -79,6 +79,7 @@ CPU_haveCPUID(void)
{ {
int has_CPUID = 0; int has_CPUID = 0;
/* *INDENT-OFF* */ /* *INDENT-OFF* */
#ifndef SDL_CPUINFO_DISABLED
#if defined(__GNUC__) && defined(i386) #if defined(__GNUC__) && defined(i386)
__asm__ ( __asm__ (
" pushfl # Get original EFLAGS \n" " pushfl # Get original EFLAGS \n"
@ -165,6 +166,7 @@ done:
"1: \n" "1: \n"
); );
#endif #endif
#endif
/* *INDENT-ON* */ /* *INDENT-ON* */
return has_CPUID; return has_CPUID;
} }
@ -272,6 +274,7 @@ static int
CPU_haveAltiVec(void) CPU_haveAltiVec(void)
{ {
volatile int altivec = 0; volatile int altivec = 0;
#ifndef SDL_CPUINFO_DISABLED
#if (defined(__MACOSX__) && (defined(__ppc__) || defined(__ppc64__))) || (defined(__OpenBSD__) && defined(__powerpc__)) #if (defined(__MACOSX__) && (defined(__ppc__) || defined(__ppc64__))) || (defined(__OpenBSD__) && defined(__powerpc__))
#ifdef __OpenBSD__ #ifdef __OpenBSD__
int selectors[2] = { CTL_MACHDEP, CPU_ALTIVEC }; int selectors[2] = { CTL_MACHDEP, CPU_ALTIVEC };
@ -291,6 +294,7 @@ CPU_haveAltiVec(void)
altivec = 1; altivec = 1;
} }
signal(SIGILL, handler); signal(SIGILL, handler);
#endif
#endif #endif
return altivec; return altivec;
} }
@ -418,6 +422,7 @@ int
SDL_GetCPUCount(void) SDL_GetCPUCount(void)
{ {
if (!SDL_CPUCount) { if (!SDL_CPUCount) {
#ifndef SDL_CPUINFO_DISABLED
#if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN) #if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
if (SDL_CPUCount <= 0) { if (SDL_CPUCount <= 0) {
SDL_CPUCount = (int)sysconf(_SC_NPROCESSORS_ONLN); SDL_CPUCount = (int)sysconf(_SC_NPROCESSORS_ONLN);
@ -435,6 +440,7 @@ SDL_GetCPUCount(void)
GetSystemInfo(&info); GetSystemInfo(&info);
SDL_CPUCount = info.dwNumberOfProcessors; SDL_CPUCount = info.dwNumberOfProcessors;
} }
#endif
#endif #endif
/* There has to be at least 1, right? :) */ /* There has to be at least 1, right? :) */
if (SDL_CPUCount <= 0) { if (SDL_CPUCount <= 0) {
@ -452,10 +458,11 @@ SDL_GetCPUType(void)
if (!SDL_CPUType[0]) { if (!SDL_CPUType[0]) {
int i = 0; int i = 0;
int a, b, c, d;
if (CPU_haveCPUID()) { if (CPU_haveCPUID()) {
int a, b, c, d;
cpuid(0x00000000, a, b, c, d); cpuid(0x00000000, a, b, c, d);
(void) a;
SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8; SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8;
SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8; SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8;
SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8; SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8;
@ -557,15 +564,12 @@ int
SDL_GetCPUCacheLineSize(void) SDL_GetCPUCacheLineSize(void)
{ {
const char *cpuType = SDL_GetCPUType(); const char *cpuType = SDL_GetCPUType();
int a, b, c, d;
(void) a; (void) b; (void) c; (void) d;
if (SDL_strcmp(cpuType, "GenuineIntel") == 0) { if (SDL_strcmp(cpuType, "GenuineIntel") == 0) {
int a, b, c, d;
cpuid(0x00000001, a, b, c, d); cpuid(0x00000001, a, b, c, d);
return (((b >> 8) & 0xff) * 8); return (((b >> 8) & 0xff) * 8);
} else if (SDL_strcmp(cpuType, "AuthenticAMD") == 0) { } else if (SDL_strcmp(cpuType, "AuthenticAMD") == 0) {
int a, b, c, d;
cpuid(0x80000005, a, b, c, d); cpuid(0x80000005, a, b, c, d);
return (c & 0xff); return (c & 0xff);
} else { } else {
@ -723,6 +727,7 @@ int
SDL_GetSystemRAM(void) SDL_GetSystemRAM(void)
{ {
if (!SDL_SystemRAM) { if (!SDL_SystemRAM) {
#ifndef SDL_CPUINFO_DISABLED
#if defined(HAVE_SYSCONF) && defined(_SC_PHYS_PAGES) && defined(_SC_PAGESIZE) #if defined(HAVE_SYSCONF) && defined(_SC_PHYS_PAGES) && defined(_SC_PAGESIZE)
if (SDL_SystemRAM <= 0) { if (SDL_SystemRAM <= 0) {
SDL_SystemRAM = (int)((Sint64)sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE) / (1024*1024)); SDL_SystemRAM = (int)((Sint64)sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE) / (1024*1024));
@ -756,6 +761,7 @@ SDL_GetSystemRAM(void)
SDL_SystemRAM = (int)(stat.ullTotalPhys / (1024 * 1024)); SDL_SystemRAM = (int)(stat.ullTotalPhys / (1024 * 1024));
} }
} }
#endif
#endif #endif
} }
return SDL_SystemRAM; return SDL_SystemRAM;

View File

@ -206,7 +206,14 @@ SDL_DYNAPI_entry(Uint32 apiver, void *table, Uint32 tablesize)
static SDL_INLINE void *get_sdlapi_entry(const char *fname, const char *sym) static SDL_INLINE void *get_sdlapi_entry(const char *fname, const char *sym)
{ {
HANDLE lib = LoadLibraryA(fname); HANDLE lib = LoadLibraryA(fname);
return lib ? GetProcAddress(lib, sym) : NULL; void *retval = NULL;
if (lib) {
retval = GetProcAddress(lib, sym);
if (retval == NULL) {
FreeLibrary(lib);
}
}
return retval;
} }
#elif defined(__HAIKU__) #elif defined(__HAIKU__)
@ -215,8 +222,11 @@ static SDL_INLINE void *get_sdlapi_entry(const char *fname, const char *sym)
{ {
image_id lib = load_add_on(fname); image_id lib = load_add_on(fname);
void *retval = NULL; void *retval = NULL;
if ((lib < 0) || (get_image_symbol(lib, sym, B_SYMBOL_TYPE_TEXT, &retval) != B_NO_ERROR)) { if (lib >= 0) {
retval = NULL; if (get_image_symbol(lib, sym, B_SYMBOL_TYPE_TEXT, &retval) != B_NO_ERROR) {
unload_add_on(lib);
retval = NULL;
}
} }
return retval; return retval;
} }
@ -225,7 +235,14 @@ static SDL_INLINE void *get_sdlapi_entry(const char *fname, const char *sym)
static SDL_INLINE void *get_sdlapi_entry(const char *fname, const char *sym) static SDL_INLINE void *get_sdlapi_entry(const char *fname, const char *sym)
{ {
void *lib = dlopen(fname, RTLD_NOW | RTLD_LOCAL); void *lib = dlopen(fname, RTLD_NOW | RTLD_LOCAL);
return lib ? dlsym(lib, sym) : NULL; void *retval = NULL;
if (lib != NULL) {
retval = dlsym(lib, sym);
if (retval == NULL) {
dlclose(lib);
}
}
return retval;
} }
#else #else
#error Please define your platform. #error Please define your platform.

View File

@ -43,13 +43,16 @@
#include "TargetConditionals.h" #include "TargetConditionals.h"
#endif #endif
#if TARGET_OS_IPHONE || __native_client__ /* probably not useful on iOS or NACL. */ #if TARGET_OS_IPHONE || __native_client__ || __EMSCRIPTEN__ /* probably not useful on iOS, NACL or Emscripten. */
#define SDL_DYNAMIC_API 0 #define SDL_DYNAMIC_API 0
#elif SDL_BUILDING_WINRT /* probaly not useful on WinRT, given current .dll loading restrictions */ #elif SDL_BUILDING_WINRT /* probaly not useful on WinRT, given current .dll loading restrictions */
#define SDL_DYNAMIC_API 0 #define SDL_DYNAMIC_API 0
#elif defined(__clang_analyzer__) #elif defined(__clang_analyzer__)
#define SDL_DYNAMIC_API 0 /* Turn off for static analysis, so reports are more clear. */ #define SDL_DYNAMIC_API 0 /* Turn off for static analysis, so reports are more clear. */
#else /* everyone else. */ #endif
/* everyone else. This is where we turn on the API if nothing forced it off. */
#ifndef SDL_DYNAMIC_API
#define SDL_DYNAMIC_API 1 #define SDL_DYNAMIC_API 1
#endif #endif

View File

@ -591,3 +591,4 @@
#define SDL_QueueAudio SDL_QueueAudio_REAL #define SDL_QueueAudio SDL_QueueAudio_REAL
#define SDL_GetQueuedAudioSize SDL_GetQueuedAudioSize_REAL #define SDL_GetQueuedAudioSize SDL_GetQueuedAudioSize_REAL
#define SDL_ClearQueuedAudio SDL_ClearQueuedAudio_REAL #define SDL_ClearQueuedAudio SDL_ClearQueuedAudio_REAL
#define SDL_GetGrabbedWindow SDL_GetGrabbedWindow_REAL

View File

@ -623,3 +623,4 @@ SDL_DYNAPI_PROC(SDL_bool,SDL_HasAVX2,(void),(),return)
SDL_DYNAPI_PROC(int,SDL_QueueAudio,(SDL_AudioDeviceID a, const void *b, Uint32 c),(a,b,c),return) SDL_DYNAPI_PROC(int,SDL_QueueAudio,(SDL_AudioDeviceID a, const void *b, Uint32 c),(a,b,c),return)
SDL_DYNAPI_PROC(Uint32,SDL_GetQueuedAudioSize,(SDL_AudioDeviceID a),(a),return) SDL_DYNAPI_PROC(Uint32,SDL_GetQueuedAudioSize,(SDL_AudioDeviceID a),(a),return)
SDL_DYNAPI_PROC(void,SDL_ClearQueuedAudio,(SDL_AudioDeviceID a),(a),) SDL_DYNAPI_PROC(void,SDL_ClearQueuedAudio,(SDL_AudioDeviceID a),(a),)
SDL_DYNAPI_PROC(SDL_Window*,SDL_GetGrabbedWindow,(void),(),return)

View File

@ -75,12 +75,13 @@ static struct
SDL_mutex *lock; SDL_mutex *lock;
volatile SDL_bool active; volatile SDL_bool active;
volatile int count; volatile int count;
volatile int max_events_seen;
SDL_EventEntry *head; SDL_EventEntry *head;
SDL_EventEntry *tail; SDL_EventEntry *tail;
SDL_EventEntry *free; SDL_EventEntry *free;
SDL_SysWMEntry *wmmsg_used; SDL_SysWMEntry *wmmsg_used;
SDL_SysWMEntry *wmmsg_free; SDL_SysWMEntry *wmmsg_free;
} SDL_EventQ = { NULL, SDL_TRUE }; } SDL_EventQ = { NULL, SDL_TRUE, 0, 0, NULL, NULL, NULL, NULL, NULL };
/* Public functions */ /* Public functions */
@ -88,6 +89,7 @@ static struct
void void
SDL_StopEventLoop(void) SDL_StopEventLoop(void)
{ {
const char *report = SDL_GetHint("SDL_EVENT_QUEUE_STATISTICS");
int i; int i;
SDL_EventEntry *entry; SDL_EventEntry *entry;
SDL_SysWMEntry *wmmsg; SDL_SysWMEntry *wmmsg;
@ -98,6 +100,11 @@ SDL_StopEventLoop(void)
SDL_EventQ.active = SDL_FALSE; SDL_EventQ.active = SDL_FALSE;
if (report && SDL_atoi(report)) {
SDL_Log("SDL EVENT QUEUE: Maximum events in-flight: %d\n",
SDL_EventQ.max_events_seen);
}
/* Clean out EventQ */ /* Clean out EventQ */
for (entry = SDL_EventQ.head; entry; ) { for (entry = SDL_EventQ.head; entry; ) {
SDL_EventEntry *next = entry->next; SDL_EventEntry *next = entry->next;
@ -119,7 +126,9 @@ SDL_StopEventLoop(void)
SDL_free(wmmsg); SDL_free(wmmsg);
wmmsg = next; wmmsg = next;
} }
SDL_EventQ.count = 0; SDL_EventQ.count = 0;
SDL_EventQ.max_events_seen = 0;
SDL_EventQ.head = NULL; SDL_EventQ.head = NULL;
SDL_EventQ.tail = NULL; SDL_EventQ.tail = NULL;
SDL_EventQ.free = NULL; SDL_EventQ.free = NULL;
@ -218,6 +227,10 @@ SDL_AddEvent(SDL_Event * event)
} }
++SDL_EventQ.count; ++SDL_EventQ.count;
if (SDL_EventQ.count > SDL_EventQ.max_events_seen) {
SDL_EventQ.max_events_seen = SDL_EventQ.count;
}
return 1; return 1;
} }

View File

@ -24,6 +24,7 @@
/* General mouse handling code for SDL */ /* General mouse handling code for SDL */
#include "SDL_events.h" #include "SDL_events.h"
#include "SDL_endian.h"
#include "SDL_events_c.h" #include "SDL_events_c.h"
#include "SDL_gesture_c.h" #include "SDL_gesture_c.h"
@ -114,14 +115,34 @@ static unsigned long SDL_HashDollar(SDL_FloatPoint* points)
static int SaveTemplate(SDL_DollarTemplate *templ, SDL_RWops *dst) static int SaveTemplate(SDL_DollarTemplate *templ, SDL_RWops *dst)
{ {
if (dst == NULL) return 0; if (dst == NULL) {
return 0;
}
/* No Longer storing the Hash, rehash on load */ /* No Longer storing the Hash, rehash on load */
/* if (SDL_RWops.write(dst, &(templ->hash), sizeof(templ->hash), 1) != 1) return 0; */ /* if (SDL_RWops.write(dst, &(templ->hash), sizeof(templ->hash), 1) != 1) return 0; */
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
if (SDL_RWwrite(dst, templ->path, if (SDL_RWwrite(dst, templ->path,
sizeof(templ->path[0]),DOLLARNPOINTS) != DOLLARNPOINTS) sizeof(templ->path[0]),DOLLARNPOINTS) != DOLLARNPOINTS) {
return 0; return 0;
}
#else
{
SDL_DollarTemplate copy = *templ;
SDL_FloatPoint *p = copy.path;
int i;
for (i = 0; i < DOLLARNPOINTS; i++, p++) {
p->x = SDL_SwapFloatLE(p->x);
p->y = SDL_SwapFloatLE(p->y);
}
if (SDL_RWwrite(dst, copy.path,
sizeof(copy.path[0]),DOLLARNPOINTS) != DOLLARNPOINTS) {
return 0;
}
}
#endif
return 1; return 1;
} }
@ -184,7 +205,7 @@ static int SDL_AddDollarGesture(SDL_GestureTouch* inTouch, SDL_FloatPoint* path)
int index = -1; int index = -1;
int i = 0; int i = 0;
if (inTouch == NULL) { if (inTouch == NULL) {
if (SDL_numGestureTouches == 0) return -1; if (SDL_numGestureTouches == 0) return SDL_SetError("no gesture touch devices registered");
for (i = 0; i < SDL_numGestureTouches; i++) { for (i = 0; i < SDL_numGestureTouches; i++) {
inTouch = &SDL_gestureTouch[i]; inTouch = &SDL_gestureTouch[i];
index = SDL_AddDollarGesture_one(inTouch, path); index = SDL_AddDollarGesture_one(inTouch, path);
@ -203,17 +224,33 @@ int SDL_LoadDollarTemplates(SDL_TouchID touchId, SDL_RWops *src)
SDL_GestureTouch *touch = NULL; SDL_GestureTouch *touch = NULL;
if (src == NULL) return 0; if (src == NULL) return 0;
if (touchId >= 0) { if (touchId >= 0) {
for (i = 0; i < SDL_numGestureTouches; i++) for (i = 0; i < SDL_numGestureTouches; i++) {
if (SDL_gestureTouch[i].id == touchId) if (SDL_gestureTouch[i].id == touchId) {
touch = &SDL_gestureTouch[i]; touch = &SDL_gestureTouch[i];
if (touch == NULL) return -1; }
}
if (touch == NULL) {
return SDL_SetError("given touch id not found");
}
} }
while (1) { while (1) {
SDL_DollarTemplate templ; SDL_DollarTemplate templ;
if (SDL_RWread(src,templ.path,sizeof(templ.path[0]),DOLLARNPOINTS) < if (SDL_RWread(src,templ.path,sizeof(templ.path[0]),DOLLARNPOINTS) < DOLLARNPOINTS) {
DOLLARNPOINTS) break; if (loaded == 0) {
return SDL_SetError("could not read any dollar gesture from rwops");
}
break;
}
#if SDL_BYTEORDER != SDL_LIL_ENDIAN
for (i = 0; i < DOLLARNPOINTS; i++) {
SDL_FloatPoint *p = &templ.path[i];
p->x = SDL_SwapFloatLE(p->x);
p->y = SDL_SwapFloatLE(p->y);
}
#endif
if (touchId >= 0) { if (touchId >= 0) {
/* printf("Adding loaded gesture to 1 touch\n"); */ /* printf("Adding loaded gesture to 1 touch\n"); */

View File

@ -293,9 +293,14 @@ SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relativ
event.motion.yrel = yrel; event.motion.yrel = yrel;
posted = (SDL_PushEvent(&event) > 0); posted = (SDL_PushEvent(&event) > 0);
} }
/* Use unclamped values if we're getting events outside the window */ if (relative) {
mouse->last_x = x; mouse->last_x = mouse->x;
mouse->last_y = y; mouse->last_y = mouse->y;
} else {
/* Use unclamped values if we're getting events outside the window */
mouse->last_x = x;
mouse->last_y = y;
}
return posted; return posted;
} }
@ -303,10 +308,11 @@ static SDL_MouseClickState *GetMouseClickState(SDL_Mouse *mouse, Uint8 button)
{ {
if (button >= mouse->num_clickstates) { if (button >= mouse->num_clickstates) {
int i, count = button + 1; int i, count = button + 1;
mouse->clickstate = (SDL_MouseClickState *)SDL_realloc(mouse->clickstate, count * sizeof(*mouse->clickstate)); SDL_MouseClickState *clickstate = (SDL_MouseClickState *)SDL_realloc(mouse->clickstate, count * sizeof(*mouse->clickstate));
if (!mouse->clickstate) { if (!clickstate) {
return NULL; return NULL;
} }
mouse->clickstate = clickstate;
for (i = mouse->num_clickstates; i < count; ++i) { for (i = mouse->num_clickstates; i < count; ++i) {
SDL_zero(mouse->clickstate[i]); SDL_zero(mouse->clickstate[i]);
@ -397,7 +403,7 @@ SDL_SendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8
} }
int int
SDL_SendMouseWheel(SDL_Window * window, SDL_MouseID mouseID, int x, int y) SDL_SendMouseWheel(SDL_Window * window, SDL_MouseID mouseID, int x, int y, SDL_MouseWheelDirection direction)
{ {
SDL_Mouse *mouse = SDL_GetMouse(); SDL_Mouse *mouse = SDL_GetMouse();
int posted; int posted;
@ -419,6 +425,7 @@ SDL_SendMouseWheel(SDL_Window * window, SDL_MouseID mouseID, int x, int y)
event.wheel.which = mouseID; event.wheel.which = mouseID;
event.wheel.x = x; event.wheel.x = x;
event.wheel.y = y; event.wheel.y = y;
event.wheel.direction = (Uint32)direction;
posted = (SDL_PushEvent(&event) > 0); posted = (SDL_PushEvent(&event) > 0);
} }
return posted; return posted;

View File

@ -120,7 +120,7 @@ extern int SDL_SendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int rel
extern int SDL_SendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8 button); extern int SDL_SendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8 button);
/* Send a mouse wheel event */ /* Send a mouse wheel event */
extern int SDL_SendMouseWheel(SDL_Window * window, SDL_MouseID mouseID, int x, int y); extern int SDL_SendMouseWheel(SDL_Window * window, SDL_MouseID mouseID, int x, int y, SDL_MouseWheelDirection direction);
/* Shutdown the mouse subsystem */ /* Shutdown the mouse subsystem */
extern void SDL_MouseQuit(void); extern void SDL_MouseQuit(void);

View File

@ -19,6 +19,7 @@
3. This notice may not be removed or altered from any source distribution. 3. This notice may not be removed or altered from any source distribution.
*/ */
#include "../SDL_internal.h" #include "../SDL_internal.h"
#include "SDL_hints.h"
/* General quit handling code for SDL */ /* General quit handling code for SDL */
@ -30,6 +31,8 @@
#include "SDL_events_c.h" #include "SDL_events_c.h"
static SDL_bool disable_signals = SDL_FALSE;
#ifdef HAVE_SIGNAL_H #ifdef HAVE_SIGNAL_H
static void static void
SDL_HandleSIG(int sig) SDL_HandleSIG(int sig)
@ -43,8 +46,8 @@ SDL_HandleSIG(int sig)
#endif /* HAVE_SIGNAL_H */ #endif /* HAVE_SIGNAL_H */
/* Public functions */ /* Public functions */
int static int
SDL_QuitInit(void) SDL_QuitInit_Internal(void)
{ {
#ifdef HAVE_SIGACTION #ifdef HAVE_SIGACTION
struct sigaction action; struct sigaction action;
@ -80,11 +83,22 @@ SDL_QuitInit(void)
#endif /* HAVE_SIGNAL_H */ #endif /* HAVE_SIGNAL_H */
/* That's it! */ /* That's it! */
return (0); return 0;
} }
void int
SDL_QuitQuit(void) SDL_QuitInit(void)
{
const char *hint = SDL_GetHint(SDL_HINT_NO_SIGNAL_HANDLERS);
disable_signals = hint && (SDL_atoi(hint) == 1);
if (!disable_signals) {
return SDL_QuitInit_Internal();
}
return 0;
}
static void
SDL_QuitQuit_Internal(void)
{ {
#ifdef HAVE_SIGACTION #ifdef HAVE_SIGACTION
struct sigaction action; struct sigaction action;
@ -110,6 +124,14 @@ SDL_QuitQuit(void)
#endif /* HAVE_SIGNAL_H */ #endif /* HAVE_SIGNAL_H */
} }
void
SDL_QuitQuit(void)
{
if (!disable_signals) {
SDL_QuitQuit_Internal();
}
}
/* This function returns 1 if it's okay to close the application window */ /* This function returns 1 if it's okay to close the application window */
int int
SDL_SendQuit(void) SDL_SendQuit(void)

View File

@ -50,14 +50,13 @@ FILE* SDL_OpenFPFromBundleOrFallback(const char *file, const char *mode)
NSString* full_path_with_file_to_try = [resource_path stringByAppendingPathComponent:ns_string_file_component]; NSString* full_path_with_file_to_try = [resource_path stringByAppendingPathComponent:ns_string_file_component];
if([file_manager fileExistsAtPath:full_path_with_file_to_try]) { if([file_manager fileExistsAtPath:full_path_with_file_to_try]) {
fp = fopen([full_path_with_file_to_try fileSystemRepresentation], mode); fp = fopen([full_path_with_file_to_try fileSystemRepresentation], mode);
} } else {
else {
fp = fopen(file, mode); fp = fopen(file, mode);
} }
return fp; return fp;
}} }}
#endif /* __MACOSX__ */ #endif /* __APPLE__ */
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */

View File

@ -41,6 +41,7 @@ SDL_GetBasePath(void)
const char* baseType = [[[bundle infoDictionary] objectForKey:@"SDL_FILESYSTEM_BASE_DIR_TYPE"] UTF8String]; const char* baseType = [[[bundle infoDictionary] objectForKey:@"SDL_FILESYSTEM_BASE_DIR_TYPE"] UTF8String];
const char *base = NULL; const char *base = NULL;
char *retval = NULL; char *retval = NULL;
if (baseType == NULL) { if (baseType == NULL) {
baseType = "resource"; baseType = "resource";
} }
@ -52,6 +53,7 @@ SDL_GetBasePath(void)
/* this returns the exedir for non-bundled and the resourceDir for bundled apps */ /* this returns the exedir for non-bundled and the resourceDir for bundled apps */
base = [[bundle resourcePath] fileSystemRepresentation]; base = [[bundle resourcePath] fileSystemRepresentation];
} }
if (base) { if (base) {
const size_t len = SDL_strlen(base) + 2; const size_t len = SDL_strlen(base) + 2;
retval = (char *) SDL_malloc(len); retval = (char *) SDL_malloc(len);
@ -69,9 +71,10 @@ char *
SDL_GetPrefPath(const char *org, const char *app) SDL_GetPrefPath(const char *org, const char *app)
{ @autoreleasepool { @autoreleasepool
{ {
NSArray *array = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
char *retval = NULL; char *retval = NULL;
NSArray *array = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
if ([array count] > 0) { /* we only want the first item in the list. */ if ([array count] > 0) { /* we only want the first item in the list. */
NSString *str = [array objectAtIndex:0]; NSString *str = [array objectAtIndex:0];
const char *base = [str fileSystemRepresentation]; const char *base = [str fileSystemRepresentation];

View File

@ -0,0 +1,69 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2014 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 SDL_FILESYSTEM_EMSCRIPTEN
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* System dependent filesystem routines */
#include <errno.h>
#include <sys/stat.h>
#include "SDL_error.h"
#include "SDL_filesystem.h"
#include <emscripten/emscripten.h>
char *
SDL_GetBasePath(void)
{
char *retval = "/";
return SDL_strdup(retval);
}
char *
SDL_GetPrefPath(const char *org, const char *app)
{
const char *append = "/libsdl/";
char *retval;
size_t len = 0;
len = SDL_strlen(append) + SDL_strlen(org) + SDL_strlen(app) + 3;
retval = (char *) SDL_malloc(len);
if (!retval) {
SDL_OutOfMemory();
return NULL;
}
SDL_snprintf(retval, len, "%s%s/%s/", append, org, app);
if (mkdir(retval, 0700) != 0 && errno != EEXIST) {
SDL_SetError("Couldn't create directory '%s': '%s'", retval, strerror(errno));
SDL_free(retval);
return NULL;
}
return retval;
}
#endif /* SDL_FILESYSTEM_EMSCRIPTEN */
/* vi: set ts=4 sw=4 expandtab: */

View File

@ -38,4 +38,5 @@ SDL_GetPrefPath(const char *org, const char *app)
return NULL; return NULL;
} }
#endif /* __NACL__ */ #endif /* SDL_FILESYSTEM_NACL */

View File

@ -27,12 +27,6 @@
#include "SDL_haptic.h" #include "SDL_haptic.h"
/*
* Number of haptic devices on the system.
*/
extern Uint8 SDL_numhaptics;
struct haptic_effect struct haptic_effect
{ {
SDL_HapticEffect effect; /* The current event */ SDL_HapticEffect effect; /* The current event */

View File

@ -262,13 +262,13 @@ MacHaptic_MaybeAddDevice( io_object_t device )
CFSTR(kIOHIDPrimaryUsagePageKey)); CFSTR(kIOHIDPrimaryUsagePageKey));
if (refCF) { if (refCF) {
if (!CFNumberGetValue(refCF, kCFNumberLongType, &item->usagePage)) { if (!CFNumberGetValue(refCF, kCFNumberLongType, &item->usagePage)) {
SDL_SetError("Haptic: Recieving device's usage page."); SDL_SetError("Haptic: Receiving device's usage page.");
} }
refCF = CFDictionaryGetValue(hidProperties, refCF = CFDictionaryGetValue(hidProperties,
CFSTR(kIOHIDPrimaryUsageKey)); CFSTR(kIOHIDPrimaryUsageKey));
if (refCF) { if (refCF) {
if (!CFNumberGetValue(refCF, kCFNumberLongType, &item->usage)) { if (!CFNumberGetValue(refCF, kCFNumberLongType, &item->usage)) {
SDL_SetError("Haptic: Recieving device's usage."); SDL_SetError("Haptic: Receiving device's usage.");
} }
} }
} }
@ -551,7 +551,7 @@ SDL_SYS_HapticOpenFromService(SDL_Haptic * haptic, io_service_t service)
FFReleaseDevice(haptic->hwdata->device); FFReleaseDevice(haptic->hwdata->device);
creat_err: creat_err:
if (haptic->hwdata != NULL) { if (haptic->hwdata != NULL) {
free(haptic->hwdata); SDL_free(haptic->hwdata);
haptic->hwdata = NULL; haptic->hwdata = NULL;
} }
return -1; return -1;

View File

@ -288,8 +288,7 @@ MaybeAddDevice(const char *path)
} }
item->fname = SDL_strdup(path); item->fname = SDL_strdup(path);
if ( (item->fname == NULL) ) { if (item->fname == NULL) {
SDL_free(item->fname);
SDL_free(item); SDL_free(item);
return -1; return -1;
} }
@ -441,7 +440,7 @@ SDL_SYS_HapticOpenFromFD(SDL_Haptic * haptic, int fd)
open_err: open_err:
close(fd); close(fd);
if (haptic->hwdata != NULL) { if (haptic->hwdata != NULL) {
free(haptic->hwdata); SDL_free(haptic->hwdata);
haptic->hwdata = NULL; haptic->hwdata = NULL;
} }
return -1; return -1;
@ -959,7 +958,7 @@ SDL_SYS_HapticNewEffect(SDL_Haptic * haptic, struct haptic_effect *effect,
return 0; return 0;
new_effect_err: new_effect_err:
free(effect->hweffect); SDL_free(effect->hweffect);
effect->hweffect = NULL; effect->hweffect = NULL;
return -1; return -1;
} }

View File

@ -89,6 +89,7 @@ typedef struct _ControllerMapping_t
static ControllerMapping_t *s_pSupportedControllers = NULL; static ControllerMapping_t *s_pSupportedControllers = NULL;
static ControllerMapping_t *s_pXInputMapping = NULL; static ControllerMapping_t *s_pXInputMapping = NULL;
static ControllerMapping_t *s_pEmscriptenMapping = NULL;
/* The SDL game controller structure */ /* The SDL game controller structure */
struct _SDL_GameController struct _SDL_GameController
@ -263,7 +264,13 @@ ControllerMapping_t *SDL_PrivateGetControllerMapping(int device_index)
return s_pXInputMapping; return s_pXInputMapping;
} }
else else
#endif /* SDL_JOYSTICK_XINPUT */ #endif
#if defined(SDL_JOYSTICK_EMSCRIPTEN)
if (s_pEmscriptenMapping) {
return s_pEmscriptenMapping;
}
else
#endif
{ {
SDL_JoystickGUID jGUID = SDL_JoystickGetDeviceGUID(device_index); SDL_JoystickGUID jGUID = SDL_JoystickGetDeviceGUID(device_index);
return SDL_PrivateGetControllerMappingForGUID(&jGUID); return SDL_PrivateGetControllerMappingForGUID(&jGUID);
@ -668,6 +675,7 @@ SDL_GameControllerAddMapping(const char *mappingString)
SDL_JoystickGUID jGUID; SDL_JoystickGUID jGUID;
ControllerMapping_t *pControllerMapping; ControllerMapping_t *pControllerMapping;
SDL_bool is_xinput_mapping = SDL_FALSE; SDL_bool is_xinput_mapping = SDL_FALSE;
SDL_bool is_emscripten_mapping = SDL_FALSE;
if (!mappingString) { if (!mappingString) {
return SDL_InvalidParamError("mappingString"); return SDL_InvalidParamError("mappingString");
@ -680,6 +688,9 @@ SDL_GameControllerAddMapping(const char *mappingString)
if (!SDL_strcasecmp(pchGUID, "xinput")) { if (!SDL_strcasecmp(pchGUID, "xinput")) {
is_xinput_mapping = SDL_TRUE; is_xinput_mapping = SDL_TRUE;
} }
if (!SDL_strcasecmp(pchGUID, "emscripten")) {
is_emscripten_mapping = SDL_TRUE;
}
jGUID = SDL_JoystickGetGUIDFromString(pchGUID); jGUID = SDL_JoystickGetGUIDFromString(pchGUID);
SDL_free(pchGUID); SDL_free(pchGUID);
@ -715,6 +726,9 @@ SDL_GameControllerAddMapping(const char *mappingString)
if (is_xinput_mapping) { if (is_xinput_mapping) {
s_pXInputMapping = pControllerMapping; s_pXInputMapping = pControllerMapping;
} }
if (is_emscripten_mapping) {
s_pEmscriptenMapping = pControllerMapping;
}
pControllerMapping->guid = jGUID; pControllerMapping->guid = jGUID;
pControllerMapping->name = pchName; pControllerMapping->name = pchName;
pControllerMapping->mapping = pchMapping; pControllerMapping->mapping = pchMapping;

View File

@ -63,7 +63,9 @@ static const char *s_ControllerMappings [] =
"030000006d0400001ec2000020200000,Logitech F510 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,", "030000006d0400001ec2000020200000,Logitech F510 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,",
"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. */ "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,", "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,",
"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,platform:Linux,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,", "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,",
"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,",
"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,",
"030000004c0500006802000011010000,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,", "030000004c0500006802000011010000,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,",
"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,", "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,", "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,",
@ -73,9 +75,13 @@ static const char *s_ControllerMappings [] =
"030000005e0400008e02000010010000,X360 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,", "030000005e0400008e02000010010000,X360 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,",
"030000005e0400001907000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "030000005e0400001907000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"030000005e0400009102000007010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "030000005e0400009102000007010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"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 #endif
#if defined(__ANDROID__) #if defined(__ANDROID__)
"4e564944494120436f72706f72617469,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", "4e564944494120436f72706f72617469,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,",
#endif
#if defined(SDL_JOYSTICK_EMSCRIPTEN)
"emscripten,Standard Gamepad,a:b0,b:b1,back:b8,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b16,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,",
#endif #endif
NULL NULL
}; };

View File

@ -206,10 +206,6 @@ SDL_PrivateJoystickValid(SDL_Joystick * joystick)
valid = 1; valid = 1;
} }
if (joystick && joystick->closed) {
valid = 0;
}
return valid; return valid;
} }
@ -412,6 +408,7 @@ SDL_JoystickClose(SDL_Joystick * joystick)
} }
SDL_SYS_JoystickClose(joystick); SDL_SYS_JoystickClose(joystick);
joystick->hwdata = NULL;
joysticklist = SDL_joysticks; joysticklist = SDL_joysticks;
joysticklistprev = NULL; joysticklistprev = NULL;
@ -668,7 +665,7 @@ SDL_JoystickUpdate(void)
SDL_SYS_JoystickUpdate(joystick); SDL_SYS_JoystickUpdate(joystick);
if (joystick->closed && joystick->uncentered) { if (joystick->force_recentering) {
int i; int i;
/* Tell the app that everything is centered/unpressed... */ /* Tell the app that everything is centered/unpressed... */
@ -681,7 +678,7 @@ SDL_JoystickUpdate(void)
for (i = 0; i < joystick->nhats; i++) for (i = 0; i < joystick->nhats; i++)
SDL_PrivateJoystickHat(joystick, i, SDL_HAT_CENTERED); SDL_PrivateJoystickHat(joystick, i, SDL_HAT_CENTERED);
joystick->uncentered = SDL_FALSE; joystick->force_recentering = SDL_FALSE;
} }
SDL_updating_joystick = NULL; SDL_updating_joystick = NULL;

View File

@ -53,8 +53,7 @@ struct _SDL_Joystick
int ref_count; /* Reference count for multiple opens */ int ref_count; /* Reference count for multiple opens */
SDL_bool closed; /* SDL_TRUE if this device is no longer valid */ SDL_bool force_recentering; /* SDL_TRUE if this device needs to have its state reset to 0 */
SDL_bool uncentered; /* SDL_TRUE if this device needs to have its state reset to 0 */
struct _SDL_Joystick *next; /* pointer to next joystick we have allocated */ struct _SDL_Joystick *next; /* pointer to next joystick we have allocated */
}; };
@ -78,14 +77,14 @@ extern const char *SDL_SYS_JoystickNameForDeviceIndex(int device_index);
extern SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index); extern SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index);
/* Function to open a joystick for use. /* Function to open a joystick for use.
The joystick to open is specified by the index field of the joystick. The joystick to open is specified by the device index.
This should fill the nbuttons and naxes fields of the joystick structure. This should fill the nbuttons and naxes fields of the joystick structure.
It returns 0, or -1 if there is an error. It returns 0, or -1 if there is an error.
*/ */
extern int SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index); extern int SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index);
/* Function to query if the joystick is currently attached /* Function to query if the joystick is currently attached
* It returns 1 if attached, 0 otherwise. * It returns SDL_TRUE if attached, SDL_FALSE otherwise.
*/ */
extern SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick * joystick); extern SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick * joystick);

View File

@ -467,7 +467,7 @@ SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
} }
/* Function to open a joystick for use. /* Function to open a joystick for use.
The joystick to open is specified by the index field of the joystick. The joystick to open is specified by the device index.
This should fill the nbuttons and naxes fields of the joystick structure. This should fill the nbuttons and naxes fields of the joystick structure.
It returns 0, or -1 if there is an error. It returns 0, or -1 if there is an error.
*/ */
@ -495,10 +495,10 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
return (0); return (0);
} }
/* Function to determine is this joystick is attached to the system right now */ /* Function to determine if this joystick is attached to the system right now */
SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick) SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
{ {
return !joystick->closed && (joystick->hwdata != NULL); return joystick->hwdata != NULL;
} }
void void
@ -529,11 +529,6 @@ SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
void void
SDL_SYS_JoystickClose(SDL_Joystick * joystick) SDL_SYS_JoystickClose(SDL_Joystick * joystick)
{ {
if (joystick->hwdata) {
((SDL_joylist_item*)joystick->hwdata)->joystick = NULL;
joystick->hwdata = NULL;
}
joystick->closed = 1;
} }
/* Function to perform any system-specific joystick related cleanup */ /* Function to perform any system-specific joystick related cleanup */

Some files were not shown because too many files have changed in this diff Show More