1.1 --- a/CMakeLists.txt Sat Jan 24 23:58:07 2015 -0400
1.2 +++ b/CMakeLists.txt Mon Apr 06 15:26:37 2015 -0300
1.3 @@ -118,9 +118,9 @@
1.4 endif()
1.5
1.6 if (UNIX_OR_MAC_SYS AND NOT EMSCRIPTEN) # JavaScript does not yet have threading support, so disable pthreads when building for Emscripten.
1.7 - set(PTHREADS_ENABLED_BY_DEFAULT ON)
1.8 + set(SDL_PTHREADS_ENABLED_BY_DEFAULT ON)
1.9 else()
1.10 - set(PTHREADS_ENABLED_BY_DEFAULT OFF)
1.11 + set(SDL_PTHREADS_ENABLED_BY_DEFAULT OFF)
1.12 endif()
1.13
1.14 # Default option knobs
1.15 @@ -202,6 +202,7 @@
1.16
1.17 # All these ENABLED_BY_DEFAULT vars will default to ON if not specified, so
1.18 # you only need to have a platform override them if they are disabling.
1.19 +set(OPT_DEF_ASM TRUE)
1.20 if(EMSCRIPTEN)
1.21 # Set up default values for the currently supported set of subsystems:
1.22 # Emscripten/Javascript does not have assembly support, a dynamic library
1.23 @@ -212,12 +213,12 @@
1.24 set(SDL_THREADS_ENABLED_BY_DEFAULT OFF)
1.25 set(SDL_LOADSO_ENABLED_BY_DEFAULT OFF)
1.26 set(SDL_CPUINFO_ENABLED_BY_DEFAULT OFF)
1.27 - set(DLOPEN_ENABLED_BY_DEFAULT OFF)
1.28 + set(SDL_DLOPEN_ENABLED_BY_DEFAULT OFF)
1.29 endif()
1.30
1.31 set(SDL_SUBSYSTEMS
1.32 Atomic Audio Video Render Events Joystick Haptic Power Threads Timers
1.33 - File Loadso CPUinfo Filesystem)
1.34 + File Loadso CPUinfo Filesystem Dlopen)
1.35 foreach(_SUB ${SDL_SUBSYSTEMS})
1.36 string(TOUPPER ${_SUB} _OPT)
1.37 if (NOT DEFINED SDL_${_OPT}_ENABLED_BY_DEFAULT)
1.38 @@ -246,9 +247,9 @@
1.39 set_option(VIDEO_DUMMY "Use dummy video driver" ON)
1.40 set_option(VIDEO_OPENGL "Include OpenGL support" ON)
1.41 set_option(VIDEO_OPENGLES "Include OpenGL ES support" ON)
1.42 -set_option(PTHREADS "Use POSIX threads for multi-threading" ${PTHREADS_ENABLED_BY_DEFAULT})
1.43 +set_option(PTHREADS "Use POSIX threads for multi-threading" ${SDL_PTHREADS_ENABLED_BY_DEFAULT})
1.44 dep_option(PTHREADS_SEM "Use pthread semaphores" ON "PTHREADS" OFF)
1.45 -set_option(SDL_DLOPEN "Use dlopen for shared object loading" ${DLOPEN_ENABLED_BY_DEFAULT})
1.46 +set_option(SDL_DLOPEN "Use dlopen for shared object loading" ${SDL_DLOPEN_ENABLED_BY_DEFAULT})
1.47 set_option(OSS "Support the OSS audio API" ${UNIX_SYS})
1.48 set_option(ALSA "Support the ALSA audio API" ${UNIX_SYS})
1.49 dep_option(ALSA_SHARED "Dynamically load ALSA audio support" ON "ALSA" OFF)
1.50 @@ -266,7 +267,10 @@
1.51 set_option(INPUT_TSLIB "Use the Touchscreen library for input" ${UNIX_SYS})
1.52 set_option(VIDEO_X11 "Use X11 video driver" ${UNIX_SYS})
1.53 set_option(VIDEO_WAYLAND "Use Wayland video driver" ${UNIX_SYS})
1.54 +dep_option(WAYLAND_SHARED "Dynamically load Wayland support" ON "VIDEO_WAYLAND" OFF)
1.55 +dep_option(VIDEO_WAYLAND_QT_TOUCH "QtWayland server support for Wayland video driver" ON "VIDEO_WAYLAND" OFF)
1.56 set_option(VIDEO_MIR "Use Mir video driver" ${UNIX_SYS})
1.57 +dep_option(MIR_SHARED "Dynamically load Mir support" ON "VIDEO_MIR" OFF)
1.58 set_option(VIDEO_RPI "Use Raspberry Pi video driver" ${UNIX_SYS})
1.59 dep_option(X11_SHARED "Dynamically load X11 support" ON "VIDEO_X11" OFF)
1.60 set(SDL_X11_OPTIONS Xcursor Xinerama XInput Xrandr Xscrnsaver XShape Xvm)
1.61 @@ -585,7 +589,7 @@
1.62 set(CMAKE_REQUIRED_LIBRARIES m)
1.63 foreach(_FN
1.64 atan atan2 ceil copysign cos cosf fabs floor log pow scalbn sin
1.65 - sinf sqrt sqrtf tan tanf)
1.66 + sinf sqrt sqrtf tan tanf acos asin)
1.67 string(TOUPPER ${_FN} _UPPER)
1.68 set(_HAVEVAR "HAVE_${_UPPER}")
1.69 check_function_exists("${_FN}" ${_HAVEVAR})
1.70 @@ -597,6 +601,15 @@
1.71 check_library_exists(iconv iconv_open "" HAVE_LIBICONV)
1.72 if(HAVE_LIBICONV)
1.73 list(APPEND EXTRA_LIBS iconv)
1.74 + set(HAVE_ICONV 1)
1.75 + endif()
1.76 +
1.77 + if(NOT APPLE)
1.78 + check_include_file(alloca.h HAVE_ALLOCA_H)
1.79 + check_function_exists(alloca HAVE_ALLOCA)
1.80 + else()
1.81 + set(HAVE_ALLOCA_H 1)
1.82 + set(HAVE_ALLOCA 1)
1.83 endif()
1.84
1.85 check_struct_has_member("struct sigaction" "sa_sigaction" "signal.h" HAVE_SA_SIGACTION)
1.86 @@ -1140,10 +1153,6 @@
1.87 set(SDL_VIDEO_OPENGL 1)
1.88 set(SDL_VIDEO_OPENGL_CGL 1)
1.89 set(SDL_VIDEO_RENDER_OGL 1)
1.90 - if(DARWIN)
1.91 - find_library(OpenGL_LIBRARY OpenGL)
1.92 - list(APPEND EXTRA_LIBRARIES ${OpenGL_LIBRARY})
1.93 - endif()
1.94 set(HAVE_VIDEO_OPENGL TRUE)
1.95 endif()
1.96 endif()
2.1 --- a/SDL2.spec.in Sat Jan 24 23:58:07 2015 -0400
2.2 +++ b/SDL2.spec.in Mon Apr 06 15:26:37 2015 -0300
2.3 @@ -1,7 +1,7 @@
2.4 Summary: Simple DirectMedia Layer
2.5 Name: SDL2
2.6 Version: @SDL_VERSION@
2.7 -Release: 1
2.8 +Release: 2
2.9 Source: http://www.libsdl.org/release/%{name}-%{version}.tar.gz
2.10 URL: http://www.libsdl.org/
2.11 License: zlib
2.12 @@ -63,12 +63,12 @@
2.13
2.14 %files
2.15 %{__defattr}
2.16 -%doc README-SDL.txt COPYING.txt CREDITS.txt BUGS.txt
2.17 +%doc README*.txt COPYING.txt CREDITS.txt BUGS.txt
2.18 %{_libdir}/lib*.%{__soext}.*
2.19
2.20 %files devel
2.21 %{__defattr}
2.22 -%doc README README-SDL.txt COPYING CREDITS BUGS WhatsNew
2.23 +%doc README*.txt COPYING.txt CREDITS.txt BUGS.txt WhatsNew.txt
2.24 %{_bindir}/*-config
2.25 %{_libdir}/lib*.a
2.26 %{_libdir}/lib*.la
2.27 @@ -78,13 +78,16 @@
2.28 %{_datadir}/aclocal/*
2.29
2.30 %changelog
2.31 +* Sun Dec 07 2014 Simone Contini <s.contini@oltrelinux.com>
2.32 +- Fixed changelog date issue and docs filenames
2.33 +
2.34 * Sun Jan 22 2012 Sam Lantinga <slouken@libsdl.org>
2.35 - Updated for SDL 2.0
2.36
2.37 * Tue May 16 2006 Sam Lantinga <slouken@libsdl.org>
2.38 - Removed support for Darwin, due to build problems on ps2linux
2.39
2.40 -* Mon Jan 03 2004 Anders Bjorklund <afb@algonet.se>
2.41 +* Sat Jan 03 2004 Anders Bjorklund <afb@algonet.se>
2.42 - Added support for Darwin, updated spec file
2.43
2.44 * Wed Jan 19 2000 Sam Lantinga <slouken@libsdl.org>
3.1 --- a/android-project/src/org/libsdl/app/SDLActivity.java Sat Jan 24 23:58:07 2015 -0400
3.2 +++ b/android-project/src/org/libsdl/app/SDLActivity.java Mon Apr 06 15:26:37 2015 -0300
3.3 @@ -41,6 +41,10 @@
3.4 /** If shared libraries (e.g. SDL or the native application) could not be loaded. */
3.5 public static boolean mBrokenLibraries;
3.6
3.7 + // If we want to separate mouse and touch events.
3.8 + // This is only toggled in native code when a hint is set!
3.9 + public static boolean mSeparateMouseAndTouch;
3.10 +
3.11 // Main components
3.12 protected static SDLActivity mSingleton;
3.13 protected static SDLSurface mSurface;
3.14 @@ -81,7 +85,6 @@
3.15 }
3.16
3.17 /**
3.18 - * This method is called by SDL using JNI.
3.19 * This method is called by SDL before starting the native application thread.
3.20 * It can be overridden to provide the arguments after the application name.
3.21 * The default implementation returns an empty array. It never returns null.
3.22 @@ -402,6 +405,7 @@
3.23 public static native void onNativeKeyDown(int keycode);
3.24 public static native void onNativeKeyUp(int keycode);
3.25 public static native void onNativeKeyboardFocusLost();
3.26 + public static native void onNativeMouse(int button, int action, float x, float y);
3.27 public static native void onNativeTouch(int touchDevId, int pointerFingerId,
3.28 int action, float x,
3.29 float y, float p);
3.30 @@ -1088,8 +1092,8 @@
3.31 // Dispatch the different events depending on where they come from
3.32 // Some SOURCE_DPAD or SOURCE_GAMEPAD are also SOURCE_KEYBOARD
3.33 // So, we try to process them as DPAD or GAMEPAD events first, if that fails we try them as KEYBOARD
3.34 -
3.35 - if ( (event.getSource() & 0x00000401) != 0 || /* API 12: SOURCE_GAMEPAD */
3.36 +
3.37 + if ( (event.getSource() & InputDevice.SOURCE_GAMEPAD) != 0 ||
3.38 (event.getSource() & InputDevice.SOURCE_DPAD) != 0 ) {
3.39 if (event.getAction() == KeyEvent.ACTION_DOWN) {
3.40 if (SDLActivity.onNativePadDown(event.getDeviceId(), keyCode) == 0) {
3.41 @@ -1126,50 +1130,65 @@
3.42 final int pointerCount = event.getPointerCount();
3.43 int action = event.getActionMasked();
3.44 int pointerFingerId;
3.45 + int mouseButton;
3.46 int i = -1;
3.47 float x,y,p;
3.48 -
3.49 - switch(action) {
3.50 - case MotionEvent.ACTION_MOVE:
3.51 - for (i = 0; i < pointerCount; i++) {
3.52 +
3.53 + // !!! FIXME: dump this SDK check after 2.0.4 ships and require API14.
3.54 + if (event.getSource() == InputDevice.SOURCE_MOUSE && SDLActivity.mSeparateMouseAndTouch) {
3.55 + if (Build.VERSION.SDK_INT < 14) {
3.56 + mouseButton = 1; // For Android==12 all mouse buttons are the left button
3.57 + } else {
3.58 + try {
3.59 + mouseButton = (Integer) event.getClass().getMethod("getButtonState").invoke(event);
3.60 + } catch(Exception e) {
3.61 + mouseButton = 1; // oh well.
3.62 + }
3.63 + }
3.64 + SDLActivity.onNativeMouse(mouseButton, action, event.getX(0), event.getY(0));
3.65 + } else {
3.66 + switch(action) {
3.67 + case MotionEvent.ACTION_MOVE:
3.68 + for (i = 0; i < pointerCount; i++) {
3.69 + pointerFingerId = event.getPointerId(i);
3.70 + x = event.getX(i) / mWidth;
3.71 + y = event.getY(i) / mHeight;
3.72 + p = event.getPressure(i);
3.73 + SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, p);
3.74 + }
3.75 + break;
3.76 +
3.77 + case MotionEvent.ACTION_UP:
3.78 + case MotionEvent.ACTION_DOWN:
3.79 + // Primary pointer up/down, the index is always zero
3.80 + i = 0;
3.81 + case MotionEvent.ACTION_POINTER_UP:
3.82 + case MotionEvent.ACTION_POINTER_DOWN:
3.83 + // Non primary pointer up/down
3.84 + if (i == -1) {
3.85 + i = event.getActionIndex();
3.86 + }
3.87 +
3.88 pointerFingerId = event.getPointerId(i);
3.89 x = event.getX(i) / mWidth;
3.90 y = event.getY(i) / mHeight;
3.91 p = event.getPressure(i);
3.92 SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, p);
3.93 - }
3.94 - break;
3.95 -
3.96 - case MotionEvent.ACTION_UP:
3.97 - case MotionEvent.ACTION_DOWN:
3.98 - // Primary pointer up/down, the index is always zero
3.99 - i = 0;
3.100 - case MotionEvent.ACTION_POINTER_UP:
3.101 - case MotionEvent.ACTION_POINTER_DOWN:
3.102 - // Non primary pointer up/down
3.103 - if (i == -1) {
3.104 - i = event.getActionIndex();
3.105 - }
3.106 + break;
3.107
3.108 - pointerFingerId = event.getPointerId(i);
3.109 - x = event.getX(i) / mWidth;
3.110 - y = event.getY(i) / mHeight;
3.111 - p = event.getPressure(i);
3.112 - SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, p);
3.113 - break;
3.114 -
3.115 - case MotionEvent.ACTION_CANCEL:
3.116 - for (i = 0; i < pointerCount; i++) {
3.117 - pointerFingerId = event.getPointerId(i);
3.118 - x = event.getX(i) / mWidth;
3.119 - y = event.getY(i) / mHeight;
3.120 - p = event.getPressure(i);
3.121 - SDLActivity.onNativeTouch(touchDevId, pointerFingerId, MotionEvent.ACTION_UP, x, y, p);
3.122 - }
3.123 - break;
3.124 + case MotionEvent.ACTION_CANCEL:
3.125 + for (i = 0; i < pointerCount; i++) {
3.126 + pointerFingerId = event.getPointerId(i);
3.127 + x = event.getX(i) / mWidth;
3.128 + y = event.getY(i) / mHeight;
3.129 + p = event.getPressure(i);
3.130 + SDLActivity.onNativeTouch(touchDevId, pointerFingerId, MotionEvent.ACTION_UP, x, y, p);
3.131 + }
3.132 + break;
3.133
3.134 - default:
3.135 - break;
3.136 + default:
3.137 + break;
3.138 + }
3.139 }
3.140
3.141 return true;
3.142 @@ -1500,9 +1519,44 @@
3.143
3.144 class SDLGenericMotionListener_API12 implements View.OnGenericMotionListener {
3.145 // Generic Motion (mouse hover, joystick...) events go here
3.146 - // We only have joysticks yet
3.147 @Override
3.148 public boolean onGenericMotion(View v, MotionEvent event) {
3.149 - return SDLActivity.handleJoystickMotionEvent(event);
3.150 + float x, y;
3.151 + int mouseButton;
3.152 + int action;
3.153 +
3.154 + switch ( event.getSource() ) {
3.155 + case InputDevice.SOURCE_JOYSTICK:
3.156 + case InputDevice.SOURCE_GAMEPAD:
3.157 + case InputDevice.SOURCE_DPAD:
3.158 + SDLActivity.handleJoystickMotionEvent(event);
3.159 + return true;
3.160 +
3.161 + case InputDevice.SOURCE_MOUSE:
3.162 + action = event.getActionMasked();
3.163 + switch(event.getActionMasked()) {
3.164 + case MotionEvent.ACTION_SCROLL:
3.165 + x = event.getAxisValue(MotionEvent.AXIS_HSCROLL, 0);
3.166 + y = event.getAxisValue(MotionEvent.AXIS_VSCROLL, 0);
3.167 + SDLActivity.onNativeMouse(0, action, x, y);
3.168 + return true;
3.169 +
3.170 + case MotionEvent.ACTION_HOVER_MOVE:
3.171 + x = event.getX(0);
3.172 + y = event.getY(0);
3.173 +
3.174 + SDLActivity.onNativeMouse(0, action, x, y);
3.175 + return true;
3.176 +
3.177 + default:
3.178 + break;
3.179 + }
3.180 +
3.181 + default:
3.182 + break;
3.183 + }
3.184 +
3.185 + // Event was not managed
3.186 + return false;
3.187 }
3.188 }
4.1 --- a/cmake/sdlchecks.cmake Sat Jan 24 23:58:07 2015 -0400
4.2 +++ b/cmake/sdlchecks.cmake Mon Apr 06 15:26:37 2015 -0300
4.3 @@ -505,8 +505,13 @@
4.4 endif()
4.5 endmacro()
4.6
4.7 +# Requires:
4.8 +# - EGL
4.9 +# - PkgCheckModules
4.10 +# Optional:
4.11 +# - MIR_SHARED opt
4.12 +# - HAVE_DLOPEN opt
4.13 macro(CheckMir)
4.14 -# !!! FIXME: hook up dynamic loading here.
4.15 if(VIDEO_MIR)
4.16 find_library(MIR_LIB mirclient mircommon egl)
4.17 pkg_check_modules(MIR_TOOLKIT mirclient mircommon)
4.18 @@ -522,15 +527,31 @@
4.19 set(SDL_VIDEO_DRIVER_MIR 1)
4.20
4.21 list(APPEND EXTRA_CFLAGS ${MIR_TOOLKIT_CFLAGS} ${EGL_CLFAGS} ${XKB_CLFLAGS})
4.22 - list(APPEND EXTRA_LDFLAGS ${MIR_TOOLKIT_LDFLAGS} ${EGL_LDLAGS} ${XKB_LDLAGS})
4.23 - endif (MIR_LIB AND MIR_TOOLKIT_FOUND AND EGL_FOUND AND XKB_FOUND)
4.24 +
4.25 + if(MIR_SHARED)
4.26 + if(NOT HAVE_DLOPEN)
4.27 + message_warn("You must have SDL_LoadObject() support for dynamic Mir loading")
4.28 + else()
4.29 + FindLibraryAndSONAME(mirclient)
4.30 + FindLibraryAndSONAME(xkbcommon)
4.31 + set(SDL_VIDEO_DRIVER_MIR_DYNAMIC "\"${MIRCLIENT_LIB_SONAME}\"")
4.32 + set(SDL_VIDEO_DRIVER_MIR_DYNAMIC_XKBCOMMON "\"${XKBCOMMON_LIB_SONAME}\"")
4.33 + set(HAVE_MIR_SHARED TRUE)
4.34 + endif()
4.35 + else()
4.36 + set(EXTRA_LIBS ${MIR_TOOLKIT_LIBRARIES} ${EXTRA_LIBS})
4.37 + endif()
4.38 + endif()
4.39 endif()
4.40 endmacro()
4.41
4.42 # Requires:
4.43 # - EGL
4.44 +# - PkgCheckModules
4.45 +# Optional:
4.46 +# - WAYLAND_SHARED opt
4.47 +# - HAVE_DLOPEN opt
4.48 macro(CheckWayland)
4.49 -# !!! FIXME: hook up dynamic loading here.
4.50 if(VIDEO_WAYLAND)
4.51 pkg_check_modules(WAYLAND wayland-client wayland-cursor wayland-egl egl xkbcommon)
4.52 if(WAYLAND_FOUND)
4.53 @@ -540,12 +561,34 @@
4.54 include_directories(
4.55 ${WAYLAND_INCLUDE_DIRS}
4.56 )
4.57 - set(EXTRA_LIBS ${WAYLAND_LIBRARIES} ${EXTRA_LIBS})
4.58 set(HAVE_VIDEO_WAYLAND TRUE)
4.59 set(HAVE_SDL_VIDEO TRUE)
4.60
4.61 file(GLOB WAYLAND_SOURCES ${SDL2_SOURCE_DIR}/src/video/wayland/*.c)
4.62 set(SOURCE_FILES ${SOURCE_FILES} ${WAYLAND_SOURCES})
4.63 +
4.64 + if(VIDEO_WAYLAND_QT_TOUCH)
4.65 + set(SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH 1)
4.66 + endif()
4.67 +
4.68 + if(WAYLAND_SHARED)
4.69 + if(NOT HAVE_DLOPEN)
4.70 + message_warn("You must have SDL_LoadObject() support for dynamic Wayland loading")
4.71 + else()
4.72 + FindLibraryAndSONAME(wayland-client)
4.73 + FindLibraryAndSONAME(wayland-egl)
4.74 + FindLibraryAndSONAME(wayland-cursor)
4.75 + FindLibraryAndSONAME(xkbcommon)
4.76 + set(SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC "\"${WAYLAND_CLIENT_LIB_SONAME}\"")
4.77 + set(SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL "\"${WAYLAND_EGL_LIB_SONAME}\"")
4.78 + set(SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR "\"${WAYLAND_CURSOR_LIB_SONAME}\"")
4.79 + set(SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON "\"${XKBCOMMON_LIB_SONAME}\"")
4.80 + set(HAVE_WAYLAND_SHARED TRUE)
4.81 + endif()
4.82 + else()
4.83 + set(EXTRA_LIBS ${WAYLAND_LIBRARIES} ${EXTRA_LIBS})
4.84 + endif()
4.85 +
4.86 set(SDL_VIDEO_DRIVER_WAYLAND 1)
4.87 endif()
4.88 endif()
4.89 @@ -682,7 +725,7 @@
4.90 endif()
4.91 endmacro()
4.92
4.93 -# Rquires:
4.94 +# Requires:
4.95 # - nada
4.96 # Optional:
4.97 # - THREADS opt
4.98 @@ -733,13 +776,17 @@
4.99
4.100 # Run some tests
4.101 set(CMAKE_REQUIRED_FLAGS "${PTHREAD_CFLAGS} ${PTHREAD_LDFLAGS}")
4.102 - check_c_source_runs("
4.103 + if(CMAKE_CROSSCOMPILING)
4.104 + set(HAVE_PTHREADS 1)
4.105 + else()
4.106 + check_c_source_runs("
4.107 #include <pthread.h>
4.108 int main(int argc, char** argv) {
4.109 pthread_attr_t type;
4.110 pthread_attr_init(&type);
4.111 return 0;
4.112 }" HAVE_PTHREADS)
4.113 + endif()
4.114 if(HAVE_PTHREADS)
4.115 set(SDL_THREAD_PTHREAD 1)
4.116 list(APPEND EXTRA_CFLAGS ${PTHREAD_CFLAGS})
4.117 @@ -788,8 +835,8 @@
4.118 #include <pthread.h>
4.119 #include <pthread_np.h>
4.120 int main(int argc, char** argv) { return 0; }" HAVE_PTHREAD_NP_H)
4.121 - check_function_exists(pthread_setname_np HAVE_PTHREAD_setNAME_NP)
4.122 - check_function_exists(pthread_set_name_np HAVE_PTHREAD_set_NAME_NP)
4.123 + check_function_exists(pthread_setname_np HAVE_PTHREAD_SETNAME_NP)
4.124 + check_function_exists(pthread_set_name_np HAVE_PTHREAD_SET_NAME_NP)
4.125 set(CMAKE_REQUIRED_FLAGS)
4.126
4.127 set(SOURCE_FILES ${SOURCE_FILES}
5.1 --- a/configure Sat Jan 24 23:58:07 2015 -0400
5.2 +++ b/configure Mon Apr 06 15:26:37 2015 -0300
5.3 @@ -21916,6 +21916,7 @@
5.4 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
5.5 /* end confdefs.h. */
5.6
5.7 + #define _GNU_SOURCE 1
5.8 #include <pthread.h>
5.9
5.10 int
5.11 @@ -21929,7 +21930,7 @@
5.12 return 0;
5.13 }
5.14 _ACEOF
5.15 -if ac_fn_c_try_compile "$LINENO"; then :
5.16 +if ac_fn_c_try_link "$LINENO"; then :
5.17
5.18 has_recursive_mutexes=yes
5.19
5.20 @@ -21937,12 +21938,14 @@
5.21
5.22
5.23 fi
5.24 -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
5.25 +rm -f core conftest.err conftest.$ac_objext \
5.26 + conftest$ac_exeext conftest.$ac_ext
5.27 fi
5.28 if test x$has_recursive_mutexes = xno; then
5.29 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
5.30 /* end confdefs.h. */
5.31
5.32 + #define _GNU_SOURCE 1
5.33 #include <pthread.h>
5.34
5.35 int
5.36 @@ -21956,7 +21959,7 @@
5.37 return 0;
5.38 }
5.39 _ACEOF
5.40 -if ac_fn_c_try_compile "$LINENO"; then :
5.41 +if ac_fn_c_try_link "$LINENO"; then :
5.42
5.43 has_recursive_mutexes=yes
5.44
5.45 @@ -21964,7 +21967,8 @@
5.46
5.47
5.48 fi
5.49 -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
5.50 +rm -f core conftest.err conftest.$ac_objext \
5.51 + conftest$ac_exeext conftest.$ac_ext
5.52 fi
5.53 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $has_recursive_mutexes" >&5
5.54 $as_echo "$has_recursive_mutexes" >&6; }
5.55 @@ -23091,11 +23095,22 @@
5.56 fi
5.57 # Set up files for the filesystem library
5.58 if test x$enable_filesystem = xyes; then
5.59 + case $ARCH in
5.60 + android)
5.61 +
5.62 +$as_echo "#define SDL_FILESYSTEM_ANDROID 1" >>confdefs.h
5.63 +
5.64 + SOURCES="$SOURCES $srcdir/src/filesystem/android/*.c"
5.65 + have_filesystem=yes
5.66 + ;;
5.67 + *)
5.68
5.69 $as_echo "#define SDL_FILESYSTEM_UNIX 1" >>confdefs.h
5.70
5.71 - SOURCES="$SOURCES $srcdir/src/filesystem/unix/*.c"
5.72 - have_filesystem=yes
5.73 + SOURCES="$SOURCES $srcdir/src/filesystem/unix/*.c"
5.74 + have_filesystem=yes
5.75 + ;;
5.76 + esac
5.77 fi
5.78 # Set up files for the timer library
5.79 if test x$enable_timers = xyes; then
6.1 --- a/configure.in Sat Jan 24 23:58:07 2015 -0400
6.2 +++ b/configure.in Mon Apr 06 15:26:37 2015 -0300
6.3 @@ -2424,7 +2424,8 @@
6.4 AC_MSG_CHECKING(for recursive mutexes)
6.5 has_recursive_mutexes=no
6.6 if test x$has_recursive_mutexes = xno; then
6.7 - AC_TRY_COMPILE([
6.8 + AC_TRY_LINK([
6.9 + #define _GNU_SOURCE 1
6.10 #include <pthread.h>
6.11 ],[
6.12 pthread_mutexattr_t attr;
6.13 @@ -2435,7 +2436,8 @@
6.14 ])
6.15 fi
6.16 if test x$has_recursive_mutexes = xno; then
6.17 - AC_TRY_COMPILE([
6.18 + AC_TRY_LINK([
6.19 + #define _GNU_SOURCE 1
6.20 #include <pthread.h>
6.21 ],[
6.22 pthread_mutexattr_t attr;
6.23 @@ -2971,9 +2973,18 @@
6.24 fi
6.25 # Set up files for the filesystem library
6.26 if test x$enable_filesystem = xyes; then
6.27 - AC_DEFINE(SDL_FILESYSTEM_UNIX, 1, [ ])
6.28 - SOURCES="$SOURCES $srcdir/src/filesystem/unix/*.c"
6.29 - have_filesystem=yes
6.30 + case $ARCH in
6.31 + android)
6.32 + AC_DEFINE(SDL_FILESYSTEM_ANDROID, 1, [ ])
6.33 + SOURCES="$SOURCES $srcdir/src/filesystem/android/*.c"
6.34 + have_filesystem=yes
6.35 + ;;
6.36 + *)
6.37 + AC_DEFINE(SDL_FILESYSTEM_UNIX, 1, [ ])
6.38 + SOURCES="$SOURCES $srcdir/src/filesystem/unix/*.c"
6.39 + have_filesystem=yes
6.40 + ;;
6.41 + esac
6.42 fi
6.43 # Set up files for the timer library
6.44 if test x$enable_timers = xyes; then
7.1 --- a/docs/README-platforms.md Sat Jan 24 23:58:07 2015 -0400
7.2 +++ b/docs/README-platforms.md Mon Apr 06 15:26:37 2015 -0300
7.3 @@ -1,34 +1,8 @@
7.4 Platforms
7.5 =========
7.6
7.7 -
7.8 -This is a list of the platforms SDL supports, and who maintains them.
7.9 -
7.10 -Officially supported platforms
7.11 -==============================
7.12 -(code compiles, and thoroughly tested for release)
7.13 -==============================
7.14 -* Windows XP/Vista/7/8
7.15 -* Mac OS X 10.5+
7.16 -* Linux 2.6+
7.17 -* iOS 5.1.1+
7.18 -* Android 2.3.3+
7.19 -
7.20 -Unofficially supported platforms
7.21 -================================
7.22 -(code compiles, but not thoroughly tested)
7.23 -================================
7.24 -* FreeBSD
7.25 -* NetBSD
7.26 -* OpenBSD
7.27 -* Solaris
7.28 -
7.29 -Platforms supported by volunteers
7.30 -=================================
7.31 -* Haiku - maintained by Axel Dörfler <axeld@pinc-software.de>
7.32 -* PSP - maintained by 527721088@qq.com
7.33 -* Pandora - maintained by Scott Smith <pickle136@sbcglobal.net>
7.34 -* NaCl - maintained by Gabriel Jacobo <gabomdq@gmail.com>
7.35 -
7.36 -Platforms that need maintainers
7.37 -===============================
7.38 +We maintain the list of supported platforms on our wiki now, and how to
7.39 +build and install SDL for those platforms:
7.40 +
7.41 + https://wiki.libsdl.org/Installation
7.42 +
8.1 --- a/docs/README-porting.md Sat Jan 24 23:58:07 2015 -0400
8.2 +++ b/docs/README-porting.md Mon Apr 06 15:26:37 2015 -0300
8.3 @@ -15,7 +15,7 @@
8.4
8.5 If you have a GNUish system, then you might try this. Edit configure.in,
8.6 take a look at the large section labelled:
8.7 - "Set up the configuration based on the target platform!"
8.8 + "Set up the configuration based on the host platform!"
8.9 Add a section for your platform, and then re-run autogen.sh and build!
8.10
8.11 2. Using an IDE:
9.1 --- a/docs/README-winrt.md Sat Jan 24 23:58:07 2015 -0400
9.2 +++ b/docs/README-winrt.md Mon Apr 06 15:26:37 2015 -0300
9.3 @@ -90,10 +90,12 @@
9.4 * keyboard input. Most of WinRT's documented virtual keys are supported, as
9.5 well as many keys with documented hardware scancodes.
9.6 * OpenGL. Experimental support for OpenGL ES 2 is available via the ANGLE
9.7 - project, using either MS Open Technologies' repository, at
9.8 - https://github.com/msopentech/angle (both the "winrt" and "future-dev"
9.9 - branches are supported), or the official ANGLE repository, at
9.10 - https://chromium.googlesource.com/angle/angle
9.11 + project, using either:
9.12 + * MS Open Technologies' "ms-master" repository, at https://github.com/MSOpenTech/angle
9.13 + (for use with Windows 8.1+ or Windows Phone 8.1+)
9.14 + * MS Open Technologies' "angle-win8.0" repository, at https://github.com/MSOpenTech/angle-win8.0
9.15 + (for Windows 8.0 only!)
9.16 + * Google's main ANGLE repository, at https://chromium.googlesource.com/angle/angle
9.17 * SDLmain. WinRT uses a different signature for each app's main() function.
9.18 SDL-based apps that use this port must compile in SDL_winrt_main_NonXAML.cpp
9.19 (in `SDL\src\main\winrt\`) directly in order for their C-style main()
9.20 @@ -112,6 +114,11 @@
9.21 supported by WinRT itself.
9.22 * joysticks and game controllers that aren't supported by Microsoft's XInput
9.23 API.
9.24 + * turning off VSync when rendering on Windows Phone. Attempts to turn VSync
9.25 + off on Windows Phone result either in Direct3D not drawing anything, or it
9.26 + forcing VSync back on. As such, SDL_RENDERER_PRESENTVSYNC will always get
9.27 + turned-on on Windows Phone. This limitation is not present in non-Phone
9.28 + WinRT (such as Windows 8.x), where turning off VSync appears to work.
9.29 * probably anything else that's not listed as supported
9.30
9.31
10.1 --- a/include/SDL_assert.h Sat Jan 24 23:58:07 2015 -0400
10.2 +++ b/include/SDL_assert.h Mon Apr 06 15:26:37 2015 -0300
10.3 @@ -102,9 +102,9 @@
10.4 SDL_ASSERTION_ABORT, /**< Terminate the program. */
10.5 SDL_ASSERTION_IGNORE, /**< Ignore the assert. */
10.6 SDL_ASSERTION_ALWAYS_IGNORE /**< Ignore the assert from now on. */
10.7 -} SDL_assert_state;
10.8 +} SDL_AssertState;
10.9
10.10 -typedef struct SDL_assert_data
10.11 +typedef struct SDL_AssertData
10.12 {
10.13 int always_ignore;
10.14 unsigned int trigger_count;
10.15 @@ -112,13 +112,13 @@
10.16 const char *filename;
10.17 int linenum;
10.18 const char *function;
10.19 - const struct SDL_assert_data *next;
10.20 -} SDL_assert_data;
10.21 + const struct SDL_AssertData *next;
10.22 +} SDL_AssertData;
10.23
10.24 #if (SDL_ASSERT_LEVEL > 0)
10.25
10.26 /* Never call this directly. Use the SDL_assert* macros. */
10.27 -extern DECLSPEC SDL_assert_state SDLCALL SDL_ReportAssertion(SDL_assert_data *,
10.28 +extern DECLSPEC SDL_AssertState SDLCALL SDL_ReportAssertion(SDL_AssertData *,
10.29 const char *,
10.30 const char *, int)
10.31 #if defined(__clang__)
10.32 @@ -141,10 +141,10 @@
10.33 #define SDL_enabled_assert(condition) \
10.34 do { \
10.35 while ( !(condition) ) { \
10.36 - static struct SDL_assert_data sdl_assert_data = { \
10.37 + static struct SDL_AssertData sdl_assert_data = { \
10.38 0, 0, #condition, 0, 0, 0, 0 \
10.39 }; \
10.40 - const SDL_assert_state sdl_assert_state = SDL_ReportAssertion(&sdl_assert_data, SDL_FUNCTION, SDL_FILE, SDL_LINE); \
10.41 + const SDL_AssertState sdl_assert_state = SDL_ReportAssertion(&sdl_assert_data, SDL_FUNCTION, SDL_FILE, SDL_LINE); \
10.42 if (sdl_assert_state == SDL_ASSERTION_RETRY) { \
10.43 continue; /* go again. */ \
10.44 } else if (sdl_assert_state == SDL_ASSERTION_BREAK) { \
10.45 @@ -181,8 +181,8 @@
10.46 #define SDL_assert_always(condition) SDL_enabled_assert(condition)
10.47
10.48
10.49 -typedef SDL_assert_state (SDLCALL *SDL_AssertionHandler)(
10.50 - const SDL_assert_data* data, void* userdata);
10.51 +typedef SDL_AssertState (SDLCALL *SDL_AssertionHandler)(
10.52 + const SDL_AssertData* data, void* userdata);
10.53
10.54 /**
10.55 * \brief Set an application-defined assertion handler.
10.56 @@ -199,7 +199,7 @@
10.57 *
10.58 * This callback is NOT reset to SDL's internal handler upon SDL_Quit()!
10.59 *
10.60 - * \return SDL_assert_state value of how to handle the assertion failure.
10.61 + * \return SDL_AssertState value of how to handle the assertion failure.
10.62 *
10.63 * \param handler Callback function, called when an assertion fails.
10.64 * \param userdata A pointer passed to the callback as-is.
10.65 @@ -246,7 +246,7 @@
10.66 * The proper way to examine this data looks something like this:
10.67 *
10.68 * <code>
10.69 - * const SDL_assert_data *item = SDL_GetAssertionReport();
10.70 + * const SDL_AssertData *item = SDL_GetAssertionReport();
10.71 * while (item) {
10.72 * printf("'%s', %s (%s:%d), triggered %u times, always ignore: %s.\n",
10.73 * item->condition, item->function, item->filename,
10.74 @@ -259,7 +259,7 @@
10.75 * \return List of all assertions.
10.76 * \sa SDL_ResetAssertionReport
10.77 */
10.78 -extern DECLSPEC const SDL_assert_data * SDLCALL SDL_GetAssertionReport(void);
10.79 +extern DECLSPEC const SDL_AssertData * SDLCALL SDL_GetAssertionReport(void);
10.80
10.81 /**
10.82 * \brief Reset the list of all assertion failures.
10.83 @@ -270,6 +270,12 @@
10.84 */
10.85 extern DECLSPEC void SDLCALL SDL_ResetAssertionReport(void);
10.86
10.87 +
10.88 +/* these had wrong naming conventions until 2.0.4. Please update your app! */
10.89 +#define SDL_assert_state SDL_AssertState
10.90 +#define SDL_assert_data SDL_AssertData
10.91 +
10.92 +
10.93 /* Ends C function definitions when using C++ */
10.94 #ifdef __cplusplus
10.95 }
11.1 --- a/include/SDL_config.h.cmake Sat Jan 24 23:58:07 2015 -0400
11.2 +++ b/include/SDL_config.h.cmake Mon Apr 06 15:26:37 2015 -0300
11.3 @@ -269,14 +269,11 @@
11.4 #cmakedefine SDL_VIDEO_DRIVER_VIVANTE @SDL_VIDEO_DRIVER_VIVANTE@
11.5 #cmakedefine SDL_VIDEO_DRIVER_VIVANTE_VDK @SDL_VIDEO_DRIVER_VIVANTE_VDK@
11.6
11.7 -#if 0
11.8 -/* !!! FIXME: in configure script version, missing here: */
11.9 -#undef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
11.10 -#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC
11.11 -#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL
11.12 -#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR
11.13 -#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON
11.14 -#endif
11.15 +#cmakedefine SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH @SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH@
11.16 +#cmakedefine SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC @SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC@
11.17 +#cmakedefine SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL @SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL@
11.18 +#cmakedefine SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR @SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR@
11.19 +#cmakedefine SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON @SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON@
11.20
11.21 #cmakedefine SDL_VIDEO_DRIVER_MIR @SDL_VIDEO_DRIVER_MIR@
11.22 #cmakedefine SDL_VIDEO_DRIVER_MIR_DYNAMIC @SDL_VIDEO_DRIVER_MIR_DYNAMIC@
12.1 --- a/include/SDL_config.h.in Sat Jan 24 23:58:07 2015 -0400
12.2 +++ b/include/SDL_config.h.in Mon Apr 06 15:26:37 2015 -0300
12.3 @@ -349,6 +349,7 @@
12.4 #undef SDL_FILESYSTEM_UNIX
12.5 #undef SDL_FILESYSTEM_WINDOWS
12.6 #undef SDL_FILESYSTEM_NACL
12.7 +#undef SDL_FILESYSTEM_ANDROID
12.8 #undef SDL_FILESYSTEM_EMSCRIPTEN
12.9
12.10 /* Enable assembly routines */
13.1 --- a/include/SDL_events.h Sat Jan 24 23:58:07 2015 -0400
13.2 +++ b/include/SDL_events.h Mon Apr 06 15:26:37 2015 -0300
13.3 @@ -134,6 +134,10 @@
13.4 /* Drag and drop events */
13.5 SDL_DROPFILE = 0x1000, /**< The system requests a file open */
13.6
13.7 + /* Audio hotplug events */
13.8 + SDL_AUDIODEVICEADDED = 0x1100, /**< A new audio device is available */
13.9 + SDL_AUDIODEVICEREMOVED, /**< An audio device has been removed. */
13.10 +
13.11 /* Render events */
13.12 SDL_RENDER_TARGETS_RESET = 0x2000, /**< The render targets have been reset and their contents need to be updated */
13.13 SDL_RENDER_DEVICE_RESET, /**< The device has been reset and all textures need to be recreated */
13.14 @@ -382,6 +386,20 @@
13.15 Sint32 which; /**< The joystick device index for the ADDED event, instance id for the REMOVED or REMAPPED event */
13.16 } SDL_ControllerDeviceEvent;
13.17
13.18 +/**
13.19 + * \brief Audio device event structure (event.adevice.*)
13.20 + */
13.21 +typedef struct SDL_AudioDeviceEvent
13.22 +{
13.23 + Uint32 type; /**< ::SDL_AUDIODEVICEADDED, or ::SDL_AUDIODEVICEREMOVED */
13.24 + Uint32 timestamp;
13.25 + Uint32 which; /**< The audio device index for the ADDED event (valid until next SDL_GetNumAudioDevices() call), SDL_AudioDeviceID for the REMOVED event */
13.26 + Uint8 iscapture; /**< zero if an output device, non-zero if a capture device. */
13.27 + Uint8 padding1;
13.28 + Uint8 padding2;
13.29 + Uint8 padding3;
13.30 +} SDL_AudioDeviceEvent;
13.31 +
13.32
13.33 /**
13.34 * \brief Touch finger event structure (event.tfinger.*)
13.35 @@ -422,7 +440,7 @@
13.36 */
13.37 typedef struct SDL_DollarGestureEvent
13.38 {
13.39 - Uint32 type; /**< ::SDL_DOLLARGESTURE */
13.40 + Uint32 type; /**< ::SDL_DOLLARGESTURE or ::SDL_DOLLARRECORD */
13.41 Uint32 timestamp;
13.42 SDL_TouchID touchId; /**< The touch device id */
13.43 SDL_GestureID gestureId;
13.44 @@ -516,6 +534,7 @@
13.45 SDL_ControllerAxisEvent caxis; /**< Game Controller axis event data */
13.46 SDL_ControllerButtonEvent cbutton; /**< Game Controller button event data */
13.47 SDL_ControllerDeviceEvent cdevice; /**< Game Controller device event data */
13.48 + SDL_AudioDeviceEvent adevice; /**< Audio device event data */
13.49 SDL_QuitEvent quit; /**< Quit request event data */
13.50 SDL_UserEvent user; /**< Custom event data */
13.51 SDL_SysWMEvent syswm; /**< System dependent window event data */
14.1 --- a/include/SDL_gamecontroller.h Sat Jan 24 23:58:07 2015 -0400
14.2 +++ b/include/SDL_gamecontroller.h Mon Apr 06 15:26:37 2015 -0300
14.3 @@ -241,7 +241,8 @@
14.4 /**
14.5 * Get the current state of an axis control on a game controller.
14.6 *
14.7 - * The state is a value ranging from -32768 to 32767.
14.8 + * The state is a value ranging from -32768 to 32767 (except for the triggers,
14.9 + * which range from 0 to 32767).
14.10 *
14.11 * The axis indices start at index 0.
14.12 */
15.1 --- a/include/SDL_hints.h Sat Jan 24 23:58:07 2015 -0400
15.2 +++ b/include/SDL_hints.h Mon Apr 06 15:26:37 2015 -0300
15.3 @@ -533,6 +533,18 @@
15.4 */
15.5 #define SDL_HINT_IME_INTERNAL_EDITING "SDL_IME_INTERNAL_EDITING"
15.6
15.7 + /**
15.8 + * \brief A variable to control whether mouse and touch events are to be treated together or separately
15.9 + *
15.10 + * The variable can be set to the following values:
15.11 + * "0" - Mouse events will be handled as touch events, and touch will raise fake mouse
15.12 + * events. This is the behaviour of SDL <= 2.0.3. (default)
15.13 + * "1" - Mouse events will be handled separately from pure touch events.
15.14 + *
15.15 + * The value of this hint is used at runtime, so it can be changed at any time.
15.16 + */
15.17 +#define SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH "SDL_ANDROID_SEPARATE_MOUSE_AND_TOUCH"
15.18 +
15.19 /**
15.20 * \brief override the binding element for keyboard inputs for Emscripten builds
15.21 *
15.22 @@ -548,6 +560,18 @@
15.23 #define SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT "SDL_EMSCRIPTEN_KEYBOARD_ELEMENT"
15.24
15.25 /**
15.26 + * \brief Tell SDL not to catch the SIGINT or SIGTERM signals.
15.27 + *
15.28 + * This hint only applies to Unix-like platforms.
15.29 + *
15.30 + * The variable can be set to the following values:
15.31 + * "0" - SDL will install a SIGINT and SIGTERM handler, and when it
15.32 + * catches a signal, convert it into an SDL_QUIT event.
15.33 + * "1" - SDL will not install a signal handler at all.
15.34 + */
15.35 +#define SDL_HINT_NO_SIGNAL_HANDLERS "SDL_NO_SIGNAL_HANDLERS"
15.36 +
15.37 +/**
15.38 * \brief An enumeration of hint priorities
15.39 */
15.40 typedef enum
16.1 --- a/include/SDL_opengl_glext.h Sat Jan 24 23:58:07 2015 -0400
16.2 +++ b/include/SDL_opengl_glext.h Mon Apr 06 15:26:37 2015 -0300
16.3 @@ -2988,6 +2988,11 @@
16.4 #define GL_ARB_framebuffer_sRGB 1
16.5 #endif /* GL_ARB_framebuffer_sRGB */
16.6
16.7 +#ifndef GL_KHR_context_flush_control
16.8 +#define GL_CONTEXT_RELEASE_BEHAVIOR 0x82FB
16.9 +#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82FC
16.10 +#endif /* GL_KHR_context_flush_control */
16.11 +
16.12 #ifndef GL_ARB_geometry_shader4
16.13 #define GL_ARB_geometry_shader4 1
16.14 #define GL_LINES_ADJACENCY_ARB 0x000A
17.1 --- a/include/SDL_render.h Sat Jan 24 23:58:07 2015 -0400
17.2 +++ b/include/SDL_render.h Mon Apr 06 15:26:37 2015 -0300
17.3 @@ -81,8 +81,8 @@
17.4 Uint32 flags; /**< Supported ::SDL_RendererFlags */
17.5 Uint32 num_texture_formats; /**< The number of available texture formats */
17.6 Uint32 texture_formats[16]; /**< The available texture formats */
17.7 - int max_texture_width; /**< The maximimum texture width */
17.8 - int max_texture_height; /**< The maximimum texture height */
17.9 + int max_texture_width; /**< The maximum texture width */
17.10 + int max_texture_height; /**< The maximum texture height */
17.11 } SDL_RendererInfo;
17.12
17.13 /**
17.14 @@ -792,7 +792,7 @@
17.15 * \param dstrect A pointer to the destination rectangle, or NULL for the
17.16 * entire rendering target.
17.17 * \param angle An angle in degrees that indicates the rotation that will be applied to dstrect
17.18 - * \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)
17.19 + * \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).
17.20 * \param flip An SDL_RendererFlip value stating which flipping actions should be performed on the texture
17.21 *
17.22 * \return 0 on success, or -1 on error
18.1 --- a/include/SDL_stdinc.h Sat Jan 24 23:58:07 2015 -0400
18.2 +++ b/include/SDL_stdinc.h Mon Apr 06 15:26:37 2015 -0300
18.3 @@ -173,6 +173,8 @@
18.4 #define SDL_PRIs64 PRIs64
18.5 #elif defined(__WIN32__)
18.6 #define SDL_PRIs64 "I64d"
18.7 +#elif defined(__LINUX__) && defined(__LP64__)
18.8 +#define SDL_PRIs64 "ld"
18.9 #else
18.10 #define SDL_PRIs64 "lld"
18.11 #endif
18.12 @@ -182,6 +184,8 @@
18.13 #define SDL_PRIu64 PRIu64
18.14 #elif defined(__WIN32__)
18.15 #define SDL_PRIu64 "I64u"
18.16 +#elif defined(__LINUX__) && defined(__LP64__)
18.17 +#define SDL_PRIu64 "lu"
18.18 #else
18.19 #define SDL_PRIu64 "llu"
18.20 #endif
18.21 @@ -191,6 +195,8 @@
18.22 #define SDL_PRIx64 PRIx64
18.23 #elif defined(__WIN32__)
18.24 #define SDL_PRIx64 "I64x"
18.25 +#elif defined(__LINUX__) && defined(__LP64__)
18.26 +#define SDL_PRIx64 "lx"
18.27 #else
18.28 #define SDL_PRIx64 "llx"
18.29 #endif
18.30 @@ -200,6 +206,8 @@
18.31 #define SDL_PRIX64 PRIX64
18.32 #elif defined(__WIN32__)
18.33 #define SDL_PRIX64 "I64X"
18.34 +#elif defined(__LINUX__) && defined(__LP64__)
18.35 +#define SDL_PRIX64 "lX"
18.36 #else
18.37 #define SDL_PRIX64 "llX"
18.38 #endif
19.1 --- a/include/SDL_syswm.h Sat Jan 24 23:58:07 2015 -0400
19.2 +++ b/include/SDL_syswm.h Mon Apr 06 15:26:37 2015 -0300
19.3 @@ -186,6 +186,7 @@
19.4 struct
19.5 {
19.6 HWND window; /**< The window handle */
19.7 + HDC hdc; /**< The window device context */
19.8 } win;
19.9 #endif
19.10 #if defined(SDL_VIDEO_DRIVER_WINRT)
20.1 --- a/include/SDL_video.h Sat Jan 24 23:58:07 2015 -0400
20.2 +++ b/include/SDL_video.h Mon Apr 06 15:26:37 2015 -0300
20.3 @@ -189,7 +189,8 @@
20.4 SDL_GL_CONTEXT_FLAGS,
20.5 SDL_GL_CONTEXT_PROFILE_MASK,
20.6 SDL_GL_SHARE_WITH_CURRENT_CONTEXT,
20.7 - SDL_GL_FRAMEBUFFER_SRGB_CAPABLE
20.8 + SDL_GL_FRAMEBUFFER_SRGB_CAPABLE,
20.9 + SDL_GL_CONTEXT_RELEASE_BEHAVIOR
20.10 } SDL_GLattr;
20.11
20.12 typedef enum
20.13 @@ -207,6 +208,12 @@
20.14 SDL_GL_CONTEXT_RESET_ISOLATION_FLAG = 0x0008
20.15 } SDL_GLcontextFlag;
20.16
20.17 +typedef enum
20.18 +{
20.19 + SDL_GL_CONTEXT_RELEASE_BEHAVIOR_NONE = 0x0000,
20.20 + SDL_GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH = 0x0001
20.21 +} SDL_GLcontextReleaseFlag;
20.22 +
20.23
20.24 /* Function prototypes */
20.25
20.26 @@ -715,6 +722,9 @@
20.27 * \param window The window for which the input grab mode should be set.
20.28 * \param grabbed This is SDL_TRUE to grab input, and SDL_FALSE to release input.
20.29 *
20.30 + * If the caller enables a grab while another window is currently grabbed,
20.31 + * the other window loses its grab in favor of the caller's window.
20.32 + *
20.33 * \sa SDL_GetWindowGrab()
20.34 */
20.35 extern DECLSPEC void SDLCALL SDL_SetWindowGrab(SDL_Window * window,
20.36 @@ -730,6 +740,15 @@
20.37 extern DECLSPEC SDL_bool SDLCALL SDL_GetWindowGrab(SDL_Window * window);
20.38
20.39 /**
20.40 + * \brief Get the window that currently has an input grab enabled.
20.41 + *
20.42 + * \return This returns the window if input is grabbed, and NULL otherwise.
20.43 + *
20.44 + * \sa SDL_SetWindowGrab()
20.45 + */
20.46 +extern DECLSPEC SDL_Window * SDLCALL SDL_GetGrabbedWindow(void);
20.47 +
20.48 +/**
20.49 * \brief Set the brightness (gamma correction) for a window.
20.50 *
20.51 * \return 0 on success, or -1 if setting the brightness isn't supported.
21.1 --- a/src/SDL.c Sat Jan 24 23:58:07 2015 -0400
21.2 +++ b/src/SDL.c Mon Apr 06 15:26:37 2015 -0300
21.3 @@ -405,6 +405,8 @@
21.4 return "BSDI";
21.5 #elif __DREAMCAST__
21.6 return "Dreamcast";
21.7 +#elif __EMSCRIPTEN__
21.8 + return "Emscripten";
21.9 #elif __FREEBSD__
21.10 return "FreeBSD";
21.11 #elif __HAIKU__
22.1 --- a/src/SDL_error.c Sat Jan 24 23:58:07 2015 -0400
22.2 +++ b/src/SDL_error.c Mon Apr 06 15:26:37 2015 -0300
22.3 @@ -120,7 +120,7 @@
22.4 so that it supports internationalization and thread-safe errors.
22.5 */
22.6 static char *
22.7 -SDL_GetErrorMsg(char *errstr, unsigned int maxlen)
22.8 +SDL_GetErrorMsg(char *errstr, int maxlen)
22.9 {
22.10 SDL_error *error;
22.11
22.12 @@ -163,37 +163,55 @@
22.13 len =
22.14 SDL_snprintf(msg, maxlen, tmp,
22.15 error->args[argi++].value_i);
22.16 - msg += len;
22.17 - maxlen -= len;
22.18 + if (len > 0) {
22.19 + msg += len;
22.20 + maxlen -= len;
22.21 + }
22.22 break;
22.23 +
22.24 case 'f':
22.25 len =
22.26 SDL_snprintf(msg, maxlen, tmp,
22.27 error->args[argi++].value_f);
22.28 - msg += len;
22.29 - maxlen -= len;
22.30 + if (len > 0) {
22.31 + msg += len;
22.32 + maxlen -= len;
22.33 + }
22.34 break;
22.35 +
22.36 case 'p':
22.37 len =
22.38 SDL_snprintf(msg, maxlen, tmp,
22.39 error->args[argi++].value_ptr);
22.40 - msg += len;
22.41 - maxlen -= len;
22.42 + if (len > 0) {
22.43 + msg += len;
22.44 + maxlen -= len;
22.45 + }
22.46 break;
22.47 +
22.48 case 's':
22.49 len =
22.50 SDL_snprintf(msg, maxlen, tmp,
22.51 SDL_LookupString(error->args[argi++].
22.52 buf));
22.53 - msg += len;
22.54 - maxlen -= len;
22.55 + if (len > 0) {
22.56 + msg += len;
22.57 + maxlen -= len;
22.58 + }
22.59 break;
22.60 +
22.61 }
22.62 } else {
22.63 *msg++ = *fmt++;
22.64 maxlen -= 1;
22.65 }
22.66 }
22.67 +
22.68 + /* slide back if we've overshot the end of our buffer. */
22.69 + if (maxlen < 0) {
22.70 + msg -= (-maxlen) + 1;
22.71 + }
22.72 +
22.73 *msg = 0; /* NULL terminate the string */
22.74 }
22.75 return (errstr);
23.1 --- a/src/audio/SDL_audio.c Sat Jan 24 23:58:07 2015 -0400
23.2 +++ b/src/audio/SDL_audio.c Mon Apr 06 15:26:37 2015 -0300
23.3 @@ -51,9 +51,7 @@
23.4 extern AudioBootStrap SUNAUDIO_bootstrap;
23.5 extern AudioBootStrap ARTS_bootstrap;
23.6 extern AudioBootStrap ESD_bootstrap;
23.7 -#if SDL_AUDIO_DRIVER_NACL
23.8 extern AudioBootStrap NACLAUD_bootstrap;
23.9 -#endif
23.10 extern AudioBootStrap NAS_bootstrap;
23.11 extern AudioBootStrap XAUDIO2_bootstrap;
23.12 extern AudioBootStrap DSOUND_bootstrap;
23.13 @@ -163,8 +161,16 @@
23.14
23.15 /* stubs for audio drivers that don't need a specific entry point... */
23.16 static void
23.17 -SDL_AudioDetectDevices_Default(int iscapture, SDL_AddAudioDevice addfn)
23.18 -{ /* no-op. */
23.19 +SDL_AudioDetectDevices_Default(void)
23.20 +{
23.21 + /* you have to write your own implementation if these assertions fail. */
23.22 + SDL_assert(current_audio.impl.OnlyHasDefaultOutputDevice);
23.23 + SDL_assert(current_audio.impl.OnlyHasDefaultInputDevice || !current_audio.impl.HasCaptureSupport);
23.24 +
23.25 + SDL_AddAudioDevice(SDL_FALSE, DEFAULT_OUTPUT_DEVNAME, (void *) ((size_t) 0x1));
23.26 + if (current_audio.impl.HasCaptureSupport) {
23.27 + SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, (void *) ((size_t) 0x2));
23.28 + }
23.29 }
23.30
23.31 static void
23.32 @@ -209,10 +215,16 @@
23.33 { /* no-op. */
23.34 }
23.35
23.36 +static void
23.37 +SDL_AudioFreeDeviceHandle_Default(void *handle)
23.38 +{ /* no-op. */
23.39 +}
23.40 +
23.41 +
23.42 static int
23.43 -SDL_AudioOpenDevice_Default(_THIS, const char *devname, int iscapture)
23.44 +SDL_AudioOpenDevice_Default(_THIS, void *handle, const char *devname, int iscapture)
23.45 {
23.46 - return -1;
23.47 + return SDL_Unsupported();
23.48 }
23.49
23.50 static SDL_INLINE SDL_bool
23.51 @@ -269,71 +281,139 @@
23.52 FILL_STUB(CloseDevice);
23.53 FILL_STUB(LockDevice);
23.54 FILL_STUB(UnlockDevice);
23.55 + FILL_STUB(FreeDeviceHandle);
23.56 FILL_STUB(Deinitialize);
23.57 #undef FILL_STUB
23.58 }
23.59
23.60 -#if 0 /* !!! FIXME: rewrite/remove this streamer code. */
23.61 -/* Streaming functions (for when the input and output buffer sizes are different) */
23.62 -/* Write [length] bytes from buf into the streamer */
23.63 -static void
23.64 -SDL_StreamWrite(SDL_AudioStreamer * stream, Uint8 * buf, int length)
23.65 +
23.66 +/* device hotplug support... */
23.67 +
23.68 +static int
23.69 +add_audio_device(const char *name, void *handle, SDL_AudioDeviceItem **devices, int *devCount)
23.70 {
23.71 - int i;
23.72 + int retval = -1;
23.73 + const size_t size = sizeof (SDL_AudioDeviceItem) + SDL_strlen(name) + 1;
23.74 + SDL_AudioDeviceItem *item = (SDL_AudioDeviceItem *) SDL_malloc(size);
23.75 + if (item == NULL) {
23.76 + return -1;
23.77 + }
23.78 +
23.79 + SDL_assert(handle != NULL); /* we reserve NULL, audio backends can't use it. */
23.80 +
23.81 + item->handle = handle;
23.82 + SDL_strlcpy(item->name, name, size - sizeof (SDL_AudioDeviceItem));
23.83
23.84 - for (i = 0; i < length; ++i) {
23.85 - stream->buffer[stream->write_pos] = buf[i];
23.86 - ++stream->write_pos;
23.87 - }
23.88 + SDL_LockMutex(current_audio.detectionLock);
23.89 + item->next = *devices;
23.90 + *devices = item;
23.91 + retval = (*devCount)++;
23.92 + SDL_UnlockMutex(current_audio.detectionLock);
23.93 +
23.94 + return retval;
23.95 +}
23.96 +
23.97 +static SDL_INLINE int
23.98 +add_capture_device(const char *name, void *handle)
23.99 +{
23.100 + /* !!! FIXME: add this later. SDL_assert(current_audio.impl.HasCaptureSupport);*/
23.101 + return add_audio_device(name, handle, ¤t_audio.inputDevices, ¤t_audio.inputDeviceCount);
23.102 }
23.103
23.104 -/* Read [length] bytes out of the streamer into buf */
23.105 +static SDL_INLINE int
23.106 +add_output_device(const char *name, void *handle)
23.107 +{
23.108 + return add_audio_device(name, handle, ¤t_audio.outputDevices, ¤t_audio.outputDeviceCount);
23.109 +}
23.110 +
23.111 static void
23.112 -SDL_StreamRead(SDL_AudioStreamer * stream, Uint8 * buf, int length)
23.113 +free_device_list(SDL_AudioDeviceItem **devices, int *devCount)
23.114 {
23.115 - int i;
23.116 + SDL_AudioDeviceItem *item, *next;
23.117 + for (item = *devices; item != NULL; item = next) {
23.118 + next = item->next;
23.119 + if (item->handle != NULL) {
23.120 + current_audio.impl.FreeDeviceHandle(item->handle);
23.121 + }
23.122 + SDL_free(item);
23.123 + }
23.124 + *devices = NULL;
23.125 + *devCount = 0;
23.126 +}
23.127 +
23.128
23.129 - for (i = 0; i < length; ++i) {
23.130 - buf[i] = stream->buffer[stream->read_pos];
23.131 - ++stream->read_pos;
23.132 +/* The audio backends call this when a new device is plugged in. */
23.133 +void
23.134 +SDL_AddAudioDevice(const int iscapture, const char *name, void *handle)
23.135 +{
23.136 + const int device_index = iscapture ? add_capture_device(name, handle) : add_output_device(name, handle);
23.137 + if (device_index != -1) {
23.138 + /* Post the event, if desired */
23.139 + if (SDL_GetEventState(SDL_AUDIODEVICEADDED) == SDL_ENABLE) {
23.140 + SDL_Event event;
23.141 + SDL_zero(event);
23.142 + event.adevice.type = SDL_AUDIODEVICEADDED;
23.143 + event.adevice.which = device_index;
23.144 + event.adevice.iscapture = iscapture;
23.145 + SDL_PushEvent(&event);
23.146 + }
23.147 }
23.148 }
23.149
23.150 -static int
23.151 -SDL_StreamLength(SDL_AudioStreamer * stream)
23.152 +/* The audio backends call this when a currently-opened device is lost. */
23.153 +void SDL_OpenedAudioDeviceDisconnected(SDL_AudioDevice *device)
23.154 {
23.155 - return (stream->write_pos - stream->read_pos) % stream->max_len;
23.156 -}
23.157 + SDL_assert(get_audio_device(device->id) == device);
23.158
23.159 -/* Initialize the stream by allocating the buffer and setting the read/write heads to the beginning */
23.160 -#if 0
23.161 -static int
23.162 -SDL_StreamInit(SDL_AudioStreamer * stream, int max_len, Uint8 silence)
23.163 -{
23.164 - /* First try to allocate the buffer */
23.165 - stream->buffer = (Uint8 *) SDL_malloc(max_len);
23.166 - if (stream->buffer == NULL) {
23.167 - return -1;
23.168 + if (!device->enabled) {
23.169 + return;
23.170 }
23.171
23.172 - stream->max_len = max_len;
23.173 - stream->read_pos = 0;
23.174 - stream->write_pos = 0;
23.175 + /* Ends the audio callback and mark the device as STOPPED, but the
23.176 + app still needs to close the device to free resources. */
23.177 + current_audio.impl.LockDevice(device);
23.178 + device->enabled = 0;
23.179 + current_audio.impl.UnlockDevice(device);
23.180
23.181 - /* Zero out the buffer */
23.182 - SDL_memset(stream->buffer, silence, max_len);
23.183 -
23.184 - return 0;
23.185 + /* Post the event, if desired */
23.186 + if (SDL_GetEventState(SDL_AUDIODEVICEREMOVED) == SDL_ENABLE) {
23.187 + SDL_Event event;
23.188 + SDL_zero(event);
23.189 + event.adevice.type = SDL_AUDIODEVICEREMOVED;
23.190 + event.adevice.which = device->id;
23.191 + event.adevice.iscapture = device->iscapture ? 1 : 0;
23.192 + SDL_PushEvent(&event);
23.193 + }
23.194 }
23.195 -#endif
23.196
23.197 -/* Deinitialize the stream simply by freeing the buffer */
23.198 static void
23.199 -SDL_StreamDeinit(SDL_AudioStreamer * stream)
23.200 +mark_device_removed(void *handle, SDL_AudioDeviceItem *devices, SDL_bool *removedFlag)
23.201 {
23.202 - SDL_free(stream->buffer);
23.203 + SDL_AudioDeviceItem *item;
23.204 + SDL_assert(handle != NULL);
23.205 + for (item = devices; item != NULL; item = item->next) {
23.206 + if (item->handle == handle) {
23.207 + item->handle = NULL;
23.208 + *removedFlag = SDL_TRUE;
23.209 + return;
23.210 + }
23.211 + }
23.212 }
23.213 -#endif
23.214 +
23.215 +/* The audio backends call this when a device is removed from the system. */
23.216 +void
23.217 +SDL_RemoveAudioDevice(const int iscapture, void *handle)
23.218 +{
23.219 + SDL_LockMutex(current_audio.detectionLock);
23.220 + if (iscapture) {
23.221 + mark_device_removed(handle, current_audio.inputDevices, ¤t_audio.captureDevicesRemoved);
23.222 + } else {
23.223 + mark_device_removed(handle, current_audio.outputDevices, ¤t_audio.outputDevicesRemoved);
23.224 + }
23.225 + SDL_UnlockMutex(current_audio.detectionLock);
23.226 + current_audio.impl.FreeDeviceHandle(handle);
23.227 +}
23.228 +
23.229
23.230
23.231 /* buffer queueing support... */
23.232 @@ -510,26 +590,17 @@
23.233 }
23.234
23.235
23.236 -#if defined(__ANDROID__)
23.237 -#include <android/log.h>
23.238 -#endif
23.239 -
23.240 /* The general mixing thread function */
23.241 int SDLCALL
23.242 SDL_RunAudio(void *devicep)
23.243 {
23.244 SDL_AudioDevice *device = (SDL_AudioDevice *) devicep;
23.245 + const int silence = (int) device->spec.silence;
23.246 + const Uint32 delay = ((device->spec.samples * 1000) / device->spec.freq);
23.247 + const int stream_len = (device->convert.needed) ? device->convert.len : device->spec.size;
23.248 Uint8 *stream;
23.249 - int stream_len;
23.250 - void *udata;
23.251 - void (SDLCALL * fill) (void *userdata, Uint8 * stream, int len);
23.252 - Uint32 delay;
23.253 -
23.254 -#if 0 /* !!! FIXME: rewrite/remove this streamer code. */
23.255 - /* For streaming when the buffer sizes don't match up */
23.256 - Uint8 *istream;
23.257 - int istream_len = 0;
23.258 -#endif
23.259 + void *udata = device->spec.userdata;
23.260 + void (SDLCALL *fill) (void *, Uint8 *, int) = device->spec.callback;
23.261
23.262 /* The audio mixing is always a high priority thread */
23.263 SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH);
23.264 @@ -538,197 +609,60 @@
23.265 device->threadid = SDL_ThreadID();
23.266 current_audio.impl.ThreadInit(device);
23.267
23.268 - /* Set up the mixing function */
23.269 - fill = device->spec.callback;
23.270 - udata = device->spec.userdata;
23.271 -
23.272 - /* By default do not stream */
23.273 - device->use_streamer = 0;
23.274 -
23.275 - if (device->convert.needed) {
23.276 -#if 0 /* !!! FIXME: I took len_div out of the structure. Use rate_incr instead? */
23.277 - /* If the result of the conversion alters the length, i.e. resampling is being used, use the streamer */
23.278 - if (device->convert.len_mult != 1 || device->convert.len_div != 1) {
23.279 - /* The streamer's maximum length should be twice whichever is larger: spec.size or len_cvt */
23.280 - stream_max_len = 2 * device->spec.size;
23.281 - if (device->convert.len_mult > device->convert.len_div) {
23.282 - stream_max_len *= device->convert.len_mult;
23.283 - stream_max_len /= device->convert.len_div;
23.284 - }
23.285 - if (SDL_StreamInit(&device->streamer, stream_max_len, silence) <
23.286 - 0)
23.287 - return -1;
23.288 - device->use_streamer = 1;
23.289 -
23.290 - /* istream_len should be the length of what we grab from the callback and feed to conversion,
23.291 - so that we get close to spec_size. I.e. we want device.spec_size = istream_len * u / d
23.292 - */
23.293 - istream_len =
23.294 - device->spec.size * device->convert.len_div /
23.295 - device->convert.len_mult;
23.296 + /* Loop, filling the audio buffers */
23.297 + while (!device->shutdown) {
23.298 + /* Fill the current buffer with sound */
23.299 + if (device->convert.needed) {
23.300 + stream = device->convert.buf;
23.301 + } else if (device->enabled) {
23.302 + stream = current_audio.impl.GetDeviceBuf(device);
23.303 + } else {
23.304 + /* if the device isn't enabled, we still write to the
23.305 + fake_stream, so the app's callback will fire with
23.306 + a regular frequency, in case they depend on that
23.307 + for timing or progress. They can use hotplug
23.308 + now to know if the device failed. */
23.309 + stream = NULL;
23.310 }
23.311 -#endif
23.312 - stream_len = device->convert.len;
23.313 - } else {
23.314 - stream_len = device->spec.size;
23.315 - }
23.316 -
23.317 - /* Calculate the delay while paused */
23.318 - delay = ((device->spec.samples * 1000) / device->spec.freq);
23.319 -
23.320 - /* Determine if the streamer is necessary here */
23.321 -#if 0 /* !!! FIXME: rewrite/remove this streamer code. */
23.322 - if (device->use_streamer == 1) {
23.323 - /* This code is almost the same as the old code. The difference is, instead of reading
23.324 - directly from the callback into "stream", then converting and sending the audio off,
23.325 - we go: callback -> "istream" -> (conversion) -> streamer -> stream -> device.
23.326 - However, reading and writing with streamer are done separately:
23.327 - - We only call the callback and write to the streamer when the streamer does not
23.328 - contain enough samples to output to the device.
23.329 - - We only read from the streamer and tell the device to play when the streamer
23.330 - does have enough samples to output.
23.331 - This allows us to perform resampling in the conversion step, where the output of the
23.332 - resampling process can be any number. We will have to see what a good size for the
23.333 - stream's maximum length is, but I suspect 2*max(len_cvt, stream_len) is a good figure.
23.334 - */
23.335 - while (device->enabled) {
23.336 -
23.337 - if (device->paused) {
23.338 - SDL_Delay(delay);
23.339 - continue;
23.340 - }
23.341 -
23.342 - /* Only read in audio if the streamer doesn't have enough already (if it does not have enough samples to output) */
23.343 - if (SDL_StreamLength(&device->streamer) < stream_len) {
23.344 - /* Set up istream */
23.345 - if (device->convert.needed) {
23.346 - if (device->convert.buf) {
23.347 - istream = device->convert.buf;
23.348 - } else {
23.349 - continue;
23.350 - }
23.351 - } else {
23.352 -/* FIXME: Ryan, this is probably wrong. I imagine we don't want to get
23.353 - * a device buffer both here and below in the stream output.
23.354 - */
23.355 - istream = current_audio.impl.GetDeviceBuf(device);
23.356 - if (istream == NULL) {
23.357 - istream = device->fake_stream;
23.358 - }
23.359 - }
23.360
23.361 - /* Read from the callback into the _input_ stream */
23.362 - SDL_LockMutex(device->mixer_lock);
23.363 - (*fill) (udata, istream, istream_len);
23.364 - SDL_UnlockMutex(device->mixer_lock);
23.365 -
23.366 - /* Convert the audio if necessary and write to the streamer */
23.367 - if (device->convert.needed) {
23.368 - SDL_ConvertAudio(&device->convert);
23.369 - if (istream == NULL) {
23.370 - istream = device->fake_stream;
23.371 - }
23.372 - /* SDL_memcpy(istream, device->convert.buf, device->convert.len_cvt); */
23.373 - SDL_StreamWrite(&device->streamer, device->convert.buf,
23.374 - device->convert.len_cvt);
23.375 - } else {
23.376 - SDL_StreamWrite(&device->streamer, istream, istream_len);
23.377 - }
23.378 - }
23.379 -
23.380 - /* Only output audio if the streamer has enough to output */
23.381 - if (SDL_StreamLength(&device->streamer) >= stream_len) {
23.382 - /* Set up the output stream */
23.383 - if (device->convert.needed) {
23.384 - if (device->convert.buf) {
23.385 - stream = device->convert.buf;
23.386 - } else {
23.387 - continue;
23.388 - }
23.389 - } else {
23.390 - stream = current_audio.impl.GetDeviceBuf(device);
23.391 - if (stream == NULL) {
23.392 - stream = device->fake_stream;
23.393 - }
23.394 - }
23.395 -
23.396 - /* Now read from the streamer */
23.397 - SDL_StreamRead(&device->streamer, stream, stream_len);
23.398 + if (stream == NULL) {
23.399 + stream = device->fake_stream;
23.400 + }
23.401
23.402 - /* Ready current buffer for play and change current buffer */
23.403 - if (stream != device->fake_stream) {
23.404 - current_audio.impl.PlayDevice(device);
23.405 - /* Wait for an audio buffer to become available */
23.406 - current_audio.impl.WaitDevice(device);
23.407 - } else {
23.408 - SDL_Delay(delay);
23.409 - }
23.410 - }
23.411 -
23.412 + /* !!! FIXME: this should be LockDevice. */
23.413 + SDL_LockMutex(device->mixer_lock);
23.414 + if (device->paused) {
23.415 + SDL_memset(stream, silence, stream_len);
23.416 + } else {
23.417 + (*fill) (udata, stream, stream_len);
23.418 }
23.419 - } else
23.420 -#endif
23.421 - {
23.422 - /* Otherwise, do not use the streamer. This is the old code. */
23.423 - const int silence = (int) device->spec.silence;
23.424 -
23.425 - /* Loop, filling the audio buffers */
23.426 - while (device->enabled) {
23.427 + SDL_UnlockMutex(device->mixer_lock);
23.428
23.429 - /* Fill the current buffer with sound */
23.430 - if (device->convert.needed) {
23.431 - if (device->convert.buf) {
23.432 - stream = device->convert.buf;
23.433 - } else {
23.434 - continue;
23.435 - }
23.436 + /* Convert the audio if necessary */
23.437 + if (device->enabled && device->convert.needed) {
23.438 + SDL_ConvertAudio(&device->convert);
23.439 + stream = current_audio.impl.GetDeviceBuf(device);
23.440 + if (stream == NULL) {
23.441 + stream = device->fake_stream;
23.442 } else {
23.443 - stream = current_audio.impl.GetDeviceBuf(device);
23.444 - if (stream == NULL) {
23.445 - stream = device->fake_stream;
23.446 - }
23.447 - }
23.448 -
23.449 - SDL_LockMutex(device->mixer_lock);
23.450 - if (device->paused) {
23.451 - SDL_memset(stream, silence, stream_len);
23.452 - } else {
23.453 - (*fill) (udata, stream, stream_len);
23.454 - }
23.455 - SDL_UnlockMutex(device->mixer_lock);
23.456 -
23.457 - /* Convert the audio if necessary */
23.458 - if (device->convert.needed) {
23.459 - SDL_ConvertAudio(&device->convert);
23.460 - stream = current_audio.impl.GetDeviceBuf(device);
23.461 - if (stream == NULL) {
23.462 - stream = device->fake_stream;
23.463 - }
23.464 SDL_memcpy(stream, device->convert.buf,
23.465 device->convert.len_cvt);
23.466 }
23.467 + }
23.468
23.469 - /* Ready current buffer for play and change current buffer */
23.470 - if (stream != device->fake_stream) {
23.471 - current_audio.impl.PlayDevice(device);
23.472 - /* Wait for an audio buffer to become available */
23.473 - current_audio.impl.WaitDevice(device);
23.474 - } else {
23.475 - SDL_Delay(delay);
23.476 - }
23.477 + /* Ready current buffer for play and change current buffer */
23.478 + if (stream == device->fake_stream) {
23.479 + SDL_Delay(delay);
23.480 + } else {
23.481 + current_audio.impl.PlayDevice(device);
23.482 + current_audio.impl.WaitDevice(device);
23.483 }
23.484 }
23.485
23.486 - /* Wait for the audio to drain.. */
23.487 + /* Wait for the audio to drain. */
23.488 current_audio.impl.WaitDone(device);
23.489
23.490 - /* If necessary, deinit the streamer */
23.491 -#if 0 /* !!! FIXME: rewrite/remove this streamer code. */
23.492 - if (device->use_streamer == 1)
23.493 - SDL_StreamDeinit(&device->streamer);
23.494 -#endif
23.495 -
23.496 - return (0);
23.497 + return 0;
23.498 }
23.499
23.500
23.501 @@ -761,16 +695,16 @@
23.502 int
23.503 SDL_GetNumAudioDrivers(void)
23.504 {
23.505 - return (SDL_arraysize(bootstrap) - 1);
23.506 + return SDL_arraysize(bootstrap) - 1;
23.507 }
23.508
23.509 const char *
23.510 SDL_GetAudioDriver(int index)
23.511 {
23.512 if (index >= 0 && index < SDL_GetNumAudioDrivers()) {
23.513 - return (bootstrap[index]->name);
23.514 + return bootstrap[index]->name;
23.515 }
23.516 - return (NULL);
23.517 + return NULL;
23.518 }
23.519
23.520 int
23.521 @@ -784,8 +718,8 @@
23.522 SDL_AudioQuit(); /* shutdown driver if already running. */
23.523 }
23.524
23.525 - SDL_memset(¤t_audio, '\0', sizeof(current_audio));
23.526 - SDL_memset(open_devices, '\0', sizeof(open_devices));
23.527 + SDL_zero(current_audio);
23.528 + SDL_zero(open_devices);
23.529
23.530 /* Select the proper audio driver */
23.531 if (driver_name == NULL) {
23.532 @@ -801,7 +735,7 @@
23.533 }
23.534
23.535 tried_to_init = 1;
23.536 - SDL_memset(¤t_audio, 0, sizeof(current_audio));
23.537 + SDL_zero(current_audio);
23.538 current_audio.name = backend->name;
23.539 current_audio.desc = backend->desc;
23.540 initialized = backend->init(¤t_audio.impl);
23.541 @@ -817,13 +751,18 @@
23.542 }
23.543 }
23.544
23.545 - SDL_memset(¤t_audio, 0, sizeof(current_audio));
23.546 - return (-1); /* No driver was available, so fail. */
23.547 + SDL_zero(current_audio);
23.548 + return -1; /* No driver was available, so fail. */
23.549 }
23.550
23.551 + current_audio.detectionLock = SDL_CreateMutex();
23.552 +
23.553 finalize_audio_entry_points();
23.554
23.555 - return (0);
23.556 + /* Make sure we have a list of devices available at startup. */
23.557 + current_audio.impl.DetectDevices();
23.558 +
23.559 + return 0;
23.560 }
23.561
23.562 /*
23.563 @@ -835,50 +774,32 @@
23.564 return current_audio.name;
23.565 }
23.566
23.567 +/* Clean out devices that we've removed but had to keep around for stability. */
23.568 static void
23.569 -free_device_list(char ***devices, int *devCount)
23.570 +clean_out_device_list(SDL_AudioDeviceItem **devices, int *devCount, SDL_bool *removedFlag)
23.571 {
23.572 - int i = *devCount;
23.573 - if ((i > 0) && (*devices != NULL)) {
23.574 - while (i--) {
23.575 - SDL_free((*devices)[i]);
23.576 + SDL_AudioDeviceItem *item = *devices;
23.577 + SDL_AudioDeviceItem *prev = NULL;
23.578 + int total = 0;
23.579 +
23.580 + while (item) {
23.581 + SDL_AudioDeviceItem *next = item->next;
23.582 + if (item->handle != NULL) {
23.583 + total++;
23.584 + prev = item;
23.585 + } else {
23.586 + if (prev) {
23.587 + prev->next = next;
23.588 + } else {
23.589 + *devices = next;
23.590 + }
23.591 + SDL_free(item);
23.592 }
23.593 + item = next;
23.594 }
23.595
23.596 - SDL_free(*devices);
23.597 -
23.598 - *devices = NULL;
23.599 - *devCount = 0;
23.600 -}
23.601 -
23.602 -static
23.603 -void SDL_AddCaptureAudioDevice(const char *_name)
23.604 -{
23.605 - char *name = NULL;
23.606 - void *ptr = SDL_realloc(current_audio.inputDevices,
23.607 - (current_audio.inputDeviceCount+1) * sizeof(char*));
23.608 - if (ptr == NULL) {
23.609 - return; /* oh well. */
23.610 - }
23.611 -
23.612 - current_audio.inputDevices = (char **) ptr;
23.613 - name = SDL_strdup(_name); /* if this returns NULL, that's okay. */
23.614 - current_audio.inputDevices[current_audio.inputDeviceCount++] = name;
23.615 -}
23.616 -
23.617 -static
23.618 -void SDL_AddOutputAudioDevice(const char *_name)
23.619 -{
23.620 - char *name = NULL;
23.621 - void *ptr = SDL_realloc(current_audio.outputDevices,
23.622 - (current_audio.outputDeviceCount+1) * sizeof(char*));
23.623 - if (ptr == NULL) {
23.624 - return; /* oh well. */
23.625 - }
23.626 -
23.627 - current_audio.outputDevices = (char **) ptr;
23.628 - name = SDL_strdup(_name); /* if this returns NULL, that's okay. */
23.629 - current_audio.outputDevices[current_audio.outputDeviceCount++] = name;
23.630 + *devCount = total;
23.631 + *removedFlag = SDL_FALSE;
23.632 }
23.633
23.634
23.635 @@ -891,30 +812,19 @@
23.636 return -1;
23.637 }
23.638
23.639 - if ((iscapture) && (!current_audio.impl.HasCaptureSupport)) {
23.640 - return 0;
23.641 - }
23.642 -
23.643 - if ((iscapture) && (current_audio.impl.OnlyHasDefaultInputDevice)) {
23.644 - return 1;
23.645 - }
23.646 -
23.647 - if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) {
23.648 - return 1;
23.649 + SDL_LockMutex(current_audio.detectionLock);
23.650 + if (iscapture && current_audio.captureDevicesRemoved) {
23.651 + clean_out_device_list(¤t_audio.inputDevices, ¤t_audio.inputDeviceCount, ¤t_audio.captureDevicesRemoved);
23.652 }
23.653
23.654 - if (iscapture) {
23.655 - free_device_list(¤t_audio.inputDevices,
23.656 - ¤t_audio.inputDeviceCount);
23.657 - current_audio.impl.DetectDevices(iscapture, SDL_AddCaptureAudioDevice);
23.658 - retval = current_audio.inputDeviceCount;
23.659 - } else {
23.660 - free_device_list(¤t_audio.outputDevices,
23.661 - ¤t_audio.outputDeviceCount);
23.662 - current_audio.impl.DetectDevices(iscapture, SDL_AddOutputAudioDevice);
23.663 - retval = current_audio.outputDeviceCount;
23.664 + if (!iscapture && current_audio.outputDevicesRemoved) {
23.665 + clean_out_device_list(¤t_audio.outputDevices, ¤t_audio.outputDeviceCount, ¤t_audio.outputDevicesRemoved);
23.666 + current_audio.outputDevicesRemoved = SDL_FALSE;
23.667 }
23.668
23.669 + retval = iscapture ? current_audio.inputDeviceCount : current_audio.outputDeviceCount;
23.670 + SDL_UnlockMutex(current_audio.detectionLock);
23.671 +
23.672 return retval;
23.673 }
23.674
23.675 @@ -922,6 +832,8 @@
23.676 const char *
23.677 SDL_GetAudioDeviceName(int index, int iscapture)
23.678 {
23.679 + const char *retval = NULL;
23.680 +
23.681 if (!SDL_WasInit(SDL_INIT_AUDIO)) {
23.682 SDL_SetError("Audio subsystem is not initialized");
23.683 return NULL;
23.684 @@ -932,39 +844,28 @@
23.685 return NULL;
23.686 }
23.687
23.688 - if (index < 0) {
23.689 - goto no_such_device;
23.690 - }
23.691 + if (index >= 0) {
23.692 + SDL_AudioDeviceItem *item;
23.693 + int i;
23.694
23.695 - if ((iscapture) && (current_audio.impl.OnlyHasDefaultInputDevice)) {
23.696 - if (index > 0) {
23.697 - goto no_such_device;
23.698 + SDL_LockMutex(current_audio.detectionLock);
23.699 + item = iscapture ? current_audio.inputDevices : current_audio.outputDevices;
23.700 + i = iscapture ? current_audio.inputDeviceCount : current_audio.outputDeviceCount;
23.701 + if (index < i) {
23.702 + for (i--; i > index; i--, item = item->next) {
23.703 + SDL_assert(item != NULL);
23.704 + }
23.705 + SDL_assert(item != NULL);
23.706 + retval = item->name;
23.707 }
23.708 - return DEFAULT_INPUT_DEVNAME;
23.709 + SDL_UnlockMutex(current_audio.detectionLock);
23.710 }
23.711
23.712 - if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) {
23.713 - if (index > 0) {
23.714 - goto no_such_device;
23.715 - }
23.716 - return DEFAULT_OUTPUT_DEVNAME;
23.717 + if (retval == NULL) {
23.718 + SDL_SetError("No such device");
23.719 }
23.720
23.721 - if (iscapture) {
23.722 - if (index >= current_audio.inputDeviceCount) {
23.723 - goto no_such_device;
23.724 - }
23.725 - return current_audio.inputDevices[index];
23.726 - } else {
23.727 - if (index >= current_audio.outputDeviceCount) {
23.728 - goto no_such_device;
23.729 - }
23.730 - return current_audio.outputDevices[index];
23.731 - }
23.732 -
23.733 -no_such_device:
23.734 - SDL_SetError("No such device");
23.735 - return NULL;
23.736 + return retval;
23.737 }
23.738
23.739
23.740 @@ -972,6 +873,7 @@
23.741 close_audio_device(SDL_AudioDevice * device)
23.742 {
23.743 device->enabled = 0;
23.744 + device->shutdown = 1;
23.745 if (device->thread != NULL) {
23.746 SDL_WaitThread(device->thread, NULL);
23.747 }
23.748 @@ -1065,6 +967,8 @@
23.749 SDL_AudioSpec _obtained;
23.750 SDL_AudioDevice *device;
23.751 SDL_bool build_cvt;
23.752 + void *handle = NULL;
23.753 + Uint32 stream_len;
23.754 int i = 0;
23.755
23.756 if (!SDL_WasInit(SDL_INIT_AUDIO)) {
23.757 @@ -1077,6 +981,18 @@
23.758 return 0;
23.759 }
23.760
23.761 + /* Find an available device ID... */
23.762 + for (id = min_id - 1; id < SDL_arraysize(open_devices); id++) {
23.763 + if (open_devices[id] == NULL) {
23.764 + break;
23.765 + }
23.766 + }
23.767 +
23.768 + if (id == SDL_arraysize(open_devices)) {
23.769 + SDL_SetError("Too many open audio devices");
23.770 + return 0;
23.771 + }
23.772 +
23.773 if (!obtained) {
23.774 obtained = &_obtained;
23.775 }
23.776 @@ -1112,9 +1028,7 @@
23.777 return 0;
23.778 }
23.779 }
23.780 - }
23.781 -
23.782 - if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) {
23.783 + } else if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) {
23.784 if ((devname) && (SDL_strcmp(devname, DEFAULT_OUTPUT_DEVNAME) != 0)) {
23.785 SDL_SetError("No such device");
23.786 return 0;
23.787 @@ -1127,6 +1041,30 @@
23.788 return 0;
23.789 }
23.790 }
23.791 + } else if (devname != NULL) {
23.792 + /* if the app specifies an exact string, we can pass the backend
23.793 + an actual device handle thingey, which saves them the effort of
23.794 + figuring out what device this was (such as, reenumerating
23.795 + everything again to find the matching human-readable name).
23.796 + It might still need to open a device based on the string for,
23.797 + say, a network audio server, but this optimizes some cases. */
23.798 + SDL_AudioDeviceItem *item;
23.799 + SDL_LockMutex(current_audio.detectionLock);
23.800 + for (item = iscapture ? current_audio.inputDevices : current_audio.outputDevices; item; item = item->next) {
23.801 + if ((item->handle != NULL) && (SDL_strcmp(item->name, devname) == 0)) {
23.802 + handle = item->handle;
23.803 + break;
23.804 + }
23.805 + }
23.806 + SDL_UnlockMutex(current_audio.detectionLock);
23.807 + }
23.808 +
23.809 + if (!current_audio.impl.AllowsArbitraryDeviceNames) {
23.810 + /* has to be in our device list, or the default device. */
23.811 + if ((handle == NULL) && (devname != NULL)) {
23.812 + SDL_SetError("No such device.");
23.813 + return 0;
23.814 + }
23.815 }
23.816
23.817 device = (SDL_AudioDevice *) SDL_AllocAudioMem(sizeof(SDL_AudioDevice));
23.818 @@ -1135,12 +1073,13 @@
23.819 return 0;
23.820 }
23.821 SDL_zerop(device);
23.822 + device->id = id + 1;
23.823 device->spec = *obtained;
23.824 device->enabled = 1;
23.825 device->paused = 1;
23.826 device->iscapture = iscapture;
23.827
23.828 - /* Create a semaphore for locking the sound buffers */
23.829 + /* Create a mutex for locking the sound buffers */
23.830 if (!current_audio.impl.SkipMixerLock) {
23.831 device->mixer_lock = SDL_CreateMutex();
23.832 if (device->mixer_lock == NULL) {
23.833 @@ -1150,26 +1089,12 @@
23.834 }
23.835 }
23.836
23.837 - /* force a device detection if we haven't done one yet. */
23.838 - if ( ((iscapture) && (current_audio.inputDevices == NULL)) ||
23.839 - ((!iscapture) && (current_audio.outputDevices == NULL)) ) {
23.840 - SDL_GetNumAudioDevices(iscapture);
23.841 - }
23.842 -
23.843 - if (current_audio.impl.OpenDevice(device, devname, iscapture) < 0) {
23.844 + if (current_audio.impl.OpenDevice(device, handle, devname, iscapture) < 0) {
23.845 close_audio_device(device);
23.846 return 0;
23.847 }
23.848 device->opened = 1;
23.849
23.850 - /* Allocate a fake audio memory buffer */
23.851 - device->fake_stream = (Uint8 *)SDL_AllocAudioMem(device->spec.size);
23.852 - if (device->fake_stream == NULL) {
23.853 - close_audio_device(device);
23.854 - SDL_OutOfMemory();
23.855 - return 0;
23.856 - }
23.857 -
23.858 /* See if we need to do any conversion */
23.859 build_cvt = SDL_FALSE;
23.860 if (obtained->freq != device->spec.freq) {
23.861 @@ -1228,6 +1153,19 @@
23.862 }
23.863 }
23.864
23.865 + /* Allocate a fake audio memory buffer */
23.866 + stream_len = (device->convert.needed) ? device->convert.len_cvt : 0;
23.867 + if (device->spec.size > stream_len) {
23.868 + stream_len = device->spec.size;
23.869 + }
23.870 + SDL_assert(stream_len > 0);
23.871 + device->fake_stream = (Uint8 *)SDL_AllocAudioMem(stream_len);
23.872 + if (device->fake_stream == NULL) {
23.873 + close_audio_device(device);
23.874 + SDL_OutOfMemory();
23.875 + return 0;
23.876 + }
23.877 +
23.878 if (device->spec.callback == NULL) { /* use buffer queueing? */
23.879 /* pool a few packets to start. Enough for two callbacks. */
23.880 const int packetlen = SDL_AUDIOBUFFERQUEUE_PACKETLEN;
23.881 @@ -1247,25 +1185,14 @@
23.882 device->spec.userdata = device;
23.883 }
23.884
23.885 - /* Find an available device ID and store the structure... */
23.886 - for (id = min_id - 1; id < SDL_arraysize(open_devices); id++) {
23.887 - if (open_devices[id] == NULL) {
23.888 - open_devices[id] = device;
23.889 - break;
23.890 - }
23.891 - }
23.892 -
23.893 - if (id == SDL_arraysize(open_devices)) {
23.894 - SDL_SetError("Too many open audio devices");
23.895 - close_audio_device(device);
23.896 - return 0;
23.897 - }
23.898 + /* add it to our list of open devices. */
23.899 + open_devices[id] = device;
23.900
23.901 /* Start the audio thread if necessary */
23.902 if (!current_audio.impl.ProvidesOwnCallbackThread) {
23.903 /* Start the audio thread */
23.904 char name[64];
23.905 - SDL_snprintf(name, sizeof (name), "SDLAudioDev%d", (int) (id + 1));
23.906 + SDL_snprintf(name, sizeof (name), "SDLAudioDev%d", (int) device->id);
23.907 /* !!! FIXME: this is nasty. */
23.908 #if defined(__WIN32__) && !defined(HAVE_LIBC)
23.909 #undef SDL_CreateThread
23.910 @@ -1278,13 +1205,13 @@
23.911 device->thread = SDL_CreateThread(SDL_RunAudio, name, device);
23.912 #endif
23.913 if (device->thread == NULL) {
23.914 - SDL_CloseAudioDevice(id + 1);
23.915 + SDL_CloseAudioDevice(device->id);
23.916 SDL_SetError("Couldn't create audio thread");
23.917 return 0;
23.918 }
23.919 }
23.920
23.921 - return id + 1;
23.922 + return device->id;
23.923 }
23.924
23.925
23.926 @@ -1296,14 +1223,14 @@
23.927 /* Start up the audio driver, if necessary. This is legacy behaviour! */
23.928 if (!SDL_WasInit(SDL_INIT_AUDIO)) {
23.929 if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
23.930 - return (-1);
23.931 + return -1;
23.932 }
23.933 }
23.934
23.935 /* SDL_OpenAudio() is legacy and can only act on Device ID #1. */
23.936 if (open_devices[0] != NULL) {
23.937 SDL_SetError("Audio device is already opened");
23.938 - return (-1);
23.939 + return -1;
23.940 }
23.941
23.942 if (obtained) {
23.943 @@ -1314,7 +1241,7 @@
23.944 }
23.945
23.946 SDL_assert((id == 0) || (id == 1));
23.947 - return ((id == 0) ? -1 : 0);
23.948 + return (id == 0) ? -1 : 0;
23.949 }
23.950
23.951 SDL_AudioDeviceID
23.952 @@ -1338,7 +1265,7 @@
23.953 status = SDL_AUDIO_PLAYING;
23.954 }
23.955 }
23.956 - return (status);
23.957 + return status;
23.958 }
23.959
23.960
23.961 @@ -1429,14 +1356,16 @@
23.962 }
23.963 }
23.964
23.965 + free_device_list(¤t_audio.outputDevices, ¤t_audio.outputDeviceCount);
23.966 + free_device_list(¤t_audio.inputDevices, ¤t_audio.inputDeviceCount);
23.967 +
23.968 /* Free the driver data */
23.969 current_audio.impl.Deinitialize();
23.970 - free_device_list(¤t_audio.outputDevices,
23.971 - ¤t_audio.outputDeviceCount);
23.972 - free_device_list(¤t_audio.inputDevices,
23.973 - ¤t_audio.inputDeviceCount);
23.974 - SDL_memset(¤t_audio, '\0', sizeof(current_audio));
23.975 - SDL_memset(open_devices, '\0', sizeof(open_devices));
23.976 +
23.977 + SDL_DestroyMutex(current_audio.detectionLock);
23.978 +
23.979 + SDL_zero(current_audio);
23.980 + SDL_zero(open_devices);
23.981 }
23.982
23.983 #define NUM_FORMATS 10
23.984 @@ -1474,16 +1403,16 @@
23.985 }
23.986 }
23.987 format_idx_sub = 0;
23.988 - return (SDL_NextAudioFormat());
23.989 + return SDL_NextAudioFormat();
23.990 }
23.991
23.992 SDL_AudioFormat
23.993 SDL_NextAudioFormat(void)
23.994 {
23.995 if ((format_idx == NUM_FORMATS) || (format_idx_sub == NUM_FORMATS)) {
23.996 - return (0);
23.997 + return 0;
23.998 }
23.999 - return (format_list[format_idx][format_idx_sub++]);
23.1000 + return format_list[format_idx][format_idx_sub++];
23.1001 }
23.1002
23.1003 void
24.1 --- a/src/audio/SDL_audiodev.c Sat Jan 24 23:58:07 2015 -0400
24.2 +++ b/src/audio/SDL_audiodev.c Mon Apr 06 15:26:37 2015 -0300
24.3 @@ -46,18 +46,21 @@
24.4 #define _PATH_DEV_AUDIO "/dev/audio"
24.5 #endif
24.6
24.7 -static SDL_INLINE void
24.8 -test_device(const char *fname, int flags, int (*test) (int fd),
24.9 - SDL_AddAudioDevice addfn)
24.10 +static void
24.11 +test_device(const int iscapture, const char *fname, int flags, int (*test) (int fd))
24.12 {
24.13 struct stat sb;
24.14 if ((stat(fname, &sb) == 0) && (S_ISCHR(sb.st_mode))) {
24.15 const int audio_fd = open(fname, flags, 0);
24.16 if (audio_fd >= 0) {
24.17 - if (test(audio_fd)) {
24.18 - addfn(fname);
24.19 + const int okay = test(audio_fd);
24.20 + close(audio_fd);
24.21 + if (okay) {
24.22 + static size_t dummyhandle = 0;
24.23 + dummyhandle++;
24.24 + SDL_assert(dummyhandle != 0);
24.25 + SDL_AddAudioDevice(iscapture, fname, (void *) dummyhandle);
24.26 }
24.27 - close(audio_fd);
24.28 }
24.29 }
24.30 }
24.31 @@ -68,11 +71,10 @@
24.32 return 1;
24.33 }
24.34
24.35 -void
24.36 -SDL_EnumUnixAudioDevices(int iscapture, int classic, int (*test)(int fd),
24.37 - SDL_AddAudioDevice addfn)
24.38 +static void
24.39 +SDL_EnumUnixAudioDevices_Internal(const int iscapture, const int classic, int (*test)(int))
24.40 {
24.41 - const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT);
24.42 + const int flags = iscapture ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT;
24.43 const char *audiodev;
24.44 char audiopath[1024];
24.45
24.46 @@ -97,17 +99,25 @@
24.47 }
24.48 }
24.49 }
24.50 - test_device(audiodev, flags, test, addfn);
24.51 + test_device(iscapture, audiodev, flags, test);
24.52
24.53 if (SDL_strlen(audiodev) < (sizeof(audiopath) - 3)) {
24.54 int instance = 0;
24.55 while (instance++ <= 64) {
24.56 SDL_snprintf(audiopath, SDL_arraysize(audiopath),
24.57 "%s%d", audiodev, instance);
24.58 - test_device(audiopath, flags, test, addfn);
24.59 + test_device(iscapture, audiopath, flags, test);
24.60 }
24.61 }
24.62 }
24.63
24.64 +void
24.65 +SDL_EnumUnixAudioDevices(const int classic, int (*test)(int))
24.66 +{
24.67 + SDL_EnumUnixAudioDevices_Internal(SDL_TRUE, classic, test);
24.68 + SDL_EnumUnixAudioDevices_Internal(SDL_FALSE, classic, test);
24.69 +}
24.70 +
24.71 #endif /* Audio driver selection */
24.72 +
24.73 /* vi: set ts=4 sw=4 expandtab: */
25.1 --- a/src/audio/SDL_audiodev_c.h Sat Jan 24 23:58:07 2015 -0400
25.2 +++ b/src/audio/SDL_audiodev_c.h Mon Apr 06 15:26:37 2015 -0300
25.3 @@ -33,7 +33,6 @@
25.4 #define OPEN_FLAGS_INPUT (O_RDONLY|O_NONBLOCK)
25.5 #endif
25.6
25.7 -void SDL_EnumUnixAudioDevices(int iscapture, int classic,
25.8 - int (*test) (int fd), SDL_AddAudioDevice addfn);
25.9 +extern void SDL_EnumUnixAudioDevices(const int classic, int (*test)(int));
25.10
25.11 /* vi: set ts=4 sw=4 expandtab: */
26.1 --- a/src/audio/SDL_sysaudio.h Sat Jan 24 23:58:07 2015 -0400
26.2 +++ b/src/audio/SDL_sysaudio.h Mon Apr 06 15:26:37 2015 -0300
26.3 @@ -30,8 +30,21 @@
26.4 typedef struct SDL_AudioDevice SDL_AudioDevice;
26.5 #define _THIS SDL_AudioDevice *_this
26.6
26.7 -/* Used by audio targets during DetectDevices() */
26.8 -typedef void (*SDL_AddAudioDevice)(const char *name);
26.9 +/* Audio targets should call this as devices are added to the system (such as
26.10 + a USB headset being plugged in), and should also be called for
26.11 + for every device found during DetectDevices(). */
26.12 +extern void SDL_AddAudioDevice(const int iscapture, const char *name, void *handle);
26.13 +
26.14 +/* Audio targets should call this as devices are removed, so SDL can update
26.15 + its list of available devices. */
26.16 +extern void SDL_RemoveAudioDevice(const int iscapture, void *handle);
26.17 +
26.18 +/* Audio targets should call this if an opened audio device is lost while
26.19 + being used. This can happen due to i/o errors, or a device being unplugged,
26.20 + etc. If the device is totally gone, please also call SDL_RemoveAudioDevice()
26.21 + as appropriate so SDL's list of devices is accurate. */
26.22 +extern void SDL_OpenedAudioDeviceDisconnected(SDL_AudioDevice *device);
26.23 +
26.24
26.25 /* This is the size of a packet when using SDL_QueueAudio(). We allocate
26.26 these as necessary and pool them, under the assumption that we'll
26.27 @@ -55,8 +68,8 @@
26.28
26.29 typedef struct SDL_AudioDriverImpl
26.30 {
26.31 - void (*DetectDevices) (int iscapture, SDL_AddAudioDevice addfn);
26.32 - int (*OpenDevice) (_THIS, const char *devname, int iscapture);
26.33 + void (*DetectDevices) (void);
26.34 + int (*OpenDevice) (_THIS, void *handle, const char *devname, int iscapture);
26.35 void (*ThreadInit) (_THIS); /* Called by audio thread at start */
26.36 void (*WaitDevice) (_THIS);
26.37 void (*PlayDevice) (_THIS);
26.38 @@ -66,19 +79,34 @@
26.39 void (*CloseDevice) (_THIS);
26.40 void (*LockDevice) (_THIS);
26.41 void (*UnlockDevice) (_THIS);
26.42 + void (*FreeDeviceHandle) (void *handle); /**< SDL is done with handle from SDL_AddAudioDevice() */
26.43 void (*Deinitialize) (void);
26.44
26.45 /* !!! FIXME: add pause(), so we can optimize instead of mixing silence. */
26.46
26.47 /* Some flags to push duplicate code into the core and reduce #ifdefs. */
26.48 + /* !!! FIXME: these should be SDL_bool */
26.49 int ProvidesOwnCallbackThread;
26.50 int SkipMixerLock; /* !!! FIXME: do we need this anymore? */
26.51 int HasCaptureSupport;
26.52 int OnlyHasDefaultOutputDevice;
26.53 int OnlyHasDefaultInputDevice;
26.54 + int AllowsArbitraryDeviceNames;
26.55 } SDL_AudioDriverImpl;
26.56
26.57
26.58 +typedef struct SDL_AudioDeviceItem
26.59 +{
26.60 + void *handle;
26.61 + struct SDL_AudioDeviceItem *next;
26.62 + #if (defined(__GNUC__) && (__GNUC__ <= 2))
26.63 + char name[1]; /* actually variable length. */
26.64 + #else
26.65 + char name[];
26.66 + #endif
26.67 +} SDL_AudioDeviceItem;
26.68 +
26.69 +
26.70 typedef struct SDL_AudioDriver
26.71 {
26.72 /* * * */
26.73 @@ -91,11 +119,14 @@
26.74
26.75 SDL_AudioDriverImpl impl;
26.76
26.77 - char **outputDevices;
26.78 + /* A mutex for device detection */
26.79 + SDL_mutex *detectionLock;
26.80 + SDL_bool captureDevicesRemoved;
26.81 + SDL_bool outputDevicesRemoved;
26.82 int outputDeviceCount;
26.83 -
26.84 - char **inputDevices;
26.85 int inputDeviceCount;
26.86 + SDL_AudioDeviceItem *outputDevices;
26.87 + SDL_AudioDeviceItem *inputDevices;
26.88 } SDL_AudioDriver;
26.89
26.90
26.91 @@ -113,6 +144,7 @@
26.92 {
26.93 /* * * */
26.94 /* Data common to all devices */
26.95 + SDL_AudioDeviceID id;
26.96
26.97 /* The current audio specification (shared with audio thread) */
26.98 SDL_AudioSpec spec;
26.99 @@ -125,15 +157,17 @@
26.100 SDL_AudioStreamer streamer;
26.101
26.102 /* Current state flags */
26.103 + /* !!! FIXME: should be SDL_bool */
26.104 int iscapture;
26.105 - int enabled;
26.106 + int enabled; /* true if device is functioning and connected. */
26.107 + int shutdown; /* true if we are signaling the play thread to end. */
26.108 int paused;
26.109 int opened;
26.110
26.111 /* Fake audio buffer for when the audio hardware is busy */
26.112 Uint8 *fake_stream;
26.113
26.114 - /* A semaphore for locking the mixing buffers */
26.115 + /* A mutex for locking the mixing buffers */
26.116 SDL_mutex *mixer_lock;
26.117
26.118 /* A thread to feed the audio device */
27.1 --- a/src/audio/alsa/SDL_alsa_audio.c Sat Jan 24 23:58:07 2015 -0400
27.2 +++ b/src/audio/alsa/SDL_alsa_audio.c Mon Apr 06 15:26:37 2015 -0300
27.3 @@ -320,7 +320,7 @@
27.4 /* Hmm, not much we can do - abort */
27.5 fprintf(stderr, "ALSA write failed (unrecoverable): %s\n",
27.6 ALSA_snd_strerror(status));
27.7 - this->enabled = 0;
27.8 + SDL_OpenedAudioDeviceDisconnected(this);
27.9 return;
27.10 }
27.11 continue;
27.12 @@ -465,7 +465,7 @@
27.13 }
27.14
27.15 static int
27.16 -ALSA_OpenDevice(_THIS, const char *devname, int iscapture)
27.17 +ALSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
27.18 {
27.19 int status = 0;
27.20 snd_pcm_t *pcm_handle = NULL;
28.1 --- a/src/audio/android/SDL_androidaudio.c Sat Jan 24 23:58:07 2015 -0400
28.2 +++ b/src/audio/android/SDL_androidaudio.c Mon Apr 06 15:26:37 2015 -0300
28.3 @@ -35,7 +35,7 @@
28.4 static SDL_AudioDevice* audioDevice = NULL;
28.5
28.6 static int
28.7 -AndroidAUD_OpenDevice(_THIS, const char *devname, int iscapture)
28.8 +AndroidAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
28.9 {
28.10 SDL_AudioFormat test_format;
28.11
29.1 --- a/src/audio/arts/SDL_artsaudio.c Sat Jan 24 23:58:07 2015 -0400
29.2 +++ b/src/audio/arts/SDL_artsaudio.c Mon Apr 06 15:26:37 2015 -0300
29.3 @@ -151,7 +151,7 @@
29.4 /* Check every 10 loops */
29.5 if (this->hidden->parent && (((++cnt) % 10) == 0)) {
29.6 if (kill(this->hidden->parent, 0) < 0 && errno == ESRCH) {
29.7 - this->enabled = 0;
29.8 + SDL_OpenedAudioDeviceDisconnected(this);
29.9 }
29.10 }
29.11 }
29.12 @@ -179,7 +179,7 @@
29.13
29.14 /* If we couldn't write, assume fatal error for now */
29.15 if (written < 0) {
29.16 - this->enabled = 0;
29.17 + SDL_OpenedAudioDeviceDisconnected(this);
29.18 }
29.19 #ifdef DEBUG_AUDIO
29.20 fprintf(stderr, "Wrote %d bytes of audio data\n", written);
29.21 @@ -229,7 +229,7 @@
29.22 }
29.23
29.24 static int
29.25 -ARTS_OpenDevice(_THIS, const char *devname, int iscapture)
29.26 +ARTS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
29.27 {
29.28 int rc = 0;
29.29 int bits = 0, frag_spec = 0;
30.1 --- a/src/audio/bsd/SDL_bsdaudio.c Sat Jan 24 23:58:07 2015 -0400
30.2 +++ b/src/audio/bsd/SDL_bsdaudio.c Mon Apr 06 15:26:37 2015 -0300
30.3 @@ -51,9 +51,9 @@
30.4
30.5
30.6 static void
30.7 -BSDAUDIO_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
30.8 +BSDAUDIO_DetectDevices(void)
30.9 {
30.10 - SDL_EnumUnixAudioDevices(iscapture, 0, NULL, addfn);
30.11 + SDL_EnumUnixAudioDevices(0, NULL);
30.12 }
30.13
30.14
30.15 @@ -150,7 +150,7 @@
30.16 the user know what happened.
30.17 */
30.18 fprintf(stderr, "SDL: %s\n", message);
30.19 - this->enabled = 0;
30.20 + SDL_OpenedAudioDeviceDisconnected(this);
30.21 /* Don't try to close - may hang */
30.22 this->hidden->audio_fd = -1;
30.23 #ifdef DEBUG_AUDIO
30.24 @@ -195,7 +195,7 @@
30.25
30.26 /* If we couldn't write, assume fatal error for now */
30.27 if (written < 0) {
30.28 - this->enabled = 0;
30.29 + SDL_OpenedAudioDeviceDisconnected(this);
30.30 }
30.31 #ifdef DEBUG_AUDIO
30.32 fprintf(stderr, "Wrote %d bytes of audio data\n", written);
30.33 @@ -224,7 +224,7 @@
30.34 }
30.35
30.36 static int
30.37 -BSDAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
30.38 +BSDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
30.39 {
30.40 const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT);
30.41 SDL_AudioFormat format = 0;
30.42 @@ -348,6 +348,8 @@
30.43 impl->GetDeviceBuf = BSDAUDIO_GetDeviceBuf;
30.44 impl->CloseDevice = BSDAUDIO_CloseDevice;
30.45
30.46 + impl->AllowsArbitraryDeviceNames = 1;
30.47 +
30.48 return 1; /* this audio target is available. */
30.49 }
30.50
31.1 --- a/src/audio/coreaudio/SDL_coreaudio.c Sat Jan 24 23:58:07 2015 -0400
31.2 +++ b/src/audio/coreaudio/SDL_coreaudio.c Mon Apr 06 15:26:37 2015 -0300
31.3 @@ -19,6 +19,9 @@
31.4 3. This notice may not be removed or altered from any source distribution.
31.5 */
31.6 #include "../../SDL_internal.h"
31.7 +
31.8 +#if SDL_AUDIO_DRIVER_COREAUDIO
31.9 +
31.10 #include "SDL_audio.h"
31.11 #include "../SDL_audio_c.h"
31.12 #include "../SDL_sysaudio.h"
31.13 @@ -37,31 +40,48 @@
31.14 }
31.15
31.16 #if MACOSX_COREAUDIO
31.17 -typedef void (*addDevFn)(const char *name, AudioDeviceID devId, void *data);
31.18 +static const AudioObjectPropertyAddress devlist_address = {
31.19 + kAudioHardwarePropertyDevices,
31.20 + kAudioObjectPropertyScopeGlobal,
31.21 + kAudioObjectPropertyElementMaster
31.22 +};
31.23 +
31.24 +typedef void (*addDevFn)(const char *name, const int iscapture, AudioDeviceID devId, void *data);
31.25 +
31.26 +typedef struct AudioDeviceList
31.27 +{
31.28 + AudioDeviceID devid;
31.29 + SDL_bool alive;
31.30 + struct AudioDeviceList *next;
31.31 +} AudioDeviceList;
31.32 +
31.33 +static AudioDeviceList *output_devs = NULL;
31.34 +static AudioDeviceList *capture_devs = NULL;
31.35
31.36 -static void
31.37 -addToDevList(const char *name, AudioDeviceID devId, void *data)
31.38 +static SDL_bool
31.39 +add_to_internal_dev_list(const int iscapture, AudioDeviceID devId)
31.40 {
31.41 - SDL_AddAudioDevice addfn = (SDL_AddAudioDevice) data;
31.42 - addfn(name);
31.43 + AudioDeviceList *item = (AudioDeviceList *) SDL_malloc(sizeof (AudioDeviceList));
31.44 + if (item == NULL) {
31.45 + return SDL_FALSE;
31.46 + }
31.47 + item->devid = devId;
31.48 + item->alive = SDL_TRUE;
31.49 + item->next = iscapture ? capture_devs : output_devs;
31.50 + if (iscapture) {
31.51 + capture_devs = item;
31.52 + } else {
31.53 + output_devs = item;
31.54 + }
31.55 +
31.56 + return SDL_TRUE;
31.57 }
31.58
31.59 -typedef struct
31.60 +static void
31.61 +addToDevList(const char *name, const int iscapture, AudioDeviceID devId, void *data)
31.62 {
31.63 - const char *findname;
31.64 - AudioDeviceID devId;
31.65 - int found;
31.66 -} FindDevIdData;
31.67 -
31.68 -static void
31.69 -findDevId(const char *name, AudioDeviceID devId, void *_data)
31.70 -{
31.71 - FindDevIdData *data = (FindDevIdData *) _data;
31.72 - if (!data->found) {
31.73 - if (SDL_strcmp(name, data->findname) == 0) {
31.74 - data->found = 1;
31.75 - data->devId = devId;
31.76 - }
31.77 + if (add_to_internal_dev_list(iscapture, devId)) {
31.78 + SDL_AddAudioDevice(iscapture, name, (void *) ((size_t) devId));
31.79 }
31.80 }
31.81
31.82 @@ -74,14 +94,8 @@
31.83 UInt32 i = 0;
31.84 UInt32 max = 0;
31.85
31.86 - AudioObjectPropertyAddress addr = {
31.87 - kAudioHardwarePropertyDevices,
31.88 - kAudioObjectPropertyScopeGlobal,
31.89 - kAudioObjectPropertyElementMaster
31.90 - };
31.91 -
31.92 - result = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &addr,
31.93 - 0, NULL, &size);
31.94 + result = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject,
31.95 + &devlist_address, 0, NULL, &size);
31.96 if (result != kAudioHardwareNoError)
31.97 return;
31.98
31.99 @@ -89,8 +103,8 @@
31.100 if (devs == NULL)
31.101 return;
31.102
31.103 - result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr,
31.104 - 0, NULL, &size, devs);
31.105 + result = AudioObjectGetPropertyData(kAudioObjectSystemObject,
31.106 + &devlist_address, 0, NULL, &size, devs);
31.107 if (result != kAudioHardwareNoError)
31.108 return;
31.109
31.110 @@ -102,10 +116,17 @@
31.111 AudioBufferList *buflist = NULL;
31.112 int usable = 0;
31.113 CFIndex len = 0;
31.114 + const AudioObjectPropertyAddress addr = {
31.115 + kAudioDevicePropertyStreamConfiguration,
31.116 + iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput,
31.117 + kAudioObjectPropertyElementMaster
31.118 + };
31.119
31.120 - addr.mScope = iscapture ? kAudioDevicePropertyScopeInput :
31.121 - kAudioDevicePropertyScopeOutput;
31.122 - addr.mSelector = kAudioDevicePropertyStreamConfiguration;
31.123 + const AudioObjectPropertyAddress nameaddr = {
31.124 + kAudioObjectPropertyName,
31.125 + iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput,
31.126 + kAudioObjectPropertyElementMaster
31.127 + };
31.128
31.129 result = AudioObjectGetPropertyDataSize(dev, &addr, 0, NULL, &size);
31.130 if (result != noErr)
31.131 @@ -133,9 +154,9 @@
31.132 if (!usable)
31.133 continue;
31.134
31.135 - addr.mSelector = kAudioObjectPropertyName;
31.136 +
31.137 size = sizeof (CFStringRef);
31.138 - result = AudioObjectGetPropertyData(dev, &addr, 0, NULL, &size, &cfstr);
31.139 + result = AudioObjectGetPropertyData(dev, &nameaddr, 0, NULL, &size, &cfstr);
31.140 if (result != kAudioHardwareNoError)
31.141 continue;
31.142
31.143 @@ -166,79 +187,84 @@
31.144 ((iscapture) ? "capture" : "output"),
31.145 (int) *devCount, ptr, (int) dev);
31.146 #endif
31.147 - addfn(ptr, dev, addfndata);
31.148 + addfn(ptr, iscapture, dev, addfndata);
31.149 }
31.150 SDL_free(ptr); /* addfn() would have copied the string. */
31.151 }
31.152 }
31.153
31.154 static void
31.155 -COREAUDIO_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
31.156 +free_audio_device_list(AudioDeviceList **list)
31.157 +{
31.158 + AudioDeviceList *item = *list;
31.159 + while (item) {
31.160 + AudioDeviceList *next = item->next;
31.161 + SDL_free(item);
31.162 + item = next;
31.163 + }
31.164 + *list = NULL;
31.165 +}
31.166 +
31.167 +static void
31.168 +COREAUDIO_DetectDevices(void)
31.169 {
31.170 - build_device_list(iscapture, addToDevList, addfn);
31.171 + build_device_list(SDL_TRUE, addToDevList, NULL);
31.172 + build_device_list(SDL_FALSE, addToDevList, NULL);
31.173 +}
31.174 +
31.175 +static void
31.176 +build_device_change_list(const char *name, const int iscapture, AudioDeviceID devId, void *data)
31.177 +{
31.178 + AudioDeviceList **list = (AudioDeviceList **) data;
31.179 + AudioDeviceList *item;
31.180 + for (item = *list; item != NULL; item = item->next) {
31.181 + if (item->devid == devId) {
31.182 + item->alive = SDL_TRUE;
31.183 + return;
31.184 + }
31.185 + }
31.186 +
31.187 + add_to_internal_dev_list(iscapture, devId); /* new device, add it. */
31.188 + SDL_AddAudioDevice(iscapture, name, (void *) ((size_t) devId));
31.189 }
31.190
31.191 -static int
31.192 -find_device_by_name(_THIS, const char *devname, int iscapture)
31.193 +static void
31.194 +reprocess_device_list(const int iscapture, AudioDeviceList **list)
31.195 {
31.196 - AudioDeviceID devid = 0;
31.197 - OSStatus result = noErr;
31.198 - UInt32 size = 0;
31.199 - UInt32 alive = 0;
31.200 - pid_t pid = 0;
31.201 -
31.202 - AudioObjectPropertyAddress addr = {
31.203 - 0,
31.204 - kAudioObjectPropertyScopeGlobal,
31.205 - kAudioObjectPropertyElementMaster
31.206 - };
31.207 -
31.208 - if (devname == NULL) {
31.209 - size = sizeof (AudioDeviceID);
31.210 - addr.mSelector =
31.211 - ((iscapture) ? kAudioHardwarePropertyDefaultInputDevice :
31.212 - kAudioHardwarePropertyDefaultOutputDevice);
31.213 - result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr,
31.214 - 0, NULL, &size, &devid);
31.215 - CHECK_RESULT("AudioHardwareGetProperty (default device)");
31.216 - } else {
31.217 - FindDevIdData data;
31.218 - SDL_zero(data);
31.219 - data.findname = devname;
31.220 - build_device_list(iscapture, findDevId, &data);
31.221 - if (!data.found) {
31.222 - SDL_SetError("CoreAudio: No such audio device.");
31.223 - return 0;
31.224 - }
31.225 - devid = data.devId;
31.226 + AudioDeviceList *item;
31.227 + AudioDeviceList *prev = NULL;
31.228 + for (item = *list; item != NULL; item = item->next) {
31.229 + item->alive = SDL_FALSE;
31.230 }
31.231
31.232 - addr.mSelector = kAudioDevicePropertyDeviceIsAlive;
31.233 - addr.mScope = iscapture ? kAudioDevicePropertyScopeInput :
31.234 - kAudioDevicePropertyScopeOutput;
31.235 + build_device_list(iscapture, build_device_change_list, list);
31.236
31.237 - size = sizeof (alive);
31.238 - result = AudioObjectGetPropertyData(devid, &addr, 0, NULL, &size, &alive);
31.239 - CHECK_RESULT
31.240 - ("AudioDeviceGetProperty (kAudioDevicePropertyDeviceIsAlive)");
31.241 -
31.242 - if (!alive) {
31.243 - SDL_SetError("CoreAudio: requested device exists, but isn't alive.");
31.244 - return 0;
31.245 + /* free items in the list that aren't still alive. */
31.246 + item = *list;
31.247 + while (item != NULL) {
31.248 + AudioDeviceList *next = item->next;
31.249 + if (item->alive) {
31.250 + prev = item;
31.251 + } else {
31.252 + SDL_RemoveAudioDevice(iscapture, (void *) ((size_t) item->devid));
31.253 + if (prev) {
31.254 + prev->next = item->next;
31.255 + } else {
31.256 + *list = item->next;
31.257 + }
31.258 + SDL_free(item);
31.259 + }
31.260 + item = next;
31.261 }
31.262 -
31.263 - addr.mSelector = kAudioDevicePropertyHogMode;
31.264 - size = sizeof (pid);
31.265 - result = AudioObjectGetPropertyData(devid, &addr, 0, NULL, &size, &pid);
31.266 +}
31.267
31.268 - /* some devices don't support this property, so errors are fine here. */
31.269 - if ((result == noErr) && (pid != -1)) {
31.270 - SDL_SetError("CoreAudio: requested device is being hogged.");
31.271 - return 0;
31.272 - }
31.273 -
31.274 - this->hidden->deviceID = devid;
31.275 - return 1;
31.276 +/* this is called when the system's list of available audio devices changes. */
31.277 +static OSStatus
31.278 +device_list_changed(AudioObjectID systemObj, UInt32 num_addr, const AudioObjectPropertyAddress *addrs, void *data)
31.279 +{
31.280 + reprocess_device_list(SDL_TRUE, &capture_devs);
31.281 + reprocess_device_list(SDL_FALSE, &output_devs);
31.282 + return 0;
31.283 }
31.284 #endif
31.285
31.286 @@ -314,11 +340,54 @@
31.287 }
31.288
31.289
31.290 +#if MACOSX_COREAUDIO
31.291 +static const AudioObjectPropertyAddress alive_address =
31.292 +{
31.293 + kAudioDevicePropertyDeviceIsAlive,
31.294 + kAudioObjectPropertyScopeGlobal,
31.295 + kAudioObjectPropertyElementMaster
31.296 +};
31.297 +
31.298 +static OSStatus
31.299 +device_unplugged(AudioObjectID devid, UInt32 num_addr, const AudioObjectPropertyAddress *addrs, void *data)
31.300 +{
31.301 + SDL_AudioDevice *this = (SDL_AudioDevice *) data;
31.302 + SDL_bool dead = SDL_FALSE;
31.303 + UInt32 isAlive = 1;
31.304 + UInt32 size = sizeof (isAlive);
31.305 + OSStatus error;
31.306 +
31.307 + if (!this->enabled) {
31.308 + return 0; /* already known to be dead. */
31.309 + }
31.310 +
31.311 + error = AudioObjectGetPropertyData(this->hidden->deviceID, &alive_address,
31.312 + 0, NULL, &size, &isAlive);
31.313 +
31.314 + if (error == kAudioHardwareBadDeviceError) {
31.315 + dead = SDL_TRUE; /* device was unplugged. */
31.316 + } else if ((error == kAudioHardwareNoError) && (!isAlive)) {
31.317 + dead = SDL_TRUE; /* device died in some other way. */
31.318 + }
31.319 +
31.320 + if (dead) {
31.321 + SDL_OpenedAudioDeviceDisconnected(this);
31.322 + }
31.323 +
31.324 + return 0;
31.325 +}
31.326 +#endif
31.327 +
31.328 static void
31.329 COREAUDIO_CloseDevice(_THIS)
31.330 {
31.331 if (this->hidden != NULL) {
31.332 if (this->hidden->audioUnitOpened) {
31.333 + #if MACOSX_COREAUDIO
31.334 + /* Unregister our disconnect callback. */
31.335 + AudioObjectRemovePropertyListener(this->hidden->deviceID, &alive_address, device_unplugged, this);
31.336 + #endif
31.337 +
31.338 AURenderCallbackStruct callback;
31.339 const AudioUnitElement output_bus = 0;
31.340 const AudioUnitElement input_bus = 1;
31.341 @@ -352,9 +421,63 @@
31.342 }
31.343 }
31.344
31.345 +#if MACOSX_COREAUDIO
31.346 +static int
31.347 +prepare_device(_THIS, void *handle, int iscapture)
31.348 +{
31.349 + AudioDeviceID devid = (AudioDeviceID) ((size_t) handle);
31.350 + OSStatus result = noErr;
31.351 + UInt32 size = 0;
31.352 + UInt32 alive = 0;
31.353 + pid_t pid = 0;
31.354 +
31.355 + AudioObjectPropertyAddress addr = {
31.356 + 0,
31.357 + kAudioObjectPropertyScopeGlobal,
31.358 + kAudioObjectPropertyElementMaster
31.359 + };
31.360 +
31.361 + if (handle == NULL) {
31.362 + size = sizeof (AudioDeviceID);
31.363 + addr.mSelector =
31.364 + ((iscapture) ? kAudioHardwarePropertyDefaultInputDevice :
31.365 + kAudioHardwarePropertyDefaultOutputDevice);
31.366 + result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr,
31.367 + 0, NULL, &size, &devid);
31.368 + CHECK_RESULT("AudioHardwareGetProperty (default device)");
31.369 + }
31.370 +
31.371 + addr.mSelector = kAudioDevicePropertyDeviceIsAlive;
31.372 + addr.mScope = iscapture ? kAudioDevicePropertyScopeInput :
31.373 + kAudioDevicePropertyScopeOutput;
31.374 +
31.375 + size = sizeof (alive);
31.376 + result = AudioObjectGetPropertyData(devid, &addr, 0, NULL, &size, &alive);
31.377 + CHECK_RESULT
31.378 + ("AudioDeviceGetProperty (kAudioDevicePropertyDeviceIsAlive)");
31.379 +
31.380 + if (!alive) {
31.381 + SDL_SetError("CoreAudio: requested device exists, but isn't alive.");
31.382 + return 0;
31.383 + }
31.384 +
31.385 + addr.mSelector = kAudioDevicePropertyHogMode;
31.386 + size = sizeof (pid);
31.387 + result = AudioObjectGetPropertyData(devid, &addr, 0, NULL, &size, &pid);
31.388 +
31.389 + /* some devices don't support this property, so errors are fine here. */
31.390 + if ((result == noErr) && (pid != -1)) {
31.391 + SDL_SetError("CoreAudio: requested device is being hogged.");
31.392 + return 0;
31.393 + }
31.394 +
31.395 + this->hidden->deviceID = devid;
31.396 + return 1;
31.397 +}
31.398 +#endif
31.399
31.400 static int
31.401 -prepare_audiounit(_THIS, const char *devname, int iscapture,
31.402 +prepare_audiounit(_THIS, void *handle, int iscapture,
31.403 const AudioStreamBasicDescription * strdesc)
31.404 {
31.405 OSStatus result = noErr;
31.406 @@ -373,8 +496,7 @@
31.407 kAudioUnitScope_Input);
31.408
31.409 #if MACOSX_COREAUDIO
31.410 - if (!find_device_by_name(this, devname, iscapture)) {
31.411 - SDL_SetError("Couldn't find requested CoreAudio device");
31.412 + if (!prepare_device(this, handle, iscapture)) {
31.413 return 0;
31.414 }
31.415 #endif
31.416 @@ -451,13 +573,18 @@
31.417 result = AudioOutputUnitStart(this->hidden->audioUnit);
31.418 CHECK_RESULT("AudioOutputUnitStart");
31.419
31.420 +#if MACOSX_COREAUDIO
31.421 + /* Fire a callback if the device stops being "alive" (disconnected, etc). */
31.422 + AudioObjectAddPropertyListener(this->hidden->deviceID, &alive_address, device_unplugged, this);
31.423 +#endif
31.424 +
31.425 /* We're running! */
31.426 return 1;
31.427 }
31.428
31.429
31.430 static int
31.431 -COREAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
31.432 +COREAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
31.433 {
31.434 AudioStreamBasicDescription strdesc;
31.435 SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
31.436 @@ -516,7 +643,7 @@
31.437 strdesc.mBytesPerPacket =
31.438 strdesc.mBytesPerFrame * strdesc.mFramesPerPacket;
31.439
31.440 - if (!prepare_audiounit(this, devname, iscapture, &strdesc)) {
31.441 + if (!prepare_audiounit(this, handle, iscapture, &strdesc)) {
31.442 COREAUDIO_CloseDevice(this);
31.443 return -1; /* prepare_audiounit() will call SDL_SetError()... */
31.444 }
31.445 @@ -524,15 +651,27 @@
31.446 return 0; /* good to go. */
31.447 }
31.448
31.449 +static void
31.450 +COREAUDIO_Deinitialize(void)
31.451 +{
31.452 +#if MACOSX_COREAUDIO
31.453 + AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &devlist_address, device_list_changed, NULL);
31.454 + free_audio_device_list(&capture_devs);
31.455 + free_audio_device_list(&output_devs);
31.456 +#endif
31.457 +}
31.458 +
31.459 static int
31.460 COREAUDIO_Init(SDL_AudioDriverImpl * impl)
31.461 {
31.462 /* Set the function pointers */
31.463 impl->OpenDevice = COREAUDIO_OpenDevice;
31.464 impl->CloseDevice = COREAUDIO_CloseDevice;
31.465 + impl->Deinitialize = COREAUDIO_Deinitialize;
31.466
31.467 #if MACOSX_COREAUDIO
31.468 impl->DetectDevices = COREAUDIO_DetectDevices;
31.469 + AudioObjectAddPropertyListener(kAudioObjectSystemObject, &devlist_address, device_list_changed, NULL);
31.470 #else
31.471 impl->OnlyHasDefaultOutputDevice = 1;
31.472
31.473 @@ -554,4 +693,6 @@
31.474 "coreaudio", "CoreAudio", COREAUDIO_Init, 0
31.475 };
31.476
31.477 +#endif /* SDL_AUDIO_DRIVER_COREAUDIO */
31.478 +
31.479 /* vi: set ts=4 sw=4 expandtab: */
32.1 --- a/src/audio/directsound/SDL_directsound.c Sat Jan 24 23:58:07 2015 -0400
32.2 +++ b/src/audio/directsound/SDL_directsound.c Mon Apr 06 15:26:37 2015 -0300
32.3 @@ -144,15 +144,22 @@
32.4 return SDL_SetError("%s", errbuf);
32.5 }
32.6
32.7 +static void
32.8 +DSOUND_FreeDeviceHandle(void *handle)
32.9 +{
32.10 + SDL_free(handle);
32.11 +}
32.12
32.13 static BOOL CALLBACK
32.14 FindAllDevs(LPGUID guid, LPCWSTR desc, LPCWSTR module, LPVOID data)
32.15 {
32.16 - SDL_AddAudioDevice addfn = (SDL_AddAudioDevice) data;
32.17 + const int iscapture = (int) ((size_t) data);
32.18 if (guid != NULL) { /* skip default device */
32.19 char *str = WIN_StringToUTF8(desc);
32.20 if (str != NULL) {
32.21 - addfn(str);
32.22 + LPGUID cpyguid = (LPGUID) SDL_malloc(sizeof (GUID));
32.23 + SDL_memcpy(cpyguid, guid, sizeof (GUID));
32.24 + SDL_AddAudioDevice(iscapture, str, cpyguid);
32.25 SDL_free(str); /* addfn() makes a copy of this string. */
32.26 }
32.27 }
32.28 @@ -160,13 +167,10 @@
32.29 }
32.30
32.31 static void
32.32 -DSOUND_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
32.33 +DSOUND_DetectDevices(void)
32.34 {
32.35 - if (iscapture) {
32.36 - pDirectSoundCaptureEnumerateW(FindAllDevs, addfn);
32.37 - } else {
32.38 - pDirectSoundEnumerateW(FindAllDevs, addfn);
32.39 - }
32.40 + pDirectSoundCaptureEnumerateW(FindAllDevs, (void *) ((size_t) 1));
32.41 + pDirectSoundEnumerateW(FindAllDevs, (void *) ((size_t) 0));
32.42 }
32.43
32.44
32.45 @@ -419,53 +423,14 @@
32.46 return (numchunks);
32.47 }
32.48
32.49 -typedef struct FindDevGUIDData
32.50 -{
32.51 - const char *devname;
32.52 - GUID guid;
32.53 - int found;
32.54 -} FindDevGUIDData;
32.55 -
32.56 -static BOOL CALLBACK
32.57 -FindDevGUID(LPGUID guid, LPCWSTR desc, LPCWSTR module, LPVOID _data)
32.58 -{
32.59 - if (guid != NULL) { /* skip the default device. */
32.60 - FindDevGUIDData *data = (FindDevGUIDData *) _data;
32.61 - char *str = WIN_StringToUTF8(desc);
32.62 - const int match = (SDL_strcmp(str, data->devname) == 0);
32.63 - SDL_free(str);
32.64 - if (match) {
32.65 - data->found = 1;
32.66 - SDL_memcpy(&data->guid, guid, sizeof (data->guid));
32.67 - return FALSE; /* found it! stop enumerating. */
32.68 - }
32.69 - }
32.70 - return TRUE; /* keep enumerating. */
32.71 -}
32.72 -
32.73 static int
32.74 -DSOUND_OpenDevice(_THIS, const char *devname, int iscapture)
32.75 +DSOUND_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
32.76 {
32.77 HRESULT result;
32.78 SDL_bool valid_format = SDL_FALSE;
32.79 SDL_bool tried_format = SDL_FALSE;
32.80 SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
32.81 - FindDevGUIDData devguid;
32.82 - LPGUID guid = NULL;
32.83 -
32.84 - if (devname != NULL) {
32.85 - devguid.found = 0;
32.86 - devguid.devname = devname;
32.87 - if (iscapture)
32.88 - pDirectSoundCaptureEnumerateW(FindDevGUID, &devguid);
32.89 - else
32.90 - pDirectSoundEnumerateW(FindDevGUID, &devguid);
32.91 -
32.92 - if (!devguid.found) {
32.93 - return SDL_SetError("DirectSound: Requested device not found");
32.94 - }
32.95 - guid = &devguid.guid;
32.96 - }
32.97 + LPGUID guid = (LPGUID) handle;
32.98
32.99 /* Initialize all variables that we clean on shutdown */
32.100 this->hidden = (struct SDL_PrivateAudioData *)
32.101 @@ -536,6 +501,8 @@
32.102 impl->WaitDone = DSOUND_WaitDone;
32.103 impl->GetDeviceBuf = DSOUND_GetDeviceBuf;
32.104 impl->CloseDevice = DSOUND_CloseDevice;
32.105 + impl->FreeDeviceHandle = DSOUND_FreeDeviceHandle;
32.106 +
32.107 impl->Deinitialize = DSOUND_Deinitialize;
32.108
32.109 return 1; /* this audio target is available. */
33.1 --- a/src/audio/disk/SDL_diskaudio.c Sat Jan 24 23:58:07 2015 -0400
33.2 +++ b/src/audio/disk/SDL_diskaudio.c Mon Apr 06 15:26:37 2015 -0300
33.3 @@ -71,7 +71,7 @@
33.4
33.5 /* If we couldn't write, assume fatal error for now */
33.6 if (written != this->hidden->mixlen) {
33.7 - this->enabled = 0;
33.8 + SDL_OpenedAudioDeviceDisconnected(this);
33.9 }
33.10 #ifdef DEBUG_AUDIO
33.11 fprintf(stderr, "Wrote %d bytes of audio data\n", written);
33.12 @@ -100,7 +100,7 @@
33.13 }
33.14
33.15 static int
33.16 -DISKAUD_OpenDevice(_THIS, const char *devname, int iscapture)
33.17 +DISKAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
33.18 {
33.19 const char *envr = SDL_getenv(DISKENVR_WRITEDELAY);
33.20 const char *fname = DISKAUD_GetOutputFilename(devname);
33.21 @@ -151,6 +151,8 @@
33.22 impl->GetDeviceBuf = DISKAUD_GetDeviceBuf;
33.23 impl->CloseDevice = DISKAUD_CloseDevice;
33.24
33.25 + impl->AllowsArbitraryDeviceNames = 1;
33.26 +
33.27 return 1; /* this audio target is available. */
33.28 }
33.29
34.1 --- a/src/audio/dsp/SDL_dspaudio.c Sat Jan 24 23:58:07 2015 -0400
34.2 +++ b/src/audio/dsp/SDL_dspaudio.c Mon Apr 06 15:26:37 2015 -0300
34.3 @@ -51,9 +51,9 @@
34.4
34.5
34.6 static void
34.7 -DSP_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
34.8 +DSP_DetectDevices(void)
34.9 {
34.10 - SDL_EnumUnixAudioDevices(iscapture, 0, NULL, addfn);
34.11 + SDL_EnumUnixAudioDevices(0, NULL);
34.12 }
34.13
34.14
34.15 @@ -74,7 +74,7 @@
34.16
34.17
34.18 static int
34.19 -DSP_OpenDevice(_THIS, const char *devname, int iscapture)
34.20 +DSP_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
34.21 {
34.22 const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT);
34.23 int format;
34.24 @@ -270,7 +270,7 @@
34.25 const int mixlen = this->hidden->mixlen;
34.26 if (write(this->hidden->audio_fd, mixbuf, mixlen) == -1) {
34.27 perror("Audio write");
34.28 - this->enabled = 0;
34.29 + SDL_OpenedAudioDeviceDisconnected(this);
34.30 }
34.31 #ifdef DEBUG_AUDIO
34.32 fprintf(stderr, "Wrote %d bytes of audio data\n", mixlen);
34.33 @@ -293,6 +293,8 @@
34.34 impl->GetDeviceBuf = DSP_GetDeviceBuf;
34.35 impl->CloseDevice = DSP_CloseDevice;
34.36
34.37 + impl->AllowsArbitraryDeviceNames = 1;
34.38 +
34.39 return 1; /* this audio target is available. */
34.40 }
34.41
35.1 --- a/src/audio/dummy/SDL_dummyaudio.c Sat Jan 24 23:58:07 2015 -0400
35.2 +++ b/src/audio/dummy/SDL_dummyaudio.c Mon Apr 06 15:26:37 2015 -0300
35.3 @@ -27,7 +27,7 @@
35.4 #include "SDL_dummyaudio.h"
35.5
35.6 static int
35.7 -DUMMYAUD_OpenDevice(_THIS, const char *devname, int iscapture)
35.8 +DUMMYAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
35.9 {
35.10 return 0; /* always succeeds. */
35.11 }
36.1 --- a/src/audio/emscripten/SDL_emscriptenaudio.c Sat Jan 24 23:58:07 2015 -0400
36.2 +++ b/src/audio/emscripten/SDL_emscriptenaudio.c Mon Apr 06 15:26:37 2015 -0300
36.3 @@ -151,12 +151,13 @@
36.4 }
36.5
36.6 static int
36.7 -Emscripten_OpenDevice(_THIS, const char *devname, int iscapture)
36.8 +Emscripten_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
36.9 {
36.10 SDL_bool valid_format = SDL_FALSE;
36.11 SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
36.12 int i;
36.13 float f;
36.14 + int result;
36.15
36.16 while ((!valid_format) && (test_format)) {
36.17 switch (test_format) {
36.18 @@ -185,7 +186,7 @@
36.19 /* based on parts of library_sdl.js */
36.20
36.21 /* create context (TODO: this puts stuff in the global namespace...)*/
36.22 - EM_ASM({
36.23 + result = EM_ASM_INT_V({
36.24 if(typeof(SDL2) === 'undefined')
36.25 SDL2 = {};
36.26
36.27 @@ -198,10 +199,14 @@
36.28 } else if (typeof(webkitAudioContext) !== 'undefined') {
36.29 SDL2.audioContext = new webkitAudioContext();
36.30 } else {
36.31 - throw 'Web Audio API is not available!';
36.32 + return -1;
36.33 }
36.34 }
36.35 + return 0;
36.36 });
36.37 + if (result < 0) {
36.38 + return SDL_SetError("Web Audio API is not available!");
36.39 + }
36.40
36.41 /* limit to native freq */
36.42 int sampleRate = EM_ASM_INT_V({
37.1 --- a/src/audio/esd/SDL_esdaudio.c Sat Jan 24 23:58:07 2015 -0400
37.2 +++ b/src/audio/esd/SDL_esdaudio.c Mon Apr 06 15:26:37 2015 -0300
37.3 @@ -129,7 +129,7 @@
37.4 /* Check every 10 loops */
37.5 if (this->hidden->parent && (((++cnt) % 10) == 0)) {
37.6 if (kill(this->hidden->parent, 0) < 0 && errno == ESRCH) {
37.7 - this->enabled = 0;
37.8 + SDL_OpenedAudioDeviceDisconnected(this);
37.9 }
37.10 }
37.11 }
37.12 @@ -161,7 +161,7 @@
37.13
37.14 /* If we couldn't write, assume fatal error for now */
37.15 if (written < 0) {
37.16 - this->enabled = 0;
37.17 + SDL_OpenedAudioDeviceDisconnected(this);
37.18 }
37.19 }
37.20
37.21 @@ -215,7 +215,7 @@
37.22
37.23
37.24 static int
37.25 -ESD_OpenDevice(_THIS, const char *devname, int iscapture)
37.26 +ESD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
37.27 {
37.28 esd_format_t format = (ESD_STREAM | ESD_PLAY);
37.29 SDL_AudioFormat test_format = 0;
38.1 --- a/src/audio/fusionsound/SDL_fsaudio.c Sat Jan 24 23:58:07 2015 -0400
38.2 +++ b/src/audio/fusionsound/SDL_fsaudio.c Mon Apr 06 15:26:37 2015 -0300
38.3 @@ -143,7 +143,7 @@
38.4 this->hidden->mixsamples);
38.5 /* If we couldn't write, assume fatal error for now */
38.6 if (ret) {
38.7 - this->enabled = 0;
38.8 + SDL_OpenedAudioDeviceDisconnected(this);
38.9 }
38.10 #ifdef DEBUG_AUDIO
38.11 fprintf(stderr, "Wrote %d bytes of audio data\n", this->hidden->mixlen);
38.12 @@ -186,7 +186,7 @@
38.13
38.14
38.15 static int
38.16 -SDL_FS_OpenDevice(_THIS, const char *devname, int iscapture)
38.17 +SDL_FS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
38.18 {
38.19 int bytes;
38.20 SDL_AudioFormat test_format = 0, format = 0;
39.1 --- a/src/audio/haiku/SDL_haikuaudio.cc Sat Jan 24 23:58:07 2015 -0400
39.2 +++ b/src/audio/haiku/SDL_haikuaudio.cc Mon Apr 06 15:26:37 2015 -0300
39.3 @@ -111,7 +111,7 @@
39.4
39.5
39.6 static int
39.7 -HAIKUAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
39.8 +HAIKUAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
39.9 {
39.10 int valid_datatype = 0;
39.11 media_raw_audio_format format;
40.1 --- a/src/audio/nacl/SDL_naclaudio.c Sat Jan 24 23:58:07 2015 -0400
40.2 +++ b/src/audio/nacl/SDL_naclaudio.c Mon Apr 06 15:26:37 2015 -0300
40.3 @@ -20,6 +20,9 @@
40.4 */
40.5
40.6 #include "../../SDL_internal.h"
40.7 +
40.8 +#if SDL_AUDIO_DRIVER_NACL
40.9 +
40.10 #include "SDL_naclaudio.h"
40.11
40.12 #include "SDL_audio.h"
40.13 @@ -40,7 +43,7 @@
40.14 #define SAMPLE_FRAME_COUNT 4096
40.15
40.16 /* Audio driver functions */
40.17 -static int NACLAUD_OpenDevice(_THIS, const char *devname, int iscapture);
40.18 +static int NACLAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture);
40.19 static void NACLAUD_CloseDevice(_THIS);
40.20 static void nacl_audio_callback(void* samples, uint32_t buffer_size, PP_TimeDelta latency, void* data);
40.21
40.22 @@ -82,7 +85,7 @@
40.23 }
40.24
40.25 static int
40.26 -NACLAUD_OpenDevice(_THIS, const char *devname, int iscapture) {
40.27 +NACLAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) {
40.28 PP_Instance instance = PSGetInstanceId();
40.29 const PPB_Audio *ppb_audio = PSInterfaceAudio();
40.30 const PPB_AudioConfig *ppb_audiocfg = PSInterfaceAudioConfig();
40.31 @@ -127,9 +130,7 @@
40.32 /* Set the function pointers */
40.33 impl->OpenDevice = NACLAUD_OpenDevice;
40.34 impl->CloseDevice = NACLAUD_CloseDevice;
40.35 - impl->HasCaptureSupport = 0;
40.36 impl->OnlyHasDefaultOutputDevice = 1;
40.37 - impl->OnlyHasDefaultInputDevice = 1;
40.38 impl->ProvidesOwnCallbackThread = 1;
40.39 /*
40.40 * impl->WaitDevice = NACLAUD_WaitDevice;
40.41 @@ -145,3 +146,7 @@
40.42 NACLAUD_DRIVER_NAME, "SDL NaCl Audio Driver",
40.43 NACLAUD_Init, 0
40.44 };
40.45 +
40.46 +#endif /* SDL_AUDIO_DRIVER_NACL */
40.47 +
40.48 +/* vi: set ts=4 sw=4 expandtab: */
41.1 --- a/src/audio/nas/SDL_nasaudio.c Sat Jan 24 23:58:07 2015 -0400
41.2 +++ b/src/audio/nas/SDL_nasaudio.c Mon Apr 06 15:26:37 2015 -0300
41.3 @@ -276,7 +276,7 @@
41.4 }
41.5
41.6 static int
41.7 -NAS_OpenDevice(_THIS, const char *devname, int iscapture)
41.8 +NAS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
41.9 {
41.10 AuElement elms[3];
41.11 int buffer_size;
42.1 --- a/src/audio/paudio/SDL_paudio.c Sat Jan 24 23:58:07 2015 -0400
42.2 +++ b/src/audio/paudio/SDL_paudio.c Mon Apr 06 15:26:37 2015 -0300
42.3 @@ -176,7 +176,7 @@
42.4 * the user know what happened.
42.5 */
42.6 fprintf(stderr, "SDL: %s - %s\n", strerror(errno), message);
42.7 - this->enabled = 0;
42.8 + SDL_OpenedAudioDeviceDisconnected(this);
42.9 /* Don't try to close - may hang */
42.10 this->hidden->audio_fd = -1;
42.11 #ifdef DEBUG_AUDIO
42.12 @@ -212,7 +212,7 @@
42.13
42.14 /* If we couldn't write, assume fatal error for now */
42.15 if (written < 0) {
42.16 - this->enabled = 0;
42.17 + SDL_OpenedAudioDeviceDisconnected(this);
42.18 }
42.19 #ifdef DEBUG_AUDIO
42.20 fprintf(stderr, "Wrote %d bytes of audio data\n", written);
42.21 @@ -241,7 +241,7 @@
42.22 }
42.23
42.24 static int
42.25 -PAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
42.26 +PAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
42.27 {
42.28 const char *workaround = SDL_getenv("SDL_DSP_NOSELECT");
42.29 char audiodev[1024];
43.1 --- a/src/audio/psp/SDL_pspaudio.c Sat Jan 24 23:58:07 2015 -0400
43.2 +++ b/src/audio/psp/SDL_pspaudio.c Mon Apr 06 15:26:37 2015 -0300
43.3 @@ -18,6 +18,9 @@
43.4 misrepresented as being the original software.
43.5 3. This notice may not be removed or altered from any source distribution.
43.6 */
43.7 +#include "../../SDL_internal.h"
43.8 +
43.9 +#if SDL_AUDIO_DRIVER_PSP
43.10
43.11 #include <stdio.h>
43.12 #include <string.h>
43.13 @@ -40,7 +43,7 @@
43.14 #define PSPAUD_DRIVER_NAME "psp"
43.15
43.16 static int
43.17 -PSPAUD_OpenDevice(_THIS, const char *devname, int iscapture)
43.18 +PSPAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
43.19 {
43.20 int format, mixlen, i;
43.21 this->hidden = (struct SDL_PrivateAudioData *)
43.22 @@ -191,5 +194,6 @@
43.23
43.24 /* SDL_AUDI */
43.25
43.26 +#endif /* SDL_AUDIO_DRIVER_PSP */
43.27
43.28 -
43.29 +/* vi: set ts=4 sw=4 expandtab: */
44.1 --- a/src/audio/psp/SDL_pspaudio.h Sat Jan 24 23:58:07 2015 -0400
44.2 +++ b/src/audio/psp/SDL_pspaudio.h Mon Apr 06 15:26:37 2015 -0300
44.3 @@ -24,7 +24,7 @@
44.4
44.5 #include "../SDL_sysaudio.h"
44.6
44.7 -/* Hidden "this" pointer for the video functions */
44.8 +/* Hidden "this" pointer for the audio functions */
44.9 #define _THIS SDL_AudioDevice *this
44.10
44.11 #define NUM_BUFFERS 2
45.1 --- a/src/audio/pulseaudio/SDL_pulseaudio.c Sat Jan 24 23:58:07 2015 -0400
45.2 +++ b/src/audio/pulseaudio/SDL_pulseaudio.c Mon Apr 06 15:26:37 2015 -0300
45.3 @@ -26,6 +26,7 @@
45.4 Stéphan Kochen: stephan .a.t. kochen.nl
45.5 */
45.6 #include "../../SDL_internal.h"
45.7 +#include "SDL_assert.h"
45.8
45.9 #if SDL_AUDIO_DRIVER_PULSEAUDIO
45.10
45.11 @@ -38,7 +39,6 @@
45.12 #include <sys/types.h>
45.13 #include <errno.h>
45.14 #include <pulse/pulseaudio.h>
45.15 -#include <pulse/simple.h>
45.16
45.17 #include "SDL_timer.h"
45.18 #include "SDL_audio.h"
45.19 @@ -66,16 +66,14 @@
45.20
45.21
45.22 static const char *(*PULSEAUDIO_pa_get_library_version) (void);
45.23 -static pa_simple *(*PULSEAUDIO_pa_simple_new) (const char *, const char *,
45.24 - pa_stream_direction_t, const char *, const char *, const pa_sample_spec *,
45.25 - const pa_channel_map *, const pa_buffer_attr *, int *);
45.26 -static void (*PULSEAUDIO_pa_simple_free) (pa_simple *);
45.27 static pa_channel_map *(*PULSEAUDIO_pa_channel_map_init_auto) (
45.28 pa_channel_map *, unsigned, pa_channel_map_def_t);
45.29 static const char * (*PULSEAUDIO_pa_strerror) (int);
45.30 static pa_mainloop * (*PULSEAUDIO_pa_mainloop_new) (void);
45.31 static pa_mainloop_api * (*PULSEAUDIO_pa_mainloop_get_api) (pa_mainloop *);
45.32 static int (*PULSEAUDIO_pa_mainloop_iterate) (pa_mainloop *, int, int *);
45.33 +static int (*PULSEAUDIO_pa_mainloop_run) (pa_mainloop *, int *);
45.34 +static void (*PULSEAUDIO_pa_mainloop_quit) (pa_mainloop *, int);
45.35 static void (*PULSEAUDIO_pa_mainloop_free) (pa_mainloop *);
45.36
45.37 static pa_operation_state_t (*PULSEAUDIO_pa_operation_get_state) (
45.38 @@ -87,7 +85,13 @@
45.39 const char *);
45.40 static int (*PULSEAUDIO_pa_context_connect) (pa_context *, const char *,
45.41 pa_context_flags_t, const pa_spawn_api *);
45.42 +static pa_operation * (*PULSEAUDIO_pa_context_get_sink_info_list) (pa_context *, pa_sink_info_cb_t, void *);
45.43 +static pa_operation * (*PULSEAUDIO_pa_context_get_source_info_list) (pa_context *, pa_source_info_cb_t, void *);
45.44 +static pa_operation * (*PULSEAUDIO_pa_context_get_sink_info_by_index) (pa_context *, uint32_t, pa_sink_info_cb_t, void *);
45.45 +static pa_operation * (*PULSEAUDIO_pa_context_get_source_info_by_index) (pa_context *, uint32_t, pa_source_info_cb_t, void *);
45.46 static pa_context_state_t (*PULSEAUDIO_pa_context_get_state) (pa_context *);
45.47 +static pa_operation * (*PULSEAUDIO_pa_context_subscribe) (pa_context *, pa_subscription_mask_t, pa_context_success_cb_t, void *);
45.48 +static void (*PULSEAUDIO_pa_context_set_subscribe_callback) (pa_context *, pa_context_subscribe_cb_t, void *);
45.49 static void (*PULSEAUDIO_pa_context_disconnect) (pa_context *);
45.50 static void (*PULSEAUDIO_pa_context_unref) (pa_context *);
45.51
45.52 @@ -179,18 +183,24 @@
45.53 load_pulseaudio_syms(void)
45.54 {
45.55 SDL_PULSEAUDIO_SYM(pa_get_library_version);
45.56 - SDL_PULSEAUDIO_SYM(pa_simple_new);
45.57 - SDL_PULSEAUDIO_SYM(pa_simple_free);
45.58 SDL_PULSEAUDIO_SYM(pa_mainloop_new);
45.59 SDL_PULSEAUDIO_SYM(pa_mainloop_get_api);
45.60 SDL_PULSEAUDIO_SYM(pa_mainloop_iterate);
45.61 + SDL_PULSEAUDIO_SYM(pa_mainloop_run);
45.62 + SDL_PULSEAUDIO_SYM(pa_mainloop_quit);
45.63 SDL_PULSEAUDIO_SYM(pa_mainloop_free);
45.64 SDL_PULSEAUDIO_SYM(pa_operation_get_state);
45.65 SDL_PULSEAUDIO_SYM(pa_operation_cancel);
45.66 SDL_PULSEAUDIO_SYM(pa_operation_unref);
45.67 SDL_PULSEAUDIO_SYM(pa_context_new);
45.68 SDL_PULSEAUDIO_SYM(pa_context_connect);
45.69 + SDL_PULSEAUDIO_SYM(pa_context_get_sink_info_list);
45.70 + SDL_PULSEAUDIO_SYM(pa_context_get_source_info_list);
45.71 + SDL_PULSEAUDIO_SYM(pa_context_get_sink_info_by_index);
45.72 + SDL_PULSEAUDIO_SYM(pa_context_get_source_info_by_index);
45.73 SDL_PULSEAUDIO_SYM(pa_context_get_state);
45.74 + SDL_PULSEAUDIO_SYM(pa_context_subscribe);
45.75 + SDL_PULSEAUDIO_SYM(pa_context_set_subscribe_callback);
45.76 SDL_PULSEAUDIO_SYM(pa_context_disconnect);
45.77 SDL_PULSEAUDIO_SYM(pa_context_unref);
45.78 SDL_PULSEAUDIO_SYM(pa_stream_new);
45.79 @@ -206,122 +216,6 @@
45.80 return 0;
45.81 }
45.82
45.83 -
45.84 -/* Check to see if we can connect to PulseAudio */
45.85 -static SDL_bool
45.86 -CheckPulseAudioAvailable()
45.87 -{
45.88 - pa_simple *s;
45.89 - pa_sample_spec ss;
45.90 -
45.91 - ss.format = PA_SAMPLE_S16NE;
45.92 - ss.channels = 1;
45.93 - ss.rate = 22050;
45.94 -
45.95 - s = PULSEAUDIO_pa_simple_new(NULL, "SDL", PA_STREAM_PLAYBACK, NULL,
45.96 - "Test", &ss, NULL, NULL, NULL);
45.97 - if (s) {
45.98 - PULSEAUDIO_pa_simple_free(s);
45.99 - return SDL_TRUE;
45.100 - } else {
45.101 - return SDL_FALSE;
45.102 - }
45.103 -}
45.104 -
45.105 -/* This function waits until it is possible to write a full sound buffer */
45.106 -static void
45.107 -PULSEAUDIO_WaitDevice(_THIS)
45.108 -{
45.109 - struct SDL_PrivateAudioData *h = this->hidden;
45.110 -
45.111 - while(1) {
45.112 - if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY ||
45.113 - PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY ||
45.114 - PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
45.115 - this->enabled = 0;
45.116 - return;
45.117 - }
45.118 - if (PULSEAUDIO_pa_stream_writable_size(h->stream) >= h->mixlen) {
45.119 - return;
45.120 - }
45.121 - }
45.122 -}
45.123 -
45.124 -static void
45.125 -PULSEAUDIO_PlayDevice(_THIS)
45.126 -{
45.127 - /* Write the audio data */
45.128 - struct SDL_PrivateAudioData *h = this->hidden;
45.129 - if (PULSEAUDIO_pa_stream_write(h->stream, h->mixbuf, h->mixlen, NULL, 0LL,
45.130 - PA_SEEK_RELATIVE) < 0) {
45.131 - this->enabled = 0;
45.132 - }
45.133 -}
45.134 -
45.135 -static void
45.136 -stream_drain_complete(pa_stream *s, int success, void *userdata)
45.137 -{
45.138 - /* no-op for pa_stream_drain() to use for callback. */
45.139 -}
45.140 -
45.141 -static void
45.142 -PULSEAUDIO_WaitDone(_THIS)
45.143 -{
45.144 - struct SDL_PrivateAudioData *h = this->hidden;
45.145 - pa_operation *o;
45.146 -
45.147 - o = PULSEAUDIO_pa_stream_drain(h->stream, stream_drain_complete, NULL);
45.148 - if (!o) {
45.149 - return;
45.150 - }
45.151 -
45.152 - while (PULSEAUDIO_pa_operation_get_state(o) != PA_OPERATION_DONE) {
45.153 - if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY ||
45.154 - PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY ||
45.155 - PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
45.156 - PULSEAUDIO_pa_operation_cancel(o);
45.157 - break;
45.158 - }
45.159 - }
45.160 -
45.161 - PULSEAUDIO_pa_operation_unref(o);
45.162 -}
45.163 -
45.164 -
45.165 -
45.166 -static Uint8 *
45.167 -PULSEAUDIO_GetDeviceBuf(_THIS)
45.168 -{
45.169 - return (this->hidden->mixbuf);
45.170 -}
45.171 -
45.172 -
45.173 -static void
45.174 -PULSEAUDIO_CloseDevice(_THIS)
45.175 -{
45.176 - if (this->hidden != NULL) {
45.177 - SDL_FreeAudioMem(this->hidden->mixbuf);
45.178 - this->hidden->mixbuf = NULL;
45.179 - if (this->hidden->stream) {
45.180 - PULSEAUDIO_pa_stream_disconnect(this->hidden->stream);
45.181 - PULSEAUDIO_pa_stream_unref(this->hidden->stream);
45.182 - this->hidden->stream = NULL;
45.183 - }
45.184 - if (this->hidden->context != NULL) {
45.185 - PULSEAUDIO_pa_context_disconnect(this->hidden->context);
45.186 - PULSEAUDIO_pa_context_unref(this->hidden->context);
45.187 - this->hidden->context = NULL;
45.188 - }
45.189 - if (this->hidden->mainloop != NULL) {
45.190 - PULSEAUDIO_pa_mainloop_free(this->hidden->mainloop);
45.191 - this->hidden->mainloop = NULL;
45.192 - }
45.193 - SDL_free(this->hidden);
45.194 - this->hidden = NULL;
45.195 - }
45.196 -}
45.197 -
45.198 -
45.199 static SDL_INLINE int
45.200 squashVersion(const int major, const int minor, const int patch)
45.201 {
45.202 @@ -344,8 +238,193 @@
45.203 return "SDL Application"; /* oh well. */
45.204 }
45.205
45.206 +static void
45.207 +WaitForPulseOperation(pa_mainloop *mainloop, pa_operation *o)
45.208 +{
45.209 + /* This checks for NO errors currently. Either fix that, check results elsewhere, or do things you don't care about. */
45.210 + if (mainloop && o) {
45.211 + SDL_bool okay = SDL_TRUE;
45.212 + while (okay && (PULSEAUDIO_pa_operation_get_state(o) == PA_OPERATION_RUNNING)) {
45.213 + okay = (PULSEAUDIO_pa_mainloop_iterate(mainloop, 1, NULL) >= 0);
45.214 + }
45.215 + PULSEAUDIO_pa_operation_unref(o);
45.216 + }
45.217 +}
45.218 +
45.219 +static void
45.220 +DisconnectFromPulseServer(pa_mainloop *mainloop, pa_context *context)
45.221 +{
45.222 + if (context) {
45.223 + PULSEAUDIO_pa_context_disconnect(context);
45.224 + PULSEAUDIO_pa_context_unref(context);
45.225 + }
45.226 + if (mainloop != NULL) {
45.227 + PULSEAUDIO_pa_mainloop_free(mainloop);
45.228 + }
45.229 +}
45.230 +
45.231 static int
45.232 -PULSEAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
45.233 +ConnectToPulseServer_Internal(pa_mainloop **_mainloop, pa_context **_context)
45.234 +{
45.235 + pa_mainloop *mainloop = NULL;
45.236 + pa_context *context = NULL;
45.237 + pa_mainloop_api *mainloop_api = NULL;
45.238 + int state = 0;
45.239 +
45.240 + *_mainloop = NULL;
45.241 + *_context = NULL;
45.242 +
45.243 + /* Set up a new main loop */
45.244 + if (!(mainloop = PULSEAUDIO_pa_mainloop_new())) {
45.245 + return SDL_SetError("pa_mainloop_new() failed");
45.246 + }
45.247 +
45.248 + *_mainloop = mainloop;
45.249 +
45.250 + mainloop_api = PULSEAUDIO_pa_mainloop_get_api(mainloop);
45.251 + SDL_assert(mainloop_api); /* this never fails, right? */
45.252 +
45.253 + context = PULSEAUDIO_pa_context_new(mainloop_api, getAppName());
45.254 + if (!context) {
45.255 + return SDL_SetError("pa_context_new() failed");
45.256 + }
45.257 + *_context = context;
45.258 +
45.259 + /* Connect to the PulseAudio server */
45.260 + if (PULSEAUDIO_pa_context_connect(context, NULL, 0, NULL) < 0) {
45.261 + return SDL_SetError("Could not setup connection to PulseAudio");
45.262 + }
45.263 +
45.264 + do {
45.265 + if (PULSEAUDIO_pa_mainloop_iterate(mainloop, 1, NULL) < 0) {
45.266 + return SDL_SetError("pa_mainloop_iterate() failed");
45.267 + }
45.268 + state = PULSEAUDIO_pa_context_get_state(context);
45.269 + if (!PA_CONTEXT_IS_GOOD(state)) {
45.270 + return SDL_SetError("Could not connect to PulseAudio");
45.271 + }
45.272 + } while (state != PA_CONTEXT_READY);
45.273 +
45.274 + return 0; /* connected and ready! */
45.275 +}
45.276 +
45.277 +static int
45.278 +ConnectToPulseServer(pa_mainloop **_mainloop, pa_context **_context)
45.279 +{
45.280 + const int retval = ConnectToPulseServer_Internal(_mainloop, _context);
45.281 + if (retval < 0) {
45.282 + DisconnectFromPulseServer(*_mainloop, *_context);
45.283 + }
45.284 + return retval;
45.285 +}
45.286 +
45.287 +
45.288 +/* This function waits until it is possible to write a full sound buffer */
45.289 +static void
45.290 +PULSEAUDIO_WaitDevice(_THIS)
45.291 +{
45.292 + struct SDL_PrivateAudioData *h = this->hidden;
45.293 +
45.294 + while (this->enabled) {
45.295 + if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY ||
45.296 + PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY ||
45.297 + PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
45.298 + SDL_OpenedAudioDeviceDisconnected(this);
45.299 + return;
45.300 + }
45.301 + if (PULSEAUDIO_pa_stream_writable_size(h->stream) >= h->mixlen) {
45.302 + return;
45.303 + }
45.304 + }
45.305 +}
45.306 +
45.307 +static void
45.308 +PULSEAUDIO_PlayDevice(_THIS)
45.309 +{
45.310 + /* Write the audio data */
45.311 + struct SDL_PrivateAudioData *h = this->hidden;
45.312 + if (this->enabled) {
45.313 + if (PULSEAUDIO_pa_stream_write(h->stream, h->mixbuf, h->mixlen, NULL, 0LL, PA_SEEK_RELATIVE) < 0) {
45.314 + SDL_OpenedAudioDeviceDisconnected(this);
45.315 + }
45.316 + }
45.317 +}
45.318 +
45.319 +static void
45.320 +stream_drain_complete(pa_stream *s, int success, void *userdata)
45.321 +{
45.322 + /* no-op for pa_stream_drain() to use for callback. */
45.323 +}
45.324 +
45.325 +static void
45.326 +PULSEAUDIO_WaitDone(_THIS)
45.327 +{
45.328 + if (this->enabled) {
45.329 + struct SDL_PrivateAudioData *h = this->hidden;
45.330 + pa_operation *o = PULSEAUDIO_pa_stream_drain(h->stream, stream_drain_complete, NULL);
45.331 + if (o) {
45.332 + while (PULSEAUDIO_pa_operation_get_state(o) != PA_OPERATION_DONE) {
45.333 + if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY ||
45.334 + PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY ||
45.335 + PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
45.336 + PULSEAUDIO_pa_operation_cancel(o);
45.337 + break;
45.338 + }
45.339 + }
45.340 + PULSEAUDIO_pa_operation_unref(o);
45.341 + }
45.342 + }
45.343 +}
45.344 +
45.345 +
45.346 +
45.347 +static Uint8 *
45.348 +PULSEAUDIO_GetDeviceBuf(_THIS)
45.349 +{
45.350 + return (this->hidden->mixbuf);
45.351 +}
45.352 +
45.353 +
45.354 +static void
45.355 +PULSEAUDIO_CloseDevice(_THIS)
45.356 +{
45.357 + if (this->hidden != NULL) {
45.358 + SDL_FreeAudioMem(this->hidden->mixbuf);
45.359 + SDL_free(this->hidden->device_name);
45.360 + if (this->hidden->stream) {
45.361 + PULSEAUDIO_pa_stream_disconnect(this->hidden->stream);
45.362 + PULSEAUDIO_pa_stream_unref(this->hidden->stream);
45.363 + }
45.364 + DisconnectFromPulseServer(this->hidden->mainloop, this->hidden->context);
45.365 + SDL_free(this->hidden);
45.366 + this->hidden = NULL;
45.367 + }
45.368 +}
45.369 +
45.370 +static void
45.371 +DeviceNameCallback(pa_context *c, const pa_sink_info *i, int is_last, void *data)
45.372 +{
45.373 + if (i) {
45.374 + char **devname = (char **) data;
45.375 + *devname = SDL_strdup(i->name);
45.376 + }
45.377 +}
45.378 +
45.379 +static SDL_bool
45.380 +FindDeviceName(struct SDL_PrivateAudioData *h, void *handle)
45.381 +{
45.382 + const uint32_t idx = ((uint32_t) ((size_t) handle)) - 1;
45.383 +
45.384 + if (handle == NULL) { /* NULL == default device. */
45.385 + return SDL_TRUE;
45.386 + }
45.387 +
45.388 + WaitForPulseOperation(h->mainloop, PULSEAUDIO_pa_context_get_sink_info_by_index(h->context, idx, DeviceNameCallback, &h->device_name));
45.389 + return (h->device_name != NULL);
45.390 +}
45.391 +
45.392 +static int
45.393 +PULSEAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
45.394 {
45.395 struct SDL_PrivateAudioData *h = NULL;
45.396 Uint16 test_format = 0;
45.397 @@ -442,42 +521,21 @@
45.398 paattr.minreq = h->mixlen;
45.399 #endif
45.400
45.401 + if (ConnectToPulseServer(&h->mainloop, &h->context) < 0) {
45.402 + PULSEAUDIO_CloseDevice(this);
45.403 + return SDL_SetError("Could not connect to PulseAudio server");
45.404 + }
45.405 +
45.406 + if (!FindDeviceName(h, handle)) {
45.407 + PULSEAUDIO_CloseDevice(this);
45.408 + return SDL_SetError("Requested PulseAudio sink missing?");
45.409 + }
45.410 +
45.411 /* The SDL ALSA output hints us that we use Windows' channel mapping */
45.412 /* http://bugzilla.libsdl.org/show_bug.cgi?id=110 */
45.413 PULSEAUDIO_pa_channel_map_init_auto(&pacmap, this->spec.channels,
45.414 PA_CHANNEL_MAP_WAVEEX);
45.415
45.416 - /* Set up a new main loop */
45.417 - if (!(h->mainloop = PULSEAUDIO_pa_mainloop_new())) {
45.418 - PULSEAUDIO_CloseDevice(this);
45.419 - return SDL_SetError("pa_mainloop_new() failed");
45.420 - }
45.421 -
45.422 - h->mainloop_api = PULSEAUDIO_pa_mainloop_get_api(h->mainloop);
45.423 - h->context = PULSEAUDIO_pa_context_new(h->mainloop_api, getAppName());
45.424 - if (!h->context) {
45.425 - PULSEAUDIO_CloseDevice(this);
45.426 - return SDL_SetError("pa_context_new() failed");
45.427 - }
45.428 -
45.429 - /* Connect to the PulseAudio server */
45.430 - if (PULSEAUDIO_pa_context_connect(h->context, NULL, 0, NULL) < 0) {
45.431 - PULSEAUDIO_CloseDevice(this);
45.432 - return SDL_SetError("Could not setup connection to PulseAudio");
45.433 - }
45.434 -
45.435 - do {
45.436 - if (PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
45.437 - PULSEAUDIO_CloseDevice(this);
45.438 - return SDL_SetError("pa_mainloop_iterate() failed");
45.439 - }
45.440 - state = PULSEAUDIO_pa_context_get_state(h->context);
45.441 - if (!PA_CONTEXT_IS_GOOD(state)) {
45.442 - PULSEAUDIO_CloseDevice(this);
45.443 - return SDL_SetError("Could not connect to PulseAudio");
45.444 - }
45.445 - } while (state != PA_CONTEXT_READY);
45.446 -
45.447 h->stream = PULSEAUDIO_pa_stream_new(
45.448 h->context,
45.449 "Simple DirectMedia Layer", /* stream description */
45.450 @@ -490,7 +548,13 @@
45.451 return SDL_SetError("Could not set up PulseAudio stream");
45.452 }
45.453
45.454 - if (PULSEAUDIO_pa_stream_connect_playback(h->stream, NULL, &paattr, flags,
45.455 + /* now that we have multi-device support, don't move a stream from
45.456 + a device that was unplugged to something else, unless we're default. */
45.457 + if (h->device_name != NULL) {
45.458 + flags |= PA_STREAM_DONT_MOVE;
45.459 + }
45.460 +
45.461 + if (PULSEAUDIO_pa_stream_connect_playback(h->stream, h->device_name, &paattr, flags,
45.462 NULL, NULL) < 0) {
45.463 PULSEAUDIO_CloseDevice(this);
45.464 return SDL_SetError("Could not connect PulseAudio stream");
45.465 @@ -504,7 +568,7 @@
45.466 state = PULSEAUDIO_pa_stream_get_state(h->stream);
45.467 if (!PA_STREAM_IS_GOOD(state)) {
45.468 PULSEAUDIO_CloseDevice(this);
45.469 - return SDL_SetError("Could not create to PulseAudio stream");
45.470 + return SDL_SetError("Could not connect PulseAudio stream");
45.471 }
45.472 } while (state != PA_STREAM_READY);
45.473
45.474 @@ -512,10 +576,92 @@
45.475 return 0;
45.476 }
45.477
45.478 +static pa_mainloop *hotplug_mainloop = NULL;
45.479 +static pa_context *hotplug_context = NULL;
45.480 +static SDL_Thread *hotplug_thread = NULL;
45.481 +
45.482 +/* device handles are device index + 1, cast to void*, so we never pass a NULL. */
45.483 +
45.484 +/* This is called when PulseAudio adds an output ("sink") device. */
45.485 +static void
45.486 +SinkInfoCallback(pa_context *c, const pa_sink_info *i, int is_last, void *data)
45.487 +{
45.488 + if (i) {
45.489 + SDL_AddAudioDevice(SDL_FALSE, i->description, (void *) ((size_t) i->index+1));
45.490 + }
45.491 +}
45.492 +
45.493 +/* This is called when PulseAudio adds a capture ("source") device. */
45.494 +static void
45.495 +SourceInfoCallback(pa_context *c, const pa_source_info *i, int is_last, void *data)
45.496 +{
45.497 + if (i) {
45.498 + /* Skip "monitor" sources. These are just output from other sinks. */
45.499 + if (i->monitor_of_sink == PA_INVALID_INDEX) {
45.500 + SDL_AddAudioDevice(SDL_TRUE, i->description, (void *) ((size_t) i->index+1));
45.501 + }
45.502 + }
45.503 +}
45.504 +
45.505 +/* This is called when PulseAudio has a device connected/removed/changed. */
45.506 +static void
45.507 +HotplugCallback(pa_context *c, pa_subscription_event_type_t t, uint32_t idx, void *data)
45.508 +{
45.509 + const SDL_bool added = ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW);
45.510 + const SDL_bool removed = ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE);
45.511 +
45.512 + if (added || removed) { /* we only care about add/remove events. */
45.513 + const SDL_bool sink = ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK);
45.514 + const SDL_bool source = ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SOURCE);
45.515 +
45.516 + /* adds need sink details from the PulseAudio server. Another callback... */
45.517 + if (added && sink) {
45.518 + PULSEAUDIO_pa_context_get_sink_info_by_index(hotplug_context, idx, SinkInfoCallback, NULL);
45.519 + } else if (added && source) {
45.520 + PULSEAUDIO_pa_context_get_source_info_by_index(hotplug_context, idx, SourceInfoCallback, NULL);
45.521 + } else if (removed && (sink || source)) {
45.522 + /* removes we can handle just with the device index. */
45.523 + SDL_RemoveAudioDevice(source != 0, (void *) ((size_t) idx+1));
45.524 + }
45.525 + }
45.526 +}
45.527 +
45.528 +/* this runs as a thread while the Pulse target is initialized to catch hotplug events. */
45.529 +static int SDLCALL
45.530 +HotplugThread(void *data)
45.531 +{
45.532 + pa_operation *o;
45.533 + SDL_SetThreadPriority(SDL_THREAD_PRIORITY_LOW);
45.534 + PULSEAUDIO_pa_context_set_subscribe_callback(hotplug_context, HotplugCallback, NULL);
45.535 + o = PULSEAUDIO_pa_context_subscribe(hotplug_context, PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SOURCE, NULL, NULL);
45.536 + PULSEAUDIO_pa_operation_unref(o); /* don't wait for it, just do our thing. */
45.537 + PULSEAUDIO_pa_mainloop_run(hotplug_mainloop, NULL);
45.538 + return 0;
45.539 +}
45.540 +
45.541 +static void
45.542 +PULSEAUDIO_DetectDevices()
45.543 +{
45.544 + WaitForPulseOperation(hotplug_mainloop, PULSEAUDIO_pa_context_get_sink_info_list(hotplug_context, SinkInfoCallback, NULL));
45.545 + WaitForPulseOperation(hotplug_mainloop, PULSEAUDIO_pa_context_get_source_info_list(hotplug_context, SourceInfoCallback, NULL));
45.546 +
45.547 + /* ok, we have a sane list, let's set up hotplug notifications now... */
45.548 + hotplug_thread = SDL_CreateThread(HotplugThread, "PulseHotplug", NULL);
45.549 +}
45.550
45.551 static void
45.552 PULSEAUDIO_Deinitialize(void)
45.553 {
45.554 + if (hotplug_thread) {
45.555 + PULSEAUDIO_pa_mainloop_quit(hotplug_mainloop, 0);
45.556 + SDL_WaitThread(hotplug_thread, NULL);
45.557 + hotplug_thread = NULL;
45.558 + }
45.559 +
45.560 + DisconnectFromPulseServer(hotplug_mainloop, hotplug_context);
45.561 + hotplug_mainloop = NULL;
45.562 + hotplug_context = NULL;
45.563 +
45.564 UnloadPulseAudioLibrary();
45.565 }
45.566
45.567 @@ -526,12 +672,13 @@
45.568 return 0;
45.569 }
45.570
45.571 - if (!CheckPulseAudioAvailable()) {
45.572 + if (ConnectToPulseServer(&hotplug_mainloop, &hotplug_context) < 0) {
45.573 UnloadPulseAudioLibrary();
45.574 return 0;
45.575 }
45.576
45.577 /* Set the function pointers */
45.578 + impl->DetectDevices = PULSEAUDIO_DetectDevices;
45.579 impl->OpenDevice = PULSEAUDIO_OpenDevice;
45.580 impl->PlayDevice = PULSEAUDIO_PlayDevice;
45.581 impl->WaitDevice = PULSEAUDIO_WaitDevice;
45.582 @@ -539,12 +686,10 @@
45.583 impl->CloseDevice = PULSEAUDIO_CloseDevice;
45.584 impl->WaitDone = PULSEAUDIO_WaitDone;
45.585 impl->Deinitialize = PULSEAUDIO_Deinitialize;
45.586 - impl->OnlyHasDefaultOutputDevice = 1;
45.587
45.588 return 1; /* this audio target is available. */
45.589 }
45.590
45.591 -
45.592 AudioBootStrap PULSEAUDIO_bootstrap = {
45.593 "pulseaudio", "PulseAudio", PULSEAUDIO_Init, 0
45.594 };
46.1 --- a/src/audio/pulseaudio/SDL_pulseaudio.h Sat Jan 24 23:58:07 2015 -0400
46.2 +++ b/src/audio/pulseaudio/SDL_pulseaudio.h Mon Apr 06 15:26:37 2015 -0300
46.3 @@ -32,9 +32,10 @@
46.4
46.5 struct SDL_PrivateAudioData
46.6 {
46.7 + char *device_name;
46.8 +
46.9 /* pulseaudio structures */
46.10 pa_mainloop *mainloop;
46.11 - pa_mainloop_api *mainloop_api;
46.12 pa_context *context;
46.13 pa_stream *stream;
46.14
47.1 --- a/src/audio/qsa/SDL_qsa_audio.c Sat Jan 24 23:58:07 2015 -0400
47.2 +++ b/src/audio/qsa/SDL_qsa_audio.c Mon Apr 06 15:26:37 2015 -0300
47.3 @@ -19,6 +19,15 @@
47.4 3. This notice may not be removed or altered from any source distribution.
47.5 */
47.6
47.7 +/*
47.8 + * !!! FIXME: streamline this a little by removing all the
47.9 + * !!! FIXME: if (capture) {} else {} sections that are identical
47.10 + * !!! FIXME: except for one flag.
47.11 + */
47.12 +
47.13 +/* !!! FIXME: can this target support hotplugging? */
47.14 +/* !!! FIXME: ...does SDL2 even support QNX? */
47.15 +
47.16 #include "../../SDL_internal.h"
47.17
47.18 #if SDL_AUDIO_DRIVER_QSA
47.19 @@ -300,7 +309,7 @@
47.20
47.21 /* If we couldn't write, assume fatal error for now */
47.22 if (towrite != 0) {
47.23 - this->enabled = 0;
47.24 + SDL_OpenedAudioDeviceDisconnected(this);
47.25 }
47.26 }
47.27
47.28 @@ -337,8 +346,9 @@
47.29 }
47.30
47.31 static int
47.32 -QSA_OpenDevice(_THIS, const char *devname, int iscapture)
47.33 +QSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
47.34 {
47.35 + const QSA_Device *device = (const QSA_Device *) handle;
47.36 int status = 0;
47.37 int format = 0;
47.38 SDL_AudioFormat test_format = 0;
47.39 @@ -363,80 +373,19 @@
47.40 /* Initialize channel direction: capture or playback */
47.41 this->hidden->iscapture = iscapture;
47.42
47.43 - /* Find deviceid and cardid by device name for playback */
47.44 - if ((!this->hidden->iscapture) && (devname != NULL)) {
47.45 - uint32_t device;
47.46 - int32_t status;
47.47 -
47.48 - /* Search in the playback devices */
47.49 - device = 0;
47.50 - do {
47.51 - status = SDL_strcmp(qsa_playback_device[device].name, devname);
47.52 - if (status == 0) {
47.53 - /* Found requested device */
47.54 - this->hidden->deviceno = qsa_playback_device[device].deviceno;
47.55 - this->hidden->cardno = qsa_playback_device[device].cardno;
47.56 - break;
47.57 - }
47.58 - device++;
47.59 - if (device >= qsa_playback_devices) {
47.60 - QSA_CloseDevice(this);
47.61 - return SDL_SetError("No such playback device");
47.62 - }
47.63 - } while (1);
47.64 - }
47.65 -
47.66 - /* Find deviceid and cardid by device name for capture */
47.67 - if ((this->hidden->iscapture) && (devname != NULL)) {
47.68 - /* Search in the capture devices */
47.69 - uint32_t device;
47.70 - int32_t status;
47.71 -
47.72 - /* Searching in the playback devices */
47.73 - device = 0;
47.74 - do {
47.75 - status = SDL_strcmp(qsa_capture_device[device].name, devname);
47.76 - if (status == 0) {
47.77 - /* Found requested device */
47.78 - this->hidden->deviceno = qsa_capture_device[device].deviceno;
47.79 - this->hidden->cardno = qsa_capture_device[device].cardno;
47.80 - break;
47.81 - }
47.82 - device++;
47.83 - if (device >= qsa_capture_devices) {
47.84 - QSA_CloseDevice(this);
47.85 - return SDL_SetError("No such capture device");
47.86 - }
47.87 - } while (1);
47.88 - }
47.89 -
47.90 - /* Check if SDL requested default audio device */
47.91 - if (devname == NULL) {
47.92 + if (device != NULL) {
47.93 + /* Open requested audio device */
47.94 + this->hidden->deviceno = device->deviceno;
47.95 + this->hidden->cardno = device->cardno;
47.96 + status = snd_pcm_open(&this->hidden->audio_handle,
47.97 + device->cardno, device->deviceno,
47.98 + iscapture ? SND_PCM_OPEN_PLAYBACK : SND_PCM_OPEN_CAPTURE);
47.99 + } else {
47.100 /* Open system default audio device */
47.101 - if (!this->hidden->iscapture) {
47.102 - status = snd_pcm_open_preferred(&this->hidden->audio_handle,
47.103 - &this->hidden->cardno,
47.104 - &this->hidden->deviceno,
47.105 - SND_PCM_OPEN_PLAYBACK);
47.106 - } else {
47.107 - status = snd_pcm_open_preferred(&this->hidden->audio_handle,
47.108 - &this->hidden->cardno,
47.109 - &this->hidden->deviceno,
47.110 - SND_PCM_OPEN_CAPTURE);
47.111 - }
47.112 - } else {
47.113 - /* Open requested audio device */
47.114 - if (!this->hidden->iscapture) {
47.115 - status =
47.116 - snd_pcm_open(&this->hidden->audio_handle,
47.117 - this->hidden->cardno, this->hidden->deviceno,
47.118 - SND_PCM_OPEN_PLAYBACK);
47.119 - } else {
47.120 - status =
47.121 - snd_pcm_open(&this->hidden->audio_handle,
47.122 - this->hidden->cardno, this->hidden->deviceno,
47.123 - SND_PCM_OPEN_CAPTURE);
47.124 - }
47.125 + status = snd_pcm_open_preferred(&this->hidden->audio_handle,
47.126 + &this->hidden->cardno,
47.127 + &this->hidden->deviceno,
47.128 + iscapture ? SND_PCM_OPEN_PLAYBACK : SND_PCM_OPEN_CAPTURE);
47.129 }
47.130
47.131 /* Check if requested device is opened */
47.132 @@ -638,7 +587,7 @@
47.133 }
47.134
47.135 static void
47.136 -QSA_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
47.137 +QSA_DetectDevices(void)
47.138 {
47.139 uint32_t it;
47.140 uint32_t cards;
47.141 @@ -656,8 +605,9 @@
47.142 return;
47.143 }
47.144
47.145 + /* !!! FIXME: code duplication */
47.146 /* Find requested devices by type */
47.147 - if (!iscapture) {
47.148 + { /* output devices */
47.149 /* Playback devices enumeration requested */
47.150 for (it = 0; it < cards; it++) {
47.151 devices = 0;
47.152 @@ -688,7 +638,7 @@
47.153 devices;
47.154 status = snd_pcm_close(handle);
47.155 if (status == EOK) {
47.156 - addfn(qsa_playback_device[qsa_playback_devices].name);
47.157 + SDL_AddAudioDevice(SDL_FALSE, qsa_playback_device[qsa_playback_devices].name, &qsa_playback_device[qsa_playback_devices]);
47.158 qsa_playback_devices++;
47.159 }
47.160 } else {
47.161 @@ -713,7 +663,9 @@
47.162 break;
47.163 }
47.164 }
47.165 - } else {
47.166 + }
47.167 +
47.168 + { /* capture devices */
47.169 /* Capture devices enumeration requested */
47.170 for (it = 0; it < cards; it++) {
47.171 devices = 0;
47.172 @@ -744,7 +696,7 @@
47.173 devices;
47.174 status = snd_pcm_close(handle);
47.175 if (status == EOK) {
47.176 - addfn(qsa_capture_device[qsa_capture_devices].name);
47.177 + SDL_AddAudioDevice(SDL_TRUE, qsa_capture_device[qsa_capture_devices].name, &qsa_capture_device[qsa_capture_devices]);
47.178 qsa_capture_devices++;
47.179 }
47.180 } else {
48.1 --- a/src/audio/sndio/SDL_sndioaudio.c Sat Jan 24 23:58:07 2015 -0400
48.2 +++ b/src/audio/sndio/SDL_sndioaudio.c Mon Apr 06 15:26:37 2015 -0300
48.3 @@ -158,7 +158,7 @@
48.4
48.5 /* If we couldn't write, assume fatal error for now */
48.6 if ( written == 0 ) {
48.7 - this->enabled = 0;
48.8 + SDL_OpenedAudioDeviceDisconnected(this);
48.9 }
48.10 #ifdef DEBUG_AUDIO
48.11 fprintf(stderr, "Wrote %d bytes of audio data\n", written);
48.12 @@ -193,7 +193,7 @@
48.13 }
48.14
48.15 static int
48.16 -SNDIO_OpenDevice(_THIS, const char *devname, int iscapture)
48.17 +SNDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
48.18 {
48.19 SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
48.20 struct sio_par par;
49.1 --- a/src/audio/sun/SDL_sunaudio.c Sat Jan 24 23:58:07 2015 -0400
49.2 +++ b/src/audio/sun/SDL_sunaudio.c Mon Apr 06 15:26:37 2015 -0300
49.3 @@ -56,9 +56,9 @@
49.4
49.5 /* Audio driver bootstrap functions */
49.6 static void
49.7 -SUNAUDIO_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
49.8 +SUNAUDIO_DetectDevices(void)
49.9 {
49.10 - SDL_EnumUnixAudioDevices(iscapture, 1, (int (*)(int fd)) NULL, addfn);
49.11 + SDL_EnumUnixAudioDevices(1, (int (*)(int)) NULL);
49.12 }
49.13
49.14 #ifdef DEBUG_AUDIO
49.15 @@ -158,7 +158,7 @@
49.16 if (write(this->hidden->audio_fd, this->hidden->ulaw_buf,
49.17 this->hidden->fragsize) < 0) {
49.18 /* Assume fatal error, for now */
49.19 - this->enabled = 0;
49.20 + SDL_OpenedAudioDeviceDisconnected(this);
49.21 }
49.22 this->hidden->written += this->hidden->fragsize;
49.23 } else {
49.24 @@ -168,7 +168,7 @@
49.25 if (write(this->hidden->audio_fd, this->hidden->mixbuf,
49.26 this->spec.size) < 0) {
49.27 /* Assume fatal error, for now */
49.28 - this->enabled = 0;
49.29 + SDL_OpenedAudioDeviceDisconnected(this);
49.30 }
49.31 this->hidden->written += this->hidden->fragsize;
49.32 }
49.33 @@ -198,7 +198,7 @@
49.34 }
49.35
49.36 static int
49.37 -SUNAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
49.38 +SUNAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
49.39 {
49.40 const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT);
49.41 SDL_AudioFormat format = 0;
49.42 @@ -414,6 +414,8 @@
49.43 impl->GetDeviceBuf = SUNAUDIO_GetDeviceBuf;
49.44 impl->CloseDevice = SUNAUDIO_CloseDevice;
49.45
49.46 + impl->AllowsArbitraryDeviceNames = 1;
49.47 +
49.48 return 1; /* this audio target is available. */
49.49 }
49.50
50.1 --- a/src/audio/winmm/SDL_winmm.c Sat Jan 24 23:58:07 2015 -0400
50.2 +++ b/src/audio/winmm/SDL_winmm.c Mon Apr 06 15:26:37 2015 -0300
50.3 @@ -36,8 +36,9 @@
50.4 #define WAVE_FORMAT_IEEE_FLOAT 0x0003
50.5 #endif
50.6
50.7 -#define DETECT_DEV_IMPL(typ, capstyp) \
50.8 -static void DetectWave##typ##Devs(SDL_AddAudioDevice addfn) { \
50.9 +#define DETECT_DEV_IMPL(iscap, typ, capstyp) \
50.10 +static void DetectWave##typ##Devs(void) { \
50.11 + const UINT iscapture = iscap ? 1 : 0; \
50.12 const UINT devcount = wave##typ##GetNumDevs(); \
50.13 capstyp caps; \
50.14 UINT i; \
50.15 @@ -45,24 +46,21 @@
50.16 if (wave##typ##GetDevCaps(i,&caps,sizeof(caps))==MMSYSERR_NOERROR) { \
50.17 char *name = WIN_StringToUTF8(caps.szPname); \
50.18 if (name != NULL) { \
50.19 - addfn(name); \
50.20 + SDL_AddAudioDevice((int) iscapture, name, (void *) ((size_t) i+1)); \
50.21 SDL_free(name); \
50.22 } \
50.23 } \
50.24 } \
50.25 }
50.26
50.27 -DETECT_DEV_IMPL(Out, WAVEOUTCAPS)
50.28 -DETECT_DEV_IMPL(In, WAVEINCAPS)
50.29 +DETECT_DEV_IMPL(SDL_FALSE, Out, WAVEOUTCAPS)
50.30 +DETECT_DEV_IMPL(SDL_TRUE, In, WAVEINCAPS)
50.31
50.32 static void
50.33 -WINMM_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
50.34 +WINMM_DetectDevices(void)
50.35 {
50.36 - if (iscapture) {
50.37 - DetectWaveInDevs(addfn);
50.38 - } else {
50.39 - DetectWaveOutDevs(addfn);
50.40 - }
50.41 + DetectWaveInDevs();
50.42 + DetectWaveOutDevs();
50.43 }
50.44
50.45 static void CALLBACK
50.46 @@ -220,48 +218,19 @@
50.47 }
50.48
50.49 static int
50.50 -WINMM_OpenDevice(_THIS, const char *devname, int iscapture)
50.51 +WINMM_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
50.52 {
50.53 SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
50.54 int valid_datatype = 0;
50.55 MMRESULT result;
50.56 WAVEFORMATEX waveformat;
50.57 UINT devId = WAVE_MAPPER; /* WAVE_MAPPER == choose system's default */
50.58 - char *utf8 = NULL;
50.59 UINT i;
50.60
50.61 - if (devname != NULL) { /* specific device requested? */
50.62 - if (iscapture) {
50.63 - const UINT devcount = waveInGetNumDevs();
50.64 - WAVEINCAPS caps;
50.65 - for (i = 0; (i < devcount) && (devId == WAVE_MAPPER); i++) {
50.66 - result = waveInGetDevCaps(i, &caps, sizeof (caps));
50.67 - if (result != MMSYSERR_NOERROR)
50.68 - continue;
50.69 - else if ((utf8 = WIN_StringToUTF8(caps.szPname)) == NULL)
50.70 - continue;
50.71 - else if (SDL_strcmp(devname, utf8) == 0)
50.72 - devId = i;
50.73 - SDL_free(utf8);
50.74 - }
50.75 - } else {
50.76 - const UINT devcount = waveOutGetNumDevs();
50.77 - WAVEOUTCAPS caps;
50.78 - for (i = 0; (i < devcount) && (devId == WAVE_MAPPER); i++) {
50.79 - result = waveOutGetDevCaps(i, &caps, sizeof (caps));
50.80 - if (result != MMSYSERR_NOERROR)
50.81 - continue;
50.82 - else if ((utf8 = WIN_StringToUTF8(caps.szPname)) == NULL)
50.83 - continue;
50.84 - else if (SDL_strcmp(devname, utf8) == 0)
50.85 - devId = i;
50.86 - SDL_free(utf8);
50.87 - }
50.88 - }
50.89 -
50.90 - if (devId == WAVE_MAPPER) {
50.91 - return SDL_SetError("Requested device not found");
50.92 - }
50.93 + if (handle != NULL) { /* specific device requested? */
50.94 + /* -1 because we increment the original value to avoid NULL. */
50.95 + const size_t val = ((size_t) handle) - 1;
50.96 + devId = (UINT) val;
50.97 }
50.98
50.99 /* Initialize all variables that we clean on shutdown */
50.100 @@ -279,10 +248,6 @@
50.101 if (this->spec.channels > 2)
50.102 this->spec.channels = 2; /* !!! FIXME: is this right? */
50.103
50.104 - /* Check the buffer size -- minimum of 1/4 second (word aligned) */
50.105 - if (this->spec.samples < (this->spec.freq / 4))
50.106 - this->spec.samples = ((this->spec.freq / 4) + 3) & ~3;
50.107 -
50.108 while ((!valid_datatype) && (test_format)) {
50.109 switch (test_format) {
50.110 case AUDIO_U8:
51.1 --- a/src/audio/xaudio2/SDL_xaudio2.c Sat Jan 24 23:58:07 2015 -0400
51.2 +++ b/src/audio/xaudio2/SDL_xaudio2.c Mon Apr 06 15:26:37 2015 -0300
51.3 @@ -126,16 +126,13 @@
51.4
51.5
51.6 static void
51.7 -XAUDIO2_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
51.8 +XAUDIO2_DetectDevices(void)
51.9 {
51.10 IXAudio2 *ixa2 = NULL;
51.11 UINT32 devcount = 0;
51.12 UINT32 i = 0;
51.13
51.14 - if (iscapture) {
51.15 - SDL_SetError("XAudio2: capture devices unsupported.");
51.16 - return;
51.17 - } else if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) {
51.18 + if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) {
51.19 SDL_SetError("XAudio2: XAudio2Create() failed at detection.");
51.20 return;
51.21 } else if (IXAudio2_GetDeviceCount(ixa2, &devcount) != S_OK) {
51.22 @@ -149,8 +146,8 @@
51.23 if (IXAudio2_GetDeviceDetails(ixa2, i, &details) == S_OK) {
51.24 char *str = WIN_StringToUTF8(details.DisplayName);
51.25 if (str != NULL) {
51.26 - addfn(str);
51.27 - SDL_free(str); /* addfn() made a copy of the string. */
51.28 + SDL_AddAudioDevice(SDL_FALSE, str, (void *) ((size_t) i+1));
51.29 + SDL_free(str); /* SDL_AddAudioDevice made a copy of the string. */
51.30 }
51.31 }
51.32 }
51.33 @@ -169,8 +166,8 @@
51.34 static void STDMETHODCALLTYPE
51.35 VoiceCBOnVoiceError(THIS_ void *data, HRESULT Error)
51.36 {
51.37 - /* !!! FIXME: attempt to recover, or mark device disconnected. */
51.38 - SDL_assert(0 && "write me!");
51.39 + SDL_AudioDevice *this = (SDL_AudioDevice *) data;
51.40 + SDL_OpenedAudioDeviceDisconnected(this);
51.41 }
51.42
51.43 /* no-op callbacks... */
51.44 @@ -221,7 +218,7 @@
51.45
51.46 if (result != S_OK) { /* uhoh, panic! */
51.47 IXAudio2SourceVoice_FlushSourceBuffers(source);
51.48 - this->enabled = 0;
51.49 + SDL_OpenedAudioDeviceDisconnected(this);
51.50 }
51.51 }
51.52
51.53 @@ -289,7 +286,7 @@
51.54 }
51.55
51.56 static int
51.57 -XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture)
51.58 +XAUDIO2_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
51.59 {
51.60 HRESULT result = S_OK;
51.61 WAVEFORMATEX waveformat;
51.62 @@ -315,9 +312,17 @@
51.63
51.64 static IXAudio2VoiceCallback callbacks = { &callbacks_vtable };
51.65
51.66 - if (iscapture) {
51.67 - return SDL_SetError("XAudio2: capture devices unsupported.");
51.68 - } else if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) {
51.69 +#if defined(SDL_XAUDIO2_WIN8)
51.70 + /* !!! FIXME: hook up hotplugging. */
51.71 +#else
51.72 + if (handle != NULL) { /* specific device requested? */
51.73 + /* -1 because we increment the original value to avoid NULL. */
51.74 + const size_t val = ((size_t) handle) - 1;
51.75 + devId = (UINT32) val;
51.76 + }
51.77 +#endif
51.78 +
51.79 + if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) {
51.80 return SDL_SetError("XAudio2: XAudio2Create() failed at open.");
51.81 }
51.82
51.83 @@ -332,37 +337,6 @@
51.84 ixa2->SetDebugConfiguration(&debugConfig);
51.85 */
51.86
51.87 -#if ! defined(__WINRT__)
51.88 - if (devname != NULL) {
51.89 - UINT32 devcount = 0;
51.90 - UINT32 i = 0;
51.91 -
51.92 - if (IXAudio2_GetDeviceCount(ixa2, &devcount) != S_OK) {
51.93 - IXAudio2_Release(ixa2);
51.94 - return SDL_SetError("XAudio2: IXAudio2_GetDeviceCount() failed.");
51.95 - }
51.96 - for (i = 0; i < devcount; i++) {
51.97 - XAUDIO2_DEVICE_DETAILS details;
51.98 - if (IXAudio2_GetDeviceDetails(ixa2, i, &details) == S_OK) {
51.99 - char *str = WIN_StringToUTF8(details.DisplayName);
51.100 - if (str != NULL) {
51.101 - const int match = (SDL_strcmp(str, devname) == 0);
51.102 - SDL_free(str);
51.103 - if (match) {
51.104 - devId = i;
51.105 - break;
51.106 - }
51.107 - }
51.108 - }
51.109 - }
51.110 -
51.111 - if (i == devcount) {
51.112 - IXAudio2_Release(ixa2);
51.113 - return SDL_SetError("XAudio2: Requested device not found.");
51.114 - }
51.115 - }
51.116 -#endif
51.117 -
51.118 /* Initialize all variables that we clean on shutdown */
51.119 this->hidden = (struct SDL_PrivateAudioData *)
51.120 SDL_malloc((sizeof *this->hidden));
51.121 @@ -529,6 +503,16 @@
51.122 impl->CloseDevice = XAUDIO2_CloseDevice;
51.123 impl->Deinitialize = XAUDIO2_Deinitialize;
51.124
51.125 + /* !!! FIXME: We can apparently use a C++ interface on Windows 8
51.126 + * !!! FIXME: (Windows::Devices::Enumeration::DeviceInformation) for device
51.127 + * !!! FIXME: detection, but it's not implemented here yet.
51.128 + * !!! FIXME: see http://blogs.msdn.com/b/chuckw/archive/2012/04/02/xaudio2-and-windows-8-consumer-preview.aspx
51.129 + * !!! FIXME: for now, force the default device.
51.130 + */
51.131 +#if defined(SDL_XAUDIO2_WIN8) || defined(__WINRT__)
51.132 + impl->OnlyHasDefaultOutputDevice = 1;
51.133 +#endif
51.134 +
51.135 return 1; /* this audio target is available. */
51.136 #endif
51.137 }
52.1 --- a/src/core/android/SDL_android.c Sat Jan 24 23:58:07 2015 -0400
52.2 +++ b/src/core/android/SDL_android.c Mon Apr 06 15:26:37 2015 -0300
52.3 @@ -32,6 +32,7 @@
52.4
52.5 #include "../../events/SDL_events_c.h"
52.6 #include "../../video/android/SDL_androidkeyboard.h"
52.7 +#include "../../video/android/SDL_androidmouse.h"
52.8 #include "../../video/android/SDL_androidtouch.h"
52.9 #include "../../video/android/SDL_androidvideo.h"
52.10 #include "../../video/android/SDL_androidwindow.h"
52.11 @@ -293,6 +294,14 @@
52.12 Android_OnTouch(touch_device_id_in, pointer_finger_id_in, action, x, y, p);
52.13 }
52.14
52.15 +/* Mouse */
52.16 +JNIEXPORT void JNICALL Java_org_libsdl_app_SDLActivity_onNativeMouse(
52.17 + JNIEnv* env, jclass jcls,
52.18 + jint button, jint action, jfloat x, jfloat y)
52.19 +{
52.20 + Android_OnMouse(button, action, x, y);
52.21 +}
52.22 +
52.23 /* Accelerometer */
52.24 JNIEXPORT void JNICALL Java_org_libsdl_app_SDLActivity_onNativeAccel(
52.25 JNIEnv* env, jclass jcls,
52.26 @@ -548,12 +557,12 @@
52.27 * Audio support
52.28 */
52.29 static jboolean audioBuffer16Bit = JNI_FALSE;
52.30 -static jboolean audioBufferStereo = JNI_FALSE;
52.31 static jobject audioBuffer = NULL;
52.32 static void* audioBufferPinned = NULL;
52.33
52.34 int Android_JNI_OpenAudioDevice(int sampleRate, int is16Bit, int channelCount, int desiredBufferFrames)
52.35 {
52.36 + jboolean audioBufferStereo;
52.37 int audioBufferFrames;
52.38
52.39 JNIEnv *env = Android_JNI_GetEnv();
52.40 @@ -1601,6 +1610,11 @@
52.41 return s_AndroidExternalFilesPath;
52.42 }
52.43
52.44 +jclass Android_JNI_GetActivityClass(void)
52.45 +{
52.46 + return mActivityClass;
52.47 +}
52.48 +
52.49 #endif /* __ANDROID__ */
52.50
52.51 /* vi: set ts=4 sw=4 expandtab: */
53.1 --- a/src/core/android/SDL_android.h Sat Jan 24 23:58:07 2015 -0400
53.2 +++ b/src/core/android/SDL_android.h Mon Apr 06 15:26:37 2015 -0300
53.3 @@ -78,6 +78,7 @@
53.4 #include <jni.h>
53.5 JNIEnv *Android_JNI_GetEnv(void);
53.6 int Android_JNI_SetupThread(void);
53.7 +jclass Android_JNI_GetActivityClass(void);
53.8
53.9 /* Generic messages */
53.10 int Android_JNI_SendMessage(int command, int param);
54.1 --- a/src/core/linux/SDL_ibus.c Sat Jan 24 23:58:07 2015 -0400
54.2 +++ b/src/core/linux/SDL_ibus.c Mon Apr 06 15:26:37 2015 -0300
54.3 @@ -462,6 +462,9 @@
54.4 ibus_addr_file = SDL_strdup(addr_file);
54.5
54.6 addr = IBus_ReadAddressFromFile(addr_file);
54.7 + if (!addr) {
54.8 + return SDL_FALSE;
54.9 + }
54.10
54.11 if (inotify_fd < 0) {
54.12 inotify_fd = inotify_init();
55.1 --- a/src/core/linux/SDL_udev.c Sat Jan 24 23:58:07 2015 -0400
55.2 +++ b/src/core/linux/SDL_udev.c Mon Apr 06 15:26:37 2015 -0300
55.3 @@ -350,17 +350,19 @@
55.4 devclass |= SDL_UDEV_DEVICE_MOUSE; /* ID_INPUT_MOUSE */
55.5 } else if (test_bit(BTN_TOUCH, bitmask_key)) {
55.6 ; /* ID_INPUT_TOUCHSCREEN */
55.7 - } else if (test_bit(BTN_TRIGGER, bitmask_key) ||
55.8 - test_bit(BTN_A, bitmask_key) ||
55.9 - test_bit(BTN_1, bitmask_key) ||
55.10 - test_bit(ABS_RX, bitmask_abs) ||
55.11 - test_bit(ABS_RY, bitmask_abs) ||
55.12 - test_bit(ABS_RZ, bitmask_abs) ||
55.13 - test_bit(ABS_THROTTLE, bitmask_abs) ||
55.14 - test_bit(ABS_RUDDER, bitmask_abs) ||
55.15 - test_bit(ABS_WHEEL, bitmask_abs) ||
55.16 - test_bit(ABS_GAS, bitmask_abs) ||
55.17 - test_bit(ABS_BRAKE, bitmask_abs)) {
55.18 + }
55.19 +
55.20 + if (test_bit(BTN_TRIGGER, bitmask_key) ||
55.21 + test_bit(BTN_A, bitmask_key) ||
55.22 + test_bit(BTN_1, bitmask_key) ||
55.23 + test_bit(ABS_RX, bitmask_abs) ||
55.24 + test_bit(ABS_RY, bitmask_abs) ||
55.25 + test_bit(ABS_RZ, bitmask_abs) ||
55.26 + test_bit(ABS_THROTTLE, bitmask_abs) ||
55.27 + test_bit(ABS_RUDDER, bitmask_abs) ||
55.28 + test_bit(ABS_WHEEL, bitmask_abs) ||
55.29 + test_bit(ABS_GAS, bitmask_abs) ||
55.30 + test_bit(ABS_BRAKE, bitmask_abs)) {
55.31 devclass |= SDL_UDEV_DEVICE_JOYSTICK; /* ID_INPUT_JOYSTICK */
55.32 }
55.33 }
56.1 --- a/src/dynapi/SDL_dynapi.h Sat Jan 24 23:58:07 2015 -0400
56.2 +++ b/src/dynapi/SDL_dynapi.h Mon Apr 06 15:26:37 2015 -0300
56.3 @@ -49,7 +49,10 @@
56.4 #define SDL_DYNAMIC_API 0
56.5 #elif defined(__clang_analyzer__)
56.6 #define SDL_DYNAMIC_API 0 /* Turn off for static analysis, so reports are more clear. */
56.7 -#else /* everyone else. */
56.8 +#endif
56.9 +
56.10 +/* everyone else. This is where we turn on the API if nothing forced it off. */
56.11 +#ifndef SDL_DYNAMIC_API
56.12 #define SDL_DYNAMIC_API 1
56.13 #endif
56.14
57.1 --- a/src/dynapi/SDL_dynapi_overrides.h Sat Jan 24 23:58:07 2015 -0400
57.2 +++ b/src/dynapi/SDL_dynapi_overrides.h Mon Apr 06 15:26:37 2015 -0300
57.3 @@ -591,3 +591,4 @@
57.4 #define SDL_QueueAudio SDL_QueueAudio_REAL
57.5 #define SDL_GetQueuedAudioSize SDL_GetQueuedAudioSize_REAL
57.6 #define SDL_ClearQueuedAudio SDL_ClearQueuedAudio_REAL
57.7 +#define SDL_GetGrabbedWindow SDL_GetGrabbedWindow_REAL
58.1 --- a/src/dynapi/SDL_dynapi_procs.h Sat Jan 24 23:58:07 2015 -0400
58.2 +++ b/src/dynapi/SDL_dynapi_procs.h Mon Apr 06 15:26:37 2015 -0300
58.3 @@ -623,3 +623,4 @@
58.4 SDL_DYNAPI_PROC(int,SDL_QueueAudio,(SDL_AudioDeviceID a, const void *b, Uint32 c),(a,b,c),return)
58.5 SDL_DYNAPI_PROC(Uint32,SDL_GetQueuedAudioSize,(SDL_AudioDeviceID a),(a),return)
58.6 SDL_DYNAPI_PROC(void,SDL_ClearQueuedAudio,(SDL_AudioDeviceID a),(a),)
58.7 +SDL_DYNAPI_PROC(SDL_Window*,SDL_GetGrabbedWindow,(void),(),return)
59.1 --- a/src/events/SDL_events.c Sat Jan 24 23:58:07 2015 -0400
59.2 +++ b/src/events/SDL_events.c Mon Apr 06 15:26:37 2015 -0300
59.3 @@ -75,12 +75,13 @@
59.4 SDL_mutex *lock;
59.5 volatile SDL_bool active;
59.6 volatile int count;
59.7 + volatile int max_events_seen;
59.8 SDL_EventEntry *head;
59.9 SDL_EventEntry *tail;
59.10 SDL_EventEntry *free;
59.11 SDL_SysWMEntry *wmmsg_used;
59.12 SDL_SysWMEntry *wmmsg_free;
59.13 -} SDL_EventQ = { NULL, SDL_TRUE };
59.14 +} SDL_EventQ = { NULL, SDL_TRUE, 0, 0, NULL, NULL, NULL, NULL, NULL };
59.15
59.16
59.17 /* Public functions */
59.18 @@ -88,6 +89,7 @@
59.19 void
59.20 SDL_StopEventLoop(void)
59.21 {
59.22 + const char *report = SDL_GetHint("SDL_EVENT_QUEUE_STATISTICS");
59.23 int i;
59.24 SDL_EventEntry *entry;
59.25 SDL_SysWMEntry *wmmsg;
59.26 @@ -98,6 +100,11 @@
59.27
59.28 SDL_EventQ.active = SDL_FALSE;
59.29
59.30 + if (report && SDL_atoi(report)) {
59.31 + SDL_Log("SDL EVENT QUEUE: Maximum events in-flight: %d\n",
59.32 + SDL_EventQ.max_events_seen);
59.33 + }
59.34 +
59.35 /* Clean out EventQ */
59.36 for (entry = SDL_EventQ.head; entry; ) {
59.37 SDL_EventEntry *next = entry->next;
59.38 @@ -119,7 +126,9 @@
59.39 SDL_free(wmmsg);
59.40 wmmsg = next;
59.41 }
59.42 +
59.43 SDL_EventQ.count = 0;
59.44 + SDL_EventQ.max_events_seen = 0;
59.45 SDL_EventQ.head = NULL;
59.46 SDL_EventQ.tail = NULL;
59.47 SDL_EventQ.free = NULL;
59.48 @@ -218,6 +227,10 @@
59.49 }
59.50 ++SDL_EventQ.count;
59.51
59.52 + if (SDL_EventQ.count > SDL_EventQ.max_events_seen) {
59.53 + SDL_EventQ.max_events_seen = SDL_EventQ.count;
59.54 + }
59.55 +
59.56 return 1;
59.57 }
59.58
60.1 --- a/src/events/SDL_gesture.c Sat Jan 24 23:58:07 2015 -0400
60.2 +++ b/src/events/SDL_gesture.c Mon Apr 06 15:26:37 2015 -0300
60.3 @@ -24,6 +24,7 @@
60.4 /* General mouse handling code for SDL */
60.5
60.6 #include "SDL_events.h"
60.7 +#include "SDL_endian.h"
60.8 #include "SDL_events_c.h"
60.9 #include "SDL_gesture_c.h"
60.10
60.11 @@ -114,14 +115,34 @@
60.12
60.13 static int SaveTemplate(SDL_DollarTemplate *templ, SDL_RWops *dst)
60.14 {
60.15 - if (dst == NULL) return 0;
60.16 + if (dst == NULL) {
60.17 + return 0;
60.18 + }
60.19
60.20 /* No Longer storing the Hash, rehash on load */
60.21 /* if (SDL_RWops.write(dst, &(templ->hash), sizeof(templ->hash), 1) != 1) return 0; */
60.22
60.23 +#if SDL_BYTEORDER == SDL_LIL_ENDIAN
60.24 if (SDL_RWwrite(dst, templ->path,
60.25 - sizeof(templ->path[0]),DOLLARNPOINTS) != DOLLARNPOINTS)
60.26 + sizeof(templ->path[0]),DOLLARNPOINTS) != DOLLARNPOINTS) {
60.27 return 0;
60.28 + }
60.29 +#else
60.30 + {
60.31 + SDL_DollarTemplate copy = *templ;
60.32 + SDL_FloatPoint *p = copy.path;
60.33 + int i;
60.34 + for (i = 0; i < DOLLARNPOINTS; i++, p++) {
60.35 + p->x = SDL_SwapFloatLE(p->x);
60.36 + p->y = SDL_SwapFloatLE(p->y);
60.37 + }
60.38 +
60.39 + if (SDL_RWwrite(dst, copy.path,
60.40 + sizeof(copy.path[0]),DOLLARNPOINTS) != DOLLARNPOINTS) {
60.41 + return 0;
60.42 + }
60.43 + }
60.44 +#endif
60.45
60.46 return 1;
60.47 }
60.48 @@ -184,7 +205,7 @@
60.49 int index = -1;
60.50 int i = 0;
60.51 if (inTouch == NULL) {
60.52 - if (SDL_numGestureTouches == 0) return -1;
60.53 + if (SDL_numGestureTouches == 0) return SDL_SetError("no gesture touch devices registered");
60.54 for (i = 0; i < SDL_numGestureTouches; i++) {
60.55 inTouch = &SDL_gestureTouch[i];
60.56 index = SDL_AddDollarGesture_one(inTouch, path);
60.57 @@ -203,17 +224,33 @@
60.58 SDL_GestureTouch *touch = NULL;
60.59 if (src == NULL) return 0;
60.60 if (touchId >= 0) {
60.61 - for (i = 0; i < SDL_numGestureTouches; i++)
60.62 - if (SDL_gestureTouch[i].id == touchId)
60.63 + for (i = 0; i < SDL_numGestureTouches; i++) {
60.64 + if (SDL_gestureTouch[i].id == touchId) {
60.65 touch = &SDL_gestureTouch[i];
60.66 - if (touch == NULL) return -1;
60.67 + }
60.68 + }
60.69 + if (touch == NULL) {
60.70 + return SDL_SetError("given touch id not found");
60.71 + }
60.72 }
60.73
60.74 while (1) {
60.75 SDL_DollarTemplate templ;
60.76
60.77 - if (SDL_RWread(src,templ.path,sizeof(templ.path[0]),DOLLARNPOINTS) <
60.78 - DOLLARNPOINTS) break;
60.79 + if (SDL_RWread(src,templ.path,sizeof(templ.path[0]),DOLLARNPOINTS) < DOLLARNPOINTS) {
60.80 + if (loaded == 0) {
60.81 + return SDL_SetError("could not read any dollar gesture from rwops");
60.82 + }
60.83 + break;
60.84 + }
60.85 +
60.86 +#if SDL_BYTEORDER != SDL_LIL_ENDIAN
60.87 + for (i = 0; i < DOLLARNPOINTS; i++) {
60.88 + SDL_FloatPoint *p = &templ.path[i];
60.89 + p->x = SDL_SwapFloatLE(p->x);
60.90 + p->y = SDL_SwapFloatLE(p->y);
60.91 + }
60.92 +#endif
60.93
60.94 if (touchId >= 0) {
60.95 /* printf("Adding loaded gesture to 1 touch\n"); */
61.1 --- a/src/events/SDL_mouse.c Sat Jan 24 23:58:07 2015 -0400
61.2 +++ b/src/events/SDL_mouse.c Mon Apr 06 15:26:37 2015 -0300
61.3 @@ -293,9 +293,14 @@
61.4 event.motion.yrel = yrel;
61.5 posted = (SDL_PushEvent(&event) > 0);
61.6 }
61.7 - /* Use unclamped values if we're getting events outside the window */
61.8 - mouse->last_x = x;
61.9 - mouse->last_y = y;
61.10 + if (relative) {
61.11 + mouse->last_x = mouse->x;
61.12 + mouse->last_y = mouse->y;
61.13 + } else {
61.14 + /* Use unclamped values if we're getting events outside the window */
61.15 + mouse->last_x = x;
61.16 + mouse->last_y = y;
61.17 + }
61.18 return posted;
61.19 }
61.20
61.21 @@ -303,10 +308,11 @@
61.22 {
61.23 if (button >= mouse->num_clickstates) {
61.24 int i, count = button + 1;
61.25 - mouse->clickstate = (SDL_MouseClickState *)SDL_realloc(mouse->clickstate, count * sizeof(*mouse->clickstate));
61.26 - if (!mouse->clickstate) {
61.27 + SDL_MouseClickState *clickstate = (SDL_MouseClickState *)SDL_realloc(mouse->clickstate, count * sizeof(*mouse->clickstate));
61.28 + if (!clickstate) {
61.29 return NULL;
61.30 }
61.31 + mouse->clickstate = clickstate;
61.32
61.33 for (i = mouse->num_clickstates; i < count; ++i) {
61.34 SDL_zero(mouse->clickstate[i]);
62.1 --- a/src/events/SDL_quit.c Sat Jan 24 23:58:07 2015 -0400
62.2 +++ b/src/events/SDL_quit.c Mon Apr 06 15:26:37 2015 -0300
62.3 @@ -19,6 +19,7 @@
62.4 3. This notice may not be removed or altered from any source distribution.
62.5 */
62.6 #include "../SDL_internal.h"
62.7 +#include "SDL_hints.h"
62.8
62.9 /* General quit handling code for SDL */
62.10
62.11 @@ -30,6 +31,8 @@
62.12 #include "SDL_events_c.h"
62.13
62.14
62.15 +static SDL_bool disable_signals = SDL_FALSE;
62.16 +
62.17 #ifdef HAVE_SIGNAL_H
62.18 static void
62.19 SDL_HandleSIG(int sig)
62.20 @@ -43,8 +46,8 @@
62.21 #endif /* HAVE_SIGNAL_H */
62.22
62.23 /* Public functions */
62.24 -int
62.25 -SDL_QuitInit(void)
62.26 +static int
62.27 +SDL_QuitInit_Internal(void)
62.28 {
62.29 #ifdef HAVE_SIGACTION
62.30 struct sigaction action;
62.31 @@ -80,11 +83,22 @@
62.32 #endif /* HAVE_SIGNAL_H */
62.33
62.34 /* That's it! */
62.35 - return (0);
62.36 + return 0;
62.37 }
62.38
62.39 -void
62.40 -SDL_QuitQuit(void)
62.41 +int
62.42 +SDL_QuitInit(void)
62.43 +{
62.44 + const char *hint = SDL_GetHint(SDL_HINT_NO_SIGNAL_HANDLERS);
62.45 + disable_signals = hint && (SDL_atoi(hint) == 1);
62.46 + if (!disable_signals) {
62.47 + return SDL_QuitInit_Internal();
62.48 + }
62.49 + return 0;
62.50 +}
62.51 +
62.52 +static void
62.53 +SDL_QuitQuit_Internal(void)
62.54 {
62.55 #ifdef HAVE_SIGACTION
62.56 struct sigaction action;
62.57 @@ -110,6 +124,14 @@
62.58 #endif /* HAVE_SIGNAL_H */
62.59 }
62.60
62.61 +void
62.62 +SDL_QuitQuit(void)
62.63 +{
62.64 + if (!disable_signals) {
62.65 + SDL_QuitQuit_Internal();
62.66 + }
62.67 +}
62.68 +
62.69 /* This function returns 1 if it's okay to close the application window */
62.70 int
62.71 SDL_SendQuit(void)
63.1 --- a/src/filesystem/nacl/SDL_sysfilesystem.c Sat Jan 24 23:58:07 2015 -0400
63.2 +++ b/src/filesystem/nacl/SDL_sysfilesystem.c Mon Apr 06 15:26:37 2015 -0300
63.3 @@ -38,4 +38,5 @@
63.4 return NULL;
63.5 }
63.6
63.7 -#endif /* __NACL__ */
63.8 \ No newline at end of file
63.9 +#endif /* SDL_FILESYSTEM_NACL */
63.10 +
64.1 --- a/src/haptic/linux/SDL_syshaptic.c Sat Jan 24 23:58:07 2015 -0400
64.2 +++ b/src/haptic/linux/SDL_syshaptic.c Mon Apr 06 15:26:37 2015 -0300
64.3 @@ -288,8 +288,7 @@
64.4 }
64.5
64.6 item->fname = SDL_strdup(path);
64.7 - if ( (item->fname == NULL) ) {
64.8 - SDL_free(item->fname);
64.9 + if (item->fname == NULL) {
64.10 SDL_free(item);
64.11 return -1;
64.12 }
65.1 --- a/src/joystick/SDL_gamecontrollerdb.h Sat Jan 24 23:58:07 2015 -0400
65.2 +++ b/src/joystick/SDL_gamecontrollerdb.h Mon Apr 06 15:26:37 2015 -0300
65.3 @@ -63,6 +63,8 @@
65.4 "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,",
65.5 "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. */
65.6 "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,",
65.7 + "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,",
65.8 + "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,platform:Linux,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,",
65.9 "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,",
65.10 "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,",
65.11 "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,",
65.12 @@ -73,12 +75,13 @@
65.13 "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,",
65.14 "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,",
65.15 "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,",
65.16 + "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,",
65.17 #endif
65.18 #if defined(__ANDROID__)
65.19 "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,",
65.20 #endif
65.21 #if defined(SDL_JOYSTICK_EMSCRIPTEN)
65.22 - "emscripten,Standard Gamepad,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,lefttrigger:b6,righttrigger:b7,back:b8,start:b9,leftstick:b10,rightstick:b11,dpup:b12,dpdown:b13,dpleft:b14,dpright:b15,guide:b16,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
65.23 + "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,",
65.24 #endif
65.25 NULL
65.26 };
66.1 --- a/src/joystick/SDL_joystick.c Sat Jan 24 23:58:07 2015 -0400
66.2 +++ b/src/joystick/SDL_joystick.c Mon Apr 06 15:26:37 2015 -0300
66.3 @@ -206,10 +206,6 @@
66.4 valid = 1;
66.5 }
66.6
66.7 - if (joystick && joystick->closed) {
66.8 - valid = 0;
66.9 - }
66.10 -
66.11 return valid;
66.12 }
66.13
66.14 @@ -412,6 +408,7 @@
66.15 }
66.16
66.17 SDL_SYS_JoystickClose(joystick);
66.18 + joystick->hwdata = NULL;
66.19
66.20 joysticklist = SDL_joysticks;
66.21 joysticklistprev = NULL;
66.22 @@ -668,7 +665,7 @@
66.23
66.24 SDL_SYS_JoystickUpdate(joystick);
66.25
66.26 - if (joystick->closed && joystick->uncentered) {
66.27 + if (joystick->force_recentering) {
66.28 int i;
66.29
66.30 /* Tell the app that everything is centered/unpressed... */
66.31 @@ -681,7 +678,7 @@
66.32 for (i = 0; i < joystick->nhats; i++)
66.33 SDL_PrivateJoystickHat(joystick, i, SDL_HAT_CENTERED);
66.34
66.35 - joystick->uncentered = SDL_FALSE;
66.36 + joystick->force_recentering = SDL_FALSE;
66.37 }
66.38
66.39 SDL_updating_joystick = NULL;
67.1 --- a/src/joystick/SDL_sysjoystick.h Sat Jan 24 23:58:07 2015 -0400
67.2 +++ b/src/joystick/SDL_sysjoystick.h Mon Apr 06 15:26:37 2015 -0300
67.3 @@ -53,8 +53,7 @@
67.4
67.5 int ref_count; /* Reference count for multiple opens */
67.6
67.7 - SDL_bool closed; /* SDL_TRUE if this device is no longer valid */
67.8 - SDL_bool uncentered; /* SDL_TRUE if this device needs to have its state reset to 0 */
67.9 + SDL_bool force_recentering; /* SDL_TRUE if this device needs to have its state reset to 0 */
67.10 struct _SDL_Joystick *next; /* pointer to next joystick we have allocated */
67.11 };
67.12
67.13 @@ -78,14 +77,14 @@
67.14 extern SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index);
67.15
67.16 /* Function to open a joystick for use.
67.17 - The joystick to open is specified by the index field of the joystick.
67.18 + The joystick to open is specified by the device index.
67.19 This should fill the nbuttons and naxes fields of the joystick structure.
67.20 It returns 0, or -1 if there is an error.
67.21 */
67.22 extern int SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index);
67.23
67.24 /* Function to query if the joystick is currently attached
67.25 - * It returns 1 if attached, 0 otherwise.
67.26 + * It returns SDL_TRUE if attached, SDL_FALSE otherwise.
67.27 */
67.28 extern SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick * joystick);
67.29
68.1 --- a/src/joystick/android/SDL_sysjoystick.c Sat Jan 24 23:58:07 2015 -0400
68.2 +++ b/src/joystick/android/SDL_sysjoystick.c Mon Apr 06 15:26:37 2015 -0300
68.3 @@ -467,7 +467,7 @@
68.4 }
68.5
68.6 /* Function to open a joystick for use.
68.7 - The joystick to open is specified by the index field of the joystick.
68.8 + The joystick to open is specified by the device index.
68.9 This should fill the nbuttons and naxes fields of the joystick structure.
68.10 It returns 0, or -1 if there is an error.
68.11 */
68.12 @@ -498,7 +498,7 @@
68.13 /* Function to determine is this joystick is attached to the system right now */
68.14 SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
68.15 {
68.16 - return !joystick->closed && (joystick->hwdata != NULL);
68.17 + return joystick->hwdata != NULL;
68.18 }
68.19
68.20 void
68.21 @@ -529,11 +529,6 @@
68.22 void
68.23 SDL_SYS_JoystickClose(SDL_Joystick * joystick)
68.24 {
68.25 - if (joystick->hwdata) {
68.26 - ((SDL_joylist_item*)joystick->hwdata)->joystick = NULL;
68.27 - joystick->hwdata = NULL;
68.28 - }
68.29 - joystick->closed = 1;
68.30 }
68.31
68.32 /* Function to perform any system-specific joystick related cleanup */
69.1 --- a/src/joystick/android/SDL_sysjoystick_c.h Sat Jan 24 23:58:07 2015 -0400
69.2 +++ b/src/joystick/android/SDL_sysjoystick_c.h Mon Apr 06 15:26:37 2015 -0300
69.3 @@ -19,7 +19,7 @@
69.4 3. This notice may not be removed or altered from any source distribution.
69.5 */
69.6
69.7 -#include "SDL_config.h"
69.8 +#include "../../SDL_internal.h"
69.9
69.10 #ifdef SDL_JOYSTICK_ANDROID
69.11 #include "../SDL_sysjoystick.h"
70.1 --- a/src/joystick/bsd/SDL_sysjoystick.c Sat Jan 24 23:58:07 2015 -0400
70.2 +++ b/src/joystick/bsd/SDL_sysjoystick.c Mon Apr 06 15:26:37 2015 -0300
70.3 @@ -558,8 +558,6 @@
70.4 close(joy->hwdata->fd);
70.5 SDL_free(joy->hwdata->path);
70.6 SDL_free(joy->hwdata);
70.7 -
70.8 - return;
70.9 }
70.10
70.11 void
71.1 --- a/src/joystick/darwin/SDL_sysjoystick.c Sat Jan 24 23:58:07 2015 -0400
71.2 +++ b/src/joystick/darwin/SDL_sysjoystick.c Mon Apr 06 15:26:37 2015 -0300
71.3 @@ -138,7 +138,7 @@
71.4 JoystickDeviceWasRemovedCallback(void *ctx, IOReturn result, void *sender)
71.5 {
71.6 recDevice *device = (recDevice *) ctx;
71.7 - device->removed = 1;
71.8 + device->removed = SDL_TRUE;
71.9 device->deviceRef = NULL; // deviceRef was invalidated due to the remove
71.10 #if SDL_HAPTIC_IOKIT
71.11 MacHaptic_MaybeRemoveDevice(device->ffservice);
71.12 @@ -412,12 +412,12 @@
71.13 /* We have to do some storage of the io_service_t for SDL_HapticOpenFromJoystick */
71.14 if (IOHIDDeviceGetService != NULL) { /* weak reference: available in 10.6 and later. */
71.15 const io_service_t ioservice = IOHIDDeviceGetService(ioHIDDeviceObject);
71.16 +#if SDL_HAPTIC_IOKIT
71.17 if ((ioservice) && (FFIsForceFeedback(ioservice) == FF_OK)) {
71.18 device->ffservice = ioservice;
71.19 -#if SDL_HAPTIC_IOKIT
71.20 MacHaptic_MaybeAddDevice(ioservice);
71.21 + }
71.22 #endif
71.23 - }
71.24 }
71.25
71.26 device->send_open_event = 1;
71.27 @@ -446,9 +446,9 @@
71.28 return SDL_FALSE;
71.29 }
71.30
71.31 + IOHIDManagerSetDeviceMatchingMultiple(hidman, matchingArray);
71.32 IOHIDManagerRegisterDeviceMatchingCallback(hidman, JoystickDeviceWasAddedCallback, NULL);
71.33 IOHIDManagerScheduleWithRunLoop(hidman, runloop, SDL_JOYSTICK_RUNLOOP_MODE);
71.34 - IOHIDManagerSetDeviceMatchingMultiple(hidman, matchingArray);
71.35
71.36 while (CFRunLoopRunInMode(SDL_JOYSTICK_RUNLOOP_MODE,0,TRUE) == kCFRunLoopRunHandledSource) {
71.37 /* no-op. Callback fires once per existing device. */
71.38 @@ -560,10 +560,6 @@
71.39 void
71.40 SDL_SYS_JoystickDetect()
71.41 {
71.42 - while (CFRunLoopRunInMode(SDL_JOYSTICK_RUNLOOP_MODE,0,TRUE) == kCFRunLoopRunHandledSource) {
71.43 - /* no-op. Pending callbacks will fire in CFRunLoopRunInMode(). */
71.44 - }
71.45 -
71.46 if (s_bDeviceAdded || s_bDeviceRemoved) {
71.47 recDevice *device = gpDeviceList;
71.48 s_bDeviceAdded = SDL_FALSE;
71.49 @@ -613,6 +609,12 @@
71.50 }
71.51 }
71.52 }
71.53 +
71.54 + // run this after the checks above so we don't set device->removed and delete the device before
71.55 + // SDL_SYS_JoystickUpdate can run to clean up the SDL_Joystick object that owns this device
71.56 + while (CFRunLoopRunInMode(SDL_JOYSTICK_RUNLOOP_MODE,0,TRUE) == kCFRunLoopRunHandledSource) {
71.57 + /* no-op. Pending callbacks will fire in CFRunLoopRunInMode(). */
71.58 + }
71.59 }
71.60
71.61 /* Function to get the device-dependent name of a joystick */
71.62 @@ -644,7 +646,7 @@
71.63 }
71.64
71.65 /* Function to open a joystick for use.
71.66 - * The joystick to open is specified by the index field of the joystick.
71.67 + * The joystick to open is specified by the device index.
71.68 * This should fill the nbuttons and naxes fields of the joystick structure.
71.69 * It returns 0, or -1 if there is an error.
71.70 */
71.71 @@ -670,21 +672,12 @@
71.72 }
71.73
71.74 /* Function to query if the joystick is currently attached
71.75 - * It returns 1 if attached, 0 otherwise.
71.76 + * It returns SDL_TRUE if attached, SDL_FALSE otherwise.
71.77 */
71.78 SDL_bool
71.79 SDL_SYS_JoystickAttached(SDL_Joystick * joystick)
71.80 {
71.81 - recDevice *device = gpDeviceList;
71.82 -
71.83 - while (device) {
71.84 - if (joystick->instance_id == device->instance_id) {
71.85 - return SDL_TRUE;
71.86 - }
71.87 - device = device->pNext;
71.88 - }
71.89 -
71.90 - return SDL_FALSE;
71.91 + return joystick->hwdata != NULL;
71.92 }
71.93
71.94 /* Function to update the state of a joystick - called as a device poll.
71.95 @@ -705,9 +698,10 @@
71.96 }
71.97
71.98 if (device->removed) { /* device was unplugged; ignore it. */
71.99 - joystick->closed = 1;
71.100 - joystick->uncentered = 1;
71.101 - joystick->hwdata = NULL;
71.102 + if (joystick->hwdata) {
71.103 + joystick->force_recentering = SDL_TRUE;
71.104 + joystick->hwdata = NULL;
71.105 + }
71.106 return;
71.107 }
71.108
71.109 @@ -795,7 +789,6 @@
71.110 void
71.111 SDL_SYS_JoystickClose(SDL_Joystick * joystick)
71.112 {
71.113 - joystick->closed = 1;
71.114 }
71.115
71.116 /* Function to perform any system-specific joystick related cleanup */
72.1 --- a/src/joystick/darwin/SDL_sysjoystick_c.h Sat Jan 24 23:58:07 2015 -0400
72.2 +++ b/src/joystick/darwin/SDL_sysjoystick_c.h Mon Apr 06 15:26:37 2015 -0300
72.3 @@ -58,8 +58,7 @@
72.4 recElement *firstButton;
72.5 recElement *firstHat;
72.6
72.7 - int removed;
72.8 - int uncentered;
72.9 + SDL_bool removed;
72.10
72.11 int instance_id;
72.12 SDL_JoystickGUID guid;
73.1 --- a/src/joystick/dummy/SDL_sysjoystick.c Sat Jan 24 23:58:07 2015 -0400
73.2 +++ b/src/joystick/dummy/SDL_sysjoystick.c Mon Apr 06 15:26:37 2015 -0300
73.3 @@ -34,7 +34,7 @@
73.4 int
73.5 SDL_SYS_JoystickInit(void)
73.6 {
73.7 - return (0);
73.8 + return 0;
73.9 }
73.10
73.11 int SDL_SYS_NumJoysticks()
73.12 @@ -61,7 +61,7 @@
73.13 }
73.14
73.15 /* Function to open a joystick for use.
73.16 - The joystick to open is specified by the index field of the joystick.
73.17 + The joystick to open is specified by the device index.
73.18 This should fill the nbuttons and naxes fields of the joystick structure.
73.19 It returns 0, or -1 if there is an error.
73.20 */
73.21 @@ -85,21 +85,18 @@
73.22 void
73.23 SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
73.24 {
73.25 - return;
73.26 }
73.27
73.28 /* Function to close a joystick after use */
73.29 void
73.30 SDL_SYS_JoystickClose(SDL_Joystick * joystick)
73.31 {
73.32 - return;
73.33 }
73.34
73.35 /* Function to perform any system-specific joystick related cleanup */
73.36 void
73.37 SDL_SYS_JoystickQuit(void)
73.38 {
73.39 - return;
73.40 }
73.41
73.42 SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
74.1 --- a/src/joystick/emscripten/SDL_sysjoystick.c Sat Jan 24 23:58:07 2015 -0400
74.2 +++ b/src/joystick/emscripten/SDL_sysjoystick.c Mon Apr 06 15:26:37 2015 -0300
74.3 @@ -46,7 +46,7 @@
74.4 static int numjoysticks = 0;
74.5 static int instance_counter = 0;
74.6
74.7 -int
74.8 +EM_BOOL
74.9 Emscripten_JoyStickConnected(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData)
74.10 {
74.11 int i;
74.12 @@ -105,12 +105,14 @@
74.13 }
74.14
74.15 ++numjoysticks;
74.16 - SDL_Log("%d",numjoysticks);
74.17 +#ifdef DEBUG_JOYSTICK
74.18 + SDL_Log("Number of joysticks is %d", numjoysticks);
74.19 +#endif
74.20 #if !SDL_EVENTS_DISABLED
74.21 event.type = SDL_JOYDEVICEADDED;
74.22
74.23 if (SDL_GetEventState(event.type) == SDL_ENABLE) {
74.24 - event.jdevice.which = item->device_instance - 1;
74.25 + event.jdevice.which = numjoysticks - 1;
74.26 if ( (SDL_EventOK == NULL) ||
74.27 (*SDL_EventOK) (SDL_EventOKParam, &event) ) {
74.28 SDL_PushEvent(&event);
74.29 @@ -118,12 +120,14 @@
74.30 }
74.31 #endif /* !SDL_EVENTS_DISABLED */
74.32
74.33 +#ifdef DEBUG_JOYSTICK
74.34 SDL_Log("Added joystick with index %d", item->index);
74.35 +#endif
74.36
74.37 return 1;
74.38 }
74.39
74.40 -int
74.41 +EM_BOOL
74.42 Emscripten_JoyStickDisconnected(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData)
74.43 {
74.44 SDL_joylist_item *item = SDL_joylist;
74.45 @@ -144,7 +148,6 @@
74.46 return 1;
74.47 }
74.48
74.49 - const int retval = item->device_instance;
74.50 if (item->joystick) {
74.51 item->joystick->hwdata = NULL;
74.52 }
74.53 @@ -174,7 +177,9 @@
74.54 }
74.55 #endif /* !SDL_EVENTS_DISABLED */
74.56
74.57 - SDL_Log("Removed joystick with index %d", retval);
74.58 +#ifdef DEBUG_JOYSTICK
74.59 + SDL_Log("Removed joystick with id %d", item->device_instance);
74.60 +#endif
74.61 SDL_free(item->name);
74.62 SDL_free(item->mapping);
74.63 SDL_free(item);
74.64 @@ -215,6 +220,7 @@
74.65 Emscripten_JoyStickConnected);
74.66
74.67 if(retval != EMSCRIPTEN_RESULT_SUCCESS) {
74.68 + SDL_SYS_JoystickQuit();
74.69 return -1;
74.70 }
74.71
74.72 @@ -222,12 +228,28 @@
74.73 0,
74.74 Emscripten_JoyStickDisconnected);
74.75 if(retval != EMSCRIPTEN_RESULT_SUCCESS) {
74.76 + SDL_SYS_JoystickQuit();
74.77 return -1;
74.78 }
74.79
74.80 return 0;
74.81 }
74.82
74.83 +/* Returns item matching given SDL device index. */
74.84 +static SDL_joylist_item *
74.85 +JoystickByDeviceIndex(int device_index)
74.86 +{
74.87 + SDL_joylist_item *item = SDL_joylist;
74.88 +
74.89 + while (0 < device_index) {
74.90 + --device_index;
74.91 + item = item->next;
74.92 + }
74.93 +
74.94 + return item;
74.95 +}
74.96 +
74.97 +/* Returns item matching given HTML gamepad index. */
74.98 static SDL_joylist_item *
74.99 JoystickByIndex(int index)
74.100 {
74.101 @@ -256,46 +278,28 @@
74.102 {
74.103 }
74.104
74.105 -// we need to poll to see if the gamepad state has changed
74.106 -SDL_bool SDL_SYS_JoystickNeedsPolling()
74.107 -{
74.108 - return SDL_TRUE;
74.109 -}
74.110 -
74.111 /* Function to get the device-dependent name of a joystick */
74.112 const char *
74.113 -SDL_SYS_JoystickNameForDeviceIndex(int index)
74.114 +SDL_SYS_JoystickNameForDeviceIndex(int device_index)
74.115 {
74.116 - SDL_joylist_item *item = JoystickByIndex(index);
74.117 - if (item == NULL) {
74.118 - SDL_SetError("Joystick with index %d not found", index);
74.119 - return NULL;
74.120 - }
74.121 -
74.122 - return item->name;
74.123 + return JoystickByDeviceIndex(device_index)->name;
74.124 }
74.125
74.126 /* Function to perform the mapping from device index to the instance id for this index */
74.127 -SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int index)
74.128 +SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
74.129 {
74.130 - SDL_joylist_item *item = JoystickByIndex(index);
74.131 - if (item == NULL) {
74.132 - SDL_SetError("Joystick with index %d not found", index);
74.133 - return 0;
74.134 - }
74.135 -
74.136 - return item->device_instance;
74.137 + return JoystickByDeviceIndex(device_index)->device_instance;
74.138 }
74.139
74.140 /* Function to open a joystick for use.
74.141 - The joystick to open is specified by the index field of the joystick.
74.142 + The joystick to open is specified by the device index.
74.143 This should fill the nbuttons and naxes fields of the joystick structure.
74.144 It returns 0, or -1 if there is an error.
74.145 */
74.146 int
74.147 -SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int index)
74.148 +SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
74.149 {
74.150 - SDL_joylist_item *item = JoystickByIndex(index);
74.151 + SDL_joylist_item *item = JoystickByDeviceIndex(device_index);
74.152
74.153 if (item == NULL ) {
74.154 return SDL_SetError("No such device");
74.155 @@ -322,7 +326,7 @@
74.156 /* Function to determine is this joystick is attached to the system right now */
74.157 SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
74.158 {
74.159 - return !joystick->closed && (joystick->hwdata != NULL);
74.160 + return joystick->hwdata != NULL;
74.161 }
74.162
74.163 /* Function to update the state of a joystick - called as a device poll.
74.164 @@ -334,10 +338,10 @@
74.165 SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
74.166 {
74.167 EmscriptenGamepadEvent gamepadState;
74.168 - SDL_joylist_item *item = SDL_joylist;
74.169 + SDL_joylist_item *item = (SDL_joylist_item *) joystick->hwdata;
74.170 int i, result, buttonState;
74.171
74.172 - while (item != NULL) {
74.173 + if (item) {
74.174 result = emscripten_get_gamepad_status(item->index, &gamepadState);
74.175 if( result == EMSCRIPTEN_RESULT_SUCCESS) {
74.176 if(gamepadState.timestamp == 0 || gamepadState.timestamp != item->timestamp) {
74.177 @@ -367,7 +371,6 @@
74.178 }
74.179 }
74.180 }
74.181 - item = item->next;
74.182 }
74.183 }
74.184
74.185 @@ -375,11 +378,6 @@
74.186 void
74.187 SDL_SYS_JoystickClose(SDL_Joystick * joystick)
74.188 {
74.189 - if (joystick->hwdata) {
74.190 - ((SDL_joylist_item*)joystick->hwdata)->joystick = NULL;
74.191 - joystick->hwdata = NULL;
74.192 - }
74.193 - joystick->closed = 1;
74.194 }
74.195
74.196 /* Function to perform any system-specific joystick related cleanup */
74.197 @@ -400,20 +398,24 @@
74.198
74.199 numjoysticks = 0;
74.200 instance_counter = 0;
74.201 +
74.202 + emscripten_set_gamepadconnected_callback(NULL, 0, NULL);
74.203 + emscripten_set_gamepaddisconnected_callback(NULL, 0, NULL);
74.204 }
74.205
74.206 -SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID(int index)
74.207 +SDL_JoystickGUID
74.208 +SDL_SYS_JoystickGetDeviceGUID(int device_index)
74.209 {
74.210 SDL_JoystickGUID guid;
74.211 /* the GUID is just the first 16 chars of the name for now */
74.212 - const char *name = SDL_SYS_JoystickNameForDeviceIndex(index);
74.213 + const char *name = SDL_SYS_JoystickNameForDeviceIndex(device_index);
74.214 SDL_zero(guid);
74.215 SDL_memcpy(&guid, name, SDL_min(sizeof(guid), SDL_strlen(name)));
74.216 return guid;
74.217 }
74.218
74.219 -
74.220 -SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick)
74.221 +SDL_JoystickGUID
74.222 +SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick)
74.223 {
74.224 SDL_JoystickGUID guid;
74.225 /* the GUID is just the first 16 chars of the name for now */
75.1 --- a/src/joystick/emscripten/SDL_sysjoystick_c.h Sat Jan 24 23:58:07 2015 -0400
75.2 +++ b/src/joystick/emscripten/SDL_sysjoystick_c.h Mon Apr 06 15:26:37 2015 -0300
75.3 @@ -19,7 +19,7 @@
75.4 3. This notice may not be removed or altered from any source distribution.
75.5 */
75.6
75.7 -#include "SDL_config.h"
75.8 +#include "../../SDL_internal.h"
75.9
75.10 #ifdef SDL_JOYSTICK_EMSCRIPTEN
75.11 #include "../SDL_sysjoystick.h"
76.1 --- a/src/joystick/haiku/SDL_haikujoystick.cc Sat Jan 24 23:58:07 2015 -0400
76.2 +++ b/src/joystick/haiku/SDL_haikujoystick.cc Mon Apr 06 15:26:37 2015 -0300
76.3 @@ -106,7 +106,7 @@
76.4 }
76.5
76.6 /* Function to open a joystick for use.
76.7 - The joystick to open is specified by the index field of the joystick.
76.8 + The joystick to open is specified by the device index.
76.9 This should fill the nbuttons and naxes fields of the joystick structure.
76.10 It returns 0, or -1 if there is an error.
76.11 */
76.12 @@ -228,7 +228,6 @@
76.13 SDL_free(joystick->hwdata->new_hats);
76.14 SDL_free(joystick->hwdata->new_axes);
76.15 SDL_free(joystick->hwdata);
76.16 - joystick->hwdata = NULL;
76.17 }
76.18 }
76.19
77.1 --- a/src/joystick/iphoneos/SDL_sysjoystick.m Sat Jan 24 23:58:07 2015 -0400
77.2 +++ b/src/joystick/iphoneos/SDL_sysjoystick.m Mon Apr 06 15:26:37 2015 -0300
77.3 @@ -77,7 +77,7 @@
77.4 }
77.5
77.6 /* Function to open a joystick for use.
77.7 - The joystick to open is specified by the index field of the joystick.
77.8 + The joystick to open is specified by the device index.
77.9 This should fill the nbuttons and naxes fields of the joystick structure.
77.10 It returns 0, or -1 if there is an error.
77.11 */
77.12 @@ -167,7 +167,6 @@
77.13 @autoreleasepool {
77.14 [motionManager stopAccelerometerUpdates];
77.15 }
77.16 - joystick->closed = 1;
77.17 }
77.18
77.19 /* Function to perform any system-specific joystick related cleanup */
78.1 --- a/src/joystick/linux/SDL_sysjoystick.c Sat Jan 24 23:58:07 2015 -0400
78.2 +++ b/src/joystick/linux/SDL_sysjoystick.c Mon Apr 06 15:26:37 2015 -0300
78.3 @@ -142,13 +142,15 @@
78.4 #if SDL_USE_LIBUDEV
78.5 void joystick_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath)
78.6 {
78.7 - if (devpath == NULL || !(udev_class & SDL_UDEV_DEVICE_JOYSTICK)) {
78.8 + if (devpath == NULL) {
78.9 return;
78.10 }
78.11 -
78.12 - switch( udev_type )
78.13 - {
78.14 +
78.15 + switch (udev_type) {
78.16 case SDL_UDEV_DEVICEADDED:
78.17 + if (!(udev_class & SDL_UDEV_DEVICE_JOYSTICK)) {
78.18 + return;
78.19 + }
78.20 MaybeAddDevice(devpath);
78.21 break;
78.22
78.23 @@ -335,13 +337,12 @@
78.24 static int
78.25 JoystickInitWithUdev(void)
78.26 {
78.27 -
78.28 if (SDL_UDEV_Init() < 0) {
78.29 return SDL_SetError("Could not initialize UDEV");
78.30 }
78.31
78.32 /* Set up the udev callback */
78.33 - if ( SDL_UDEV_AddCallback(joystick_udev_callback) < 0) {
78.34 + if (SDL_UDEV_AddCallback(joystick_udev_callback) < 0) {
78.35 SDL_UDEV_Quit();
78.36 return SDL_SetError("Could not set up joystick <-> udev callback");
78.37 }
78.38 @@ -565,7 +566,7 @@
78.39
78.40
78.41 /* Function to open a joystick for use.
78.42 - The joystick to open is specified by the index field of the joystick.
78.43 + The joystick to open is specified by the device index.
78.44 This should fill the nbuttons and naxes fields of the joystick structure.
78.45 It returns 0, or -1 if there is an error.
78.46 */
78.47 @@ -623,7 +624,7 @@
78.48 /* Function to determine is this joystick is attached to the system right now */
78.49 SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
78.50 {
78.51 - return !joystick->closed && (joystick->hwdata->item != NULL);
78.52 + return joystick->hwdata->item != NULL;
78.53 }
78.54
78.55 static SDL_INLINE void
78.56 @@ -840,9 +841,7 @@
78.57 SDL_free(joystick->hwdata->balls);
78.58 SDL_free(joystick->hwdata->fname);
78.59 SDL_free(joystick->hwdata);
78.60 - joystick->hwdata = NULL;
78.61 }
78.62 - joystick->closed = 1;
78.63 }
78.64
78.65 /* Function to perform any system-specific joystick related cleanup */
79.1 --- a/src/joystick/psp/SDL_sysjoystick.c Sat Jan 24 23:58:07 2015 -0400
79.2 +++ b/src/joystick/psp/SDL_sysjoystick.c Mon Apr 06 15:26:37 2015 -0300
79.3 @@ -18,6 +18,9 @@
79.4 misrepresented as being the original software.
79.5 3. This notice may not be removed or altered from any source distribution.
79.6 */
79.7 +#include "../../SDL_internal.h"
79.8 +
79.9 +#if SDL_JOYSTICK_PSP
79.10
79.11 /* This is the PSP implementation of the SDL joystick API */
79.12 #include <pspctrl.h>
79.13 @@ -161,7 +164,7 @@
79.14 }
79.15
79.16 /* Function to open a joystick for use.
79.17 - The joystick to open is specified by the index field of the joystick.
79.18 + The joystick to open is specified by the device index.
79.19 This should fill the nbuttons and naxes fields of the joystick structure.
79.20 It returns 0, or -1 if there is an error.
79.21 */
79.22 @@ -179,12 +182,12 @@
79.23 {
79.24 return SDL_TRUE;
79.25 }
79.26 +
79.27 /* Function to update the state of a joystick - called as a device poll.
79.28 * This function shouldn't update the joystick structure directly,
79.29 * but instead should call SDL_PrivateJoystick*() to deliver events
79.30 * and update joystick device state.
79.31 */
79.32 -
79.33 void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
79.34 {
79.35 int i;
79.36 @@ -230,7 +233,6 @@
79.37 /* Function to close a joystick after use */
79.38 void SDL_SYS_JoystickClose(SDL_Joystick *joystick)
79.39 {
79.40 - /* Do nothing. */
79.41 }
79.42
79.43 /* Function to perform any system-specific joystick related cleanup */
79.44 @@ -262,5 +264,7 @@
79.45 return guid;
79.46 }
79.47
79.48 +#endif /* SDL_JOYSTICK_PSP */
79.49 +
79.50 /* vim: ts=4 sw=4
79.51 */
80.1 --- a/src/joystick/windows/SDL_mmjoystick.c Sat Jan 24 23:58:07 2015 -0400
80.2 +++ b/src/joystick/windows/SDL_mmjoystick.c Mon Apr 06 15:26:37 2015 -0300
80.3 @@ -210,7 +210,7 @@
80.4 }
80.5
80.6 /* Function to open a joystick for use.
80.7 - The joystick to open is specified by the index field of the joystick.
80.8 + The joystick to open is specified by the device index.
80.9 This should fill the nbuttons and naxes fields of the joystick structure.
80.10 It returns 0, or -1 if there is an error.
80.11 */
80.12 @@ -383,9 +383,7 @@
80.13 void
80.14 SDL_SYS_JoystickClose(SDL_Joystick * joystick)
80.15 {
80.16 - /* free system specific hardware data */
80.17 SDL_free(joystick->hwdata);
80.18 - joystick->hwdata = NULL;
80.19 }
80.20
80.21 /* Function to perform any system-specific joystick related cleanup */
81.1 --- a/src/joystick/windows/SDL_windowsjoystick.c Sat Jan 24 23:58:07 2015 -0400
81.2 +++ b/src/joystick/windows/SDL_windowsjoystick.c Mon Apr 06 15:26:37 2015 -0300
81.3 @@ -446,7 +446,7 @@
81.4 }
81.5
81.6 /* Function to open a joystick for use.
81.7 - The joystick to open is specified by the index field of the joystick.
81.8 + The joystick to open is specified by the device index.
81.9 This should fill the nbuttons and naxes fields of the joystick structure.
81.10 It returns 0, or -1 if there is an error.
81.11 */
81.12 @@ -460,7 +460,6 @@
81.13
81.14 /* allocate memory for system specific hardware data */
81.15 joystick->instance_id = joystickdevice->nInstanceID;
81.16 - joystick->closed = SDL_FALSE;
81.17 joystick->hwdata =
81.18 (struct joystick_hwdata *) SDL_malloc(sizeof(struct joystick_hwdata));
81.19 if (joystick->hwdata == NULL) {
81.20 @@ -480,13 +479,13 @@
81.21 SDL_bool
81.22 SDL_SYS_JoystickAttached(SDL_Joystick * joystick)
81.23 {
81.24 - return !joystick->closed && !joystick->hwdata->removed;
81.25 + return joystick->hwdata && !joystick->hwdata->removed;
81.26 }
81.27
81.28 void
81.29 SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
81.30 {
81.31 - if (joystick->closed || !joystick->hwdata) {
81.32 + if (!joystick->hwdata || joystick->hwdata->removed) {
81.33 return;
81.34 }
81.35
81.36 @@ -497,8 +496,7 @@
81.37 }
81.38
81.39 if (joystick->hwdata->removed) {
81.40 - joystick->closed = SDL_TRUE;
81.41 - joystick->uncentered = SDL_TRUE;
81.42 + joystick->force_recentering = SDL_TRUE;
81.43 }
81.44 }
81.45
81.46 @@ -512,10 +510,7 @@
81.47 SDL_DINPUT_JoystickClose(joystick);
81.48 }
81.49
81.50 - /* free system specific hardware data */
81.51 SDL_free(joystick->hwdata);
81.52 -
81.53 - joystick->closed = SDL_TRUE;
81.54 }
81.55
81.56 /* Function to perform any system-specific joystick related cleanup */
82.1 --- a/src/main/psp/SDL_psp_main.c Sat Jan 24 23:58:07 2015 -0400
82.2 +++ b/src/main/psp/SDL_psp_main.c Mon Apr 06 15:26:37 2015 -0300
82.3 @@ -1,6 +1,9 @@
82.4 /*
82.5 SDL_psp_main.c, placed in the public domain by Sam Lantinga 3/13/14
82.6 */
82.7 +#include "SDL_config.h"
82.8 +
82.9 +#ifdef __PSP__
82.10
82.11 #include "SDL_main.h"
82.12 #include <pspkernel.h>
82.13 @@ -61,3 +64,7 @@
82.14 (void)SDL_main(argc, argv);
82.15 return 0;
82.16 }
82.17 +
82.18 +#endif /* __PSP__ */
82.19 +
82.20 +/* vi: set ts=4 sw=4 expandtab: */
83.1 --- a/src/main/windows/SDL_windows_main.c Sat Jan 24 23:58:07 2015 -0400
83.2 +++ b/src/main/windows/SDL_windows_main.c Mon Apr 06 15:26:37 2015 -0300
83.3 @@ -109,13 +109,16 @@
83.4 }
83.5
83.6 #if defined(_MSC_VER)
83.7 -/* The VC++ compiler needs main defined */
83.8 -#define console_main main
83.9 +/* The VC++ compiler needs main/wmain defined */
83.10 +# define console_ansi_main main
83.11 +# if UNICODE
83.12 +# define console_wmain wmain
83.13 +# endif
83.14 #endif
83.15
83.16 -/* This is where execution begins [console apps] */
83.17 -int
83.18 -console_main(int argc, char *argv[])
83.19 +/* WinMain, main, and wmain eventually call into here. */
83.20 +static int
83.21 +main_utf8(int argc, char *argv[])
83.22 {
83.23 SDL_SetMainReady();
83.24
83.25 @@ -123,6 +126,37 @@
83.26 return SDL_main(argc, argv);
83.27 }
83.28
83.29 +/* This is where execution begins [console apps, ansi] */
83.30 +int
83.31 +console_ansi_main(int argc, char *argv[])
83.32 +{
83.33 + /* !!! FIXME: are these in the system codepage? We need to convert to UTF-8. */
83.34 + return main_utf8(argc, argv);
83.35 +}
83.36 +
83.37 +
83.38 +#if UNICODE
83.39 +/* This is where execution begins [console apps, unicode] */
83.40 +int
83.41 +console_wmain(int argc, wchar_t *wargv[], wchar_t *wenvp)
83.42 +{
83.43 + int retval = 0;
83.44 + char **argv = SDL_stack_alloc(char*, argc);
83.45 + int i;
83.46 +
83.47 + for (i = 0; i < argc; ++i) {
83.48 + argv[i] = WIN_StringToUTF8(wargv[i]);
83.49 + }
83.50 +
83.51 + retval = main_utf8(argc, argv);
83.52 +
83.53 + /* !!! FIXME: we are leaking all the elements of argv we allocated. */
83.54 + SDL_stack_free(argv);
83.55 +
83.56 + return retval;
83.57 +}
83.58 +#endif
83.59 +
83.60 /* This is where execution begins [windowed apps] */
83.61 int WINAPI
83.62 WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
83.63 @@ -136,6 +170,7 @@
83.64 #if UNICODE
83.65 cmdline = WIN_StringToUTF8(text);
83.66 #else
83.67 + /* !!! FIXME: are these in the system codepage? We need to convert to UTF-8. */
83.68 cmdline = SDL_strdup(text);
83.69 #endif
83.70 if (cmdline == NULL) {
83.71 @@ -151,7 +186,7 @@
83.72 ParseCommandLine(cmdline, argv);
83.73
83.74 /* Run the main program */
83.75 - console_main(argc, argv);
83.76 + main_utf8(argc, argv);
83.77
83.78 SDL_stack_free(argv);
83.79
84.1 --- a/src/render/direct3d11/SDL_render_d3d11.c Sat Jan 24 23:58:07 2015 -0400
84.2 +++ b/src/render/direct3d11/SDL_render_d3d11.c Mon Apr 06 15:26:37 2015 -0300
84.3 @@ -829,9 +829,24 @@
84.4 renderer->info.flags = (SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);
84.5 renderer->driverdata = data;
84.6
84.7 +#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
84.8 + /* VSync is required in Windows Phone, at least for Win Phone 8.0 and 8.1.
84.9 + * Failure to use it seems to either result in:
84.10 + *
84.11 + * - with the D3D11 debug runtime turned OFF, vsync seemingly gets turned
84.12 + * off (framerate doesn't get capped), but nothing appears on-screen
84.13 + *
84.14 + * - with the D3D11 debug runtime turned ON, vsync gets automatically
84.15 + * turned back on, and the following gets output to the debug console:
84.16 + *
84.17 + * DXGI ERROR: IDXGISwapChain::Present: Interval 0 is not supported, changed to Interval 1. [ UNKNOWN ERROR #1024: ]
84.18 + */
84.19 + renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
84.20 +#else
84.21 if ((flags & SDL_RENDERER_PRESENTVSYNC)) {
84.22 renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
84.23 }
84.24 +#endif
84.25
84.26 /* HACK: make sure the SDL_Renderer references the SDL_Window data now, in
84.27 * order to give init functions access to the underlying window handle:
85.1 --- a/src/render/opengl/SDL_render_gl.c Sat Jan 24 23:58:07 2015 -0400
85.2 +++ b/src/render/opengl/SDL_render_gl.c Mon Apr 06 15:26:37 2015 -0300
85.3 @@ -342,9 +342,11 @@
85.4
85.5 if (type == GL_DEBUG_TYPE_ERROR_ARB) {
85.6 /* Record this error */
85.7 - ++data->errors;
85.8 - data->error_messages = SDL_realloc(data->error_messages, data->errors * sizeof(*data->error_messages));
85.9 - if (data->error_messages) {
85.10 + int errors = data->errors + 1;
85.11 + char **error_messages = SDL_realloc(data->error_messages, errors * sizeof(*data->error_messages));
85.12 + if (error_messages) {
85.13 + data->errors = errors;
85.14 + data->error_messages = error_messages;
85.15 data->error_messages[data->errors-1] = SDL_strdup(message);
85.16 }
85.17 }
86.1 --- a/src/test/SDL_test_common.c Sat Jan 24 23:58:07 2015 -0400
86.2 +++ b/src/test/SDL_test_common.c Mon Apr 06 15:26:37 2015 -0300
86.3 @@ -1204,10 +1204,10 @@
86.4 event->tfinger.dx, event->tfinger.dy, event->tfinger.pressure);
86.5 break;
86.6 case SDL_DOLLARGESTURE:
86.7 - SDL_Log("SDL_EVENT: Dollar gesture detect: %"SDL_PRIs64, (long long) event->dgesture.gestureId);
86.8 + SDL_Log("SDL_EVENT: Dollar gesture detect: %"SDL_PRIs64, (Sint64) event->dgesture.gestureId);
86.9 break;
86.10 case SDL_DOLLARRECORD:
86.11 - SDL_Log("SDL_EVENT: Dollar gesture record: %"SDL_PRIs64, (long long) event->dgesture.gestureId);
86.12 + SDL_Log("SDL_EVENT: Dollar gesture record: %"SDL_PRIs64, (Sint64) event->dgesture.gestureId);
86.13 break;
86.14 case SDL_MULTIGESTURE:
86.15 SDL_Log("SDL_EVENT: Multi gesture fingers: %d", event->mgesture.numFingers);
87.1 --- a/src/thread/psp/SDL_syscond.c Sat Jan 24 23:58:07 2015 -0400
87.2 +++ b/src/thread/psp/SDL_syscond.c Mon Apr 06 15:26:37 2015 -0300
87.3 @@ -20,6 +20,8 @@
87.4 */
87.5 #include "../../SDL_internal.h"
87.6
87.7 +#if SDL_THREAD_PSP
87.8 +
87.9 /* An implementation of condition variables using semaphores and mutexes */
87.10 /*
87.11 This implementation borrows heavily from the BeOS condition variable
87.12 @@ -217,4 +219,6 @@
87.13 return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT);
87.14 }
87.15
87.16 +#endif /* SDL_THREAD_PSP */
87.17 +
87.18 /* vi: set ts=4 sw=4 expandtab: */
88.1 --- a/src/thread/psp/SDL_sysmutex.c Sat Jan 24 23:58:07 2015 -0400
88.2 +++ b/src/thread/psp/SDL_sysmutex.c Mon Apr 06 15:26:37 2015 -0300
88.3 @@ -20,6 +20,8 @@
88.4 */
88.5 #include "../../SDL_internal.h"
88.6
88.7 +#if SDL_THREAD_PSP
88.8 +
88.9 /* An implementation of mutexes using semaphores */
88.10
88.11 #include "SDL_thread.h"
88.12 @@ -129,4 +131,6 @@
88.13 #endif /* SDL_THREADS_DISABLED */
88.14 }
88.15
88.16 +#endif /* SDL_THREAD_PSP */
88.17 +
88.18 /* vi: set ts=4 sw=4 expandtab: */
89.1 --- a/src/thread/psp/SDL_syssem.c Sat Jan 24 23:58:07 2015 -0400
89.2 +++ b/src/thread/psp/SDL_syssem.c Mon Apr 06 15:26:37 2015 -0300
89.3 @@ -18,6 +18,9 @@
89.4 misrepresented as being the original software.
89.5 3. This notice may not be removed or altered from any source distribution.
89.6 */
89.7 +#include "../../SDL_internal.h"
89.8 +
89.9 +#if SDL_THREAD_PSP
89.10
89.11 /* Semaphore functions for the PSP. */
89.12
89.13 @@ -152,5 +155,7 @@
89.14 return 0;
89.15 }
89.16
89.17 +#endif /* SDL_THREAD_PSP */
89.18 +
89.19 /* vim: ts=4 sw=4
89.20 */
90.1 --- a/src/thread/psp/SDL_systhread.c Sat Jan 24 23:58:07 2015 -0400
90.2 +++ b/src/thread/psp/SDL_systhread.c Mon Apr 06 15:26:37 2015 -0300
90.3 @@ -18,7 +18,9 @@
90.4 misrepresented as being the original software.
90.5 3. This notice may not be removed or altered from any source distribution.
90.6 */
90.7 +#include "../../SDL_internal.h"
90.8
90.9 +#if SDL_THREAD_PSP
90.10
90.11 /* PSP thread management routines for SDL */
90.12
90.13 @@ -104,5 +106,7 @@
90.14
90.15 }
90.16
90.17 +#endif /* SDL_THREAD_PSP */
90.18 +
90.19 /* vim: ts=4 sw=4
90.20 */
91.1 --- a/src/timer/psp/SDL_systimer.c Sat Jan 24 23:58:07 2015 -0400
91.2 +++ b/src/timer/psp/SDL_systimer.c Mon Apr 06 15:26:37 2015 -0300
91.3 @@ -18,6 +18,9 @@
91.4 misrepresented as being the original software.
91.5 3. This notice may not be removed or altered from any source distribution.
91.6 */
91.7 +#include "../../SDL_internal.h"
91.8 +
91.9 +#ifdef SDL_TIMERS_PSP
91.10
91.11 #include "SDL_thread.h"
91.12 #include "SDL_timer.h"
91.13 @@ -82,5 +85,7 @@
91.14 sceKernelDelayThreadCB(ms * 1000);
91.15 }
91.16
91.17 +#endif /* SDL_TIMERS_PSP */
91.18 +
91.19 /* vim: ts=4 sw=4
91.20 */
92.1 --- a/src/video/SDL_bmp.c Sat Jan 24 23:58:07 2015 -0400
92.2 +++ b/src/video/SDL_bmp.c Mon Apr 06 15:26:37 2015 -0300
92.3 @@ -306,16 +306,19 @@
92.4 biClrUsed = 1 << biBitCount;
92.5 }
92.6 if ((int) biClrUsed > palette->ncolors) {
92.7 - palette->ncolors = biClrUsed;
92.8 - palette->colors =
92.9 + SDL_Color *colors;
92.10 + int ncolors = biClrUsed;
92.11 + colors =
92.12 (SDL_Color *) SDL_realloc(palette->colors,
92.13 - palette->ncolors *
92.14 + ncolors *
92.15 sizeof(*palette->colors));
92.16 - if (!palette->colors) {
92.17 + if (!colors) {
92.18 SDL_OutOfMemory();
92.19 was_error = SDL_TRUE;
92.20 goto done;
92.21 }
92.22 + palette->ncolors = ncolors;
92.23 + palette->colors = colors;
92.24 } else if ((int) biClrUsed < palette->ncolors) {
92.25 palette->ncolors = biClrUsed;
92.26 }
93.1 --- a/src/video/SDL_clipboard.c Sat Jan 24 23:58:07 2015 -0400
93.2 +++ b/src/video/SDL_clipboard.c Mon Apr 06 15:26:37 2015 -0300
93.3 @@ -29,6 +29,10 @@
93.4 {
93.5 SDL_VideoDevice *_this = SDL_GetVideoDevice();
93.6
93.7 + if (!_this) {
93.8 + return SDL_SetError("Video subsystem must be initialized to set clipboard text");
93.9 + }
93.10 +
93.11 if (!text) {
93.12 text = "";
93.13 }
93.14 @@ -46,6 +50,11 @@
93.15 {
93.16 SDL_VideoDevice *_this = SDL_GetVideoDevice();
93.17
93.18 + if (!_this) {
93.19 + SDL_SetError("Video subsystem must be initialized to get clipboard text");
93.20 + return SDL_strdup("");
93.21 + }
93.22 +
93.23 if (_this->GetClipboardText) {
93.24 return _this->GetClipboardText(_this);
93.25 } else {
93.26 @@ -62,6 +71,11 @@
93.27 {
93.28 SDL_VideoDevice *_this = SDL_GetVideoDevice();
93.29
93.30 + if (!_this) {
93.31 + SDL_SetError("Video subsystem must be initialized to check clipboard text");
93.32 + return SDL_FALSE;
93.33 + }
93.34 +
93.35 if (_this->HasClipboardText) {
93.36 return _this->HasClipboardText(_this);
93.37 } else {
94.1 --- a/src/video/SDL_fillrect.c Sat Jan 24 23:58:07 2015 -0400
94.2 +++ b/src/video/SDL_fillrect.c Mon Apr 06 15:26:37 2015 -0300
94.3 @@ -251,6 +251,10 @@
94.4 rect = &clipped;
94.5 } else {
94.6 rect = &dst->clip_rect;
94.7 + /* Don't attempt to fill if the surface's clip_rect is empty */
94.8 + if (SDL_RectEmpty(rect)) {
94.9 + return 0;
94.10 + }
94.11 }
94.12
94.13 /* Perform software fill */
95.1 --- a/src/video/SDL_sysvideo.h Sat Jan 24 23:58:07 2015 -0400
95.2 +++ b/src/video/SDL_sysvideo.h Mon Apr 06 15:26:37 2015 -0300
95.3 @@ -274,6 +274,7 @@
95.4 int num_displays;
95.5 SDL_VideoDisplay *displays;
95.6 SDL_Window *windows;
95.7 + SDL_Window *grabbed_window;
95.8 Uint8 window_magic;
95.9 Uint32 next_object_id;
95.10 char * clipboard_text;
95.11 @@ -303,6 +304,7 @@
95.12 int flags;
95.13 int profile_mask;
95.14 int share_with_current_context;
95.15 + int release_behavior;
95.16 int framebuffer_srgb_capable;
95.17 int retained_backing;
95.18 int driver_loaded;
96.1 --- a/src/video/SDL_video.c Sat Jan 24 23:58:07 2015 -0400
96.2 +++ b/src/video/SDL_video.c Mon Apr 06 15:26:37 2015 -0300
96.3 @@ -46,6 +46,10 @@
96.4 #include "SDL_opengles2.h"
96.5 #endif /* SDL_VIDEO_OPENGL_ES2 && !SDL_VIDEO_OPENGL */
96.6
96.7 +#ifndef GL_CONTEXT_RELEASE_BEHAVIOR_KHR
96.8 +#define GL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x82FB
96.9 +#endif
96.10 +
96.11 /* On Windows, windows.h defines CreateWindow */
96.12 #ifdef CreateWindow
96.13 #undef CreateWindow
96.14 @@ -1612,13 +1616,14 @@
96.15 CHECK_WINDOW_MAGIC(window,);
96.16
96.17 if (SDL_WINDOWPOS_ISCENTERED(x) || SDL_WINDOWPOS_ISCENTERED(y)) {
96.18 - SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
96.19 - int displayIndex;
96.20 + int displayIndex = (x & 0xFFFF);
96.21 SDL_Rect bounds;
96.22 + if (displayIndex > _this->num_displays) {
96.23 + displayIndex = 0;
96.24 + }
96.25
96.26 SDL_zero(bounds);
96.27
96.28 - displayIndex = SDL_GetIndexOfDisplay(display);
96.29 SDL_GetDisplayBounds(displayIndex, &bounds);
96.30 if (SDL_WINDOWPOS_ISCENTERED(x)) {
96.31 x = bounds.x + (bounds.w - window->w) / 2;
96.32 @@ -2114,6 +2119,7 @@
96.33 SDL_UpdateWindowGrab(SDL_Window * window)
96.34 {
96.35 if (_this->SetWindowGrab) {
96.36 + SDL_Window *grabbed_window;
96.37 SDL_bool grabbed;
96.38 if ((SDL_GetMouse()->relative_mode || (window->flags & SDL_WINDOW_INPUT_GRABBED)) &&
96.39 (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
96.40 @@ -2121,6 +2127,19 @@
96.41 } else {
96.42 grabbed = SDL_FALSE;
96.43 }
96.44 +
96.45 + grabbed_window = _this->grabbed_window;
96.46 + if (grabbed) {
96.47 + if (grabbed_window && (grabbed_window != window)) {
96.48 + /* stealing a grab from another window! */
96.49 + grabbed_window->flags &= ~SDL_WINDOW_INPUT_GRABBED;
96.50 + _this->SetWindowGrab(_this, grabbed_window, SDL_FALSE);
96.51 + }
96.52 + _this->grabbed_window = window;
96.53 + } else if (grabbed_window == window) {
96.54 + _this->grabbed_window = NULL; /* ungrabbing. */
96.55 + }
96.56 +
96.57 _this->SetWindowGrab(_this, window, grabbed);
96.58 }
96.59 }
96.60 @@ -2145,8 +2164,15 @@
96.61 SDL_GetWindowGrab(SDL_Window * window)
96.62 {
96.63 CHECK_WINDOW_MAGIC(window, SDL_FALSE);
96.64 -
96.65 - return ((window->flags & SDL_WINDOW_INPUT_GRABBED) != 0);
96.66 + SDL_assert(!_this->grabbed_window || ((_this->grabbed_window->flags & SDL_WINDOW_INPUT_GRABBED) != 0));
96.67 + return window == _this->grabbed_window;
96.68 +}
96.69 +
96.70 +SDL_Window *
96.71 +SDL_GetGrabbedWindow(void)
96.72 +{
96.73 + SDL_assert(!_this->grabbed_window || ((_this->grabbed_window->flags & SDL_WINDOW_INPUT_GRABBED) != 0));
96.74 + return _this->grabbed_window;
96.75 }
96.76
96.77 void
96.78 @@ -2639,6 +2665,7 @@
96.79 #endif
96.80 _this->gl_config.flags = 0;
96.81 _this->gl_config.framebuffer_srgb_capable = 0;
96.82 + _this->gl_config.release_behavior = SDL_GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH;
96.83
96.84 _this->gl_config.share_with_current_context = 0;
96.85 }
96.86 @@ -2745,6 +2772,9 @@
96.87 case SDL_GL_FRAMEBUFFER_SRGB_CAPABLE:
96.88 _this->gl_config.framebuffer_srgb_capable = value;
96.89 break;
96.90 + case SDL_GL_CONTEXT_RELEASE_BEHAVIOR:
96.91 + _this->gl_config.release_behavior = value;
96.92 + break;
96.93 default:
96.94 retval = SDL_SetError("Unknown OpenGL attribute");
96.95 break;
96.96 @@ -2847,6 +2877,13 @@
96.97 attrib = GL_SAMPLES;
96.98 #endif
96.99 break;
96.100 + case SDL_GL_CONTEXT_RELEASE_BEHAVIOR:
96.101 +#if SDL_VIDEO_OPENGL
96.102 + attrib = GL_CONTEXT_RELEASE_BEHAVIOR;
96.103 +#else
96.104 + attrib = GL_CONTEXT_RELEASE_BEHAVIOR_KHR;
96.105 +#endif
96.106 + break;
96.107 case SDL_GL_BUFFER_SIZE:
96.108 {
96.109 GLint bits = 0;
97.1 --- a/src/video/android/SDL_androidevents.c Sat Jan 24 23:58:07 2015 -0400
97.2 +++ b/src/video/android/SDL_androidevents.c Mon Apr 06 15:26:37 2015 -0300
97.3 @@ -32,8 +32,14 @@
97.4
97.5 void android_egl_context_backup();
97.6 void android_egl_context_restore();
97.7 +
97.8 +#if SDL_AUDIO_DRIVER_ANDROID
97.9 void AndroidAUD_ResumeDevices(void);
97.10 void AndroidAUD_PauseDevices(void);
97.11 +#else
97.12 +static void AndroidAUD_ResumeDevices(void) {}
97.13 +static void AndroidAUD_PauseDevices(void) {}
97.14 +#endif
97.15
97.16 void
97.17 android_egl_context_restore()
98.1 --- a/src/video/android/SDL_androidmessagebox.c Sat Jan 24 23:58:07 2015 -0400
98.2 +++ b/src/video/android/SDL_androidmessagebox.c Mon Apr 06 15:26:37 2015 -0300
98.3 @@ -18,7 +18,7 @@
98.4 misrepresented as being the original software.
98.5 3. This notice may not be removed or altered from any source distribution.
98.6 */
98.7 -#include "SDL_config.h"
98.8 +#include "../../SDL_internal.h"
98.9
98.10 #if SDL_VIDEO_DRIVER_ANDROID
98.11
99.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
99.2 +++ b/src/video/android/SDL_androidmouse.c Mon Apr 06 15:26:37 2015 -0300
99.3 @@ -0,0 +1,84 @@
99.4 +/*
99.5 + Simple DirectMedia Layer
99.6 + Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
99.7 +
99.8 + This software is provided 'as-is', without any express or implied
99.9 + warranty. In no event will the authors be held liable for any damages
99.10 + arising from the use of this software.
99.11 +
99.12 + Permission is granted to anyone to use this software for any purpose,
99.13 + including commercial applications, and to alter it and redistribute it
99.14 + freely, subject to the following restrictions:
99.15 +
99.16 + 1. The origin of this software must not be misrepresented; you must not
99.17 + claim that you wrote the original software. If you use this software
99.18 + in a product, an acknowledgment in the product documentation would be
99.19 + appreciated but is not required.
99.20 + 2. Altered source versions must be plainly marked as such, and must not be
99.21 + misrepresented as being the original software.
99.22 + 3. This notice may not be removed or altered from any source distribution.
99.23 +*/
99.24 +
99.25 +#include "../../SDL_internal.h"
99.26 +
99.27 +#if SDL_VIDEO_DRIVER_ANDROID
99.28 +
99.29 +#include "SDL_androidmouse.h"
99.30 +
99.31 +#include "SDL_events.h"
99.32 +#include "../../events/SDL_mouse_c.h"
99.33 +
99.34 +#include "../../core/android/SDL_android.h"
99.35 +
99.36 +#define ACTION_DOWN 0
99.37 +#define ACTION_UP 1
99.38 +#define ACTION_HOVER_MOVE 7
99.39 +#define ACTION_SCROLL 8
99.40 +#define BUTTON_PRIMARY 1
99.41 +#define BUTTON_SECONDARY 2
99.42 +#define BUTTON_TERTIARY 4
99.43 +
99.44 +void Android_OnMouse( int androidButton, int action, float x, float y) {
99.45 + static Uint8 SDLButton;
99.46 +
99.47 + if (!Android_Window) {
99.48 + return;
99.49 + }
99.50 +
99.51 + switch(action) {
99.52 + case ACTION_DOWN:
99.53 + // Determine which button originated the event, and store it for ACTION_UP
99.54 + SDLButton = SDL_BUTTON_LEFT;
99.55 + if (androidButton == BUTTON_SECONDARY) {
99.56 + SDLButton = SDL_BUTTON_RIGHT;
99.57 + } else if (androidButton == BUTTON_TERTIARY) {
99.58 + SDLButton = SDL_BUTTON_MIDDLE;
99.59 + }
99.60 + SDL_SendMouseMotion(Android_Window, 0, 0, x, y);
99.61 + SDL_SendMouseButton(Android_Window, 0, SDL_PRESSED, SDLButton);
99.62 + break;
99.63 +
99.64 + case ACTION_UP:
99.65 + // Android won't give us the button that originated the ACTION_DOWN event, so we'll
99.66 + // assume it's the one we stored
99.67 + SDL_SendMouseMotion(Android_Window, 0, 0, x, y);
99.68 + SDL_SendMouseButton(Android_Window, 0, SDL_RELEASED, SDLButton);
99.69 + break;
99.70 +
99.71 + case ACTION_HOVER_MOVE:
99.72 + SDL_SendMouseMotion(Android_Window, 0, 0, x, y);
99.73 + break;
99.74 +
99.75 + case ACTION_SCROLL:
99.76 + SDL_SendMouseWheel(Android_Window, 0, x, y, SDL_MOUSEWHEEL_NORMAL);
99.77 + break;
99.78 +
99.79 + default:
99.80 + break;
99.81 + }
99.82 +}
99.83 +
99.84 +#endif /* SDL_VIDEO_DRIVER_ANDROID */
99.85 +
99.86 +/* vi: set ts=4 sw=4 expandtab: */
99.87 +
100.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
100.2 +++ b/src/video/android/SDL_androidmouse.h Mon Apr 06 15:26:37 2015 -0300
100.3 @@ -0,0 +1,31 @@
100.4 +/*
100.5 + Simple DirectMedia Layer
100.6 + Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
100.7 +
100.8 + This software is provided 'as-is', without any express or implied
100.9 + warranty. In no event will the authors be held liable for any damages
100.10 + arising from the use of this software.
100.11 +
100.12 + Permission is granted to anyone to use this software for any purpose,
100.13 + including commercial applications, and to alter it and redistribute it
100.14 + freely, subject to the following restrictions:
100.15 +
100.16 + 1. The origin of this software must not be misrepresented; you must not
100.17 + claim that you wrote the original software. If you use this software
100.18 + in a product, an acknowledgment in the product documentation would be
100.19 + appreciated but is not required.
100.20 + 2. Altered source versions must be plainly marked as such, and must not be
100.21 + misrepresented as being the original software.
100.22 + 3. This notice may not be removed or altered from any source distribution.
100.23 +*/
100.24 +
100.25 +#ifndef _SDL_androidmouse_h
100.26 +#define _SDL_androidmouse_h
100.27 +
100.28 +#include "SDL_androidvideo.h"
100.29 +
100.30 +extern void Android_OnMouse( int button, int action, float x, float y);
100.31 +
100.32 +#endif /* _SDL_androidmouse_h */
100.33 +
100.34 +/* vi: set ts=4 sw=4 expandtab: */
101.1 --- a/src/video/android/SDL_androidtouch.c Sat Jan 24 23:58:07 2015 -0400
101.2 +++ b/src/video/android/SDL_androidtouch.c Mon Apr 06 15:26:37 2015 -0300
101.3 @@ -24,13 +24,12 @@
101.4
101.5 #include <android/log.h>
101.6
101.7 +#include "SDL_hints.h"
101.8 #include "SDL_events.h"
101.9 +#include "SDL_log.h"
101.10 +#include "SDL_androidtouch.h"
101.11 #include "../../events/SDL_mouse_c.h"
101.12 #include "../../events/SDL_touch_c.h"
101.13 -#include "SDL_log.h"
101.14 -
101.15 -#include "SDL_androidtouch.h"
101.16 -
101.17 #include "../../core/android/SDL_android.h"
101.18
101.19 #define ACTION_DOWN 0
101.20 @@ -51,11 +50,29 @@
101.21 *window_y = (int)(y * window_h);
101.22 }
101.23
101.24 +static volatile SDL_bool separate_mouse_and_touch = SDL_FALSE;
101.25 +
101.26 +static void
101.27 +SeparateEventsHintWatcher(void *userdata, const char *name,
101.28 + const char *oldValue, const char *newValue)
101.29 +{
101.30 + jclass mActivityClass = Android_JNI_GetActivityClass();
101.31 + JNIEnv *env = Android_JNI_GetEnv();
101.32 + jfieldID fid = (*env)->GetStaticFieldID(env, mActivityClass, "mSeparateMouseAndTouch", "Z");
101.33 +
101.34 + separate_mouse_and_touch = (newValue && (SDL_strcmp(newValue, "1") == 0));
101.35 + (*env)->SetStaticBooleanField(env, mActivityClass, fid, separate_mouse_and_touch ? JNI_TRUE : JNI_FALSE);
101.36 +}
101.37 +
101.38 void Android_InitTouch(void)
101.39 {
101.40 int i;
101.41 int* ids;
101.42 - int number = Android_JNI_GetTouchDeviceIds(&ids);
101.43 + const int number = Android_JNI_GetTouchDeviceIds(&ids);
101.44 +
101.45 + SDL_AddHintCallback(SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH,
101.46 + SeparateEventsHintWatcher, NULL);
101.47 +
101.48 if (0 < number) {
101.49 for (i = 0; i < number; ++i) {
101.50 SDL_AddTouch((SDL_TouchID) ids[i], ""); /* no error handling */
101.51 @@ -64,6 +81,13 @@
101.52 }
101.53 }
101.54
101.55 +void Android_QuitTouch(void)
101.56 +{
101.57 + SDL_DelHintCallback(SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH,
101.58 + SeparateEventsHintWatcher, NULL);
101.59 + separate_mouse_and_touch = SDL_FALSE;
101.60 +}
101.61 +
101.62 void Android_OnTouch(int touch_device_id_in, int pointer_finger_id_in, int action, float x, float y, float p)
101.63 {
101.64 SDL_TouchID touchDeviceId = 0;
101.65 @@ -85,36 +109,41 @@
101.66 case ACTION_DOWN:
101.67 /* Primary pointer down */
101.68 Android_GetWindowCoordinates(x, y, &window_x, &window_y);
101.69 - /* send moved event */
101.70 - SDL_SendMouseMotion(Android_Window, SDL_TOUCH_MOUSEID, 0, window_x, window_y);
101.71 - /* send mouse down event */
101.72 - SDL_SendMouseButton(Android_Window, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT);
101.73 + if (!separate_mouse_and_touch) {
101.74 + /* send moved event */
101.75 + SDL_SendMouseMotion(Android_Window, SDL_TOUCH_MOUSEID, 0, window_x, window_y);
101.76 + /* send mouse down event */
101.77 + SDL_SendMouseButton(Android_Window, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT);
101.78 + }
101.79 pointerFingerID = fingerId;
101.80 case ACTION_POINTER_DOWN:
101.81 /* Non primary pointer down */
101.82 SDL_SendTouch(touchDeviceId, fingerId, SDL_TRUE, x, y, p);
101.83 break;
101.84 -
101.85 +
101.86 case ACTION_MOVE:
101.87 if (!pointerFingerID) {
101.88 Android_GetWindowCoordinates(x, y, &window_x, &window_y);
101.89 -
101.90 - /* send moved event */
101.91 - SDL_SendMouseMotion(Android_Window, SDL_TOUCH_MOUSEID, 0, window_x, window_y);
101.92 + if (!separate_mouse_and_touch) {
101.93 + /* send moved event */
101.94 + SDL_SendMouseMotion(Android_Window, SDL_TOUCH_MOUSEID, 0, window_x, window_y);
101.95 + }
101.96 }
101.97 SDL_SendTouchMotion(touchDeviceId, fingerId, x, y, p);
101.98 break;
101.99 -
101.100 +
101.101 case ACTION_UP:
101.102 /* Primary pointer up */
101.103 - /* send mouse up */
101.104 - pointerFingerID = (SDL_FingerID) 0;
101.105 - SDL_SendMouseButton(Android_Window, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT);
101.106 + if (!separate_mouse_and_touch) {
101.107 + /* send mouse up */
101.108 + pointerFingerID = (SDL_FingerID) 0;
101.109 + SDL_SendMouseButton(Android_Window, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT);
101.110 + }
101.111 case ACTION_POINTER_UP:
101.112 /* Non primary pointer up */
101.113 SDL_SendTouch(touchDeviceId, fingerId, SDL_FALSE, x, y, p);
101.114 break;
101.115 -
101.116 +
101.117 default:
101.118 break;
101.119 }
102.1 --- a/src/video/android/SDL_androidtouch.h Sat Jan 24 23:58:07 2015 -0400
102.2 +++ b/src/video/android/SDL_androidtouch.h Mon Apr 06 15:26:37 2015 -0300
102.3 @@ -23,6 +23,7 @@
102.4 #include "SDL_androidvideo.h"
102.5
102.6 extern void Android_InitTouch(void);
102.7 +extern void Android_QuitTouch(void);
102.8 extern void Android_OnTouch( int touch_device_id_in, int pointer_finger_id_in, int action, float x, float y, float p);
102.9
102.10 /* vi: set ts=4 sw=4 expandtab: */
103.1 --- a/src/video/android/SDL_androidvideo.c Sat Jan 24 23:58:07 2015 -0400
103.2 +++ b/src/video/android/SDL_androidvideo.c Mon Apr 06 15:26:37 2015 -0300
103.3 @@ -86,6 +86,7 @@
103.4 static void
103.5 Android_DeleteDevice(SDL_VideoDevice * device)
103.6 {
103.7 + SDL_free(device->driverdata);
103.8 SDL_free(device);
103.9 }
103.10
103.11 @@ -187,6 +188,7 @@
103.12 void
103.13 Android_VideoQuit(_THIS)
103.14 {
103.15 + Android_QuitTouch();
103.16 }
103.17
103.18 /* This function gets called before VideoInit() */
104.1 --- a/src/video/cocoa/SDL_cocoaevents.h Sat Jan 24 23:58:07 2015 -0400
104.2 +++ b/src/video/cocoa/SDL_cocoaevents.h Mon Apr 06 15:26:37 2015 -0300
104.3 @@ -25,6 +25,7 @@
104.4
104.5 extern void Cocoa_RegisterApp(void);
104.6 extern void Cocoa_PumpEvents(_THIS);
104.7 +extern void Cocoa_SuspendScreenSaver(_THIS);
104.8
104.9 #endif /* _SDL_cocoaevents_h */
104.10
105.1 --- a/src/video/cocoa/SDL_cocoaevents.m Sat Jan 24 23:58:07 2015 -0400
105.2 +++ b/src/video/cocoa/SDL_cocoaevents.m Mon Apr 06 15:26:37 2015 -0300
105.3 @@ -27,6 +27,11 @@
105.4 #include "../../events/SDL_events_c.h"
105.5 #include "SDL_assert.h"
105.6
105.7 +/* This define was added in the 10.9 SDK. */
105.8 +#ifndef kIOPMAssertPreventUserIdleDisplaySleep
105.9 +#define kIOPMAssertPreventUserIdleDisplaySleep kIOPMAssertionTypePreventUserIdleDisplaySleep
105.10 +#endif
105.11 +
105.12 @interface SDLApplication : NSApplication
105.13
105.14 - (void)terminate:(id)sender;
105.15 @@ -61,11 +66,19 @@
105.16 {
105.17 self = [super init];
105.18 if (self) {
105.19 + NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
105.20 +
105.21 seenFirstActivate = NO;
105.22 - [[NSNotificationCenter defaultCenter] addObserver:self
105.23 - selector:@selector(focusSomeWindow:)
105.24 - name:NSApplicationDidBecomeActiveNotification
105.25 - object:nil];
105.26 +
105.27 + [center addObserver:self
105.28 + selector:@selector(windowWillClose:)
105.29 + name:NSWindowWillCloseNotification
105.30 + object:nil];
105.31 +
105.32 + [center addObserver:self
105.33 + selector:@selector(focusSomeWindow:)
105.34 + name:NSApplicationDidBecomeActiveNotification
105.35 + object:nil];
105.36 }
105.37
105.38 return self;
105.39 @@ -73,16 +86,65 @@
105.40
105.41 - (void)dealloc
105.42 {
105.43 - [[NSNotificationCenter defaultCenter] removeObserver:self];
105.44 + NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
105.45 +
105.46 + [center removeObserver:self name:NSWindowWillCloseNotification object:nil];
105.47 + [center removeObserver:self name:NSApplicationDidBecomeActiveNotification object:nil];
105.48 +
105.49 [super dealloc];
105.50 }
105.51
105.52 +- (void)windowWillClose:(NSNotification *)notification;
105.53 +{
105.54 + NSWindow *win = (NSWindow*)[notification object];
105.55 +
105.56 + if (![win isKeyWindow]) {
105.57 + return;
105.58 + }
105.59 +
105.60 + /* HACK: Make the next window in the z-order key when the key window is
105.61 + * closed. The custom event loop and/or windowing code we have seems to
105.62 + * prevent the normal behavior: https://bugzilla.libsdl.org/show_bug.cgi?id=1825
105.63 + */
105.64 +
105.65 + /* +[NSApp orderedWindows] never includes the 'About' window, but we still
105.66 + * want to try its list first since the behavior in other apps is to only
105.67 + * make the 'About' window key if no other windows are on-screen.
105.68 + */
105.69 + for (NSWindow *window in [NSApp orderedWindows]) {
105.70 + if (window != win && [window canBecomeKeyWindow]) {
105.71 + if ([window respondsToSelector:@selector(isOnActiveSpace)]) {
105.72 + if (![window isOnActiveSpace]) {
105.73 + continue;
105.74 + }
105.75 + }
105.76 + [window makeKeyAndOrderFront:self];
105.77 + return;
105.78 + }
105.79 + }
105.80 +
105.81 + /* If a window wasn't found above, iterate through all visible windows
105.82 + * (including the 'About' window, if it's shown) and make the first one key.
105.83 + * Note that +[NSWindow windowNumbersWithOptions:] was added in 10.6.
105.84 + */
105.85 + if ([NSWindow respondsToSelector:@selector(windowNumbersWithOptions:)]) {
105.86 + /* Get all visible windows in the active Space, in z-order. */
105.87 + for (NSNumber *num in [NSWindow windowNumbersWithOptions:0]) {
105.88 + NSWindow *window = [NSApp windowWithWindowNumber:[num integerValue]];
105.89 + if (window && window != win && [window canBecomeKeyWindow]) {
105.90 + [window makeKeyAndOrderFront:self];
105.91 + return;
105.92 + }
105.93 + }
105.94 + }
105.95 +}
105.96 +
105.97 - (void)focusSomeWindow:(NSNotification *)aNotification
105.98 {
105.99 /* HACK: Ignore the first call. The application gets a
105.100 * applicationDidBecomeActive: a little bit after the first window is
105.101 * created, and if we don't ignore it, a window that has been created with
105.102 - * SDL_WINDOW_MINIZED will ~immediately be restored.
105.103 + * SDL_WINDOW_MINIMIZED will ~immediately be restored.
105.104 */
105.105 if (!seenFirstActivate) {
105.106 seenFirstActivate = YES;
105.107 @@ -251,17 +313,24 @@
105.108 { @autoreleasepool
105.109 {
105.110 /* This can get called more than once! Be careful what you initialize! */
105.111 - ProcessSerialNumber psn;
105.112 -
105.113 - if (!GetCurrentProcess(&psn)) {
105.114 - TransformProcessType(&psn, kProcessTransformToForegroundApplication);
105.115 - SetFrontProcess(&psn);
105.116 - }
105.117
105.118 if (NSApp == nil) {
105.119 [SDLApplication sharedApplication];
105.120 SDL_assert(NSApp != nil);
105.121
105.122 +#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6
105.123 + if ([NSApp respondsToSelector:@selector(setActivationPolicy:)]) {
105.124 +#endif
105.125 + [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
105.126 +#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6
105.127 + } else {
105.128 + ProcessSerialNumber psn = {0, kCurrentProcess};
105.129 + TransformProcessType(&psn, kProcessTransformToForegroundApplication);
105.130 + }
105.131 +#endif
105.132 +
105.133 + [NSApp activateIgnoringOtherApps:YES];
105.134 +
105.135 if ([NSApp mainMenu] == nil) {
105.136 CreateApplicationMenus();
105.137 }
105.138 @@ -293,8 +362,8 @@
105.139 { @autoreleasepool
105.140 {
105.141 /* Update activity every 30 seconds to prevent screensaver */
105.142 - if (_this->suspend_screensaver) {
105.143 - SDL_VideoData *data = (SDL_VideoData *)_this->driverdata;
105.144 + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata;
105.145 + if (_this->suspend_screensaver && !data->screensaver_use_iopm) {
105.146 Uint32 now = SDL_GetTicks();
105.147 if (!data->screensaver_activity ||
105.148 SDL_TICKS_PASSED(now, data->screensaver_activity + 30000)) {
105.149 @@ -336,6 +405,35 @@
105.150 }
105.151 }}
105.152
105.153 +void
105.154 +Cocoa_SuspendScreenSaver(_THIS)
105.155 +{ @autoreleasepool
105.156 +{
105.157 + SDL_VideoData *data = (SDL_VideoData *)_this->driverdata;
105.158 +
105.159 + if (!data->screensaver_use_iopm) {
105.160 + return;
105.161 + }
105.162 +
105.163 + if (data->screensaver_assertion) {
105.164 + IOPMAssertionRelease(data->screensaver_assertion);
105.165 + data->screensaver_assertion = 0;
105.166 + }
105.167 +
105.168 + if (_this->suspend_screensaver) {
105.169 + /* FIXME: this should ideally describe the real reason why the game
105.170 + * called SDL_DisableScreenSaver. Note that the name is only meant to be
105.171 + * seen by OS X power users. there's an additional optional human-readable
105.172 + * (localized) reason parameter which we don't set.
105.173 + */
105.174 + NSString *name = [GetApplicationName() stringByAppendingString:@" using SDL_DisableScreenSaver"];
105.175 + IOPMAssertionCreateWithDescription(kIOPMAssertPreventUserIdleDisplaySleep,
105.176 + (CFStringRef) name,
105.177 + NULL, NULL, NULL, 0, NULL,
105.178 + &data->screensaver_assertion);
105.179 + }
105.180 +}}
105.181 +
105.182 #endif /* SDL_VIDEO_DRIVER_COCOA */
105.183
105.184 /* vi: set ts=4 sw=4 expandtab: */
106.1 --- a/src/video/cocoa/SDL_cocoavideo.h Sat Jan 24 23:58:07 2015 -0400
106.2 +++ b/src/video/cocoa/SDL_cocoavideo.h Mon Apr 06 15:26:37 2015 -0300
106.3 @@ -26,6 +26,7 @@
106.4 #include "SDL_opengl.h"
106.5
106.6 #include <ApplicationServices/ApplicationServices.h>
106.7 +#include <IOKit/pwr_mgt/IOPMLib.h>
106.8 #include <Cocoa/Cocoa.h>
106.9
106.10 #include "SDL_keycode.h"
106.11 @@ -51,6 +52,9 @@
106.12 SDLTranslatorResponder *fieldEdit;
106.13 NSInteger clipboard_count;
106.14 Uint32 screensaver_activity;
106.15 + BOOL screensaver_use_iopm;
106.16 + IOPMAssertionID screensaver_assertion;
106.17 +
106.18 } SDL_VideoData;
106.19
106.20 /* Utility functions */
107.1 --- a/src/video/cocoa/SDL_cocoavideo.m Sat Jan 24 23:58:07 2015 -0400
107.2 +++ b/src/video/cocoa/SDL_cocoavideo.m Mon Apr 06 15:26:37 2015 -0300
107.3 @@ -76,6 +76,7 @@
107.4 device->GetDisplayModes = Cocoa_GetDisplayModes;
107.5 device->SetDisplayMode = Cocoa_SetDisplayMode;
107.6 device->PumpEvents = Cocoa_PumpEvents;
107.7 + device->SuspendScreenSaver = Cocoa_SuspendScreenSaver;
107.8
107.9 device->CreateWindow = Cocoa_CreateWindow;
107.10 device->CreateWindowFrom = Cocoa_CreateWindowFrom;
107.11 @@ -148,6 +149,9 @@
107.12 const char *hint = SDL_GetHint(SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES);
107.13 data->allow_spaces = ( (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) && (!hint || (*hint != '0')) );
107.14
107.15 + /* The IOPM assertion API can disable the screensaver as of 10.7. */
107.16 + data->screensaver_use_iopm = floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6;
107.17 +
107.18 return 0;
107.19 }
107.20
108.1 --- a/src/video/cocoa/SDL_cocoawindow.m Sat Jan 24 23:58:07 2015 -0400
108.2 +++ b/src/video/cocoa/SDL_cocoawindow.m Mon Apr 06 15:26:37 2015 -0300
108.3 @@ -374,7 +374,6 @@
108.4 NSNotificationCenter *center;
108.5 NSWindow *window = _data->nswindow;
108.6 NSView *view = [window contentView];
108.7 - NSArray *windows = nil;
108.8
108.9 center = [NSNotificationCenter defaultCenter];
108.10
108.11 @@ -402,25 +401,6 @@
108.12 if ([view nextResponder] == self) {
108.13 [view setNextResponder:nil];
108.14 }
108.15 -
108.16 - /* Make the next window in the z-order Key. If we weren't the foreground
108.17 - when closed, this is a no-op.
108.18 - !!! FIXME: Note that this is a hack, and there are corner cases where
108.19 - !!! FIXME: this fails (such as the About box). The typical nib+RunLoop
108.20 - !!! FIXME: handles this for Cocoa apps, but we bypass all that in SDL.
108.21 - !!! FIXME: We should remove this code when we find a better way to
108.22 - !!! FIXME: have the system do this for us. See discussion in
108.23 - !!! FIXME: http://bugzilla.libsdl.org/show_bug.cgi?id=1825
108.24 - */
108.25 - windows = [NSApp orderedWindows];
108.26 - for (NSWindow *win in windows) {
108.27 - if (win == window) {
108.28 - continue;
108.29 - }
108.30 -
108.31 - [win makeKeyAndOrderFront:self];
108.32 - break;
108.33 - }
108.34 }
108.35
108.36 - (BOOL)isMoving
109.1 --- a/src/video/dummy/SDL_nullvideo.c Sat Jan 24 23:58:07 2015 -0400
109.2 +++ b/src/video/dummy/SDL_nullvideo.c Mon Apr 06 15:26:37 2015 -0300
109.3 @@ -82,7 +82,6 @@
109.4 device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
109.5 if (!device) {
109.6 SDL_OutOfMemory();
109.7 - SDL_free(device);
109.8 return (0);
109.9 }
109.10
110.1 --- a/src/video/emscripten/SDL_emscriptenevents.c Sat Jan 24 23:58:07 2015 -0400
110.2 +++ b/src/video/emscripten/SDL_emscriptenevents.c Mon Apr 06 15:26:37 2015 -0300
110.3 @@ -296,7 +296,7 @@
110.4 return SDL_TRUE;
110.5 }
110.6
110.7 -int
110.8 +EM_BOOL
110.9 Emscripten_HandleMouseMove(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData)
110.10 {
110.11 SDL_WindowData *window_data = userData;
110.12 @@ -322,7 +322,7 @@
110.13 return 0;
110.14 }
110.15
110.16 -int
110.17 +EM_BOOL
110.18 Emscripten_HandleMouseButton(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData)
110.19 {
110.20 SDL_WindowData *window_data = userData;
110.21 @@ -344,7 +344,7 @@
110.22 return 1;
110.23 }
110.24
110.25 -int
110.26 +EM_BOOL
110.27 Emscripten_HandleMouseFocus(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData)
110.28 {
110.29 SDL_WindowData *window_data = userData;
110.30 @@ -352,7 +352,7 @@
110.31 return 1;
110.32 }
110.33
110.34 -int
110.35 +EM_BOOL
110.36 Emscripten_HandleWheel(int eventType, const EmscriptenWheelEvent *wheelEvent, void *userData)
110.37 {
110.38 SDL_WindowData *window_data = userData;
110.39 @@ -360,7 +360,7 @@
110.40 return 1;
110.41 }
110.42
110.43 -int
110.44 +EM_BOOL
110.45 Emscripten_HandleFocus(int eventType, const EmscriptenFocusEvent *wheelEvent, void *userData)
110.46 {
110.47 SDL_WindowData *window_data = userData;
110.48 @@ -368,7 +368,7 @@
110.49 return 1;
110.50 }
110.51
110.52 -int
110.53 +EM_BOOL
110.54 Emscripten_HandleTouch(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData)
110.55 {
110.56 /*SDL_WindowData *window_data = userData;*/
110.57 @@ -404,7 +404,7 @@
110.58 return 1;
110.59 }
110.60
110.61 -int
110.62 +EM_BOOL
110.63 Emscripten_HandleKey(int eventType, const EmscriptenKeyboardEvent *keyEvent, void *userData)
110.64 {
110.65 Uint32 scancode;
110.66 @@ -443,16 +443,17 @@
110.67 || keyEvent->keyCode == 8 /* backspace */ || keyEvent->keyCode == 9 /* tab */;
110.68 }
110.69
110.70 -int
110.71 +EM_BOOL
110.72 Emscripten_HandleKeyPress(int eventType, const EmscriptenKeyboardEvent *keyEvent, void *userData)
110.73 {
110.74 char text[5];
110.75 - Emscripten_ConvertUTF32toUTF8(keyEvent->charCode, text);
110.76 - SDL_SendKeyboardText(text);
110.77 + if (Emscripten_ConvertUTF32toUTF8(keyEvent->charCode, text)) {
110.78 + SDL_SendKeyboardText(text);
110.79 + }
110.80 return 1;
110.81 }
110.82
110.83 -int
110.84 +EM_BOOL
110.85 Emscripten_HandleFullscreenChange(int eventType, const EmscriptenFullscreenChangeEvent *fullscreenChangeEvent, void *userData)
110.86 {
110.87 /*make sure this is actually our element going fullscreen*/
110.88 @@ -514,7 +515,7 @@
110.89 return 0;
110.90 }
110.91
110.92 -int
110.93 +EM_BOOL
110.94 Emscripten_HandleResize(int eventType, const EmscriptenUiEvent *uiEvent, void *userData)
110.95 {
110.96 SDL_WindowData *window_data = userData;
110.97 @@ -554,7 +555,7 @@
110.98 return 0;
110.99 }
110.100
110.101 -int
110.102 +EM_BOOL
110.103 Emscripten_HandleVisibilityChange(int eventType, const EmscriptenVisibilityChangeEvent *visEvent, void *userData)
110.104 {
110.105 SDL_WindowData *window_data = userData;
110.106 @@ -621,10 +622,15 @@
110.107 emscripten_set_touchmove_callback("#canvas", NULL, 0, NULL);
110.108 emscripten_set_touchcancel_callback("#canvas", NULL, 0, NULL);
110.109
110.110 - emscripten_set_keydown_callback("#window", NULL, 0, NULL);
110.111 - emscripten_set_keyup_callback("#window", NULL, 0, NULL);
110.112 + const char *target = SDL_GetHint(SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT);
110.113 + if (!target) {
110.114 + target = "#window";
110.115 + }
110.116
110.117 - emscripten_set_keypress_callback("#window", NULL, 0, NULL);
110.118 + emscripten_set_keydown_callback(target, NULL, 0, NULL);
110.119 + emscripten_set_keyup_callback(target, NULL, 0, NULL);
110.120 +
110.121 + emscripten_set_keypress_callback(target, NULL, 0, NULL);
110.122
110.123 emscripten_set_fullscreenchange_callback("#document", NULL, 0, NULL);
110.124
111.1 --- a/src/video/emscripten/SDL_emscriptenframebuffer.c Sat Jan 24 23:58:07 2015 -0400
111.2 +++ b/src/video/emscripten/SDL_emscriptenframebuffer.c Mon Apr 06 15:26:37 2015 -0300
111.3 @@ -63,7 +63,7 @@
111.4 SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
111.5 surface = data->surface;
111.6 if (!surface) {
111.7 - return SDL_SetError("Couldn't find dummy surface for window");
111.8 + return SDL_SetError("Couldn't find framebuffer surface for window");
111.9 }
111.10
111.11 /* Send the data to the display */
112.1 --- a/src/video/nacl/SDL_naclevents.c Sat Jan 24 23:58:07 2015 -0400
112.2 +++ b/src/video/nacl/SDL_naclevents.c Mon Apr 06 15:26:37 2015 -0300
112.3 @@ -20,6 +20,8 @@
112.4 */
112.5 #include "../../SDL_internal.h"
112.6
112.7 +#if SDL_VIDEO_DRIVER_NACL
112.8 +
112.9 #include "SDL.h"
112.10 #include "../../events/SDL_sysevents.h"
112.11 #include "../../events/SDL_events_c.h"
112.12 @@ -430,3 +432,7 @@
112.13 }
112.14 }
112.15 }
112.16 +
112.17 +#endif /* SDL_VIDEO_DRIVER_NACL */
112.18 +
112.19 +/* vi: set ts=4 sw=4 expandtab: */
113.1 --- a/src/video/psp/SDL_pspevents.c Sat Jan 24 23:58:07 2015 -0400
113.2 +++ b/src/video/psp/SDL_pspevents.c Mon Apr 06 15:26:37 2015 -0300
113.3 @@ -18,6 +18,9 @@
113.4 misrepresented as being the original software.
113.5 3. This notice may not be removed or altered from any source distribution.
113.6 */
113.7 +#include "../../SDL_internal.h"
113.8 +
113.9 +#if SDL_VIDEO_DRIVER_PSP
113.10
113.11 /* Being a null driver, there's no event stream. We just define stubs for
113.12 most of the API. */
113.13 @@ -282,3 +285,6 @@
113.14
113.15 /* end of SDL_pspevents.c ... */
113.16
113.17 +#endif /* SDL_VIDEO_DRIVER_PSP */
113.18 +
113.19 +/* vi: set ts=4 sw=4 expandtab: */
114.1 --- a/src/video/psp/SDL_pspgl.c Sat Jan 24 23:58:07 2015 -0400
114.2 +++ b/src/video/psp/SDL_pspgl.c Mon Apr 06 15:26:37 2015 -0300
114.3 @@ -18,6 +18,9 @@
114.4 misrepresented as being the original software.
114.5 3. This notice may not be removed or altered from any source distribution.
114.6 */
114.7 +#include "../../SDL_internal.h"
114.8 +
114.9 +#if SDL_VIDEO_DRIVER_PSP
114.10
114.11 #include <stdlib.h>
114.12 #include <string.h>
114.13 @@ -203,3 +206,6 @@
114.14 return;
114.15 }
114.16
114.17 +#endif /* SDL_VIDEO_DRIVER_PSP */
114.18 +
114.19 +/* vi: set ts=4 sw=4 expandtab: */
115.1 --- a/src/video/psp/SDL_pspmouse.c Sat Jan 24 23:58:07 2015 -0400
115.2 +++ b/src/video/psp/SDL_pspmouse.c Mon Apr 06 15:26:37 2015 -0300
115.3 @@ -18,7 +18,9 @@
115.4 misrepresented as being the original software.
115.5 3. This notice may not be removed or altered from any source distribution.
115.6 */
115.7 +#include "../../SDL_internal.h"
115.8
115.9 +#if SDL_VIDEO_DRIVER_PSP
115.10
115.11 #include <stdio.h>
115.12
115.13 @@ -33,3 +35,7 @@
115.14 struct WMcursor {
115.15 int unused;
115.16 };
115.17 +
115.18 +#endif /* SDL_VIDEO_DRIVER_PSP */
115.19 +
115.20 +/* vi: set ts=4 sw=4 expandtab: */
116.1 --- a/src/video/psp/SDL_pspvideo.c Sat Jan 24 23:58:07 2015 -0400
116.2 +++ b/src/video/psp/SDL_pspvideo.c Mon Apr 06 15:26:37 2015 -0300
116.3 @@ -66,7 +66,7 @@
116.4 SDL_GLDriverData *gldata;
116.5 int status;
116.6
116.7 - /* Check if pandora could be initialized */
116.8 + /* Check if PSP could be initialized */
116.9 status = PSP_Available();
116.10 if (status == 0) {
116.11 /* PSP could not be used */
116.12 @@ -80,7 +80,7 @@
116.13 return NULL;
116.14 }
116.15
116.16 - /* Initialize internal Pandora specific data */
116.17 + /* Initialize internal PSP specific data */
116.18 phdata = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
116.19 if (phdata == NULL) {
116.20 SDL_OutOfMemory();
117.1 --- a/src/video/psp/SDL_pspvideo.h Sat Jan 24 23:58:07 2015 -0400
117.2 +++ b/src/video/psp/SDL_pspvideo.h Mon Apr 06 15:26:37 2015 -0300
117.3 @@ -19,8 +19,8 @@
117.4 3. This notice may not be removed or altered from any source distribution.
117.5 */
117.6
117.7 -#ifndef __SDL_PANDORA_H__
117.8 -#define __SDL_PANDORA_H__
117.9 +#ifndef _SDL_pspvideo_h
117.10 +#define _SDL_pspvideo_h
117.11
117.12 #include <GLES/egl.h>
117.13
117.14 @@ -97,6 +97,6 @@
117.15 void PSP_HideScreenKeyboard(_THIS, SDL_Window *window);
117.16 SDL_bool PSP_IsScreenKeyboardShown(_THIS, SDL_Window *window);
117.17
117.18 -#endif /* __SDL_PANDORA_H__ */
117.19 +#endif /* _SDL_pspvideo_h */
117.20
117.21 /* vi: set ts=4 sw=4 expandtab: */
118.1 --- a/src/video/wayland/SDL_waylandwindow.c Sat Jan 24 23:58:07 2015 -0400
118.2 +++ b/src/video/wayland/SDL_waylandwindow.c Mon Apr 06 15:26:37 2015 -0300
118.3 @@ -29,6 +29,7 @@
118.4 #include "SDL_waylandwindow.h"
118.5 #include "SDL_waylandvideo.h"
118.6 #include "SDL_waylandtouch.h"
118.7 +#include "SDL_waylanddyn.h"
118.8
118.9 static void
118.10 handle_ping(void *data, struct wl_shell_surface *shell_surface,
119.1 --- a/src/video/windows/SDL_windowsevents.c Sat Jan 24 23:58:07 2015 -0400
119.2 +++ b/src/video/windows/SDL_windowsevents.c Mon Apr 06 15:26:37 2015 -0300
119.3 @@ -559,10 +559,11 @@
119.4
119.5 GetKeyboardState(keyboardState);
119.6 if (ToUnicode(wParam, (lParam >> 16) & 0xff, keyboardState, (LPWSTR)&utf32, 1, 0) > 0) {
119.7 - WORD repetition;
119.8 - for (repetition = lParam & 0xffff; repetition > 0; repetition--) {
119.9 - WIN_ConvertUTF32toUTF8(utf32, text);
119.10 - SDL_SendKeyboardText(text);
119.11 + if (WIN_ConvertUTF32toUTF8(utf32, text)) {
119.12 + WORD repetition;
119.13 + for (repetition = lParam & 0xffff; repetition > 0; repetition--) {
119.14 + SDL_SendKeyboardText(text);
119.15 + }
119.16 }
119.17 }
119.18 }
120.1 --- a/src/video/windows/SDL_windowsopengl.c Sat Jan 24 23:58:07 2015 -0400
120.2 +++ b/src/video/windows/SDL_windowsopengl.c Mon Apr 06 15:26:37 2015 -0300
120.3 @@ -74,6 +74,13 @@
120.4 #define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9
120.5 #endif
120.6
120.7 +#ifndef WGL_ARB_context_flush_control
120.8 +#define WGL_ARB_context_flush_control
120.9 +#define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
120.10 +#define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0x0000
120.11 +#define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
120.12 +#endif
120.13 +
120.14 typedef HGLRC(APIENTRYP PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC,
120.15 HGLRC
120.16 hShareContext,
120.17 @@ -405,6 +412,11 @@
120.18 _this->gl_data->HAS_WGL_EXT_create_context_es2_profile = SDL_TRUE;
120.19 }
120.20
120.21 + /* Check for GLX_ARB_context_flush_control */
120.22 + if (HasExtension("WGL_ARB_context_flush_control", extensions)) {
120.23 + _this->gl_data->HAS_WGL_ARB_context_flush_control = SDL_TRUE;
120.24 + }
120.25 +
120.26 _this->gl_data->wglMakeCurrent(hdc, NULL);
120.27 _this->gl_data->wglDeleteContext(hglrc);
120.28 ReleaseDC(hwnd, hdc);
120.29 @@ -648,8 +660,8 @@
120.30 SDL_SetError("GL 3.x is not supported");
120.31 context = temp_context;
120.32 } else {
120.33 - /* max 8 attributes plus terminator */
120.34 - int attribs[9] = {
120.35 + /* max 10 attributes plus terminator */
120.36 + int attribs[11] = {
120.37 WGL_CONTEXT_MAJOR_VERSION_ARB, _this->gl_config.major_version,
120.38 WGL_CONTEXT_MINOR_VERSION_ARB, _this->gl_config.minor_version,
120.39 0
120.40 @@ -668,6 +680,14 @@
120.41 attribs[iattr++] = _this->gl_config.flags;
120.42 }
120.43
120.44 + /* only set if wgl extension is available */
120.45 + if( _this->gl_data->HAS_WGL_ARB_context_flush_control ) {
120.46 + attribs[iattr++] = WGL_CONTEXT_RELEASE_BEHAVIOR_ARB;
120.47 + attribs[iattr++] = _this->gl_config.release_behavior ?
120.48 + WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB :
120.49 + WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB;
120.50 + }
120.51 +
120.52 attribs[iattr++] = 0;
120.53
120.54 /* Create the GL 3.x context */
121.1 --- a/src/video/windows/SDL_windowsopengl.h Sat Jan 24 23:58:07 2015 -0400
121.2 +++ b/src/video/windows/SDL_windowsopengl.h Mon Apr 06 15:26:37 2015 -0300
121.3 @@ -30,6 +30,7 @@
121.4 SDL_bool HAS_WGL_ARB_pixel_format;
121.5 SDL_bool HAS_WGL_EXT_swap_control_tear;
121.6 SDL_bool HAS_WGL_EXT_create_context_es2_profile;
121.7 + SDL_bool HAS_WGL_ARB_context_flush_control;
121.8
121.9 void *(WINAPI * wglGetProcAddress) (const char *proc);
121.10 HGLRC(WINAPI * wglCreateContext) (HDC hdc);
122.1 --- a/src/video/windows/SDL_windowswindow.c Sat Jan 24 23:58:07 2015 -0400
122.2 +++ b/src/video/windows/SDL_windowswindow.c Mon Apr 06 15:26:37 2015 -0300
122.3 @@ -643,10 +643,11 @@
122.4 SDL_bool
122.5 WIN_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
122.6 {
122.7 - HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
122.8 + const SDL_WindowData *data = (const SDL_WindowData *) window->driverdata;
122.9 if (info->version.major <= SDL_MAJOR_VERSION) {
122.10 info->subsystem = SDL_SYSWM_WINDOWS;
122.11 - info->info.win.window = hwnd;
122.12 + info->info.win.window = data->hwnd;
122.13 + info->info.win.hdc = data->hdc;
122.14 return SDL_TRUE;
122.15 } else {
122.16 SDL_SetError("Application not compiled with SDL %d.%d\n",
123.1 --- a/src/video/winrt/SDL_winrtopengles.cpp Sat Jan 24 23:58:07 2015 -0400
123.2 +++ b/src/video/winrt/SDL_winrtopengles.cpp Mon Apr 06 15:26:37 2015 -0300
123.3 @@ -36,10 +36,17 @@
123.4
123.5 /* ANGLE/WinRT constants */
123.6 static const int ANGLE_D3D_FEATURE_LEVEL_ANY = 0;
123.7 -#define EGL_PLATFORM_ANGLE_ANGLE 0x3201
123.8 -#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3202
123.9 -#define EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE 0x3203
123.10 -#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3205
123.11 +#define EGL_PLATFORM_ANGLE_ANGLE 0x3202
123.12 +#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3203
123.13 +#define EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE 0x3204
123.14 +#define EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE 0x3205
123.15 +#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208
123.16 +#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE 0x3209
123.17 +#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE 0x320B
123.18 +#define EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE 0x320F
123.19 +
123.20 +#define EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER 0x320B
123.21 +
123.22
123.23 /*
123.24 * SDL/EGL top-level implementation
123.25 @@ -80,11 +87,40 @@
123.26 Microsoft::WRL::ComPtr<IUnknown> cpp_display = video_data->winrtEglWindow;
123.27 _this->egl_data->egl_display = ((eglGetDisplay_Old_Function)_this->egl_data->eglGetDisplay)(cpp_display);
123.28 if (!_this->egl_data->egl_display) {
123.29 - return SDL_SetError("Could not get EGL display");
123.30 + return SDL_SetError("Could not get Windows 8.0 EGL display");
123.31 + }
123.32 +
123.33 + if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE) {
123.34 + return SDL_SetError("Could not initialize Windows 8.0 EGL");
123.35 }
123.36 } else {
123.37 - const EGLint displayAttributes[] = {
123.38 + /* Declare some ANGLE/EGL initialization property-sets, as suggested by
123.39 + * MSOpenTech's ANGLE-for-WinRT template apps:
123.40 + */
123.41 + const EGLint defaultDisplayAttributes[] =
123.42 + {
123.43 + EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
123.44 + EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE,
123.45 + EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE,
123.46 + EGL_NONE,
123.47 + };
123.48 +
123.49 + const EGLint fl9_3DisplayAttributes[] =
123.50 + {
123.51 EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
123.52 + EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, 9,
123.53 + EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, 3,
123.54 + EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE,
123.55 + EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE,
123.56 + EGL_NONE,
123.57 + };
123.58 +
123.59 + const EGLint warpDisplayAttributes[] =
123.60 + {
123.61 + EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
123.62 + EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE,
123.63 + EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE,
123.64 + EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE,
123.65 EGL_NONE,
123.66 };
123.67
123.68 @@ -99,14 +135,41 @@
123.69 return SDL_SetError("Could not retrieve ANGLE/WinRT display function(s)");
123.70 }
123.71
123.72 - _this->egl_data->egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, displayAttributes);
123.73 +#if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP)
123.74 + /* Try initializing EGL at D3D11 Feature Level 10_0+ (which is not
123.75 + * supported on WinPhone 8.x.
123.76 + */
123.77 + _this->egl_data->egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, defaultDisplayAttributes);
123.78 if (!_this->egl_data->egl_display) {
123.79 - return SDL_SetError("Could not get EGL display");
123.80 + return SDL_SetError("Could not get 10_0+ EGL display");
123.81 }
123.82 - }
123.83 +
123.84 + if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE)
123.85 +#endif
123.86 + {
123.87 + /* Try initializing EGL at D3D11 Feature Level 9_3, in case the
123.88 + * 10_0 init fails, or we're on Windows Phone (which only supports
123.89 + * 9_3).
123.90 + */
123.91 + _this->egl_data->egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, fl9_3DisplayAttributes);
123.92 + if (!_this->egl_data->egl_display) {
123.93 + return SDL_SetError("Could not get 9_3 EGL display");
123.94 + }
123.95
123.96 - if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE) {
123.97 - return SDL_SetError("Could not initialize EGL");
123.98 + if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE) {
123.99 + /* Try initializing EGL at D3D11 Feature Level 11_0 on WARP
123.100 + * (a Windows-provided, software rasterizer) if all else fails.
123.101 + */
123.102 + _this->egl_data->egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, warpDisplayAttributes);
123.103 + if (!_this->egl_data->egl_display) {
123.104 + return SDL_SetError("Could not get WARP EGL display");
123.105 + }
123.106 +
123.107 + if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE) {
123.108 + return SDL_SetError("Could not initialize WinRT 8.x+ EGL");
123.109 + }
123.110 + }
123.111 + }
123.112 }
123.113
123.114 return 0;
124.1 --- a/src/video/x11/SDL_x11events.c Sat Jan 24 23:58:07 2015 -0400
124.2 +++ b/src/video/x11/SDL_x11events.c Mon Apr 06 15:26:37 2015 -0300
124.3 @@ -677,8 +677,17 @@
124.4 data->window == SDL_GetKeyboardFocus()) {
124.5 ReconcileKeyboardState(_this, data);
124.6 }
124.7 - data->pending_focus = PENDING_FOCUS_IN;
124.8 - data->pending_focus_time = SDL_GetTicks() + PENDING_FOCUS_IN_TIME;
124.9 + if (!videodata->last_mode_change_deadline) /* no recent mode changes */
124.10 + {
124.11 + data->pending_focus = PENDING_FOCUS_NONE;
124.12 + data->pending_focus_time = 0;
124.13 + X11_DispatchFocusIn(data);
124.14 + }
124.15 + else
124.16 + {
124.17 + data->pending_focus = PENDING_FOCUS_IN;
124.18 + data->pending_focus_time = SDL_GetTicks() + PENDING_FOCUS_TIME;
124.19 + }
124.20 }
124.21 break;
124.22
124.23 @@ -701,8 +710,17 @@
124.24 #ifdef DEBUG_XEVENTS
124.25 printf("window %p: FocusOut!\n", data);
124.26 #endif
124.27 - data->pending_focus = PENDING_FOCUS_OUT;
124.28 - data->pending_focus_time = SDL_GetTicks() + PENDING_FOCUS_OUT_TIME;
124.29 + if (!videodata->last_mode_change_deadline) /* no recent mode changes */
124.30 + {
124.31 + data->pending_focus = PENDING_FOCUS_NONE;
124.32 + data->pending_focus_time = 0;
124.33 + X11_DispatchFocusOut(data);
124.34 + }
124.35 + else
124.36 + {
124.37 + data->pending_focus = PENDING_FOCUS_OUT;
124.38 + data->pending_focus_time = SDL_GetTicks() + PENDING_FOCUS_TIME;
124.39 + }
124.40 }
124.41 break;
124.42
124.43 @@ -1090,15 +1108,25 @@
124.44 without ever mapping / unmapping them, so we handle that here,
124.45 because they use the NETWM protocol to notify us of changes.
124.46 */
124.47 - Uint32 flags = X11_GetNetWMState(_this, xevent.xproperty.window);
124.48 - if ((flags^data->window->flags) & SDL_WINDOW_HIDDEN ||
124.49 - (flags^data->window->flags) & SDL_WINDOW_FULLSCREEN ) {
124.50 - if (flags & SDL_WINDOW_HIDDEN) {
124.51 - X11_DispatchUnmapNotify(data);
124.52 - } else {
124.53 - X11_DispatchMapNotify(data);
124.54 + const Uint32 flags = X11_GetNetWMState(_this, xevent.xproperty.window);
124.55 + const Uint32 changed = flags ^ data->window->flags;
124.56 +
124.57 + if ((changed & SDL_WINDOW_HIDDEN) || (changed & SDL_WINDOW_FULLSCREEN)) {
124.58 + if (flags & SDL_WINDOW_HIDDEN) {
124.59 + X11_DispatchUnmapNotify(data);
124.60 + } else {
124.61 + X11_DispatchMapNotify(data);
124.62 }
124.63 }
124.64 +
124.65 + if (changed & SDL_WINDOW_MAXIMIZED) {
124.66 + if (flags & SDL_WINDOW_MAXIMIZED) {
124.67 + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MAXIMIZED, 0, 0);
124.68 + } else {
124.69 + SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESTORED, 0, 0);
124.70 + }
124.71 + }
124.72 +
124.73 }
124.74 }
124.75 break;
124.76 @@ -1283,9 +1311,15 @@
124.77 {
124.78 SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
124.79
124.80 + if (data->last_mode_change_deadline) {
124.81 + if (SDL_TICKS_PASSED(SDL_GetTicks(), data->last_mode_change_deadline)) {
124.82 + data->last_mode_change_deadline = 0; /* assume we're done. */
124.83 + }
124.84 + }
124.85 +
124.86 /* Update activity every 30 seconds to prevent screensaver */
124.87 if (_this->suspend_screensaver) {
124.88 - Uint32 now = SDL_GetTicks();
124.89 + const Uint32 now = SDL_GetTicks();
124.90 if (!data->screensaver_activity ||
124.91 SDL_TICKS_PASSED(now, data->screensaver_activity + 30000)) {
124.92 X11_XResetScreenSaver(data->display);
125.1 --- a/src/video/x11/SDL_x11messagebox.c Sat Jan 24 23:58:07 2015 -0400
125.2 +++ b/src/video/x11/SDL_x11messagebox.c Mon Apr 06 15:26:37 2015 -0300
125.3 @@ -31,8 +31,8 @@
125.4 #include <locale.h>
125.5
125.6
125.7 -#define SDL_FORK_MESSAGEBOX 0
125.8 -#define SDL_SET_LOCALE 0
125.9 +#define SDL_FORK_MESSAGEBOX 1
125.10 +#define SDL_SET_LOCALE 1
125.11
125.12 #if SDL_FORK_MESSAGEBOX
125.13 #include <sys/types.h>
125.14 @@ -366,6 +366,7 @@
125.15 int x, y;
125.16 XSizeHints *sizehints;
125.17 XSetWindowAttributes wnd_attr;
125.18 + Atom _NET_WM_WINDOW_TYPE, _NET_WM_WINDOW_TYPE_DIALOG;
125.19 Display *display = data->display;
125.20 SDL_WindowData *windowdata = NULL;
125.21 const SDL_MessageBoxData *messageboxdata = data->messageboxdata;
125.22 @@ -401,6 +402,13 @@
125.23
125.24 X11_XStoreName( display, data->window, messageboxdata->title );
125.25
125.26 + /* Let the window manager know this is a dialog box */
125.27 + _NET_WM_WINDOW_TYPE = X11_XInternAtom(display, "_NET_WM_WINDOW_TYPE", False);
125.28 + _NET_WM_WINDOW_TYPE_DIALOG = X11_XInternAtom(display, "_NET_WM_WINDOW_TYPE_DIALOG", False);
125.29 + X11_XChangeProperty(display, data->window, _NET_WM_WINDOW_TYPE, XA_ATOM, 32,
125.30 + PropModeReplace,
125.31 + (unsigned char *)&_NET_WM_WINDOW_TYPE_DIALOG, 1);
125.32 +
125.33 /* Allow the window to be deleted by the window manager */
125.34 data->wm_protocols = X11_XInternAtom( display, "WM_PROTOCOLS", False );
125.35 data->wm_delete_message = X11_XInternAtom( display, "WM_DELETE_WINDOW", False );
125.36 @@ -710,9 +718,6 @@
125.37 int fds[2];
125.38 int status = 0;
125.39
125.40 - /* Need to flush here in case someone has turned grab off and it hasn't gone through yet, etc. */
125.41 - X11_XFlush(data->display);
125.42 -
125.43 if (pipe(fds) == -1) {
125.44 return X11_ShowMessageBoxImpl(messageboxdata, buttonid); /* oh well. */
125.45 }
126.1 --- a/src/video/x11/SDL_x11modes.c Sat Jan 24 23:58:07 2015 -0400
126.2 +++ b/src/video/x11/SDL_x11modes.c Mon Apr 06 15:26:37 2015 -0300
126.3 @@ -24,6 +24,7 @@
126.4
126.5 #include "SDL_hints.h"
126.6 #include "SDL_x11video.h"
126.7 +#include "SDL_timer.h"
126.8 #include "edid.h"
126.9
126.10 /* #define X11MODES_DEBUG */
126.11 @@ -813,10 +814,13 @@
126.12 int
126.13 X11_SetDisplayMode(_THIS, SDL_VideoDisplay * sdl_display, SDL_DisplayMode * mode)
126.14 {
126.15 - Display *display = ((SDL_VideoData *) _this->driverdata)->display;
126.16 + SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata;
126.17 + Display *display = viddata->display;
126.18 SDL_DisplayData *data = (SDL_DisplayData *) sdl_display->driverdata;
126.19 SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata;
126.20
126.21 + viddata->last_mode_change_deadline = SDL_GetTicks() + (PENDING_FOCUS_TIME * 2);
126.22 +
126.23 #if SDL_VIDEO_DRIVER_X11_XRANDR
126.24 if (data->use_xrandr) {
126.25 XRRScreenResources *res;
127.1 --- a/src/video/x11/SDL_x11opengl.c Sat Jan 24 23:58:07 2015 -0400
127.2 +++ b/src/video/x11/SDL_x11opengl.c Mon Apr 06 15:26:37 2015 -0300
127.3 @@ -122,6 +122,13 @@
127.4 #define GLX_LATE_SWAPS_TEAR_EXT 0x20F3
127.5 #endif
127.6
127.7 +#ifndef GLX_ARB_context_flush_control
127.8 +#define GLX_ARB_context_flush_control
127.9 +#define GLX_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
127.10 +#define GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0x0000
127.11 +#define GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
127.12 +#endif
127.13 +
127.14 #define OPENGL_REQUIRES_DLOPEN
127.15 #if defined(OPENGL_REQUIRES_DLOPEN) && defined(SDL_LOADSO_DLOPEN)
127.16 #include <dlfcn.h>
127.17 @@ -279,14 +286,14 @@
127.18 const char *start;
127.19 const char *where, *terminator;
127.20
127.21 + if (!extensions)
127.22 + return SDL_FALSE;
127.23 +
127.24 /* Extension names should not have spaces. */
127.25 where = SDL_strchr(extension, ' ');
127.26 if (where || *extension == '\0')
127.27 return SDL_FALSE;
127.28
127.29 - if (!extensions)
127.30 - return SDL_FALSE;
127.31 -
127.32 /* It takes a bit of care to be fool-proof about parsing the
127.33 * OpenGL extensions string. Don't be fooled by sub-strings,
127.34 * etc. */
127.35 @@ -312,32 +319,10 @@
127.36 X11_GL_InitExtensions(_THIS)
127.37 {
127.38 Display *display = ((SDL_VideoData *) _this->driverdata)->display;
127.39 - int screen = DefaultScreen(display);
127.40 - XVisualInfo *vinfo;
127.41 - XSetWindowAttributes xattr;
127.42 - Window w;
127.43 - GLXContext context;
127.44 + const int screen = DefaultScreen(display);
127.45 const char *(*glXQueryExtensionsStringFunc) (Display *, int);
127.46 const char *extensions;
127.47
127.48 - vinfo = X11_GL_GetVisual(_this, display, screen);
127.49 - if (!vinfo) {
127.50 - return;
127.51 - }
127.52 - xattr.background_pixel = 0;
127.53 - xattr.border_pixel = 0;
127.54 - xattr.colormap =
127.55 - X11_XCreateColormap(display, RootWindow(display, screen), vinfo->visual,
127.56 - AllocNone);
127.57 - w = X11_XCreateWindow(display, RootWindow(display, screen), 0, 0, 32, 32, 0,
127.58 - vinfo->depth, InputOutput, vinfo->visual,
127.59 - (CWBackPixel | CWBorderPixel | CWColormap), &xattr);
127.60 - context = _this->gl_data->glXCreateContext(display, vinfo, NULL, True);
127.61 - if (context) {
127.62 - _this->gl_data->glXMakeCurrent(display, w, context);
127.63 - }
127.64 - X11_XFree(vinfo);
127.65 -
127.66 glXQueryExtensionsStringFunc =
127.67 (const char *(*)(Display *, int)) X11_GL_GetProcAddress(_this,
127.68 "glXQueryExtensionsString");
127.69 @@ -373,6 +358,16 @@
127.70 (int (*)(int)) X11_GL_GetProcAddress(_this, "glXSwapIntervalSGI");
127.71 }
127.72
127.73 + /* Check for GLX_ARB_create_context */
127.74 + if (HasExtension("GLX_ARB_create_context", extensions)) {
127.75 + _this->gl_data->glXCreateContextAttribsARB =
127.76 + (GLXContext (*)(Display*,GLXFBConfig,GLXContext,Bool,const int *))
127.77 + X11_GL_GetProcAddress(_this, "glXCreateContextAttribsARB");
127.78 + _this->gl_data->glXChooseFBConfig =
127.79 + (GLXFBConfig *(*)(Display *, int, const int *, int *))
127.80 + X11_GL_GetProcAddress(_this, "glXChooseFBConfig");
127.81 + }
127.82 +
127.83 /* Check for GLX_EXT_visual_rating */
127.84 if (HasExtension("GLX_EXT_visual_rating", extensions)) {
127.85 _this->gl_data->HAS_GLX_EXT_visual_rating = SDL_TRUE;
127.86 @@ -388,18 +383,16 @@
127.87 _this->gl_data->HAS_GLX_EXT_create_context_es2_profile = SDL_TRUE;
127.88 }
127.89
127.90 - if (context) {
127.91 - _this->gl_data->glXMakeCurrent(display, None, NULL);
127.92 - _this->gl_data->glXDestroyContext(display, context);
127.93 + /* Check for GLX_ARB_context_flush_control */
127.94 + if (HasExtension("GLX_ARB_context_flush_control", extensions)) {
127.95 + _this->gl_data->HAS_GLX_ARB_context_flush_control = SDL_TRUE;
127.96 }
127.97 - X11_XDestroyWindow(display, w);
127.98 - X11_PumpEvents(_this);
127.99 }
127.100
127.101 /* glXChooseVisual and glXChooseFBConfig have some small differences in
127.102 * the attribute encoding, it can be chosen with the for_FBConfig parameter.
127.103 */
127.104 -int
127.105 +static int
127.106 X11_GL_GetAttributes(_THIS, Display * display, int screen, int * attribs, int size, Bool for_FBConfig)
127.107 {
127.108 int i = 0;
127.109 @@ -481,9 +474,7 @@
127.110
127.111 if (_this->gl_config.framebuffer_srgb_capable) {
127.112 attribs[i++] = GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB;
127.113 - if( for_FBConfig ) {
127.114 - attribs[i++] = True;
127.115 - }
127.116 + attribs[i++] = True; /* always needed, for_FBConfig or not! */
127.117 }
127.118
127.119 if (_this->gl_config.accelerated >= 0 &&
127.120 @@ -576,7 +567,6 @@
127.121 XVisualInfo v, *vinfo;
127.122 int n;
127.123 GLXContext context = NULL, share_context;
127.124 - PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribs = NULL;
127.125
127.126 if (_this->gl_config.share_with_current_context) {
127.127 share_context = (GLXContext)SDL_GL_GetCurrentContext();
127.128 @@ -601,78 +591,61 @@
127.129 context =
127.130 _this->gl_data->glXCreateContext(display, vinfo, share_context, True);
127.131 } else {
127.132 - /* If we want a GL 3.0 context or later we need to get a temporary
127.133 - context to grab the new context creation function */
127.134 - GLXContext temp_context =
127.135 - _this->gl_data->glXCreateContext(display, vinfo, NULL, True);
127.136 - if (temp_context) {
127.137 - /* max 8 attributes plus terminator */
127.138 - int attribs[9] = {
127.139 - GLX_CONTEXT_MAJOR_VERSION_ARB,
127.140 - _this->gl_config.major_version,
127.141 - GLX_CONTEXT_MINOR_VERSION_ARB,
127.142 - _this->gl_config.minor_version,
127.143 - 0
127.144 - };
127.145 - int iattr = 4;
127.146 + /* max 10 attributes plus terminator */
127.147 + int attribs[11] = {
127.148 + GLX_CONTEXT_MAJOR_VERSION_ARB,
127.149 + _this->gl_config.major_version,
127.150 + GLX_CONTEXT_MINOR_VERSION_ARB,
127.151 + _this->gl_config.minor_version,
127.152 + 0
127.153 + };
127.154 + int iattr = 4;
127.155
127.156 - /* SDL profile bits match GLX profile bits */
127.157 - if( _this->gl_config.profile_mask != 0 ) {
127.158 - attribs[iattr++] = GLX_CONTEXT_PROFILE_MASK_ARB;
127.159 - attribs[iattr++] = _this->gl_config.profile_mask;
127.160 - }
127.161 + /* SDL profile bits match GLX profile bits */
127.162 + if( _this->gl_config.profile_mask != 0 ) {
127.163 + attribs[iattr++] = GLX_CONTEXT_PROFILE_MASK_ARB;
127.164 + attribs[iattr++] = _this->gl_config.profile_mask;
127.165 + }
127.166
127.167 - /* SDL flags match GLX flags */
127.168 - if( _this->gl_config.flags != 0 ) {
127.169 - attribs[iattr++] = GLX_CONTEXT_FLAGS_ARB;
127.170 - attribs[iattr++] = _this->gl_config.flags;
127.171 - }
127.172 -
127.173 - attribs[iattr++] = 0;
127.174 + /* SDL flags match GLX flags */
127.175 + if( _this->gl_config.flags != 0 ) {
127.176 + attribs[iattr++] = GLX_CONTEXT_FLAGS_ARB;
127.177 + attribs[iattr++] = _this->gl_config.flags;
127.178 + }
127.179
127.180 - /* Get a pointer to the context creation function for GL 3.0 */
127.181 - glXCreateContextAttribs =
127.182 - (PFNGLXCREATECONTEXTATTRIBSARBPROC) _this->gl_data->
127.183 - glXGetProcAddress((GLubyte *)
127.184 - "glXCreateContextAttribsARB");
127.185 - if (!glXCreateContextAttribs) {
127.186 - SDL_SetError("GL 3.x is not supported");
127.187 - context = temp_context;
127.188 - } else {
127.189 - int glxAttribs[64];
127.190 + /* only set if glx extension is available */
127.191 + if( _this->gl_data->HAS_GLX_ARB_context_flush_control ) {
127.192 + attribs[iattr++] = GLX_CONTEXT_RELEASE_BEHAVIOR_ARB;
127.193 + attribs[iattr++] =
127.194 + _this->gl_config.release_behavior ?
127.195 + GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB :
127.196 + GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB;
127.197 + }
127.198
127.199 - /* Create a GL 3.x context */
127.200 - GLXFBConfig *framebuffer_config = NULL;
127.201 - int fbcount = 0;
127.202 - GLXFBConfig *(*glXChooseFBConfig) (Display * disp,
127.203 - int screen,
127.204 - const int *attrib_list,
127.205 - int *nelements);
127.206 + attribs[iattr++] = 0;
127.207
127.208 - glXChooseFBConfig =
127.209 - (GLXFBConfig *
127.210 - (*)(Display *, int, const int *,
127.211 - int *)) _this->gl_data->
127.212 - glXGetProcAddress((GLubyte *) "glXChooseFBConfig");
127.213 + /* Get a pointer to the context creation function for GL 3.0 */
127.214 + if (!_this->gl_data->glXCreateContextAttribsARB) {
127.215 + SDL_SetError("OpenGL 3.0 and later are not supported by this system");
127.216 + } else {
127.217 + int glxAttribs[64];
127.218
127.219 - X11_GL_GetAttributes(_this,display,screen,glxAttribs,64,SDL_TRUE);
127.220 + /* Create a GL 3.x context */
127.221 + GLXFBConfig *framebuffer_config = NULL;
127.222 + int fbcount = 0;
127.223
127.224 - if (!glXChooseFBConfig
127.225 - || !(framebuffer_config =
127.226 - glXChooseFBConfig(display,
127.227 - DefaultScreen(display), glxAttribs,
127.228 - &fbcount))) {
127.229 - SDL_SetError
127.230 - ("No good framebuffers found. GL 3.x disabled");
127.231 - context = temp_context;
127.232 - } else {
127.233 - context =
127.234 - glXCreateContextAttribs(display,
127.235 + X11_GL_GetAttributes(_this,display,screen,glxAttribs,64,SDL_TRUE);
127.236 +
127.237 + if (!_this->gl_data->glXChooseFBConfig
127.238 + || !(framebuffer_config =
127.239 + _this->gl_data->glXChooseFBConfig(display,
127.240 + DefaultScreen(display), glxAttribs,
127.241 + &fbcount))) {
127.242 + SDL_SetError("No good framebuffers found. OpenGL 3.0 and later unavailable");
127.243 + } else {
127.244 + context = _this->gl_data->glXCreateContextAttribsARB(display,
127.245 framebuffer_config[0],
127.246 share_context, True, attribs);
127.247 - _this->gl_data->glXDestroyContext(display,
127.248 - temp_context);
127.249 - }
127.250 }
127.251 }
127.252 }
128.1 --- a/src/video/x11/SDL_x11opengl.h Sat Jan 24 23:58:07 2015 -0400
128.2 +++ b/src/video/x11/SDL_x11opengl.h Mon Apr 06 15:26:37 2015 -0300
128.3 @@ -35,11 +35,14 @@
128.4 SDL_bool HAS_GLX_EXT_visual_info;
128.5 SDL_bool HAS_GLX_EXT_swap_control_tear;
128.6 SDL_bool HAS_GLX_EXT_create_context_es2_profile;
128.7 + SDL_bool HAS_GLX_ARB_context_flush_control;
128.8
128.9 Bool (*glXQueryExtension) (Display*,int*,int*);
128.10 void *(*glXGetProcAddress) (const GLubyte*);
128.11 XVisualInfo *(*glXChooseVisual) (Display*,int,int*);
128.12 GLXContext (*glXCreateContext) (Display*,XVisualInfo*,GLXContext,Bool);
128.13 + GLXContext (*glXCreateContextAttribsARB) (Display*,GLXFBConfig,GLXContext,Bool,const int *);
128.14 + GLXFBConfig *(*glXChooseFBConfig) (Display*,int,const int *,int *);
128.15 void (*glXDestroyContext) (Display*, GLXContext);
128.16 Bool(*glXMakeCurrent) (Display*,GLXDrawable,GLXContext);
128.17 void (*glXSwapBuffers) (Display*, GLXDrawable);
129.1 --- a/src/video/x11/SDL_x11video.h Sat Jan 24 23:58:07 2015 -0400
129.2 +++ b/src/video/x11/SDL_x11video.h Mon Apr 06 15:26:37 2015 -0300
129.3 @@ -112,6 +112,7 @@
129.4 SDL_Scancode key_layout[256];
129.5 SDL_bool selection_waiting;
129.6
129.7 + Uint32 last_mode_change_deadline;
129.8 } SDL_VideoData;
129.9
129.10 extern SDL_bool X11_UseDirectColorVisuals(void);
130.1 --- a/src/video/x11/SDL_x11window.h Sat Jan 24 23:58:07 2015 -0400
130.2 +++ b/src/video/x11/SDL_x11window.h Mon Apr 06 15:26:37 2015 -0300
130.3 @@ -27,8 +27,7 @@
130.4 video mode changes and we can respond to them by triggering more mode
130.5 changes.
130.6 */
130.7 -#define PENDING_FOCUS_IN_TIME 200
130.8 -#define PENDING_FOCUS_OUT_TIME 200
130.9 +#define PENDING_FOCUS_TIME 200
130.10
130.11 #if SDL_VIDEO_OPENGL_EGL
130.12 #include <EGL/egl.h>
131.1 --- a/test/Makefile.in Sat Jan 24 23:58:07 2015 -0400
131.2 +++ b/test/Makefile.in Mon Apr 06 15:26:37 2015 -0300
131.3 @@ -38,6 +38,7 @@
131.4 testloadso$(EXE) \
131.5 testlock$(EXE) \
131.6 testmultiaudio$(EXE) \
131.7 + testaudiohotplug$(EXE) \
131.8 testnative$(EXE) \
131.9 testoverlay2$(EXE) \
131.10 testplatform$(EXE) \
131.11 @@ -105,6 +106,9 @@
131.12 testmultiaudio$(EXE): $(srcdir)/testmultiaudio.c
131.13 $(CC) -o $@ $^ $(CFLAGS) $(LIBS)
131.14
131.15 +testaudiohotplug$(EXE): $(srcdir)/testaudiohotplug.c
131.16 + $(CC) -o $@ $^ $(CFLAGS) $(LIBS)
131.17 +
131.18 testatomic$(EXE): $(srcdir)/testatomic.c
131.19 $(CC) -o $@ $^ $(CFLAGS) $(LIBS)
131.20
132.1 --- a/test/loopwave.c Sat Jan 24 23:58:07 2015 -0400
132.2 +++ b/test/loopwave.c Mon Apr 06 15:26:37 2015 -0300
132.3 @@ -29,7 +29,6 @@
132.4 #endif
132.5
132.6 #include "SDL.h"
132.7 -#include "SDL_audio.h"
132.8
132.9 struct
132.10 {
133.1 --- a/test/loopwavequeue.c Sat Jan 24 23:58:07 2015 -0400
133.2 +++ b/test/loopwavequeue.c Mon Apr 06 15:26:37 2015 -0300
133.3 @@ -15,6 +15,10 @@
133.4 #include <stdio.h>
133.5 #include <stdlib.h>
133.6
133.7 +#ifdef __EMSCRIPTEN__
133.8 +#include <emscripten/emscripten.h>
133.9 +#endif
133.10 +
133.11 #include "SDL.h"
133.12
133.13 #if HAVE_SIGNAL_H
133.14 @@ -45,10 +49,32 @@
133.15 done = 1;
133.16 }
133.17
133.18 +void
133.19 +loop()
133.20 +{
133.21 +#ifdef __EMSCRIPTEN__
133.22 + if (done || (SDL_GetAudioStatus() != SDL_AUDIO_PLAYING)) {
133.23 + emscripten_cancel_main_loop();
133.24 + }
133.25 + else
133.26 +#endif
133.27 + {
133.28 + /* The device from SDL_OpenAudio() is always device #1. */
133.29 + const Uint32 queued = SDL_GetQueuedAudioSize(1);
133.30 + SDL_Log("Device has %u bytes queued.\n", (unsigned int) queued);
133.31 + if (queued <= 8192) { /* time to requeue the whole thing? */
133.32 + if (SDL_QueueAudio(1, wave.sound, wave.soundlen) == 0) {
133.33 + SDL_Log("Device queued %u more bytes.\n", (unsigned int) wave.soundlen);
133.34 + } else {
133.35 + SDL_Log("Device FAILED to queue %u more bytes: %s\n", (unsigned int) wave.soundlen, SDL_GetError());
133.36 + }
133.37 + }
133.38 + }
133.39 +}
133.40 +
133.41 int
133.42 main(int argc, char *argv[])
133.43 {
133.44 - int i;
133.45 char filename[4096];
133.46
133.47 /* Enable standard application logging */
133.48 @@ -97,25 +123,22 @@
133.49 /* Let the audio run */
133.50 SDL_PauseAudio(0);
133.51
133.52 + done = 0;
133.53 +
133.54 /* Note that we stuff the entire audio buffer into the queue in one
133.55 shot. Most apps would want to feed it a little at a time, as it
133.56 plays, but we're going for simplicity here. */
133.57
133.58 +#ifdef __EMSCRIPTEN__
133.59 + emscripten_set_main_loop(loop, 0, 1);
133.60 +#else
133.61 while (!done && (SDL_GetAudioStatus() == SDL_AUDIO_PLAYING))
133.62 {
133.63 - /* The device from SDL_OpenAudio() is always device #1. */
133.64 - const Uint32 queued = SDL_GetQueuedAudioSize(1);
133.65 - SDL_Log("Device has %u bytes queued.\n", (unsigned int) queued);
133.66 - if (queued <= 8192) { /* time to requeue the whole thing? */
133.67 - if (SDL_QueueAudio(1, wave.sound, wave.soundlen) == 0) {
133.68 - SDL_Log("Device queued %u more bytes.\n", (unsigned int) wave.soundlen);
133.69 - } else {
133.70 - SDL_Log("Device FAILED to queue %u more bytes: %s\n", (unsigned int) wave.soundlen, SDL_GetError());
133.71 - }
133.72 - }
133.73 + loop();
133.74
133.75 SDL_Delay(100); /* let it play for awhile. */
133.76 }
133.77 +#endif
133.78
133.79 /* Clean up on signal */
133.80 SDL_CloseAudio();
134.1 --- a/test/relative_mode.markdown Sat Jan 24 23:58:07 2015 -0400
134.2 +++ b/test/relative_mode.markdown Mon Apr 06 15:26:37 2015 -0300
134.3 @@ -37,9 +37,11 @@
134.4
134.5 int main(int argc, char *argv[])
134.6 {
134.7 + SDL_Window *win;
134.8 +
134.9 SDL_Init(SDL_INIT_VIDEO);
134.10
134.11 - SDL_Window *win = SDL_CreateWindow("Test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, 0);
134.12 + win = SDL_CreateWindow("Test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, 0);
134.13 SDL_SetRelativeMouseMode(SDL_TRUE);
134.14
134.15 while (1)
135.1 --- a/test/testatomic.c Sat Jan 24 23:58:07 2015 -0400
135.2 +++ b/test/testatomic.c Mon Apr 06 15:26:37 2015 -0300
135.3 @@ -12,9 +12,6 @@
135.4 #include <stdio.h>
135.5
135.6 #include "SDL.h"
135.7 -#include "SDL_atomic.h"
135.8 -#include "SDL_assert.h"
135.9 -#include "SDL_cpuinfo.h"
135.10
135.11 /*
135.12 Absolutely basic tests just to see if we get the expected value
136.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
136.2 +++ b/test/testaudiohotplug.c Mon Apr 06 15:26:37 2015 -0300
136.3 @@ -0,0 +1,183 @@
136.4 +/*
136.5 + Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
136.6 +
136.7 + This software is provided 'as-is', without any express or implied
136.8 + warranty. In no event will the authors be held liable for any damages
136.9 + arising from the use of this software.
136.10 +
136.11 + Permission is granted to anyone to use this software for any purpose,
136.12 + including commercial applications, and to alter it and redistribute it
136.13 + freely.
136.14 +*/
136.15 +
136.16 +/* Program to test hotplugging of audio devices */
136.17 +
136.18 +#include "SDL_config.h"
136.19 +
136.20 +#include <stdio.h>
136.21 +#include <stdlib.h>
136.22 +
136.23 +#if HAVE_SIGNAL_H
136.24 +#include <signal.h>
136.25 +#endif
136.26 +
136.27 +#ifdef __EMSCRIPTEN__
136.28 +#include <emscripten/emscripten.h>
136.29 +#endif
136.30 +
136.31 +#include "SDL.h"
136.32 +
136.33 +static SDL_AudioSpec spec;
136.34 +static Uint8 *sound = NULL; /* Pointer to wave data */
136.35 +static Uint32 soundlen = 0; /* Length of wave data */
136.36 +
136.37 +static int posindex = 0;
136.38 +static Uint32 positions[64];
136.39 +
136.40 +/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
136.41 +static void
136.42 +quit(int rc)
136.43 +{
136.44 + SDL_Quit();
136.45 + exit(rc);
136.46 +}
136.47 +
136.48 +void SDLCALL
136.49 +fillerup(void *_pos, Uint8 * stream, int len)
136.50 +{
136.51 + Uint32 pos = *((Uint32 *) _pos);
136.52 + Uint8 *waveptr;
136.53 + int waveleft;
136.54 +
136.55 + /* Set up the pointers */
136.56 + waveptr = sound + pos;
136.57 + waveleft = soundlen - pos;
136.58 +
136.59 + /* Go! */
136.60 + while (waveleft <= len) {
136.61 + SDL_memcpy(stream, waveptr, waveleft);
136.62 + stream += waveleft;
136.63 + len -= waveleft;
136.64 + waveptr = sound;
136.65 + waveleft = soundlen;
136.66 + pos = 0;
136.67 + }
136.68 + SDL_memcpy(stream, waveptr, len);
136.69 + pos += len;
136.70 + *((Uint32 *) _pos) = pos;
136.71 +}
136.72 +
136.73 +static int done = 0;
136.74 +void
136.75 +poked(int sig)
136.76 +{
136.77 + done = 1;
136.78 +}
136.79 +
136.80 +static void
136.81 +iteration()
136.82 +{
136.83 + SDL_Event e;
136.84 + SDL_AudioDeviceID dev;
136.85 + while (SDL_PollEvent(&e)) {
136.86 + if (e.type == SDL_QUIT) {
136.87 + done = 1;
136.88 + } else if (e.type == SDL_AUDIODEVICEADDED) {
136.89 + const char *name = SDL_GetAudioDeviceName(e.adevice.which, 0);
136.90 + SDL_Log("New %s audio device: %s\n", e.adevice.iscapture ? "capture" : "output", name);
136.91 + if (!e.adevice.iscapture) {
136.92 + positions[posindex] = 0;
136.93 + spec.userdata = &positions[posindex++];
136.94 + spec.callback = fillerup;
136.95 + dev = SDL_OpenAudioDevice(name, 0, &spec, NULL, 0);
136.96 + if (!dev) {
136.97 + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't open '%s': %s\n", name, SDL_GetError());
136.98 + } else {
136.99 + SDL_Log("Opened '%s' as %u\n", name, (unsigned int) dev);
136.100 + SDL_PauseAudioDevice(dev, 0);
136.101 + }
136.102 + }
136.103 + } else if (e.type == SDL_AUDIODEVICEREMOVED) {
136.104 + dev = (SDL_AudioDeviceID) e.adevice.which;
136.105 + SDL_Log("%s device %u removed.\n", e.adevice.iscapture ? "capture" : "output", (unsigned int) dev);
136.106 + SDL_CloseAudioDevice(dev);
136.107 + }
136.108 + }
136.109 +}
136.110 +
136.111 +#ifdef __EMSCRIPTEN__
136.112 +void
136.113 +loop()
136.114 +{
136.115 + if(done)
136.116 + emscripten_cancel_main_loop();
136.117 + else
136.118 + iteration();
136.119 +}
136.120 +#endif
136.121 +
136.122 +int
136.123 +main(int argc, char *argv[])
136.124 +{
136.125 + int i;
136.126 + char filename[4096];
136.127 +
136.128 + /* Enable standard application logging */
136.129 + SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
136.130 +
136.131 + /* Load the SDL library */
136.132 + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) {
136.133 + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
136.134 + return (1);
136.135 + }
136.136 +
136.137 + /* Some targets (Mac CoreAudio) need an event queue for audio hotplug, so make and immediately hide a window. */
136.138 + SDL_MinimizeWindow(SDL_CreateWindow("testaudiohotplug", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0));
136.139 +
136.140 + if (argc > 1) {
136.141 + SDL_strlcpy(filename, argv[1], sizeof(filename));
136.142 + } else {
136.143 + SDL_strlcpy(filename, "sample.wav", sizeof(filename));
136.144 + }
136.145 + /* Load the wave file into memory */
136.146 + if (SDL_LoadWAV(filename, &spec, &sound, &soundlen) == NULL) {
136.147 + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", filename, SDL_GetError());
136.148 + quit(1);
136.149 + }
136.150 +
136.151 +#if HAVE_SIGNAL_H
136.152 + /* Set the signals */
136.153 +#ifdef SIGHUP
136.154 + signal(SIGHUP, poked);
136.155 +#endif
136.156 + signal(SIGINT, poked);
136.157 +#ifdef SIGQUIT
136.158 + signal(SIGQUIT, poked);
136.159 +#endif
136.160 + signal(SIGTERM, poked);
136.161 +#endif /* HAVE_SIGNAL_H */
136.162 +
136.163 + /* Show the list of available drivers */
136.164 + SDL_Log("Available audio drivers:");
136.165 + for (i = 0; i < SDL_GetNumAudioDrivers(); ++i) {
136.166 + SDL_Log("%i: %s", i, SDL_GetAudioDriver(i));
136.167 + }
136.168 +
136.169 + SDL_Log("Using audio driver: %s\n", SDL_GetCurrentAudioDriver());
136.170 +
136.171 +#ifdef __EMSCRIPTEN__
136.172 + emscripten_set_main_loop(loop, 0, 1);
136.173 +#else
136.174 + while (!done) {
136.175 + SDL_Delay(100);
136.176 + iteration();
136.177 + }
136.178 +#endif
136.179 +
136.180 + /* Clean up on signal */
136.181 + SDL_Quit();
136.182 + SDL_FreeWAV(sound);
136.183 + return (0);
136.184 +}
136.185 +
136.186 +/* vi: set ts=4 sw=4 expandtab: */
137.1 --- a/test/testerror.c Sat Jan 24 23:58:07 2015 -0400
137.2 +++ b/test/testerror.c Mon Apr 06 15:26:37 2015 -0300
137.3 @@ -17,7 +17,6 @@
137.4 #include <signal.h>
137.5
137.6 #include "SDL.h"
137.7 -#include "SDL_thread.h"
137.8
137.9 static int alive = 0;
137.10
138.1 --- a/test/testfile.c Sat Jan 24 23:58:07 2015 -0400
138.2 +++ b/test/testfile.c Mon Apr 06 15:26:37 2015 -0300
138.3 @@ -22,7 +22,6 @@
138.4 #endif
138.5
138.6 #include "SDL.h"
138.7 -#include "SDL_endian.h"
138.8
138.9
138.10 #include <stdio.h>
139.1 --- a/test/testgamecontroller.c Sat Jan 24 23:58:07 2015 -0400
139.2 +++ b/test/testgamecontroller.c Mon Apr 06 15:26:37 2015 -0300
139.3 @@ -163,6 +163,10 @@
139.4 const size_t titlelen = SDL_strlen(basetitle) + SDL_strlen(name) + 1;
139.5 char *title = (char *)SDL_malloc(titlelen);
139.6 SDL_Window *window = NULL;
139.7 +
139.8 + retval = SDL_FALSE;
139.9 + done = SDL_FALSE;
139.10 +
139.11 if (title) {
139.12 SDL_snprintf(title, titlelen, "%s%s", basetitle, name);
139.13 }
139.14 @@ -219,6 +223,10 @@
139.15 #endif
139.16
139.17 SDL_DestroyRenderer(screen);
139.18 + screen = NULL;
139.19 + background = NULL;
139.20 + button = NULL;
139.21 + axis = NULL;
139.22 SDL_DestroyWindow(window);
139.23 return retval;
139.24 }
140.1 --- a/test/testhaptic.c Sat Jan 24 23:58:07 2015 -0400
140.2 +++ b/test/testhaptic.c Mon Apr 06 15:26:37 2015 -0300
140.3 @@ -22,8 +22,6 @@
140.4
140.5 #ifndef SDL_HAPTIC_DISABLED
140.6
140.7 -#include "SDL_haptic.h"
140.8 -
140.9 static SDL_Haptic *haptic;
140.10
140.11
141.1 --- a/test/testhotplug.c Sat Jan 24 23:58:07 2015 -0400
141.2 +++ b/test/testhotplug.c Mon Apr 06 15:26:37 2015 -0300
141.3 @@ -17,7 +17,6 @@
141.4 #include <string.h>
141.5
141.6 #include "SDL.h"
141.7 -#include "SDL_haptic.h"
141.8
141.9 #if !defined SDL_JOYSTICK_DISABLED && !defined SDL_HAPTIC_DISABLED
141.10
142.1 --- a/test/testjoystick.c Sat Jan 24 23:58:07 2015 -0400
142.2 +++ b/test/testjoystick.c Mon Apr 06 15:26:37 2015 -0300
142.3 @@ -56,6 +56,12 @@
142.4
142.5 while (SDL_PollEvent(&event)) {
142.6 switch (event.type) {
142.7 +
142.8 + case SDL_JOYDEVICEREMOVED:
142.9 + SDL_Log("Joystick device %d removed.\n", (int) event.jdevice.which);
142.10 + SDL_Log("Our instance ID is %d\n", (int) SDL_JoystickInstanceID(joystick));
142.11 + break;
142.12 +
142.13 case SDL_JOYAXISMOTION:
142.14 SDL_Log("Joystick %d axis %d value: %d\n",
142.15 event.jaxis.which,
142.16 @@ -177,6 +183,8 @@
142.17 SDL_Window *window = NULL;
142.18 const char *name = NULL;
142.19
142.20 + retval = SDL_FALSE;
142.21 + done = SDL_FALSE;
142.22
142.23 /* Create a window to display joystick axis position */
142.24 window = SDL_CreateWindow("Joystick Test", SDL_WINDOWPOS_CENTERED,
142.25 @@ -217,6 +225,7 @@
142.26 #endif
142.27
142.28 SDL_DestroyRenderer(screen);
142.29 + screen = NULL;
142.30 SDL_DestroyWindow(window);
142.31 return retval;
142.32 }
143.1 --- a/test/testlock.c Sat Jan 24 23:58:07 2015 -0400
143.2 +++ b/test/testlock.c Mon Apr 06 15:26:37 2015 -0300
143.3 @@ -19,8 +19,6 @@
143.4 #include <stdlib.h> /* for atexit() */
143.5
143.6 #include "SDL.h"
143.7 -#include "SDL_mutex.h"
143.8 -#include "SDL_thread.h"
143.9
143.10 static SDL_mutex *mutex = NULL;
143.11 static SDL_threadID mainthread;
144.1 --- a/test/testmessage.c Sat Jan 24 23:58:07 2015 -0400
144.2 +++ b/test/testmessage.c Mon Apr 06 15:26:37 2015 -0300
144.3 @@ -17,7 +17,6 @@
144.4 #include <signal.h>
144.5
144.6 #include "SDL.h"
144.7 -#include "SDL_thread.h"
144.8
144.9 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
144.10 static void
145.1 --- a/test/testplatform.c Sat Jan 24 23:58:07 2015 -0400
145.2 +++ b/test/testplatform.c Mon Apr 06 15:26:37 2015 -0300
145.3 @@ -13,9 +13,6 @@
145.4 #include <stdio.h>
145.5
145.6 #include "SDL.h"
145.7 -#include "SDL_endian.h"
145.8 -#include "SDL_cpuinfo.h"
145.9 -#include "SDL_assert.h"
145.10
145.11 /*
145.12 * Watcom C flags these as Warning 201: "Unreachable code" if you just
145.13 @@ -170,7 +167,7 @@
145.14 #endif
145.15
145.16 {
145.17 - const SDL_assert_data *item = SDL_GetAssertionReport();
145.18 + const SDL_AssertData *item = SDL_GetAssertionReport();
145.19 while (item) {
145.20 SDL_Log("'%s', %s (%s:%d), triggered %u times, always ignore: %s.\n",
145.21 item->condition, item->function, item->filename,
146.1 --- a/test/testrelative.c Sat Jan 24 23:58:07 2015 -0400
146.2 +++ b/test/testrelative.c Mon Apr 06 15:26:37 2015 -0300
146.3 @@ -49,12 +49,20 @@
146.4 }
146.5 }
146.6 for (i = 0; i < state->num_windows; ++i) {
146.7 + SDL_Rect viewport;
146.8 SDL_Renderer *renderer = state->renderers[i];
146.9 if (state->windows[i] == NULL)
146.10 continue;
146.11 SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
146.12 SDL_RenderClear(renderer);
146.13
146.14 + /* Wrap the cursor rectangle at the screen edges to keep it visible */
146.15 + SDL_RenderGetViewport(renderer, &viewport);
146.16 + if (rect.x < viewport.x) rect.x += viewport.w;
146.17 + if (rect.y < viewport.y) rect.y += viewport.h;
146.18 + if (rect.x > viewport.x + viewport.w) rect.x -= viewport.w;
146.19 + if (rect.y > viewport.y + viewport.h) rect.y -= viewport.h;
146.20 +
146.21 DrawRects(renderer, &rect);
146.22
146.23 SDL_RenderPresent(renderer);
147.1 --- a/test/testrumble.c Sat Jan 24 23:58:07 2015 -0400
147.2 +++ b/test/testrumble.c Mon Apr 06 15:26:37 2015 -0300
147.3 @@ -33,8 +33,6 @@
147.4
147.5 #ifndef SDL_HAPTIC_DISABLED
147.6
147.7 -#include "SDL_haptic.h"
147.8 -
147.9 static SDL_Haptic *haptic;
147.10
147.11
148.1 --- a/test/testsem.c Sat Jan 24 23:58:07 2015 -0400
148.2 +++ b/test/testsem.c Mon Apr 06 15:26:37 2015 -0300
148.3 @@ -17,7 +17,6 @@
148.4 #include <signal.h>
148.5
148.6 #include "SDL.h"
148.7 -#include "SDL_thread.h"
148.8
148.9 #define NUM_THREADS 10
148.10
149.1 --- a/test/testthread.c Sat Jan 24 23:58:07 2015 -0400
149.2 +++ b/test/testthread.c Mon Apr 06 15:26:37 2015 -0300
149.3 @@ -17,7 +17,6 @@
149.4 #include <signal.h>
149.5
149.6 #include "SDL.h"
149.7 -#include "SDL_thread.h"
149.8
149.9 static SDL_TLSID tls;
149.10 static int alive = 0;
150.1 --- a/test/torturethread.c Sat Jan 24 23:58:07 2015 -0400
150.2 +++ b/test/torturethread.c Mon Apr 06 15:26:37 2015 -0300
150.3 @@ -18,7 +18,6 @@
150.4 #include <string.h>
150.5
150.6 #include "SDL.h"
150.7 -#include "SDL_thread.h"
150.8
150.9 #define NUMTHREADS 10
150.10