Merged default into iOS-improvements
--HG-- branch : iOS-improvements
This commit is contained in:
commit
0bacddf42e
150 changed files with 2690 additions and 1507 deletions
|
@ -118,9 +118,9 @@ else()
|
|||
endif()
|
||||
|
||||
if (UNIX_OR_MAC_SYS AND NOT EMSCRIPTEN) # JavaScript does not yet have threading support, so disable pthreads when building for Emscripten.
|
||||
set(PTHREADS_ENABLED_BY_DEFAULT ON)
|
||||
set(SDL_PTHREADS_ENABLED_BY_DEFAULT ON)
|
||||
else()
|
||||
set(PTHREADS_ENABLED_BY_DEFAULT OFF)
|
||||
set(SDL_PTHREADS_ENABLED_BY_DEFAULT OFF)
|
||||
endif()
|
||||
|
||||
# Default option knobs
|
||||
|
@ -202,6 +202,7 @@ include_directories(${SDL2_BINARY_DIR}/include ${SDL2_SOURCE_DIR}/include)
|
|||
|
||||
# All these ENABLED_BY_DEFAULT vars will default to ON if not specified, so
|
||||
# you only need to have a platform override them if they are disabling.
|
||||
set(OPT_DEF_ASM TRUE)
|
||||
if(EMSCRIPTEN)
|
||||
# Set up default values for the currently supported set of subsystems:
|
||||
# Emscripten/Javascript does not have assembly support, a dynamic library
|
||||
|
@ -212,12 +213,12 @@ if(EMSCRIPTEN)
|
|||
set(SDL_THREADS_ENABLED_BY_DEFAULT OFF)
|
||||
set(SDL_LOADSO_ENABLED_BY_DEFAULT OFF)
|
||||
set(SDL_CPUINFO_ENABLED_BY_DEFAULT OFF)
|
||||
set(DLOPEN_ENABLED_BY_DEFAULT OFF)
|
||||
set(SDL_DLOPEN_ENABLED_BY_DEFAULT OFF)
|
||||
endif()
|
||||
|
||||
set(SDL_SUBSYSTEMS
|
||||
Atomic Audio Video Render Events Joystick Haptic Power Threads Timers
|
||||
File Loadso CPUinfo Filesystem)
|
||||
File Loadso CPUinfo Filesystem Dlopen)
|
||||
foreach(_SUB ${SDL_SUBSYSTEMS})
|
||||
string(TOUPPER ${_SUB} _OPT)
|
||||
if (NOT DEFINED SDL_${_OPT}_ENABLED_BY_DEFAULT)
|
||||
|
@ -246,9 +247,9 @@ dep_option(FUSIONSOUND_SHARED "Dynamically load fusionsound audio support" ON "
|
|||
set_option(VIDEO_DUMMY "Use dummy video driver" ON)
|
||||
set_option(VIDEO_OPENGL "Include OpenGL support" ON)
|
||||
set_option(VIDEO_OPENGLES "Include OpenGL ES support" ON)
|
||||
set_option(PTHREADS "Use POSIX threads for multi-threading" ${PTHREADS_ENABLED_BY_DEFAULT})
|
||||
set_option(PTHREADS "Use POSIX threads for multi-threading" ${SDL_PTHREADS_ENABLED_BY_DEFAULT})
|
||||
dep_option(PTHREADS_SEM "Use pthread semaphores" ON "PTHREADS" OFF)
|
||||
set_option(SDL_DLOPEN "Use dlopen for shared object loading" ${DLOPEN_ENABLED_BY_DEFAULT})
|
||||
set_option(SDL_DLOPEN "Use dlopen for shared object loading" ${SDL_DLOPEN_ENABLED_BY_DEFAULT})
|
||||
set_option(OSS "Support the OSS audio API" ${UNIX_SYS})
|
||||
set_option(ALSA "Support the ALSA audio API" ${UNIX_SYS})
|
||||
dep_option(ALSA_SHARED "Dynamically load ALSA audio support" ON "ALSA" OFF)
|
||||
|
@ -266,7 +267,10 @@ set_option(CLOCK_GETTIME "Use clock_gettime() instead of gettimeofday()" O
|
|||
set_option(INPUT_TSLIB "Use the Touchscreen library for input" ${UNIX_SYS})
|
||||
set_option(VIDEO_X11 "Use X11 video driver" ${UNIX_SYS})
|
||||
set_option(VIDEO_WAYLAND "Use Wayland video driver" ${UNIX_SYS})
|
||||
dep_option(WAYLAND_SHARED "Dynamically load Wayland support" ON "VIDEO_WAYLAND" OFF)
|
||||
dep_option(VIDEO_WAYLAND_QT_TOUCH "QtWayland server support for Wayland video driver" ON "VIDEO_WAYLAND" OFF)
|
||||
set_option(VIDEO_MIR "Use Mir video driver" ${UNIX_SYS})
|
||||
dep_option(MIR_SHARED "Dynamically load Mir support" ON "VIDEO_MIR" OFF)
|
||||
set_option(VIDEO_RPI "Use Raspberry Pi video driver" ${UNIX_SYS})
|
||||
dep_option(X11_SHARED "Dynamically load X11 support" ON "VIDEO_X11" OFF)
|
||||
set(SDL_X11_OPTIONS Xcursor Xinerama XInput Xrandr Xscrnsaver XShape Xvm)
|
||||
|
@ -585,7 +589,7 @@ if(LIBC)
|
|||
set(CMAKE_REQUIRED_LIBRARIES m)
|
||||
foreach(_FN
|
||||
atan atan2 ceil copysign cos cosf fabs floor log pow scalbn sin
|
||||
sinf sqrt sqrtf tan tanf)
|
||||
sinf sqrt sqrtf tan tanf acos asin)
|
||||
string(TOUPPER ${_FN} _UPPER)
|
||||
set(_HAVEVAR "HAVE_${_UPPER}")
|
||||
check_function_exists("${_FN}" ${_HAVEVAR})
|
||||
|
@ -597,6 +601,15 @@ if(LIBC)
|
|||
check_library_exists(iconv iconv_open "" HAVE_LIBICONV)
|
||||
if(HAVE_LIBICONV)
|
||||
list(APPEND EXTRA_LIBS iconv)
|
||||
set(HAVE_ICONV 1)
|
||||
endif()
|
||||
|
||||
if(NOT APPLE)
|
||||
check_include_file(alloca.h HAVE_ALLOCA_H)
|
||||
check_function_exists(alloca HAVE_ALLOCA)
|
||||
else()
|
||||
set(HAVE_ALLOCA_H 1)
|
||||
set(HAVE_ALLOCA 1)
|
||||
endif()
|
||||
|
||||
check_struct_has_member("struct sigaction" "sa_sigaction" "signal.h" HAVE_SA_SIGACTION)
|
||||
|
@ -1140,10 +1153,6 @@ elseif(APPLE)
|
|||
set(SDL_VIDEO_OPENGL 1)
|
||||
set(SDL_VIDEO_OPENGL_CGL 1)
|
||||
set(SDL_VIDEO_RENDER_OGL 1)
|
||||
if(DARWIN)
|
||||
find_library(OpenGL_LIBRARY OpenGL)
|
||||
list(APPEND EXTRA_LIBRARIES ${OpenGL_LIBRARY})
|
||||
endif()
|
||||
set(HAVE_VIDEO_OPENGL TRUE)
|
||||
endif()
|
||||
endif()
|
||||
|
|
11
SDL2.spec.in
11
SDL2.spec.in
|
@ -1,7 +1,7 @@
|
|||
Summary: Simple DirectMedia Layer
|
||||
Name: SDL2
|
||||
Version: @SDL_VERSION@
|
||||
Release: 1
|
||||
Release: 2
|
||||
Source: http://www.libsdl.org/release/%{name}-%{version}.tar.gz
|
||||
URL: http://www.libsdl.org/
|
||||
License: zlib
|
||||
|
@ -63,12 +63,12 @@ rm -rf $RPM_BUILD_ROOT
|
|||
|
||||
%files
|
||||
%{__defattr}
|
||||
%doc README-SDL.txt COPYING.txt CREDITS.txt BUGS.txt
|
||||
%doc README*.txt COPYING.txt CREDITS.txt BUGS.txt
|
||||
%{_libdir}/lib*.%{__soext}.*
|
||||
|
||||
%files devel
|
||||
%{__defattr}
|
||||
%doc README README-SDL.txt COPYING CREDITS BUGS WhatsNew
|
||||
%doc README*.txt COPYING.txt CREDITS.txt BUGS.txt WhatsNew.txt
|
||||
%{_bindir}/*-config
|
||||
%{_libdir}/lib*.a
|
||||
%{_libdir}/lib*.la
|
||||
|
@ -78,13 +78,16 @@ rm -rf $RPM_BUILD_ROOT
|
|||
%{_datadir}/aclocal/*
|
||||
|
||||
%changelog
|
||||
* Sun Dec 07 2014 Simone Contini <s.contini@oltrelinux.com>
|
||||
- Fixed changelog date issue and docs filenames
|
||||
|
||||
* Sun Jan 22 2012 Sam Lantinga <slouken@libsdl.org>
|
||||
- Updated for SDL 2.0
|
||||
|
||||
* Tue May 16 2006 Sam Lantinga <slouken@libsdl.org>
|
||||
- Removed support for Darwin, due to build problems on ps2linux
|
||||
|
||||
* Mon Jan 03 2004 Anders Bjorklund <afb@algonet.se>
|
||||
* Sat Jan 03 2004 Anders Bjorklund <afb@algonet.se>
|
||||
- Added support for Darwin, updated spec file
|
||||
|
||||
* Wed Jan 19 2000 Sam Lantinga <slouken@libsdl.org>
|
||||
|
|
|
@ -41,6 +41,10 @@ public class SDLActivity extends Activity {
|
|||
/** If shared libraries (e.g. SDL or the native application) could not be loaded. */
|
||||
public static boolean mBrokenLibraries;
|
||||
|
||||
// If we want to separate mouse and touch events.
|
||||
// This is only toggled in native code when a hint is set!
|
||||
public static boolean mSeparateMouseAndTouch;
|
||||
|
||||
// Main components
|
||||
protected static SDLActivity mSingleton;
|
||||
protected static SDLSurface mSurface;
|
||||
|
@ -81,7 +85,6 @@ public class SDLActivity extends Activity {
|
|||
}
|
||||
|
||||
/**
|
||||
* This method is called by SDL using JNI.
|
||||
* This method is called by SDL before starting the native application thread.
|
||||
* It can be overridden to provide the arguments after the application name.
|
||||
* The default implementation returns an empty array. It never returns null.
|
||||
|
@ -402,6 +405,7 @@ public class SDLActivity extends Activity {
|
|||
public static native void onNativeKeyDown(int keycode);
|
||||
public static native void onNativeKeyUp(int keycode);
|
||||
public static native void onNativeKeyboardFocusLost();
|
||||
public static native void onNativeMouse(int button, int action, float x, float y);
|
||||
public static native void onNativeTouch(int touchDevId, int pointerFingerId,
|
||||
int action, float x,
|
||||
float y, float p);
|
||||
|
@ -1089,7 +1093,7 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
|
|||
// Some SOURCE_DPAD or SOURCE_GAMEPAD are also SOURCE_KEYBOARD
|
||||
// So, we try to process them as DPAD or GAMEPAD events first, if that fails we try them as KEYBOARD
|
||||
|
||||
if ( (event.getSource() & 0x00000401) != 0 || /* API 12: SOURCE_GAMEPAD */
|
||||
if ( (event.getSource() & InputDevice.SOURCE_GAMEPAD) != 0 ||
|
||||
(event.getSource() & InputDevice.SOURCE_DPAD) != 0 ) {
|
||||
if (event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||
if (SDLActivity.onNativePadDown(event.getDeviceId(), keyCode) == 0) {
|
||||
|
@ -1126,50 +1130,65 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
|
|||
final int pointerCount = event.getPointerCount();
|
||||
int action = event.getActionMasked();
|
||||
int pointerFingerId;
|
||||
int mouseButton;
|
||||
int i = -1;
|
||||
float x,y,p;
|
||||
|
||||
switch(action) {
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
for (i = 0; i < pointerCount; i++) {
|
||||
// !!! FIXME: dump this SDK check after 2.0.4 ships and require API14.
|
||||
if (event.getSource() == InputDevice.SOURCE_MOUSE && SDLActivity.mSeparateMouseAndTouch) {
|
||||
if (Build.VERSION.SDK_INT < 14) {
|
||||
mouseButton = 1; // For Android==12 all mouse buttons are the left button
|
||||
} else {
|
||||
try {
|
||||
mouseButton = (Integer) event.getClass().getMethod("getButtonState").invoke(event);
|
||||
} catch(Exception e) {
|
||||
mouseButton = 1; // oh well.
|
||||
}
|
||||
}
|
||||
SDLActivity.onNativeMouse(mouseButton, action, event.getX(0), event.getY(0));
|
||||
} else {
|
||||
switch(action) {
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
for (i = 0; i < pointerCount; i++) {
|
||||
pointerFingerId = event.getPointerId(i);
|
||||
x = event.getX(i) / mWidth;
|
||||
y = event.getY(i) / mHeight;
|
||||
p = event.getPressure(i);
|
||||
SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, p);
|
||||
}
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
// Primary pointer up/down, the index is always zero
|
||||
i = 0;
|
||||
case MotionEvent.ACTION_POINTER_UP:
|
||||
case MotionEvent.ACTION_POINTER_DOWN:
|
||||
// Non primary pointer up/down
|
||||
if (i == -1) {
|
||||
i = event.getActionIndex();
|
||||
}
|
||||
|
||||
pointerFingerId = event.getPointerId(i);
|
||||
x = event.getX(i) / mWidth;
|
||||
y = event.getY(i) / mHeight;
|
||||
p = event.getPressure(i);
|
||||
SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, p);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
// Primary pointer up/down, the index is always zero
|
||||
i = 0;
|
||||
case MotionEvent.ACTION_POINTER_UP:
|
||||
case MotionEvent.ACTION_POINTER_DOWN:
|
||||
// Non primary pointer up/down
|
||||
if (i == -1) {
|
||||
i = event.getActionIndex();
|
||||
}
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
for (i = 0; i < pointerCount; i++) {
|
||||
pointerFingerId = event.getPointerId(i);
|
||||
x = event.getX(i) / mWidth;
|
||||
y = event.getY(i) / mHeight;
|
||||
p = event.getPressure(i);
|
||||
SDLActivity.onNativeTouch(touchDevId, pointerFingerId, MotionEvent.ACTION_UP, x, y, p);
|
||||
}
|
||||
break;
|
||||
|
||||
pointerFingerId = event.getPointerId(i);
|
||||
x = event.getX(i) / mWidth;
|
||||
y = event.getY(i) / mHeight;
|
||||
p = event.getPressure(i);
|
||||
SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, p);
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
for (i = 0; i < pointerCount; i++) {
|
||||
pointerFingerId = event.getPointerId(i);
|
||||
x = event.getX(i) / mWidth;
|
||||
y = event.getY(i) / mHeight;
|
||||
p = event.getPressure(i);
|
||||
SDLActivity.onNativeTouch(touchDevId, pointerFingerId, MotionEvent.ACTION_UP, x, y, p);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -1500,9 +1519,44 @@ class SDLJoystickHandler_API12 extends SDLJoystickHandler {
|
|||
|
||||
class SDLGenericMotionListener_API12 implements View.OnGenericMotionListener {
|
||||
// Generic Motion (mouse hover, joystick...) events go here
|
||||
// We only have joysticks yet
|
||||
@Override
|
||||
public boolean onGenericMotion(View v, MotionEvent event) {
|
||||
return SDLActivity.handleJoystickMotionEvent(event);
|
||||
float x, y;
|
||||
int mouseButton;
|
||||
int action;
|
||||
|
||||
switch ( event.getSource() ) {
|
||||
case InputDevice.SOURCE_JOYSTICK:
|
||||
case InputDevice.SOURCE_GAMEPAD:
|
||||
case InputDevice.SOURCE_DPAD:
|
||||
SDLActivity.handleJoystickMotionEvent(event);
|
||||
return true;
|
||||
|
||||
case InputDevice.SOURCE_MOUSE:
|
||||
action = event.getActionMasked();
|
||||
switch(event.getActionMasked()) {
|
||||
case MotionEvent.ACTION_SCROLL:
|
||||
x = event.getAxisValue(MotionEvent.AXIS_HSCROLL, 0);
|
||||
y = event.getAxisValue(MotionEvent.AXIS_VSCROLL, 0);
|
||||
SDLActivity.onNativeMouse(0, action, x, y);
|
||||
return true;
|
||||
|
||||
case MotionEvent.ACTION_HOVER_MOVE:
|
||||
x = event.getX(0);
|
||||
y = event.getY(0);
|
||||
|
||||
SDLActivity.onNativeMouse(0, action, x, y);
|
||||
return true;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Event was not managed
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -505,8 +505,13 @@ macro(CheckX11)
|
|||
endif()
|
||||
endmacro()
|
||||
|
||||
# Requires:
|
||||
# - EGL
|
||||
# - PkgCheckModules
|
||||
# Optional:
|
||||
# - MIR_SHARED opt
|
||||
# - HAVE_DLOPEN opt
|
||||
macro(CheckMir)
|
||||
# !!! FIXME: hook up dynamic loading here.
|
||||
if(VIDEO_MIR)
|
||||
find_library(MIR_LIB mirclient mircommon egl)
|
||||
pkg_check_modules(MIR_TOOLKIT mirclient mircommon)
|
||||
|
@ -522,15 +527,31 @@ macro(CheckMir)
|
|||
set(SDL_VIDEO_DRIVER_MIR 1)
|
||||
|
||||
list(APPEND EXTRA_CFLAGS ${MIR_TOOLKIT_CFLAGS} ${EGL_CLFAGS} ${XKB_CLFLAGS})
|
||||
list(APPEND EXTRA_LDFLAGS ${MIR_TOOLKIT_LDFLAGS} ${EGL_LDLAGS} ${XKB_LDLAGS})
|
||||
endif (MIR_LIB AND MIR_TOOLKIT_FOUND AND EGL_FOUND AND XKB_FOUND)
|
||||
|
||||
if(MIR_SHARED)
|
||||
if(NOT HAVE_DLOPEN)
|
||||
message_warn("You must have SDL_LoadObject() support for dynamic Mir loading")
|
||||
else()
|
||||
FindLibraryAndSONAME(mirclient)
|
||||
FindLibraryAndSONAME(xkbcommon)
|
||||
set(SDL_VIDEO_DRIVER_MIR_DYNAMIC "\"${MIRCLIENT_LIB_SONAME}\"")
|
||||
set(SDL_VIDEO_DRIVER_MIR_DYNAMIC_XKBCOMMON "\"${XKBCOMMON_LIB_SONAME}\"")
|
||||
set(HAVE_MIR_SHARED TRUE)
|
||||
endif()
|
||||
else()
|
||||
set(EXTRA_LIBS ${MIR_TOOLKIT_LIBRARIES} ${EXTRA_LIBS})
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# Requires:
|
||||
# - EGL
|
||||
# - PkgCheckModules
|
||||
# Optional:
|
||||
# - WAYLAND_SHARED opt
|
||||
# - HAVE_DLOPEN opt
|
||||
macro(CheckWayland)
|
||||
# !!! FIXME: hook up dynamic loading here.
|
||||
if(VIDEO_WAYLAND)
|
||||
pkg_check_modules(WAYLAND wayland-client wayland-cursor wayland-egl egl xkbcommon)
|
||||
if(WAYLAND_FOUND)
|
||||
|
@ -540,12 +561,34 @@ macro(CheckWayland)
|
|||
include_directories(
|
||||
${WAYLAND_INCLUDE_DIRS}
|
||||
)
|
||||
set(EXTRA_LIBS ${WAYLAND_LIBRARIES} ${EXTRA_LIBS})
|
||||
set(HAVE_VIDEO_WAYLAND TRUE)
|
||||
set(HAVE_SDL_VIDEO TRUE)
|
||||
|
||||
file(GLOB WAYLAND_SOURCES ${SDL2_SOURCE_DIR}/src/video/wayland/*.c)
|
||||
set(SOURCE_FILES ${SOURCE_FILES} ${WAYLAND_SOURCES})
|
||||
|
||||
if(VIDEO_WAYLAND_QT_TOUCH)
|
||||
set(SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH 1)
|
||||
endif()
|
||||
|
||||
if(WAYLAND_SHARED)
|
||||
if(NOT HAVE_DLOPEN)
|
||||
message_warn("You must have SDL_LoadObject() support for dynamic Wayland loading")
|
||||
else()
|
||||
FindLibraryAndSONAME(wayland-client)
|
||||
FindLibraryAndSONAME(wayland-egl)
|
||||
FindLibraryAndSONAME(wayland-cursor)
|
||||
FindLibraryAndSONAME(xkbcommon)
|
||||
set(SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC "\"${WAYLAND_CLIENT_LIB_SONAME}\"")
|
||||
set(SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL "\"${WAYLAND_EGL_LIB_SONAME}\"")
|
||||
set(SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR "\"${WAYLAND_CURSOR_LIB_SONAME}\"")
|
||||
set(SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON "\"${XKBCOMMON_LIB_SONAME}\"")
|
||||
set(HAVE_WAYLAND_SHARED TRUE)
|
||||
endif()
|
||||
else()
|
||||
set(EXTRA_LIBS ${WAYLAND_LIBRARIES} ${EXTRA_LIBS})
|
||||
endif()
|
||||
|
||||
set(SDL_VIDEO_DRIVER_WAYLAND 1)
|
||||
endif()
|
||||
endif()
|
||||
|
@ -682,7 +725,7 @@ macro(CheckOpenGLESX11)
|
|||
endif()
|
||||
endmacro()
|
||||
|
||||
# Rquires:
|
||||
# Requires:
|
||||
# - nada
|
||||
# Optional:
|
||||
# - THREADS opt
|
||||
|
@ -733,13 +776,17 @@ macro(CheckPTHREAD)
|
|||
|
||||
# Run some tests
|
||||
set(CMAKE_REQUIRED_FLAGS "${PTHREAD_CFLAGS} ${PTHREAD_LDFLAGS}")
|
||||
check_c_source_runs("
|
||||
if(CMAKE_CROSSCOMPILING)
|
||||
set(HAVE_PTHREADS 1)
|
||||
else()
|
||||
check_c_source_runs("
|
||||
#include <pthread.h>
|
||||
int main(int argc, char** argv) {
|
||||
pthread_attr_t type;
|
||||
pthread_attr_init(&type);
|
||||
return 0;
|
||||
}" HAVE_PTHREADS)
|
||||
endif()
|
||||
if(HAVE_PTHREADS)
|
||||
set(SDL_THREAD_PTHREAD 1)
|
||||
list(APPEND EXTRA_CFLAGS ${PTHREAD_CFLAGS})
|
||||
|
@ -788,8 +835,8 @@ macro(CheckPTHREAD)
|
|||
#include <pthread.h>
|
||||
#include <pthread_np.h>
|
||||
int main(int argc, char** argv) { return 0; }" HAVE_PTHREAD_NP_H)
|
||||
check_function_exists(pthread_setname_np HAVE_PTHREAD_setNAME_NP)
|
||||
check_function_exists(pthread_set_name_np HAVE_PTHREAD_set_NAME_NP)
|
||||
check_function_exists(pthread_setname_np HAVE_PTHREAD_SETNAME_NP)
|
||||
check_function_exists(pthread_set_name_np HAVE_PTHREAD_SET_NAME_NP)
|
||||
set(CMAKE_REQUIRED_FLAGS)
|
||||
|
||||
set(SOURCE_FILES ${SOURCE_FILES}
|
||||
|
|
27
configure
vendored
27
configure
vendored
|
@ -21916,6 +21916,7 @@ $as_echo_n "checking for recursive mutexes... " >&6; }
|
|||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
#define _GNU_SOURCE 1
|
||||
#include <pthread.h>
|
||||
|
||||
int
|
||||
|
@ -21929,7 +21930,7 @@ main ()
|
|||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"; then :
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
|
||||
has_recursive_mutexes=yes
|
||||
|
||||
|
@ -21937,12 +21938,14 @@ $as_echo "#define SDL_THREAD_PTHREAD_RECURSIVE_MUTEX 1" >>confdefs.h
|
|||
|
||||
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
fi
|
||||
if test x$has_recursive_mutexes = xno; then
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
#define _GNU_SOURCE 1
|
||||
#include <pthread.h>
|
||||
|
||||
int
|
||||
|
@ -21956,7 +21959,7 @@ main ()
|
|||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"; then :
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
|
||||
has_recursive_mutexes=yes
|
||||
|
||||
|
@ -21964,7 +21967,8 @@ $as_echo "#define SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP 1" >>confdefs.h
|
|||
|
||||
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $has_recursive_mutexes" >&5
|
||||
$as_echo "$has_recursive_mutexes" >&6; }
|
||||
|
@ -23091,11 +23095,22 @@ $as_echo "#define SDL_POWER_ANDROID 1" >>confdefs.h
|
|||
fi
|
||||
# Set up files for the filesystem library
|
||||
if test x$enable_filesystem = xyes; then
|
||||
case $ARCH in
|
||||
android)
|
||||
|
||||
$as_echo "#define SDL_FILESYSTEM_ANDROID 1" >>confdefs.h
|
||||
|
||||
SOURCES="$SOURCES $srcdir/src/filesystem/android/*.c"
|
||||
have_filesystem=yes
|
||||
;;
|
||||
*)
|
||||
|
||||
$as_echo "#define SDL_FILESYSTEM_UNIX 1" >>confdefs.h
|
||||
|
||||
SOURCES="$SOURCES $srcdir/src/filesystem/unix/*.c"
|
||||
have_filesystem=yes
|
||||
SOURCES="$SOURCES $srcdir/src/filesystem/unix/*.c"
|
||||
have_filesystem=yes
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
# Set up files for the timer library
|
||||
if test x$enable_timers = xyes; then
|
||||
|
|
21
configure.in
21
configure.in
|
@ -2424,7 +2424,8 @@ AC_HELP_STRING([--enable-pthread-sem], [use pthread semaphores [[default=yes]]])
|
|||
AC_MSG_CHECKING(for recursive mutexes)
|
||||
has_recursive_mutexes=no
|
||||
if test x$has_recursive_mutexes = xno; then
|
||||
AC_TRY_COMPILE([
|
||||
AC_TRY_LINK([
|
||||
#define _GNU_SOURCE 1
|
||||
#include <pthread.h>
|
||||
],[
|
||||
pthread_mutexattr_t attr;
|
||||
|
@ -2435,7 +2436,8 @@ AC_HELP_STRING([--enable-pthread-sem], [use pthread semaphores [[default=yes]]])
|
|||
])
|
||||
fi
|
||||
if test x$has_recursive_mutexes = xno; then
|
||||
AC_TRY_COMPILE([
|
||||
AC_TRY_LINK([
|
||||
#define _GNU_SOURCE 1
|
||||
#include <pthread.h>
|
||||
],[
|
||||
pthread_mutexattr_t attr;
|
||||
|
@ -2971,9 +2973,18 @@ case "$host" in
|
|||
fi
|
||||
# Set up files for the filesystem library
|
||||
if test x$enable_filesystem = xyes; then
|
||||
AC_DEFINE(SDL_FILESYSTEM_UNIX, 1, [ ])
|
||||
SOURCES="$SOURCES $srcdir/src/filesystem/unix/*.c"
|
||||
have_filesystem=yes
|
||||
case $ARCH in
|
||||
android)
|
||||
AC_DEFINE(SDL_FILESYSTEM_ANDROID, 1, [ ])
|
||||
SOURCES="$SOURCES $srcdir/src/filesystem/android/*.c"
|
||||
have_filesystem=yes
|
||||
;;
|
||||
*)
|
||||
AC_DEFINE(SDL_FILESYSTEM_UNIX, 1, [ ])
|
||||
SOURCES="$SOURCES $srcdir/src/filesystem/unix/*.c"
|
||||
have_filesystem=yes
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
# Set up files for the timer library
|
||||
if test x$enable_timers = xyes; then
|
||||
|
|
|
@ -1,34 +1,8 @@
|
|||
Platforms
|
||||
=========
|
||||
|
||||
We maintain the list of supported platforms on our wiki now, and how to
|
||||
build and install SDL for those platforms:
|
||||
|
||||
This is a list of the platforms SDL supports, and who maintains them.
|
||||
https://wiki.libsdl.org/Installation
|
||||
|
||||
Officially supported platforms
|
||||
==============================
|
||||
(code compiles, and thoroughly tested for release)
|
||||
==============================
|
||||
* Windows XP/Vista/7/8
|
||||
* Mac OS X 10.5+
|
||||
* Linux 2.6+
|
||||
* iOS 5.1.1+
|
||||
* Android 2.3.3+
|
||||
|
||||
Unofficially supported platforms
|
||||
================================
|
||||
(code compiles, but not thoroughly tested)
|
||||
================================
|
||||
* FreeBSD
|
||||
* NetBSD
|
||||
* OpenBSD
|
||||
* Solaris
|
||||
|
||||
Platforms supported by volunteers
|
||||
=================================
|
||||
* Haiku - maintained by Axel Dörfler <axeld@pinc-software.de>
|
||||
* PSP - maintained by 527721088@qq.com
|
||||
* Pandora - maintained by Scott Smith <pickle136@sbcglobal.net>
|
||||
* NaCl - maintained by Gabriel Jacobo <gabomdq@gmail.com>
|
||||
|
||||
Platforms that need maintainers
|
||||
===============================
|
||||
|
|
|
@ -15,7 +15,7 @@ There are two basic ways of building SDL at the moment:
|
|||
|
||||
If you have a GNUish system, then you might try this. Edit configure.in,
|
||||
take a look at the large section labelled:
|
||||
"Set up the configuration based on the target platform!"
|
||||
"Set up the configuration based on the host platform!"
|
||||
Add a section for your platform, and then re-run autogen.sh and build!
|
||||
|
||||
2. Using an IDE:
|
||||
|
|
|
@ -90,10 +90,12 @@ Here is a rough list of what works, and what doens't:
|
|||
* keyboard input. Most of WinRT's documented virtual keys are supported, as
|
||||
well as many keys with documented hardware scancodes.
|
||||
* OpenGL. Experimental support for OpenGL ES 2 is available via the ANGLE
|
||||
project, using either MS Open Technologies' repository, at
|
||||
https://github.com/msopentech/angle (both the "winrt" and "future-dev"
|
||||
branches are supported), or the official ANGLE repository, at
|
||||
https://chromium.googlesource.com/angle/angle
|
||||
project, using either:
|
||||
* MS Open Technologies' "ms-master" repository, at https://github.com/MSOpenTech/angle
|
||||
(for use with Windows 8.1+ or Windows Phone 8.1+)
|
||||
* MS Open Technologies' "angle-win8.0" repository, at https://github.com/MSOpenTech/angle-win8.0
|
||||
(for Windows 8.0 only!)
|
||||
* Google's main ANGLE repository, at https://chromium.googlesource.com/angle/angle
|
||||
* SDLmain. WinRT uses a different signature for each app's main() function.
|
||||
SDL-based apps that use this port must compile in SDL_winrt_main_NonXAML.cpp
|
||||
(in `SDL\src\main\winrt\`) directly in order for their C-style main()
|
||||
|
@ -112,6 +114,11 @@ Here is a rough list of what works, and what doens't:
|
|||
supported by WinRT itself.
|
||||
* joysticks and game controllers that aren't supported by Microsoft's XInput
|
||||
API.
|
||||
* turning off VSync when rendering on Windows Phone. Attempts to turn VSync
|
||||
off on Windows Phone result either in Direct3D not drawing anything, or it
|
||||
forcing VSync back on. As such, SDL_RENDERER_PRESENTVSYNC will always get
|
||||
turned-on on Windows Phone. This limitation is not present in non-Phone
|
||||
WinRT (such as Windows 8.x), where turning off VSync appears to work.
|
||||
* probably anything else that's not listed as supported
|
||||
|
||||
|
||||
|
|
|
@ -102,9 +102,9 @@ typedef enum
|
|||
SDL_ASSERTION_ABORT, /**< Terminate the program. */
|
||||
SDL_ASSERTION_IGNORE, /**< Ignore the assert. */
|
||||
SDL_ASSERTION_ALWAYS_IGNORE /**< Ignore the assert from now on. */
|
||||
} SDL_assert_state;
|
||||
} SDL_AssertState;
|
||||
|
||||
typedef struct SDL_assert_data
|
||||
typedef struct SDL_AssertData
|
||||
{
|
||||
int always_ignore;
|
||||
unsigned int trigger_count;
|
||||
|
@ -112,13 +112,13 @@ typedef struct SDL_assert_data
|
|||
const char *filename;
|
||||
int linenum;
|
||||
const char *function;
|
||||
const struct SDL_assert_data *next;
|
||||
} SDL_assert_data;
|
||||
const struct SDL_AssertData *next;
|
||||
} SDL_AssertData;
|
||||
|
||||
#if (SDL_ASSERT_LEVEL > 0)
|
||||
|
||||
/* Never call this directly. Use the SDL_assert* macros. */
|
||||
extern DECLSPEC SDL_assert_state SDLCALL SDL_ReportAssertion(SDL_assert_data *,
|
||||
extern DECLSPEC SDL_AssertState SDLCALL SDL_ReportAssertion(SDL_AssertData *,
|
||||
const char *,
|
||||
const char *, int)
|
||||
#if defined(__clang__)
|
||||
|
@ -141,10 +141,10 @@ extern DECLSPEC SDL_assert_state SDLCALL SDL_ReportAssertion(SDL_assert_data *,
|
|||
#define SDL_enabled_assert(condition) \
|
||||
do { \
|
||||
while ( !(condition) ) { \
|
||||
static struct SDL_assert_data sdl_assert_data = { \
|
||||
static struct SDL_AssertData sdl_assert_data = { \
|
||||
0, 0, #condition, 0, 0, 0, 0 \
|
||||
}; \
|
||||
const SDL_assert_state sdl_assert_state = SDL_ReportAssertion(&sdl_assert_data, SDL_FUNCTION, SDL_FILE, SDL_LINE); \
|
||||
const SDL_AssertState sdl_assert_state = SDL_ReportAssertion(&sdl_assert_data, SDL_FUNCTION, SDL_FILE, SDL_LINE); \
|
||||
if (sdl_assert_state == SDL_ASSERTION_RETRY) { \
|
||||
continue; /* go again. */ \
|
||||
} else if (sdl_assert_state == SDL_ASSERTION_BREAK) { \
|
||||
|
@ -181,8 +181,8 @@ extern DECLSPEC SDL_assert_state SDLCALL SDL_ReportAssertion(SDL_assert_data *,
|
|||
#define SDL_assert_always(condition) SDL_enabled_assert(condition)
|
||||
|
||||
|
||||
typedef SDL_assert_state (SDLCALL *SDL_AssertionHandler)(
|
||||
const SDL_assert_data* data, void* userdata);
|
||||
typedef SDL_AssertState (SDLCALL *SDL_AssertionHandler)(
|
||||
const SDL_AssertData* data, void* userdata);
|
||||
|
||||
/**
|
||||
* \brief Set an application-defined assertion handler.
|
||||
|
@ -199,7 +199,7 @@ typedef SDL_assert_state (SDLCALL *SDL_AssertionHandler)(
|
|||
*
|
||||
* This callback is NOT reset to SDL's internal handler upon SDL_Quit()!
|
||||
*
|
||||
* \return SDL_assert_state value of how to handle the assertion failure.
|
||||
* \return SDL_AssertState value of how to handle the assertion failure.
|
||||
*
|
||||
* \param handler Callback function, called when an assertion fails.
|
||||
* \param userdata A pointer passed to the callback as-is.
|
||||
|
@ -246,7 +246,7 @@ extern DECLSPEC SDL_AssertionHandler SDLCALL SDL_GetAssertionHandler(void **puse
|
|||
* The proper way to examine this data looks something like this:
|
||||
*
|
||||
* <code>
|
||||
* const SDL_assert_data *item = SDL_GetAssertionReport();
|
||||
* const SDL_AssertData *item = SDL_GetAssertionReport();
|
||||
* while (item) {
|
||||
* printf("'%s', %s (%s:%d), triggered %u times, always ignore: %s.\n",
|
||||
* item->condition, item->function, item->filename,
|
||||
|
@ -259,7 +259,7 @@ extern DECLSPEC SDL_AssertionHandler SDLCALL SDL_GetAssertionHandler(void **puse
|
|||
* \return List of all assertions.
|
||||
* \sa SDL_ResetAssertionReport
|
||||
*/
|
||||
extern DECLSPEC const SDL_assert_data * SDLCALL SDL_GetAssertionReport(void);
|
||||
extern DECLSPEC const SDL_AssertData * SDLCALL SDL_GetAssertionReport(void);
|
||||
|
||||
/**
|
||||
* \brief Reset the list of all assertion failures.
|
||||
|
@ -270,6 +270,12 @@ extern DECLSPEC const SDL_assert_data * SDLCALL SDL_GetAssertionReport(void);
|
|||
*/
|
||||
extern DECLSPEC void SDLCALL SDL_ResetAssertionReport(void);
|
||||
|
||||
|
||||
/* these had wrong naming conventions until 2.0.4. Please update your app! */
|
||||
#define SDL_assert_state SDL_AssertState
|
||||
#define SDL_assert_data SDL_AssertData
|
||||
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -269,14 +269,11 @@
|
|||
#cmakedefine SDL_VIDEO_DRIVER_VIVANTE @SDL_VIDEO_DRIVER_VIVANTE@
|
||||
#cmakedefine SDL_VIDEO_DRIVER_VIVANTE_VDK @SDL_VIDEO_DRIVER_VIVANTE_VDK@
|
||||
|
||||
#if 0
|
||||
/* !!! FIXME: in configure script version, missing here: */
|
||||
#undef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
|
||||
#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC
|
||||
#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL
|
||||
#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR
|
||||
#undef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON
|
||||
#endif
|
||||
#cmakedefine SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH @SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH@
|
||||
#cmakedefine SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC @SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC@
|
||||
#cmakedefine SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL @SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_EGL@
|
||||
#cmakedefine SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR @SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_CURSOR@
|
||||
#cmakedefine SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON @SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC_XKBCOMMON@
|
||||
|
||||
#cmakedefine SDL_VIDEO_DRIVER_MIR @SDL_VIDEO_DRIVER_MIR@
|
||||
#cmakedefine SDL_VIDEO_DRIVER_MIR_DYNAMIC @SDL_VIDEO_DRIVER_MIR_DYNAMIC@
|
||||
|
|
|
@ -349,6 +349,7 @@
|
|||
#undef SDL_FILESYSTEM_UNIX
|
||||
#undef SDL_FILESYSTEM_WINDOWS
|
||||
#undef SDL_FILESYSTEM_NACL
|
||||
#undef SDL_FILESYSTEM_ANDROID
|
||||
#undef SDL_FILESYSTEM_EMSCRIPTEN
|
||||
|
||||
/* Enable assembly routines */
|
||||
|
|
|
@ -134,6 +134,10 @@ typedef enum
|
|||
/* Drag and drop events */
|
||||
SDL_DROPFILE = 0x1000, /**< The system requests a file open */
|
||||
|
||||
/* Audio hotplug events */
|
||||
SDL_AUDIODEVICEADDED = 0x1100, /**< A new audio device is available */
|
||||
SDL_AUDIODEVICEREMOVED, /**< An audio device has been removed. */
|
||||
|
||||
/* Render events */
|
||||
SDL_RENDER_TARGETS_RESET = 0x2000, /**< The render targets have been reset and their contents need to be updated */
|
||||
SDL_RENDER_DEVICE_RESET, /**< The device has been reset and all textures need to be recreated */
|
||||
|
@ -382,6 +386,20 @@ typedef struct SDL_ControllerDeviceEvent
|
|||
Sint32 which; /**< The joystick device index for the ADDED event, instance id for the REMOVED or REMAPPED event */
|
||||
} SDL_ControllerDeviceEvent;
|
||||
|
||||
/**
|
||||
* \brief Audio device event structure (event.adevice.*)
|
||||
*/
|
||||
typedef struct SDL_AudioDeviceEvent
|
||||
{
|
||||
Uint32 type; /**< ::SDL_AUDIODEVICEADDED, or ::SDL_AUDIODEVICEREMOVED */
|
||||
Uint32 timestamp;
|
||||
Uint32 which; /**< The audio device index for the ADDED event (valid until next SDL_GetNumAudioDevices() call), SDL_AudioDeviceID for the REMOVED event */
|
||||
Uint8 iscapture; /**< zero if an output device, non-zero if a capture device. */
|
||||
Uint8 padding1;
|
||||
Uint8 padding2;
|
||||
Uint8 padding3;
|
||||
} SDL_AudioDeviceEvent;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Touch finger event structure (event.tfinger.*)
|
||||
|
@ -422,7 +440,7 @@ typedef struct SDL_MultiGestureEvent
|
|||
*/
|
||||
typedef struct SDL_DollarGestureEvent
|
||||
{
|
||||
Uint32 type; /**< ::SDL_DOLLARGESTURE */
|
||||
Uint32 type; /**< ::SDL_DOLLARGESTURE or ::SDL_DOLLARRECORD */
|
||||
Uint32 timestamp;
|
||||
SDL_TouchID touchId; /**< The touch device id */
|
||||
SDL_GestureID gestureId;
|
||||
|
@ -516,6 +534,7 @@ typedef union SDL_Event
|
|||
SDL_ControllerAxisEvent caxis; /**< Game Controller axis event data */
|
||||
SDL_ControllerButtonEvent cbutton; /**< Game Controller button event data */
|
||||
SDL_ControllerDeviceEvent cdevice; /**< Game Controller device event data */
|
||||
SDL_AudioDeviceEvent adevice; /**< Audio device event data */
|
||||
SDL_QuitEvent quit; /**< Quit request event data */
|
||||
SDL_UserEvent user; /**< Custom event data */
|
||||
SDL_SysWMEvent syswm; /**< System dependent window event data */
|
||||
|
|
|
@ -241,7 +241,8 @@ SDL_GameControllerGetBindForAxis(SDL_GameController *gamecontroller,
|
|||
/**
|
||||
* Get the current state of an axis control on a game controller.
|
||||
*
|
||||
* The state is a value ranging from -32768 to 32767.
|
||||
* The state is a value ranging from -32768 to 32767 (except for the triggers,
|
||||
* which range from 0 to 32767).
|
||||
*
|
||||
* The axis indices start at index 0.
|
||||
*/
|
||||
|
|
|
@ -533,6 +533,18 @@ extern "C" {
|
|||
*/
|
||||
#define SDL_HINT_IME_INTERNAL_EDITING "SDL_IME_INTERNAL_EDITING"
|
||||
|
||||
/**
|
||||
* \brief A variable to control whether mouse and touch events are to be treated together or separately
|
||||
*
|
||||
* The variable can be set to the following values:
|
||||
* "0" - Mouse events will be handled as touch events, and touch will raise fake mouse
|
||||
* events. This is the behaviour of SDL <= 2.0.3. (default)
|
||||
* "1" - Mouse events will be handled separately from pure touch events.
|
||||
*
|
||||
* The value of this hint is used at runtime, so it can be changed at any time.
|
||||
*/
|
||||
#define SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH "SDL_ANDROID_SEPARATE_MOUSE_AND_TOUCH"
|
||||
|
||||
/**
|
||||
* \brief override the binding element for keyboard inputs for Emscripten builds
|
||||
*
|
||||
|
@ -547,6 +559,18 @@ extern "C" {
|
|||
*/
|
||||
#define SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT "SDL_EMSCRIPTEN_KEYBOARD_ELEMENT"
|
||||
|
||||
/**
|
||||
* \brief Tell SDL not to catch the SIGINT or SIGTERM signals.
|
||||
*
|
||||
* This hint only applies to Unix-like platforms.
|
||||
*
|
||||
* The variable can be set to the following values:
|
||||
* "0" - SDL will install a SIGINT and SIGTERM handler, and when it
|
||||
* catches a signal, convert it into an SDL_QUIT event.
|
||||
* "1" - SDL will not install a signal handler at all.
|
||||
*/
|
||||
#define SDL_HINT_NO_SIGNAL_HANDLERS "SDL_NO_SIGNAL_HANDLERS"
|
||||
|
||||
/**
|
||||
* \brief An enumeration of hint priorities
|
||||
*/
|
||||
|
|
|
@ -2988,6 +2988,11 @@ GLAPI GLboolean APIENTRY glIsProgramARB (GLuint program);
|
|||
#define GL_ARB_framebuffer_sRGB 1
|
||||
#endif /* GL_ARB_framebuffer_sRGB */
|
||||
|
||||
#ifndef GL_KHR_context_flush_control
|
||||
#define GL_CONTEXT_RELEASE_BEHAVIOR 0x82FB
|
||||
#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82FC
|
||||
#endif /* GL_KHR_context_flush_control */
|
||||
|
||||
#ifndef GL_ARB_geometry_shader4
|
||||
#define GL_ARB_geometry_shader4 1
|
||||
#define GL_LINES_ADJACENCY_ARB 0x000A
|
||||
|
|
|
@ -81,8 +81,8 @@ typedef struct SDL_RendererInfo
|
|||
Uint32 flags; /**< Supported ::SDL_RendererFlags */
|
||||
Uint32 num_texture_formats; /**< The number of available texture formats */
|
||||
Uint32 texture_formats[16]; /**< The available texture formats */
|
||||
int max_texture_width; /**< The maximimum texture width */
|
||||
int max_texture_height; /**< The maximimum texture height */
|
||||
int max_texture_width; /**< The maximum texture width */
|
||||
int max_texture_height; /**< The maximum texture height */
|
||||
} SDL_RendererInfo;
|
||||
|
||||
/**
|
||||
|
@ -792,7 +792,7 @@ extern DECLSPEC int SDLCALL SDL_RenderCopy(SDL_Renderer * renderer,
|
|||
* \param dstrect A pointer to the destination rectangle, or NULL for the
|
||||
* entire rendering target.
|
||||
* \param angle An angle in degrees that indicates the rotation that will be applied to dstrect
|
||||
* \param center A pointer to a point indicating the point around which dstrect will be rotated (if NULL, rotation will be done aroud dstrect.w/2, dstrect.h/2)
|
||||
* \param center A pointer to a point indicating the point around which dstrect will be rotated (if NULL, rotation will be done around dstrect.w/2, dstrect.h/2).
|
||||
* \param flip An SDL_RendererFlip value stating which flipping actions should be performed on the texture
|
||||
*
|
||||
* \return 0 on success, or -1 on error
|
||||
|
|
|
@ -173,6 +173,8 @@ typedef uint64_t Uint64;
|
|||
#define SDL_PRIs64 PRIs64
|
||||
#elif defined(__WIN32__)
|
||||
#define SDL_PRIs64 "I64d"
|
||||
#elif defined(__LINUX__) && defined(__LP64__)
|
||||
#define SDL_PRIs64 "ld"
|
||||
#else
|
||||
#define SDL_PRIs64 "lld"
|
||||
#endif
|
||||
|
@ -182,6 +184,8 @@ typedef uint64_t Uint64;
|
|||
#define SDL_PRIu64 PRIu64
|
||||
#elif defined(__WIN32__)
|
||||
#define SDL_PRIu64 "I64u"
|
||||
#elif defined(__LINUX__) && defined(__LP64__)
|
||||
#define SDL_PRIu64 "lu"
|
||||
#else
|
||||
#define SDL_PRIu64 "llu"
|
||||
#endif
|
||||
|
@ -191,6 +195,8 @@ typedef uint64_t Uint64;
|
|||
#define SDL_PRIx64 PRIx64
|
||||
#elif defined(__WIN32__)
|
||||
#define SDL_PRIx64 "I64x"
|
||||
#elif defined(__LINUX__) && defined(__LP64__)
|
||||
#define SDL_PRIx64 "lx"
|
||||
#else
|
||||
#define SDL_PRIx64 "llx"
|
||||
#endif
|
||||
|
@ -200,6 +206,8 @@ typedef uint64_t Uint64;
|
|||
#define SDL_PRIX64 PRIX64
|
||||
#elif defined(__WIN32__)
|
||||
#define SDL_PRIX64 "I64X"
|
||||
#elif defined(__LINUX__) && defined(__LP64__)
|
||||
#define SDL_PRIX64 "lX"
|
||||
#else
|
||||
#define SDL_PRIX64 "llX"
|
||||
#endif
|
||||
|
|
|
@ -186,6 +186,7 @@ struct SDL_SysWMinfo
|
|||
struct
|
||||
{
|
||||
HWND window; /**< The window handle */
|
||||
HDC hdc; /**< The window device context */
|
||||
} win;
|
||||
#endif
|
||||
#if defined(SDL_VIDEO_DRIVER_WINRT)
|
||||
|
|
|
@ -189,7 +189,8 @@ typedef enum
|
|||
SDL_GL_CONTEXT_FLAGS,
|
||||
SDL_GL_CONTEXT_PROFILE_MASK,
|
||||
SDL_GL_SHARE_WITH_CURRENT_CONTEXT,
|
||||
SDL_GL_FRAMEBUFFER_SRGB_CAPABLE
|
||||
SDL_GL_FRAMEBUFFER_SRGB_CAPABLE,
|
||||
SDL_GL_CONTEXT_RELEASE_BEHAVIOR
|
||||
} SDL_GLattr;
|
||||
|
||||
typedef enum
|
||||
|
@ -207,6 +208,12 @@ typedef enum
|
|||
SDL_GL_CONTEXT_RESET_ISOLATION_FLAG = 0x0008
|
||||
} SDL_GLcontextFlag;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SDL_GL_CONTEXT_RELEASE_BEHAVIOR_NONE = 0x0000,
|
||||
SDL_GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH = 0x0001
|
||||
} SDL_GLcontextReleaseFlag;
|
||||
|
||||
|
||||
/* Function prototypes */
|
||||
|
||||
|
@ -715,6 +722,9 @@ extern DECLSPEC int SDLCALL SDL_UpdateWindowSurfaceRects(SDL_Window * window,
|
|||
* \param window The window for which the input grab mode should be set.
|
||||
* \param grabbed This is SDL_TRUE to grab input, and SDL_FALSE to release input.
|
||||
*
|
||||
* If the caller enables a grab while another window is currently grabbed,
|
||||
* the other window loses its grab in favor of the caller's window.
|
||||
*
|
||||
* \sa SDL_GetWindowGrab()
|
||||
*/
|
||||
extern DECLSPEC void SDLCALL SDL_SetWindowGrab(SDL_Window * window,
|
||||
|
@ -729,6 +739,15 @@ extern DECLSPEC void SDLCALL SDL_SetWindowGrab(SDL_Window * window,
|
|||
*/
|
||||
extern DECLSPEC SDL_bool SDLCALL SDL_GetWindowGrab(SDL_Window * window);
|
||||
|
||||
/**
|
||||
* \brief Get the window that currently has an input grab enabled.
|
||||
*
|
||||
* \return This returns the window if input is grabbed, and NULL otherwise.
|
||||
*
|
||||
* \sa SDL_SetWindowGrab()
|
||||
*/
|
||||
extern DECLSPEC SDL_Window * SDLCALL SDL_GetGrabbedWindow(void);
|
||||
|
||||
/**
|
||||
* \brief Set the brightness (gamma correction) for a window.
|
||||
*
|
||||
|
|
|
@ -405,6 +405,8 @@ SDL_GetPlatform()
|
|||
return "BSDI";
|
||||
#elif __DREAMCAST__
|
||||
return "Dreamcast";
|
||||
#elif __EMSCRIPTEN__
|
||||
return "Emscripten";
|
||||
#elif __FREEBSD__
|
||||
return "FreeBSD";
|
||||
#elif __HAIKU__
|
||||
|
|
|
@ -120,7 +120,7 @@ SDL_SetError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
|
|||
so that it supports internationalization and thread-safe errors.
|
||||
*/
|
||||
static char *
|
||||
SDL_GetErrorMsg(char *errstr, unsigned int maxlen)
|
||||
SDL_GetErrorMsg(char *errstr, int maxlen)
|
||||
{
|
||||
SDL_error *error;
|
||||
|
||||
|
@ -163,37 +163,55 @@ SDL_GetErrorMsg(char *errstr, unsigned int maxlen)
|
|||
len =
|
||||
SDL_snprintf(msg, maxlen, tmp,
|
||||
error->args[argi++].value_i);
|
||||
msg += len;
|
||||
maxlen -= len;
|
||||
if (len > 0) {
|
||||
msg += len;
|
||||
maxlen -= len;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
len =
|
||||
SDL_snprintf(msg, maxlen, tmp,
|
||||
error->args[argi++].value_f);
|
||||
msg += len;
|
||||
maxlen -= len;
|
||||
if (len > 0) {
|
||||
msg += len;
|
||||
maxlen -= len;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
len =
|
||||
SDL_snprintf(msg, maxlen, tmp,
|
||||
error->args[argi++].value_ptr);
|
||||
msg += len;
|
||||
maxlen -= len;
|
||||
if (len > 0) {
|
||||
msg += len;
|
||||
maxlen -= len;
|
||||
}
|
||||
break;
|
||||
|
||||
case 's':
|
||||
len =
|
||||
SDL_snprintf(msg, maxlen, tmp,
|
||||
SDL_LookupString(error->args[argi++].
|
||||
buf));
|
||||
msg += len;
|
||||
maxlen -= len;
|
||||
if (len > 0) {
|
||||
msg += len;
|
||||
maxlen -= len;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
} else {
|
||||
*msg++ = *fmt++;
|
||||
maxlen -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* slide back if we've overshot the end of our buffer. */
|
||||
if (maxlen < 0) {
|
||||
msg -= (-maxlen) + 1;
|
||||
}
|
||||
|
||||
*msg = 0; /* NULL terminate the string */
|
||||
}
|
||||
return (errstr);
|
||||
|
|
|
@ -51,9 +51,7 @@ extern AudioBootStrap QSAAUDIO_bootstrap;
|
|||
extern AudioBootStrap SUNAUDIO_bootstrap;
|
||||
extern AudioBootStrap ARTS_bootstrap;
|
||||
extern AudioBootStrap ESD_bootstrap;
|
||||
#if SDL_AUDIO_DRIVER_NACL
|
||||
extern AudioBootStrap NACLAUD_bootstrap;
|
||||
#endif
|
||||
extern AudioBootStrap NAS_bootstrap;
|
||||
extern AudioBootStrap XAUDIO2_bootstrap;
|
||||
extern AudioBootStrap DSOUND_bootstrap;
|
||||
|
@ -163,8 +161,16 @@ get_audio_device(SDL_AudioDeviceID id)
|
|||
|
||||
/* stubs for audio drivers that don't need a specific entry point... */
|
||||
static void
|
||||
SDL_AudioDetectDevices_Default(int iscapture, SDL_AddAudioDevice addfn)
|
||||
{ /* no-op. */
|
||||
SDL_AudioDetectDevices_Default(void)
|
||||
{
|
||||
/* you have to write your own implementation if these assertions fail. */
|
||||
SDL_assert(current_audio.impl.OnlyHasDefaultOutputDevice);
|
||||
SDL_assert(current_audio.impl.OnlyHasDefaultInputDevice || !current_audio.impl.HasCaptureSupport);
|
||||
|
||||
SDL_AddAudioDevice(SDL_FALSE, DEFAULT_OUTPUT_DEVNAME, (void *) ((size_t) 0x1));
|
||||
if (current_audio.impl.HasCaptureSupport) {
|
||||
SDL_AddAudioDevice(SDL_TRUE, DEFAULT_INPUT_DEVNAME, (void *) ((size_t) 0x2));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -209,10 +215,16 @@ SDL_AudioDeinitialize_Default(void)
|
|||
{ /* no-op. */
|
||||
}
|
||||
|
||||
static void
|
||||
SDL_AudioFreeDeviceHandle_Default(void *handle)
|
||||
{ /* no-op. */
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
SDL_AudioOpenDevice_Default(_THIS, const char *devname, int iscapture)
|
||||
SDL_AudioOpenDevice_Default(_THIS, void *handle, const char *devname, int iscapture)
|
||||
{
|
||||
return -1;
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static SDL_INLINE SDL_bool
|
||||
|
@ -269,71 +281,139 @@ finalize_audio_entry_points(void)
|
|||
FILL_STUB(CloseDevice);
|
||||
FILL_STUB(LockDevice);
|
||||
FILL_STUB(UnlockDevice);
|
||||
FILL_STUB(FreeDeviceHandle);
|
||||
FILL_STUB(Deinitialize);
|
||||
#undef FILL_STUB
|
||||
}
|
||||
|
||||
#if 0 /* !!! FIXME: rewrite/remove this streamer code. */
|
||||
/* Streaming functions (for when the input and output buffer sizes are different) */
|
||||
/* Write [length] bytes from buf into the streamer */
|
||||
static void
|
||||
SDL_StreamWrite(SDL_AudioStreamer * stream, Uint8 * buf, int length)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < length; ++i) {
|
||||
stream->buffer[stream->write_pos] = buf[i];
|
||||
++stream->write_pos;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read [length] bytes out of the streamer into buf */
|
||||
static void
|
||||
SDL_StreamRead(SDL_AudioStreamer * stream, Uint8 * buf, int length)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < length; ++i) {
|
||||
buf[i] = stream->buffer[stream->read_pos];
|
||||
++stream->read_pos;
|
||||
}
|
||||
}
|
||||
/* device hotplug support... */
|
||||
|
||||
static int
|
||||
SDL_StreamLength(SDL_AudioStreamer * stream)
|
||||
add_audio_device(const char *name, void *handle, SDL_AudioDeviceItem **devices, int *devCount)
|
||||
{
|
||||
return (stream->write_pos - stream->read_pos) % stream->max_len;
|
||||
}
|
||||
|
||||
/* Initialize the stream by allocating the buffer and setting the read/write heads to the beginning */
|
||||
#if 0
|
||||
static int
|
||||
SDL_StreamInit(SDL_AudioStreamer * stream, int max_len, Uint8 silence)
|
||||
{
|
||||
/* First try to allocate the buffer */
|
||||
stream->buffer = (Uint8 *) SDL_malloc(max_len);
|
||||
if (stream->buffer == NULL) {
|
||||
int retval = -1;
|
||||
const size_t size = sizeof (SDL_AudioDeviceItem) + SDL_strlen(name) + 1;
|
||||
SDL_AudioDeviceItem *item = (SDL_AudioDeviceItem *) SDL_malloc(size);
|
||||
if (item == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
stream->max_len = max_len;
|
||||
stream->read_pos = 0;
|
||||
stream->write_pos = 0;
|
||||
SDL_assert(handle != NULL); /* we reserve NULL, audio backends can't use it. */
|
||||
|
||||
/* Zero out the buffer */
|
||||
SDL_memset(stream->buffer, silence, max_len);
|
||||
item->handle = handle;
|
||||
SDL_strlcpy(item->name, name, size - sizeof (SDL_AudioDeviceItem));
|
||||
|
||||
return 0;
|
||||
SDL_LockMutex(current_audio.detectionLock);
|
||||
item->next = *devices;
|
||||
*devices = item;
|
||||
retval = (*devCount)++;
|
||||
SDL_UnlockMutex(current_audio.detectionLock);
|
||||
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Deinitialize the stream simply by freeing the buffer */
|
||||
static void
|
||||
SDL_StreamDeinit(SDL_AudioStreamer * stream)
|
||||
static SDL_INLINE int
|
||||
add_capture_device(const char *name, void *handle)
|
||||
{
|
||||
SDL_free(stream->buffer);
|
||||
/* !!! FIXME: add this later. SDL_assert(current_audio.impl.HasCaptureSupport);*/
|
||||
return add_audio_device(name, handle, ¤t_audio.inputDevices, ¤t_audio.inputDeviceCount);
|
||||
}
|
||||
#endif
|
||||
|
||||
static SDL_INLINE int
|
||||
add_output_device(const char *name, void *handle)
|
||||
{
|
||||
return add_audio_device(name, handle, ¤t_audio.outputDevices, ¤t_audio.outputDeviceCount);
|
||||
}
|
||||
|
||||
static void
|
||||
free_device_list(SDL_AudioDeviceItem **devices, int *devCount)
|
||||
{
|
||||
SDL_AudioDeviceItem *item, *next;
|
||||
for (item = *devices; item != NULL; item = next) {
|
||||
next = item->next;
|
||||
if (item->handle != NULL) {
|
||||
current_audio.impl.FreeDeviceHandle(item->handle);
|
||||
}
|
||||
SDL_free(item);
|
||||
}
|
||||
*devices = NULL;
|
||||
*devCount = 0;
|
||||
}
|
||||
|
||||
|
||||
/* The audio backends call this when a new device is plugged in. */
|
||||
void
|
||||
SDL_AddAudioDevice(const int iscapture, const char *name, void *handle)
|
||||
{
|
||||
const int device_index = iscapture ? add_capture_device(name, handle) : add_output_device(name, handle);
|
||||
if (device_index != -1) {
|
||||
/* Post the event, if desired */
|
||||
if (SDL_GetEventState(SDL_AUDIODEVICEADDED) == SDL_ENABLE) {
|
||||
SDL_Event event;
|
||||
SDL_zero(event);
|
||||
event.adevice.type = SDL_AUDIODEVICEADDED;
|
||||
event.adevice.which = device_index;
|
||||
event.adevice.iscapture = iscapture;
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* The audio backends call this when a currently-opened device is lost. */
|
||||
void SDL_OpenedAudioDeviceDisconnected(SDL_AudioDevice *device)
|
||||
{
|
||||
SDL_assert(get_audio_device(device->id) == device);
|
||||
|
||||
if (!device->enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Ends the audio callback and mark the device as STOPPED, but the
|
||||
app still needs to close the device to free resources. */
|
||||
current_audio.impl.LockDevice(device);
|
||||
device->enabled = 0;
|
||||
current_audio.impl.UnlockDevice(device);
|
||||
|
||||
/* Post the event, if desired */
|
||||
if (SDL_GetEventState(SDL_AUDIODEVICEREMOVED) == SDL_ENABLE) {
|
||||
SDL_Event event;
|
||||
SDL_zero(event);
|
||||
event.adevice.type = SDL_AUDIODEVICEREMOVED;
|
||||
event.adevice.which = device->id;
|
||||
event.adevice.iscapture = device->iscapture ? 1 : 0;
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mark_device_removed(void *handle, SDL_AudioDeviceItem *devices, SDL_bool *removedFlag)
|
||||
{
|
||||
SDL_AudioDeviceItem *item;
|
||||
SDL_assert(handle != NULL);
|
||||
for (item = devices; item != NULL; item = item->next) {
|
||||
if (item->handle == handle) {
|
||||
item->handle = NULL;
|
||||
*removedFlag = SDL_TRUE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* The audio backends call this when a device is removed from the system. */
|
||||
void
|
||||
SDL_RemoveAudioDevice(const int iscapture, void *handle)
|
||||
{
|
||||
SDL_LockMutex(current_audio.detectionLock);
|
||||
if (iscapture) {
|
||||
mark_device_removed(handle, current_audio.inputDevices, ¤t_audio.captureDevicesRemoved);
|
||||
} else {
|
||||
mark_device_removed(handle, current_audio.outputDevices, ¤t_audio.outputDevicesRemoved);
|
||||
}
|
||||
SDL_UnlockMutex(current_audio.detectionLock);
|
||||
current_audio.impl.FreeDeviceHandle(handle);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* buffer queueing support... */
|
||||
|
@ -510,26 +590,17 @@ SDL_ClearQueuedAudio(SDL_AudioDeviceID devid)
|
|||
}
|
||||
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
#include <android/log.h>
|
||||
#endif
|
||||
|
||||
/* The general mixing thread function */
|
||||
int SDLCALL
|
||||
SDL_RunAudio(void *devicep)
|
||||
{
|
||||
SDL_AudioDevice *device = (SDL_AudioDevice *) devicep;
|
||||
const int silence = (int) device->spec.silence;
|
||||
const Uint32 delay = ((device->spec.samples * 1000) / device->spec.freq);
|
||||
const int stream_len = (device->convert.needed) ? device->convert.len : device->spec.size;
|
||||
Uint8 *stream;
|
||||
int stream_len;
|
||||
void *udata;
|
||||
void (SDLCALL * fill) (void *userdata, Uint8 * stream, int len);
|
||||
Uint32 delay;
|
||||
|
||||
#if 0 /* !!! FIXME: rewrite/remove this streamer code. */
|
||||
/* For streaming when the buffer sizes don't match up */
|
||||
Uint8 *istream;
|
||||
int istream_len = 0;
|
||||
#endif
|
||||
void *udata = device->spec.userdata;
|
||||
void (SDLCALL *fill) (void *, Uint8 *, int) = device->spec.callback;
|
||||
|
||||
/* The audio mixing is always a high priority thread */
|
||||
SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH);
|
||||
|
@ -538,197 +609,60 @@ SDL_RunAudio(void *devicep)
|
|||
device->threadid = SDL_ThreadID();
|
||||
current_audio.impl.ThreadInit(device);
|
||||
|
||||
/* Set up the mixing function */
|
||||
fill = device->spec.callback;
|
||||
udata = device->spec.userdata;
|
||||
|
||||
/* By default do not stream */
|
||||
device->use_streamer = 0;
|
||||
|
||||
if (device->convert.needed) {
|
||||
#if 0 /* !!! FIXME: I took len_div out of the structure. Use rate_incr instead? */
|
||||
/* If the result of the conversion alters the length, i.e. resampling is being used, use the streamer */
|
||||
if (device->convert.len_mult != 1 || device->convert.len_div != 1) {
|
||||
/* The streamer's maximum length should be twice whichever is larger: spec.size or len_cvt */
|
||||
stream_max_len = 2 * device->spec.size;
|
||||
if (device->convert.len_mult > device->convert.len_div) {
|
||||
stream_max_len *= device->convert.len_mult;
|
||||
stream_max_len /= device->convert.len_div;
|
||||
}
|
||||
if (SDL_StreamInit(&device->streamer, stream_max_len, silence) <
|
||||
0)
|
||||
return -1;
|
||||
device->use_streamer = 1;
|
||||
|
||||
/* istream_len should be the length of what we grab from the callback and feed to conversion,
|
||||
so that we get close to spec_size. I.e. we want device.spec_size = istream_len * u / d
|
||||
*/
|
||||
istream_len =
|
||||
device->spec.size * device->convert.len_div /
|
||||
device->convert.len_mult;
|
||||
/* Loop, filling the audio buffers */
|
||||
while (!device->shutdown) {
|
||||
/* Fill the current buffer with sound */
|
||||
if (device->convert.needed) {
|
||||
stream = device->convert.buf;
|
||||
} else if (device->enabled) {
|
||||
stream = current_audio.impl.GetDeviceBuf(device);
|
||||
} else {
|
||||
/* if the device isn't enabled, we still write to the
|
||||
fake_stream, so the app's callback will fire with
|
||||
a regular frequency, in case they depend on that
|
||||
for timing or progress. They can use hotplug
|
||||
now to know if the device failed. */
|
||||
stream = NULL;
|
||||
}
|
||||
#endif
|
||||
stream_len = device->convert.len;
|
||||
} else {
|
||||
stream_len = device->spec.size;
|
||||
}
|
||||
|
||||
/* Calculate the delay while paused */
|
||||
delay = ((device->spec.samples * 1000) / device->spec.freq);
|
||||
|
||||
/* Determine if the streamer is necessary here */
|
||||
#if 0 /* !!! FIXME: rewrite/remove this streamer code. */
|
||||
if (device->use_streamer == 1) {
|
||||
/* This code is almost the same as the old code. The difference is, instead of reading
|
||||
directly from the callback into "stream", then converting and sending the audio off,
|
||||
we go: callback -> "istream" -> (conversion) -> streamer -> stream -> device.
|
||||
However, reading and writing with streamer are done separately:
|
||||
- We only call the callback and write to the streamer when the streamer does not
|
||||
contain enough samples to output to the device.
|
||||
- We only read from the streamer and tell the device to play when the streamer
|
||||
does have enough samples to output.
|
||||
This allows us to perform resampling in the conversion step, where the output of the
|
||||
resampling process can be any number. We will have to see what a good size for the
|
||||
stream's maximum length is, but I suspect 2*max(len_cvt, stream_len) is a good figure.
|
||||
*/
|
||||
while (device->enabled) {
|
||||
|
||||
if (device->paused) {
|
||||
SDL_Delay(delay);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Only read in audio if the streamer doesn't have enough already (if it does not have enough samples to output) */
|
||||
if (SDL_StreamLength(&device->streamer) < stream_len) {
|
||||
/* Set up istream */
|
||||
if (device->convert.needed) {
|
||||
if (device->convert.buf) {
|
||||
istream = device->convert.buf;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
/* FIXME: Ryan, this is probably wrong. I imagine we don't want to get
|
||||
* a device buffer both here and below in the stream output.
|
||||
*/
|
||||
istream = current_audio.impl.GetDeviceBuf(device);
|
||||
if (istream == NULL) {
|
||||
istream = device->fake_stream;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read from the callback into the _input_ stream */
|
||||
SDL_LockMutex(device->mixer_lock);
|
||||
(*fill) (udata, istream, istream_len);
|
||||
SDL_UnlockMutex(device->mixer_lock);
|
||||
|
||||
/* Convert the audio if necessary and write to the streamer */
|
||||
if (device->convert.needed) {
|
||||
SDL_ConvertAudio(&device->convert);
|
||||
if (istream == NULL) {
|
||||
istream = device->fake_stream;
|
||||
}
|
||||
/* SDL_memcpy(istream, device->convert.buf, device->convert.len_cvt); */
|
||||
SDL_StreamWrite(&device->streamer, device->convert.buf,
|
||||
device->convert.len_cvt);
|
||||
} else {
|
||||
SDL_StreamWrite(&device->streamer, istream, istream_len);
|
||||
}
|
||||
}
|
||||
|
||||
/* Only output audio if the streamer has enough to output */
|
||||
if (SDL_StreamLength(&device->streamer) >= stream_len) {
|
||||
/* Set up the output stream */
|
||||
if (device->convert.needed) {
|
||||
if (device->convert.buf) {
|
||||
stream = device->convert.buf;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
stream = current_audio.impl.GetDeviceBuf(device);
|
||||
if (stream == NULL) {
|
||||
stream = device->fake_stream;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now read from the streamer */
|
||||
SDL_StreamRead(&device->streamer, stream, stream_len);
|
||||
|
||||
/* Ready current buffer for play and change current buffer */
|
||||
if (stream != device->fake_stream) {
|
||||
current_audio.impl.PlayDevice(device);
|
||||
/* Wait for an audio buffer to become available */
|
||||
current_audio.impl.WaitDevice(device);
|
||||
} else {
|
||||
SDL_Delay(delay);
|
||||
}
|
||||
}
|
||||
|
||||
if (stream == NULL) {
|
||||
stream = device->fake_stream;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
/* Otherwise, do not use the streamer. This is the old code. */
|
||||
const int silence = (int) device->spec.silence;
|
||||
|
||||
/* Loop, filling the audio buffers */
|
||||
while (device->enabled) {
|
||||
/* !!! FIXME: this should be LockDevice. */
|
||||
SDL_LockMutex(device->mixer_lock);
|
||||
if (device->paused) {
|
||||
SDL_memset(stream, silence, stream_len);
|
||||
} else {
|
||||
(*fill) (udata, stream, stream_len);
|
||||
}
|
||||
SDL_UnlockMutex(device->mixer_lock);
|
||||
|
||||
/* Fill the current buffer with sound */
|
||||
if (device->convert.needed) {
|
||||
if (device->convert.buf) {
|
||||
stream = device->convert.buf;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
/* Convert the audio if necessary */
|
||||
if (device->enabled && device->convert.needed) {
|
||||
SDL_ConvertAudio(&device->convert);
|
||||
stream = current_audio.impl.GetDeviceBuf(device);
|
||||
if (stream == NULL) {
|
||||
stream = device->fake_stream;
|
||||
} else {
|
||||
stream = current_audio.impl.GetDeviceBuf(device);
|
||||
if (stream == NULL) {
|
||||
stream = device->fake_stream;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_LockMutex(device->mixer_lock);
|
||||
if (device->paused) {
|
||||
SDL_memset(stream, silence, stream_len);
|
||||
} else {
|
||||
(*fill) (udata, stream, stream_len);
|
||||
}
|
||||
SDL_UnlockMutex(device->mixer_lock);
|
||||
|
||||
/* Convert the audio if necessary */
|
||||
if (device->convert.needed) {
|
||||
SDL_ConvertAudio(&device->convert);
|
||||
stream = current_audio.impl.GetDeviceBuf(device);
|
||||
if (stream == NULL) {
|
||||
stream = device->fake_stream;
|
||||
}
|
||||
SDL_memcpy(stream, device->convert.buf,
|
||||
device->convert.len_cvt);
|
||||
}
|
||||
}
|
||||
|
||||
/* Ready current buffer for play and change current buffer */
|
||||
if (stream != device->fake_stream) {
|
||||
current_audio.impl.PlayDevice(device);
|
||||
/* Wait for an audio buffer to become available */
|
||||
current_audio.impl.WaitDevice(device);
|
||||
} else {
|
||||
SDL_Delay(delay);
|
||||
}
|
||||
/* Ready current buffer for play and change current buffer */
|
||||
if (stream == device->fake_stream) {
|
||||
SDL_Delay(delay);
|
||||
} else {
|
||||
current_audio.impl.PlayDevice(device);
|
||||
current_audio.impl.WaitDevice(device);
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for the audio to drain.. */
|
||||
/* Wait for the audio to drain. */
|
||||
current_audio.impl.WaitDone(device);
|
||||
|
||||
/* If necessary, deinit the streamer */
|
||||
#if 0 /* !!! FIXME: rewrite/remove this streamer code. */
|
||||
if (device->use_streamer == 1)
|
||||
SDL_StreamDeinit(&device->streamer);
|
||||
#endif
|
||||
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -761,16 +695,16 @@ SDL_ParseAudioFormat(const char *string)
|
|||
int
|
||||
SDL_GetNumAudioDrivers(void)
|
||||
{
|
||||
return (SDL_arraysize(bootstrap) - 1);
|
||||
return SDL_arraysize(bootstrap) - 1;
|
||||
}
|
||||
|
||||
const char *
|
||||
SDL_GetAudioDriver(int index)
|
||||
{
|
||||
if (index >= 0 && index < SDL_GetNumAudioDrivers()) {
|
||||
return (bootstrap[index]->name);
|
||||
return bootstrap[index]->name;
|
||||
}
|
||||
return (NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -784,8 +718,8 @@ SDL_AudioInit(const char *driver_name)
|
|||
SDL_AudioQuit(); /* shutdown driver if already running. */
|
||||
}
|
||||
|
||||
SDL_memset(¤t_audio, '\0', sizeof(current_audio));
|
||||
SDL_memset(open_devices, '\0', sizeof(open_devices));
|
||||
SDL_zero(current_audio);
|
||||
SDL_zero(open_devices);
|
||||
|
||||
/* Select the proper audio driver */
|
||||
if (driver_name == NULL) {
|
||||
|
@ -801,7 +735,7 @@ SDL_AudioInit(const char *driver_name)
|
|||
}
|
||||
|
||||
tried_to_init = 1;
|
||||
SDL_memset(¤t_audio, 0, sizeof(current_audio));
|
||||
SDL_zero(current_audio);
|
||||
current_audio.name = backend->name;
|
||||
current_audio.desc = backend->desc;
|
||||
initialized = backend->init(¤t_audio.impl);
|
||||
|
@ -817,13 +751,18 @@ SDL_AudioInit(const char *driver_name)
|
|||
}
|
||||
}
|
||||
|
||||
SDL_memset(¤t_audio, 0, sizeof(current_audio));
|
||||
return (-1); /* No driver was available, so fail. */
|
||||
SDL_zero(current_audio);
|
||||
return -1; /* No driver was available, so fail. */
|
||||
}
|
||||
|
||||
current_audio.detectionLock = SDL_CreateMutex();
|
||||
|
||||
finalize_audio_entry_points();
|
||||
|
||||
return (0);
|
||||
/* Make sure we have a list of devices available at startup. */
|
||||
current_audio.impl.DetectDevices();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -835,50 +774,32 @@ SDL_GetCurrentAudioDriver()
|
|||
return current_audio.name;
|
||||
}
|
||||
|
||||
/* Clean out devices that we've removed but had to keep around for stability. */
|
||||
static void
|
||||
free_device_list(char ***devices, int *devCount)
|
||||
clean_out_device_list(SDL_AudioDeviceItem **devices, int *devCount, SDL_bool *removedFlag)
|
||||
{
|
||||
int i = *devCount;
|
||||
if ((i > 0) && (*devices != NULL)) {
|
||||
while (i--) {
|
||||
SDL_free((*devices)[i]);
|
||||
SDL_AudioDeviceItem *item = *devices;
|
||||
SDL_AudioDeviceItem *prev = NULL;
|
||||
int total = 0;
|
||||
|
||||
while (item) {
|
||||
SDL_AudioDeviceItem *next = item->next;
|
||||
if (item->handle != NULL) {
|
||||
total++;
|
||||
prev = item;
|
||||
} else {
|
||||
if (prev) {
|
||||
prev->next = next;
|
||||
} else {
|
||||
*devices = next;
|
||||
}
|
||||
SDL_free(item);
|
||||
}
|
||||
item = next;
|
||||
}
|
||||
|
||||
SDL_free(*devices);
|
||||
|
||||
*devices = NULL;
|
||||
*devCount = 0;
|
||||
}
|
||||
|
||||
static
|
||||
void SDL_AddCaptureAudioDevice(const char *_name)
|
||||
{
|
||||
char *name = NULL;
|
||||
void *ptr = SDL_realloc(current_audio.inputDevices,
|
||||
(current_audio.inputDeviceCount+1) * sizeof(char*));
|
||||
if (ptr == NULL) {
|
||||
return; /* oh well. */
|
||||
}
|
||||
|
||||
current_audio.inputDevices = (char **) ptr;
|
||||
name = SDL_strdup(_name); /* if this returns NULL, that's okay. */
|
||||
current_audio.inputDevices[current_audio.inputDeviceCount++] = name;
|
||||
}
|
||||
|
||||
static
|
||||
void SDL_AddOutputAudioDevice(const char *_name)
|
||||
{
|
||||
char *name = NULL;
|
||||
void *ptr = SDL_realloc(current_audio.outputDevices,
|
||||
(current_audio.outputDeviceCount+1) * sizeof(char*));
|
||||
if (ptr == NULL) {
|
||||
return; /* oh well. */
|
||||
}
|
||||
|
||||
current_audio.outputDevices = (char **) ptr;
|
||||
name = SDL_strdup(_name); /* if this returns NULL, that's okay. */
|
||||
current_audio.outputDevices[current_audio.outputDeviceCount++] = name;
|
||||
*devCount = total;
|
||||
*removedFlag = SDL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -891,29 +812,18 @@ SDL_GetNumAudioDevices(int iscapture)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if ((iscapture) && (!current_audio.impl.HasCaptureSupport)) {
|
||||
return 0;
|
||||
SDL_LockMutex(current_audio.detectionLock);
|
||||
if (iscapture && current_audio.captureDevicesRemoved) {
|
||||
clean_out_device_list(¤t_audio.inputDevices, ¤t_audio.inputDeviceCount, ¤t_audio.captureDevicesRemoved);
|
||||
}
|
||||
|
||||
if ((iscapture) && (current_audio.impl.OnlyHasDefaultInputDevice)) {
|
||||
return 1;
|
||||
if (!iscapture && current_audio.outputDevicesRemoved) {
|
||||
clean_out_device_list(¤t_audio.outputDevices, ¤t_audio.outputDeviceCount, ¤t_audio.outputDevicesRemoved);
|
||||
current_audio.outputDevicesRemoved = SDL_FALSE;
|
||||
}
|
||||
|
||||
if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (iscapture) {
|
||||
free_device_list(¤t_audio.inputDevices,
|
||||
¤t_audio.inputDeviceCount);
|
||||
current_audio.impl.DetectDevices(iscapture, SDL_AddCaptureAudioDevice);
|
||||
retval = current_audio.inputDeviceCount;
|
||||
} else {
|
||||
free_device_list(¤t_audio.outputDevices,
|
||||
¤t_audio.outputDeviceCount);
|
||||
current_audio.impl.DetectDevices(iscapture, SDL_AddOutputAudioDevice);
|
||||
retval = current_audio.outputDeviceCount;
|
||||
}
|
||||
retval = iscapture ? current_audio.inputDeviceCount : current_audio.outputDeviceCount;
|
||||
SDL_UnlockMutex(current_audio.detectionLock);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
@ -922,6 +832,8 @@ SDL_GetNumAudioDevices(int iscapture)
|
|||
const char *
|
||||
SDL_GetAudioDeviceName(int index, int iscapture)
|
||||
{
|
||||
const char *retval = NULL;
|
||||
|
||||
if (!SDL_WasInit(SDL_INIT_AUDIO)) {
|
||||
SDL_SetError("Audio subsystem is not initialized");
|
||||
return NULL;
|
||||
|
@ -932,39 +844,28 @@ SDL_GetAudioDeviceName(int index, int iscapture)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (index < 0) {
|
||||
goto no_such_device;
|
||||
if (index >= 0) {
|
||||
SDL_AudioDeviceItem *item;
|
||||
int i;
|
||||
|
||||
SDL_LockMutex(current_audio.detectionLock);
|
||||
item = iscapture ? current_audio.inputDevices : current_audio.outputDevices;
|
||||
i = iscapture ? current_audio.inputDeviceCount : current_audio.outputDeviceCount;
|
||||
if (index < i) {
|
||||
for (i--; i > index; i--, item = item->next) {
|
||||
SDL_assert(item != NULL);
|
||||
}
|
||||
SDL_assert(item != NULL);
|
||||
retval = item->name;
|
||||
}
|
||||
SDL_UnlockMutex(current_audio.detectionLock);
|
||||
}
|
||||
|
||||
if ((iscapture) && (current_audio.impl.OnlyHasDefaultInputDevice)) {
|
||||
if (index > 0) {
|
||||
goto no_such_device;
|
||||
}
|
||||
return DEFAULT_INPUT_DEVNAME;
|
||||
if (retval == NULL) {
|
||||
SDL_SetError("No such device");
|
||||
}
|
||||
|
||||
if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) {
|
||||
if (index > 0) {
|
||||
goto no_such_device;
|
||||
}
|
||||
return DEFAULT_OUTPUT_DEVNAME;
|
||||
}
|
||||
|
||||
if (iscapture) {
|
||||
if (index >= current_audio.inputDeviceCount) {
|
||||
goto no_such_device;
|
||||
}
|
||||
return current_audio.inputDevices[index];
|
||||
} else {
|
||||
if (index >= current_audio.outputDeviceCount) {
|
||||
goto no_such_device;
|
||||
}
|
||||
return current_audio.outputDevices[index];
|
||||
}
|
||||
|
||||
no_such_device:
|
||||
SDL_SetError("No such device");
|
||||
return NULL;
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
|
@ -972,6 +873,7 @@ static void
|
|||
close_audio_device(SDL_AudioDevice * device)
|
||||
{
|
||||
device->enabled = 0;
|
||||
device->shutdown = 1;
|
||||
if (device->thread != NULL) {
|
||||
SDL_WaitThread(device->thread, NULL);
|
||||
}
|
||||
|
@ -1065,6 +967,8 @@ open_audio_device(const char *devname, int iscapture,
|
|||
SDL_AudioSpec _obtained;
|
||||
SDL_AudioDevice *device;
|
||||
SDL_bool build_cvt;
|
||||
void *handle = NULL;
|
||||
Uint32 stream_len;
|
||||
int i = 0;
|
||||
|
||||
if (!SDL_WasInit(SDL_INIT_AUDIO)) {
|
||||
|
@ -1077,6 +981,18 @@ open_audio_device(const char *devname, int iscapture,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Find an available device ID... */
|
||||
for (id = min_id - 1; id < SDL_arraysize(open_devices); id++) {
|
||||
if (open_devices[id] == NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (id == SDL_arraysize(open_devices)) {
|
||||
SDL_SetError("Too many open audio devices");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!obtained) {
|
||||
obtained = &_obtained;
|
||||
}
|
||||
|
@ -1112,9 +1028,7 @@ open_audio_device(const char *devname, int iscapture,
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) {
|
||||
} else if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) {
|
||||
if ((devname) && (SDL_strcmp(devname, DEFAULT_OUTPUT_DEVNAME) != 0)) {
|
||||
SDL_SetError("No such device");
|
||||
return 0;
|
||||
|
@ -1127,6 +1041,30 @@ open_audio_device(const char *devname, int iscapture,
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
} else if (devname != NULL) {
|
||||
/* if the app specifies an exact string, we can pass the backend
|
||||
an actual device handle thingey, which saves them the effort of
|
||||
figuring out what device this was (such as, reenumerating
|
||||
everything again to find the matching human-readable name).
|
||||
It might still need to open a device based on the string for,
|
||||
say, a network audio server, but this optimizes some cases. */
|
||||
SDL_AudioDeviceItem *item;
|
||||
SDL_LockMutex(current_audio.detectionLock);
|
||||
for (item = iscapture ? current_audio.inputDevices : current_audio.outputDevices; item; item = item->next) {
|
||||
if ((item->handle != NULL) && (SDL_strcmp(item->name, devname) == 0)) {
|
||||
handle = item->handle;
|
||||
break;
|
||||
}
|
||||
}
|
||||
SDL_UnlockMutex(current_audio.detectionLock);
|
||||
}
|
||||
|
||||
if (!current_audio.impl.AllowsArbitraryDeviceNames) {
|
||||
/* has to be in our device list, or the default device. */
|
||||
if ((handle == NULL) && (devname != NULL)) {
|
||||
SDL_SetError("No such device.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
device = (SDL_AudioDevice *) SDL_AllocAudioMem(sizeof(SDL_AudioDevice));
|
||||
|
@ -1135,12 +1073,13 @@ open_audio_device(const char *devname, int iscapture,
|
|||
return 0;
|
||||
}
|
||||
SDL_zerop(device);
|
||||
device->id = id + 1;
|
||||
device->spec = *obtained;
|
||||
device->enabled = 1;
|
||||
device->paused = 1;
|
||||
device->iscapture = iscapture;
|
||||
|
||||
/* Create a semaphore for locking the sound buffers */
|
||||
/* Create a mutex for locking the sound buffers */
|
||||
if (!current_audio.impl.SkipMixerLock) {
|
||||
device->mixer_lock = SDL_CreateMutex();
|
||||
if (device->mixer_lock == NULL) {
|
||||
|
@ -1150,26 +1089,12 @@ open_audio_device(const char *devname, int iscapture,
|
|||
}
|
||||
}
|
||||
|
||||
/* force a device detection if we haven't done one yet. */
|
||||
if ( ((iscapture) && (current_audio.inputDevices == NULL)) ||
|
||||
((!iscapture) && (current_audio.outputDevices == NULL)) ) {
|
||||
SDL_GetNumAudioDevices(iscapture);
|
||||
}
|
||||
|
||||
if (current_audio.impl.OpenDevice(device, devname, iscapture) < 0) {
|
||||
if (current_audio.impl.OpenDevice(device, handle, devname, iscapture) < 0) {
|
||||
close_audio_device(device);
|
||||
return 0;
|
||||
}
|
||||
device->opened = 1;
|
||||
|
||||
/* Allocate a fake audio memory buffer */
|
||||
device->fake_stream = (Uint8 *)SDL_AllocAudioMem(device->spec.size);
|
||||
if (device->fake_stream == NULL) {
|
||||
close_audio_device(device);
|
||||
SDL_OutOfMemory();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* See if we need to do any conversion */
|
||||
build_cvt = SDL_FALSE;
|
||||
if (obtained->freq != device->spec.freq) {
|
||||
|
@ -1228,6 +1153,19 @@ open_audio_device(const char *devname, int iscapture,
|
|||
}
|
||||
}
|
||||
|
||||
/* Allocate a fake audio memory buffer */
|
||||
stream_len = (device->convert.needed) ? device->convert.len_cvt : 0;
|
||||
if (device->spec.size > stream_len) {
|
||||
stream_len = device->spec.size;
|
||||
}
|
||||
SDL_assert(stream_len > 0);
|
||||
device->fake_stream = (Uint8 *)SDL_AllocAudioMem(stream_len);
|
||||
if (device->fake_stream == NULL) {
|
||||
close_audio_device(device);
|
||||
SDL_OutOfMemory();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (device->spec.callback == NULL) { /* use buffer queueing? */
|
||||
/* pool a few packets to start. Enough for two callbacks. */
|
||||
const int packetlen = SDL_AUDIOBUFFERQUEUE_PACKETLEN;
|
||||
|
@ -1247,25 +1185,14 @@ open_audio_device(const char *devname, int iscapture,
|
|||
device->spec.userdata = device;
|
||||
}
|
||||
|
||||
/* Find an available device ID and store the structure... */
|
||||
for (id = min_id - 1; id < SDL_arraysize(open_devices); id++) {
|
||||
if (open_devices[id] == NULL) {
|
||||
open_devices[id] = device;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (id == SDL_arraysize(open_devices)) {
|
||||
SDL_SetError("Too many open audio devices");
|
||||
close_audio_device(device);
|
||||
return 0;
|
||||
}
|
||||
/* add it to our list of open devices. */
|
||||
open_devices[id] = device;
|
||||
|
||||
/* Start the audio thread if necessary */
|
||||
if (!current_audio.impl.ProvidesOwnCallbackThread) {
|
||||
/* Start the audio thread */
|
||||
char name[64];
|
||||
SDL_snprintf(name, sizeof (name), "SDLAudioDev%d", (int) (id + 1));
|
||||
SDL_snprintf(name, sizeof (name), "SDLAudioDev%d", (int) device->id);
|
||||
/* !!! FIXME: this is nasty. */
|
||||
#if defined(__WIN32__) && !defined(HAVE_LIBC)
|
||||
#undef SDL_CreateThread
|
||||
|
@ -1278,13 +1205,13 @@ open_audio_device(const char *devname, int iscapture,
|
|||
device->thread = SDL_CreateThread(SDL_RunAudio, name, device);
|
||||
#endif
|
||||
if (device->thread == NULL) {
|
||||
SDL_CloseAudioDevice(id + 1);
|
||||
SDL_CloseAudioDevice(device->id);
|
||||
SDL_SetError("Couldn't create audio thread");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return id + 1;
|
||||
return device->id;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1296,14 +1223,14 @@ SDL_OpenAudio(SDL_AudioSpec * desired, SDL_AudioSpec * obtained)
|
|||
/* Start up the audio driver, if necessary. This is legacy behaviour! */
|
||||
if (!SDL_WasInit(SDL_INIT_AUDIO)) {
|
||||
if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
|
||||
return (-1);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* SDL_OpenAudio() is legacy and can only act on Device ID #1. */
|
||||
if (open_devices[0] != NULL) {
|
||||
SDL_SetError("Audio device is already opened");
|
||||
return (-1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (obtained) {
|
||||
|
@ -1314,7 +1241,7 @@ SDL_OpenAudio(SDL_AudioSpec * desired, SDL_AudioSpec * obtained)
|
|||
}
|
||||
|
||||
SDL_assert((id == 0) || (id == 1));
|
||||
return ((id == 0) ? -1 : 0);
|
||||
return (id == 0) ? -1 : 0;
|
||||
}
|
||||
|
||||
SDL_AudioDeviceID
|
||||
|
@ -1338,7 +1265,7 @@ SDL_GetAudioDeviceStatus(SDL_AudioDeviceID devid)
|
|||
status = SDL_AUDIO_PLAYING;
|
||||
}
|
||||
}
|
||||
return (status);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1429,14 +1356,16 @@ SDL_AudioQuit(void)
|
|||
}
|
||||
}
|
||||
|
||||
free_device_list(¤t_audio.outputDevices, ¤t_audio.outputDeviceCount);
|
||||
free_device_list(¤t_audio.inputDevices, ¤t_audio.inputDeviceCount);
|
||||
|
||||
/* Free the driver data */
|
||||
current_audio.impl.Deinitialize();
|
||||
free_device_list(¤t_audio.outputDevices,
|
||||
¤t_audio.outputDeviceCount);
|
||||
free_device_list(¤t_audio.inputDevices,
|
||||
¤t_audio.inputDeviceCount);
|
||||
SDL_memset(¤t_audio, '\0', sizeof(current_audio));
|
||||
SDL_memset(open_devices, '\0', sizeof(open_devices));
|
||||
|
||||
SDL_DestroyMutex(current_audio.detectionLock);
|
||||
|
||||
SDL_zero(current_audio);
|
||||
SDL_zero(open_devices);
|
||||
}
|
||||
|
||||
#define NUM_FORMATS 10
|
||||
|
@ -1474,16 +1403,16 @@ SDL_FirstAudioFormat(SDL_AudioFormat format)
|
|||
}
|
||||
}
|
||||
format_idx_sub = 0;
|
||||
return (SDL_NextAudioFormat());
|
||||
return SDL_NextAudioFormat();
|
||||
}
|
||||
|
||||
SDL_AudioFormat
|
||||
SDL_NextAudioFormat(void)
|
||||
{
|
||||
if ((format_idx == NUM_FORMATS) || (format_idx_sub == NUM_FORMATS)) {
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
return (format_list[format_idx][format_idx_sub++]);
|
||||
return format_list[format_idx][format_idx_sub++];
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -46,18 +46,21 @@
|
|||
#define _PATH_DEV_AUDIO "/dev/audio"
|
||||
#endif
|
||||
|
||||
static SDL_INLINE void
|
||||
test_device(const char *fname, int flags, int (*test) (int fd),
|
||||
SDL_AddAudioDevice addfn)
|
||||
static void
|
||||
test_device(const int iscapture, const char *fname, int flags, int (*test) (int fd))
|
||||
{
|
||||
struct stat sb;
|
||||
if ((stat(fname, &sb) == 0) && (S_ISCHR(sb.st_mode))) {
|
||||
const int audio_fd = open(fname, flags, 0);
|
||||
if (audio_fd >= 0) {
|
||||
if (test(audio_fd)) {
|
||||
addfn(fname);
|
||||
}
|
||||
const int okay = test(audio_fd);
|
||||
close(audio_fd);
|
||||
if (okay) {
|
||||
static size_t dummyhandle = 0;
|
||||
dummyhandle++;
|
||||
SDL_assert(dummyhandle != 0);
|
||||
SDL_AddAudioDevice(iscapture, fname, (void *) dummyhandle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -68,11 +71,10 @@ test_stub(int fd)
|
|||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
SDL_EnumUnixAudioDevices(int iscapture, int classic, int (*test)(int fd),
|
||||
SDL_AddAudioDevice addfn)
|
||||
static void
|
||||
SDL_EnumUnixAudioDevices_Internal(const int iscapture, const int classic, int (*test)(int))
|
||||
{
|
||||
const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT);
|
||||
const int flags = iscapture ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT;
|
||||
const char *audiodev;
|
||||
char audiopath[1024];
|
||||
|
||||
|
@ -97,17 +99,25 @@ SDL_EnumUnixAudioDevices(int iscapture, int classic, int (*test)(int fd),
|
|||
}
|
||||
}
|
||||
}
|
||||
test_device(audiodev, flags, test, addfn);
|
||||
test_device(iscapture, audiodev, flags, test);
|
||||
|
||||
if (SDL_strlen(audiodev) < (sizeof(audiopath) - 3)) {
|
||||
int instance = 0;
|
||||
while (instance++ <= 64) {
|
||||
SDL_snprintf(audiopath, SDL_arraysize(audiopath),
|
||||
"%s%d", audiodev, instance);
|
||||
test_device(audiopath, flags, test, addfn);
|
||||
test_device(iscapture, audiopath, flags, test);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SDL_EnumUnixAudioDevices(const int classic, int (*test)(int))
|
||||
{
|
||||
SDL_EnumUnixAudioDevices_Internal(SDL_TRUE, classic, test);
|
||||
SDL_EnumUnixAudioDevices_Internal(SDL_FALSE, classic, test);
|
||||
}
|
||||
|
||||
#endif /* Audio driver selection */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
#define OPEN_FLAGS_INPUT (O_RDONLY|O_NONBLOCK)
|
||||
#endif
|
||||
|
||||
void SDL_EnumUnixAudioDevices(int iscapture, int classic,
|
||||
int (*test) (int fd), SDL_AddAudioDevice addfn);
|
||||
extern void SDL_EnumUnixAudioDevices(const int classic, int (*test)(int));
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
@ -30,8 +30,21 @@
|
|||
typedef struct SDL_AudioDevice SDL_AudioDevice;
|
||||
#define _THIS SDL_AudioDevice *_this
|
||||
|
||||
/* Used by audio targets during DetectDevices() */
|
||||
typedef void (*SDL_AddAudioDevice)(const char *name);
|
||||
/* Audio targets should call this as devices are added to the system (such as
|
||||
a USB headset being plugged in), and should also be called for
|
||||
for every device found during DetectDevices(). */
|
||||
extern void SDL_AddAudioDevice(const int iscapture, const char *name, void *handle);
|
||||
|
||||
/* Audio targets should call this as devices are removed, so SDL can update
|
||||
its list of available devices. */
|
||||
extern void SDL_RemoveAudioDevice(const int iscapture, void *handle);
|
||||
|
||||
/* Audio targets should call this if an opened audio device is lost while
|
||||
being used. This can happen due to i/o errors, or a device being unplugged,
|
||||
etc. If the device is totally gone, please also call SDL_RemoveAudioDevice()
|
||||
as appropriate so SDL's list of devices is accurate. */
|
||||
extern void SDL_OpenedAudioDeviceDisconnected(SDL_AudioDevice *device);
|
||||
|
||||
|
||||
/* This is the size of a packet when using SDL_QueueAudio(). We allocate
|
||||
these as necessary and pool them, under the assumption that we'll
|
||||
|
@ -55,8 +68,8 @@ typedef struct SDL_AudioBufferQueue
|
|||
|
||||
typedef struct SDL_AudioDriverImpl
|
||||
{
|
||||
void (*DetectDevices) (int iscapture, SDL_AddAudioDevice addfn);
|
||||
int (*OpenDevice) (_THIS, const char *devname, int iscapture);
|
||||
void (*DetectDevices) (void);
|
||||
int (*OpenDevice) (_THIS, void *handle, const char *devname, int iscapture);
|
||||
void (*ThreadInit) (_THIS); /* Called by audio thread at start */
|
||||
void (*WaitDevice) (_THIS);
|
||||
void (*PlayDevice) (_THIS);
|
||||
|
@ -66,19 +79,34 @@ typedef struct SDL_AudioDriverImpl
|
|||
void (*CloseDevice) (_THIS);
|
||||
void (*LockDevice) (_THIS);
|
||||
void (*UnlockDevice) (_THIS);
|
||||
void (*FreeDeviceHandle) (void *handle); /**< SDL is done with handle from SDL_AddAudioDevice() */
|
||||
void (*Deinitialize) (void);
|
||||
|
||||
/* !!! FIXME: add pause(), so we can optimize instead of mixing silence. */
|
||||
|
||||
/* Some flags to push duplicate code into the core and reduce #ifdefs. */
|
||||
/* !!! FIXME: these should be SDL_bool */
|
||||
int ProvidesOwnCallbackThread;
|
||||
int SkipMixerLock; /* !!! FIXME: do we need this anymore? */
|
||||
int HasCaptureSupport;
|
||||
int OnlyHasDefaultOutputDevice;
|
||||
int OnlyHasDefaultInputDevice;
|
||||
int AllowsArbitraryDeviceNames;
|
||||
} SDL_AudioDriverImpl;
|
||||
|
||||
|
||||
typedef struct SDL_AudioDeviceItem
|
||||
{
|
||||
void *handle;
|
||||
struct SDL_AudioDeviceItem *next;
|
||||
#if (defined(__GNUC__) && (__GNUC__ <= 2))
|
||||
char name[1]; /* actually variable length. */
|
||||
#else
|
||||
char name[];
|
||||
#endif
|
||||
} SDL_AudioDeviceItem;
|
||||
|
||||
|
||||
typedef struct SDL_AudioDriver
|
||||
{
|
||||
/* * * */
|
||||
|
@ -91,11 +119,14 @@ typedef struct SDL_AudioDriver
|
|||
|
||||
SDL_AudioDriverImpl impl;
|
||||
|
||||
char **outputDevices;
|
||||
/* A mutex for device detection */
|
||||
SDL_mutex *detectionLock;
|
||||
SDL_bool captureDevicesRemoved;
|
||||
SDL_bool outputDevicesRemoved;
|
||||
int outputDeviceCount;
|
||||
|
||||
char **inputDevices;
|
||||
int inputDeviceCount;
|
||||
SDL_AudioDeviceItem *outputDevices;
|
||||
SDL_AudioDeviceItem *inputDevices;
|
||||
} SDL_AudioDriver;
|
||||
|
||||
|
||||
|
@ -113,6 +144,7 @@ struct SDL_AudioDevice
|
|||
{
|
||||
/* * * */
|
||||
/* Data common to all devices */
|
||||
SDL_AudioDeviceID id;
|
||||
|
||||
/* The current audio specification (shared with audio thread) */
|
||||
SDL_AudioSpec spec;
|
||||
|
@ -125,15 +157,17 @@ struct SDL_AudioDevice
|
|||
SDL_AudioStreamer streamer;
|
||||
|
||||
/* Current state flags */
|
||||
/* !!! FIXME: should be SDL_bool */
|
||||
int iscapture;
|
||||
int enabled;
|
||||
int enabled; /* true if device is functioning and connected. */
|
||||
int shutdown; /* true if we are signaling the play thread to end. */
|
||||
int paused;
|
||||
int opened;
|
||||
|
||||
/* Fake audio buffer for when the audio hardware is busy */
|
||||
Uint8 *fake_stream;
|
||||
|
||||
/* A semaphore for locking the mixing buffers */
|
||||
/* A mutex for locking the mixing buffers */
|
||||
SDL_mutex *mixer_lock;
|
||||
|
||||
/* A thread to feed the audio device */
|
||||
|
|
|
@ -320,7 +320,7 @@ ALSA_PlayDevice(_THIS)
|
|||
/* Hmm, not much we can do - abort */
|
||||
fprintf(stderr, "ALSA write failed (unrecoverable): %s\n",
|
||||
ALSA_snd_strerror(status));
|
||||
this->enabled = 0;
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
|
@ -465,7 +465,7 @@ ALSA_set_buffer_size(_THIS, snd_pcm_hw_params_t *params, int override)
|
|||
}
|
||||
|
||||
static int
|
||||
ALSA_OpenDevice(_THIS, const char *devname, int iscapture)
|
||||
ALSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
{
|
||||
int status = 0;
|
||||
snd_pcm_t *pcm_handle = NULL;
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
static SDL_AudioDevice* audioDevice = NULL;
|
||||
|
||||
static int
|
||||
AndroidAUD_OpenDevice(_THIS, const char *devname, int iscapture)
|
||||
AndroidAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
{
|
||||
SDL_AudioFormat test_format;
|
||||
|
||||
|
|
|
@ -151,7 +151,7 @@ ARTS_WaitDevice(_THIS)
|
|||
/* Check every 10 loops */
|
||||
if (this->hidden->parent && (((++cnt) % 10) == 0)) {
|
||||
if (kill(this->hidden->parent, 0) < 0 && errno == ESRCH) {
|
||||
this->enabled = 0;
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -179,7 +179,7 @@ ARTS_PlayDevice(_THIS)
|
|||
|
||||
/* If we couldn't write, assume fatal error for now */
|
||||
if (written < 0) {
|
||||
this->enabled = 0;
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
}
|
||||
#ifdef DEBUG_AUDIO
|
||||
fprintf(stderr, "Wrote %d bytes of audio data\n", written);
|
||||
|
@ -229,7 +229,7 @@ ARTS_Suspend(void)
|
|||
}
|
||||
|
||||
static int
|
||||
ARTS_OpenDevice(_THIS, const char *devname, int iscapture)
|
||||
ARTS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
{
|
||||
int rc = 0;
|
||||
int bits = 0, frag_spec = 0;
|
||||
|
|
|
@ -51,9 +51,9 @@
|
|||
|
||||
|
||||
static void
|
||||
BSDAUDIO_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
|
||||
BSDAUDIO_DetectDevices(void)
|
||||
{
|
||||
SDL_EnumUnixAudioDevices(iscapture, 0, NULL, addfn);
|
||||
SDL_EnumUnixAudioDevices(0, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -150,7 +150,7 @@ BSDAUDIO_WaitDevice(_THIS)
|
|||
the user know what happened.
|
||||
*/
|
||||
fprintf(stderr, "SDL: %s\n", message);
|
||||
this->enabled = 0;
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
/* Don't try to close - may hang */
|
||||
this->hidden->audio_fd = -1;
|
||||
#ifdef DEBUG_AUDIO
|
||||
|
@ -195,7 +195,7 @@ BSDAUDIO_PlayDevice(_THIS)
|
|||
|
||||
/* If we couldn't write, assume fatal error for now */
|
||||
if (written < 0) {
|
||||
this->enabled = 0;
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
}
|
||||
#ifdef DEBUG_AUDIO
|
||||
fprintf(stderr, "Wrote %d bytes of audio data\n", written);
|
||||
|
@ -224,7 +224,7 @@ BSDAUDIO_CloseDevice(_THIS)
|
|||
}
|
||||
|
||||
static int
|
||||
BSDAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
|
||||
BSDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
{
|
||||
const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT);
|
||||
SDL_AudioFormat format = 0;
|
||||
|
@ -348,6 +348,8 @@ BSDAUDIO_Init(SDL_AudioDriverImpl * impl)
|
|||
impl->GetDeviceBuf = BSDAUDIO_GetDeviceBuf;
|
||||
impl->CloseDevice = BSDAUDIO_CloseDevice;
|
||||
|
||||
impl->AllowsArbitraryDeviceNames = 1;
|
||||
|
||||
return 1; /* this audio target is available. */
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_AUDIO_DRIVER_COREAUDIO
|
||||
|
||||
#include "SDL_audio.h"
|
||||
#include "../SDL_audio_c.h"
|
||||
#include "../SDL_sysaudio.h"
|
||||
|
@ -37,31 +40,48 @@ static void COREAUDIO_CloseDevice(_THIS);
|
|||
}
|
||||
|
||||
#if MACOSX_COREAUDIO
|
||||
typedef void (*addDevFn)(const char *name, AudioDeviceID devId, void *data);
|
||||
static const AudioObjectPropertyAddress devlist_address = {
|
||||
kAudioHardwarePropertyDevices,
|
||||
kAudioObjectPropertyScopeGlobal,
|
||||
kAudioObjectPropertyElementMaster
|
||||
};
|
||||
|
||||
static void
|
||||
addToDevList(const char *name, AudioDeviceID devId, void *data)
|
||||
typedef void (*addDevFn)(const char *name, const int iscapture, AudioDeviceID devId, void *data);
|
||||
|
||||
typedef struct AudioDeviceList
|
||||
{
|
||||
SDL_AddAudioDevice addfn = (SDL_AddAudioDevice) data;
|
||||
addfn(name);
|
||||
AudioDeviceID devid;
|
||||
SDL_bool alive;
|
||||
struct AudioDeviceList *next;
|
||||
} AudioDeviceList;
|
||||
|
||||
static AudioDeviceList *output_devs = NULL;
|
||||
static AudioDeviceList *capture_devs = NULL;
|
||||
|
||||
static SDL_bool
|
||||
add_to_internal_dev_list(const int iscapture, AudioDeviceID devId)
|
||||
{
|
||||
AudioDeviceList *item = (AudioDeviceList *) SDL_malloc(sizeof (AudioDeviceList));
|
||||
if (item == NULL) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
item->devid = devId;
|
||||
item->alive = SDL_TRUE;
|
||||
item->next = iscapture ? capture_devs : output_devs;
|
||||
if (iscapture) {
|
||||
capture_devs = item;
|
||||
} else {
|
||||
output_devs = item;
|
||||
}
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char *findname;
|
||||
AudioDeviceID devId;
|
||||
int found;
|
||||
} FindDevIdData;
|
||||
|
||||
static void
|
||||
findDevId(const char *name, AudioDeviceID devId, void *_data)
|
||||
addToDevList(const char *name, const int iscapture, AudioDeviceID devId, void *data)
|
||||
{
|
||||
FindDevIdData *data = (FindDevIdData *) _data;
|
||||
if (!data->found) {
|
||||
if (SDL_strcmp(name, data->findname) == 0) {
|
||||
data->found = 1;
|
||||
data->devId = devId;
|
||||
}
|
||||
if (add_to_internal_dev_list(iscapture, devId)) {
|
||||
SDL_AddAudioDevice(iscapture, name, (void *) ((size_t) devId));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,14 +94,8 @@ build_device_list(int iscapture, addDevFn addfn, void *addfndata)
|
|||
UInt32 i = 0;
|
||||
UInt32 max = 0;
|
||||
|
||||
AudioObjectPropertyAddress addr = {
|
||||
kAudioHardwarePropertyDevices,
|
||||
kAudioObjectPropertyScopeGlobal,
|
||||
kAudioObjectPropertyElementMaster
|
||||
};
|
||||
|
||||
result = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &addr,
|
||||
0, NULL, &size);
|
||||
result = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject,
|
||||
&devlist_address, 0, NULL, &size);
|
||||
if (result != kAudioHardwareNoError)
|
||||
return;
|
||||
|
||||
|
@ -89,8 +103,8 @@ build_device_list(int iscapture, addDevFn addfn, void *addfndata)
|
|||
if (devs == NULL)
|
||||
return;
|
||||
|
||||
result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr,
|
||||
0, NULL, &size, devs);
|
||||
result = AudioObjectGetPropertyData(kAudioObjectSystemObject,
|
||||
&devlist_address, 0, NULL, &size, devs);
|
||||
if (result != kAudioHardwareNoError)
|
||||
return;
|
||||
|
||||
|
@ -102,10 +116,17 @@ build_device_list(int iscapture, addDevFn addfn, void *addfndata)
|
|||
AudioBufferList *buflist = NULL;
|
||||
int usable = 0;
|
||||
CFIndex len = 0;
|
||||
const AudioObjectPropertyAddress addr = {
|
||||
kAudioDevicePropertyStreamConfiguration,
|
||||
iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput,
|
||||
kAudioObjectPropertyElementMaster
|
||||
};
|
||||
|
||||
addr.mScope = iscapture ? kAudioDevicePropertyScopeInput :
|
||||
kAudioDevicePropertyScopeOutput;
|
||||
addr.mSelector = kAudioDevicePropertyStreamConfiguration;
|
||||
const AudioObjectPropertyAddress nameaddr = {
|
||||
kAudioObjectPropertyName,
|
||||
iscapture ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput,
|
||||
kAudioObjectPropertyElementMaster
|
||||
};
|
||||
|
||||
result = AudioObjectGetPropertyDataSize(dev, &addr, 0, NULL, &size);
|
||||
if (result != noErr)
|
||||
|
@ -133,9 +154,9 @@ build_device_list(int iscapture, addDevFn addfn, void *addfndata)
|
|||
if (!usable)
|
||||
continue;
|
||||
|
||||
addr.mSelector = kAudioObjectPropertyName;
|
||||
|
||||
size = sizeof (CFStringRef);
|
||||
result = AudioObjectGetPropertyData(dev, &addr, 0, NULL, &size, &cfstr);
|
||||
result = AudioObjectGetPropertyData(dev, &nameaddr, 0, NULL, &size, &cfstr);
|
||||
if (result != kAudioHardwareNoError)
|
||||
continue;
|
||||
|
||||
|
@ -166,79 +187,84 @@ build_device_list(int iscapture, addDevFn addfn, void *addfndata)
|
|||
((iscapture) ? "capture" : "output"),
|
||||
(int) *devCount, ptr, (int) dev);
|
||||
#endif
|
||||
addfn(ptr, dev, addfndata);
|
||||
addfn(ptr, iscapture, dev, addfndata);
|
||||
}
|
||||
SDL_free(ptr); /* addfn() would have copied the string. */
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
COREAUDIO_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
|
||||
free_audio_device_list(AudioDeviceList **list)
|
||||
{
|
||||
build_device_list(iscapture, addToDevList, addfn);
|
||||
AudioDeviceList *item = *list;
|
||||
while (item) {
|
||||
AudioDeviceList *next = item->next;
|
||||
SDL_free(item);
|
||||
item = next;
|
||||
}
|
||||
*list = NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
find_device_by_name(_THIS, const char *devname, int iscapture)
|
||||
static void
|
||||
COREAUDIO_DetectDevices(void)
|
||||
{
|
||||
AudioDeviceID devid = 0;
|
||||
OSStatus result = noErr;
|
||||
UInt32 size = 0;
|
||||
UInt32 alive = 0;
|
||||
pid_t pid = 0;
|
||||
build_device_list(SDL_TRUE, addToDevList, NULL);
|
||||
build_device_list(SDL_FALSE, addToDevList, NULL);
|
||||
}
|
||||
|
||||
AudioObjectPropertyAddress addr = {
|
||||
0,
|
||||
kAudioObjectPropertyScopeGlobal,
|
||||
kAudioObjectPropertyElementMaster
|
||||
};
|
||||
|
||||
if (devname == NULL) {
|
||||
size = sizeof (AudioDeviceID);
|
||||
addr.mSelector =
|
||||
((iscapture) ? kAudioHardwarePropertyDefaultInputDevice :
|
||||
kAudioHardwarePropertyDefaultOutputDevice);
|
||||
result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr,
|
||||
0, NULL, &size, &devid);
|
||||
CHECK_RESULT("AudioHardwareGetProperty (default device)");
|
||||
} else {
|
||||
FindDevIdData data;
|
||||
SDL_zero(data);
|
||||
data.findname = devname;
|
||||
build_device_list(iscapture, findDevId, &data);
|
||||
if (!data.found) {
|
||||
SDL_SetError("CoreAudio: No such audio device.");
|
||||
return 0;
|
||||
static void
|
||||
build_device_change_list(const char *name, const int iscapture, AudioDeviceID devId, void *data)
|
||||
{
|
||||
AudioDeviceList **list = (AudioDeviceList **) data;
|
||||
AudioDeviceList *item;
|
||||
for (item = *list; item != NULL; item = item->next) {
|
||||
if (item->devid == devId) {
|
||||
item->alive = SDL_TRUE;
|
||||
return;
|
||||
}
|
||||
devid = data.devId;
|
||||
}
|
||||
|
||||
addr.mSelector = kAudioDevicePropertyDeviceIsAlive;
|
||||
addr.mScope = iscapture ? kAudioDevicePropertyScopeInput :
|
||||
kAudioDevicePropertyScopeOutput;
|
||||
add_to_internal_dev_list(iscapture, devId); /* new device, add it. */
|
||||
SDL_AddAudioDevice(iscapture, name, (void *) ((size_t) devId));
|
||||
}
|
||||
|
||||
size = sizeof (alive);
|
||||
result = AudioObjectGetPropertyData(devid, &addr, 0, NULL, &size, &alive);
|
||||
CHECK_RESULT
|
||||
("AudioDeviceGetProperty (kAudioDevicePropertyDeviceIsAlive)");
|
||||
|
||||
if (!alive) {
|
||||
SDL_SetError("CoreAudio: requested device exists, but isn't alive.");
|
||||
return 0;
|
||||
static void
|
||||
reprocess_device_list(const int iscapture, AudioDeviceList **list)
|
||||
{
|
||||
AudioDeviceList *item;
|
||||
AudioDeviceList *prev = NULL;
|
||||
for (item = *list; item != NULL; item = item->next) {
|
||||
item->alive = SDL_FALSE;
|
||||
}
|
||||
|
||||
addr.mSelector = kAudioDevicePropertyHogMode;
|
||||
size = sizeof (pid);
|
||||
result = AudioObjectGetPropertyData(devid, &addr, 0, NULL, &size, &pid);
|
||||
build_device_list(iscapture, build_device_change_list, list);
|
||||
|
||||
/* some devices don't support this property, so errors are fine here. */
|
||||
if ((result == noErr) && (pid != -1)) {
|
||||
SDL_SetError("CoreAudio: requested device is being hogged.");
|
||||
return 0;
|
||||
/* free items in the list that aren't still alive. */
|
||||
item = *list;
|
||||
while (item != NULL) {
|
||||
AudioDeviceList *next = item->next;
|
||||
if (item->alive) {
|
||||
prev = item;
|
||||
} else {
|
||||
SDL_RemoveAudioDevice(iscapture, (void *) ((size_t) item->devid));
|
||||
if (prev) {
|
||||
prev->next = item->next;
|
||||
} else {
|
||||
*list = item->next;
|
||||
}
|
||||
SDL_free(item);
|
||||
}
|
||||
item = next;
|
||||
}
|
||||
}
|
||||
|
||||
this->hidden->deviceID = devid;
|
||||
return 1;
|
||||
/* this is called when the system's list of available audio devices changes. */
|
||||
static OSStatus
|
||||
device_list_changed(AudioObjectID systemObj, UInt32 num_addr, const AudioObjectPropertyAddress *addrs, void *data)
|
||||
{
|
||||
reprocess_device_list(SDL_TRUE, &capture_devs);
|
||||
reprocess_device_list(SDL_FALSE, &output_devs);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -314,11 +340,54 @@ inputCallback(void *inRefCon,
|
|||
}
|
||||
|
||||
|
||||
#if MACOSX_COREAUDIO
|
||||
static const AudioObjectPropertyAddress alive_address =
|
||||
{
|
||||
kAudioDevicePropertyDeviceIsAlive,
|
||||
kAudioObjectPropertyScopeGlobal,
|
||||
kAudioObjectPropertyElementMaster
|
||||
};
|
||||
|
||||
static OSStatus
|
||||
device_unplugged(AudioObjectID devid, UInt32 num_addr, const AudioObjectPropertyAddress *addrs, void *data)
|
||||
{
|
||||
SDL_AudioDevice *this = (SDL_AudioDevice *) data;
|
||||
SDL_bool dead = SDL_FALSE;
|
||||
UInt32 isAlive = 1;
|
||||
UInt32 size = sizeof (isAlive);
|
||||
OSStatus error;
|
||||
|
||||
if (!this->enabled) {
|
||||
return 0; /* already known to be dead. */
|
||||
}
|
||||
|
||||
error = AudioObjectGetPropertyData(this->hidden->deviceID, &alive_address,
|
||||
0, NULL, &size, &isAlive);
|
||||
|
||||
if (error == kAudioHardwareBadDeviceError) {
|
||||
dead = SDL_TRUE; /* device was unplugged. */
|
||||
} else if ((error == kAudioHardwareNoError) && (!isAlive)) {
|
||||
dead = SDL_TRUE; /* device died in some other way. */
|
||||
}
|
||||
|
||||
if (dead) {
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
COREAUDIO_CloseDevice(_THIS)
|
||||
{
|
||||
if (this->hidden != NULL) {
|
||||
if (this->hidden->audioUnitOpened) {
|
||||
#if MACOSX_COREAUDIO
|
||||
/* Unregister our disconnect callback. */
|
||||
AudioObjectRemovePropertyListener(this->hidden->deviceID, &alive_address, device_unplugged, this);
|
||||
#endif
|
||||
|
||||
AURenderCallbackStruct callback;
|
||||
const AudioUnitElement output_bus = 0;
|
||||
const AudioUnitElement input_bus = 1;
|
||||
|
@ -352,9 +421,63 @@ COREAUDIO_CloseDevice(_THIS)
|
|||
}
|
||||
}
|
||||
|
||||
#if MACOSX_COREAUDIO
|
||||
static int
|
||||
prepare_device(_THIS, void *handle, int iscapture)
|
||||
{
|
||||
AudioDeviceID devid = (AudioDeviceID) ((size_t) handle);
|
||||
OSStatus result = noErr;
|
||||
UInt32 size = 0;
|
||||
UInt32 alive = 0;
|
||||
pid_t pid = 0;
|
||||
|
||||
AudioObjectPropertyAddress addr = {
|
||||
0,
|
||||
kAudioObjectPropertyScopeGlobal,
|
||||
kAudioObjectPropertyElementMaster
|
||||
};
|
||||
|
||||
if (handle == NULL) {
|
||||
size = sizeof (AudioDeviceID);
|
||||
addr.mSelector =
|
||||
((iscapture) ? kAudioHardwarePropertyDefaultInputDevice :
|
||||
kAudioHardwarePropertyDefaultOutputDevice);
|
||||
result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &addr,
|
||||
0, NULL, &size, &devid);
|
||||
CHECK_RESULT("AudioHardwareGetProperty (default device)");
|
||||
}
|
||||
|
||||
addr.mSelector = kAudioDevicePropertyDeviceIsAlive;
|
||||
addr.mScope = iscapture ? kAudioDevicePropertyScopeInput :
|
||||
kAudioDevicePropertyScopeOutput;
|
||||
|
||||
size = sizeof (alive);
|
||||
result = AudioObjectGetPropertyData(devid, &addr, 0, NULL, &size, &alive);
|
||||
CHECK_RESULT
|
||||
("AudioDeviceGetProperty (kAudioDevicePropertyDeviceIsAlive)");
|
||||
|
||||
if (!alive) {
|
||||
SDL_SetError("CoreAudio: requested device exists, but isn't alive.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
addr.mSelector = kAudioDevicePropertyHogMode;
|
||||
size = sizeof (pid);
|
||||
result = AudioObjectGetPropertyData(devid, &addr, 0, NULL, &size, &pid);
|
||||
|
||||
/* some devices don't support this property, so errors are fine here. */
|
||||
if ((result == noErr) && (pid != -1)) {
|
||||
SDL_SetError("CoreAudio: requested device is being hogged.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
this->hidden->deviceID = devid;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
prepare_audiounit(_THIS, const char *devname, int iscapture,
|
||||
prepare_audiounit(_THIS, void *handle, int iscapture,
|
||||
const AudioStreamBasicDescription * strdesc)
|
||||
{
|
||||
OSStatus result = noErr;
|
||||
|
@ -373,8 +496,7 @@ prepare_audiounit(_THIS, const char *devname, int iscapture,
|
|||
kAudioUnitScope_Input);
|
||||
|
||||
#if MACOSX_COREAUDIO
|
||||
if (!find_device_by_name(this, devname, iscapture)) {
|
||||
SDL_SetError("Couldn't find requested CoreAudio device");
|
||||
if (!prepare_device(this, handle, iscapture)) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -451,13 +573,18 @@ prepare_audiounit(_THIS, const char *devname, int iscapture,
|
|||
result = AudioOutputUnitStart(this->hidden->audioUnit);
|
||||
CHECK_RESULT("AudioOutputUnitStart");
|
||||
|
||||
#if MACOSX_COREAUDIO
|
||||
/* Fire a callback if the device stops being "alive" (disconnected, etc). */
|
||||
AudioObjectAddPropertyListener(this->hidden->deviceID, &alive_address, device_unplugged, this);
|
||||
#endif
|
||||
|
||||
/* We're running! */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
COREAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
|
||||
COREAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
{
|
||||
AudioStreamBasicDescription strdesc;
|
||||
SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
|
||||
|
@ -516,7 +643,7 @@ COREAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
|
|||
strdesc.mBytesPerPacket =
|
||||
strdesc.mBytesPerFrame * strdesc.mFramesPerPacket;
|
||||
|
||||
if (!prepare_audiounit(this, devname, iscapture, &strdesc)) {
|
||||
if (!prepare_audiounit(this, handle, iscapture, &strdesc)) {
|
||||
COREAUDIO_CloseDevice(this);
|
||||
return -1; /* prepare_audiounit() will call SDL_SetError()... */
|
||||
}
|
||||
|
@ -524,15 +651,27 @@ COREAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
|
|||
return 0; /* good to go. */
|
||||
}
|
||||
|
||||
static void
|
||||
COREAUDIO_Deinitialize(void)
|
||||
{
|
||||
#if MACOSX_COREAUDIO
|
||||
AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &devlist_address, device_list_changed, NULL);
|
||||
free_audio_device_list(&capture_devs);
|
||||
free_audio_device_list(&output_devs);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
COREAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||
{
|
||||
/* Set the function pointers */
|
||||
impl->OpenDevice = COREAUDIO_OpenDevice;
|
||||
impl->CloseDevice = COREAUDIO_CloseDevice;
|
||||
impl->Deinitialize = COREAUDIO_Deinitialize;
|
||||
|
||||
#if MACOSX_COREAUDIO
|
||||
impl->DetectDevices = COREAUDIO_DetectDevices;
|
||||
AudioObjectAddPropertyListener(kAudioObjectSystemObject, &devlist_address, device_list_changed, NULL);
|
||||
#else
|
||||
impl->OnlyHasDefaultOutputDevice = 1;
|
||||
|
||||
|
@ -554,4 +693,6 @@ AudioBootStrap COREAUDIO_bootstrap = {
|
|||
"coreaudio", "CoreAudio", COREAUDIO_Init, 0
|
||||
};
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_COREAUDIO */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
@ -144,15 +144,22 @@ SetDSerror(const char *function, int code)
|
|||
return SDL_SetError("%s", errbuf);
|
||||
}
|
||||
|
||||
static void
|
||||
DSOUND_FreeDeviceHandle(void *handle)
|
||||
{
|
||||
SDL_free(handle);
|
||||
}
|
||||
|
||||
static BOOL CALLBACK
|
||||
FindAllDevs(LPGUID guid, LPCWSTR desc, LPCWSTR module, LPVOID data)
|
||||
{
|
||||
SDL_AddAudioDevice addfn = (SDL_AddAudioDevice) data;
|
||||
const int iscapture = (int) ((size_t) data);
|
||||
if (guid != NULL) { /* skip default device */
|
||||
char *str = WIN_StringToUTF8(desc);
|
||||
if (str != NULL) {
|
||||
addfn(str);
|
||||
LPGUID cpyguid = (LPGUID) SDL_malloc(sizeof (GUID));
|
||||
SDL_memcpy(cpyguid, guid, sizeof (GUID));
|
||||
SDL_AddAudioDevice(iscapture, str, cpyguid);
|
||||
SDL_free(str); /* addfn() makes a copy of this string. */
|
||||
}
|
||||
}
|
||||
|
@ -160,13 +167,10 @@ FindAllDevs(LPGUID guid, LPCWSTR desc, LPCWSTR module, LPVOID data)
|
|||
}
|
||||
|
||||
static void
|
||||
DSOUND_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
|
||||
DSOUND_DetectDevices(void)
|
||||
{
|
||||
if (iscapture) {
|
||||
pDirectSoundCaptureEnumerateW(FindAllDevs, addfn);
|
||||
} else {
|
||||
pDirectSoundEnumerateW(FindAllDevs, addfn);
|
||||
}
|
||||
pDirectSoundCaptureEnumerateW(FindAllDevs, (void *) ((size_t) 1));
|
||||
pDirectSoundEnumerateW(FindAllDevs, (void *) ((size_t) 0));
|
||||
}
|
||||
|
||||
|
||||
|
@ -419,53 +423,14 @@ CreateSecondary(_THIS, HWND focus)
|
|||
return (numchunks);
|
||||
}
|
||||
|
||||
typedef struct FindDevGUIDData
|
||||
{
|
||||
const char *devname;
|
||||
GUID guid;
|
||||
int found;
|
||||
} FindDevGUIDData;
|
||||
|
||||
static BOOL CALLBACK
|
||||
FindDevGUID(LPGUID guid, LPCWSTR desc, LPCWSTR module, LPVOID _data)
|
||||
{
|
||||
if (guid != NULL) { /* skip the default device. */
|
||||
FindDevGUIDData *data = (FindDevGUIDData *) _data;
|
||||
char *str = WIN_StringToUTF8(desc);
|
||||
const int match = (SDL_strcmp(str, data->devname) == 0);
|
||||
SDL_free(str);
|
||||
if (match) {
|
||||
data->found = 1;
|
||||
SDL_memcpy(&data->guid, guid, sizeof (data->guid));
|
||||
return FALSE; /* found it! stop enumerating. */
|
||||
}
|
||||
}
|
||||
return TRUE; /* keep enumerating. */
|
||||
}
|
||||
|
||||
static int
|
||||
DSOUND_OpenDevice(_THIS, const char *devname, int iscapture)
|
||||
DSOUND_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
{
|
||||
HRESULT result;
|
||||
SDL_bool valid_format = SDL_FALSE;
|
||||
SDL_bool tried_format = SDL_FALSE;
|
||||
SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
|
||||
FindDevGUIDData devguid;
|
||||
LPGUID guid = NULL;
|
||||
|
||||
if (devname != NULL) {
|
||||
devguid.found = 0;
|
||||
devguid.devname = devname;
|
||||
if (iscapture)
|
||||
pDirectSoundCaptureEnumerateW(FindDevGUID, &devguid);
|
||||
else
|
||||
pDirectSoundEnumerateW(FindDevGUID, &devguid);
|
||||
|
||||
if (!devguid.found) {
|
||||
return SDL_SetError("DirectSound: Requested device not found");
|
||||
}
|
||||
guid = &devguid.guid;
|
||||
}
|
||||
LPGUID guid = (LPGUID) handle;
|
||||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
this->hidden = (struct SDL_PrivateAudioData *)
|
||||
|
@ -536,6 +501,8 @@ DSOUND_Init(SDL_AudioDriverImpl * impl)
|
|||
impl->WaitDone = DSOUND_WaitDone;
|
||||
impl->GetDeviceBuf = DSOUND_GetDeviceBuf;
|
||||
impl->CloseDevice = DSOUND_CloseDevice;
|
||||
impl->FreeDeviceHandle = DSOUND_FreeDeviceHandle;
|
||||
|
||||
impl->Deinitialize = DSOUND_Deinitialize;
|
||||
|
||||
return 1; /* this audio target is available. */
|
||||
|
|
|
@ -71,7 +71,7 @@ DISKAUD_PlayDevice(_THIS)
|
|||
|
||||
/* If we couldn't write, assume fatal error for now */
|
||||
if (written != this->hidden->mixlen) {
|
||||
this->enabled = 0;
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
}
|
||||
#ifdef DEBUG_AUDIO
|
||||
fprintf(stderr, "Wrote %d bytes of audio data\n", written);
|
||||
|
@ -100,7 +100,7 @@ DISKAUD_CloseDevice(_THIS)
|
|||
}
|
||||
|
||||
static int
|
||||
DISKAUD_OpenDevice(_THIS, const char *devname, int iscapture)
|
||||
DISKAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
{
|
||||
const char *envr = SDL_getenv(DISKENVR_WRITEDELAY);
|
||||
const char *fname = DISKAUD_GetOutputFilename(devname);
|
||||
|
@ -151,6 +151,8 @@ DISKAUD_Init(SDL_AudioDriverImpl * impl)
|
|||
impl->GetDeviceBuf = DISKAUD_GetDeviceBuf;
|
||||
impl->CloseDevice = DISKAUD_CloseDevice;
|
||||
|
||||
impl->AllowsArbitraryDeviceNames = 1;
|
||||
|
||||
return 1; /* this audio target is available. */
|
||||
}
|
||||
|
||||
|
|
|
@ -51,9 +51,9 @@
|
|||
|
||||
|
||||
static void
|
||||
DSP_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
|
||||
DSP_DetectDevices(void)
|
||||
{
|
||||
SDL_EnumUnixAudioDevices(iscapture, 0, NULL, addfn);
|
||||
SDL_EnumUnixAudioDevices(0, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -74,7 +74,7 @@ DSP_CloseDevice(_THIS)
|
|||
|
||||
|
||||
static int
|
||||
DSP_OpenDevice(_THIS, const char *devname, int iscapture)
|
||||
DSP_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
{
|
||||
const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT);
|
||||
int format;
|
||||
|
@ -270,7 +270,7 @@ DSP_PlayDevice(_THIS)
|
|||
const int mixlen = this->hidden->mixlen;
|
||||
if (write(this->hidden->audio_fd, mixbuf, mixlen) == -1) {
|
||||
perror("Audio write");
|
||||
this->enabled = 0;
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
}
|
||||
#ifdef DEBUG_AUDIO
|
||||
fprintf(stderr, "Wrote %d bytes of audio data\n", mixlen);
|
||||
|
@ -293,6 +293,8 @@ DSP_Init(SDL_AudioDriverImpl * impl)
|
|||
impl->GetDeviceBuf = DSP_GetDeviceBuf;
|
||||
impl->CloseDevice = DSP_CloseDevice;
|
||||
|
||||
impl->AllowsArbitraryDeviceNames = 1;
|
||||
|
||||
return 1; /* this audio target is available. */
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "SDL_dummyaudio.h"
|
||||
|
||||
static int
|
||||
DUMMYAUD_OpenDevice(_THIS, const char *devname, int iscapture)
|
||||
DUMMYAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
{
|
||||
return 0; /* always succeeds. */
|
||||
}
|
||||
|
|
|
@ -151,12 +151,13 @@ Emscripten_CloseDevice(_THIS)
|
|||
}
|
||||
|
||||
static int
|
||||
Emscripten_OpenDevice(_THIS, const char *devname, int iscapture)
|
||||
Emscripten_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
{
|
||||
SDL_bool valid_format = SDL_FALSE;
|
||||
SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
|
||||
int i;
|
||||
float f;
|
||||
int result;
|
||||
|
||||
while ((!valid_format) && (test_format)) {
|
||||
switch (test_format) {
|
||||
|
@ -185,7 +186,7 @@ Emscripten_OpenDevice(_THIS, const char *devname, int iscapture)
|
|||
/* based on parts of library_sdl.js */
|
||||
|
||||
/* create context (TODO: this puts stuff in the global namespace...)*/
|
||||
EM_ASM({
|
||||
result = EM_ASM_INT_V({
|
||||
if(typeof(SDL2) === 'undefined')
|
||||
SDL2 = {};
|
||||
|
||||
|
@ -198,10 +199,14 @@ Emscripten_OpenDevice(_THIS, const char *devname, int iscapture)
|
|||
} else if (typeof(webkitAudioContext) !== 'undefined') {
|
||||
SDL2.audioContext = new webkitAudioContext();
|
||||
} else {
|
||||
throw 'Web Audio API is not available!';
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
if (result < 0) {
|
||||
return SDL_SetError("Web Audio API is not available!");
|
||||
}
|
||||
|
||||
/* limit to native freq */
|
||||
int sampleRate = EM_ASM_INT_V({
|
||||
|
|
|
@ -129,7 +129,7 @@ ESD_WaitDevice(_THIS)
|
|||
/* Check every 10 loops */
|
||||
if (this->hidden->parent && (((++cnt) % 10) == 0)) {
|
||||
if (kill(this->hidden->parent, 0) < 0 && errno == ESRCH) {
|
||||
this->enabled = 0;
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -161,7 +161,7 @@ ESD_PlayDevice(_THIS)
|
|||
|
||||
/* If we couldn't write, assume fatal error for now */
|
||||
if (written < 0) {
|
||||
this->enabled = 0;
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -215,7 +215,7 @@ get_progname(void)
|
|||
|
||||
|
||||
static int
|
||||
ESD_OpenDevice(_THIS, const char *devname, int iscapture)
|
||||
ESD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
{
|
||||
esd_format_t format = (ESD_STREAM | ESD_PLAY);
|
||||
SDL_AudioFormat test_format = 0;
|
||||
|
|
|
@ -143,7 +143,7 @@ SDL_FS_PlayDevice(_THIS)
|
|||
this->hidden->mixsamples);
|
||||
/* If we couldn't write, assume fatal error for now */
|
||||
if (ret) {
|
||||
this->enabled = 0;
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
}
|
||||
#ifdef DEBUG_AUDIO
|
||||
fprintf(stderr, "Wrote %d bytes of audio data\n", this->hidden->mixlen);
|
||||
|
@ -186,7 +186,7 @@ SDL_FS_CloseDevice(_THIS)
|
|||
|
||||
|
||||
static int
|
||||
SDL_FS_OpenDevice(_THIS, const char *devname, int iscapture)
|
||||
SDL_FS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
{
|
||||
int bytes;
|
||||
SDL_AudioFormat test_format = 0, format = 0;
|
||||
|
|
|
@ -111,7 +111,7 @@ UnmaskSignals(sigset_t * omask)
|
|||
|
||||
|
||||
static int
|
||||
HAIKUAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
|
||||
HAIKUAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
{
|
||||
int valid_datatype = 0;
|
||||
media_raw_audio_format format;
|
||||
|
|
|
@ -20,6 +20,9 @@
|
|||
*/
|
||||
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_AUDIO_DRIVER_NACL
|
||||
|
||||
#include "SDL_naclaudio.h"
|
||||
|
||||
#include "SDL_audio.h"
|
||||
|
@ -40,7 +43,7 @@
|
|||
#define SAMPLE_FRAME_COUNT 4096
|
||||
|
||||
/* Audio driver functions */
|
||||
static int NACLAUD_OpenDevice(_THIS, const char *devname, int iscapture);
|
||||
static int NACLAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture);
|
||||
static void NACLAUD_CloseDevice(_THIS);
|
||||
static void nacl_audio_callback(void* samples, uint32_t buffer_size, PP_TimeDelta latency, void* data);
|
||||
|
||||
|
@ -82,7 +85,7 @@ static void NACLAUD_CloseDevice(SDL_AudioDevice *device) {
|
|||
}
|
||||
|
||||
static int
|
||||
NACLAUD_OpenDevice(_THIS, const char *devname, int iscapture) {
|
||||
NACLAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture) {
|
||||
PP_Instance instance = PSGetInstanceId();
|
||||
const PPB_Audio *ppb_audio = PSInterfaceAudio();
|
||||
const PPB_AudioConfig *ppb_audiocfg = PSInterfaceAudioConfig();
|
||||
|
@ -127,9 +130,7 @@ NACLAUD_Init(SDL_AudioDriverImpl * impl)
|
|||
/* Set the function pointers */
|
||||
impl->OpenDevice = NACLAUD_OpenDevice;
|
||||
impl->CloseDevice = NACLAUD_CloseDevice;
|
||||
impl->HasCaptureSupport = 0;
|
||||
impl->OnlyHasDefaultOutputDevice = 1;
|
||||
impl->OnlyHasDefaultInputDevice = 1;
|
||||
impl->ProvidesOwnCallbackThread = 1;
|
||||
/*
|
||||
* impl->WaitDevice = NACLAUD_WaitDevice;
|
||||
|
@ -145,3 +146,7 @@ AudioBootStrap NACLAUD_bootstrap = {
|
|||
NACLAUD_DRIVER_NAME, "SDL NaCl Audio Driver",
|
||||
NACLAUD_Init, 0
|
||||
};
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_NACL */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
@ -276,7 +276,7 @@ find_device(_THIS, int nch)
|
|||
}
|
||||
|
||||
static int
|
||||
NAS_OpenDevice(_THIS, const char *devname, int iscapture)
|
||||
NAS_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
{
|
||||
AuElement elms[3];
|
||||
int buffer_size;
|
||||
|
|
|
@ -176,7 +176,7 @@ PAUDIO_WaitDevice(_THIS)
|
|||
* the user know what happened.
|
||||
*/
|
||||
fprintf(stderr, "SDL: %s - %s\n", strerror(errno), message);
|
||||
this->enabled = 0;
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
/* Don't try to close - may hang */
|
||||
this->hidden->audio_fd = -1;
|
||||
#ifdef DEBUG_AUDIO
|
||||
|
@ -212,7 +212,7 @@ PAUDIO_PlayDevice(_THIS)
|
|||
|
||||
/* If we couldn't write, assume fatal error for now */
|
||||
if (written < 0) {
|
||||
this->enabled = 0;
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
}
|
||||
#ifdef DEBUG_AUDIO
|
||||
fprintf(stderr, "Wrote %d bytes of audio data\n", written);
|
||||
|
@ -241,7 +241,7 @@ PAUDIO_CloseDevice(_THIS)
|
|||
}
|
||||
|
||||
static int
|
||||
PAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
|
||||
PAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
{
|
||||
const char *workaround = SDL_getenv("SDL_DSP_NOSELECT");
|
||||
char audiodev[1024];
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_AUDIO_DRIVER_PSP
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -40,7 +43,7 @@
|
|||
#define PSPAUD_DRIVER_NAME "psp"
|
||||
|
||||
static int
|
||||
PSPAUD_OpenDevice(_THIS, const char *devname, int iscapture)
|
||||
PSPAUD_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
{
|
||||
int format, mixlen, i;
|
||||
this->hidden = (struct SDL_PrivateAudioData *)
|
||||
|
@ -191,5 +194,6 @@ AudioBootStrap PSPAUD_bootstrap = {
|
|||
|
||||
/* SDL_AUDI */
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_PSP */
|
||||
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
#include "../SDL_sysaudio.h"
|
||||
|
||||
/* Hidden "this" pointer for the video functions */
|
||||
/* Hidden "this" pointer for the audio functions */
|
||||
#define _THIS SDL_AudioDevice *this
|
||||
|
||||
#define NUM_BUFFERS 2
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
Stéphan Kochen: stephan .a.t. kochen.nl
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
#include "SDL_assert.h"
|
||||
|
||||
#if SDL_AUDIO_DRIVER_PULSEAUDIO
|
||||
|
||||
|
@ -38,7 +39,6 @@
|
|||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <pulse/pulseaudio.h>
|
||||
#include <pulse/simple.h>
|
||||
|
||||
#include "SDL_timer.h"
|
||||
#include "SDL_audio.h"
|
||||
|
@ -66,16 +66,14 @@ static SDL_INLINE int PA_STREAM_IS_GOOD(pa_stream_state_t x) {
|
|||
|
||||
|
||||
static const char *(*PULSEAUDIO_pa_get_library_version) (void);
|
||||
static pa_simple *(*PULSEAUDIO_pa_simple_new) (const char *, const char *,
|
||||
pa_stream_direction_t, const char *, const char *, const pa_sample_spec *,
|
||||
const pa_channel_map *, const pa_buffer_attr *, int *);
|
||||
static void (*PULSEAUDIO_pa_simple_free) (pa_simple *);
|
||||
static pa_channel_map *(*PULSEAUDIO_pa_channel_map_init_auto) (
|
||||
pa_channel_map *, unsigned, pa_channel_map_def_t);
|
||||
static const char * (*PULSEAUDIO_pa_strerror) (int);
|
||||
static pa_mainloop * (*PULSEAUDIO_pa_mainloop_new) (void);
|
||||
static pa_mainloop_api * (*PULSEAUDIO_pa_mainloop_get_api) (pa_mainloop *);
|
||||
static int (*PULSEAUDIO_pa_mainloop_iterate) (pa_mainloop *, int, int *);
|
||||
static int (*PULSEAUDIO_pa_mainloop_run) (pa_mainloop *, int *);
|
||||
static void (*PULSEAUDIO_pa_mainloop_quit) (pa_mainloop *, int);
|
||||
static void (*PULSEAUDIO_pa_mainloop_free) (pa_mainloop *);
|
||||
|
||||
static pa_operation_state_t (*PULSEAUDIO_pa_operation_get_state) (
|
||||
|
@ -87,7 +85,13 @@ static pa_context * (*PULSEAUDIO_pa_context_new) (pa_mainloop_api *,
|
|||
const char *);
|
||||
static int (*PULSEAUDIO_pa_context_connect) (pa_context *, const char *,
|
||||
pa_context_flags_t, const pa_spawn_api *);
|
||||
static pa_operation * (*PULSEAUDIO_pa_context_get_sink_info_list) (pa_context *, pa_sink_info_cb_t, void *);
|
||||
static pa_operation * (*PULSEAUDIO_pa_context_get_source_info_list) (pa_context *, pa_source_info_cb_t, void *);
|
||||
static pa_operation * (*PULSEAUDIO_pa_context_get_sink_info_by_index) (pa_context *, uint32_t, pa_sink_info_cb_t, void *);
|
||||
static pa_operation * (*PULSEAUDIO_pa_context_get_source_info_by_index) (pa_context *, uint32_t, pa_source_info_cb_t, void *);
|
||||
static pa_context_state_t (*PULSEAUDIO_pa_context_get_state) (pa_context *);
|
||||
static pa_operation * (*PULSEAUDIO_pa_context_subscribe) (pa_context *, pa_subscription_mask_t, pa_context_success_cb_t, void *);
|
||||
static void (*PULSEAUDIO_pa_context_set_subscribe_callback) (pa_context *, pa_context_subscribe_cb_t, void *);
|
||||
static void (*PULSEAUDIO_pa_context_disconnect) (pa_context *);
|
||||
static void (*PULSEAUDIO_pa_context_unref) (pa_context *);
|
||||
|
||||
|
@ -179,18 +183,24 @@ static int
|
|||
load_pulseaudio_syms(void)
|
||||
{
|
||||
SDL_PULSEAUDIO_SYM(pa_get_library_version);
|
||||
SDL_PULSEAUDIO_SYM(pa_simple_new);
|
||||
SDL_PULSEAUDIO_SYM(pa_simple_free);
|
||||
SDL_PULSEAUDIO_SYM(pa_mainloop_new);
|
||||
SDL_PULSEAUDIO_SYM(pa_mainloop_get_api);
|
||||
SDL_PULSEAUDIO_SYM(pa_mainloop_iterate);
|
||||
SDL_PULSEAUDIO_SYM(pa_mainloop_run);
|
||||
SDL_PULSEAUDIO_SYM(pa_mainloop_quit);
|
||||
SDL_PULSEAUDIO_SYM(pa_mainloop_free);
|
||||
SDL_PULSEAUDIO_SYM(pa_operation_get_state);
|
||||
SDL_PULSEAUDIO_SYM(pa_operation_cancel);
|
||||
SDL_PULSEAUDIO_SYM(pa_operation_unref);
|
||||
SDL_PULSEAUDIO_SYM(pa_context_new);
|
||||
SDL_PULSEAUDIO_SYM(pa_context_connect);
|
||||
SDL_PULSEAUDIO_SYM(pa_context_get_sink_info_list);
|
||||
SDL_PULSEAUDIO_SYM(pa_context_get_source_info_list);
|
||||
SDL_PULSEAUDIO_SYM(pa_context_get_sink_info_by_index);
|
||||
SDL_PULSEAUDIO_SYM(pa_context_get_source_info_by_index);
|
||||
SDL_PULSEAUDIO_SYM(pa_context_get_state);
|
||||
SDL_PULSEAUDIO_SYM(pa_context_subscribe);
|
||||
SDL_PULSEAUDIO_SYM(pa_context_set_subscribe_callback);
|
||||
SDL_PULSEAUDIO_SYM(pa_context_disconnect);
|
||||
SDL_PULSEAUDIO_SYM(pa_context_unref);
|
||||
SDL_PULSEAUDIO_SYM(pa_stream_new);
|
||||
|
@ -206,122 +216,6 @@ load_pulseaudio_syms(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Check to see if we can connect to PulseAudio */
|
||||
static SDL_bool
|
||||
CheckPulseAudioAvailable()
|
||||
{
|
||||
pa_simple *s;
|
||||
pa_sample_spec ss;
|
||||
|
||||
ss.format = PA_SAMPLE_S16NE;
|
||||
ss.channels = 1;
|
||||
ss.rate = 22050;
|
||||
|
||||
s = PULSEAUDIO_pa_simple_new(NULL, "SDL", PA_STREAM_PLAYBACK, NULL,
|
||||
"Test", &ss, NULL, NULL, NULL);
|
||||
if (s) {
|
||||
PULSEAUDIO_pa_simple_free(s);
|
||||
return SDL_TRUE;
|
||||
} else {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* This function waits until it is possible to write a full sound buffer */
|
||||
static void
|
||||
PULSEAUDIO_WaitDevice(_THIS)
|
||||
{
|
||||
struct SDL_PrivateAudioData *h = this->hidden;
|
||||
|
||||
while(1) {
|
||||
if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY ||
|
||||
PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY ||
|
||||
PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
|
||||
this->enabled = 0;
|
||||
return;
|
||||
}
|
||||
if (PULSEAUDIO_pa_stream_writable_size(h->stream) >= h->mixlen) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
PULSEAUDIO_PlayDevice(_THIS)
|
||||
{
|
||||
/* Write the audio data */
|
||||
struct SDL_PrivateAudioData *h = this->hidden;
|
||||
if (PULSEAUDIO_pa_stream_write(h->stream, h->mixbuf, h->mixlen, NULL, 0LL,
|
||||
PA_SEEK_RELATIVE) < 0) {
|
||||
this->enabled = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
stream_drain_complete(pa_stream *s, int success, void *userdata)
|
||||
{
|
||||
/* no-op for pa_stream_drain() to use for callback. */
|
||||
}
|
||||
|
||||
static void
|
||||
PULSEAUDIO_WaitDone(_THIS)
|
||||
{
|
||||
struct SDL_PrivateAudioData *h = this->hidden;
|
||||
pa_operation *o;
|
||||
|
||||
o = PULSEAUDIO_pa_stream_drain(h->stream, stream_drain_complete, NULL);
|
||||
if (!o) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (PULSEAUDIO_pa_operation_get_state(o) != PA_OPERATION_DONE) {
|
||||
if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY ||
|
||||
PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY ||
|
||||
PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
|
||||
PULSEAUDIO_pa_operation_cancel(o);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
PULSEAUDIO_pa_operation_unref(o);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static Uint8 *
|
||||
PULSEAUDIO_GetDeviceBuf(_THIS)
|
||||
{
|
||||
return (this->hidden->mixbuf);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
PULSEAUDIO_CloseDevice(_THIS)
|
||||
{
|
||||
if (this->hidden != NULL) {
|
||||
SDL_FreeAudioMem(this->hidden->mixbuf);
|
||||
this->hidden->mixbuf = NULL;
|
||||
if (this->hidden->stream) {
|
||||
PULSEAUDIO_pa_stream_disconnect(this->hidden->stream);
|
||||
PULSEAUDIO_pa_stream_unref(this->hidden->stream);
|
||||
this->hidden->stream = NULL;
|
||||
}
|
||||
if (this->hidden->context != NULL) {
|
||||
PULSEAUDIO_pa_context_disconnect(this->hidden->context);
|
||||
PULSEAUDIO_pa_context_unref(this->hidden->context);
|
||||
this->hidden->context = NULL;
|
||||
}
|
||||
if (this->hidden->mainloop != NULL) {
|
||||
PULSEAUDIO_pa_mainloop_free(this->hidden->mainloop);
|
||||
this->hidden->mainloop = NULL;
|
||||
}
|
||||
SDL_free(this->hidden);
|
||||
this->hidden = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static SDL_INLINE int
|
||||
squashVersion(const int major, const int minor, const int patch)
|
||||
{
|
||||
|
@ -344,8 +238,193 @@ getAppName(void)
|
|||
return "SDL Application"; /* oh well. */
|
||||
}
|
||||
|
||||
static void
|
||||
WaitForPulseOperation(pa_mainloop *mainloop, pa_operation *o)
|
||||
{
|
||||
/* This checks for NO errors currently. Either fix that, check results elsewhere, or do things you don't care about. */
|
||||
if (mainloop && o) {
|
||||
SDL_bool okay = SDL_TRUE;
|
||||
while (okay && (PULSEAUDIO_pa_operation_get_state(o) == PA_OPERATION_RUNNING)) {
|
||||
okay = (PULSEAUDIO_pa_mainloop_iterate(mainloop, 1, NULL) >= 0);
|
||||
}
|
||||
PULSEAUDIO_pa_operation_unref(o);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
DisconnectFromPulseServer(pa_mainloop *mainloop, pa_context *context)
|
||||
{
|
||||
if (context) {
|
||||
PULSEAUDIO_pa_context_disconnect(context);
|
||||
PULSEAUDIO_pa_context_unref(context);
|
||||
}
|
||||
if (mainloop != NULL) {
|
||||
PULSEAUDIO_pa_mainloop_free(mainloop);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
PULSEAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
|
||||
ConnectToPulseServer_Internal(pa_mainloop **_mainloop, pa_context **_context)
|
||||
{
|
||||
pa_mainloop *mainloop = NULL;
|
||||
pa_context *context = NULL;
|
||||
pa_mainloop_api *mainloop_api = NULL;
|
||||
int state = 0;
|
||||
|
||||
*_mainloop = NULL;
|
||||
*_context = NULL;
|
||||
|
||||
/* Set up a new main loop */
|
||||
if (!(mainloop = PULSEAUDIO_pa_mainloop_new())) {
|
||||
return SDL_SetError("pa_mainloop_new() failed");
|
||||
}
|
||||
|
||||
*_mainloop = mainloop;
|
||||
|
||||
mainloop_api = PULSEAUDIO_pa_mainloop_get_api(mainloop);
|
||||
SDL_assert(mainloop_api); /* this never fails, right? */
|
||||
|
||||
context = PULSEAUDIO_pa_context_new(mainloop_api, getAppName());
|
||||
if (!context) {
|
||||
return SDL_SetError("pa_context_new() failed");
|
||||
}
|
||||
*_context = context;
|
||||
|
||||
/* Connect to the PulseAudio server */
|
||||
if (PULSEAUDIO_pa_context_connect(context, NULL, 0, NULL) < 0) {
|
||||
return SDL_SetError("Could not setup connection to PulseAudio");
|
||||
}
|
||||
|
||||
do {
|
||||
if (PULSEAUDIO_pa_mainloop_iterate(mainloop, 1, NULL) < 0) {
|
||||
return SDL_SetError("pa_mainloop_iterate() failed");
|
||||
}
|
||||
state = PULSEAUDIO_pa_context_get_state(context);
|
||||
if (!PA_CONTEXT_IS_GOOD(state)) {
|
||||
return SDL_SetError("Could not connect to PulseAudio");
|
||||
}
|
||||
} while (state != PA_CONTEXT_READY);
|
||||
|
||||
return 0; /* connected and ready! */
|
||||
}
|
||||
|
||||
static int
|
||||
ConnectToPulseServer(pa_mainloop **_mainloop, pa_context **_context)
|
||||
{
|
||||
const int retval = ConnectToPulseServer_Internal(_mainloop, _context);
|
||||
if (retval < 0) {
|
||||
DisconnectFromPulseServer(*_mainloop, *_context);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/* This function waits until it is possible to write a full sound buffer */
|
||||
static void
|
||||
PULSEAUDIO_WaitDevice(_THIS)
|
||||
{
|
||||
struct SDL_PrivateAudioData *h = this->hidden;
|
||||
|
||||
while (this->enabled) {
|
||||
if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY ||
|
||||
PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY ||
|
||||
PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
return;
|
||||
}
|
||||
if (PULSEAUDIO_pa_stream_writable_size(h->stream) >= h->mixlen) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
PULSEAUDIO_PlayDevice(_THIS)
|
||||
{
|
||||
/* Write the audio data */
|
||||
struct SDL_PrivateAudioData *h = this->hidden;
|
||||
if (this->enabled) {
|
||||
if (PULSEAUDIO_pa_stream_write(h->stream, h->mixbuf, h->mixlen, NULL, 0LL, PA_SEEK_RELATIVE) < 0) {
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
stream_drain_complete(pa_stream *s, int success, void *userdata)
|
||||
{
|
||||
/* no-op for pa_stream_drain() to use for callback. */
|
||||
}
|
||||
|
||||
static void
|
||||
PULSEAUDIO_WaitDone(_THIS)
|
||||
{
|
||||
if (this->enabled) {
|
||||
struct SDL_PrivateAudioData *h = this->hidden;
|
||||
pa_operation *o = PULSEAUDIO_pa_stream_drain(h->stream, stream_drain_complete, NULL);
|
||||
if (o) {
|
||||
while (PULSEAUDIO_pa_operation_get_state(o) != PA_OPERATION_DONE) {
|
||||
if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY ||
|
||||
PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY ||
|
||||
PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
|
||||
PULSEAUDIO_pa_operation_cancel(o);
|
||||
break;
|
||||
}
|
||||
}
|
||||
PULSEAUDIO_pa_operation_unref(o);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static Uint8 *
|
||||
PULSEAUDIO_GetDeviceBuf(_THIS)
|
||||
{
|
||||
return (this->hidden->mixbuf);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
PULSEAUDIO_CloseDevice(_THIS)
|
||||
{
|
||||
if (this->hidden != NULL) {
|
||||
SDL_FreeAudioMem(this->hidden->mixbuf);
|
||||
SDL_free(this->hidden->device_name);
|
||||
if (this->hidden->stream) {
|
||||
PULSEAUDIO_pa_stream_disconnect(this->hidden->stream);
|
||||
PULSEAUDIO_pa_stream_unref(this->hidden->stream);
|
||||
}
|
||||
DisconnectFromPulseServer(this->hidden->mainloop, this->hidden->context);
|
||||
SDL_free(this->hidden);
|
||||
this->hidden = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
DeviceNameCallback(pa_context *c, const pa_sink_info *i, int is_last, void *data)
|
||||
{
|
||||
if (i) {
|
||||
char **devname = (char **) data;
|
||||
*devname = SDL_strdup(i->name);
|
||||
}
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
FindDeviceName(struct SDL_PrivateAudioData *h, void *handle)
|
||||
{
|
||||
const uint32_t idx = ((uint32_t) ((size_t) handle)) - 1;
|
||||
|
||||
if (handle == NULL) { /* NULL == default device. */
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
WaitForPulseOperation(h->mainloop, PULSEAUDIO_pa_context_get_sink_info_by_index(h->context, idx, DeviceNameCallback, &h->device_name));
|
||||
return (h->device_name != NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
PULSEAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
{
|
||||
struct SDL_PrivateAudioData *h = NULL;
|
||||
Uint16 test_format = 0;
|
||||
|
@ -442,42 +521,21 @@ PULSEAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
|
|||
paattr.minreq = h->mixlen;
|
||||
#endif
|
||||
|
||||
if (ConnectToPulseServer(&h->mainloop, &h->context) < 0) {
|
||||
PULSEAUDIO_CloseDevice(this);
|
||||
return SDL_SetError("Could not connect to PulseAudio server");
|
||||
}
|
||||
|
||||
if (!FindDeviceName(h, handle)) {
|
||||
PULSEAUDIO_CloseDevice(this);
|
||||
return SDL_SetError("Requested PulseAudio sink missing?");
|
||||
}
|
||||
|
||||
/* The SDL ALSA output hints us that we use Windows' channel mapping */
|
||||
/* http://bugzilla.libsdl.org/show_bug.cgi?id=110 */
|
||||
PULSEAUDIO_pa_channel_map_init_auto(&pacmap, this->spec.channels,
|
||||
PA_CHANNEL_MAP_WAVEEX);
|
||||
|
||||
/* Set up a new main loop */
|
||||
if (!(h->mainloop = PULSEAUDIO_pa_mainloop_new())) {
|
||||
PULSEAUDIO_CloseDevice(this);
|
||||
return SDL_SetError("pa_mainloop_new() failed");
|
||||
}
|
||||
|
||||
h->mainloop_api = PULSEAUDIO_pa_mainloop_get_api(h->mainloop);
|
||||
h->context = PULSEAUDIO_pa_context_new(h->mainloop_api, getAppName());
|
||||
if (!h->context) {
|
||||
PULSEAUDIO_CloseDevice(this);
|
||||
return SDL_SetError("pa_context_new() failed");
|
||||
}
|
||||
|
||||
/* Connect to the PulseAudio server */
|
||||
if (PULSEAUDIO_pa_context_connect(h->context, NULL, 0, NULL) < 0) {
|
||||
PULSEAUDIO_CloseDevice(this);
|
||||
return SDL_SetError("Could not setup connection to PulseAudio");
|
||||
}
|
||||
|
||||
do {
|
||||
if (PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
|
||||
PULSEAUDIO_CloseDevice(this);
|
||||
return SDL_SetError("pa_mainloop_iterate() failed");
|
||||
}
|
||||
state = PULSEAUDIO_pa_context_get_state(h->context);
|
||||
if (!PA_CONTEXT_IS_GOOD(state)) {
|
||||
PULSEAUDIO_CloseDevice(this);
|
||||
return SDL_SetError("Could not connect to PulseAudio");
|
||||
}
|
||||
} while (state != PA_CONTEXT_READY);
|
||||
|
||||
h->stream = PULSEAUDIO_pa_stream_new(
|
||||
h->context,
|
||||
"Simple DirectMedia Layer", /* stream description */
|
||||
|
@ -490,7 +548,13 @@ PULSEAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
|
|||
return SDL_SetError("Could not set up PulseAudio stream");
|
||||
}
|
||||
|
||||
if (PULSEAUDIO_pa_stream_connect_playback(h->stream, NULL, &paattr, flags,
|
||||
/* now that we have multi-device support, don't move a stream from
|
||||
a device that was unplugged to something else, unless we're default. */
|
||||
if (h->device_name != NULL) {
|
||||
flags |= PA_STREAM_DONT_MOVE;
|
||||
}
|
||||
|
||||
if (PULSEAUDIO_pa_stream_connect_playback(h->stream, h->device_name, &paattr, flags,
|
||||
NULL, NULL) < 0) {
|
||||
PULSEAUDIO_CloseDevice(this);
|
||||
return SDL_SetError("Could not connect PulseAudio stream");
|
||||
|
@ -504,7 +568,7 @@ PULSEAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
|
|||
state = PULSEAUDIO_pa_stream_get_state(h->stream);
|
||||
if (!PA_STREAM_IS_GOOD(state)) {
|
||||
PULSEAUDIO_CloseDevice(this);
|
||||
return SDL_SetError("Could not create to PulseAudio stream");
|
||||
return SDL_SetError("Could not connect PulseAudio stream");
|
||||
}
|
||||
} while (state != PA_STREAM_READY);
|
||||
|
||||
|
@ -512,10 +576,92 @@ PULSEAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static pa_mainloop *hotplug_mainloop = NULL;
|
||||
static pa_context *hotplug_context = NULL;
|
||||
static SDL_Thread *hotplug_thread = NULL;
|
||||
|
||||
/* device handles are device index + 1, cast to void*, so we never pass a NULL. */
|
||||
|
||||
/* This is called when PulseAudio adds an output ("sink") device. */
|
||||
static void
|
||||
SinkInfoCallback(pa_context *c, const pa_sink_info *i, int is_last, void *data)
|
||||
{
|
||||
if (i) {
|
||||
SDL_AddAudioDevice(SDL_FALSE, i->description, (void *) ((size_t) i->index+1));
|
||||
}
|
||||
}
|
||||
|
||||
/* This is called when PulseAudio adds a capture ("source") device. */
|
||||
static void
|
||||
SourceInfoCallback(pa_context *c, const pa_source_info *i, int is_last, void *data)
|
||||
{
|
||||
if (i) {
|
||||
/* Skip "monitor" sources. These are just output from other sinks. */
|
||||
if (i->monitor_of_sink == PA_INVALID_INDEX) {
|
||||
SDL_AddAudioDevice(SDL_TRUE, i->description, (void *) ((size_t) i->index+1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* This is called when PulseAudio has a device connected/removed/changed. */
|
||||
static void
|
||||
HotplugCallback(pa_context *c, pa_subscription_event_type_t t, uint32_t idx, void *data)
|
||||
{
|
||||
const SDL_bool added = ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW);
|
||||
const SDL_bool removed = ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE);
|
||||
|
||||
if (added || removed) { /* we only care about add/remove events. */
|
||||
const SDL_bool sink = ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK);
|
||||
const SDL_bool source = ((t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SOURCE);
|
||||
|
||||
/* adds need sink details from the PulseAudio server. Another callback... */
|
||||
if (added && sink) {
|
||||
PULSEAUDIO_pa_context_get_sink_info_by_index(hotplug_context, idx, SinkInfoCallback, NULL);
|
||||
} else if (added && source) {
|
||||
PULSEAUDIO_pa_context_get_source_info_by_index(hotplug_context, idx, SourceInfoCallback, NULL);
|
||||
} else if (removed && (sink || source)) {
|
||||
/* removes we can handle just with the device index. */
|
||||
SDL_RemoveAudioDevice(source != 0, (void *) ((size_t) idx+1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* this runs as a thread while the Pulse target is initialized to catch hotplug events. */
|
||||
static int SDLCALL
|
||||
HotplugThread(void *data)
|
||||
{
|
||||
pa_operation *o;
|
||||
SDL_SetThreadPriority(SDL_THREAD_PRIORITY_LOW);
|
||||
PULSEAUDIO_pa_context_set_subscribe_callback(hotplug_context, HotplugCallback, NULL);
|
||||
o = PULSEAUDIO_pa_context_subscribe(hotplug_context, PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SOURCE, NULL, NULL);
|
||||
PULSEAUDIO_pa_operation_unref(o); /* don't wait for it, just do our thing. */
|
||||
PULSEAUDIO_pa_mainloop_run(hotplug_mainloop, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
PULSEAUDIO_DetectDevices()
|
||||
{
|
||||
WaitForPulseOperation(hotplug_mainloop, PULSEAUDIO_pa_context_get_sink_info_list(hotplug_context, SinkInfoCallback, NULL));
|
||||
WaitForPulseOperation(hotplug_mainloop, PULSEAUDIO_pa_context_get_source_info_list(hotplug_context, SourceInfoCallback, NULL));
|
||||
|
||||
/* ok, we have a sane list, let's set up hotplug notifications now... */
|
||||
hotplug_thread = SDL_CreateThread(HotplugThread, "PulseHotplug", NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
PULSEAUDIO_Deinitialize(void)
|
||||
{
|
||||
if (hotplug_thread) {
|
||||
PULSEAUDIO_pa_mainloop_quit(hotplug_mainloop, 0);
|
||||
SDL_WaitThread(hotplug_thread, NULL);
|
||||
hotplug_thread = NULL;
|
||||
}
|
||||
|
||||
DisconnectFromPulseServer(hotplug_mainloop, hotplug_context);
|
||||
hotplug_mainloop = NULL;
|
||||
hotplug_context = NULL;
|
||||
|
||||
UnloadPulseAudioLibrary();
|
||||
}
|
||||
|
||||
|
@ -526,12 +672,13 @@ PULSEAUDIO_Init(SDL_AudioDriverImpl * impl)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (!CheckPulseAudioAvailable()) {
|
||||
if (ConnectToPulseServer(&hotplug_mainloop, &hotplug_context) < 0) {
|
||||
UnloadPulseAudioLibrary();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set the function pointers */
|
||||
impl->DetectDevices = PULSEAUDIO_DetectDevices;
|
||||
impl->OpenDevice = PULSEAUDIO_OpenDevice;
|
||||
impl->PlayDevice = PULSEAUDIO_PlayDevice;
|
||||
impl->WaitDevice = PULSEAUDIO_WaitDevice;
|
||||
|
@ -539,12 +686,10 @@ PULSEAUDIO_Init(SDL_AudioDriverImpl * impl)
|
|||
impl->CloseDevice = PULSEAUDIO_CloseDevice;
|
||||
impl->WaitDone = PULSEAUDIO_WaitDone;
|
||||
impl->Deinitialize = PULSEAUDIO_Deinitialize;
|
||||
impl->OnlyHasDefaultOutputDevice = 1;
|
||||
|
||||
return 1; /* this audio target is available. */
|
||||
}
|
||||
|
||||
|
||||
AudioBootStrap PULSEAUDIO_bootstrap = {
|
||||
"pulseaudio", "PulseAudio", PULSEAUDIO_Init, 0
|
||||
};
|
||||
|
|
|
@ -32,9 +32,10 @@
|
|||
|
||||
struct SDL_PrivateAudioData
|
||||
{
|
||||
char *device_name;
|
||||
|
||||
/* pulseaudio structures */
|
||||
pa_mainloop *mainloop;
|
||||
pa_mainloop_api *mainloop_api;
|
||||
pa_context *context;
|
||||
pa_stream *stream;
|
||||
|
||||
|
|
|
@ -19,6 +19,15 @@
|
|||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
/*
|
||||
* !!! FIXME: streamline this a little by removing all the
|
||||
* !!! FIXME: if (capture) {} else {} sections that are identical
|
||||
* !!! FIXME: except for one flag.
|
||||
*/
|
||||
|
||||
/* !!! FIXME: can this target support hotplugging? */
|
||||
/* !!! FIXME: ...does SDL2 even support QNX? */
|
||||
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_AUDIO_DRIVER_QSA
|
||||
|
@ -300,7 +309,7 @@ QSA_PlayDevice(_THIS)
|
|||
|
||||
/* If we couldn't write, assume fatal error for now */
|
||||
if (towrite != 0) {
|
||||
this->enabled = 0;
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -337,8 +346,9 @@ QSA_CloseDevice(_THIS)
|
|||
}
|
||||
|
||||
static int
|
||||
QSA_OpenDevice(_THIS, const char *devname, int iscapture)
|
||||
QSA_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
{
|
||||
const QSA_Device *device = (const QSA_Device *) handle;
|
||||
int status = 0;
|
||||
int format = 0;
|
||||
SDL_AudioFormat test_format = 0;
|
||||
|
@ -363,80 +373,19 @@ QSA_OpenDevice(_THIS, const char *devname, int iscapture)
|
|||
/* Initialize channel direction: capture or playback */
|
||||
this->hidden->iscapture = iscapture;
|
||||
|
||||
/* Find deviceid and cardid by device name for playback */
|
||||
if ((!this->hidden->iscapture) && (devname != NULL)) {
|
||||
uint32_t device;
|
||||
int32_t status;
|
||||
|
||||
/* Search in the playback devices */
|
||||
device = 0;
|
||||
do {
|
||||
status = SDL_strcmp(qsa_playback_device[device].name, devname);
|
||||
if (status == 0) {
|
||||
/* Found requested device */
|
||||
this->hidden->deviceno = qsa_playback_device[device].deviceno;
|
||||
this->hidden->cardno = qsa_playback_device[device].cardno;
|
||||
break;
|
||||
}
|
||||
device++;
|
||||
if (device >= qsa_playback_devices) {
|
||||
QSA_CloseDevice(this);
|
||||
return SDL_SetError("No such playback device");
|
||||
}
|
||||
} while (1);
|
||||
}
|
||||
|
||||
/* Find deviceid and cardid by device name for capture */
|
||||
if ((this->hidden->iscapture) && (devname != NULL)) {
|
||||
/* Search in the capture devices */
|
||||
uint32_t device;
|
||||
int32_t status;
|
||||
|
||||
/* Searching in the playback devices */
|
||||
device = 0;
|
||||
do {
|
||||
status = SDL_strcmp(qsa_capture_device[device].name, devname);
|
||||
if (status == 0) {
|
||||
/* Found requested device */
|
||||
this->hidden->deviceno = qsa_capture_device[device].deviceno;
|
||||
this->hidden->cardno = qsa_capture_device[device].cardno;
|
||||
break;
|
||||
}
|
||||
device++;
|
||||
if (device >= qsa_capture_devices) {
|
||||
QSA_CloseDevice(this);
|
||||
return SDL_SetError("No such capture device");
|
||||
}
|
||||
} while (1);
|
||||
}
|
||||
|
||||
/* Check if SDL requested default audio device */
|
||||
if (devname == NULL) {
|
||||
/* Open system default audio device */
|
||||
if (!this->hidden->iscapture) {
|
||||
status = snd_pcm_open_preferred(&this->hidden->audio_handle,
|
||||
&this->hidden->cardno,
|
||||
&this->hidden->deviceno,
|
||||
SND_PCM_OPEN_PLAYBACK);
|
||||
} else {
|
||||
status = snd_pcm_open_preferred(&this->hidden->audio_handle,
|
||||
&this->hidden->cardno,
|
||||
&this->hidden->deviceno,
|
||||
SND_PCM_OPEN_CAPTURE);
|
||||
}
|
||||
} else {
|
||||
if (device != NULL) {
|
||||
/* Open requested audio device */
|
||||
if (!this->hidden->iscapture) {
|
||||
status =
|
||||
snd_pcm_open(&this->hidden->audio_handle,
|
||||
this->hidden->cardno, this->hidden->deviceno,
|
||||
SND_PCM_OPEN_PLAYBACK);
|
||||
} else {
|
||||
status =
|
||||
snd_pcm_open(&this->hidden->audio_handle,
|
||||
this->hidden->cardno, this->hidden->deviceno,
|
||||
SND_PCM_OPEN_CAPTURE);
|
||||
}
|
||||
this->hidden->deviceno = device->deviceno;
|
||||
this->hidden->cardno = device->cardno;
|
||||
status = snd_pcm_open(&this->hidden->audio_handle,
|
||||
device->cardno, device->deviceno,
|
||||
iscapture ? SND_PCM_OPEN_PLAYBACK : SND_PCM_OPEN_CAPTURE);
|
||||
} else {
|
||||
/* Open system default audio device */
|
||||
status = snd_pcm_open_preferred(&this->hidden->audio_handle,
|
||||
&this->hidden->cardno,
|
||||
&this->hidden->deviceno,
|
||||
iscapture ? SND_PCM_OPEN_PLAYBACK : SND_PCM_OPEN_CAPTURE);
|
||||
}
|
||||
|
||||
/* Check if requested device is opened */
|
||||
|
@ -638,7 +587,7 @@ QSA_OpenDevice(_THIS, const char *devname, int iscapture)
|
|||
}
|
||||
|
||||
static void
|
||||
QSA_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
|
||||
QSA_DetectDevices(void)
|
||||
{
|
||||
uint32_t it;
|
||||
uint32_t cards;
|
||||
|
@ -656,8 +605,9 @@ QSA_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
|
|||
return;
|
||||
}
|
||||
|
||||
/* !!! FIXME: code duplication */
|
||||
/* Find requested devices by type */
|
||||
if (!iscapture) {
|
||||
{ /* output devices */
|
||||
/* Playback devices enumeration requested */
|
||||
for (it = 0; it < cards; it++) {
|
||||
devices = 0;
|
||||
|
@ -688,7 +638,7 @@ QSA_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
|
|||
devices;
|
||||
status = snd_pcm_close(handle);
|
||||
if (status == EOK) {
|
||||
addfn(qsa_playback_device[qsa_playback_devices].name);
|
||||
SDL_AddAudioDevice(SDL_FALSE, qsa_playback_device[qsa_playback_devices].name, &qsa_playback_device[qsa_playback_devices]);
|
||||
qsa_playback_devices++;
|
||||
}
|
||||
} else {
|
||||
|
@ -713,7 +663,9 @@ QSA_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
|
|||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
|
||||
{ /* capture devices */
|
||||
/* Capture devices enumeration requested */
|
||||
for (it = 0; it < cards; it++) {
|
||||
devices = 0;
|
||||
|
@ -744,7 +696,7 @@ QSA_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
|
|||
devices;
|
||||
status = snd_pcm_close(handle);
|
||||
if (status == EOK) {
|
||||
addfn(qsa_capture_device[qsa_capture_devices].name);
|
||||
SDL_AddAudioDevice(SDL_TRUE, qsa_capture_device[qsa_capture_devices].name, &qsa_capture_device[qsa_capture_devices]);
|
||||
qsa_capture_devices++;
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -158,7 +158,7 @@ SNDIO_PlayDevice(_THIS)
|
|||
|
||||
/* If we couldn't write, assume fatal error for now */
|
||||
if ( written == 0 ) {
|
||||
this->enabled = 0;
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
}
|
||||
#ifdef DEBUG_AUDIO
|
||||
fprintf(stderr, "Wrote %d bytes of audio data\n", written);
|
||||
|
@ -193,7 +193,7 @@ SNDIO_CloseDevice(_THIS)
|
|||
}
|
||||
|
||||
static int
|
||||
SNDIO_OpenDevice(_THIS, const char *devname, int iscapture)
|
||||
SNDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
{
|
||||
SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
|
||||
struct sio_par par;
|
||||
|
|
|
@ -56,9 +56,9 @@ static Uint8 snd2au(int sample);
|
|||
|
||||
/* Audio driver bootstrap functions */
|
||||
static void
|
||||
SUNAUDIO_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
|
||||
SUNAUDIO_DetectDevices(void)
|
||||
{
|
||||
SDL_EnumUnixAudioDevices(iscapture, 1, (int (*)(int fd)) NULL, addfn);
|
||||
SDL_EnumUnixAudioDevices(1, (int (*)(int)) NULL);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_AUDIO
|
||||
|
@ -158,7 +158,7 @@ SUNAUDIO_PlayDevice(_THIS)
|
|||
if (write(this->hidden->audio_fd, this->hidden->ulaw_buf,
|
||||
this->hidden->fragsize) < 0) {
|
||||
/* Assume fatal error, for now */
|
||||
this->enabled = 0;
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
}
|
||||
this->hidden->written += this->hidden->fragsize;
|
||||
} else {
|
||||
|
@ -168,7 +168,7 @@ SUNAUDIO_PlayDevice(_THIS)
|
|||
if (write(this->hidden->audio_fd, this->hidden->mixbuf,
|
||||
this->spec.size) < 0) {
|
||||
/* Assume fatal error, for now */
|
||||
this->enabled = 0;
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
}
|
||||
this->hidden->written += this->hidden->fragsize;
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ SUNAUDIO_CloseDevice(_THIS)
|
|||
}
|
||||
|
||||
static int
|
||||
SUNAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
|
||||
SUNAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
{
|
||||
const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT);
|
||||
SDL_AudioFormat format = 0;
|
||||
|
@ -414,6 +414,8 @@ SUNAUDIO_Init(SDL_AudioDriverImpl * impl)
|
|||
impl->GetDeviceBuf = SUNAUDIO_GetDeviceBuf;
|
||||
impl->CloseDevice = SUNAUDIO_CloseDevice;
|
||||
|
||||
impl->AllowsArbitraryDeviceNames = 1;
|
||||
|
||||
return 1; /* this audio target is available. */
|
||||
}
|
||||
|
||||
|
|
|
@ -36,8 +36,9 @@
|
|||
#define WAVE_FORMAT_IEEE_FLOAT 0x0003
|
||||
#endif
|
||||
|
||||
#define DETECT_DEV_IMPL(typ, capstyp) \
|
||||
static void DetectWave##typ##Devs(SDL_AddAudioDevice addfn) { \
|
||||
#define DETECT_DEV_IMPL(iscap, typ, capstyp) \
|
||||
static void DetectWave##typ##Devs(void) { \
|
||||
const UINT iscapture = iscap ? 1 : 0; \
|
||||
const UINT devcount = wave##typ##GetNumDevs(); \
|
||||
capstyp caps; \
|
||||
UINT i; \
|
||||
|
@ -45,24 +46,21 @@ static void DetectWave##typ##Devs(SDL_AddAudioDevice addfn) { \
|
|||
if (wave##typ##GetDevCaps(i,&caps,sizeof(caps))==MMSYSERR_NOERROR) { \
|
||||
char *name = WIN_StringToUTF8(caps.szPname); \
|
||||
if (name != NULL) { \
|
||||
addfn(name); \
|
||||
SDL_AddAudioDevice((int) iscapture, name, (void *) ((size_t) i+1)); \
|
||||
SDL_free(name); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
DETECT_DEV_IMPL(Out, WAVEOUTCAPS)
|
||||
DETECT_DEV_IMPL(In, WAVEINCAPS)
|
||||
DETECT_DEV_IMPL(SDL_FALSE, Out, WAVEOUTCAPS)
|
||||
DETECT_DEV_IMPL(SDL_TRUE, In, WAVEINCAPS)
|
||||
|
||||
static void
|
||||
WINMM_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
|
||||
WINMM_DetectDevices(void)
|
||||
{
|
||||
if (iscapture) {
|
||||
DetectWaveInDevs(addfn);
|
||||
} else {
|
||||
DetectWaveOutDevs(addfn);
|
||||
}
|
||||
DetectWaveInDevs();
|
||||
DetectWaveOutDevs();
|
||||
}
|
||||
|
||||
static void CALLBACK
|
||||
|
@ -220,48 +218,19 @@ PrepWaveFormat(_THIS, UINT devId, WAVEFORMATEX *pfmt, const int iscapture)
|
|||
}
|
||||
|
||||
static int
|
||||
WINMM_OpenDevice(_THIS, const char *devname, int iscapture)
|
||||
WINMM_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
{
|
||||
SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
|
||||
int valid_datatype = 0;
|
||||
MMRESULT result;
|
||||
WAVEFORMATEX waveformat;
|
||||
UINT devId = WAVE_MAPPER; /* WAVE_MAPPER == choose system's default */
|
||||
char *utf8 = NULL;
|
||||
UINT i;
|
||||
|
||||
if (devname != NULL) { /* specific device requested? */
|
||||
if (iscapture) {
|
||||
const UINT devcount = waveInGetNumDevs();
|
||||
WAVEINCAPS caps;
|
||||
for (i = 0; (i < devcount) && (devId == WAVE_MAPPER); i++) {
|
||||
result = waveInGetDevCaps(i, &caps, sizeof (caps));
|
||||
if (result != MMSYSERR_NOERROR)
|
||||
continue;
|
||||
else if ((utf8 = WIN_StringToUTF8(caps.szPname)) == NULL)
|
||||
continue;
|
||||
else if (SDL_strcmp(devname, utf8) == 0)
|
||||
devId = i;
|
||||
SDL_free(utf8);
|
||||
}
|
||||
} else {
|
||||
const UINT devcount = waveOutGetNumDevs();
|
||||
WAVEOUTCAPS caps;
|
||||
for (i = 0; (i < devcount) && (devId == WAVE_MAPPER); i++) {
|
||||
result = waveOutGetDevCaps(i, &caps, sizeof (caps));
|
||||
if (result != MMSYSERR_NOERROR)
|
||||
continue;
|
||||
else if ((utf8 = WIN_StringToUTF8(caps.szPname)) == NULL)
|
||||
continue;
|
||||
else if (SDL_strcmp(devname, utf8) == 0)
|
||||
devId = i;
|
||||
SDL_free(utf8);
|
||||
}
|
||||
}
|
||||
|
||||
if (devId == WAVE_MAPPER) {
|
||||
return SDL_SetError("Requested device not found");
|
||||
}
|
||||
if (handle != NULL) { /* specific device requested? */
|
||||
/* -1 because we increment the original value to avoid NULL. */
|
||||
const size_t val = ((size_t) handle) - 1;
|
||||
devId = (UINT) val;
|
||||
}
|
||||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
|
@ -279,10 +248,6 @@ WINMM_OpenDevice(_THIS, const char *devname, int iscapture)
|
|||
if (this->spec.channels > 2)
|
||||
this->spec.channels = 2; /* !!! FIXME: is this right? */
|
||||
|
||||
/* Check the buffer size -- minimum of 1/4 second (word aligned) */
|
||||
if (this->spec.samples < (this->spec.freq / 4))
|
||||
this->spec.samples = ((this->spec.freq / 4) + 3) & ~3;
|
||||
|
||||
while ((!valid_datatype) && (test_format)) {
|
||||
switch (test_format) {
|
||||
case AUDIO_U8:
|
||||
|
|
|
@ -126,16 +126,13 @@ struct SDL_PrivateAudioData
|
|||
|
||||
|
||||
static void
|
||||
XAUDIO2_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
|
||||
XAUDIO2_DetectDevices(void)
|
||||
{
|
||||
IXAudio2 *ixa2 = NULL;
|
||||
UINT32 devcount = 0;
|
||||
UINT32 i = 0;
|
||||
|
||||
if (iscapture) {
|
||||
SDL_SetError("XAudio2: capture devices unsupported.");
|
||||
return;
|
||||
} else if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) {
|
||||
if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) {
|
||||
SDL_SetError("XAudio2: XAudio2Create() failed at detection.");
|
||||
return;
|
||||
} else if (IXAudio2_GetDeviceCount(ixa2, &devcount) != S_OK) {
|
||||
|
@ -149,8 +146,8 @@ XAUDIO2_DetectDevices(int iscapture, SDL_AddAudioDevice addfn)
|
|||
if (IXAudio2_GetDeviceDetails(ixa2, i, &details) == S_OK) {
|
||||
char *str = WIN_StringToUTF8(details.DisplayName);
|
||||
if (str != NULL) {
|
||||
addfn(str);
|
||||
SDL_free(str); /* addfn() made a copy of the string. */
|
||||
SDL_AddAudioDevice(SDL_FALSE, str, (void *) ((size_t) i+1));
|
||||
SDL_free(str); /* SDL_AddAudioDevice made a copy of the string. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -169,8 +166,8 @@ VoiceCBOnBufferEnd(THIS_ void *data)
|
|||
static void STDMETHODCALLTYPE
|
||||
VoiceCBOnVoiceError(THIS_ void *data, HRESULT Error)
|
||||
{
|
||||
/* !!! FIXME: attempt to recover, or mark device disconnected. */
|
||||
SDL_assert(0 && "write me!");
|
||||
SDL_AudioDevice *this = (SDL_AudioDevice *) data;
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
}
|
||||
|
||||
/* no-op callbacks... */
|
||||
|
@ -221,7 +218,7 @@ XAUDIO2_PlayDevice(_THIS)
|
|||
|
||||
if (result != S_OK) { /* uhoh, panic! */
|
||||
IXAudio2SourceVoice_FlushSourceBuffers(source);
|
||||
this->enabled = 0;
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -289,7 +286,7 @@ XAUDIO2_CloseDevice(_THIS)
|
|||
}
|
||||
|
||||
static int
|
||||
XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture)
|
||||
XAUDIO2_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
|
||||
{
|
||||
HRESULT result = S_OK;
|
||||
WAVEFORMATEX waveformat;
|
||||
|
@ -315,9 +312,17 @@ XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture)
|
|||
|
||||
static IXAudio2VoiceCallback callbacks = { &callbacks_vtable };
|
||||
|
||||
if (iscapture) {
|
||||
return SDL_SetError("XAudio2: capture devices unsupported.");
|
||||
} else if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) {
|
||||
#if defined(SDL_XAUDIO2_WIN8)
|
||||
/* !!! FIXME: hook up hotplugging. */
|
||||
#else
|
||||
if (handle != NULL) { /* specific device requested? */
|
||||
/* -1 because we increment the original value to avoid NULL. */
|
||||
const size_t val = ((size_t) handle) - 1;
|
||||
devId = (UINT32) val;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (XAudio2Create(&ixa2, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) {
|
||||
return SDL_SetError("XAudio2: XAudio2Create() failed at open.");
|
||||
}
|
||||
|
||||
|
@ -332,37 +337,6 @@ XAUDIO2_OpenDevice(_THIS, const char *devname, int iscapture)
|
|||
ixa2->SetDebugConfiguration(&debugConfig);
|
||||
*/
|
||||
|
||||
#if ! defined(__WINRT__)
|
||||
if (devname != NULL) {
|
||||
UINT32 devcount = 0;
|
||||
UINT32 i = 0;
|
||||
|
||||
if (IXAudio2_GetDeviceCount(ixa2, &devcount) != S_OK) {
|
||||
IXAudio2_Release(ixa2);
|
||||
return SDL_SetError("XAudio2: IXAudio2_GetDeviceCount() failed.");
|
||||
}
|
||||
for (i = 0; i < devcount; i++) {
|
||||
XAUDIO2_DEVICE_DETAILS details;
|
||||
if (IXAudio2_GetDeviceDetails(ixa2, i, &details) == S_OK) {
|
||||
char *str = WIN_StringToUTF8(details.DisplayName);
|
||||
if (str != NULL) {
|
||||
const int match = (SDL_strcmp(str, devname) == 0);
|
||||
SDL_free(str);
|
||||
if (match) {
|
||||
devId = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i == devcount) {
|
||||
IXAudio2_Release(ixa2);
|
||||
return SDL_SetError("XAudio2: Requested device not found.");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Initialize all variables that we clean on shutdown */
|
||||
this->hidden = (struct SDL_PrivateAudioData *)
|
||||
SDL_malloc((sizeof *this->hidden));
|
||||
|
@ -529,6 +503,16 @@ XAUDIO2_Init(SDL_AudioDriverImpl * impl)
|
|||
impl->CloseDevice = XAUDIO2_CloseDevice;
|
||||
impl->Deinitialize = XAUDIO2_Deinitialize;
|
||||
|
||||
/* !!! FIXME: We can apparently use a C++ interface on Windows 8
|
||||
* !!! FIXME: (Windows::Devices::Enumeration::DeviceInformation) for device
|
||||
* !!! FIXME: detection, but it's not implemented here yet.
|
||||
* !!! FIXME: see http://blogs.msdn.com/b/chuckw/archive/2012/04/02/xaudio2-and-windows-8-consumer-preview.aspx
|
||||
* !!! FIXME: for now, force the default device.
|
||||
*/
|
||||
#if defined(SDL_XAUDIO2_WIN8) || defined(__WINRT__)
|
||||
impl->OnlyHasDefaultOutputDevice = 1;
|
||||
#endif
|
||||
|
||||
return 1; /* this audio target is available. */
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
#include "../../events/SDL_events_c.h"
|
||||
#include "../../video/android/SDL_androidkeyboard.h"
|
||||
#include "../../video/android/SDL_androidmouse.h"
|
||||
#include "../../video/android/SDL_androidtouch.h"
|
||||
#include "../../video/android/SDL_androidvideo.h"
|
||||
#include "../../video/android/SDL_androidwindow.h"
|
||||
|
@ -293,6 +294,14 @@ JNIEXPORT void JNICALL Java_org_libsdl_app_SDLActivity_onNativeTouch(
|
|||
Android_OnTouch(touch_device_id_in, pointer_finger_id_in, action, x, y, p);
|
||||
}
|
||||
|
||||
/* Mouse */
|
||||
JNIEXPORT void JNICALL Java_org_libsdl_app_SDLActivity_onNativeMouse(
|
||||
JNIEnv* env, jclass jcls,
|
||||
jint button, jint action, jfloat x, jfloat y)
|
||||
{
|
||||
Android_OnMouse(button, action, x, y);
|
||||
}
|
||||
|
||||
/* Accelerometer */
|
||||
JNIEXPORT void JNICALL Java_org_libsdl_app_SDLActivity_onNativeAccel(
|
||||
JNIEnv* env, jclass jcls,
|
||||
|
@ -548,12 +557,12 @@ int Android_JNI_SetupThread(void)
|
|||
* Audio support
|
||||
*/
|
||||
static jboolean audioBuffer16Bit = JNI_FALSE;
|
||||
static jboolean audioBufferStereo = JNI_FALSE;
|
||||
static jobject audioBuffer = NULL;
|
||||
static void* audioBufferPinned = NULL;
|
||||
|
||||
int Android_JNI_OpenAudioDevice(int sampleRate, int is16Bit, int channelCount, int desiredBufferFrames)
|
||||
{
|
||||
jboolean audioBufferStereo;
|
||||
int audioBufferFrames;
|
||||
|
||||
JNIEnv *env = Android_JNI_GetEnv();
|
||||
|
@ -1601,6 +1610,11 @@ const char * SDL_AndroidGetExternalStoragePath()
|
|||
return s_AndroidExternalFilesPath;
|
||||
}
|
||||
|
||||
jclass Android_JNI_GetActivityClass(void)
|
||||
{
|
||||
return mActivityClass;
|
||||
}
|
||||
|
||||
#endif /* __ANDROID__ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
@ -78,6 +78,7 @@ int Android_JNI_GetTouchDeviceIds(int **ids);
|
|||
#include <jni.h>
|
||||
JNIEnv *Android_JNI_GetEnv(void);
|
||||
int Android_JNI_SetupThread(void);
|
||||
jclass Android_JNI_GetActivityClass(void);
|
||||
|
||||
/* Generic messages */
|
||||
int Android_JNI_SendMessage(int command, int param);
|
||||
|
|
|
@ -462,6 +462,9 @@ SDL_IBus_Init(void)
|
|||
ibus_addr_file = SDL_strdup(addr_file);
|
||||
|
||||
addr = IBus_ReadAddressFromFile(addr_file);
|
||||
if (!addr) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (inotify_fd < 0) {
|
||||
inotify_fd = inotify_init();
|
||||
|
|
|
@ -350,17 +350,19 @@ guess_device_class(struct udev_device *dev)
|
|||
devclass |= SDL_UDEV_DEVICE_MOUSE; /* ID_INPUT_MOUSE */
|
||||
} else if (test_bit(BTN_TOUCH, bitmask_key)) {
|
||||
; /* ID_INPUT_TOUCHSCREEN */
|
||||
} else if (test_bit(BTN_TRIGGER, bitmask_key) ||
|
||||
test_bit(BTN_A, bitmask_key) ||
|
||||
test_bit(BTN_1, bitmask_key) ||
|
||||
test_bit(ABS_RX, bitmask_abs) ||
|
||||
test_bit(ABS_RY, bitmask_abs) ||
|
||||
test_bit(ABS_RZ, bitmask_abs) ||
|
||||
test_bit(ABS_THROTTLE, bitmask_abs) ||
|
||||
test_bit(ABS_RUDDER, bitmask_abs) ||
|
||||
test_bit(ABS_WHEEL, bitmask_abs) ||
|
||||
test_bit(ABS_GAS, bitmask_abs) ||
|
||||
test_bit(ABS_BRAKE, bitmask_abs)) {
|
||||
}
|
||||
|
||||
if (test_bit(BTN_TRIGGER, bitmask_key) ||
|
||||
test_bit(BTN_A, bitmask_key) ||
|
||||
test_bit(BTN_1, bitmask_key) ||
|
||||
test_bit(ABS_RX, bitmask_abs) ||
|
||||
test_bit(ABS_RY, bitmask_abs) ||
|
||||
test_bit(ABS_RZ, bitmask_abs) ||
|
||||
test_bit(ABS_THROTTLE, bitmask_abs) ||
|
||||
test_bit(ABS_RUDDER, bitmask_abs) ||
|
||||
test_bit(ABS_WHEEL, bitmask_abs) ||
|
||||
test_bit(ABS_GAS, bitmask_abs) ||
|
||||
test_bit(ABS_BRAKE, bitmask_abs)) {
|
||||
devclass |= SDL_UDEV_DEVICE_JOYSTICK; /* ID_INPUT_JOYSTICK */
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,7 +49,10 @@
|
|||
#define SDL_DYNAMIC_API 0
|
||||
#elif defined(__clang_analyzer__)
|
||||
#define SDL_DYNAMIC_API 0 /* Turn off for static analysis, so reports are more clear. */
|
||||
#else /* everyone else. */
|
||||
#endif
|
||||
|
||||
/* everyone else. This is where we turn on the API if nothing forced it off. */
|
||||
#ifndef SDL_DYNAMIC_API
|
||||
#define SDL_DYNAMIC_API 1
|
||||
#endif
|
||||
|
||||
|
|
|
@ -591,3 +591,4 @@
|
|||
#define SDL_QueueAudio SDL_QueueAudio_REAL
|
||||
#define SDL_GetQueuedAudioSize SDL_GetQueuedAudioSize_REAL
|
||||
#define SDL_ClearQueuedAudio SDL_ClearQueuedAudio_REAL
|
||||
#define SDL_GetGrabbedWindow SDL_GetGrabbedWindow_REAL
|
||||
|
|
|
@ -623,3 +623,4 @@ SDL_DYNAPI_PROC(SDL_bool,SDL_HasAVX2,(void),(),return)
|
|||
SDL_DYNAPI_PROC(int,SDL_QueueAudio,(SDL_AudioDeviceID a, const void *b, Uint32 c),(a,b,c),return)
|
||||
SDL_DYNAPI_PROC(Uint32,SDL_GetQueuedAudioSize,(SDL_AudioDeviceID a),(a),return)
|
||||
SDL_DYNAPI_PROC(void,SDL_ClearQueuedAudio,(SDL_AudioDeviceID a),(a),)
|
||||
SDL_DYNAPI_PROC(SDL_Window*,SDL_GetGrabbedWindow,(void),(),return)
|
||||
|
|
|
@ -75,12 +75,13 @@ static struct
|
|||
SDL_mutex *lock;
|
||||
volatile SDL_bool active;
|
||||
volatile int count;
|
||||
volatile int max_events_seen;
|
||||
SDL_EventEntry *head;
|
||||
SDL_EventEntry *tail;
|
||||
SDL_EventEntry *free;
|
||||
SDL_SysWMEntry *wmmsg_used;
|
||||
SDL_SysWMEntry *wmmsg_free;
|
||||
} SDL_EventQ = { NULL, SDL_TRUE };
|
||||
} SDL_EventQ = { NULL, SDL_TRUE, 0, 0, NULL, NULL, NULL, NULL, NULL };
|
||||
|
||||
|
||||
/* Public functions */
|
||||
|
@ -88,6 +89,7 @@ static struct
|
|||
void
|
||||
SDL_StopEventLoop(void)
|
||||
{
|
||||
const char *report = SDL_GetHint("SDL_EVENT_QUEUE_STATISTICS");
|
||||
int i;
|
||||
SDL_EventEntry *entry;
|
||||
SDL_SysWMEntry *wmmsg;
|
||||
|
@ -98,6 +100,11 @@ SDL_StopEventLoop(void)
|
|||
|
||||
SDL_EventQ.active = SDL_FALSE;
|
||||
|
||||
if (report && SDL_atoi(report)) {
|
||||
SDL_Log("SDL EVENT QUEUE: Maximum events in-flight: %d\n",
|
||||
SDL_EventQ.max_events_seen);
|
||||
}
|
||||
|
||||
/* Clean out EventQ */
|
||||
for (entry = SDL_EventQ.head; entry; ) {
|
||||
SDL_EventEntry *next = entry->next;
|
||||
|
@ -119,7 +126,9 @@ SDL_StopEventLoop(void)
|
|||
SDL_free(wmmsg);
|
||||
wmmsg = next;
|
||||
}
|
||||
|
||||
SDL_EventQ.count = 0;
|
||||
SDL_EventQ.max_events_seen = 0;
|
||||
SDL_EventQ.head = NULL;
|
||||
SDL_EventQ.tail = NULL;
|
||||
SDL_EventQ.free = NULL;
|
||||
|
@ -218,6 +227,10 @@ SDL_AddEvent(SDL_Event * event)
|
|||
}
|
||||
++SDL_EventQ.count;
|
||||
|
||||
if (SDL_EventQ.count > SDL_EventQ.max_events_seen) {
|
||||
SDL_EventQ.max_events_seen = SDL_EventQ.count;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
/* General mouse handling code for SDL */
|
||||
|
||||
#include "SDL_events.h"
|
||||
#include "SDL_endian.h"
|
||||
#include "SDL_events_c.h"
|
||||
#include "SDL_gesture_c.h"
|
||||
|
||||
|
@ -114,14 +115,34 @@ static unsigned long SDL_HashDollar(SDL_FloatPoint* points)
|
|||
|
||||
static int SaveTemplate(SDL_DollarTemplate *templ, SDL_RWops *dst)
|
||||
{
|
||||
if (dst == NULL) return 0;
|
||||
if (dst == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* No Longer storing the Hash, rehash on load */
|
||||
/* if (SDL_RWops.write(dst, &(templ->hash), sizeof(templ->hash), 1) != 1) return 0; */
|
||||
|
||||
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
|
||||
if (SDL_RWwrite(dst, templ->path,
|
||||
sizeof(templ->path[0]),DOLLARNPOINTS) != DOLLARNPOINTS)
|
||||
sizeof(templ->path[0]),DOLLARNPOINTS) != DOLLARNPOINTS) {
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
{
|
||||
SDL_DollarTemplate copy = *templ;
|
||||
SDL_FloatPoint *p = copy.path;
|
||||
int i;
|
||||
for (i = 0; i < DOLLARNPOINTS; i++, p++) {
|
||||
p->x = SDL_SwapFloatLE(p->x);
|
||||
p->y = SDL_SwapFloatLE(p->y);
|
||||
}
|
||||
|
||||
if (SDL_RWwrite(dst, copy.path,
|
||||
sizeof(copy.path[0]),DOLLARNPOINTS) != DOLLARNPOINTS) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -184,7 +205,7 @@ static int SDL_AddDollarGesture(SDL_GestureTouch* inTouch, SDL_FloatPoint* path)
|
|||
int index = -1;
|
||||
int i = 0;
|
||||
if (inTouch == NULL) {
|
||||
if (SDL_numGestureTouches == 0) return -1;
|
||||
if (SDL_numGestureTouches == 0) return SDL_SetError("no gesture touch devices registered");
|
||||
for (i = 0; i < SDL_numGestureTouches; i++) {
|
||||
inTouch = &SDL_gestureTouch[i];
|
||||
index = SDL_AddDollarGesture_one(inTouch, path);
|
||||
|
@ -203,17 +224,33 @@ int SDL_LoadDollarTemplates(SDL_TouchID touchId, SDL_RWops *src)
|
|||
SDL_GestureTouch *touch = NULL;
|
||||
if (src == NULL) return 0;
|
||||
if (touchId >= 0) {
|
||||
for (i = 0; i < SDL_numGestureTouches; i++)
|
||||
if (SDL_gestureTouch[i].id == touchId)
|
||||
for (i = 0; i < SDL_numGestureTouches; i++) {
|
||||
if (SDL_gestureTouch[i].id == touchId) {
|
||||
touch = &SDL_gestureTouch[i];
|
||||
if (touch == NULL) return -1;
|
||||
}
|
||||
}
|
||||
if (touch == NULL) {
|
||||
return SDL_SetError("given touch id not found");
|
||||
}
|
||||
}
|
||||
|
||||
while (1) {
|
||||
SDL_DollarTemplate templ;
|
||||
|
||||
if (SDL_RWread(src,templ.path,sizeof(templ.path[0]),DOLLARNPOINTS) <
|
||||
DOLLARNPOINTS) break;
|
||||
if (SDL_RWread(src,templ.path,sizeof(templ.path[0]),DOLLARNPOINTS) < DOLLARNPOINTS) {
|
||||
if (loaded == 0) {
|
||||
return SDL_SetError("could not read any dollar gesture from rwops");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
#if SDL_BYTEORDER != SDL_LIL_ENDIAN
|
||||
for (i = 0; i < DOLLARNPOINTS; i++) {
|
||||
SDL_FloatPoint *p = &templ.path[i];
|
||||
p->x = SDL_SwapFloatLE(p->x);
|
||||
p->y = SDL_SwapFloatLE(p->y);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (touchId >= 0) {
|
||||
/* printf("Adding loaded gesture to 1 touch\n"); */
|
||||
|
|
|
@ -293,9 +293,14 @@ SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relativ
|
|||
event.motion.yrel = yrel;
|
||||
posted = (SDL_PushEvent(&event) > 0);
|
||||
}
|
||||
/* Use unclamped values if we're getting events outside the window */
|
||||
mouse->last_x = x;
|
||||
mouse->last_y = y;
|
||||
if (relative) {
|
||||
mouse->last_x = mouse->x;
|
||||
mouse->last_y = mouse->y;
|
||||
} else {
|
||||
/* Use unclamped values if we're getting events outside the window */
|
||||
mouse->last_x = x;
|
||||
mouse->last_y = y;
|
||||
}
|
||||
return posted;
|
||||
}
|
||||
|
||||
|
@ -303,10 +308,11 @@ static SDL_MouseClickState *GetMouseClickState(SDL_Mouse *mouse, Uint8 button)
|
|||
{
|
||||
if (button >= mouse->num_clickstates) {
|
||||
int i, count = button + 1;
|
||||
mouse->clickstate = (SDL_MouseClickState *)SDL_realloc(mouse->clickstate, count * sizeof(*mouse->clickstate));
|
||||
if (!mouse->clickstate) {
|
||||
SDL_MouseClickState *clickstate = (SDL_MouseClickState *)SDL_realloc(mouse->clickstate, count * sizeof(*mouse->clickstate));
|
||||
if (!clickstate) {
|
||||
return NULL;
|
||||
}
|
||||
mouse->clickstate = clickstate;
|
||||
|
||||
for (i = mouse->num_clickstates; i < count; ++i) {
|
||||
SDL_zero(mouse->clickstate[i]);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../SDL_internal.h"
|
||||
#include "SDL_hints.h"
|
||||
|
||||
/* General quit handling code for SDL */
|
||||
|
||||
|
@ -30,6 +31,8 @@
|
|||
#include "SDL_events_c.h"
|
||||
|
||||
|
||||
static SDL_bool disable_signals = SDL_FALSE;
|
||||
|
||||
#ifdef HAVE_SIGNAL_H
|
||||
static void
|
||||
SDL_HandleSIG(int sig)
|
||||
|
@ -43,8 +46,8 @@ SDL_HandleSIG(int sig)
|
|||
#endif /* HAVE_SIGNAL_H */
|
||||
|
||||
/* Public functions */
|
||||
int
|
||||
SDL_QuitInit(void)
|
||||
static int
|
||||
SDL_QuitInit_Internal(void)
|
||||
{
|
||||
#ifdef HAVE_SIGACTION
|
||||
struct sigaction action;
|
||||
|
@ -80,11 +83,22 @@ SDL_QuitInit(void)
|
|||
#endif /* HAVE_SIGNAL_H */
|
||||
|
||||
/* That's it! */
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
SDL_QuitQuit(void)
|
||||
int
|
||||
SDL_QuitInit(void)
|
||||
{
|
||||
const char *hint = SDL_GetHint(SDL_HINT_NO_SIGNAL_HANDLERS);
|
||||
disable_signals = hint && (SDL_atoi(hint) == 1);
|
||||
if (!disable_signals) {
|
||||
return SDL_QuitInit_Internal();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
SDL_QuitQuit_Internal(void)
|
||||
{
|
||||
#ifdef HAVE_SIGACTION
|
||||
struct sigaction action;
|
||||
|
@ -110,6 +124,14 @@ SDL_QuitQuit(void)
|
|||
#endif /* HAVE_SIGNAL_H */
|
||||
}
|
||||
|
||||
void
|
||||
SDL_QuitQuit(void)
|
||||
{
|
||||
if (!disable_signals) {
|
||||
SDL_QuitQuit_Internal();
|
||||
}
|
||||
}
|
||||
|
||||
/* This function returns 1 if it's okay to close the application window */
|
||||
int
|
||||
SDL_SendQuit(void)
|
||||
|
|
|
@ -38,4 +38,5 @@ SDL_GetPrefPath(const char *org, const char *app)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* __NACL__ */
|
||||
#endif /* SDL_FILESYSTEM_NACL */
|
||||
|
||||
|
|
|
@ -288,8 +288,7 @@ MaybeAddDevice(const char *path)
|
|||
}
|
||||
|
||||
item->fname = SDL_strdup(path);
|
||||
if ( (item->fname == NULL) ) {
|
||||
SDL_free(item->fname);
|
||||
if (item->fname == NULL) {
|
||||
SDL_free(item);
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -63,6 +63,8 @@ static const char *s_ControllerMappings [] =
|
|||
"030000006d0400001ec2000020200000,Logitech F510 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
|
||||
"030000006d04000019c2000011010000,Logitech F710 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", /* Guide button doesn't seem to be sent in DInput mode. */
|
||||
"030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
|
||||
"030000006d04000018c2000010010000,Logitech RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
|
||||
"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,",
|
||||
"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,",
|
||||
"030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,",
|
||||
"030000004c050000c405000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
|
||||
|
@ -73,12 +75,13 @@ static const char *s_ControllerMappings [] =
|
|||
"030000005e0400008e02000010010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
|
||||
"030000005e0400001907000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
|
||||
"030000005e0400009102000007010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
|
||||
"030000005e040000d102000001010000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
|
||||
#endif
|
||||
#if defined(__ANDROID__)
|
||||
"4e564944494120436f72706f72617469,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,",
|
||||
#endif
|
||||
#if defined(SDL_JOYSTICK_EMSCRIPTEN)
|
||||
"emscripten,Standard Gamepad,a:b0,b:b1,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,",
|
||||
"emscripten,Standard Gamepad,a:b0,b:b1,back:b8,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b16,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
|
|
@ -206,10 +206,6 @@ SDL_PrivateJoystickValid(SDL_Joystick * joystick)
|
|||
valid = 1;
|
||||
}
|
||||
|
||||
if (joystick && joystick->closed) {
|
||||
valid = 0;
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
|
@ -412,6 +408,7 @@ SDL_JoystickClose(SDL_Joystick * joystick)
|
|||
}
|
||||
|
||||
SDL_SYS_JoystickClose(joystick);
|
||||
joystick->hwdata = NULL;
|
||||
|
||||
joysticklist = SDL_joysticks;
|
||||
joysticklistprev = NULL;
|
||||
|
@ -668,7 +665,7 @@ SDL_JoystickUpdate(void)
|
|||
|
||||
SDL_SYS_JoystickUpdate(joystick);
|
||||
|
||||
if (joystick->closed && joystick->uncentered) {
|
||||
if (joystick->force_recentering) {
|
||||
int i;
|
||||
|
||||
/* Tell the app that everything is centered/unpressed... */
|
||||
|
@ -681,7 +678,7 @@ SDL_JoystickUpdate(void)
|
|||
for (i = 0; i < joystick->nhats; i++)
|
||||
SDL_PrivateJoystickHat(joystick, i, SDL_HAT_CENTERED);
|
||||
|
||||
joystick->uncentered = SDL_FALSE;
|
||||
joystick->force_recentering = SDL_FALSE;
|
||||
}
|
||||
|
||||
SDL_updating_joystick = NULL;
|
||||
|
|
|
@ -53,8 +53,7 @@ struct _SDL_Joystick
|
|||
|
||||
int ref_count; /* Reference count for multiple opens */
|
||||
|
||||
SDL_bool closed; /* SDL_TRUE if this device is no longer valid */
|
||||
SDL_bool uncentered; /* SDL_TRUE if this device needs to have its state reset to 0 */
|
||||
SDL_bool force_recentering; /* SDL_TRUE if this device needs to have its state reset to 0 */
|
||||
struct _SDL_Joystick *next; /* pointer to next joystick we have allocated */
|
||||
};
|
||||
|
||||
|
@ -78,14 +77,14 @@ extern const char *SDL_SYS_JoystickNameForDeviceIndex(int device_index);
|
|||
extern SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index);
|
||||
|
||||
/* Function to open a joystick for use.
|
||||
The joystick to open is specified by the index field of the joystick.
|
||||
The joystick to open is specified by the device index.
|
||||
This should fill the nbuttons and naxes fields of the joystick structure.
|
||||
It returns 0, or -1 if there is an error.
|
||||
*/
|
||||
extern int SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index);
|
||||
|
||||
/* Function to query if the joystick is currently attached
|
||||
* It returns 1 if attached, 0 otherwise.
|
||||
* It returns SDL_TRUE if attached, SDL_FALSE otherwise.
|
||||
*/
|
||||
extern SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick * joystick);
|
||||
|
||||
|
|
|
@ -467,7 +467,7 @@ SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
|
|||
}
|
||||
|
||||
/* Function to open a joystick for use.
|
||||
The joystick to open is specified by the index field of the joystick.
|
||||
The joystick to open is specified by the device index.
|
||||
This should fill the nbuttons and naxes fields of the joystick structure.
|
||||
It returns 0, or -1 if there is an error.
|
||||
*/
|
||||
|
@ -498,7 +498,7 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
|
|||
/* Function to determine is this joystick is attached to the system right now */
|
||||
SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
|
||||
{
|
||||
return !joystick->closed && (joystick->hwdata != NULL);
|
||||
return joystick->hwdata != NULL;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -529,11 +529,6 @@ SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
|
|||
void
|
||||
SDL_SYS_JoystickClose(SDL_Joystick * joystick)
|
||||
{
|
||||
if (joystick->hwdata) {
|
||||
((SDL_joylist_item*)joystick->hwdata)->joystick = NULL;
|
||||
joystick->hwdata = NULL;
|
||||
}
|
||||
joystick->closed = 1;
|
||||
}
|
||||
|
||||
/* Function to perform any system-specific joystick related cleanup */
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "SDL_config.h"
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#ifdef SDL_JOYSTICK_ANDROID
|
||||
#include "../SDL_sysjoystick.h"
|
||||
|
|
|
@ -558,8 +558,6 @@ SDL_SYS_JoystickClose(SDL_Joystick * joy)
|
|||
close(joy->hwdata->fd);
|
||||
SDL_free(joy->hwdata->path);
|
||||
SDL_free(joy->hwdata);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -138,7 +138,7 @@ static void
|
|||
JoystickDeviceWasRemovedCallback(void *ctx, IOReturn result, void *sender)
|
||||
{
|
||||
recDevice *device = (recDevice *) ctx;
|
||||
device->removed = 1;
|
||||
device->removed = SDL_TRUE;
|
||||
device->deviceRef = NULL; // deviceRef was invalidated due to the remove
|
||||
#if SDL_HAPTIC_IOKIT
|
||||
MacHaptic_MaybeRemoveDevice(device->ffservice);
|
||||
|
@ -412,12 +412,12 @@ JoystickDeviceWasAddedCallback(void *ctx, IOReturn res, void *sender, IOHIDDevic
|
|||
/* We have to do some storage of the io_service_t for SDL_HapticOpenFromJoystick */
|
||||
if (IOHIDDeviceGetService != NULL) { /* weak reference: available in 10.6 and later. */
|
||||
const io_service_t ioservice = IOHIDDeviceGetService(ioHIDDeviceObject);
|
||||
#if SDL_HAPTIC_IOKIT
|
||||
if ((ioservice) && (FFIsForceFeedback(ioservice) == FF_OK)) {
|
||||
device->ffservice = ioservice;
|
||||
#if SDL_HAPTIC_IOKIT
|
||||
MacHaptic_MaybeAddDevice(ioservice);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
device->send_open_event = 1;
|
||||
|
@ -446,9 +446,9 @@ ConfigHIDManager(CFArrayRef matchingArray)
|
|||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
IOHIDManagerSetDeviceMatchingMultiple(hidman, matchingArray);
|
||||
IOHIDManagerRegisterDeviceMatchingCallback(hidman, JoystickDeviceWasAddedCallback, NULL);
|
||||
IOHIDManagerScheduleWithRunLoop(hidman, runloop, SDL_JOYSTICK_RUNLOOP_MODE);
|
||||
IOHIDManagerSetDeviceMatchingMultiple(hidman, matchingArray);
|
||||
|
||||
while (CFRunLoopRunInMode(SDL_JOYSTICK_RUNLOOP_MODE,0,TRUE) == kCFRunLoopRunHandledSource) {
|
||||
/* no-op. Callback fires once per existing device. */
|
||||
|
@ -560,10 +560,6 @@ SDL_SYS_NumJoysticks()
|
|||
void
|
||||
SDL_SYS_JoystickDetect()
|
||||
{
|
||||
while (CFRunLoopRunInMode(SDL_JOYSTICK_RUNLOOP_MODE,0,TRUE) == kCFRunLoopRunHandledSource) {
|
||||
/* no-op. Pending callbacks will fire in CFRunLoopRunInMode(). */
|
||||
}
|
||||
|
||||
if (s_bDeviceAdded || s_bDeviceRemoved) {
|
||||
recDevice *device = gpDeviceList;
|
||||
s_bDeviceAdded = SDL_FALSE;
|
||||
|
@ -613,6 +609,12 @@ SDL_SYS_JoystickDetect()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// run this after the checks above so we don't set device->removed and delete the device before
|
||||
// SDL_SYS_JoystickUpdate can run to clean up the SDL_Joystick object that owns this device
|
||||
while (CFRunLoopRunInMode(SDL_JOYSTICK_RUNLOOP_MODE,0,TRUE) == kCFRunLoopRunHandledSource) {
|
||||
/* no-op. Pending callbacks will fire in CFRunLoopRunInMode(). */
|
||||
}
|
||||
}
|
||||
|
||||
/* Function to get the device-dependent name of a joystick */
|
||||
|
@ -644,7 +646,7 @@ SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
|
|||
}
|
||||
|
||||
/* Function to open a joystick for use.
|
||||
* The joystick to open is specified by the index field of the joystick.
|
||||
* The joystick to open is specified by the device index.
|
||||
* This should fill the nbuttons and naxes fields of the joystick structure.
|
||||
* It returns 0, or -1 if there is an error.
|
||||
*/
|
||||
|
@ -670,21 +672,12 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
|
|||
}
|
||||
|
||||
/* Function to query if the joystick is currently attached
|
||||
* It returns 1 if attached, 0 otherwise.
|
||||
* It returns SDL_TRUE if attached, SDL_FALSE otherwise.
|
||||
*/
|
||||
SDL_bool
|
||||
SDL_SYS_JoystickAttached(SDL_Joystick * joystick)
|
||||
{
|
||||
recDevice *device = gpDeviceList;
|
||||
|
||||
while (device) {
|
||||
if (joystick->instance_id == device->instance_id) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
device = device->pNext;
|
||||
}
|
||||
|
||||
return SDL_FALSE;
|
||||
return joystick->hwdata != NULL;
|
||||
}
|
||||
|
||||
/* Function to update the state of a joystick - called as a device poll.
|
||||
|
@ -705,9 +698,10 @@ SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
|
|||
}
|
||||
|
||||
if (device->removed) { /* device was unplugged; ignore it. */
|
||||
joystick->closed = 1;
|
||||
joystick->uncentered = 1;
|
||||
joystick->hwdata = NULL;
|
||||
if (joystick->hwdata) {
|
||||
joystick->force_recentering = SDL_TRUE;
|
||||
joystick->hwdata = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -795,7 +789,6 @@ SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
|
|||
void
|
||||
SDL_SYS_JoystickClose(SDL_Joystick * joystick)
|
||||
{
|
||||
joystick->closed = 1;
|
||||
}
|
||||
|
||||
/* Function to perform any system-specific joystick related cleanup */
|
||||
|
|
|
@ -58,8 +58,7 @@ struct joystick_hwdata
|
|||
recElement *firstButton;
|
||||
recElement *firstHat;
|
||||
|
||||
int removed;
|
||||
int uncentered;
|
||||
SDL_bool removed;
|
||||
|
||||
int instance_id;
|
||||
SDL_JoystickGUID guid;
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
int
|
||||
SDL_SYS_JoystickInit(void)
|
||||
{
|
||||
return (0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDL_SYS_NumJoysticks()
|
||||
|
@ -61,7 +61,7 @@ SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
|
|||
}
|
||||
|
||||
/* Function to open a joystick for use.
|
||||
The joystick to open is specified by the index field of the joystick.
|
||||
The joystick to open is specified by the device index.
|
||||
This should fill the nbuttons and naxes fields of the joystick structure.
|
||||
It returns 0, or -1 if there is an error.
|
||||
*/
|
||||
|
@ -85,21 +85,18 @@ SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
|
|||
void
|
||||
SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Function to close a joystick after use */
|
||||
void
|
||||
SDL_SYS_JoystickClose(SDL_Joystick * joystick)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Function to perform any system-specific joystick related cleanup */
|
||||
void
|
||||
SDL_SYS_JoystickQuit(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
|
||||
|
|
|
@ -46,7 +46,7 @@ static SDL_joylist_item *SDL_joylist_tail = NULL;
|
|||
static int numjoysticks = 0;
|
||||
static int instance_counter = 0;
|
||||
|
||||
int
|
||||
EM_BOOL
|
||||
Emscripten_JoyStickConnected(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData)
|
||||
{
|
||||
int i;
|
||||
|
@ -105,12 +105,14 @@ Emscripten_JoyStickConnected(int eventType, const EmscriptenGamepadEvent *gamepa
|
|||
}
|
||||
|
||||
++numjoysticks;
|
||||
SDL_Log("%d",numjoysticks);
|
||||
#ifdef DEBUG_JOYSTICK
|
||||
SDL_Log("Number of joysticks is %d", numjoysticks);
|
||||
#endif
|
||||
#if !SDL_EVENTS_DISABLED
|
||||
event.type = SDL_JOYDEVICEADDED;
|
||||
|
||||
if (SDL_GetEventState(event.type) == SDL_ENABLE) {
|
||||
event.jdevice.which = item->device_instance - 1;
|
||||
event.jdevice.which = numjoysticks - 1;
|
||||
if ( (SDL_EventOK == NULL) ||
|
||||
(*SDL_EventOK) (SDL_EventOKParam, &event) ) {
|
||||
SDL_PushEvent(&event);
|
||||
|
@ -118,12 +120,14 @@ Emscripten_JoyStickConnected(int eventType, const EmscriptenGamepadEvent *gamepa
|
|||
}
|
||||
#endif /* !SDL_EVENTS_DISABLED */
|
||||
|
||||
#ifdef DEBUG_JOYSTICK
|
||||
SDL_Log("Added joystick with index %d", item->index);
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
EM_BOOL
|
||||
Emscripten_JoyStickDisconnected(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData)
|
||||
{
|
||||
SDL_joylist_item *item = SDL_joylist;
|
||||
|
@ -144,7 +148,6 @@ Emscripten_JoyStickDisconnected(int eventType, const EmscriptenGamepadEvent *gam
|
|||
return 1;
|
||||
}
|
||||
|
||||
const int retval = item->device_instance;
|
||||
if (item->joystick) {
|
||||
item->joystick->hwdata = NULL;
|
||||
}
|
||||
|
@ -174,7 +177,9 @@ Emscripten_JoyStickDisconnected(int eventType, const EmscriptenGamepadEvent *gam
|
|||
}
|
||||
#endif /* !SDL_EVENTS_DISABLED */
|
||||
|
||||
SDL_Log("Removed joystick with index %d", retval);
|
||||
#ifdef DEBUG_JOYSTICK
|
||||
SDL_Log("Removed joystick with id %d", item->device_instance);
|
||||
#endif
|
||||
SDL_free(item->name);
|
||||
SDL_free(item->mapping);
|
||||
SDL_free(item);
|
||||
|
@ -215,6 +220,7 @@ SDL_SYS_JoystickInit(void)
|
|||
Emscripten_JoyStickConnected);
|
||||
|
||||
if(retval != EMSCRIPTEN_RESULT_SUCCESS) {
|
||||
SDL_SYS_JoystickQuit();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -222,12 +228,28 @@ SDL_SYS_JoystickInit(void)
|
|||
0,
|
||||
Emscripten_JoyStickDisconnected);
|
||||
if(retval != EMSCRIPTEN_RESULT_SUCCESS) {
|
||||
SDL_SYS_JoystickQuit();
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Returns item matching given SDL device index. */
|
||||
static SDL_joylist_item *
|
||||
JoystickByDeviceIndex(int device_index)
|
||||
{
|
||||
SDL_joylist_item *item = SDL_joylist;
|
||||
|
||||
while (0 < device_index) {
|
||||
--device_index;
|
||||
item = item->next;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
/* Returns item matching given HTML gamepad index. */
|
||||
static SDL_joylist_item *
|
||||
JoystickByIndex(int index)
|
||||
{
|
||||
|
@ -256,46 +278,28 @@ void SDL_SYS_JoystickDetect()
|
|||
{
|
||||
}
|
||||
|
||||
// we need to poll to see if the gamepad state has changed
|
||||
SDL_bool SDL_SYS_JoystickNeedsPolling()
|
||||
{
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
/* Function to get the device-dependent name of a joystick */
|
||||
const char *
|
||||
SDL_SYS_JoystickNameForDeviceIndex(int index)
|
||||
SDL_SYS_JoystickNameForDeviceIndex(int device_index)
|
||||
{
|
||||
SDL_joylist_item *item = JoystickByIndex(index);
|
||||
if (item == NULL) {
|
||||
SDL_SetError("Joystick with index %d not found", index);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return item->name;
|
||||
return JoystickByDeviceIndex(device_index)->name;
|
||||
}
|
||||
|
||||
/* Function to perform the mapping from device index to the instance id for this index */
|
||||
SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int index)
|
||||
SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
|
||||
{
|
||||
SDL_joylist_item *item = JoystickByIndex(index);
|
||||
if (item == NULL) {
|
||||
SDL_SetError("Joystick with index %d not found", index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return item->device_instance;
|
||||
return JoystickByDeviceIndex(device_index)->device_instance;
|
||||
}
|
||||
|
||||
/* Function to open a joystick for use.
|
||||
The joystick to open is specified by the index field of the joystick.
|
||||
The joystick to open is specified by the device index.
|
||||
This should fill the nbuttons and naxes fields of the joystick structure.
|
||||
It returns 0, or -1 if there is an error.
|
||||
*/
|
||||
int
|
||||
SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int index)
|
||||
SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
|
||||
{
|
||||
SDL_joylist_item *item = JoystickByIndex(index);
|
||||
SDL_joylist_item *item = JoystickByDeviceIndex(device_index);
|
||||
|
||||
if (item == NULL ) {
|
||||
return SDL_SetError("No such device");
|
||||
|
@ -322,7 +326,7 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int index)
|
|||
/* Function to determine is this joystick is attached to the system right now */
|
||||
SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
|
||||
{
|
||||
return !joystick->closed && (joystick->hwdata != NULL);
|
||||
return joystick->hwdata != NULL;
|
||||
}
|
||||
|
||||
/* Function to update the state of a joystick - called as a device poll.
|
||||
|
@ -334,10 +338,10 @@ void
|
|||
SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
|
||||
{
|
||||
EmscriptenGamepadEvent gamepadState;
|
||||
SDL_joylist_item *item = SDL_joylist;
|
||||
SDL_joylist_item *item = (SDL_joylist_item *) joystick->hwdata;
|
||||
int i, result, buttonState;
|
||||
|
||||
while (item != NULL) {
|
||||
if (item) {
|
||||
result = emscripten_get_gamepad_status(item->index, &gamepadState);
|
||||
if( result == EMSCRIPTEN_RESULT_SUCCESS) {
|
||||
if(gamepadState.timestamp == 0 || gamepadState.timestamp != item->timestamp) {
|
||||
|
@ -367,7 +371,6 @@ SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
|
|||
}
|
||||
}
|
||||
}
|
||||
item = item->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -375,11 +378,6 @@ SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
|
|||
void
|
||||
SDL_SYS_JoystickClose(SDL_Joystick * joystick)
|
||||
{
|
||||
if (joystick->hwdata) {
|
||||
((SDL_joylist_item*)joystick->hwdata)->joystick = NULL;
|
||||
joystick->hwdata = NULL;
|
||||
}
|
||||
joystick->closed = 1;
|
||||
}
|
||||
|
||||
/* Function to perform any system-specific joystick related cleanup */
|
||||
|
@ -400,20 +398,24 @@ SDL_SYS_JoystickQuit(void)
|
|||
|
||||
numjoysticks = 0;
|
||||
instance_counter = 0;
|
||||
|
||||
emscripten_set_gamepadconnected_callback(NULL, 0, NULL);
|
||||
emscripten_set_gamepaddisconnected_callback(NULL, 0, NULL);
|
||||
}
|
||||
|
||||
SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID(int index)
|
||||
SDL_JoystickGUID
|
||||
SDL_SYS_JoystickGetDeviceGUID(int device_index)
|
||||
{
|
||||
SDL_JoystickGUID guid;
|
||||
/* the GUID is just the first 16 chars of the name for now */
|
||||
const char *name = SDL_SYS_JoystickNameForDeviceIndex(index);
|
||||
const char *name = SDL_SYS_JoystickNameForDeviceIndex(device_index);
|
||||
SDL_zero(guid);
|
||||
SDL_memcpy(&guid, name, SDL_min(sizeof(guid), SDL_strlen(name)));
|
||||
return guid;
|
||||
}
|
||||
|
||||
|
||||
SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick)
|
||||
SDL_JoystickGUID
|
||||
SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick)
|
||||
{
|
||||
SDL_JoystickGUID guid;
|
||||
/* the GUID is just the first 16 chars of the name for now */
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "SDL_config.h"
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#ifdef SDL_JOYSTICK_EMSCRIPTEN
|
||||
#include "../SDL_sysjoystick.h"
|
||||
|
|
|
@ -106,7 +106,7 @@ extern "C"
|
|||
}
|
||||
|
||||
/* Function to open a joystick for use.
|
||||
The joystick to open is specified by the index field of the joystick.
|
||||
The joystick to open is specified by the device index.
|
||||
This should fill the nbuttons and naxes fields of the joystick structure.
|
||||
It returns 0, or -1 if there is an error.
|
||||
*/
|
||||
|
@ -228,7 +228,6 @@ extern "C"
|
|||
SDL_free(joystick->hwdata->new_hats);
|
||||
SDL_free(joystick->hwdata->new_axes);
|
||||
SDL_free(joystick->hwdata);
|
||||
joystick->hwdata = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
|
|||
}
|
||||
|
||||
/* Function to open a joystick for use.
|
||||
The joystick to open is specified by the index field of the joystick.
|
||||
The joystick to open is specified by the device index.
|
||||
This should fill the nbuttons and naxes fields of the joystick structure.
|
||||
It returns 0, or -1 if there is an error.
|
||||
*/
|
||||
|
@ -167,7 +167,6 @@ SDL_SYS_JoystickClose(SDL_Joystick * joystick)
|
|||
@autoreleasepool {
|
||||
[motionManager stopAccelerometerUpdates];
|
||||
}
|
||||
joystick->closed = 1;
|
||||
}
|
||||
|
||||
/* Function to perform any system-specific joystick related cleanup */
|
||||
|
|
|
@ -142,13 +142,15 @@ IsJoystick(int fd, char *namebuf, const size_t namebuflen, SDL_JoystickGUID *gui
|
|||
#if SDL_USE_LIBUDEV
|
||||
void joystick_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath)
|
||||
{
|
||||
if (devpath == NULL || !(udev_class & SDL_UDEV_DEVICE_JOYSTICK)) {
|
||||
if (devpath == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch( udev_type )
|
||||
{
|
||||
switch (udev_type) {
|
||||
case SDL_UDEV_DEVICEADDED:
|
||||
if (!(udev_class & SDL_UDEV_DEVICE_JOYSTICK)) {
|
||||
return;
|
||||
}
|
||||
MaybeAddDevice(devpath);
|
||||
break;
|
||||
|
||||
|
@ -335,13 +337,12 @@ JoystickInitWithoutUdev(void)
|
|||
static int
|
||||
JoystickInitWithUdev(void)
|
||||
{
|
||||
|
||||
if (SDL_UDEV_Init() < 0) {
|
||||
return SDL_SetError("Could not initialize UDEV");
|
||||
}
|
||||
|
||||
/* Set up the udev callback */
|
||||
if ( SDL_UDEV_AddCallback(joystick_udev_callback) < 0) {
|
||||
if (SDL_UDEV_AddCallback(joystick_udev_callback) < 0) {
|
||||
SDL_UDEV_Quit();
|
||||
return SDL_SetError("Could not set up joystick <-> udev callback");
|
||||
}
|
||||
|
@ -565,7 +566,7 @@ ConfigJoystick(SDL_Joystick * joystick, int fd)
|
|||
|
||||
|
||||
/* Function to open a joystick for use.
|
||||
The joystick to open is specified by the index field of the joystick.
|
||||
The joystick to open is specified by the device index.
|
||||
This should fill the nbuttons and naxes fields of the joystick structure.
|
||||
It returns 0, or -1 if there is an error.
|
||||
*/
|
||||
|
@ -623,7 +624,7 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
|
|||
/* Function to determine is this joystick is attached to the system right now */
|
||||
SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
|
||||
{
|
||||
return !joystick->closed && (joystick->hwdata->item != NULL);
|
||||
return joystick->hwdata->item != NULL;
|
||||
}
|
||||
|
||||
static SDL_INLINE void
|
||||
|
@ -840,9 +841,7 @@ SDL_SYS_JoystickClose(SDL_Joystick * joystick)
|
|||
SDL_free(joystick->hwdata->balls);
|
||||
SDL_free(joystick->hwdata->fname);
|
||||
SDL_free(joystick->hwdata);
|
||||
joystick->hwdata = NULL;
|
||||
}
|
||||
joystick->closed = 1;
|
||||
}
|
||||
|
||||
/* Function to perform any system-specific joystick related cleanup */
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_JOYSTICK_PSP
|
||||
|
||||
/* This is the PSP implementation of the SDL joystick API */
|
||||
#include <pspctrl.h>
|
||||
|
@ -161,7 +164,7 @@ const char *SDL_SYS_JoystickName(int index)
|
|||
}
|
||||
|
||||
/* Function to open a joystick for use.
|
||||
The joystick to open is specified by the index field of the joystick.
|
||||
The joystick to open is specified by the device index.
|
||||
This should fill the nbuttons and naxes fields of the joystick structure.
|
||||
It returns 0, or -1 if there is an error.
|
||||
*/
|
||||
|
@ -179,12 +182,12 @@ SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
|
|||
{
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
/* Function to update the state of a joystick - called as a device poll.
|
||||
* This function shouldn't update the joystick structure directly,
|
||||
* but instead should call SDL_PrivateJoystick*() to deliver events
|
||||
* and update joystick device state.
|
||||
*/
|
||||
|
||||
void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
|
||||
{
|
||||
int i;
|
||||
|
@ -230,7 +233,6 @@ void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick)
|
|||
/* Function to close a joystick after use */
|
||||
void SDL_SYS_JoystickClose(SDL_Joystick *joystick)
|
||||
{
|
||||
/* Do nothing. */
|
||||
}
|
||||
|
||||
/* Function to perform any system-specific joystick related cleanup */
|
||||
|
@ -262,5 +264,7 @@ SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick)
|
|||
return guid;
|
||||
}
|
||||
|
||||
#endif /* SDL_JOYSTICK_PSP */
|
||||
|
||||
/* vim: ts=4 sw=4
|
||||
*/
|
||||
|
|
|
@ -210,7 +210,7 @@ SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
|
|||
}
|
||||
|
||||
/* Function to open a joystick for use.
|
||||
The joystick to open is specified by the index field of the joystick.
|
||||
The joystick to open is specified by the device index.
|
||||
This should fill the nbuttons and naxes fields of the joystick structure.
|
||||
It returns 0, or -1 if there is an error.
|
||||
*/
|
||||
|
@ -383,9 +383,7 @@ SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
|
|||
void
|
||||
SDL_SYS_JoystickClose(SDL_Joystick * joystick)
|
||||
{
|
||||
/* free system specific hardware data */
|
||||
SDL_free(joystick->hwdata);
|
||||
joystick->hwdata = NULL;
|
||||
}
|
||||
|
||||
/* Function to perform any system-specific joystick related cleanup */
|
||||
|
|
|
@ -446,7 +446,7 @@ SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
|
|||
}
|
||||
|
||||
/* Function to open a joystick for use.
|
||||
The joystick to open is specified by the index field of the joystick.
|
||||
The joystick to open is specified by the device index.
|
||||
This should fill the nbuttons and naxes fields of the joystick structure.
|
||||
It returns 0, or -1 if there is an error.
|
||||
*/
|
||||
|
@ -460,7 +460,6 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
|
|||
|
||||
/* allocate memory for system specific hardware data */
|
||||
joystick->instance_id = joystickdevice->nInstanceID;
|
||||
joystick->closed = SDL_FALSE;
|
||||
joystick->hwdata =
|
||||
(struct joystick_hwdata *) SDL_malloc(sizeof(struct joystick_hwdata));
|
||||
if (joystick->hwdata == NULL) {
|
||||
|
@ -480,13 +479,13 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
|
|||
SDL_bool
|
||||
SDL_SYS_JoystickAttached(SDL_Joystick * joystick)
|
||||
{
|
||||
return !joystick->closed && !joystick->hwdata->removed;
|
||||
return joystick->hwdata && !joystick->hwdata->removed;
|
||||
}
|
||||
|
||||
void
|
||||
SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
|
||||
{
|
||||
if (joystick->closed || !joystick->hwdata) {
|
||||
if (!joystick->hwdata || joystick->hwdata->removed) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -497,8 +496,7 @@ SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
|
|||
}
|
||||
|
||||
if (joystick->hwdata->removed) {
|
||||
joystick->closed = SDL_TRUE;
|
||||
joystick->uncentered = SDL_TRUE;
|
||||
joystick->force_recentering = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -512,10 +510,7 @@ SDL_SYS_JoystickClose(SDL_Joystick * joystick)
|
|||
SDL_DINPUT_JoystickClose(joystick);
|
||||
}
|
||||
|
||||
/* free system specific hardware data */
|
||||
SDL_free(joystick->hwdata);
|
||||
|
||||
joystick->closed = SDL_TRUE;
|
||||
}
|
||||
|
||||
/* Function to perform any system-specific joystick related cleanup */
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
/*
|
||||
SDL_psp_main.c, placed in the public domain by Sam Lantinga 3/13/14
|
||||
*/
|
||||
#include "SDL_config.h"
|
||||
|
||||
#ifdef __PSP__
|
||||
|
||||
#include "SDL_main.h"
|
||||
#include <pspkernel.h>
|
||||
|
@ -61,3 +64,7 @@ int main(int argc, char *argv[])
|
|||
(void)SDL_main(argc, argv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* __PSP__ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
@ -109,13 +109,16 @@ OutOfMemory(void)
|
|||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
/* The VC++ compiler needs main defined */
|
||||
#define console_main main
|
||||
/* The VC++ compiler needs main/wmain defined */
|
||||
# define console_ansi_main main
|
||||
# if UNICODE
|
||||
# define console_wmain wmain
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* This is where execution begins [console apps] */
|
||||
int
|
||||
console_main(int argc, char *argv[])
|
||||
/* WinMain, main, and wmain eventually call into here. */
|
||||
static int
|
||||
main_utf8(int argc, char *argv[])
|
||||
{
|
||||
SDL_SetMainReady();
|
||||
|
||||
|
@ -123,6 +126,37 @@ console_main(int argc, char *argv[])
|
|||
return SDL_main(argc, argv);
|
||||
}
|
||||
|
||||
/* This is where execution begins [console apps, ansi] */
|
||||
int
|
||||
console_ansi_main(int argc, char *argv[])
|
||||
{
|
||||
/* !!! FIXME: are these in the system codepage? We need to convert to UTF-8. */
|
||||
return main_utf8(argc, argv);
|
||||
}
|
||||
|
||||
|
||||
#if UNICODE
|
||||
/* This is where execution begins [console apps, unicode] */
|
||||
int
|
||||
console_wmain(int argc, wchar_t *wargv[], wchar_t *wenvp)
|
||||
{
|
||||
int retval = 0;
|
||||
char **argv = SDL_stack_alloc(char*, argc);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < argc; ++i) {
|
||||
argv[i] = WIN_StringToUTF8(wargv[i]);
|
||||
}
|
||||
|
||||
retval = main_utf8(argc, argv);
|
||||
|
||||
/* !!! FIXME: we are leaking all the elements of argv we allocated. */
|
||||
SDL_stack_free(argv);
|
||||
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* This is where execution begins [windowed apps] */
|
||||
int WINAPI
|
||||
WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
|
||||
|
@ -136,6 +170,7 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
|
|||
#if UNICODE
|
||||
cmdline = WIN_StringToUTF8(text);
|
||||
#else
|
||||
/* !!! FIXME: are these in the system codepage? We need to convert to UTF-8. */
|
||||
cmdline = SDL_strdup(text);
|
||||
#endif
|
||||
if (cmdline == NULL) {
|
||||
|
@ -151,7 +186,7 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
|
|||
ParseCommandLine(cmdline, argv);
|
||||
|
||||
/* Run the main program */
|
||||
console_main(argc, argv);
|
||||
main_utf8(argc, argv);
|
||||
|
||||
SDL_stack_free(argv);
|
||||
|
||||
|
|
|
@ -829,9 +829,24 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags)
|
|||
renderer->info.flags = (SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);
|
||||
renderer->driverdata = data;
|
||||
|
||||
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
|
||||
/* VSync is required in Windows Phone, at least for Win Phone 8.0 and 8.1.
|
||||
* Failure to use it seems to either result in:
|
||||
*
|
||||
* - with the D3D11 debug runtime turned OFF, vsync seemingly gets turned
|
||||
* off (framerate doesn't get capped), but nothing appears on-screen
|
||||
*
|
||||
* - with the D3D11 debug runtime turned ON, vsync gets automatically
|
||||
* turned back on, and the following gets output to the debug console:
|
||||
*
|
||||
* DXGI ERROR: IDXGISwapChain::Present: Interval 0 is not supported, changed to Interval 1. [ UNKNOWN ERROR #1024: ]
|
||||
*/
|
||||
renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
|
||||
#else
|
||||
if ((flags & SDL_RENDERER_PRESENTVSYNC)) {
|
||||
renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* HACK: make sure the SDL_Renderer references the SDL_Window data now, in
|
||||
* order to give init functions access to the underlying window handle:
|
||||
|
|
|
@ -342,9 +342,11 @@ GL_HandleDebugMessage(GLenum source, GLenum type, GLuint id, GLenum severity, GL
|
|||
|
||||
if (type == GL_DEBUG_TYPE_ERROR_ARB) {
|
||||
/* Record this error */
|
||||
++data->errors;
|
||||
data->error_messages = SDL_realloc(data->error_messages, data->errors * sizeof(*data->error_messages));
|
||||
if (data->error_messages) {
|
||||
int errors = data->errors + 1;
|
||||
char **error_messages = SDL_realloc(data->error_messages, errors * sizeof(*data->error_messages));
|
||||
if (error_messages) {
|
||||
data->errors = errors;
|
||||
data->error_messages = error_messages;
|
||||
data->error_messages[data->errors-1] = SDL_strdup(message);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1204,10 +1204,10 @@ SDLTest_PrintEvent(SDL_Event * event)
|
|||
event->tfinger.dx, event->tfinger.dy, event->tfinger.pressure);
|
||||
break;
|
||||
case SDL_DOLLARGESTURE:
|
||||
SDL_Log("SDL_EVENT: Dollar gesture detect: %"SDL_PRIs64, (long long) event->dgesture.gestureId);
|
||||
SDL_Log("SDL_EVENT: Dollar gesture detect: %"SDL_PRIs64, (Sint64) event->dgesture.gestureId);
|
||||
break;
|
||||
case SDL_DOLLARRECORD:
|
||||
SDL_Log("SDL_EVENT: Dollar gesture record: %"SDL_PRIs64, (long long) event->dgesture.gestureId);
|
||||
SDL_Log("SDL_EVENT: Dollar gesture record: %"SDL_PRIs64, (Sint64) event->dgesture.gestureId);
|
||||
break;
|
||||
case SDL_MULTIGESTURE:
|
||||
SDL_Log("SDL_EVENT: Multi gesture fingers: %d", event->mgesture.numFingers);
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_THREAD_PSP
|
||||
|
||||
/* An implementation of condition variables using semaphores and mutexes */
|
||||
/*
|
||||
This implementation borrows heavily from the BeOS condition variable
|
||||
|
@ -217,4 +219,6 @@ SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex)
|
|||
return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT);
|
||||
}
|
||||
|
||||
#endif /* SDL_THREAD_PSP */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_THREAD_PSP
|
||||
|
||||
/* An implementation of mutexes using semaphores */
|
||||
|
||||
#include "SDL_thread.h"
|
||||
|
@ -129,4 +131,6 @@ SDL_mutexV(SDL_mutex * mutex)
|
|||
#endif /* SDL_THREADS_DISABLED */
|
||||
}
|
||||
|
||||
#endif /* SDL_THREAD_PSP */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_THREAD_PSP
|
||||
|
||||
/* Semaphore functions for the PSP. */
|
||||
|
||||
|
@ -152,5 +155,7 @@ int SDL_SemPost(SDL_sem *sem)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#endif /* SDL_THREAD_PSP */
|
||||
|
||||
/* vim: ts=4 sw=4
|
||||
*/
|
||||
|
|
|
@ -18,7 +18,9 @@
|
|||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_THREAD_PSP
|
||||
|
||||
/* PSP thread management routines for SDL */
|
||||
|
||||
|
@ -104,5 +106,7 @@ int SDL_SYS_SetThreadPriority(SDL_ThreadPriority priority)
|
|||
|
||||
}
|
||||
|
||||
#endif /* SDL_THREAD_PSP */
|
||||
|
||||
/* vim: ts=4 sw=4
|
||||
*/
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#ifdef SDL_TIMERS_PSP
|
||||
|
||||
#include "SDL_thread.h"
|
||||
#include "SDL_timer.h"
|
||||
|
@ -82,5 +85,7 @@ void SDL_Delay(Uint32 ms)
|
|||
sceKernelDelayThreadCB(ms * 1000);
|
||||
}
|
||||
|
||||
#endif /* SDL_TIMERS_PSP */
|
||||
|
||||
/* vim: ts=4 sw=4
|
||||
*/
|
||||
|
|
|
@ -306,16 +306,19 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc)
|
|||
biClrUsed = 1 << biBitCount;
|
||||
}
|
||||
if ((int) biClrUsed > palette->ncolors) {
|
||||
palette->ncolors = biClrUsed;
|
||||
palette->colors =
|
||||
SDL_Color *colors;
|
||||
int ncolors = biClrUsed;
|
||||
colors =
|
||||
(SDL_Color *) SDL_realloc(palette->colors,
|
||||
palette->ncolors *
|
||||
ncolors *
|
||||
sizeof(*palette->colors));
|
||||
if (!palette->colors) {
|
||||
if (!colors) {
|
||||
SDL_OutOfMemory();
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
}
|
||||
palette->ncolors = ncolors;
|
||||
palette->colors = colors;
|
||||
} else if ((int) biClrUsed < palette->ncolors) {
|
||||
palette->ncolors = biClrUsed;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,10 @@ SDL_SetClipboardText(const char *text)
|
|||
{
|
||||
SDL_VideoDevice *_this = SDL_GetVideoDevice();
|
||||
|
||||
if (!_this) {
|
||||
return SDL_SetError("Video subsystem must be initialized to set clipboard text");
|
||||
}
|
||||
|
||||
if (!text) {
|
||||
text = "";
|
||||
}
|
||||
|
@ -46,6 +50,11 @@ SDL_GetClipboardText(void)
|
|||
{
|
||||
SDL_VideoDevice *_this = SDL_GetVideoDevice();
|
||||
|
||||
if (!_this) {
|
||||
SDL_SetError("Video subsystem must be initialized to get clipboard text");
|
||||
return SDL_strdup("");
|
||||
}
|
||||
|
||||
if (_this->GetClipboardText) {
|
||||
return _this->GetClipboardText(_this);
|
||||
} else {
|
||||
|
@ -62,6 +71,11 @@ SDL_HasClipboardText(void)
|
|||
{
|
||||
SDL_VideoDevice *_this = SDL_GetVideoDevice();
|
||||
|
||||
if (!_this) {
|
||||
SDL_SetError("Video subsystem must be initialized to check clipboard text");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (_this->HasClipboardText) {
|
||||
return _this->HasClipboardText(_this);
|
||||
} else {
|
||||
|
|
|
@ -251,6 +251,10 @@ SDL_FillRect(SDL_Surface * dst, const SDL_Rect * rect, Uint32 color)
|
|||
rect = &clipped;
|
||||
} else {
|
||||
rect = &dst->clip_rect;
|
||||
/* Don't attempt to fill if the surface's clip_rect is empty */
|
||||
if (SDL_RectEmpty(rect)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Perform software fill */
|
||||
|
|
|
@ -274,6 +274,7 @@ struct SDL_VideoDevice
|
|||
int num_displays;
|
||||
SDL_VideoDisplay *displays;
|
||||
SDL_Window *windows;
|
||||
SDL_Window *grabbed_window;
|
||||
Uint8 window_magic;
|
||||
Uint32 next_object_id;
|
||||
char * clipboard_text;
|
||||
|
@ -303,6 +304,7 @@ struct SDL_VideoDevice
|
|||
int flags;
|
||||
int profile_mask;
|
||||
int share_with_current_context;
|
||||
int release_behavior;
|
||||
int framebuffer_srgb_capable;
|
||||
int retained_backing;
|
||||
int driver_loaded;
|
||||
|
|
|
@ -46,6 +46,10 @@
|
|||
#include "SDL_opengles2.h"
|
||||
#endif /* SDL_VIDEO_OPENGL_ES2 && !SDL_VIDEO_OPENGL */
|
||||
|
||||
#ifndef GL_CONTEXT_RELEASE_BEHAVIOR_KHR
|
||||
#define GL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x82FB
|
||||
#endif
|
||||
|
||||
/* On Windows, windows.h defines CreateWindow */
|
||||
#ifdef CreateWindow
|
||||
#undef CreateWindow
|
||||
|
@ -1612,13 +1616,14 @@ SDL_SetWindowPosition(SDL_Window * window, int x, int y)
|
|||
CHECK_WINDOW_MAGIC(window,);
|
||||
|
||||
if (SDL_WINDOWPOS_ISCENTERED(x) || SDL_WINDOWPOS_ISCENTERED(y)) {
|
||||
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
|
||||
int displayIndex;
|
||||
int displayIndex = (x & 0xFFFF);
|
||||
SDL_Rect bounds;
|
||||
if (displayIndex > _this->num_displays) {
|
||||
displayIndex = 0;
|
||||
}
|
||||
|
||||
SDL_zero(bounds);
|
||||
|
||||
displayIndex = SDL_GetIndexOfDisplay(display);
|
||||
SDL_GetDisplayBounds(displayIndex, &bounds);
|
||||
if (SDL_WINDOWPOS_ISCENTERED(x)) {
|
||||
x = bounds.x + (bounds.w - window->w) / 2;
|
||||
|
@ -2114,6 +2119,7 @@ void
|
|||
SDL_UpdateWindowGrab(SDL_Window * window)
|
||||
{
|
||||
if (_this->SetWindowGrab) {
|
||||
SDL_Window *grabbed_window;
|
||||
SDL_bool grabbed;
|
||||
if ((SDL_GetMouse()->relative_mode || (window->flags & SDL_WINDOW_INPUT_GRABBED)) &&
|
||||
(window->flags & SDL_WINDOW_INPUT_FOCUS)) {
|
||||
|
@ -2121,6 +2127,19 @@ SDL_UpdateWindowGrab(SDL_Window * window)
|
|||
} else {
|
||||
grabbed = SDL_FALSE;
|
||||
}
|
||||
|
||||
grabbed_window = _this->grabbed_window;
|
||||
if (grabbed) {
|
||||
if (grabbed_window && (grabbed_window != window)) {
|
||||
/* stealing a grab from another window! */
|
||||
grabbed_window->flags &= ~SDL_WINDOW_INPUT_GRABBED;
|
||||
_this->SetWindowGrab(_this, grabbed_window, SDL_FALSE);
|
||||
}
|
||||
_this->grabbed_window = window;
|
||||
} else if (grabbed_window == window) {
|
||||
_this->grabbed_window = NULL; /* ungrabbing. */
|
||||
}
|
||||
|
||||
_this->SetWindowGrab(_this, window, grabbed);
|
||||
}
|
||||
}
|
||||
|
@ -2145,8 +2164,15 @@ SDL_bool
|
|||
SDL_GetWindowGrab(SDL_Window * window)
|
||||
{
|
||||
CHECK_WINDOW_MAGIC(window, SDL_FALSE);
|
||||
SDL_assert(!_this->grabbed_window || ((_this->grabbed_window->flags & SDL_WINDOW_INPUT_GRABBED) != 0));
|
||||
return window == _this->grabbed_window;
|
||||
}
|
||||
|
||||
return ((window->flags & SDL_WINDOW_INPUT_GRABBED) != 0);
|
||||
SDL_Window *
|
||||
SDL_GetGrabbedWindow(void)
|
||||
{
|
||||
SDL_assert(!_this->grabbed_window || ((_this->grabbed_window->flags & SDL_WINDOW_INPUT_GRABBED) != 0));
|
||||
return _this->grabbed_window;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2639,6 +2665,7 @@ SDL_GL_ResetAttributes()
|
|||
#endif
|
||||
_this->gl_config.flags = 0;
|
||||
_this->gl_config.framebuffer_srgb_capable = 0;
|
||||
_this->gl_config.release_behavior = SDL_GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH;
|
||||
|
||||
_this->gl_config.share_with_current_context = 0;
|
||||
}
|
||||
|
@ -2745,6 +2772,9 @@ SDL_GL_SetAttribute(SDL_GLattr attr, int value)
|
|||
case SDL_GL_FRAMEBUFFER_SRGB_CAPABLE:
|
||||
_this->gl_config.framebuffer_srgb_capable = value;
|
||||
break;
|
||||
case SDL_GL_CONTEXT_RELEASE_BEHAVIOR:
|
||||
_this->gl_config.release_behavior = value;
|
||||
break;
|
||||
default:
|
||||
retval = SDL_SetError("Unknown OpenGL attribute");
|
||||
break;
|
||||
|
@ -2845,6 +2875,13 @@ SDL_GL_GetAttribute(SDL_GLattr attr, int *value)
|
|||
attrib = GL_SAMPLES_ARB;
|
||||
#else
|
||||
attrib = GL_SAMPLES;
|
||||
#endif
|
||||
break;
|
||||
case SDL_GL_CONTEXT_RELEASE_BEHAVIOR:
|
||||
#if SDL_VIDEO_OPENGL
|
||||
attrib = GL_CONTEXT_RELEASE_BEHAVIOR;
|
||||
#else
|
||||
attrib = GL_CONTEXT_RELEASE_BEHAVIOR_KHR;
|
||||
#endif
|
||||
break;
|
||||
case SDL_GL_BUFFER_SIZE:
|
||||
|
|
|
@ -32,8 +32,14 @@
|
|||
|
||||
void android_egl_context_backup();
|
||||
void android_egl_context_restore();
|
||||
|
||||
#if SDL_AUDIO_DRIVER_ANDROID
|
||||
void AndroidAUD_ResumeDevices(void);
|
||||
void AndroidAUD_PauseDevices(void);
|
||||
#else
|
||||
static void AndroidAUD_ResumeDevices(void) {}
|
||||
static void AndroidAUD_PauseDevices(void) {}
|
||||
#endif
|
||||
|
||||
void
|
||||
android_egl_context_restore()
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_config.h"
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_VIDEO_DRIVER_ANDROID
|
||||
|
||||
|
|
84
src/video/android/SDL_androidmouse.c
Normal file
84
src/video/android/SDL_androidmouse.c
Normal file
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_VIDEO_DRIVER_ANDROID
|
||||
|
||||
#include "SDL_androidmouse.h"
|
||||
|
||||
#include "SDL_events.h"
|
||||
#include "../../events/SDL_mouse_c.h"
|
||||
|
||||
#include "../../core/android/SDL_android.h"
|
||||
|
||||
#define ACTION_DOWN 0
|
||||
#define ACTION_UP 1
|
||||
#define ACTION_HOVER_MOVE 7
|
||||
#define ACTION_SCROLL 8
|
||||
#define BUTTON_PRIMARY 1
|
||||
#define BUTTON_SECONDARY 2
|
||||
#define BUTTON_TERTIARY 4
|
||||
|
||||
void Android_OnMouse( int androidButton, int action, float x, float y) {
|
||||
static Uint8 SDLButton;
|
||||
|
||||
if (!Android_Window) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch(action) {
|
||||
case ACTION_DOWN:
|
||||
// Determine which button originated the event, and store it for ACTION_UP
|
||||
SDLButton = SDL_BUTTON_LEFT;
|
||||
if (androidButton == BUTTON_SECONDARY) {
|
||||
SDLButton = SDL_BUTTON_RIGHT;
|
||||
} else if (androidButton == BUTTON_TERTIARY) {
|
||||
SDLButton = SDL_BUTTON_MIDDLE;
|
||||
}
|
||||
SDL_SendMouseMotion(Android_Window, 0, 0, x, y);
|
||||
SDL_SendMouseButton(Android_Window, 0, SDL_PRESSED, SDLButton);
|
||||
break;
|
||||
|
||||
case ACTION_UP:
|
||||
// Android won't give us the button that originated the ACTION_DOWN event, so we'll
|
||||
// assume it's the one we stored
|
||||
SDL_SendMouseMotion(Android_Window, 0, 0, x, y);
|
||||
SDL_SendMouseButton(Android_Window, 0, SDL_RELEASED, SDLButton);
|
||||
break;
|
||||
|
||||
case ACTION_HOVER_MOVE:
|
||||
SDL_SendMouseMotion(Android_Window, 0, 0, x, y);
|
||||
break;
|
||||
|
||||
case ACTION_SCROLL:
|
||||
SDL_SendMouseWheel(Android_Window, 0, x, y, SDL_MOUSEWHEEL_NORMAL);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_ANDROID */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
31
src/video/android/SDL_androidmouse.h
Normal file
31
src/video/android/SDL_androidmouse.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef _SDL_androidmouse_h
|
||||
#define _SDL_androidmouse_h
|
||||
|
||||
#include "SDL_androidvideo.h"
|
||||
|
||||
extern void Android_OnMouse( int button, int action, float x, float y);
|
||||
|
||||
#endif /* _SDL_androidmouse_h */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue