Merge SDL-ryan-batching-renderer branch to default.

This commit is contained in:
Ryan C. Gordon 2018-10-31 15:03:41 -04:00
commit 62494a2e27
215 changed files with 5146 additions and 2712 deletions

View File

@ -102,7 +102,7 @@ include $(CLEAR_VARS)
LOCAL_CPPFLAGS += -std=c++11 LOCAL_CPPFLAGS += -std=c++11
LOCAL_SRC_FILES := $(LOCAL_PATH)/src/hidapi/android/hid.cpp LOCAL_SRC_FILES := src/hidapi/android/hid.cpp
LOCAL_MODULE := libhidapi LOCAL_MODULE := libhidapi
LOCAL_LDLIBS := -llog LOCAL_LDLIBS := -llog

View File

@ -42,10 +42,13 @@ include(${SDL2_SOURCE_DIR}/cmake/sdlchecks.cmake)
# set SDL_BINARY_AGE and SDL_INTERFACE_AGE to 0. # set SDL_BINARY_AGE and SDL_INTERFACE_AGE to 0.
set(SDL_MAJOR_VERSION 2) set(SDL_MAJOR_VERSION 2)
set(SDL_MINOR_VERSION 0) set(SDL_MINOR_VERSION 0)
set(SDL_MICRO_VERSION 8) set(SDL_MICRO_VERSION 9)
set(SDL_INTERFACE_AGE 0) set(SDL_INTERFACE_AGE 0)
set(SDL_BINARY_AGE 8) set(SDL_BINARY_AGE 9)
set(SDL_VERSION "${SDL_MAJOR_VERSION}.${SDL_MINOR_VERSION}.${SDL_MICRO_VERSION}") set(SDL_VERSION "${SDL_MAJOR_VERSION}.${SDL_MINOR_VERSION}.${SDL_MICRO_VERSION}")
# the following should match the versions in Xcode project file:
set(DYLIB_CURRENT_VERSION 10.0.0)
set(DYLIB_COMPATIBILITY_VERSION 1.0.0)
# Set defaults preventing destination file conflicts # Set defaults preventing destination file conflicts
set(SDL_CMAKE_DEBUG_POSTFIX "d" set(SDL_CMAKE_DEBUG_POSTFIX "d"
@ -334,7 +337,7 @@ foreach(_SUB ${SDL_X11_OPTIONS})
endforeach() endforeach()
set_option(VIDEO_COCOA "Use Cocoa video driver" ${APPLE}) set_option(VIDEO_COCOA "Use Cocoa video driver" ${APPLE})
set_option(DIRECTX "Use DirectX for Windows audio/video" ${WINDOWS}) set_option(DIRECTX "Use DirectX for Windows audio/video" ${WINDOWS})
dep_option(WASAPI "Use the Windows WASAPI audio driver" ON "DIRECTX" OFF) set_option(WASAPI "Use the Windows WASAPI audio driver" ${WINDOWS})
set_option(RENDER_D3D "Enable the Direct3D render driver" ${WINDOWS}) set_option(RENDER_D3D "Enable the Direct3D render driver" ${WINDOWS})
set_option(VIDEO_VIVANTE "Use Vivante EGL video driver" ${UNIX_SYS}) set_option(VIDEO_VIVANTE "Use Vivante EGL video driver" ${UNIX_SYS})
dep_option(VIDEO_VULKAN "Enable Vulkan support" ON "ANDROID OR APPLE OR LINUX OR WINDOWS" OFF) dep_option(VIDEO_VULKAN "Enable Vulkan support" ON "ANDROID OR APPLE OR LINUX OR WINDOWS" OFF)
@ -451,6 +454,8 @@ if(USE_GCC OR USE_CLANG)
if(APPLE) if(APPLE)
list(APPEND EXTRA_LDFLAGS "-Wl,-undefined,error") list(APPEND EXTRA_LDFLAGS "-Wl,-undefined,error")
list(APPEND EXTRA_LDFLAGS "-Wl,-compatibility_version,${DYLIB_COMPATIBILITY_VERSION}")
list(APPEND EXTRA_LDFLAGS "-Wl,-current_version,${DYLIB_CURRENT_VERSION}")
else() else()
set(CMAKE_REQUIRED_FLAGS "-Wl,--no-undefined") set(CMAKE_REQUIRED_FLAGS "-Wl,--no-undefined")
check_c_compiler_flag("" HAVE_NO_UNDEFINED) check_c_compiler_flag("" HAVE_NO_UNDEFINED)
@ -1059,6 +1064,12 @@ elseif(UNIX AND NOT APPLE AND NOT ANDROID)
include_directories(${IBUS_INCLUDE_DIRS}) include_directories(${IBUS_INCLUDE_DIRS})
list(APPEND EXTRA_LIBS ${IBUS_LIBRARIES}) list(APPEND EXTRA_LIBS ${IBUS_LIBRARIES})
endif() endif()
if(HAVE_LIBUNWIND_H)
# We've already found the header, so REQUIRE the lib to be present
pkg_search_module(UNWIND REQUIRED libunwind)
pkg_search_module(UNWIND_GENERIC REQUIRED libunwind-generic)
list(APPEND EXTRA_LIBS ${UNWIND_LIBRARIES} ${UNWIND_GENERIC_LIBRARIES})
endif()
endif() endif()
check_include_file("fcitx/frontend.h" HAVE_FCITX_FRONTEND_H) check_include_file("fcitx/frontend.h" HAVE_FCITX_FRONTEND_H)
@ -1200,8 +1211,6 @@ elseif(WINDOWS)
check_include_file(ddraw.h HAVE_DDRAW_H) check_include_file(ddraw.h HAVE_DDRAW_H)
check_include_file(dsound.h HAVE_DSOUND_H) check_include_file(dsound.h HAVE_DSOUND_H)
check_include_file(dinput.h HAVE_DINPUT_H) check_include_file(dinput.h HAVE_DINPUT_H)
check_include_file(mmdeviceapi.h HAVE_MMDEVICEAPI_H)
check_include_file(audioclient.h HAVE_AUDIOCLIENT_H)
check_include_file(dxgi.h HAVE_DXGI_H) check_include_file(dxgi.h HAVE_DXGI_H)
if(HAVE_D3D_H OR HAVE_D3D11_H OR HAVE_DDRAW_H OR HAVE_DSOUND_H OR HAVE_DINPUT_H) if(HAVE_D3D_H OR HAVE_D3D11_H OR HAVE_DDRAW_H OR HAVE_DSOUND_H OR HAVE_DINPUT_H)
set(HAVE_DIRECTX TRUE) set(HAVE_DIRECTX TRUE)
@ -1214,6 +1223,11 @@ elseif(WINDOWS)
set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS}) set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
endif() endif()
# headers needed elsewhere ...
check_include_file(mmdeviceapi.h HAVE_MMDEVICEAPI_H)
check_include_file(audioclient.h HAVE_AUDIOCLIENT_H)
check_include_file(endpointvolume.h HAVE_ENDPOINTVOLUME_H)
if(SDL_AUDIO) if(SDL_AUDIO)
set(SDL_AUDIO_DRIVER_WINMM 1) set(SDL_AUDIO_DRIVER_WINMM 1)
file(GLOB WINMM_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/winmm/*.c) file(GLOB WINMM_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/winmm/*.c)
@ -1544,6 +1558,7 @@ endif()
if(VIDEO_VULKAN) if(VIDEO_VULKAN)
set(SDL_VIDEO_VULKAN 1) set(SDL_VIDEO_VULKAN 1)
set(HAVE_VIDEO_VULKAN TRUE)
endif() endif()
# Dummies # Dummies
@ -1555,7 +1570,7 @@ endif()
# This leads to missing internal references on building, since the # This leads to missing internal references on building, since the
# src/X/*.c does not get included. # src/X/*.c does not get included.
if(NOT HAVE_SDL_JOYSTICK) if(NOT HAVE_SDL_JOYSTICK)
set(SDL_JOYSTICK_DISABLED 1) set(SDL_JOYSTICK_DUMMY 1)
if(SDL_JOYSTICK AND NOT APPLE) # results in unresolved symbols on OSX if(SDL_JOYSTICK AND NOT APPLE) # results in unresolved symbols on OSX
file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/dummy/*.c) file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/dummy/*.c)
@ -1563,10 +1578,15 @@ if(NOT HAVE_SDL_JOYSTICK)
endif() endif()
endif() endif()
if(NOT HAVE_SDL_HAPTIC) if(NOT HAVE_SDL_HAPTIC)
set(SDL_HAPTIC_DISABLED 1) set(SDL_HAPTIC_DUMMY 1)
file(GLOB HAPTIC_SOURCES ${SDL2_SOURCE_DIR}/src/haptic/dummy/*.c) file(GLOB HAPTIC_SOURCES ${SDL2_SOURCE_DIR}/src/haptic/dummy/*.c)
set(SOURCE_FILES ${SOURCE_FILES} ${HAPTIC_SOURCES}) set(SOURCE_FILES ${SOURCE_FILES} ${HAPTIC_SOURCES})
endif() endif()
if(NOT HAVE_SDL_SENSORS)
set(SDL_SENSOR_DUMMY 1)
file(GLOB SENSORS_SOURCES ${SDL2_SOURCE_DIR}/src/sensor/dummy/*.c)
set(SOURCE_FILES ${SOURCE_FILES} ${SENSORS_SOURCES})
endif()
if(NOT HAVE_SDL_LOADSO) if(NOT HAVE_SDL_LOADSO)
set(SDL_LOADSO_DISABLED 1) set(SDL_LOADSO_DISABLED 1)
file(GLOB LOADSO_SOURCES ${SDL2_SOURCE_DIR}/src/loadso/dummy/*.c) file(GLOB LOADSO_SOURCES ${SDL2_SOURCE_DIR}/src/loadso/dummy/*.c)
@ -1577,11 +1597,6 @@ if(NOT HAVE_SDL_FILESYSTEM)
file(GLOB FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/dummy/*.c) file(GLOB FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/dummy/*.c)
set(SOURCE_FILES ${SOURCE_FILES} ${FILESYSTEM_SOURCES}) set(SOURCE_FILES ${SOURCE_FILES} ${FILESYSTEM_SOURCES})
endif() endif()
if(NOT HAVE_SDL_SENSORS)
set(SDL_SENSOR_DISABLED 1)
file(GLOB SENSORS_SOURCES ${SDL2_SOURCE_DIR}/src/sensor/dummy/*.c)
set(SOURCE_FILES ${SOURCE_FILES} ${SENSORS_SOURCES})
endif()
# We always need to have threads and timers around # We always need to have threads and timers around
if(NOT HAVE_SDL_THREADS) if(NOT HAVE_SDL_THREADS)
@ -1717,7 +1732,7 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
# Always build SDLmain # Always build SDLmain
add_library(SDL2main STATIC ${SDLMAIN_SOURCES}) add_library(SDL2main STATIC ${SDLMAIN_SOURCES})
target_include_directories(SDL2main PUBLIC $<INSTALL_INTERFACE:include/SDL2>) target_include_directories(SDL2main PUBLIC "$<BUILD_INTERFACE:${SDL2_SOURCE_DIR}/include>" $<INSTALL_INTERFACE:include/SDL2>)
set(_INSTALL_LIBS "SDL2main") set(_INSTALL_LIBS "SDL2main")
if (NOT ANDROID) if (NOT ANDROID)
set_target_properties(SDL2main PROPERTIES DEBUG_POSTFIX ${SDL_CMAKE_DEBUG_POSTFIX}) set_target_properties(SDL2main PROPERTIES DEBUG_POSTFIX ${SDL_CMAKE_DEBUG_POSTFIX})
@ -1726,7 +1741,9 @@ endif()
if(SDL_SHARED) if(SDL_SHARED)
add_library(SDL2 SHARED ${SOURCE_FILES} ${VERSION_SOURCES}) add_library(SDL2 SHARED ${SOURCE_FILES} ${VERSION_SOURCES})
if(APPLE) if(APPLE)
set_target_properties(SDL2 PROPERTIES MACOSX_RPATH 1) set_target_properties(SDL2 PROPERTIES
MACOSX_RPATH 1
OUTPUT_NAME "SDL2-${LT_RELEASE}")
elseif(UNIX AND NOT ANDROID) elseif(UNIX AND NOT ANDROID)
set_target_properties(SDL2 PROPERTIES set_target_properties(SDL2 PROPERTIES
VERSION ${LT_VERSION} VERSION ${LT_VERSION}
@ -1746,7 +1763,7 @@ if(SDL_SHARED)
endif() endif()
set(_INSTALL_LIBS "SDL2" ${_INSTALL_LIBS}) set(_INSTALL_LIBS "SDL2" ${_INSTALL_LIBS})
target_link_libraries(SDL2 ${EXTRA_LIBS} ${EXTRA_LDFLAGS}) target_link_libraries(SDL2 ${EXTRA_LIBS} ${EXTRA_LDFLAGS})
target_include_directories(SDL2 PUBLIC $<INSTALL_INTERFACE:include/SDL2>) target_include_directories(SDL2 PUBLIC "$<BUILD_INTERFACE:${SDL2_SOURCE_DIR}/include>" $<INSTALL_INTERFACE:include/SDL2>)
if (NOT ANDROID) if (NOT ANDROID)
set_target_properties(SDL2 PROPERTIES DEBUG_POSTFIX ${SDL_CMAKE_DEBUG_POSTFIX}) set_target_properties(SDL2 PROPERTIES DEBUG_POSTFIX ${SDL_CMAKE_DEBUG_POSTFIX})
endif() endif()
@ -1772,7 +1789,7 @@ if(SDL_STATIC)
# libraries - do we need to consider this? # libraries - do we need to consider this?
set(_INSTALL_LIBS "SDL2-static" ${_INSTALL_LIBS}) set(_INSTALL_LIBS "SDL2-static" ${_INSTALL_LIBS})
target_link_libraries(SDL2-static ${EXTRA_LIBS} ${EXTRA_LDFLAGS}) target_link_libraries(SDL2-static ${EXTRA_LIBS} ${EXTRA_LDFLAGS})
target_include_directories(SDL2-static PUBLIC $<INSTALL_INTERFACE:include/SDL2>) target_include_directories(SDL2-static PUBLIC "$<BUILD_INTERFACE:${SDL2_SOURCE_DIR}/include>" $<INSTALL_INTERFACE:include/SDL2>)
if (NOT ANDROID) if (NOT ANDROID)
set_target_properties(SDL2-static PROPERTIES DEBUG_POSTFIX ${SDL_CMAKE_DEBUG_POSTFIX}) set_target_properties(SDL2-static PROPERTIES DEBUG_POSTFIX ${SDL_CMAKE_DEBUG_POSTFIX})
endif() endif()
@ -1839,17 +1856,14 @@ endif()
if(NOT (WINDOWS OR CYGWIN)) if(NOT (WINDOWS OR CYGWIN))
if(SDL_SHARED) if(SDL_SHARED)
if (APPLE) set(SOEXT ${CMAKE_SHARED_LIBRARY_SUFFIX}) # ".so", ".dylib", etc.
set(SOEXT "dylib") get_target_property(SONAME SDL2 OUTPUT_NAME)
else()
set(SOEXT "so")
endif()
if(NOT ANDROID) if(NOT ANDROID)
install(CODE " install(CODE "
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink
\"libSDL2-2.0${SOPOSTFIX}.${SOEXT}\" \"libSDL2.${SOEXT}\")" \"lib${SONAME}${SOPOSTFIX}${SOEXT}\" \"libSDL2${SOPOSTFIX}${SOEXT}\")"
WORKING_DIR "${SDL2_BINARY_DIR}") WORKING_DIR "${SDL2_BINARY_DIR}")
install(FILES ${SDL2_BINARY_DIR}/libSDL2.${SOEXT} DESTINATION "lib${LIB_SUFFIX}") install(FILES ${SDL2_BINARY_DIR}/libSDL2${SOPOSTFIX}${SOEXT} DESTINATION "lib${LIB_SUFFIX}")
endif() endif()
endif() endif()
if(FREEBSD) if(FREEBSD)

126
Makefile.os2 Normal file
View File

@ -0,0 +1,126 @@
# Open Watcom makefile to build SDL2.dll for OS/2:
# wmake -f Makefile.os2
LIBNAME = SDL2
VERSION = 2.0.9
DESCRIPTION = Simple DirectMedia Layer 2
LIBHOME = .
LIBPATH = $(LIBHOME)/lib
DLLFILE = $(LIBHOME)/$(LIBNAME).dll
LIBFILE = $(LIBHOME)/$(LIBNAME).lib
LNKFILE = $(LIBNAME).lnk
INCPATH = -I"$(%WATCOM)/h/os2" -I"$(%WATCOM)/h"
INCPATH+= -I"$(LIBHOME)/h"
INCPATH+= -Iinclude
LIBS = mmpm2.lib libuls.lib libconv.lib
CFLAGS = -bt=os2 -d0 -q -bm -5s -fp5 -fpi87 -sg -oteanbmier -ei
# max warnings:
CFLAGS+= -wx
# building dll:
CFLAGS+= -bd
# the include paths :
CFLAGS+= $(INCPATH)
# building SDL itself:
CFLAGS+= -DBUILD_SDL
SRCS = SDL.c SDL_assert.c SDL_error.c SDL_log.c SDL_dataqueue.c SDL_hints.c
SRCS+= SDL_getenv.c SDL_iconv.c SDL_malloc.c SDL_qsort.c SDL_stdlib.c SDL_string.c
SRCS+= SDL_cpuinfo.c SDL_atomic.c SDL_spinlock.c SDL_thread.c SDL_timer.c
SRCS+= SDL_rwops.c SDL_power.c
SRCS+= SDL_audio.c SDL_audiocvt.c SDL_audiodev.c SDL_audiotypecvt.c SDL_mixer.c SDL_wave.c
SRCS+= SDL_events.c SDL_quit.c SDL_keyboard.c SDL_mouse.c SDL_windowevents.c &
SDL_clipboardevents.c SDL_dropevents.c SDL_displayevents.c SDL_gesture.c &
SDL_sensor.c SDL_touch.c
SRCS+= SDL_haptic.c SDL_gamecontroller.c SDL_joystick.c
SRCS+= SDL_render.c yuv_rgb.c SDL_yuv.c SDL_yuv_sw.c SDL_blendfillrect.c &
SDL_blendline.c SDL_blendpoint.c SDL_drawline.c SDL_drawpoint.c &
SDL_render_sw.c SDL_rotate.c
SRCS+= SDL_blit.c SDL_blit_0.c SDL_blit_1.c SDL_blit_A.c SDL_blit_auto.c &
SDL_blit_copy.c SDL_blit_N.c SDL_blit_slow.c SDL_fillrect.c SDL_bmp.c &
SDL_pixels.c SDL_rect.c SDL_RLEaccel.c SDL_shape.c SDL_stretch.c &
SDL_surface.c SDL_video.c SDL_clipboard.c SDL_vulkan_utils.c SDL_egl.c
SRCS+= SDL_syscond.c SDL_sysmutex.c SDL_syssem.c SDL_systhread.c SDL_systls.c
SRCS+= SDL_systimer.c
SRCS+= SDL_sysloadso.c
SRCS+= SDL_sysfilesystem.c
SRCS+= SDL_syshaptic.c SDL_sysjoystick.c
SRCS+= SDL_dummyaudio.c SDL_diskaudio.c
SRCS+= SDL_nullvideo.c SDL_nullframebuffer.c SDL_nullevents.c
SRCS+= SDL_dummysensor.c
SRCS+= SDL_dynapi.c
OBJS = $(SRCS:.c=.obj)
.extensions:
.extensions: .lib .dll .obj .c .asm
.c: ./src;./src/dynapi;./src/audio;./src/cpuinfo;./src/events;./src/file;./src/haptic;./src/joystick;./src/power;./src/render;./src/render/software;./src/sensor;./src/stdlib;./src/thread;./src/timer;./src/video;./src/video/yuv2rgb;./src/atomic;./src/audio/disk;
.c: ./src/haptic/dummy;./src/joystick/dummy;./src/audio/dummy;./src/video/dummy;./src/sensor/dummy;
.c: ./src/loadso/dummy;./src/filesystem/dummy;./src/timer/dummy;./src/thread/generic;
all: $(DLLFILE) $(LIBFILE) .symbolic
$(DLLFILE): $(OBJS) $(LNKFILE)
@echo * Linking: $@
wlink @$(LNKFILE)
$(LIBFILE): $(DLLFILE)
@echo * Creating LIB file: $@
wlib -q -b -n -c -pa -s -t -zld -ii -io $* $(DLLFILE)
.c.obj:
wcc386 $(CFLAGS) -fo=$^@ $<
SDL_cpuinfo.obj: SDL_cpuinfo.c
wcc386 $(CFLAGS) -wcd=200 -fo=$^@ $<
SDL_rwops.obj: SDL_rwops.c
wcc386 $(CFLAGS) -wcd=136 -fo=$^@ $<
SDL_blendfillrect.obj: SDL_blendfillrect.c
wcc386 $(CFLAGS) -wcd=200 -fo=$^@ $<
SDL_blendline.obj: SDL_blendline.c
wcc386 $(CFLAGS) -wcd=200 -fo=$^@ $<
SDL_blendpoint.obj: SDL_blendpoint.c
wcc386 $(CFLAGS) -wcd=200 -fo=$^@ $<
SDL_RLEaccel.obj: SDL_RLEaccel.c
wcc386 $(CFLAGS) -wcd=201 -fo=$^@ $<
$(LNKFILE):
@echo * Creating linker file: $@
@%create $@
@%append $@ SYSTEM os2v2_dll INITINSTANCE TERMINSTANCE
@%append $@ NAME $(DLLFILE)
@for %i in ($(OBJS)) do @%append $@ FILE %i
@%append $@ LIBPATH $(%LIB);$(LIBPATH)
@for %i in ($(LIBS)) do @%append $@ LIB %i
@%append $@ OPTION QUIET
@%append $@ OPTION IMPF=$(LIBHOME)/$^&.exp
@%append $@ OPTION MAP=$(LIBHOME)/$^&.map
@%append $@ OPTION DESCRIPTION '@$#libsdl org:$(VERSION)$#@$(DESCRIPTION)'
@%append $@ OPTION QUIET
@%append $@ OPTION ELIMINATE
@%append $@ OPTION MANYAUTODATA
@%append $@ OPTION OSNAME='OS/2 and eComStation'
@%append $@ OPTION SHOWDEAD
clean: .SYMBOLIC
@ echo * Clean: $(LIBNAME)
@if exist *.obj rm *.obj
@if exist *.err rm *.err
@if exist $(LNKFILE) rm $(LNKFILE)
distclean: .SYMBOLIC clean
@if exist $(LIBHOME)/*.exp rm $(LIBHOME)/*.exp
@if exist $(LIBHOME)/*.map rm $(LIBHOME)/*.map
@if exist $(LIBFILE) rm $(LIBFILE)
@if exist $(DLLFILE) rm $(DLLFILE)

View File

@ -6,7 +6,40 @@ This is a list of major changes in SDL's version history.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
General: General:
* Added a new sensor API, initialized by passing SDL_INIT_SENSOR to SDL_Init(), and defined in SDL_sensor.h
* Added an event SDL_SENSORUPDATE which is sent when a sensor is updated
* Added SDL_GetDisplayOrientation() to return the current display orientation
* Added an event SDL_DISPLAYEVENT which is sent when the display orientation changes
* Added HIDAPI joystick drivers for more consistent support for Xbox, PS4 and Nintendo Switch Pro controller support across platforms. (Thanks to Valve for contributing the PS4 and Nintendo Switch Pro controller support)
* Added support for many other popular game controllers
* Added SDL_JoystickGetDevicePlayerIndex(), SDL_JoystickGetPlayerIndex(), and SDL_GameControllerGetPlayerIndex() to get the player index for a controller. For XInput controllers this returns the XInput index for the controller.
* Added SDL_GameControllerRumble() and SDL_JoystickRumble() which allow simple rumble without using the haptics API
* Added SDL_GameControllerMappingForDeviceIndex() to get the mapping for a controller before it's opened * Added SDL_GameControllerMappingForDeviceIndex() to get the mapping for a controller before it's opened
* Added the hint SDL_HINT_MOUSE_DOUBLE_CLICK_TIME to control the mouse double-click time
* Added the hint SDL_HINT_MOUSE_DOUBLE_CLICK_RADIUS to control the mouse double-click radius, in pixels
* Added SDL_HasColorKey() to return whether a surface has a colorkey active
* Added SDL_HasAVX512F() to return whether the CPU has AVX-512F features
* Added SDL_IsTablet() to return whether the application is running on a tablet
* Added SDL_THREAD_PRIORITY_TIME_CRITICAL for threads that must run at the highest priority
Mac OS X:
* Fixed black screen at start on Mac OS X Mojave
Linux:
* Added SDL_LinuxSetThreadPriority() to allow adjusting the thread priority of native threads using RealtimeKit if available.
iOS:
* Fixed Asian IME input
Android:
* Updated required Android SDK to API 26, to match Google's new App Store requirements
* Added support for wired USB Xbox, PS4, and Nintendo Switch Pro controllers
* Added support for relative mouse mode on Android 7.0 and newer (except where it's broken, on Chromebooks and when in DeX mode with Samsung Experience 9.0)
* Added support for custom mouse cursors on Android 7.0 and newer
* Added the hint SDL_HINT_ANDROID_TRAP_BACK_BUTTON to control whether the back button will back out of the app (the default) or be passed to the application as SDL_SCANCODE_AC_BACK
* Added SDL_AndroidBackButton() to trigger the Android system back button behavior when handling the back button in the application
* Added SDL_IsChromebook() to return whether the app is running in the Chromebook Android runtime
* Added SDL_IsDeXMode() to return whether the app is running while docked in the Samsung DeX
--------------------------------------------------------------------------- ---------------------------------------------------------------------------

View File

@ -975,6 +975,7 @@
C01FCF4F08A954540054247B /* Debug */ = { C01FCF4F08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
GCC_OPTIMIZATION_LEVEL = 0; GCC_OPTIMIZATION_LEVEL = 0;
HEADER_SEARCH_PATHS = ../../include; HEADER_SEARCH_PATHS = ../../include;
@ -988,6 +989,7 @@
C01FCF5008A954540054247B /* Release */ = { C01FCF5008A954540054247B /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
HEADER_SEARCH_PATHS = ../../include; HEADER_SEARCH_PATHS = ../../include;
PRELINK_LIBS = ""; PRELINK_LIBS = "";

View File

@ -208,6 +208,9 @@
F30D9CA7212CD0BF0047DF2E /* SDL_coremotionsensor.h in Headers */ = {isa = PBXBuildFile; fileRef = F30D9CA4212CD0BF0047DF2E /* SDL_coremotionsensor.h */; }; F30D9CA7212CD0BF0047DF2E /* SDL_coremotionsensor.h in Headers */ = {isa = PBXBuildFile; fileRef = F30D9CA4212CD0BF0047DF2E /* SDL_coremotionsensor.h */; };
F30D9CC6212CE92C0047DF2E /* hid.m in Sources */ = {isa = PBXBuildFile; fileRef = F30D9CC5212CE92C0047DF2E /* hid.m */; }; F30D9CC6212CE92C0047DF2E /* hid.m in Sources */ = {isa = PBXBuildFile; fileRef = F30D9CC5212CE92C0047DF2E /* hid.m */; };
F30D9CC7212CE92C0047DF2E /* hid.m in Sources */ = {isa = PBXBuildFile; fileRef = F30D9CC5212CE92C0047DF2E /* hid.m */; }; F30D9CC7212CE92C0047DF2E /* hid.m in Sources */ = {isa = PBXBuildFile; fileRef = F30D9CC5212CE92C0047DF2E /* hid.m */; };
F36839CC214790950000F255 /* SDL_dummysensor.h in Headers */ = {isa = PBXBuildFile; fileRef = F36839CA214790950000F255 /* SDL_dummysensor.h */; };
F36839CD214790950000F255 /* SDL_dummysensor.c in Sources */ = {isa = PBXBuildFile; fileRef = F36839CB214790950000F255 /* SDL_dummysensor.c */; };
F36839CE214790950000F255 /* SDL_dummysensor.c in Sources */ = {isa = PBXBuildFile; fileRef = F36839CB214790950000F255 /* SDL_dummysensor.c */; };
F3BDD79220F51CB8004ECBF3 /* SDL_hidapi_xbox360.c in Sources */ = {isa = PBXBuildFile; fileRef = F3BDD78B20F51CB8004ECBF3 /* SDL_hidapi_xbox360.c */; }; F3BDD79220F51CB8004ECBF3 /* SDL_hidapi_xbox360.c in Sources */ = {isa = PBXBuildFile; fileRef = F3BDD78B20F51CB8004ECBF3 /* SDL_hidapi_xbox360.c */; };
F3BDD79320F51CB8004ECBF3 /* SDL_hidapi_xbox360.c in Sources */ = {isa = PBXBuildFile; fileRef = F3BDD78B20F51CB8004ECBF3 /* SDL_hidapi_xbox360.c */; }; F3BDD79320F51CB8004ECBF3 /* SDL_hidapi_xbox360.c in Sources */ = {isa = PBXBuildFile; fileRef = F3BDD78B20F51CB8004ECBF3 /* SDL_hidapi_xbox360.c */; };
F3BDD79420F51CB8004ECBF3 /* SDL_hidapi_switch.c in Sources */ = {isa = PBXBuildFile; fileRef = F3BDD78C20F51CB8004ECBF3 /* SDL_hidapi_switch.c */; }; F3BDD79420F51CB8004ECBF3 /* SDL_hidapi_switch.c in Sources */ = {isa = PBXBuildFile; fileRef = F3BDD78C20F51CB8004ECBF3 /* SDL_hidapi_switch.c */; };
@ -542,6 +545,8 @@
F30D9CA3212CD0BF0047DF2E /* SDL_coremotionsensor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_coremotionsensor.m; sourceTree = "<group>"; }; F30D9CA3212CD0BF0047DF2E /* SDL_coremotionsensor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_coremotionsensor.m; sourceTree = "<group>"; };
F30D9CA4212CD0BF0047DF2E /* SDL_coremotionsensor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_coremotionsensor.h; sourceTree = "<group>"; }; F30D9CA4212CD0BF0047DF2E /* SDL_coremotionsensor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_coremotionsensor.h; sourceTree = "<group>"; };
F30D9CC5212CE92C0047DF2E /* hid.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = hid.m; sourceTree = "<group>"; }; F30D9CC5212CE92C0047DF2E /* hid.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = hid.m; sourceTree = "<group>"; };
F36839CA214790950000F255 /* SDL_dummysensor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_dummysensor.h; sourceTree = "<group>"; };
F36839CB214790950000F255 /* SDL_dummysensor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_dummysensor.c; sourceTree = "<group>"; };
F3BDD78B20F51CB8004ECBF3 /* SDL_hidapi_xbox360.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_xbox360.c; sourceTree = "<group>"; }; F3BDD78B20F51CB8004ECBF3 /* SDL_hidapi_xbox360.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_xbox360.c; sourceTree = "<group>"; };
F3BDD78C20F51CB8004ECBF3 /* SDL_hidapi_switch.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_switch.c; sourceTree = "<group>"; }; F3BDD78C20F51CB8004ECBF3 /* SDL_hidapi_switch.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_switch.c; sourceTree = "<group>"; };
F3BDD78D20F51CB8004ECBF3 /* SDL_hidapi_xboxone.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_xboxone.c; sourceTree = "<group>"; }; F3BDD78D20F51CB8004ECBF3 /* SDL_hidapi_xboxone.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_xboxone.c; sourceTree = "<group>"; };
@ -838,6 +843,7 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
F30D9CA2212CD09E0047DF2E /* coremotion */, F30D9CA2212CD09E0047DF2E /* coremotion */,
F36839C9214790740000F255 /* dummy */,
F30D9C9B212CD0980047DF2E /* SDL_sensor_c.h */, F30D9C9B212CD0980047DF2E /* SDL_sensor_c.h */,
F30D9C9D212CD0990047DF2E /* SDL_sensor.c */, F30D9C9D212CD0990047DF2E /* SDL_sensor.c */,
F30D9C9C212CD0990047DF2E /* SDL_syssensor.h */, F30D9C9C212CD0990047DF2E /* SDL_syssensor.h */,
@ -862,6 +868,15 @@
path = hidapi; path = hidapi;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
F36839C9214790740000F255 /* dummy */ = {
isa = PBXGroup;
children = (
F36839CB214790950000F255 /* SDL_dummysensor.c */,
F36839CA214790950000F255 /* SDL_dummysensor.h */,
);
path = dummy;
sourceTree = "<group>";
};
F3BDD77420F51C18004ECBF3 /* ios */ = { F3BDD77420F51C18004ECBF3 /* ios */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -1370,6 +1385,7 @@
AA9FF9511637C6E5000DF050 /* SDL_messagebox.h in Headers */, AA9FF9511637C6E5000DF050 /* SDL_messagebox.h in Headers */,
AABCC3941640643D00AB8930 /* SDL_uikitmessagebox.h in Headers */, AABCC3941640643D00AB8930 /* SDL_uikitmessagebox.h in Headers */,
AA0AD06516647BD400CE5896 /* SDL_gamecontroller.h in Headers */, AA0AD06516647BD400CE5896 /* SDL_gamecontroller.h in Headers */,
F36839CC214790950000F255 /* SDL_dummysensor.h in Headers */,
AADA5B8F16CCAB7C00107CF7 /* SDL_bits.h in Headers */, AADA5B8F16CCAB7C00107CF7 /* SDL_bits.h in Headers */,
56C181DF17C44D5E00406AE3 /* SDL_filesystem.h in Headers */, 56C181DF17C44D5E00406AE3 /* SDL_filesystem.h in Headers */,
); );
@ -1565,6 +1581,7 @@
FAB598731BB5C31600BE72C5 /* SDL_iconv.c in Sources */, FAB598731BB5C31600BE72C5 /* SDL_iconv.c in Sources */,
FAB598741BB5C31600BE72C5 /* SDL_malloc.c in Sources */, FAB598741BB5C31600BE72C5 /* SDL_malloc.c in Sources */,
FAB598751BB5C31600BE72C5 /* SDL_qsort.c in Sources */, FAB598751BB5C31600BE72C5 /* SDL_qsort.c in Sources */,
F36839CE214790950000F255 /* SDL_dummysensor.c in Sources */,
A7C19D2B212E552C00DF2152 /* SDL_displayevents.c in Sources */, A7C19D2B212E552C00DF2152 /* SDL_displayevents.c in Sources */,
FAB598761BB5C31600BE72C5 /* SDL_stdlib.c in Sources */, FAB598761BB5C31600BE72C5 /* SDL_stdlib.c in Sources */,
FAB598771BB5C31600BE72C5 /* SDL_string.c in Sources */, FAB598771BB5C31600BE72C5 /* SDL_string.c in Sources */,
@ -1720,6 +1737,7 @@
0442EC5512FE1C3F004C9285 /* SDL_hints.c in Sources */, 0442EC5512FE1C3F004C9285 /* SDL_hints.c in Sources */,
AA13B34A1FB8B27800D9FEE6 /* SDL_shape.c in Sources */, AA13B34A1FB8B27800D9FEE6 /* SDL_shape.c in Sources */,
0402A85812FE70C600CECEE3 /* SDL_render_gles2.c in Sources */, 0402A85812FE70C600CECEE3 /* SDL_render_gles2.c in Sources */,
F36839CD214790950000F255 /* SDL_dummysensor.c in Sources */,
0402A85912FE70C600CECEE3 /* SDL_shaders_gles2.c in Sources */, 0402A85912FE70C600CECEE3 /* SDL_shaders_gles2.c in Sources */,
04BAC09D1300C1290055DE28 /* SDL_log.c in Sources */, 04BAC09D1300C1290055DE28 /* SDL_log.c in Sources */,
56EA86FB13E9EC2B002E47EB /* SDL_coreaudio.m in Sources */, 56EA86FB13E9EC2B002E47EB /* SDL_coreaudio.m in Sources */,
@ -1955,6 +1973,7 @@
FD6526640DE8FCCB002AD96B /* Debug */ = { FD6526640DE8FCCB002AD96B /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES; CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
@ -1971,6 +1990,7 @@
FD6526650DE8FCCB002AD96B /* Release */ = { FD6526650DE8FCCB002AD96B /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES; CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;

View File

@ -26,34 +26,6 @@
047A63E813285C3200CD7973 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89D0E2D111A00EA573E /* Foundation.framework */; }; 047A63E813285C3200CD7973 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89D0E2D111A00EA573E /* Foundation.framework */; };
047A63E913285C3200CD7973 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89E0E2D111A00EA573E /* CoreAudio.framework */; }; 047A63E913285C3200CD7973 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A89E0E2D111A00EA573E /* CoreAudio.framework */; };
047A63F113285CD100CD7973 /* checkkeys.c in Sources */ = {isa = PBXBuildFile; fileRef = 047A63F013285CD100CD7973 /* checkkeys.c */; }; 047A63F113285CD100CD7973 /* checkkeys.c in Sources */ = {isa = PBXBuildFile; fileRef = 047A63F013285CD100CD7973 /* checkkeys.c */; };
55FFA91C212232BA00D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA91D212232BF00D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA91E212232BF00D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA91F212232C000D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA920212232C000D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA921212232C100D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA922212232C100D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA923212232C200D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA924212232C200D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA925212232C300D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA926212232C300D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA927212232C500D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA928212232C500D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA929212232C600D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA92A212232C600D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA92B212232C700D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA92C212232C700D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA92D212232C800D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA92E212232CA00D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA92F212232CA00D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA930212232CB00D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA931212232CB00D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA932212232CC00D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA933212232CC00D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA934212232CD00D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA935212232CE00D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA936212232CE00D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
55FFA937212232CF00D7CBED /* CoreBluetooth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */; };
56ED04FE118A8FE400A56AA6 /* icon.bmp in Resources */ = {isa = PBXBuildFile; fileRef = FDA8AAD90E2D33B000EA573E /* icon.bmp */; }; 56ED04FE118A8FE400A56AA6 /* icon.bmp in Resources */ = {isa = PBXBuildFile; fileRef = FDA8AAD90E2D33B000EA573E /* icon.bmp */; };
56ED0502118A8FE400A56AA6 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD1B48B80E3131CA007AB34E /* libSDL2.a */; }; 56ED0502118A8FE400A56AA6 /* libSDL2.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD1B48B80E3131CA007AB34E /* libSDL2.a */; };
56ED0503118A8FE400A56AA6 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A8980E2D111A00EA573E /* AudioToolbox.framework */; }; 56ED0503118A8FE400A56AA6 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FDA8A8980E2D111A00EA573E /* AudioToolbox.framework */; };
@ -451,7 +423,6 @@
047A63ED13285C3200CD7973 /* checkkeys.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = checkkeys.app; sourceTree = BUILT_PRODUCTS_DIR; }; 047A63ED13285C3200CD7973 /* checkkeys.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = checkkeys.app; sourceTree = BUILT_PRODUCTS_DIR; };
047A63F013285CD100CD7973 /* checkkeys.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = checkkeys.c; sourceTree = "<group>"; }; 047A63F013285CD100CD7973 /* checkkeys.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = checkkeys.c; sourceTree = "<group>"; };
1D6058910D05DD3D006BFB54 /* testwm2.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testwm2.app; sourceTree = BUILT_PRODUCTS_DIR; }; 1D6058910D05DD3D006BFB54 /* testwm2.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testwm2.app; sourceTree = BUILT_PRODUCTS_DIR; };
55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreBluetooth.framework; path = System/Library/Frameworks/CoreBluetooth.framework; sourceTree = SDKROOT; };
56ED050D118A8FE400A56AA6 /* testpower.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testpower.app; sourceTree = BUILT_PRODUCTS_DIR; }; 56ED050D118A8FE400A56AA6 /* testpower.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testpower.app; sourceTree = BUILT_PRODUCTS_DIR; };
56ED0510118A904200A56AA6 /* testpower.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testpower.c; sourceTree = "<group>"; }; 56ED0510118A904200A56AA6 /* testpower.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = testpower.c; sourceTree = "<group>"; };
AA13B3261FB8AEBC00D9FEE6 /* testyuv.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testyuv.app; sourceTree = BUILT_PRODUCTS_DIR; }; AA13B3261FB8AEBC00D9FEE6 /* testyuv.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testyuv.app; sourceTree = BUILT_PRODUCTS_DIR; };
@ -543,7 +514,6 @@
046CEF7F13254F23007AD51D /* CoreGraphics.framework in Frameworks */, 046CEF7F13254F23007AD51D /* CoreGraphics.framework in Frameworks */,
046CEF8013254F23007AD51D /* UIKit.framework in Frameworks */, 046CEF8013254F23007AD51D /* UIKit.framework in Frameworks */,
046CEF8113254F23007AD51D /* Foundation.framework in Frameworks */, 046CEF8113254F23007AD51D /* Foundation.framework in Frameworks */,
55FFA926212232C300D7CBED /* CoreBluetooth.framework in Frameworks */,
046CEF8213254F23007AD51D /* CoreAudio.framework in Frameworks */, 046CEF8213254F23007AD51D /* CoreAudio.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -552,7 +522,6 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
55FFA91C212232BA00D7CBED /* CoreBluetooth.framework in Frameworks */,
FABA34B01D8B5B6400915323 /* AVFoundation.framework in Frameworks */, FABA34B01D8B5B6400915323 /* AVFoundation.framework in Frameworks */,
AA1EE470176059D00029C7A5 /* libSDL2test.a in Frameworks */, AA1EE470176059D00029C7A5 /* libSDL2test.a in Frameworks */,
047A63E213285C3200CD7973 /* libSDL2.a in Frameworks */, 047A63E213285C3200CD7973 /* libSDL2.a in Frameworks */,
@ -575,7 +544,6 @@
FABA34C41D8B5BCB00915323 /* AVFoundation.framework in Frameworks */, FABA34C41D8B5BCB00915323 /* AVFoundation.framework in Frameworks */,
AA1EE47817605BF60029C7A5 /* libSDL2test.a in Frameworks */, AA1EE47817605BF60029C7A5 /* libSDL2test.a in Frameworks */,
FDBDE5810E313465006BAC0B /* libSDL2.a in Frameworks */, FDBDE5810E313465006BAC0B /* libSDL2.a in Frameworks */,
55FFA935212232CE00D7CBED /* CoreBluetooth.framework in Frameworks */,
FA684F931BAF1A8A00DCFD1A /* GameController.framework in Frameworks */, FA684F931BAF1A8A00DCFD1A /* GameController.framework in Frameworks */,
FA8B4BE0196766F400F8EB7C /* CoreMotion.framework in Frameworks */, FA8B4BE0196766F400F8EB7C /* CoreMotion.framework in Frameworks */,
FDA8A89F0E2D111A00EA573E /* AudioToolbox.framework in Frameworks */, FDA8A89F0E2D111A00EA573E /* AudioToolbox.framework in Frameworks */,
@ -602,7 +570,6 @@
56ED0506118A8FE400A56AA6 /* CoreGraphics.framework in Frameworks */, 56ED0506118A8FE400A56AA6 /* CoreGraphics.framework in Frameworks */,
56ED0507118A8FE400A56AA6 /* UIKit.framework in Frameworks */, 56ED0507118A8FE400A56AA6 /* UIKit.framework in Frameworks */,
56ED0508118A8FE400A56AA6 /* Foundation.framework in Frameworks */, 56ED0508118A8FE400A56AA6 /* Foundation.framework in Frameworks */,
55FFA92D212232C800D7CBED /* CoreBluetooth.framework in Frameworks */,
56ED0509118A8FE400A56AA6 /* CoreAudio.framework in Frameworks */, 56ED0509118A8FE400A56AA6 /* CoreAudio.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -614,7 +581,6 @@
AA13B3171FB8AEBC00D9FEE6 /* AVFoundation.framework in Frameworks */, AA13B3171FB8AEBC00D9FEE6 /* AVFoundation.framework in Frameworks */,
AA13B3181FB8AEBC00D9FEE6 /* libSDL2test.a in Frameworks */, AA13B3181FB8AEBC00D9FEE6 /* libSDL2test.a in Frameworks */,
AA13B3191FB8AEBC00D9FEE6 /* libSDL2.a in Frameworks */, AA13B3191FB8AEBC00D9FEE6 /* libSDL2.a in Frameworks */,
55FFA936212232CE00D7CBED /* CoreBluetooth.framework in Frameworks */,
AA13B31A1FB8AEBC00D9FEE6 /* GameController.framework in Frameworks */, AA13B31A1FB8AEBC00D9FEE6 /* GameController.framework in Frameworks */,
AA13B31B1FB8AEBC00D9FEE6 /* CoreMotion.framework in Frameworks */, AA13B31B1FB8AEBC00D9FEE6 /* CoreMotion.framework in Frameworks */,
AA13B31C1FB8AEBC00D9FEE6 /* AudioToolbox.framework in Frameworks */, AA13B31C1FB8AEBC00D9FEE6 /* AudioToolbox.framework in Frameworks */,
@ -634,7 +600,6 @@
FABA34BE1D8B5BB000915323 /* AVFoundation.framework in Frameworks */, FABA34BE1D8B5BB000915323 /* AVFoundation.framework in Frameworks */,
AA1EE47617605B9E0029C7A5 /* libSDL2test.a in Frameworks */, AA1EE47617605B9E0029C7A5 /* libSDL2test.a in Frameworks */,
AAE7DEE114CBB1E100DF1A0E /* libSDL2.a in Frameworks */, AAE7DEE114CBB1E100DF1A0E /* libSDL2.a in Frameworks */,
55FFA92F212232CA00D7CBED /* CoreBluetooth.framework in Frameworks */,
FA684F8D1BAF1A7800DCFD1A /* GameController.framework in Frameworks */, FA684F8D1BAF1A7800DCFD1A /* GameController.framework in Frameworks */,
FA8B4BDA196766E200F8EB7C /* CoreMotion.framework in Frameworks */, FA8B4BDA196766E200F8EB7C /* CoreMotion.framework in Frameworks */,
AAE7DEE214CBB1E100DF1A0E /* AudioToolbox.framework in Frameworks */, AAE7DEE214CBB1E100DF1A0E /* AudioToolbox.framework in Frameworks */,
@ -655,7 +620,6 @@
FABA34BD1D8B5BAB00915323 /* AVFoundation.framework in Frameworks */, FABA34BD1D8B5BAB00915323 /* AVFoundation.framework in Frameworks */,
AA1EE47517605B930029C7A5 /* libSDL2test.a in Frameworks */, AA1EE47517605B930029C7A5 /* libSDL2test.a in Frameworks */,
AAE7DFA614CBB54E00DF1A0E /* libSDL2.a in Frameworks */, AAE7DFA614CBB54E00DF1A0E /* libSDL2.a in Frameworks */,
55FFA92E212232CA00D7CBED /* CoreBluetooth.framework in Frameworks */,
FA684F8C1BAF1A7400DCFD1A /* GameController.framework in Frameworks */, FA684F8C1BAF1A7400DCFD1A /* GameController.framework in Frameworks */,
FA8B4BD9196766E000F8EB7C /* CoreMotion.framework in Frameworks */, FA8B4BD9196766E000F8EB7C /* CoreMotion.framework in Frameworks */,
AAE7DFA714CBB54E00DF1A0E /* AudioToolbox.framework in Frameworks */, AAE7DFA714CBB54E00DF1A0E /* AudioToolbox.framework in Frameworks */,
@ -680,7 +644,6 @@
FA3D994D1BC4E6AD002C96C8 /* CoreGraphics.framework in Frameworks */, FA3D994D1BC4E6AD002C96C8 /* CoreGraphics.framework in Frameworks */,
FA3D994E1BC4E6AD002C96C8 /* UIKit.framework in Frameworks */, FA3D994E1BC4E6AD002C96C8 /* UIKit.framework in Frameworks */,
FA3D994F1BC4E6AD002C96C8 /* Foundation.framework in Frameworks */, FA3D994F1BC4E6AD002C96C8 /* Foundation.framework in Frameworks */,
55FFA925212232C300D7CBED /* CoreBluetooth.framework in Frameworks */,
FA3D99501BC4E6AD002C96C8 /* CoreAudio.framework in Frameworks */, FA3D99501BC4E6AD002C96C8 /* CoreAudio.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -699,7 +662,6 @@
FABA348A1D8B575200915323 /* CoreGraphics.framework in Frameworks */, FABA348A1D8B575200915323 /* CoreGraphics.framework in Frameworks */,
FABA348B1D8B575200915323 /* UIKit.framework in Frameworks */, FABA348B1D8B575200915323 /* UIKit.framework in Frameworks */,
FABA348C1D8B575200915323 /* Foundation.framework in Frameworks */, FABA348C1D8B575200915323 /* Foundation.framework in Frameworks */,
55FFA91D212232BF00D7CBED /* CoreBluetooth.framework in Frameworks */,
FABA348D1D8B575200915323 /* CoreAudio.framework in Frameworks */, FABA348D1D8B575200915323 /* CoreAudio.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -718,7 +680,6 @@
FABA34A31D8B582100915323 /* CoreGraphics.framework in Frameworks */, FABA34A31D8B582100915323 /* CoreGraphics.framework in Frameworks */,
FABA34A41D8B582100915323 /* UIKit.framework in Frameworks */, FABA34A41D8B582100915323 /* UIKit.framework in Frameworks */,
FABA34A51D8B582100915323 /* Foundation.framework in Frameworks */, FABA34A51D8B582100915323 /* Foundation.framework in Frameworks */,
55FFA91F212232C000D7CBED /* CoreBluetooth.framework in Frameworks */,
FABA34A61D8B582100915323 /* CoreAudio.framework in Frameworks */, FABA34A61D8B582100915323 /* CoreAudio.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -737,7 +698,6 @@
FAE0E98C1BAF9B230098DFA4 /* CoreGraphics.framework in Frameworks */, FAE0E98C1BAF9B230098DFA4 /* CoreGraphics.framework in Frameworks */,
FAE0E98D1BAF9B230098DFA4 /* UIKit.framework in Frameworks */, FAE0E98D1BAF9B230098DFA4 /* UIKit.framework in Frameworks */,
FAE0E98E1BAF9B230098DFA4 /* Foundation.framework in Frameworks */, FAE0E98E1BAF9B230098DFA4 /* Foundation.framework in Frameworks */,
55FFA924212232C200D7CBED /* CoreBluetooth.framework in Frameworks */,
FAE0E98F1BAF9B230098DFA4 /* CoreAudio.framework in Frameworks */, FAE0E98F1BAF9B230098DFA4 /* CoreAudio.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -756,7 +716,6 @@
FDA8AAB40E2D330F00EA573E /* CoreGraphics.framework in Frameworks */, FDA8AAB40E2D330F00EA573E /* CoreGraphics.framework in Frameworks */,
FDA8AAB50E2D330F00EA573E /* UIKit.framework in Frameworks */, FDA8AAB50E2D330F00EA573E /* UIKit.framework in Frameworks */,
FDA8AAB60E2D330F00EA573E /* Foundation.framework in Frameworks */, FDA8AAB60E2D330F00EA573E /* Foundation.framework in Frameworks */,
55FFA91E212232BF00D7CBED /* CoreBluetooth.framework in Frameworks */,
FDA8AAB70E2D330F00EA573E /* CoreAudio.framework in Frameworks */, FDA8AAB70E2D330F00EA573E /* CoreAudio.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -775,7 +734,6 @@
FDAAC3C60E2D47E6001DB1D8 /* CoreGraphics.framework in Frameworks */, FDAAC3C60E2D47E6001DB1D8 /* CoreGraphics.framework in Frameworks */,
FDAAC3C70E2D47E6001DB1D8 /* UIKit.framework in Frameworks */, FDAAC3C70E2D47E6001DB1D8 /* UIKit.framework in Frameworks */,
FDAAC3C80E2D47E6001DB1D8 /* Foundation.framework in Frameworks */, FDAAC3C80E2D47E6001DB1D8 /* Foundation.framework in Frameworks */,
55FFA920212232C000D7CBED /* CoreBluetooth.framework in Frameworks */,
FDAAC3C90E2D47E6001DB1D8 /* CoreAudio.framework in Frameworks */, FDAAC3C90E2D47E6001DB1D8 /* CoreAudio.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -794,7 +752,6 @@
FDAAC5940E2D5429001DB1D8 /* CoreGraphics.framework in Frameworks */, FDAAC5940E2D5429001DB1D8 /* CoreGraphics.framework in Frameworks */,
FDAAC5950E2D5429001DB1D8 /* UIKit.framework in Frameworks */, FDAAC5950E2D5429001DB1D8 /* UIKit.framework in Frameworks */,
FDAAC5960E2D5429001DB1D8 /* Foundation.framework in Frameworks */, FDAAC5960E2D5429001DB1D8 /* Foundation.framework in Frameworks */,
55FFA923212232C200D7CBED /* CoreBluetooth.framework in Frameworks */,
FDAAC5970E2D5429001DB1D8 /* CoreAudio.framework in Frameworks */, FDAAC5970E2D5429001DB1D8 /* CoreAudio.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -813,7 +770,6 @@
FDAAC5C20E2D55B5001DB1D8 /* CoreGraphics.framework in Frameworks */, FDAAC5C20E2D55B5001DB1D8 /* CoreGraphics.framework in Frameworks */,
FDAAC5C30E2D55B5001DB1D8 /* UIKit.framework in Frameworks */, FDAAC5C30E2D55B5001DB1D8 /* UIKit.framework in Frameworks */,
FDAAC5C40E2D55B5001DB1D8 /* Foundation.framework in Frameworks */, FDAAC5C40E2D55B5001DB1D8 /* Foundation.framework in Frameworks */,
55FFA922212232C100D7CBED /* CoreBluetooth.framework in Frameworks */,
FDAAC5C50E2D55B5001DB1D8 /* CoreAudio.framework in Frameworks */, FDAAC5C50E2D55B5001DB1D8 /* CoreAudio.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -825,7 +781,6 @@
FABA34B61D8B5B8900915323 /* AVFoundation.framework in Frameworks */, FABA34B61D8B5B8900915323 /* AVFoundation.framework in Frameworks */,
AA1EE47417605B5C0029C7A5 /* libSDL2test.a in Frameworks */, AA1EE47417605B5C0029C7A5 /* libSDL2test.a in Frameworks */,
FDBDE57C0E313445006BAC0B /* libSDL2.a in Frameworks */, FDBDE57C0E313445006BAC0B /* libSDL2.a in Frameworks */,
55FFA927212232C500D7CBED /* CoreBluetooth.framework in Frameworks */,
FA684F851BAF1A6000DCFD1A /* GameController.framework in Frameworks */, FA684F851BAF1A6000DCFD1A /* GameController.framework in Frameworks */,
FA8B4BD2196766CB00F8EB7C /* CoreMotion.framework in Frameworks */, FA8B4BD2196766CB00F8EB7C /* CoreMotion.framework in Frameworks */,
FDAAC61C0E2D5914001DB1D8 /* AudioToolbox.framework in Frameworks */, FDAAC61C0E2D5914001DB1D8 /* AudioToolbox.framework in Frameworks */,
@ -846,7 +801,6 @@
FABA34B21D8B5B7300915323 /* AVFoundation.framework in Frameworks */, FABA34B21D8B5B7300915323 /* AVFoundation.framework in Frameworks */,
AA1EE47117605A7F0029C7A5 /* libSDL2test.a in Frameworks */, AA1EE47117605A7F0029C7A5 /* libSDL2test.a in Frameworks */,
FDC42FF40F0D866D009C87E1 /* libSDL2.a in Frameworks */, FDC42FF40F0D866D009C87E1 /* libSDL2.a in Frameworks */,
55FFA921212232C100D7CBED /* CoreBluetooth.framework in Frameworks */,
FA684F811BAF1A5300DCFD1A /* GameController.framework in Frameworks */, FA684F811BAF1A5300DCFD1A /* GameController.framework in Frameworks */,
FA8B4BCE196766C100F8EB7C /* CoreMotion.framework in Frameworks */, FA8B4BCE196766C100F8EB7C /* CoreMotion.framework in Frameworks */,
FDC42FF60F0D866D009C87E1 /* AudioToolbox.framework in Frameworks */, FDC42FF60F0D866D009C87E1 /* AudioToolbox.framework in Frameworks */,
@ -873,7 +827,6 @@
FDD2C1030E2E4F4B00B7A85F /* CoreGraphics.framework in Frameworks */, FDD2C1030E2E4F4B00B7A85F /* CoreGraphics.framework in Frameworks */,
FDD2C1040E2E4F4B00B7A85F /* UIKit.framework in Frameworks */, FDD2C1040E2E4F4B00B7A85F /* UIKit.framework in Frameworks */,
FDD2C1050E2E4F4B00B7A85F /* Foundation.framework in Frameworks */, FDD2C1050E2E4F4B00B7A85F /* Foundation.framework in Frameworks */,
55FFA932212232CC00D7CBED /* CoreBluetooth.framework in Frameworks */,
FDD2C1060E2E4F4B00B7A85F /* CoreAudio.framework in Frameworks */, FDD2C1060E2E4F4B00B7A85F /* CoreAudio.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -892,7 +845,6 @@
FDD2C17A0E2E52C000B7A85F /* CoreGraphics.framework in Frameworks */, FDD2C17A0E2E52C000B7A85F /* CoreGraphics.framework in Frameworks */,
FDD2C17B0E2E52C000B7A85F /* UIKit.framework in Frameworks */, FDD2C17B0E2E52C000B7A85F /* UIKit.framework in Frameworks */,
FDD2C17C0E2E52C000B7A85F /* Foundation.framework in Frameworks */, FDD2C17C0E2E52C000B7A85F /* Foundation.framework in Frameworks */,
55FFA928212232C500D7CBED /* CoreBluetooth.framework in Frameworks */,
FDD2C17D0E2E52C000B7A85F /* CoreAudio.framework in Frameworks */, FDD2C17D0E2E52C000B7A85F /* CoreAudio.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -911,7 +863,6 @@
FDD2C19E0E2E534F00B7A85F /* CoreGraphics.framework in Frameworks */, FDD2C19E0E2E534F00B7A85F /* CoreGraphics.framework in Frameworks */,
FDD2C19F0E2E534F00B7A85F /* UIKit.framework in Frameworks */, FDD2C19F0E2E534F00B7A85F /* UIKit.framework in Frameworks */,
FDD2C1A00E2E534F00B7A85F /* Foundation.framework in Frameworks */, FDD2C1A00E2E534F00B7A85F /* Foundation.framework in Frameworks */,
55FFA929212232C600D7CBED /* CoreBluetooth.framework in Frameworks */,
FDD2C1A10E2E534F00B7A85F /* CoreAudio.framework in Frameworks */, FDD2C1A10E2E534F00B7A85F /* CoreAudio.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -930,7 +881,6 @@
FDD2C4570E2E773800B7A85F /* CoreGraphics.framework in Frameworks */, FDD2C4570E2E773800B7A85F /* CoreGraphics.framework in Frameworks */,
FDD2C4580E2E773800B7A85F /* UIKit.framework in Frameworks */, FDD2C4580E2E773800B7A85F /* UIKit.framework in Frameworks */,
FDD2C4590E2E773800B7A85F /* Foundation.framework in Frameworks */, FDD2C4590E2E773800B7A85F /* Foundation.framework in Frameworks */,
55FFA92A212232C600D7CBED /* CoreBluetooth.framework in Frameworks */,
FDD2C45A0E2E773800B7A85F /* CoreAudio.framework in Frameworks */, FDD2C45A0E2E773800B7A85F /* CoreAudio.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -949,7 +899,6 @@
FDD2C4750E2E77D700B7A85F /* CoreGraphics.framework in Frameworks */, FDD2C4750E2E77D700B7A85F /* CoreGraphics.framework in Frameworks */,
FDD2C4760E2E77D700B7A85F /* UIKit.framework in Frameworks */, FDD2C4760E2E77D700B7A85F /* UIKit.framework in Frameworks */,
FDD2C4770E2E77D700B7A85F /* Foundation.framework in Frameworks */, FDD2C4770E2E77D700B7A85F /* Foundation.framework in Frameworks */,
55FFA92B212232C700D7CBED /* CoreBluetooth.framework in Frameworks */,
FDD2C4780E2E77D700B7A85F /* CoreAudio.framework in Frameworks */, FDD2C4780E2E77D700B7A85F /* CoreAudio.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -968,7 +917,6 @@
FDD2C5040E2E7F4800B7A85F /* CoreGraphics.framework in Frameworks */, FDD2C5040E2E7F4800B7A85F /* CoreGraphics.framework in Frameworks */,
FDD2C5050E2E7F4800B7A85F /* UIKit.framework in Frameworks */, FDD2C5050E2E7F4800B7A85F /* UIKit.framework in Frameworks */,
FDD2C5060E2E7F4800B7A85F /* Foundation.framework in Frameworks */, FDD2C5060E2E7F4800B7A85F /* Foundation.framework in Frameworks */,
55FFA92C212232C700D7CBED /* CoreBluetooth.framework in Frameworks */,
FDD2C5070E2E7F4800B7A85F /* CoreAudio.framework in Frameworks */, FDD2C5070E2E7F4800B7A85F /* CoreAudio.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -987,7 +935,6 @@
FDD2C5220E2E807600B7A85F /* CoreGraphics.framework in Frameworks */, FDD2C5220E2E807600B7A85F /* CoreGraphics.framework in Frameworks */,
FDD2C5230E2E807600B7A85F /* UIKit.framework in Frameworks */, FDD2C5230E2E807600B7A85F /* UIKit.framework in Frameworks */,
FDD2C5240E2E807600B7A85F /* Foundation.framework in Frameworks */, FDD2C5240E2E807600B7A85F /* Foundation.framework in Frameworks */,
55FFA930212232CB00D7CBED /* CoreBluetooth.framework in Frameworks */,
FDD2C5250E2E807600B7A85F /* CoreAudio.framework in Frameworks */, FDD2C5250E2E807600B7A85F /* CoreAudio.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -1000,7 +947,6 @@
FABA34C01D8B5BBA00915323 /* AVFoundation.framework in Frameworks */, FABA34C01D8B5BBA00915323 /* AVFoundation.framework in Frameworks */,
AA1EE47717605BAB0029C7A5 /* libSDL2test.a in Frameworks */, AA1EE47717605BAB0029C7A5 /* libSDL2test.a in Frameworks */,
FDBDE5CA0E313712006BAC0B /* libSDL2.a in Frameworks */, FDBDE5CA0E313712006BAC0B /* libSDL2.a in Frameworks */,
55FFA931212232CB00D7CBED /* CoreBluetooth.framework in Frameworks */,
FA684F8F1BAF1A7E00DCFD1A /* GameController.framework in Frameworks */, FA684F8F1BAF1A7E00DCFD1A /* GameController.framework in Frameworks */,
FA8B4BDC196766E800F8EB7C /* CoreMotion.framework in Frameworks */, FA8B4BDC196766E800F8EB7C /* CoreMotion.framework in Frameworks */,
FDD2C5440E2E80E400B7A85F /* AudioToolbox.framework in Frameworks */, FDD2C5440E2E80E400B7A85F /* AudioToolbox.framework in Frameworks */,
@ -1027,7 +973,6 @@
FDD2C5800E2E8C7400B7A85F /* CoreGraphics.framework in Frameworks */, FDD2C5800E2E8C7400B7A85F /* CoreGraphics.framework in Frameworks */,
FDD2C5810E2E8C7400B7A85F /* UIKit.framework in Frameworks */, FDD2C5810E2E8C7400B7A85F /* UIKit.framework in Frameworks */,
FDD2C5820E2E8C7400B7A85F /* Foundation.framework in Frameworks */, FDD2C5820E2E8C7400B7A85F /* Foundation.framework in Frameworks */,
55FFA934212232CD00D7CBED /* CoreBluetooth.framework in Frameworks */,
FDD2C5830E2E8C7400B7A85F /* CoreAudio.framework in Frameworks */, FDD2C5830E2E8C7400B7A85F /* CoreAudio.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -1046,7 +991,6 @@
FDD2C5BE0E2E8CFC00B7A85F /* CoreGraphics.framework in Frameworks */, FDD2C5BE0E2E8CFC00B7A85F /* CoreGraphics.framework in Frameworks */,
FDD2C5BF0E2E8CFC00B7A85F /* UIKit.framework in Frameworks */, FDD2C5BF0E2E8CFC00B7A85F /* UIKit.framework in Frameworks */,
FDD2C5C00E2E8CFC00B7A85F /* Foundation.framework in Frameworks */, FDD2C5C00E2E8CFC00B7A85F /* Foundation.framework in Frameworks */,
55FFA933212232CC00D7CBED /* CoreBluetooth.framework in Frameworks */,
FDD2C5C10E2E8CFC00B7A85F /* CoreAudio.framework in Frameworks */, FDD2C5C10E2E8CFC00B7A85F /* CoreAudio.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -1065,7 +1009,6 @@
FDD2C6ED0E2E959E00B7A85F /* CoreGraphics.framework in Frameworks */, FDD2C6ED0E2E959E00B7A85F /* CoreGraphics.framework in Frameworks */,
FDD2C6EE0E2E959E00B7A85F /* UIKit.framework in Frameworks */, FDD2C6EE0E2E959E00B7A85F /* UIKit.framework in Frameworks */,
FDD2C6EF0E2E959E00B7A85F /* Foundation.framework in Frameworks */, FDD2C6EF0E2E959E00B7A85F /* Foundation.framework in Frameworks */,
55FFA937212232CF00D7CBED /* CoreBluetooth.framework in Frameworks */,
FDD2C6F00E2E959E00B7A85F /* CoreAudio.framework in Frameworks */, FDD2C6F00E2E959E00B7A85F /* CoreAudio.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -1188,7 +1131,6 @@
FDA8A7C30E2D10FA00EA573E /* Frameworks */ = { FDA8A7C30E2D10FA00EA573E /* Frameworks */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
55FFA91B212232BA00D7CBED /* CoreBluetooth.framework */,
FA684F7A1BAF1A4400DCFD1A /* GameController.framework */, FA684F7A1BAF1A4400DCFD1A /* GameController.framework */,
FA8B4BAC1967076F00F8EB7C /* CoreMotion.framework */, FA8B4BAC1967076F00F8EB7C /* CoreMotion.framework */,
FDA8A8980E2D111A00EA573E /* AudioToolbox.framework */, FDA8A8980E2D111A00EA573E /* AudioToolbox.framework */,
@ -2384,6 +2326,7 @@
C01FCF4F08A954540054247B /* Debug */ = { C01FCF4F08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
GCC_OPTIMIZATION_LEVEL = 0; GCC_OPTIMIZATION_LEVEL = 0;
@ -2400,6 +2343,7 @@
C01FCF5008A954540054247B /* Release */ = { C01FCF5008A954540054247B /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
HEADER_SEARCH_PATHS = ../../include; HEADER_SEARCH_PATHS = ../../include;

View File

@ -19,10 +19,10 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>FMWK</string> <string>FMWK</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>2.0.8</string> <string>2.0.9</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>SDLX</string> <string>SDLX</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>2.0.8</string> <string>2.0.9</string>
</dict> </dict>
</plist> </plist>

View File

@ -2614,7 +2614,7 @@
0867D690FE84028FC02AAC07 /* Project object */ = { 0867D690FE84028FC02AAC07 /* Project object */ = {
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
LastUpgradeCheck = 0900; LastUpgradeCheck = 1000;
}; };
buildConfigurationList = 0073178E0858DB0500B2BC32 /* Build configuration list for PBXProject "SDL" */; buildConfigurationList = 0073178E0858DB0500B2BC32 /* Build configuration list for PBXProject "SDL" */;
compatibilityVersion = "Xcode 3.2"; compatibilityVersion = "Xcode 3.2";
@ -3107,16 +3107,19 @@
00CFA621106A567900758660 /* Release */ = { 00CFA621106A567900758660 /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES; CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_STRICT_PROTOTYPES = YES;
@ -3153,11 +3156,11 @@
00CFA622106A567900758660 /* Release */ = { 00CFA622106A567900758660 /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_LINK_OBJC_RUNTIME = NO; CLANG_LINK_OBJC_RUNTIME = NO;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
DYLIB_COMPATIBILITY_VERSION = 1.0.0; DYLIB_COMPATIBILITY_VERSION = 1.0.0;
DYLIB_CURRENT_VERSION = 9.0.0; DYLIB_CURRENT_VERSION = 10.0.0;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)", "$(PROJECT_DIR)",
@ -3176,6 +3179,7 @@
00CFA623106A567900758660 /* Release */ = { 00CFA623106A567900758660 /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
GCC_PREPROCESSOR_DEFINITIONS = ( GCC_PREPROCESSOR_DEFINITIONS = (
"$(GCC_PREPROCESSOR_DEFINITIONS)", "$(GCC_PREPROCESSOR_DEFINITIONS)",
@ -3193,6 +3197,7 @@
00CFA625106A567900758660 /* Release */ = { 00CFA625106A567900758660 /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
PRODUCT_NAME = "Standard DMG"; PRODUCT_NAME = "Standard DMG";
PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE = "";
}; };
@ -3201,16 +3206,19 @@
00CFA627106A568900758660 /* Debug */ = { 00CFA627106A568900758660 /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES; CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_STRICT_PROTOTYPES = YES;
@ -3247,11 +3255,11 @@
00CFA628106A568900758660 /* Debug */ = { 00CFA628106A568900758660 /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_LINK_OBJC_RUNTIME = NO; CLANG_LINK_OBJC_RUNTIME = NO;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
DYLIB_COMPATIBILITY_VERSION = 1.0.0; DYLIB_COMPATIBILITY_VERSION = 1.0.0;
DYLIB_CURRENT_VERSION = 9.0.0; DYLIB_CURRENT_VERSION = 10.0.0;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)", "$(PROJECT_DIR)",
@ -3270,6 +3278,7 @@
00CFA629106A568900758660 /* Debug */ = { 00CFA629106A568900758660 /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
GCC_PREPROCESSOR_DEFINITIONS = ( GCC_PREPROCESSOR_DEFINITIONS = (
"$(GCC_PREPROCESSOR_DEFINITIONS)", "$(GCC_PREPROCESSOR_DEFINITIONS)",
@ -3287,6 +3296,7 @@
00CFA62B106A568900758660 /* Debug */ = { 00CFA62B106A568900758660 /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
PRODUCT_NAME = "Standard DMG"; PRODUCT_NAME = "Standard DMG";
PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE = "";
}; };
@ -3295,6 +3305,7 @@
DB31407517554B71006C0E22 /* Debug */ = { DB31407517554B71006C0E22 /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
EXECUTABLE_PREFIX = lib; EXECUTABLE_PREFIX = lib;
GCC_PREPROCESSOR_DEFINITIONS = ( GCC_PREPROCESSOR_DEFINITIONS = (
@ -3314,6 +3325,7 @@
DB31407617554B71006C0E22 /* Release */ = { DB31407617554B71006C0E22 /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
EXECUTABLE_PREFIX = lib; EXECUTABLE_PREFIX = lib;
GCC_PREPROCESSOR_DEFINITIONS = ( GCC_PREPROCESSOR_DEFINITIONS = (

View File

@ -4040,6 +4040,7 @@
002A85B21073008E007319AE /* Debug */ = { 002A85B21073008E007319AE /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
"$(SRCROOT)/../SDL/build/$(CONFIGURATION)", "$(SRCROOT)/../SDL/build/$(CONFIGURATION)",
"$(HOME)/Library/Frameworks", "$(HOME)/Library/Frameworks",
@ -4166,6 +4167,7 @@
002A85D41073009D007319AE /* Release */ = { 002A85D41073009D007319AE /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
"$(SRCROOT)/../SDL/build/$(CONFIGURATION)", "$(SRCROOT)/../SDL/build/$(CONFIGURATION)",
"$(HOME)/Library/Frameworks", "$(HOME)/Library/Frameworks",

View File

@ -9,7 +9,6 @@ else {
android { android {
compileSdkVersion 26 compileSdkVersion 26
buildToolsVersion "26.0.1"
defaultConfig { defaultConfig {
if (buildAsApplication) { if (buildAsApplication) {
applicationId "org.libsdl.app" applicationId "org.libsdl.app"
@ -21,10 +20,9 @@ android {
externalNativeBuild { externalNativeBuild {
ndkBuild { ndkBuild {
arguments "APP_PLATFORM=android-14" arguments "APP_PLATFORM=android-14"
abiFilters 'armeabi-v7a', 'x86' abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
} }
} }
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
} }
buildTypes { buildTypes {
release { release {
@ -61,9 +59,5 @@ android {
} }
dependencies { dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs') implementation fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
testCompile 'junit:junit:4.12'
} }

View File

@ -1,7 +1,8 @@
# Uncomment this if you're using STL in your project # Uncomment this if you're using STL in your project
# See CPLUSPLUS-SUPPORT.html in the NDK documentation for more information # You can find more information here:
# APP_STL := stlport_static # https://developer.android.com/ndk/guides/cpp-support
# APP_STL := c++_shared
APP_ABI := armeabi-v7a arm64-v8a x86 x86_64 APP_ABI := armeabi-v7a arm64-v8a x86 x86_64

View File

@ -8,9 +8,6 @@
android:versionName="1.0" android:versionName="1.0"
android:installLocation="auto"> android:installLocation="auto">
<!-- Android 4.0.1 -->
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="16" />
<!-- OpenGL ES 2.0 --> <!-- OpenGL ES 2.0 -->
<uses-feature android:glEsVersion="0x00020000" /> <uses-feature android:glEsVersion="0x00020000" />

View File

@ -479,7 +479,7 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe
// Enable this for verbose logging of controller input reports // Enable this for verbose logging of controller input reports
//Log.v(TAG, "onCharacteristicChanged uuid=" + characteristic.getUuid() + " data=" + HexDump.dumpHexString(characteristic.getValue())); //Log.v(TAG, "onCharacteristicChanged uuid=" + characteristic.getUuid() + " data=" + HexDump.dumpHexString(characteristic.getValue()));
if (characteristic.getUuid().equals(inputCharacteristic)) { if (characteristic.getUuid().equals(inputCharacteristic) && !mFrozen) {
mManager.HIDDeviceInputReport(getId(), characteristic.getValue()); mManager.HIDDeviceInputReport(getId(), characteristic.getValue());
} }
} }
@ -577,7 +577,7 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe
} }
// We need to skip the first byte, as that doesn't go over the air // We need to skip the first byte, as that doesn't go over the air
byte[] actual_report = Arrays.copyOfRange(report, 1, report.length - 1); byte[] actual_report = Arrays.copyOfRange(report, 1, report.length - 1);
//Log.v(TAG, "sendFeatureReport " + HexDump.dumpHexString(actual_report)); //Log.v(TAG, "sendFeatureReport " + HexDump.dumpHexString(actual_report));
writeCharacteristic(reportCharacteristic, actual_report); writeCharacteristic(reportCharacteristic, actual_report);
return report.length; return report.length;
@ -624,6 +624,8 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe
@Override @Override
public void shutdown() { public void shutdown() {
close();
BluetoothGatt g = mGatt; BluetoothGatt g = mGatt;
if (g != null) { if (g != null) {
g.disconnect(); g.disconnect();

View File

@ -1,5 +1,7 @@
package org.libsdl.app; package org.libsdl.app;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothDevice;
@ -8,6 +10,7 @@ import android.bluetooth.BluetoothProfile;
import android.util.Log; import android.util.Log;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.SharedPreferences; import android.content.SharedPreferences;
@ -24,7 +27,28 @@ public class HIDDeviceManager {
private static final String TAG = "hidapi"; private static final String TAG = "hidapi";
private static final String ACTION_USB_PERMISSION = "org.libsdl.app.USB_PERMISSION"; private static final String ACTION_USB_PERMISSION = "org.libsdl.app.USB_PERMISSION";
protected Context mContext; private static HIDDeviceManager sManager;
private static int sManagerRefCount = 0;
public static HIDDeviceManager acquire(Context context) {
if (sManagerRefCount == 0) {
sManager = new HIDDeviceManager(context);
}
++sManagerRefCount;
return sManager;
}
public static void release(HIDDeviceManager manager) {
if (manager == sManager) {
--sManagerRefCount;
if (sManagerRefCount == 0) {
sManager.close();
sManager = null;
}
}
}
private Context mContext;
private HashMap<Integer, HIDDevice> mDevicesById = new HashMap<Integer, HIDDevice>(); private HashMap<Integer, HIDDevice> mDevicesById = new HashMap<Integer, HIDDevice>();
private HashMap<UsbDevice, HIDDeviceUSB> mUSBDevices = new HashMap<UsbDevice, HIDDeviceUSB>(); private HashMap<UsbDevice, HIDDeviceUSB> mUSBDevices = new HashMap<UsbDevice, HIDDeviceUSB>();
private HashMap<BluetoothDevice, HIDDeviceBLESteamController> mBluetoothDevices = new HashMap<BluetoothDevice, HIDDeviceBLESteamController>(); private HashMap<BluetoothDevice, HIDDeviceBLESteamController> mBluetoothDevices = new HashMap<BluetoothDevice, HIDDeviceBLESteamController>();
@ -77,10 +101,40 @@ public class HIDDeviceManager {
} }
}; };
public HIDDeviceManager(Context context) { private HIDDeviceManager(final Context context) {
mContext = context; mContext = context;
HIDDeviceRegisterCallback(this); // Make sure we have the HIDAPI library loaded with the native functions
try {
SDL.loadLibrary("hidapi");
} catch (Throwable e) {
Log.w(TAG, "Couldn't load hidapi: " + e.toString());
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setCancelable(false);
builder.setTitle("SDL HIDAPI Error");
builder.setMessage("Please report the following error to the SDL maintainers: " + e.getMessage());
builder.setNegativeButton("Quit", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
try {
// If our context is an activity, exit rather than crashing when we can't
// call our native functions.
Activity activity = (Activity)context;
activity.finish();
}
catch (ClassCastException cce) {
// Context wasn't an activity, there's nothing we can do. Give up and return.
}
}
});
builder.show();
return;
}
HIDDeviceRegisterCallback();
mSharedPreferences = mContext.getSharedPreferences("hidapi", Context.MODE_PRIVATE); mSharedPreferences = mContext.getSharedPreferences("hidapi", Context.MODE_PRIVATE);
mIsChromebook = mContext.getPackageManager().hasSystemFeature("org.chromium.arc.device_management"); mIsChromebook = mContext.getPackageManager().hasSystemFeature("org.chromium.arc.device_management");
@ -117,7 +171,7 @@ public class HIDDeviceManager {
return result; return result;
} }
protected void initializeUSB() { private void initializeUSB() {
mUsbManager = (UsbManager)mContext.getSystemService(Context.USB_SERVICE); mUsbManager = (UsbManager)mContext.getSystemService(Context.USB_SERVICE);
/* /*
@ -179,11 +233,15 @@ public class HIDDeviceManager {
return mUsbManager; return mUsbManager;
} }
protected void shutdownUSB() { private void shutdownUSB() {
mContext.unregisterReceiver(mUsbBroadcast); try {
mContext.unregisterReceiver(mUsbBroadcast);
} catch (Exception e) {
// We may not have registered, that's okay
}
} }
protected boolean isHIDDeviceUSB(UsbDevice usbDevice) { private boolean isHIDDeviceUSB(UsbDevice usbDevice) {
for (int interface_number = 0; interface_number < usbDevice.getInterfaceCount(); ++interface_number) { for (int interface_number = 0; interface_number < usbDevice.getInterfaceCount(); ++interface_number) {
if (isHIDDeviceInterface(usbDevice, interface_number)) { if (isHIDDeviceInterface(usbDevice, interface_number)) {
return true; return true;
@ -192,7 +250,7 @@ public class HIDDeviceManager {
return false; return false;
} }
protected boolean isHIDDeviceInterface(UsbDevice usbDevice, int interface_number) { private boolean isHIDDeviceInterface(UsbDevice usbDevice, int interface_number) {
UsbInterface usbInterface = usbDevice.getInterface(interface_number); UsbInterface usbInterface = usbDevice.getInterface(interface_number);
if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_HID) { if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_HID) {
return true; return true;
@ -205,7 +263,7 @@ public class HIDDeviceManager {
return false; return false;
} }
protected boolean isXbox360Controller(UsbDevice usbDevice, UsbInterface usbInterface) { private boolean isXbox360Controller(UsbDevice usbDevice, UsbInterface usbInterface) {
final int XB360_IFACE_SUBCLASS = 93; final int XB360_IFACE_SUBCLASS = 93;
final int XB360_IFACE_PROTOCOL = 1; // Wired only final int XB360_IFACE_PROTOCOL = 1; // Wired only
final int[] SUPPORTED_VENDORS = { final int[] SUPPORTED_VENDORS = {
@ -244,7 +302,7 @@ public class HIDDeviceManager {
return false; return false;
} }
protected boolean isXboxOneController(UsbDevice usbDevice, UsbInterface usbInterface) { private boolean isXboxOneController(UsbDevice usbDevice, UsbInterface usbInterface) {
final int XB1_IFACE_SUBCLASS = 71; final int XB1_IFACE_SUBCLASS = 71;
final int XB1_IFACE_PROTOCOL = 208; final int XB1_IFACE_PROTOCOL = 208;
final int[] SUPPORTED_VENDORS = { final int[] SUPPORTED_VENDORS = {
@ -269,13 +327,13 @@ public class HIDDeviceManager {
return false; return false;
} }
protected void handleUsbDeviceAttached(UsbDevice usbDevice) { private void handleUsbDeviceAttached(UsbDevice usbDevice) {
if (isHIDDeviceUSB(usbDevice)) { if (isHIDDeviceUSB(usbDevice)) {
connectHIDDeviceUSB(usbDevice); connectHIDDeviceUSB(usbDevice);
} }
} }
protected void handleUsbDeviceDetached(UsbDevice usbDevice) { private void handleUsbDeviceDetached(UsbDevice usbDevice) {
HIDDeviceUSB device = mUSBDevices.get(usbDevice); HIDDeviceUSB device = mUSBDevices.get(usbDevice);
if (device == null) if (device == null)
return; return;
@ -287,7 +345,7 @@ public class HIDDeviceManager {
HIDDeviceDisconnected(id); HIDDeviceDisconnected(id);
} }
protected void handleUsbDevicePermission(UsbDevice usbDevice, boolean permission_granted) { private void handleUsbDevicePermission(UsbDevice usbDevice, boolean permission_granted) {
HIDDeviceUSB device = mUSBDevices.get(usbDevice); HIDDeviceUSB device = mUSBDevices.get(usbDevice);
if (device == null) if (device == null)
return; return;
@ -299,7 +357,7 @@ public class HIDDeviceManager {
HIDDeviceOpenResult(device.getId(), opened); HIDDeviceOpenResult(device.getId(), opened);
} }
protected void connectHIDDeviceUSB(UsbDevice usbDevice) { private void connectHIDDeviceUSB(UsbDevice usbDevice) {
synchronized (this) { synchronized (this) {
for (int interface_number = 0; interface_number < usbDevice.getInterfaceCount(); interface_number++) { for (int interface_number = 0; interface_number < usbDevice.getInterfaceCount(); interface_number++) {
if (isHIDDeviceInterface(usbDevice, interface_number)) { if (isHIDDeviceInterface(usbDevice, interface_number)) {
@ -314,7 +372,7 @@ public class HIDDeviceManager {
} }
} }
protected void initializeBluetooth() { private void initializeBluetooth() {
Log.d(TAG, "Initializing Bluetooth"); Log.d(TAG, "Initializing Bluetooth");
if (mContext.getPackageManager().checkPermission(android.Manifest.permission.BLUETOOTH, mContext.getPackageName()) != PackageManager.PERMISSION_GRANTED) { if (mContext.getPackageManager().checkPermission(android.Manifest.permission.BLUETOOTH, mContext.getPackageName()) != PackageManager.PERMISSION_GRANTED) {
@ -365,7 +423,7 @@ public class HIDDeviceManager {
} }
} }
protected void shutdownBluetooth() { private void shutdownBluetooth() {
try { try {
mContext.unregisterReceiver(mBluetoothBroadcast); mContext.unregisterReceiver(mBluetoothBroadcast);
} catch (Exception e) { } catch (Exception e) {
@ -464,7 +522,7 @@ public class HIDDeviceManager {
return bluetoothDevice.getName().equals("SteamController") && ((bluetoothDevice.getType() & BluetoothDevice.DEVICE_TYPE_LE) != 0); return bluetoothDevice.getName().equals("SteamController") && ((bluetoothDevice.getType() & BluetoothDevice.DEVICE_TYPE_LE) != 0);
} }
public void close() { private void close() {
shutdownUSB(); shutdownUSB();
shutdownBluetooth(); shutdownBluetooth();
synchronized (this) { synchronized (this) {
@ -504,7 +562,7 @@ public class HIDDeviceManager {
////////// JNI interface functions ////////// JNI interface functions
////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////
boolean openDevice(int deviceID) { public boolean openDevice(int deviceID) {
// Look to see if this is a USB device and we have permission to access it // Look to see if this is a USB device and we have permission to access it
for (HIDDeviceUSB device : mUSBDevices.values()) { for (HIDDeviceUSB device : mUSBDevices.values()) {
if (deviceID == device.getId()) { if (deviceID == device.getId()) {
@ -539,7 +597,7 @@ public class HIDDeviceManager {
return false; return false;
} }
int sendOutputReport(int deviceID, byte[] report) { public int sendOutputReport(int deviceID, byte[] report) {
try { try {
Log.v(TAG, "sendOutputReport deviceID=" + deviceID + " length=" + report.length); Log.v(TAG, "sendOutputReport deviceID=" + deviceID + " length=" + report.length);
HIDDevice device; HIDDevice device;
@ -556,7 +614,7 @@ public class HIDDeviceManager {
return -1; return -1;
} }
int sendFeatureReport(int deviceID, byte[] report) { public int sendFeatureReport(int deviceID, byte[] report) {
try { try {
Log.v(TAG, "sendFeatureReport deviceID=" + deviceID + " length=" + report.length); Log.v(TAG, "sendFeatureReport deviceID=" + deviceID + " length=" + report.length);
HIDDevice device; HIDDevice device;
@ -573,7 +631,7 @@ public class HIDDeviceManager {
return -1; return -1;
} }
boolean getFeatureReport(int deviceID, byte[] report) { public boolean getFeatureReport(int deviceID, byte[] report) {
try { try {
Log.v(TAG, "getFeatureReport deviceID=" + deviceID); Log.v(TAG, "getFeatureReport deviceID=" + deviceID);
HIDDevice device; HIDDevice device;
@ -590,7 +648,7 @@ public class HIDDeviceManager {
return false; return false;
} }
void closeDevice(int deviceID) { public void closeDevice(int deviceID) {
try { try {
Log.v(TAG, "closeDevice deviceID=" + deviceID); Log.v(TAG, "closeDevice deviceID=" + deviceID);
HIDDevice device; HIDDevice device;
@ -611,7 +669,7 @@ public class HIDDeviceManager {
/////////////// Native methods /////////////// Native methods
////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////
private native void HIDDeviceRegisterCallback(Object callbackHandler); private native void HIDDeviceRegisterCallback();
private native void HIDDeviceReleaseCallback(); private native void HIDDeviceReleaseCallback();
native void HIDDeviceConnected(int deviceID, String identifier, int vendorId, int productId, String serial_number, int release_number, String manufacturer_string, String product_string, int interface_number); native void HIDDeviceConnected(int deviceID, String identifier, int vendorId, int productId, String serial_number, int release_number, String manufacturer_string, String product_string, int interface_number);

View File

@ -276,7 +276,16 @@ class HIDDeviceUSB implements HIDDevice {
int packetSize = mInputEndpoint.getMaxPacketSize(); int packetSize = mInputEndpoint.getMaxPacketSize();
byte[] packet = new byte[packetSize]; byte[] packet = new byte[packetSize];
while (mRunning) { while (mRunning) {
int r = mConnection.bulkTransfer(mInputEndpoint, packet, packetSize, 1000); int r;
try
{
r = mConnection.bulkTransfer(mInputEndpoint, packet, packetSize, 1000);
}
catch (Exception e)
{
Log.v(TAG, "Exception in UsbDeviceConnection bulktransfer: " + e);
break;
}
if (r < 0) { if (r < 0) {
// Could be a timeout or an I/O error // Could be a timeout or an I/O error
} }

View File

@ -2,6 +2,8 @@ package org.libsdl.app;
import android.content.Context; import android.content.Context;
import java.lang.reflect.*;
/** /**
SDL library initialization SDL library initialization
*/ */
@ -33,5 +35,50 @@ public class SDL {
return mContext; return mContext;
} }
public static void loadLibrary(String libraryName) throws UnsatisfiedLinkError, SecurityException, NullPointerException {
if (libraryName == null) {
throw new NullPointerException("No library name provided.");
}
try {
// Let's see if we have ReLinker available in the project. This is necessary for
// some projects that have huge numbers of local libraries bundled, and thus may
// trip a bug in Android's native library loader which ReLinker works around. (If
// loadLibrary works properly, ReLinker will simply use the normal Android method
// internally.)
//
// To use ReLinker, just add it as a dependency. For more information, see
// https://github.com/KeepSafe/ReLinker for ReLinker's repository.
//
Class relinkClass = mContext.getClassLoader().loadClass("com.getkeepsafe.relinker.ReLinker");
Class relinkListenerClass = mContext.getClassLoader().loadClass("com.getkeepsafe.relinker.ReLinker$LoadListener");
Class contextClass = mContext.getClassLoader().loadClass("android.content.Context");
Class stringClass = mContext.getClassLoader().loadClass("java.lang.String");
// Get a 'force' instance of the ReLinker, so we can ensure libraries are reinstalled if
// they've changed during updates.
Method forceMethod = relinkClass.getDeclaredMethod("force");
Object relinkInstance = forceMethod.invoke(null);
Class relinkInstanceClass = relinkInstance.getClass();
// Actually load the library!
Method loadMethod = relinkInstanceClass.getDeclaredMethod("loadLibrary", contextClass, stringClass, stringClass, relinkListenerClass);
loadMethod.invoke(relinkInstance, mContext, libraryName, null, null);
}
catch (final Throwable e) {
// Fall back
try {
System.loadLibrary(libraryName);
}
catch (final UnsatisfiedLinkError ule) {
throw ule;
}
catch (final SecurityException se) {
throw se;
}
}
}
protected static Context mContext; protected static Context mContext;
} }

View File

@ -154,7 +154,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
// Load the .so // Load the .so
public void loadLibraries() { public void loadLibraries() {
for (String lib : getLibraries()) { for (String lib : getLibraries()) {
System.loadLibrary(lib); SDL.loadLibrary(lib);
} }
} }
@ -191,8 +191,8 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
// Setup // Setup
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
Log.v(TAG, "Device: " + android.os.Build.DEVICE); Log.v(TAG, "Device: " + Build.DEVICE);
Log.v(TAG, "Model: " + android.os.Build.MODEL); Log.v(TAG, "Model: " + Build.MODEL);
Log.v(TAG, "onCreate()"); Log.v(TAG, "onCreate()");
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -250,7 +250,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
mClipboardHandler = new SDLClipboardHandler_Old(); mClipboardHandler = new SDLClipboardHandler_Old();
} }
mHIDDeviceManager = new HIDDeviceManager(this); mHIDDeviceManager = HIDDeviceManager.acquire(this);
// Set up the surface // Set up the surface
mSurface = new SDLSurface(getApplication()); mSurface = new SDLSurface(getApplication());
@ -380,7 +380,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
Log.v(TAG, "onDestroy()"); Log.v(TAG, "onDestroy()");
if (mHIDDeviceManager != null) { if (mHIDDeviceManager != null) {
mHIDDeviceManager.close(); HIDDeviceManager.release(mHIDDeviceManager);
mHIDDeviceManager = null; mHIDDeviceManager = null;
} }
@ -520,7 +520,9 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
/* The native thread has finished */ /* The native thread has finished */
public static void handleNativeExit() { public static void handleNativeExit() {
SDLActivity.mSDLThread = null; SDLActivity.mSDLThread = null;
mSingleton.finish(); if (mSingleton != null) {
mSingleton.finish();
}
} }
@ -581,7 +583,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY |
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.INVISIBLE; View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.INVISIBLE;
window.getDecorView().setSystemUiVisibility(flags); window.getDecorView().setSystemUiVisibility(flags);
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
window.clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN); window.clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
@ -641,7 +643,61 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
Message msg = commandHandler.obtainMessage(); Message msg = commandHandler.obtainMessage();
msg.arg1 = command; msg.arg1 = command;
msg.obj = data; msg.obj = data;
return commandHandler.sendMessage(msg); boolean result = commandHandler.sendMessage(msg);
if ((Build.VERSION.SDK_INT >= 19) && (command == COMMAND_CHANGE_WINDOW_STYLE)) {
// Ensure we don't return until the resize has actually happened,
// or 500ms have passed.
boolean bShouldWait = false;
if (data instanceof Integer) {
// Let's figure out if we're already laid out fullscreen or not.
Display display = ((WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
android.util.DisplayMetrics realMetrics = new android.util.DisplayMetrics();
display.getRealMetrics( realMetrics );
boolean bFullscreenLayout = ((realMetrics.widthPixels == mSurface.getWidth()) &&
(realMetrics.heightPixels == mSurface.getHeight()));
if (((Integer)data).intValue() == 1) {
// If we aren't laid out fullscreen or actively in fullscreen mode already, we're going
// to change size and should wait for surfaceChanged() before we return, so the size
// is right back in native code. If we're already laid out fullscreen, though, we're
// not going to change size even if we change decor modes, so we shouldn't wait for
// surfaceChanged() -- which may not even happen -- and should return immediately.
bShouldWait = !bFullscreenLayout;
}
else {
// If we're laid out fullscreen (even if the status bar and nav bar are present),
// or are actively in fullscreen, we're going to change size and should wait for
// surfaceChanged before we return, so the size is right back in native code.
bShouldWait = bFullscreenLayout;
}
}
if (bShouldWait) {
// We'll wait for the surfaceChanged() method, which will notify us
// when called. That way, we know our current size is really the
// size we need, instead of grabbing a size that's still got
// the navigation and/or status bars before they're hidden.
//
// We'll wait for up to half a second, because some devices
// take a surprisingly long time for the surface resize, but
// then we'll just give up and return.
//
synchronized(SDLActivity.getContext()) {
try {
SDLActivity.getContext().wait(500);
}
catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
}
return result;
} }
// C functions we call // C functions we call
@ -764,9 +820,14 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
return false; return false;
} }
// Samsung DeX mode doesn't support relative mice properly under Android 7 APIs, // DeX mode in Samsung Experience 9.0 and earlier doesn't support relative mice properly under
// and simply returns no data under Android 8 APIs. // Android 7 APIs, and simply returns no data under Android 8 APIs.
if (isDeXMode()) { //
// This is fixed in Samsung Experience 9.5, which corresponds to Android 8.1.0, and
// thus SDK version 27. If we are in DeX mode and not API 27 or higher, as a result,
// we should stick to relative mode.
//
if ((Build.VERSION.SDK_INT < 27) && isDeXMode()) {
return false; return false;
} }
@ -813,6 +874,9 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
if (Build.MANUFACTURER.equals("MINIX") && Build.MODEL.equals("NEO-U1")) { if (Build.MANUFACTURER.equals("MINIX") && Build.MODEL.equals("NEO-U1")) {
return true; return true;
} }
if (Build.MANUFACTURER.equals("Amlogic") && Build.MODEL.equals("X96-W")) {
return true;
}
return false; return false;
} }
@ -821,16 +885,16 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
*/ */
public static boolean isTablet() { public static boolean isTablet() {
DisplayMetrics metrics = new DisplayMetrics(); DisplayMetrics metrics = new DisplayMetrics();
Activity sdlActivity = (Activity)getContext(); Activity activity = (Activity)getContext();
sdlActivity.getWindowManager().getDefaultDisplay().getMetrics(metrics); activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
double dWidthInches = metrics.widthPixels / (double)metrics.densityDpi; double dWidthInches = metrics.widthPixels / (double)metrics.xdpi;
double dHeightInches = metrics.heightPixels / (double)metrics.densityDpi; double dHeightInches = metrics.heightPixels / (double)metrics.ydpi;
double dDiagonal = Math.sqrt((dWidthInches * dWidthInches) + (dHeightInches * dHeightInches)); double dDiagonal = Math.sqrt((dWidthInches * dWidthInches) + (dHeightInches * dHeightInches));
// If our diagonal size is seven inches or greater, we consider ourselves a tablet. // If our diagonal size is seven inches or greater, we consider ourselves a tablet.
return (dDiagonal > 7.0); return (dDiagonal >= 7.0);
} }
/** /**
@ -1505,6 +1569,10 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
int format, int width, int height) { int format, int width, int height) {
Log.v("SDL", "surfaceChanged()"); Log.v("SDL", "surfaceChanged()");
if (SDLActivity.mSingleton == null) {
return;
}
int sdlFormat = 0x15151002; // SDL_PIXELFORMAT_RGB565 by default int sdlFormat = 0x15151002; // SDL_PIXELFORMAT_RGB565 by default
switch (format) { switch (format) {
case PixelFormat.A_8: case PixelFormat.A_8:
@ -1552,25 +1620,28 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
mWidth = width; mWidth = width;
mHeight = height; mHeight = height;
int nDeviceWidth = width; int nDeviceWidth = width;
int nDeviceHeight = height; int nDeviceHeight = height;
try try
{ {
if ( android.os.Build.VERSION.SDK_INT >= 17 ) if (Build.VERSION.SDK_INT >= 17) {
{ android.util.DisplayMetrics realMetrics = new android.util.DisplayMetrics();
android.util.DisplayMetrics realMetrics = new android.util.DisplayMetrics(); mDisplay.getRealMetrics( realMetrics );
mDisplay.getRealMetrics( realMetrics ); nDeviceWidth = realMetrics.widthPixels;
nDeviceWidth = realMetrics.widthPixels; nDeviceHeight = realMetrics.heightPixels;
nDeviceHeight = realMetrics.heightPixels; }
} }
} catch ( java.lang.Throwable throwable ) {}
catch ( java.lang.Throwable throwable ) {}
Log.v("SDL", "Window size: " + width + "x" + height); synchronized(SDLActivity.getContext()) {
Log.v("SDL", "Device size: " + nDeviceWidth + "x" + nDeviceHeight); // In case we're waiting on a size change after going fullscreen, send a notification.
SDLActivity.getContext().notifyAll();
}
Log.v("SDL", "Window size: " + width + "x" + height);
Log.v("SDL", "Device size: " + nDeviceWidth + "x" + nDeviceHeight);
SDLActivity.onNativeResize(width, height, nDeviceWidth, nDeviceHeight, sdlFormat, mDisplay.getRefreshRate()); SDLActivity.onNativeResize(width, height, nDeviceWidth, nDeviceHeight, sdlFormat, mDisplay.getRefreshRate());
boolean skip = false; boolean skip = false;
int requestedOrientation = SDLActivity.mSingleton.getRequestedOrientation(); int requestedOrientation = SDLActivity.mSingleton.getRequestedOrientation();

View File

@ -1,6 +1,7 @@
package org.libsdl.app; package org.libsdl.app;
import android.media.*; import android.media.*;
import android.os.Build;
import android.util.Log; import android.util.Log;
public class SDLAudioManager public class SDLAudioManager
@ -17,41 +18,250 @@ public class SDLAudioManager
// Audio // Audio
/** protected static String getAudioFormatString(int audioFormat) {
* This method is called by SDL using JNI. switch (audioFormat) {
*/ case AudioFormat.ENCODING_PCM_8BIT:
public static int audioOpen(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) { return "8-bit";
int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO : AudioFormat.CHANNEL_CONFIGURATION_MONO; case AudioFormat.ENCODING_PCM_16BIT:
int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT; return "16-bit";
int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1); case AudioFormat.ENCODING_PCM_FLOAT:
return "float";
default:
return Integer.toString(audioFormat);
}
}
Log.v(TAG, "SDL audio: wanted " + (isStereo ? "stereo" : "mono") + " " + (is16Bit ? "16-bit" : "8-bit") + " " + (sampleRate / 1000f) + "kHz, " + desiredFrames + " frames buffer"); protected static int[] open(boolean isCapture, int sampleRate, int audioFormat, int desiredChannels, int desiredFrames) {
int channelConfig;
int sampleSize;
int frameSize;
Log.v(TAG, "Opening " + (isCapture ? "capture" : "playback") + ", requested " + desiredFrames + " frames of " + desiredChannels + " channel " + getAudioFormatString(audioFormat) + " audio at " + sampleRate + " Hz");
/* On older devices let's use known good settings */
if (Build.VERSION.SDK_INT < 21) {
if (desiredChannels > 2) {
desiredChannels = 2;
}
if (sampleRate < 8000) {
sampleRate = 8000;
} else if (sampleRate > 48000) {
sampleRate = 48000;
}
}
if (audioFormat == AudioFormat.ENCODING_PCM_FLOAT) {
int minSDKVersion = (isCapture ? 23 : 21);
if (Build.VERSION.SDK_INT < minSDKVersion) {
audioFormat = AudioFormat.ENCODING_PCM_16BIT;
}
}
switch (audioFormat)
{
case AudioFormat.ENCODING_PCM_8BIT:
sampleSize = 1;
break;
case AudioFormat.ENCODING_PCM_16BIT:
sampleSize = 2;
break;
case AudioFormat.ENCODING_PCM_FLOAT:
sampleSize = 4;
break;
default:
Log.v(TAG, "Requested format " + audioFormat + ", getting ENCODING_PCM_16BIT");
audioFormat = AudioFormat.ENCODING_PCM_16BIT;
sampleSize = 2;
break;
}
if (isCapture) {
switch (desiredChannels) {
case 1:
channelConfig = AudioFormat.CHANNEL_IN_MONO;
break;
case 2:
channelConfig = AudioFormat.CHANNEL_IN_STEREO;
break;
default:
Log.v(TAG, "Requested " + desiredChannels + " channels, getting stereo");
desiredChannels = 2;
channelConfig = AudioFormat.CHANNEL_IN_STEREO;
break;
}
} else {
switch (desiredChannels) {
case 1:
channelConfig = AudioFormat.CHANNEL_OUT_MONO;
break;
case 2:
channelConfig = AudioFormat.CHANNEL_OUT_STEREO;
break;
case 3:
channelConfig = AudioFormat.CHANNEL_OUT_STEREO | AudioFormat.CHANNEL_OUT_FRONT_CENTER;
break;
case 4:
channelConfig = AudioFormat.CHANNEL_OUT_QUAD;
break;
case 5:
channelConfig = AudioFormat.CHANNEL_OUT_QUAD | AudioFormat.CHANNEL_OUT_FRONT_CENTER;
break;
case 6:
channelConfig = AudioFormat.CHANNEL_OUT_5POINT1;
break;
case 7:
channelConfig = AudioFormat.CHANNEL_OUT_5POINT1 | AudioFormat.CHANNEL_OUT_BACK_CENTER;
break;
case 8:
if (Build.VERSION.SDK_INT >= 23) {
channelConfig = AudioFormat.CHANNEL_OUT_7POINT1_SURROUND;
} else {
Log.v(TAG, "Requested " + desiredChannels + " channels, getting 5.1 surround");
desiredChannels = 6;
channelConfig = AudioFormat.CHANNEL_OUT_5POINT1;
}
break;
default:
Log.v(TAG, "Requested " + desiredChannels + " channels, getting stereo");
desiredChannels = 2;
channelConfig = AudioFormat.CHANNEL_OUT_STEREO;
break;
}
/*
Log.v(TAG, "Speaker configuration (and order of channels):");
if ((channelConfig & 0x00000004) != 0) {
Log.v(TAG, " CHANNEL_OUT_FRONT_LEFT");
}
if ((channelConfig & 0x00000008) != 0) {
Log.v(TAG, " CHANNEL_OUT_FRONT_RIGHT");
}
if ((channelConfig & 0x00000010) != 0) {
Log.v(TAG, " CHANNEL_OUT_FRONT_CENTER");
}
if ((channelConfig & 0x00000020) != 0) {
Log.v(TAG, " CHANNEL_OUT_LOW_FREQUENCY");
}
if ((channelConfig & 0x00000040) != 0) {
Log.v(TAG, " CHANNEL_OUT_BACK_LEFT");
}
if ((channelConfig & 0x00000080) != 0) {
Log.v(TAG, " CHANNEL_OUT_BACK_RIGHT");
}
if ((channelConfig & 0x00000100) != 0) {
Log.v(TAG, " CHANNEL_OUT_FRONT_LEFT_OF_CENTER");
}
if ((channelConfig & 0x00000200) != 0) {
Log.v(TAG, " CHANNEL_OUT_FRONT_RIGHT_OF_CENTER");
}
if ((channelConfig & 0x00000400) != 0) {
Log.v(TAG, " CHANNEL_OUT_BACK_CENTER");
}
if ((channelConfig & 0x00000800) != 0) {
Log.v(TAG, " CHANNEL_OUT_SIDE_LEFT");
}
if ((channelConfig & 0x00001000) != 0) {
Log.v(TAG, " CHANNEL_OUT_SIDE_RIGHT");
}
*/
}
frameSize = (sampleSize * desiredChannels);
// Let the user pick a larger buffer if they really want -- but ye // Let the user pick a larger buffer if they really want -- but ye
// gods they probably shouldn't, the minimums are horrifyingly high // gods they probably shouldn't, the minimums are horrifyingly high
// latency already // latency already
desiredFrames = Math.max(desiredFrames, (AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat) + frameSize - 1) / frameSize); int minBufferSize;
if (isCapture) {
minBufferSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat);
} else {
minBufferSize = AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat);
}
desiredFrames = Math.max(desiredFrames, (minBufferSize + frameSize - 1) / frameSize);
if (mAudioTrack == null) { int[] results = new int[4];
mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
channelConfig, audioFormat, desiredFrames * frameSize, AudioTrack.MODE_STREAM);
// Instantiating AudioTrack can "succeed" without an exception and the track may still be invalid if (isCapture) {
// Ref: https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/media/java/android/media/AudioTrack.java if (mAudioRecord == null) {
// Ref: http://developer.android.com/reference/android/media/AudioTrack.html#getState() mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, sampleRate,
channelConfig, audioFormat, desiredFrames * frameSize);
if (mAudioTrack.getState() != AudioTrack.STATE_INITIALIZED) { // see notes about AudioTrack state in audioOpen(), above. Probably also applies here.
Log.e(TAG, "Failed during initialization of Audio Track"); if (mAudioRecord.getState() != AudioRecord.STATE_INITIALIZED) {
mAudioTrack = null; Log.e(TAG, "Failed during initialization of AudioRecord");
return -1; mAudioRecord.release();
mAudioRecord = null;
return null;
}
mAudioRecord.startRecording();
} }
mAudioTrack.play(); results[0] = mAudioRecord.getSampleRate();
results[1] = mAudioRecord.getAudioFormat();
results[2] = mAudioRecord.getChannelCount();
results[3] = desiredFrames;
} else {
if (mAudioTrack == null) {
mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, channelConfig, audioFormat, desiredFrames * frameSize, AudioTrack.MODE_STREAM);
// Instantiating AudioTrack can "succeed" without an exception and the track may still be invalid
// Ref: https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/media/java/android/media/AudioTrack.java
// Ref: http://developer.android.com/reference/android/media/AudioTrack.html#getState()
if (mAudioTrack.getState() != AudioTrack.STATE_INITIALIZED) {
/* Try again, with safer values */
Log.e(TAG, "Failed during initialization of Audio Track");
mAudioTrack.release();
mAudioTrack = null;
return null;
}
mAudioTrack.play();
}
results[0] = mAudioTrack.getSampleRate();
results[1] = mAudioTrack.getAudioFormat();
results[2] = mAudioTrack.getChannelCount();
results[3] = desiredFrames;
} }
Log.v(TAG, "SDL audio: got " + ((mAudioTrack.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioTrack.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + (mAudioTrack.getSampleRate() / 1000f) + "kHz, " + desiredFrames + " frames buffer"); Log.v(TAG, "Opening " + (isCapture ? "capture" : "playback") + ", got " + results[3] + " frames of " + results[2] + " channel " + getAudioFormatString(results[1]) + " audio at " + results[0] + " Hz");
return 0; return results;
}
/**
* This method is called by SDL using JNI.
*/
public static int[] audioOpen(int sampleRate, int audioFormat, int desiredChannels, int desiredFrames) {
return open(false, sampleRate, audioFormat, desiredChannels, desiredFrames);
}
/**
* This method is called by SDL using JNI.
*/
public static void audioWriteFloatBuffer(float[] buffer) {
if (mAudioTrack == null) {
Log.e(TAG, "Attempted to make audio call with uninitialized audio!");
return;
}
for (int i = 0; i < buffer.length;) {
int result = mAudioTrack.write(buffer, i, buffer.length - i, AudioTrack.WRITE_BLOCKING);
if (result > 0) {
i += result;
} else if (result == 0) {
try {
Thread.sleep(1);
} catch(InterruptedException e) {
// Nom nom
}
} else {
Log.w(TAG, "SDL audio: error return from write(float)");
return;
}
}
} }
/** /**
@ -63,7 +273,7 @@ public class SDLAudioManager
return; return;
} }
for (int i = 0; i < buffer.length; ) { for (int i = 0; i < buffer.length;) {
int result = mAudioTrack.write(buffer, i, buffer.length - i); int result = mAudioTrack.write(buffer, i, buffer.length - i);
if (result > 0) { if (result > 0) {
i += result; i += result;
@ -109,53 +319,33 @@ public class SDLAudioManager
/** /**
* This method is called by SDL using JNI. * This method is called by SDL using JNI.
*/ */
public static int captureOpen(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) { public static int[] captureOpen(int sampleRate, int audioFormat, int desiredChannels, int desiredFrames) {
int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO : AudioFormat.CHANNEL_CONFIGURATION_MONO; return open(true, sampleRate, audioFormat, desiredChannels, desiredFrames);
int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT; }
int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1);
Log.v(TAG, "SDL capture: wanted " + (isStereo ? "stereo" : "mono") + " " + (is16Bit ? "16-bit" : "8-bit") + " " + (sampleRate / 1000f) + "kHz, " + desiredFrames + " frames buffer"); /** This method is called by SDL using JNI. */
public static int captureReadFloatBuffer(float[] buffer, boolean blocking) {
// Let the user pick a larger buffer if they really want -- but ye return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING);
// gods they probably shouldn't, the minimums are horrifyingly high
// latency already
desiredFrames = Math.max(desiredFrames, (AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioFormat) + frameSize - 1) / frameSize);
if (mAudioRecord == null) {
mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, sampleRate,
channelConfig, audioFormat, desiredFrames * frameSize);
// see notes about AudioTrack state in audioOpen(), above. Probably also applies here.
if (mAudioRecord.getState() != AudioRecord.STATE_INITIALIZED) {
Log.e(TAG, "Failed during initialization of AudioRecord");
mAudioRecord.release();
mAudioRecord = null;
return -1;
}
mAudioRecord.startRecording();
}
Log.v(TAG, "SDL capture: got " + ((mAudioRecord.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioRecord.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + (mAudioRecord.getSampleRate() / 1000f) + "kHz, " + desiredFrames + " frames buffer");
return 0;
} }
/** This method is called by SDL using JNI. */ /** This method is called by SDL using JNI. */
public static int captureReadShortBuffer(short[] buffer, boolean blocking) { public static int captureReadShortBuffer(short[] buffer, boolean blocking) {
// !!! FIXME: this is available in API Level 23. Until then, we always block. :( if (Build.VERSION.SDK_INT < 23) {
//return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING); return mAudioRecord.read(buffer, 0, buffer.length);
return mAudioRecord.read(buffer, 0, buffer.length); } else {
return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING);
}
} }
/** This method is called by SDL using JNI. */ /** This method is called by SDL using JNI. */
public static int captureReadByteBuffer(byte[] buffer, boolean blocking) { public static int captureReadByteBuffer(byte[] buffer, boolean blocking) {
// !!! FIXME: this is available in API Level 23. Until then, we always block. :( if (Build.VERSION.SDK_INT < 23) {
//return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING); return mAudioRecord.read(buffer, 0, buffer.length);
return mAudioRecord.read(buffer, 0, buffer.length); } else {
return mAudioRecord.read(buffer, 0, buffer.length, blocking ? AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING);
}
} }
/** This method is called by SDL using JNI. */ /** This method is called by SDL using JNI. */
public static void audioClose() { public static void audioClose() {
if (mAudioTrack != null) { if (mAudioTrack != null) {

View File

@ -11,7 +11,7 @@ import android.view.*;
import android.util.Log; import android.util.Log;
public class SDLControllerManager public class SDLControllerManager
{ {
public static native int nativeSetupJNI(); public static native int nativeSetupJNI();
@ -36,23 +36,25 @@ public class SDLControllerManager
private static final String TAG = "SDLControllerManager"; private static final String TAG = "SDLControllerManager";
public static void initialize() { public static void initialize() {
mJoystickHandler = null; if (mJoystickHandler == null) {
mHapticHandler = null; if (Build.VERSION.SDK_INT >= 19) {
mJoystickHandler = new SDLJoystickHandler_API19();
SDLControllerManager.setup(); } else if (Build.VERSION.SDK_INT >= 16) {
} mJoystickHandler = new SDLJoystickHandler_API16();
} else if (Build.VERSION.SDK_INT >= 12) {
public static void setup() { mJoystickHandler = new SDLJoystickHandler_API12();
if (Build.VERSION.SDK_INT >= 19) { } else {
mJoystickHandler = new SDLJoystickHandler_API19(); mJoystickHandler = new SDLJoystickHandler();
} else if (Build.VERSION.SDK_INT >= 16) { }
mJoystickHandler = new SDLJoystickHandler_API16(); }
} else if (Build.VERSION.SDK_INT >= 12) {
mJoystickHandler = new SDLJoystickHandler_API12(); if (mHapticHandler == null) {
} else { if (Build.VERSION.SDK_INT >= 26) {
mJoystickHandler = new SDLJoystickHandler(); mHapticHandler = new SDLHapticHandler_API26();
} else {
mHapticHandler = new SDLHapticHandler();
}
} }
mHapticHandler = new SDLHapticHandler();
} }
// Joystick glue code, just a series of stubs that redirect to the SDLJoystickHandler instance // Joystick glue code, just a series of stubs that redirect to the SDLJoystickHandler instance
@ -77,8 +79,8 @@ public class SDLControllerManager
/** /**
* This method is called by SDL using JNI. * This method is called by SDL using JNI.
*/ */
public static void hapticRun(int device_id, int length) { public static void hapticRun(int device_id, float intensity, int length) {
mHapticHandler.run(device_id, length); mHapticHandler.run(device_id, intensity, length);
} }
/** /**
@ -409,6 +411,38 @@ class SDLJoystickHandler_API19 extends SDLJoystickHandler_API16 {
} }
} }
class SDLHapticHandler_API26 extends SDLHapticHandler {
@Override
public void run(int device_id, float intensity, int length) {
SDLHaptic haptic = getHaptic(device_id);
if (haptic != null) {
Log.d("SDL", "Rtest: Vibe with intensity " + intensity + " for " + length);
if (intensity == 0.0f) {
stop(device_id);
return;
}
int vibeValue = Math.round(intensity * 255);
if (vibeValue > 255) {
vibeValue = 255;
}
if (vibeValue < 1) {
stop(device_id);
return;
}
try {
haptic.vib.vibrate(VibrationEffect.createOneShot(length, vibeValue));
}
catch (Exception e) {
// Fall back to the generic method, which uses DEFAULT_AMPLITUDE, but works even if
// something went horribly wrong with the Android 8.0 APIs.
haptic.vib.vibrate(length);
}
}
}
}
class SDLHapticHandler { class SDLHapticHandler {
class SDLHaptic { class SDLHaptic {
@ -418,15 +452,15 @@ class SDLHapticHandler {
} }
private ArrayList<SDLHaptic> mHaptics; private ArrayList<SDLHaptic> mHaptics;
public SDLHapticHandler() { public SDLHapticHandler() {
mHaptics = new ArrayList<SDLHaptic>(); mHaptics = new ArrayList<SDLHaptic>();
} }
public void run(int device_id, int length) { public void run(int device_id, float intensity, int length) {
SDLHaptic haptic = getHaptic(device_id); SDLHaptic haptic = getHaptic(device_id);
if (haptic != null) { if (haptic != null) {
haptic.vib.vibrate (length); haptic.vib.vibrate(length);
} }
} }
@ -438,7 +472,7 @@ class SDLHapticHandler {
} }
public void pollHapticDevices() { public void pollHapticDevices() {
final int deviceId_VIBRATOR_SERVICE = 999999; final int deviceId_VIBRATOR_SERVICE = 999999;
boolean hasVibratorService = false; boolean hasVibratorService = false;
@ -482,7 +516,7 @@ class SDLHapticHandler {
haptic = new SDLHaptic(); haptic = new SDLHaptic();
haptic.device_id = deviceId_VIBRATOR_SERVICE; haptic.device_id = deviceId_VIBRATOR_SERVICE;
haptic.name = "VIBRATOR_SERVICE"; haptic.name = "VIBRATOR_SERVICE";
haptic.vib = vib; haptic.vib = vib;
mHaptics.add(haptic); mHaptics.add(haptic);
SDLControllerManager.nativeAddHaptic(haptic.device_id, haptic.name); SDLControllerManager.nativeAddHaptic(haptic.device_id, haptic.name);
} }
@ -524,7 +558,7 @@ class SDLHapticHandler {
} }
} }
return null; return null;
} }
} }
class SDLGenericMotionListener_API12 implements View.OnGenericMotionListener { class SDLGenericMotionListener_API12 implements View.OnGenericMotionListener {
@ -614,7 +648,7 @@ class SDLGenericMotionListener_API24 extends SDLGenericMotionListener_API12 {
case InputDevice.SOURCE_GAMEPAD: case InputDevice.SOURCE_GAMEPAD:
case InputDevice.SOURCE_DPAD: case InputDevice.SOURCE_DPAD:
return SDLControllerManager.handleJoystickMotionEvent(event); return SDLControllerManager.handleJoystickMotionEvent(event);
case InputDevice.SOURCE_MOUSE: case InputDevice.SOURCE_MOUSE:
if (!SDLActivity.mSeparateMouseAndTouch) { if (!SDLActivity.mSeparateMouseAndTouch) {
break; break;
@ -705,7 +739,7 @@ class SDLGenericMotionListener_API26 extends SDLGenericMotionListener_API24 {
case InputDevice.SOURCE_GAMEPAD: case InputDevice.SOURCE_GAMEPAD:
case InputDevice.SOURCE_DPAD: case InputDevice.SOURCE_DPAD:
return SDLControllerManager.handleJoystickMotionEvent(event); return SDLControllerManager.handleJoystickMotionEvent(event);
case InputDevice.SOURCE_MOUSE: case InputDevice.SOURCE_MOUSE:
case 12290: // DeX desktop mouse cursor is a separate non-standard input type. case 12290: // DeX desktop mouse cursor is a separate non-standard input type.
if (!SDLActivity.mSeparateMouseAndTouch) { if (!SDLActivity.mSeparateMouseAndTouch) {
@ -764,7 +798,7 @@ class SDLGenericMotionListener_API26 extends SDLGenericMotionListener_API24 {
@Override @Override
public boolean supportsRelativeMouse() { public boolean supportsRelativeMouse() {
return !SDLActivity.isDeXMode(); return (!SDLActivity.isDeXMode() || (Build.VERSION.SDK_INT >= 27));
} }
@Override @Override
@ -774,17 +808,17 @@ class SDLGenericMotionListener_API26 extends SDLGenericMotionListener_API24 {
@Override @Override
public boolean setRelativeMouseEnabled(boolean enabled) { public boolean setRelativeMouseEnabled(boolean enabled) {
if (!SDLActivity.isDeXMode()) { if (!SDLActivity.isDeXMode() || (Build.VERSION.SDK_INT >= 27)) {
if (enabled) { if (enabled) {
SDLActivity.getContentView().requestPointerCapture(); SDLActivity.getContentView().requestPointerCapture();
} }
else { else {
SDLActivity.getContentView().releasePointerCapture(); SDLActivity.getContentView().releasePointerCapture();
} }
mRelativeModeEnabled = enabled; mRelativeModeEnabled = enabled;
return true; return true;
} }
else else
{ {
return false; return false;
} }

View File

@ -3,9 +3,10 @@
buildscript { buildscript {
repositories { repositories {
jcenter() jcenter()
google()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:2.3.3' classpath 'com.android.tools.build:gradle:3.2.0'
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files
@ -15,6 +16,7 @@ buildscript {
allprojects { allprojects {
repositories { repositories {
jcenter() jcenter()
google()
} }
} }

View File

@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip

View File

@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
# install - install a program, script, or datafile # install - install a program, script, or datafile
scriptversion=2005-02-02.21 scriptversion=2011-11-20.07; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was # This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the # later released in X11R6 (xc/config/util/install.sh) with the
@ -35,42 +35,72 @@ scriptversion=2005-02-02.21
# FSF changes to this file are in the public domain. # FSF changes to this file are in the public domain.
# #
# Calling this script install-sh is preferred over install.sh, to prevent # Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it # 'make' implicit rules from creating a file called install from it
# when there is no Makefile. # when there is no Makefile.
# #
# This script is compatible with the BSD install script, but was written # This script is compatible with the BSD install script, but was written
# from scratch. It can only install one file at a time, a restriction # from scratch.
# shared with many OS's install programs.
nl='
'
IFS=" "" $nl"
# set DOITPROG to echo to test this script # set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it. # Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}" doit=${DOITPROG-}
if test -z "$doit"; then
doit_exec=exec
else
doit_exec=$doit
fi
# put in absolute paths if you don't have them in your path; or use env. vars. # Put in absolute file names if you don't have them in your path;
# or use environment vars.
mvprog="${MVPROG-mv}" chgrpprog=${CHGRPPROG-chgrp}
cpprog="${CPPROG-cp}" chmodprog=${CHMODPROG-chmod}
chmodprog="${CHMODPROG-chmod}" chownprog=${CHOWNPROG-chown}
chownprog="${CHOWNPROG-chown}" cmpprog=${CMPPROG-cmp}
chgrpprog="${CHGRPPROG-chgrp}" cpprog=${CPPROG-cp}
stripprog="${STRIPPROG-strip}" mkdirprog=${MKDIRPROG-mkdir}
rmprog="${RMPROG-rm}" mvprog=${MVPROG-mv}
mkdirprog="${MKDIRPROG-mkdir}" rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
posix_glob='?'
initialize_posix_glob='
test "$posix_glob" != "?" || {
if (set -f) 2>/dev/null; then
posix_glob=
else
posix_glob=:
fi
}
'
posix_mkdir=
# Desired mode of installed file.
mode=0755
chmodcmd="$chmodprog 0755"
chowncmd=
chgrpcmd= chgrpcmd=
stripcmd= chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f" rmcmd="$rmprog -f"
mvcmd="$mvprog" stripcmd=
src= src=
dst= dst=
dir_arg= dir_arg=
dstarg= dst_arg=
copy_on_change=false
no_target_directory= no_target_directory=
usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES... or: $0 [OPTION]... -d DIRECTORIES...
@ -80,108 +110,148 @@ In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES. In the 4th, create DIRECTORIES.
Options: Options:
-c (ignored) --help display this help and exit.
-d create directories instead of installing files. --version display version info and exit.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE. -c (ignored)
-o USER $chownprog installed files to USER. -C install only if different (preserve the last data modification time)
-s $stripprog installed files. -d create directories instead of installing files.
-t DIRECTORY install into DIRECTORY. -g GROUP $chgrpprog installed files to GROUP.
-T report an error if DSTFILE is a directory. -m MODE $chmodprog installed files to MODE.
--help display this help and exit. -o USER $chownprog installed files to USER.
--version display version info and exit. -s $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands: Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
" "
while test -n "$1"; do while test $# -ne 0; do
case $1 in case $1 in
-c) shift -c) ;;
continue;;
-d) dir_arg=true -C) copy_on_change=true;;
shift
continue;; -d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2" -g) chgrpcmd="$chgrpprog $2"
shift shift;;
shift
continue;;
--help) echo "$usage"; exit $?;; --help) echo "$usage"; exit $?;;
-m) chmodcmd="$chmodprog $2" -m) mode=$2
shift case $mode in
shift *' '* | *' '* | *'
continue;; '* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
shift;;
-o) chowncmd="$chownprog $2" -o) chowncmd="$chownprog $2"
shift shift;;
shift
continue;;
-s) stripcmd=$stripprog -s) stripcmd=$stripprog;;
shift
continue;;
-t) dstarg=$2 -t) dst_arg=$2
shift # Protect names problematic for 'test' and other utilities.
shift case $dst_arg in
continue;; -* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
shift;;
-T) no_target_directory=true -T) no_target_directory=true;;
shift
continue;;
--version) echo "$0 $scriptversion"; exit $?;; --version) echo "$0 $scriptversion"; exit $?;;
*) # When -d is used, all remaining arguments are directories to create. --) shift
# When -t is used, the destination is already specified.
test -n "$dir_arg$dstarg" && break
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dstarg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dstarg"
shift # fnord
fi
shift # arg
dstarg=$arg
done
break;; break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac esac
shift
done done
if test -z "$1"; then if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dst_arg"
shift # fnord
fi
shift # arg
dst_arg=$arg
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2 echo "$0: no input file specified." >&2
exit 1 exit 1
fi fi
# It's OK to call `install-sh -d' without argument. # It's OK to call 'install-sh -d' without argument.
# This can happen when creating conditional directories. # This can happen when creating conditional directories.
exit 0 exit 0
fi fi
if test -z "$dir_arg"; then
do_exit='(exit $ret); exit $ret'
trap "ret=129; $do_exit" 1
trap "ret=130; $do_exit" 2
trap "ret=141; $do_exit" 13
trap "ret=143; $do_exit" 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src for src
do do
# Protect names starting with `-'. # Protect names problematic for 'test' and other utilities.
case $src in case $src in
-*) src=./$src ;; -* | [=\(\)!]) src=./$src;;
esac esac
if test -n "$dir_arg"; then if test -n "$dir_arg"; then
dst=$src dst=$src
src= dstdir=$dst
test -d "$dstdir"
if test -d "$dst"; then dstdir_status=$?
mkdircmd=:
chmodcmd=
else
mkdircmd=$mkdirprog
fi
else else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad # might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'. # if $src (and thus $dsttmp) contains '*'.
@ -190,71 +260,194 @@ do
exit 1 exit 1
fi fi
if test -z "$dstarg"; then if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2 echo "$0: no destination specified." >&2
exit 1 exit 1
fi fi
dst=$dst_arg
dst=$dstarg
# Protect names starting with `-'.
case $dst in
-*) dst=./$dst ;;
esac
# If destination is a directory, append the input filename; won't work # If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored. # if double slashes aren't ignored.
if test -d "$dst"; then if test -d "$dst"; then
if test -n "$no_target_directory"; then if test -n "$no_target_directory"; then
echo "$0: $dstarg: Is a directory" >&2 echo "$0: $dst_arg: Is a directory" >&2
exit 1 exit 1
fi fi
dst=$dst/`basename "$src"` dstdir=$dst
dst=$dstdir/`basename "$src"`
dstdir_status=0
else
# Prefer dirname, but fall back on a substitute if dirname fails.
dstdir=`
(dirname "$dst") 2>/dev/null ||
expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$dst" : 'X\(//\)[^/]' \| \
X"$dst" : 'X\(//\)$' \| \
X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
echo X"$dst" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
s//\1/
q
}
s/.*/./; q'
`
test -d "$dstdir"
dstdir_status=$?
fi fi
fi fi
# This sed command emulates the dirname command. obsolete_mkdir_used=false
dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
# Make sure that the destination directory exists. if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# Create intermediate dirs using mode 755 as modified by the umask.
# This is like FreeBSD 'install' as of 1997-10-28.
umask=`umask`
case $stripcmd.$umask in
# Optimize common cases.
*[2367][2367]) mkdir_umask=$umask;;
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
# Skip lots of stat calls in the usual case. *[0-7])
if test ! -d "$dstdir"; then mkdir_umask=`expr $umask + 22 \
defaultIFS=' - $umask % 100 % 40 + $umask % 20 \
' - $umask % 10 % 4 + $umask % 2
IFS="${IFS-$defaultIFS}" `;;
*) mkdir_umask=$umask,go-w;;
esac
oIFS=$IFS # With -d, create the new directory with the user-specified mode.
# Some sh's can't handle IFS=/ for some reason. # Otherwise, rely on $mkdir_umask.
IFS='%' if test -n "$dir_arg"; then
set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` mkdir_mode=-m$mode
shift else
IFS=$oIFS mkdir_mode=
fi
pathcomp= posix_mkdir=false
case $umask in
*[123567][0-7][0-7])
# POSIX mkdir -p sets u+wx bits regardless of umask, which
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
while test $# -ne 0 ; do if (umask $mkdir_umask &&
pathcomp=$pathcomp$1 exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
ls_ld_tmpdir=`ls -ld "$tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/d" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
fi
trap '' 0;;
esac;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# The umask is ridiculous, or mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix='/';;
[-=\(\)!]*) prefix='./';;
*) prefix='';;
esac
eval "$initialize_posix_glob"
oIFS=$IFS
IFS=/
$posix_glob set -f
set fnord $dstdir
shift shift
if test ! -d "$pathcomp"; then $posix_glob set +f
$mkdirprog "$pathcomp" IFS=$oIFS
# mkdir can fail with a `File exist' error in case several
# install-sh are creating the directory concurrently. This prefixes=
# is OK.
test -d "$pathcomp" || exit for d
do
test X"$d" = X && continue
prefix=$prefix$d
if test -d "$prefix"; then
prefixes=
else
if $posix_mkdir; then
(umask=$mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi
fi
prefix=$prefix/
done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi fi
pathcomp=$pathcomp/ fi
done
fi fi
if test -n "$dir_arg"; then if test -n "$dir_arg"; then
$doit $mkdircmd "$dst" \ { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
&& { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
&& { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
else else
dstfile=`basename "$dst"`
# Make a couple of temp file names in the proper directory. # Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_ dsttmp=$dstdir/_inst.$$_
@ -262,10 +455,9 @@ do
# Trap to clean up those temp files at exit. # Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
trap '(exit $?); exit' 1 2 13 15
# Copy the file name to the temp name. # Copy the file name to the temp name.
$doit $cpprog "$src" "$dsttmp" && (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits. # and set any options; do chmod last to preserve setuid bits.
# #
@ -273,51 +465,63 @@ do
# ignore errors from any of these, just make sure not to ignore # ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command. # errors from the above "$doit $cpprog $src $dsttmp" command.
# #
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
&& { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# Now rename the file to the real destination. # If -C, don't bother to copy if it wouldn't change the file.
{ $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ if $copy_on_change &&
|| { old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
# The rename failed, perhaps because mv can't rename something else new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
# Now remove or move aside any old file at destination location. eval "$initialize_posix_glob" &&
# We try this two ways since rm can't unlink itself on some $posix_glob set -f &&
# systems and the destination file might be busy for other set X $old && old=:$2:$4:$5:$6 &&
# reasons. In this case, the final cleanup might fail but the new set X $new && new=:$2:$4:$5:$6 &&
# file should still install successfully. $posix_glob set +f &&
{
if test -f "$dstdir/$dstfile"; then
$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
|| $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
|| {
echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
(exit 1); exit 1
}
else
:
fi
} &&
# Now rename the file to the real destination. test "$old" = "$new" &&
$doit $mvcmd "$dsttmp" "$dstdir/$dstfile" $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
} then
} rm -f "$dsttmp"
fi || { (exit 1); exit 1; } else
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
{
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
test ! -f "$dst" ||
$doit $rmcmd -f "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
} ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
}
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dst"
}
fi || exit 1
trap '' 0
fi
done done
# The final little trick to "correctly" pass the exit status to the exit trap.
{
(exit 0); exit 0
}
# Local variables: # Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp) # eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion=" # time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$" # time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End: # End:

View File

@ -1,29 +1,59 @@
#! /bin/sh #! /bin/sh
# mkinstalldirs --- make directory hierarchy # mkinstalldirs --- make directory hierarchy
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
# Public domain
scriptversion=2009-04-28.21; # UTC
# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
# Public domain.
#
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
nl='
'
IFS=" "" $nl"
errstatus=0 errstatus=0
dirmode="" dirmode=
usage="\ usage="\
Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..." Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ...
Create each directory DIR (with mode MODE, if specified), including all
leading file name components.
Report bugs to <bug-automake@gnu.org>."
# process command line arguments # process command line arguments
while test $# -gt 0 ; do while test $# -gt 0 ; do
case "${1}" in case $1 in
-h | --help | --h* ) # -h for help -h | --help | --h*) # -h for help
echo "${usage}" 1>&2; exit 0 ;; echo "$usage"
-m ) # -m PERM arg exit $?
shift ;;
test $# -eq 0 && { echo "${usage}" 1>&2; exit 1; } -m) # -m PERM arg
dirmode="${1}" shift
shift ;; test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
-- ) shift; break ;; # stop option processing dirmode=$1
-* ) echo "${usage}" 1>&2; exit 1 ;; # unknown option shift
* ) break ;; # first non-opt arg ;;
esac --version)
echo "$0 $scriptversion"
exit $?
;;
--) # stop option processing
shift
break
;;
-*) # unknown option
echo "$usage" 1>&2
exit 1
;;
*) # first non-opt arg
break
;;
esac
done done
for file for file
@ -36,64 +66,97 @@ do
done done
case $# in case $# in
0) exit 0 ;; 0) exit 0 ;;
esac esac
# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and
# mkdir -p a/c at the same time, both will detect that a is missing,
# one will create a, then the other will try to create a and die with
# a "File exists" error. This is a problem when calling mkinstalldirs
# from a parallel make. We use --version in the probe to restrict
# ourselves to GNU mkdir, which is thread-safe.
case $dirmode in case $dirmode in
'') '')
if mkdir -p -- . 2>/dev/null; then if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
echo "mkdir -p -- $*" echo "mkdir -p -- $*"
exec mkdir -p -- "$@" exec mkdir -p -- "$@"
fi ;; else
*) # On NextStep and OpenStep, the 'mkdir' command does not
if mkdir -m "$dirmode" -p -- . 2>/dev/null; then # recognize any option. It will interpret all options as
echo "mkdir -m $dirmode -p -- $*" # directories to create, and then abort because '.' already
exec mkdir -m "$dirmode" -p -- "$@" # exists.
fi ;; test -d ./-p && rmdir ./-p
test -d ./--version && rmdir ./--version
fi
;;
*)
if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 &&
test ! -d ./--version; then
echo "mkdir -m $dirmode -p -- $*"
exec mkdir -m "$dirmode" -p -- "$@"
else
# Clean up after NextStep and OpenStep mkdir.
for d in ./-m ./-p ./--version "./$dirmode";
do
test -d $d && rmdir $d
done
fi
;;
esac esac
for file for file
do do
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` case $file in
shift /*) pathcomp=/ ;;
*) pathcomp= ;;
esac
oIFS=$IFS
IFS=/
set fnord $file
shift
IFS=$oIFS
pathcomp= for d
for d do
do test "x$d" = x && continue
pathcomp="$pathcomp$d"
case "$pathcomp" in
-* ) pathcomp=./$pathcomp ;;
esac
if test ! -d "$pathcomp"; then pathcomp=$pathcomp$d
echo "mkdir $pathcomp" case $pathcomp in
-*) pathcomp=./$pathcomp ;;
esac
mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp"
if test ! -d "$pathcomp"; then mkdir "$pathcomp" || lasterr=$?
errstatus=$lasterr
else
if test ! -z "$dirmode"; then
echo "chmod $dirmode $pathcomp"
lasterr="" if test ! -d "$pathcomp"; then
chmod "$dirmode" "$pathcomp" || lasterr=$? errstatus=$lasterr
else
if test ! -z "$dirmode"; then
echo "chmod $dirmode $pathcomp"
lasterr=
chmod "$dirmode" "$pathcomp" || lasterr=$?
if test ! -z "$lasterr"; then if test ! -z "$lasterr"; then
errstatus=$lasterr errstatus=$lasterr
fi
fi fi
fi fi
fi fi
fi
pathcomp="$pathcomp/" pathcomp=$pathcomp/
done done
done done
exit $errstatus exit $errstatus
# Local Variables: # Local Variables:
# mode: shell-script # mode: shell-script
# sh-indentation: 3 # sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End: # End:
# mkinstalldirs ends here

View File

@ -39,7 +39,7 @@
# #
# Base version of SDL, used for packaging purposes # Base version of SDL, used for packaging purposes
$SDLVersion = "2.0.7" $SDLVersion = "2.0.9"
# Gets the .bat file that sets up an MSBuild environment, given one of # Gets the .bat file that sets up an MSBuild environment, given one of
# Visual Studio's, "PlatformToolset"s. # Visual Studio's, "PlatformToolset"s.

79
configure vendored
View File

@ -2719,9 +2719,9 @@ orig_CFLAGS="$CFLAGS"
# #
SDL_MAJOR_VERSION=2 SDL_MAJOR_VERSION=2
SDL_MINOR_VERSION=0 SDL_MINOR_VERSION=0
SDL_MICRO_VERSION=8 SDL_MICRO_VERSION=9
SDL_INTERFACE_AGE=0 SDL_INTERFACE_AGE=0
SDL_BINARY_AGE=8 SDL_BINARY_AGE=9
SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION
@ -23165,20 +23165,6 @@ if test "x$ac_cv_header_xinput_h" = xyes; then :
fi fi
ac_fn_c_check_header_mongrel "$LINENO" "mmdeviceapi.h" "ac_cv_header_mmdeviceapi_h" "$ac_includes_default"
if test "x$ac_cv_header_mmdeviceapi_h" = xyes; then :
have_wasapi=yes
fi
ac_fn_c_check_header_mongrel "$LINENO" "audioclient.h" "ac_cv_header_audioclient_h" "$ac_includes_default"
if test "x$ac_cv_header_audioclient_h" = xyes; then :
else
have_wasapi=no
fi
cat confdefs.h - <<_ACEOF >conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */ /* end confdefs.h. */
@ -23257,14 +23243,6 @@ $as_echo "#define HAVE_XINPUT_STATE_EX 1" >>confdefs.h
SUMMARY_video="${SUMMARY_video} directx" SUMMARY_video="${SUMMARY_video} directx"
SUMMARY_audio="${SUMMARY_audio} directx" SUMMARY_audio="${SUMMARY_audio} directx"
# Check whether --enable-wasapi was given.
if test "${enable_wasapi+set}" = set; then :
enableval=$enable_wasapi;
else
enable_wasapi=yes
fi
# FIXME: latest Cygwin finds dinput headers, but we die on other win32 headers. # FIXME: latest Cygwin finds dinput headers, but we die on other win32 headers.
# FIXME: ...so force it off for now. # FIXME: ...so force it off for now.
case "$host" in case "$host" in
@ -23273,6 +23251,45 @@ fi
;; ;;
esac esac
fi fi
ac_fn_c_check_header_mongrel "$LINENO" "mmdeviceapi.h" "ac_cv_header_mmdeviceapi_h" "$ac_includes_default"
if test "x$ac_cv_header_mmdeviceapi_h" = xyes; then :
have_wasapi=yes
fi
if test x$have_wasapi = xyes; then
$as_echo "#define HAVE_MMDEVICEAPI_H 1" >>confdefs.h
fi
ac_fn_c_check_header_mongrel "$LINENO" "audioclient.h" "ac_cv_header_audioclient_h" "$ac_includes_default"
if test "x$ac_cv_header_audioclient_h" = xyes; then :
else
have_wasapi=no
fi
if test x$have_wasapi = xyes; then
$as_echo "#define HAVE_AUDIOCLIENT_H 1" >>confdefs.h
fi
ac_fn_c_check_header_mongrel "$LINENO" "endpointvolume.h" "ac_cv_header_endpointvolume_h" "$ac_includes_default"
if test "x$ac_cv_header_endpointvolume_h" = xyes; then :
$as_echo "#define HAVE_ENDPOINTVOLUME_H 1" >>confdefs.h
fi
# Check whether --enable-wasapi was given.
if test "${enable_wasapi+set}" = set; then :
enableval=$enable_wasapi;
else
enable_wasapi=yes
fi
} }
CheckDLOPEN() CheckDLOPEN()
@ -24296,7 +24313,13 @@ $as_echo "#define SDL_JOYSTICK_DINPUT 1" >>confdefs.h
$as_echo "#define SDL_JOYSTICK_WINMM 1" >>confdefs.h $as_echo "#define SDL_JOYSTICK_WINMM 1" >>confdefs.h
fi fi
$as_echo "#define SDL_JOYSTICK_HIDAPI 1" >>confdefs.h
SOURCES="$SOURCES $srcdir/src/joystick/windows/*.c" SOURCES="$SOURCES $srcdir/src/joystick/windows/*.c"
SOURCES="$SOURCES $srcdir/src/joystick/hidapi/*.c"
SOURCES="$SOURCES $srcdir/src/hidapi/windows/hid.c"
EXTRA_CFLAGS="$EXTRA_CFLAGS -I$srcdir/src/hidapi/hidapi"
have_joystick=yes have_joystick=yes
fi fi
if test x$enable_haptic = xyes; then if test x$enable_haptic = xyes; then
@ -24360,7 +24383,7 @@ $as_echo "#define SDL_LOADSO_WINDOWS 1" >>confdefs.h
else else
LIBUUID=-luuid LIBUUID=-luuid
fi fi
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion $LIBUUID -static-libgcc" EXTRA_LDFLAGS="$EXTRA_LDFLAGS -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lsetupapi -lversion $LIBUUID -static-libgcc"
# The Windows platform requires special setup # The Windows platform requires special setup
VERSION_SOURCES="$srcdir/src/main/windows/*.rc" VERSION_SOURCES="$srcdir/src/main/windows/*.rc"
SDLMAIN_SOURCES="$srcdir/src/main/windows/*.c" SDLMAIN_SOURCES="$srcdir/src/main/windows/*.c"
@ -24796,7 +24819,7 @@ esac
if test x$have_joystick != xyes; then if test x$have_joystick != xyes; then
if test x$enable_joystick = xyes; then if test x$enable_joystick = xyes; then
$as_echo "#define SDL_JOYSTICK_DISABLED 1" >>confdefs.h $as_echo "#define SDL_JOYSTICK_DUMMY 1" >>confdefs.h
fi fi
SOURCES="$SOURCES $srcdir/src/joystick/dummy/*.c" SOURCES="$SOURCES $srcdir/src/joystick/dummy/*.c"
@ -24804,7 +24827,7 @@ fi
if test x$have_haptic != xyes; then if test x$have_haptic != xyes; then
if test x$enable_haptic = xyes; then if test x$enable_haptic = xyes; then
$as_echo "#define SDL_HAPTIC_DISABLED 1" >>confdefs.h $as_echo "#define SDL_HAPTIC_DUMMY 1" >>confdefs.h
fi fi
SOURCES="$SOURCES $srcdir/src/haptic/dummy/*.c" SOURCES="$SOURCES $srcdir/src/haptic/dummy/*.c"
@ -24812,7 +24835,7 @@ fi
if test x$have_sensor != xyes; then if test x$have_sensor != xyes; then
if test x$enable_sensor = xyes; then if test x$enable_sensor = xyes; then
$as_echo "#define SDL_SENSOR_DISABLED 1" >>confdefs.h $as_echo "#define SDL_SENSOR_DUMMY 1" >>confdefs.h
fi fi
SOURCES="$SOURCES $srcdir/src/sensor/dummy/*.c" SOURCES="$SOURCES $srcdir/src/sensor/dummy/*.c"

View File

@ -20,9 +20,9 @@ dnl Set various version strings - taken gratefully from the GTk sources
# #
SDL_MAJOR_VERSION=2 SDL_MAJOR_VERSION=2
SDL_MINOR_VERSION=0 SDL_MINOR_VERSION=0
SDL_MICRO_VERSION=8 SDL_MICRO_VERSION=9
SDL_INTERFACE_AGE=0 SDL_INTERFACE_AGE=0
SDL_BINARY_AGE=8 SDL_BINARY_AGE=9
SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION
AC_SUBST(SDL_MAJOR_VERSION) AC_SUBST(SDL_MAJOR_VERSION)
@ -3052,8 +3052,6 @@ AC_HELP_STRING([--enable-directx], [use DirectX for Windows audio/video [[defaul
AC_CHECK_HEADER(dinput.h, have_dinput=yes) AC_CHECK_HEADER(dinput.h, have_dinput=yes)
AC_CHECK_HEADER(dxgi.h, have_dxgi=yes) AC_CHECK_HEADER(dxgi.h, have_dxgi=yes)
AC_CHECK_HEADER(xinput.h, have_xinput=yes) AC_CHECK_HEADER(xinput.h, have_xinput=yes)
AC_CHECK_HEADER(mmdeviceapi.h, have_wasapi=yes)
AC_CHECK_HEADER(audioclient.h,,have_wasapi=no)
AC_TRY_COMPILE([ AC_TRY_COMPILE([
#include <windows.h> #include <windows.h>
#include <xinput.h> #include <xinput.h>
@ -3090,10 +3088,6 @@ XINPUT_STATE_EX s1;
SUMMARY_video="${SUMMARY_video} directx" SUMMARY_video="${SUMMARY_video} directx"
SUMMARY_audio="${SUMMARY_audio} directx" SUMMARY_audio="${SUMMARY_audio} directx"
AC_ARG_ENABLE(wasapi,
AC_HELP_STRING([--enable-wasapi], [use the Windows WASAPI audio driver [[default=yes]]]),
, enable_wasapi=yes)
# FIXME: latest Cygwin finds dinput headers, but we die on other win32 headers. # FIXME: latest Cygwin finds dinput headers, but we die on other win32 headers.
# FIXME: ...so force it off for now. # FIXME: ...so force it off for now.
case "$host" in case "$host" in
@ -3102,6 +3096,21 @@ AC_HELP_STRING([--enable-wasapi], [use the Windows WASAPI audio driver [[default
;; ;;
esac esac
fi fi
AC_CHECK_HEADER(mmdeviceapi.h, have_wasapi=yes)
if test x$have_wasapi = xyes; then
AC_DEFINE(HAVE_MMDEVICEAPI_H,1,[])
fi
AC_CHECK_HEADER(audioclient.h,,have_wasapi=no)
if test x$have_wasapi = xyes; then
AC_DEFINE(HAVE_AUDIOCLIENT_H,1,[])
fi
AC_CHECK_HEADER(endpointvolume.h,AC_DEFINE(HAVE_ENDPOINTVOLUME_H,1,[]))
AC_ARG_ENABLE(wasapi,
AC_HELP_STRING([--enable-wasapi], [use the Windows WASAPI audio driver [[default=yes]]]),
, enable_wasapi=yes)
} }
dnl Check for the dlfcn.h interface for dynamically loading objects dnl Check for the dlfcn.h interface for dynamically loading objects
@ -3628,7 +3637,11 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau
else else
AC_DEFINE(SDL_JOYSTICK_WINMM, 1, [ ]) AC_DEFINE(SDL_JOYSTICK_WINMM, 1, [ ])
fi fi
AC_DEFINE(SDL_JOYSTICK_HIDAPI, 1, [ ])
SOURCES="$SOURCES $srcdir/src/joystick/windows/*.c" SOURCES="$SOURCES $srcdir/src/joystick/windows/*.c"
SOURCES="$SOURCES $srcdir/src/joystick/hidapi/*.c"
SOURCES="$SOURCES $srcdir/src/hidapi/windows/hid.c"
EXTRA_CFLAGS="$EXTRA_CFLAGS -I$srcdir/src/hidapi/hidapi"
have_joystick=yes have_joystick=yes
fi fi
if test x$enable_haptic = xyes; then if test x$enable_haptic = xyes; then
@ -3678,7 +3691,7 @@ AC_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau
else else
LIBUUID=-luuid LIBUUID=-luuid
fi fi
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion $LIBUUID -static-libgcc" EXTRA_LDFLAGS="$EXTRA_LDFLAGS -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lsetupapi -lversion $LIBUUID -static-libgcc"
# The Windows platform requires special setup # The Windows platform requires special setup
VERSION_SOURCES="$srcdir/src/main/windows/*.rc" VERSION_SOURCES="$srcdir/src/main/windows/*.rc"
SDLMAIN_SOURCES="$srcdir/src/main/windows/*.c" SDLMAIN_SOURCES="$srcdir/src/main/windows/*.c"
@ -3999,19 +4012,19 @@ esac
if test x$have_joystick != xyes; then if test x$have_joystick != xyes; then
if test x$enable_joystick = xyes; then if test x$enable_joystick = xyes; then
AC_DEFINE(SDL_JOYSTICK_DISABLED, 1, [ ]) AC_DEFINE(SDL_JOYSTICK_DUMMY, 1, [ ])
fi fi
SOURCES="$SOURCES $srcdir/src/joystick/dummy/*.c" SOURCES="$SOURCES $srcdir/src/joystick/dummy/*.c"
fi fi
if test x$have_haptic != xyes; then if test x$have_haptic != xyes; then
if test x$enable_haptic = xyes; then if test x$enable_haptic = xyes; then
AC_DEFINE(SDL_HAPTIC_DISABLED, 1, [ ]) AC_DEFINE(SDL_HAPTIC_DUMMY, 1, [ ])
fi fi
SOURCES="$SOURCES $srcdir/src/haptic/dummy/*.c" SOURCES="$SOURCES $srcdir/src/haptic/dummy/*.c"
fi fi
if test x$have_sensor != xyes; then if test x$have_sensor != xyes; then
if test x$enable_sensor = xyes; then if test x$enable_sensor = xyes; then
AC_DEFINE(SDL_SENSOR_DISABLED, 1, [ ]) AC_DEFINE(SDL_SENSOR_DUMMY, 1, [ ])
fi fi
SOURCES="$SOURCES $srcdir/src/sensor/dummy/*.c" SOURCES="$SOURCES $srcdir/src/sensor/dummy/*.c"
fi fi

6
debian/changelog vendored
View File

@ -1,3 +1,9 @@
libsdl2 (2.0.9) UNRELEASED; urgency=low
* Updated SDL to version 2.0.9
-- Sam Lantinga <slouken@libsdl.org> Wed, 26 Sep 2018 10:02:21 -0800
libsdl2 (2.0.8) UNRELEASED; urgency=low libsdl2 (2.0.8) UNRELEASED; urgency=low
* Updated SDL to version 2.0.8 * Updated SDL to version 2.0.8

View File

@ -77,18 +77,16 @@ For more complex projects, follow these instructions:
and rename it to the name of your project. and rename it to the name of your project.
2. Move or symlink this SDL directory into the "<project>/app/jni" directory 2. Move or symlink this SDL directory into the "<project>/app/jni" directory
3. Edit "<project>/app/jni/src/Android.mk" to include your source files 3. Edit "<project>/app/jni/src/Android.mk" to include your source files
4. Run 'ndk-build' (a script provided by the NDK). This compiles the C source
If you want to use Android Studio (recommended), skip to the Android Studio section below. 4a. If you want to use Android Studio, simply open your <project> directory and start building.
5. Run './gradlew installDebug' in the project directory. This compiles the .java, creates an .apk with the native code embedded, and installs it on any connected Android device 4b. If you want to build manually, run './gradlew installDebug' in the project directory. This compiles the .java, creates an .apk with the native code embedded, and installs it on any connected Android device
Here's an explanation of the files in the Android project, so you can customize them: Here's an explanation of the files in the Android project, so you can customize them:
android-project/app android-project/app
build.gradle - build info including the application version and SDK build.gradle - build info including the application version and SDK
src/main/AndroidManifest.xml - package manifest. Among others, it contains the class name src/main/AndroidManifest.xml - package manifest. Among others, it contains the class name of the main Activity and the package name of the application.
of the main Activity and the package name of the application.
jni/ - directory holding native code jni/ - directory holding native code
jni/Application.mk - Application JNI settings, including target platform and STL library jni/Application.mk - Application JNI settings, including target platform and STL library
jni/Android.mk - Android makefile that can call recursively the Android.mk files in all subdirectories jni/Android.mk - Android makefile that can call recursively the Android.mk files in all subdirectories
@ -216,26 +214,10 @@ detach it.
You can use STL in your project by creating an Application.mk file in the jni You can use STL in your project by creating an Application.mk file in the jni
folder and adding the following line: folder and adding the following line:
APP_STL := stlport_static APP_STL := c++_shared
For more information check out CPLUSPLUS-SUPPORT.html in the NDK documentation. For more information go here:
https://developer.android.com/ndk/guides/cpp-support
================================================================================
Additional documentation
================================================================================
The documentation in the NDK docs directory is very helpful in understanding the
build process and how to work with native code on the Android platform.
The best place to start is with docs/OVERVIEW.TXT
================================================================================
Using Android Studio
================================================================================
You can open your project directory with Android Studio and run it normally.
================================================================================ ================================================================================
@ -291,7 +273,10 @@ You can see the complete command line that ndk-build is using by passing V=1 on
ndk-build V=1 ndk-build V=1
If your application crashes in native code, you can use addr2line to convert the If your application crashes in native code, you can use ndk-stack to get a symbolic stack trace:
https://developer.android.com/ndk/guides/ndk-stack
If you want to go through the process manually, you can use addr2line to convert the
addresses in the stack trace to lines in your code. addresses in the stack trace to lines in your code.
For example, if your crash looks like this: For example, if your crash looks like this:

View File

@ -140,7 +140,8 @@ typedef Uint16 SDL_AudioFormat;
#define SDL_AUDIO_ALLOW_FREQUENCY_CHANGE 0x00000001 #define SDL_AUDIO_ALLOW_FREQUENCY_CHANGE 0x00000001
#define SDL_AUDIO_ALLOW_FORMAT_CHANGE 0x00000002 #define SDL_AUDIO_ALLOW_FORMAT_CHANGE 0x00000002
#define SDL_AUDIO_ALLOW_CHANNELS_CHANGE 0x00000004 #define SDL_AUDIO_ALLOW_CHANNELS_CHANGE 0x00000004
#define SDL_AUDIO_ALLOW_ANY_CHANGE (SDL_AUDIO_ALLOW_FREQUENCY_CHANGE|SDL_AUDIO_ALLOW_FORMAT_CHANGE|SDL_AUDIO_ALLOW_CHANNELS_CHANGE) #define SDL_AUDIO_ALLOW_SAMPLES_CHANGE 0x00000008
#define SDL_AUDIO_ALLOW_ANY_CHANGE (SDL_AUDIO_ALLOW_FREQUENCY_CHANGE|SDL_AUDIO_ALLOW_FORMAT_CHANGE|SDL_AUDIO_ALLOW_CHANNELS_CHANGE|SDL_AUDIO_ALLOW_SAMPLES_CHANGE)
/* @} */ /* @} */
/* @} *//* Audio flags */ /* @} *//* Audio flags */

View File

@ -41,8 +41,10 @@
#include "SDL_config_android.h" #include "SDL_config_android.h"
#elif defined(__PSP__) #elif defined(__PSP__)
#include "SDL_config_psp.h" #include "SDL_config_psp.h"
#elif defined(__OS2__)
#include "SDL_config_os2.h"
#else #else
/* This is a minimal configuration just to get SDL running on new platforms */ /* This is a minimal configuration just to get SDL running on new platforms. */
#include "SDL_config_minimal.h" #include "SDL_config_minimal.h"
#endif /* platform config */ #endif /* platform config */

View File

@ -209,6 +209,11 @@
#cmakedefine HAVE_DINPUT_H @HAVE_DINPUT_H@ #cmakedefine HAVE_DINPUT_H @HAVE_DINPUT_H@
#cmakedefine HAVE_XINPUT_H @HAVE_XINPUT_H@ #cmakedefine HAVE_XINPUT_H @HAVE_XINPUT_H@
#cmakedefine HAVE_DXGI_H @HAVE_DXGI_H@ #cmakedefine HAVE_DXGI_H @HAVE_DXGI_H@
#cmakedefine HAVE_ENDPOINTVOLUME_H @HAVE_ENDPOINTVOLUME_H@
#cmakedefine HAVE_MMDEVICEAPI_H @HAVE_MMDEVICEAPI_H@
#cmakedefine HAVE_AUDIOCLIENT_H @HAVE_AUDIOCLIENT_H@
#cmakedefine HAVE_XINPUT_GAMEPAD_EX @HAVE_XINPUT_GAMEPAD_EX@ #cmakedefine HAVE_XINPUT_GAMEPAD_EX @HAVE_XINPUT_GAMEPAD_EX@
#cmakedefine HAVE_XINPUT_STATE_EX @HAVE_XINPUT_STATE_EX@ #cmakedefine HAVE_XINPUT_STATE_EX @HAVE_XINPUT_STATE_EX@

View File

@ -209,6 +209,9 @@
#undef HAVE_DSOUND_H #undef HAVE_DSOUND_H
#undef HAVE_DXGI_H #undef HAVE_DXGI_H
#undef HAVE_XINPUT_H #undef HAVE_XINPUT_H
#undef HAVE_ENDPOINTVOLUME_H
#undef HAVE_MMDEVICEAPI_H
#undef HAVE_AUDIOCLIENT_H
#undef HAVE_XINPUT_GAMEPAD_EX #undef HAVE_XINPUT_GAMEPAD_EX
#undef HAVE_XINPUT_STATE_EX #undef HAVE_XINPUT_STATE_EX

View File

@ -137,7 +137,7 @@
/* Enable MFi joystick support */ /* Enable MFi joystick support */
#define SDL_JOYSTICK_MFI 1 #define SDL_JOYSTICK_MFI 1
#define SDL_JOYSTICK_HIDAPI 1 /*#define SDL_JOYSTICK_HIDAPI 1*/
#ifdef __TVOS__ #ifdef __TVOS__
#define SDL_SENSOR_DUMMY 1 #define SDL_SENSOR_DUMMY 1

170
include/SDL_config_os2.h Normal file
View File

@ -0,0 +1,170 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 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_config_os2_h_
#define SDL_config_os2_h_
#define SDL_config_h_
#include "SDL_platform.h"
#define SDL_AUDIO_DRIVER_DUMMY 1
#define SDL_AUDIO_DRIVER_DISK 1
#define SDL_POWER_DISABLED 1
#define SDL_JOYSTICK_DISABLED 1
#define SDL_HAPTIC_DISABLED 1
/*#undef SDL_JOYSTICK_HIDAPI */
#define SDL_SENSOR_DUMMY 1
#define SDL_VIDEO_DRIVER_DUMMY 1
/* Enable OpenGL support */
/* #undef SDL_VIDEO_OPENGL */
/* Enable Vulkan support */
/* #undef SDL_VIDEO_VULKAN */
#define SDL_LOADSO_DISABLED 1
#define SDL_THREADS_DISABLED 1
#define SDL_TIMERS_DISABLED 1
#define SDL_FILESYSTEM_DUMMY 1
/* Enable assembly routines */
#define SDL_ASSEMBLY_ROUTINES 1
/* #undef HAVE_LIBSAMPLERATE_H */
/* Enable dynamic libsamplerate support */
/* #undef SDL_LIBSAMPLERATE_DYNAMIC */
#define HAVE_LIBC 1
#define HAVE_SYS_TYPES_H 1
#define HAVE_STDIO_H 1
#define STDC_HEADERS 1
#define HAVE_STDLIB_H 1
#define HAVE_STDARG_H 1
#define HAVE_STDDEF_H 1
#define HAVE_MALLOC_H 1
#define HAVE_MEMORY_H 1
#define HAVE_STRING_H 1
#define HAVE_STRINGS_H 1
#define HAVE_WCHAR_H 1
#define HAVE_INTTYPES_H 1
#define HAVE_STDINT_H 1
#define HAVE_LIMITS_H 1
#define HAVE_CTYPE_H 1
#define HAVE_MATH_H 1
#define HAVE_FLOAT_H 1
#define HAVE_SIGNAL_H 1
#define HAVE_MALLOC 1
#define HAVE_CALLOC 1
#define HAVE_REALLOC 1
#define HAVE_FREE 1
#if defined(__WATCOMC__)
#define HAVE__FSEEKI64 1
#define HAVE__FTELLI64 1
#endif
#define HAVE_ALLOCA 1
#define HAVE_GETENV 1
#define HAVE_SETENV 1
#define HAVE_PUTENV 1
#define HAVE_QSORT 1
#define HAVE_ABS 1
#define HAVE_BCOPY 1
#define HAVE_MEMSET 1
#define HAVE_MEMCPY 1
#define HAVE_MEMMOVE 1
#define HAVE_MEMCMP 1
#define HAVE_WCSLEN 1
#define HAVE_WCSLCPY 1
#define HAVE_WCSLCAT 1
#define HAVE_WCSCMP 1
#define HAVE_STRLEN 1
#define HAVE_STRLCPY 1
#define HAVE_STRLCAT 1
#define HAVE__STRREV 1
#define HAVE__STRUPR 1
#define HAVE__STRLWR 1
#define HAVE_INDEX 1
#define HAVE_RINDEX 1
#define HAVE_STRCHR 1
#define HAVE_STRRCHR 1
#define HAVE_STRSTR 1
#define HAVE_ITOA 1
#define HAVE__LTOA 1
#define HAVE__ULTOA 1
#define HAVE_STRTOL 1
#define HAVE_STRTOUL 1
#define HAVE__I64TOA 1
#define HAVE__UI64TOA 1
#define HAVE_STRTOLL 1
#define HAVE_STRTOULL 1
#define HAVE_STRTOD 1
#define HAVE_ATOI 1
#define HAVE_ATOF 1
#define HAVE_STRCMP 1
#define HAVE_STRNCMP 1
#define HAVE_STRICMP 1
#define HAVE_STRCASECMP 1
#define HAVE_STRNCASECMP 1
#define HAVE_SSCANF 1
#define HAVE_SNPRINTF 1
#define HAVE_VSNPRINTF 1
#define HAVE_SETJMP 1
#define HAVE_ACOS 1
/* #undef HAVE_ACOSF */
#define HAVE_ASIN 1
/* #undef HAVE_ASINF */
#define HAVE_ATAN 1
#define HAVE_ATAN2 1
/* #undef HAVE_ATAN2F */
#define HAVE_CEIL 1
/* #undef HAVE_CEILF */
/* #undef HAVE_COPYSIGN */
/* #undef HAVE_COPYSIGNF */
#define HAVE_COS 1
/* #undef HAVE_COSF */
#define HAVE_EXP 1
/* #undef HAVE_EXPF */
#define HAVE_FABS 1
/* #undef HAVE_FABSF */
#define HAVE_FLOOR 1
/* #undef HAVE_FLOORF */
#define HAVE_FMOD 1
/* #undef HAVE_FMODF */
#define HAVE_LOG 1
/* #undef HAVE_LOGF */
#define HAVE_LOG10 1
/* #undef HAVE_LOG10F */
#define HAVE_POW 1
/* #undef HAVE_POWF */
#define HAVE_SIN 1
/* #undef HAVE_SINF */
/* #undef HAVE_SCALBN */
/* #undef HAVE_SCALBNF */
#define HAVE_SQRT 1
/* #undef HAVE_SQRTF */
#define HAVE_TAN 1
/* #undef HAVE_TANF */
#endif /* SDL_config_os2_h_ */

View File

@ -82,6 +82,9 @@ typedef unsigned int uintptr_t;
#define HAVE_DSOUND_H 1 #define HAVE_DSOUND_H 1
#define HAVE_DXGI_H 1 #define HAVE_DXGI_H 1
#define HAVE_XINPUT_H 1 #define HAVE_XINPUT_H 1
#define HAVE_MMDEVICEAPI_H 1
#define HAVE_AUDIOCLIENT_H 1
#define HAVE_ENDPOINTVOLUME_H 1
/* This is disabled by default to avoid C runtime dependencies and manifest requirements */ /* This is disabled by default to avoid C runtime dependencies and manifest requirements */
#ifdef HAVE_LIBC #ifdef HAVE_LIBC

View File

@ -97,6 +97,11 @@ typedef unsigned int uintptr_t;
#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP #if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
#define HAVE_XINPUT_H 1 #define HAVE_XINPUT_H 1
#endif #endif
#define HAVE_MMDEVICEAPI_H 1
#define HAVE_AUDIOCLIENT_H 1
#define HAVE_ENDPOINTVOLUME_H 1
#define HAVE_LIBC 1 #define HAVE_LIBC 1
#define STDC_HEADERS 1 #define STDC_HEADERS 1
#define HAVE_CTYPE_H 1 #define HAVE_CTYPE_H 1

View File

@ -204,6 +204,13 @@ extern DECLSPEC SDL_GameController *SDLCALL SDL_GameControllerFromInstanceID(SDL
*/ */
extern DECLSPEC const char *SDLCALL SDL_GameControllerName(SDL_GameController *gamecontroller); extern DECLSPEC const char *SDLCALL SDL_GameControllerName(SDL_GameController *gamecontroller);
/**
* Get the player index of an opened game controller, or -1 if it's not available
*
* For XInput controllers this returns the XInput user index.
*/
extern DECLSPEC int SDLCALL SDL_GameControllerGetPlayerIndex(SDL_GameController *gamecontroller);
/** /**
* Get the USB vendor ID of an opened controller, if available. * Get the USB vendor ID of an opened controller, if available.
* If the vendor ID isn't available this function returns 0. * If the vendor ID isn't available this function returns 0.

View File

@ -117,6 +117,17 @@
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
/* FIXME: For SDL 2.1, adjust all the magnitude variables to be Uint16 (0xFFFF).
*
* At the moment the magnitude variables are mixed between signed/unsigned, and
* it is also not made clear that ALL of those variables expect a max of 0x7FFF.
*
* Some platforms may have higher precision than that (Linux FF, Windows XInput)
* so we should fix the inconsistency in favor of higher possible precision,
* adjusting for platforms that use different scales.
* -flibit
*/
/** /**
* \typedef SDL_Haptic * \typedef SDL_Haptic
* *

View File

@ -262,6 +262,16 @@ extern "C" {
*/ */
#define SDL_HINT_GRAB_KEYBOARD "SDL_GRAB_KEYBOARD" #define SDL_HINT_GRAB_KEYBOARD "SDL_GRAB_KEYBOARD"
/**
* \brief A variable setting the double click time, in milliseconds.
*/
#define SDL_HINT_MOUSE_DOUBLE_CLICK_TIME "SDL_MOUSE_DOUBLE_CLICK_TIME"
/**
* \brief A variable setting the double click radius, in pixels.
*/
#define SDL_HINT_MOUSE_DOUBLE_CLICK_RADIUS "SDL_MOUSE_DOUBLE_CLICK_RADIUS"
/** /**
* \brief A variable setting the speed scale for mouse motion, in floating point, when the mouse is not in relative mode * \brief A variable setting the speed scale for mouse motion, in floating point, when the mouse is not in relative mode
*/ */
@ -329,7 +339,7 @@ extern "C" {
#define SDL_HINT_IDLE_TIMER_DISABLED "SDL_IOS_IDLE_TIMER_DISABLED" #define SDL_HINT_IDLE_TIMER_DISABLED "SDL_IOS_IDLE_TIMER_DISABLED"
/** /**
* \brief A variable controlling which orientations are allowed on iOS. * \brief A variable controlling which orientations are allowed on iOS/Android.
* *
* In some circumstances it is necessary to be able to explicitly control * In some circumstances it is necessary to be able to explicitly control
* which UI orientations are allowed. * which UI orientations are allowed.
@ -609,6 +619,10 @@ extern "C" {
* This is specially useful if you build SDL against a non glibc libc library (such as musl) which * This is specially useful if you build SDL against a non glibc libc library (such as musl) which
* provides a relatively small default thread stack size (a few kilobytes versus the default 8MB glibc uses). * provides a relatively small default thread stack size (a few kilobytes versus the default 8MB glibc uses).
* Support for this hint is currently available only in the pthread, Windows, and PSP backend. * Support for this hint is currently available only in the pthread, Windows, and PSP backend.
*
* Instead of this hint, in 2.0.9 and later, you can use
* SDL_CreateThreadWithStackSize(). This hint only works with the classic
* SDL_CreateThread().
*/ */
#define SDL_HINT_THREAD_STACK_SIZE "SDL_THREAD_STACK_SIZE" #define SDL_HINT_THREAD_STACK_SIZE "SDL_THREAD_STACK_SIZE"

View File

@ -132,6 +132,12 @@ extern DECLSPEC int SDLCALL SDL_NumJoysticks(void);
*/ */
extern DECLSPEC const char *SDLCALL SDL_JoystickNameForIndex(int device_index); extern DECLSPEC const char *SDLCALL SDL_JoystickNameForIndex(int device_index);
/**
* Get the player index of a joystick, or -1 if it's not available
* This can be called before any joysticks are opened.
*/
extern DECLSPEC int SDLCALL SDL_JoystickGetDevicePlayerIndex(int device_index);
/** /**
* Return the GUID for the joystick at this index * Return the GUID for the joystick at this index
* This can be called before any joysticks are opened. * This can be called before any joysticks are opened.
@ -194,6 +200,13 @@ extern DECLSPEC SDL_Joystick *SDLCALL SDL_JoystickFromInstanceID(SDL_JoystickID
*/ */
extern DECLSPEC const char *SDLCALL SDL_JoystickName(SDL_Joystick * joystick); extern DECLSPEC const char *SDLCALL SDL_JoystickName(SDL_Joystick * joystick);
/**
* Get the player index of an opened joystick, or -1 if it's not available
*
* For XInput controllers this returns the XInput user index.
*/
extern DECLSPEC int SDLCALL SDL_JoystickGetPlayerIndex(SDL_Joystick * joystick);
/** /**
* Return the GUID for this opened joystick * Return the GUID for this opened joystick
*/ */

View File

@ -41,7 +41,7 @@ extern "C" {
#endif #endif
/** /**
* \file SDL_sensor.h * \brief SDL_sensor.h
* *
* In order to use these functions, SDL_Init() must have been called * In order to use these functions, SDL_Init() must have been called
* with the ::SDL_INIT_SENSOR flag. This causes SDL to scan the system * with the ::SDL_INIT_SENSOR flag. This causes SDL to scan the system
@ -71,7 +71,7 @@ typedef enum
SDL_SENSOR_INVALID = -1, /**< Returned for an invalid sensor */ SDL_SENSOR_INVALID = -1, /**< Returned for an invalid sensor */
SDL_SENSOR_UNKNOWN, /**< Unknown sensor type */ SDL_SENSOR_UNKNOWN, /**< Unknown sensor type */
SDL_SENSOR_ACCEL, /**< Accelerometer */ SDL_SENSOR_ACCEL, /**< Accelerometer */
SDL_SENSOR_GYRO, /**< Gyroscope */ SDL_SENSOR_GYRO /**< Gyroscope */
} SDL_SensorType; } SDL_SensorType;
/** /**

View File

@ -248,6 +248,13 @@ extern DECLSPEC int SDLCALL SDL_SetSurfaceRLE(SDL_Surface * surface,
extern DECLSPEC int SDLCALL SDL_SetColorKey(SDL_Surface * surface, extern DECLSPEC int SDLCALL SDL_SetColorKey(SDL_Surface * surface,
int flag, Uint32 key); int flag, Uint32 key);
/**
* \brief Returns whether the surface has a color key
*
* \return SDL_TRUE if the surface has a color key, or SDL_FALSE if the surface is NULL or has no color key
*/
extern DECLSPEC SDL_bool SDLCALL SDL_HasColorKey(SDL_Surface * surface);
/** /**
* \brief Gets the color key (transparent pixel) in a blittable surface. * \brief Gets the color key (transparent pixel) in a blittable surface.
* *

View File

@ -106,14 +106,24 @@ SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data,
pfnSDL_CurrentBeginThread pfnBeginThread, pfnSDL_CurrentBeginThread pfnBeginThread,
pfnSDL_CurrentEndThread pfnEndThread); pfnSDL_CurrentEndThread pfnEndThread);
extern DECLSPEC SDL_Thread *SDLCALL
SDL_CreateThreadWithStackSize(int (SDLCALL * fn) (void *),
const char *name, const size_t stacksize, void *data,
pfnSDL_CurrentBeginThread pfnBeginThread,
pfnSDL_CurrentEndThread pfnEndThread);
/** /**
* Create a thread. * Create a thread.
*/ */
#if defined(SDL_CreateThread) && SDL_DYNAMIC_API #if defined(SDL_CreateThread) && SDL_DYNAMIC_API
#undef SDL_CreateThread #undef SDL_CreateThread
#define SDL_CreateThread(fn, name, data) SDL_CreateThread_REAL(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthreadex, (pfnSDL_CurrentEndThread)_endthreadex) #define SDL_CreateThread(fn, name, data) SDL_CreateThread_REAL(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthreadex, (pfnSDL_CurrentEndThread)_endthreadex)
#undef SDL_CreateThreadWithStackSize
#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize_REAL(fn, name, stacksize, data, (pfnSDL_CurrentBeginThread)_beginthreadex, (pfnSDL_CurrentEndThread)_endthreadex)
#else #else
#define SDL_CreateThread(fn, name, data) SDL_CreateThread(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthreadex, (pfnSDL_CurrentEndThread)_endthreadex) #define SDL_CreateThread(fn, name, data) SDL_CreateThread(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthreadex, (pfnSDL_CurrentEndThread)_endthreadex)
#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthreadex, (pfnSDL_CurrentEndThread)_endthreadex)
#endif #endif
#elif defined(__OS2__) #elif defined(__OS2__)
@ -133,15 +143,31 @@ extern DECLSPEC SDL_Thread *SDLCALL
SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data, SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data,
pfnSDL_CurrentBeginThread pfnBeginThread, pfnSDL_CurrentBeginThread pfnBeginThread,
pfnSDL_CurrentEndThread pfnEndThread); pfnSDL_CurrentEndThread pfnEndThread);
extern DECLSPEC SDL_Thread *SDLCALL
SDL_CreateThreadWithStackSize(SDL_ThreadFunction fn, const char *name, const size_t stacksize, void *data,
pfnSDL_CurrentBeginThread pfnBeginThread,
pfnSDL_CurrentEndThread pfnEndThread);
#if defined(SDL_CreateThread) && SDL_DYNAMIC_API #if defined(SDL_CreateThread) && SDL_DYNAMIC_API
#undef SDL_CreateThread #undef SDL_CreateThread
#define SDL_CreateThread(fn, name, data) SDL_CreateThread_REAL(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthread, (pfnSDL_CurrentEndThread)_endthread) #define SDL_CreateThread(fn, name, data) SDL_CreateThread_REAL(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthread, (pfnSDL_CurrentEndThread)_endthread)
#undef SDL_CreateThreadWithStackSize
#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize_REAL(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthread, (pfnSDL_CurrentEndThread)_endthread)
#else #else
#define SDL_CreateThread(fn, name, data) SDL_CreateThread(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthread, (pfnSDL_CurrentEndThread)_endthread) #define SDL_CreateThread(fn, name, data) SDL_CreateThread(fn, name, data, (pfnSDL_CurrentBeginThread)_beginthread, (pfnSDL_CurrentEndThread)_endthread)
#define SDL_CreateThreadWithStackSize(fn, name, stacksize, data) SDL_CreateThreadWithStackSize(fn, name, stacksize, data, (pfnSDL_CurrentBeginThread)_beginthread, (pfnSDL_CurrentEndThread)_endthread)
#endif #endif
#else #else
/**
* Create a thread with a default stack size.
*
* This is equivalent to calling:
* SDL_CreateThreadWithStackSize(fn, name, 0, data);
*/
extern DECLSPEC SDL_Thread *SDLCALL
SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data);
/** /**
* Create a thread. * Create a thread.
* *
@ -159,9 +185,17 @@ SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data,
* If a system imposes requirements, SDL will try to munge the string for * If a system imposes requirements, SDL will try to munge the string for
* it (truncate, etc), but the original string contents will be available * it (truncate, etc), but the original string contents will be available
* from SDL_GetThreadName(). * from SDL_GetThreadName().
*
* The size (in bytes) of the new stack can be specified. Zero means "use
* the system default" which might be wildly different between platforms
* (x86 Linux generally defaults to eight megabytes, an embedded device
* might be a few kilobytes instead).
*
* In SDL 2.1, stacksize will be folded into the original SDL_CreateThread
* function.
*/ */
extern DECLSPEC SDL_Thread *SDLCALL extern DECLSPEC SDL_Thread *SDLCALL
SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data); SDL_CreateThreadWithStackSize(SDL_ThreadFunction fn, const char *name, const size_t stacksize, void *data);
#endif #endif

View File

@ -59,7 +59,7 @@ typedef struct SDL_version
*/ */
#define SDL_MAJOR_VERSION 2 #define SDL_MAJOR_VERSION 2
#define SDL_MINOR_VERSION 0 #define SDL_MINOR_VERSION 0
#define SDL_PATCHLEVEL 8 #define SDL_PATCHLEVEL 9
/** /**
* \brief Macro to determine SDL version program was compiled against. * \brief Macro to determine SDL version program was compiled against.

View File

@ -175,7 +175,7 @@ typedef enum
typedef enum typedef enum
{ {
SDL_DISPLAYEVENT_NONE, /**< Never used */ SDL_DISPLAYEVENT_NONE, /**< Never used */
SDL_DISPLAYEVENT_ORIENTATION, /**< Display orientation has changed to data1 */ SDL_DISPLAYEVENT_ORIENTATION /**< Display orientation has changed to data1 */
} SDL_DisplayEventID; } SDL_DisplayEventID;
typedef enum typedef enum
@ -184,7 +184,7 @@ typedef enum
SDL_ORIENTATION_LANDSCAPE, /**< The display is in landscape mode, with the right side up, relative to portrait mode */ SDL_ORIENTATION_LANDSCAPE, /**< The display is in landscape mode, with the right side up, relative to portrait mode */
SDL_ORIENTATION_LANDSCAPE_FLIPPED, /**< The display is in landscape mode, with the left side up, relative to portrait mode */ SDL_ORIENTATION_LANDSCAPE_FLIPPED, /**< The display is in landscape mode, with the left side up, relative to portrait mode */
SDL_ORIENTATION_PORTRAIT, /**< The display is in portrait mode */ SDL_ORIENTATION_PORTRAIT, /**< The display is in portrait mode */
SDL_ORIENTATION_PORTRAIT_FLIPPED, /**< The display is in portrait mode, upside down */ SDL_ORIENTATION_PORTRAIT_FLIPPED /**< The display is in portrait mode, upside down */
} SDL_DisplayOrientation; } SDL_DisplayOrientation;
/** /**

View File

@ -137,9 +137,9 @@ extern DECLSPEC void SDLCALL SDL_Vulkan_UnloadLibrary(void);
* *
* \param [in] \c NULL or window Window for which the required Vulkan instance * \param [in] \c NULL or window Window for which the required Vulkan instance
* extensions should be retrieved * extensions should be retrieved
* \param [in,out] count pointer to an \c unsigned related to the number of * \param [in,out] pCount pointer to an \c unsigned related to the number of
* required Vulkan instance extensions * required Vulkan instance extensions
* \param [out] names \c NULL or a pointer to an array to be filled with the * \param [out] pNames \c NULL or a pointer to an array to be filled with the
* required Vulkan instance extensions * required Vulkan instance extensions
* *
* \return \c SDL_TRUE on success, \c SDL_FALSE on error. * \return \c SDL_TRUE on success, \c SDL_FALSE on error.

View File

@ -124,11 +124,11 @@ SDL_InitSubSystem(Uint32 flags)
} }
#if SDL_VIDEO_DRIVER_WINDOWS #if SDL_VIDEO_DRIVER_WINDOWS
if ((flags & (SDL_INIT_HAPTIC|SDL_INIT_JOYSTICK))) { if ((flags & (SDL_INIT_HAPTIC|SDL_INIT_JOYSTICK))) {
if (SDL_HelperWindowCreate() < 0) { if (SDL_HelperWindowCreate() < 0) {
return -1; return -1;
} }
} }
#endif #endif
#if !SDL_TIMERS_DISABLED #if !SDL_TIMERS_DISABLED
@ -263,8 +263,8 @@ SDL_QuitSubSystem(Uint32 flags)
#if !SDL_SENSOR_DISABLED #if !SDL_SENSOR_DISABLED
if ((flags & SDL_INIT_SENSOR)) { if ((flags & SDL_INIT_SENSOR)) {
if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_SENSOR)) { if (SDL_PrivateShouldQuitSubsystem(SDL_INIT_SENSOR)) {
SDL_SensorQuit(); SDL_SensorQuit();
} }
SDL_PrivateSubsystemRefCountDecr(SDL_INIT_SENSOR); SDL_PrivateSubsystemRefCountDecr(SDL_INIT_SENSOR);
} }
#endif #endif

View File

@ -19,6 +19,11 @@
3. This notice may not be removed or altered from any source distribution. 3. This notice may not be removed or altered from any source distribution.
*/ */
#ifndef SDL_assert_c_h_
#define SDL_assert_c_h_
extern void SDL_AssertionsQuit(void); extern void SDL_AssertionsQuit(void);
#endif /* SDL_assert_c_h_ */
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */

View File

@ -53,10 +53,11 @@
#endif #endif
#if defined(__WATCOMC__) && defined(__386__) #if defined(__WATCOMC__) && defined(__386__)
SDL_COMPILE_TIME_ASSERT(intsize, 4==sizeof(int));
#define HAVE_WATCOM_ATOMICS #define HAVE_WATCOM_ATOMICS
extern _inline int _SDL_xchg_watcom(volatile int *a, int v); extern _inline int _SDL_xchg_watcom(volatile int *a, int v);
#pragma aux _SDL_xchg_watcom = \ #pragma aux _SDL_xchg_watcom = \
"xchg [ecx], eax" \ "lock xchg [ecx], eax" \
parm [ecx] [eax] \ parm [ecx] [eax] \
value [eax] \ value [eax] \
modify exact [eax]; modify exact [eax];

View File

@ -40,7 +40,7 @@
SDL_COMPILE_TIME_ASSERT(locksize, 4==sizeof(SDL_SpinLock)); SDL_COMPILE_TIME_ASSERT(locksize, 4==sizeof(SDL_SpinLock));
extern _inline int _SDL_xchg_watcom(volatile int *a, int v); extern _inline int _SDL_xchg_watcom(volatile int *a, int v);
#pragma aux _SDL_xchg_watcom = \ #pragma aux _SDL_xchg_watcom = \
"xchg [ecx], eax" \ "lock xchg [ecx], eax" \
parm [ecx] [eax] \ parm [ecx] [eax] \
value [eax] \ value [eax] \
modify exact [eax]; modify exact [eax];

View File

@ -378,21 +378,57 @@ static int
add_audio_device(const char *name, void *handle, SDL_AudioDeviceItem **devices, int *devCount) add_audio_device(const char *name, void *handle, SDL_AudioDeviceItem **devices, int *devCount)
{ {
int retval = -1; int retval = -1;
const size_t size = sizeof (SDL_AudioDeviceItem) + SDL_strlen(name) + 1; SDL_AudioDeviceItem *item;
SDL_AudioDeviceItem *item = (SDL_AudioDeviceItem *) SDL_malloc(size); const SDL_AudioDeviceItem *i;
if (item == NULL) { int dupenum = 0;
return -1;
}
SDL_assert(handle != NULL); /* we reserve NULL, audio backends can't use it. */ SDL_assert(handle != NULL); /* we reserve NULL, audio backends can't use it. */
SDL_assert(name != NULL);
item = (SDL_AudioDeviceItem *) SDL_malloc(sizeof (SDL_AudioDeviceItem));
if (!item) {
return SDL_OutOfMemory();
}
item->original_name = SDL_strdup(name);
if (!item->original_name) {
SDL_free(item);
return SDL_OutOfMemory();
}
item->dupenum = 0;
item->name = item->original_name;
item->handle = handle; item->handle = handle;
SDL_strlcpy(item->name, name, size - sizeof (SDL_AudioDeviceItem));
SDL_LockMutex(current_audio.detectionLock); SDL_LockMutex(current_audio.detectionLock);
for (i = *devices; i != NULL; i = i->next) {
if (SDL_strcmp(name, i->original_name) == 0) {
dupenum = i->dupenum + 1;
break; /* stop at the highest-numbered dupe. */
}
}
if (dupenum) {
const size_t len = SDL_strlen(name) + 16;
char *replacement = (char *) SDL_malloc(len);
if (!replacement) {
SDL_UnlockMutex(current_audio.detectionLock);
SDL_free(item->original_name);
SDL_free(item);
SDL_OutOfMemory();
return -1;
}
SDL_snprintf(replacement, len, "%s (%d)", name, dupenum + 1);
item->dupenum = dupenum;
item->name = replacement;
}
item->next = *devices; item->next = *devices;
*devices = item; *devices = item;
retval = (*devCount)++; retval = (*devCount)++; /* !!! FIXME: this should be an atomic increment */
SDL_UnlockMutex(current_audio.detectionLock); SDL_UnlockMutex(current_audio.detectionLock);
return retval; return retval;
@ -420,6 +456,11 @@ free_device_list(SDL_AudioDeviceItem **devices, int *devCount)
if (item->handle != NULL) { if (item->handle != NULL) {
current_audio.impl.FreeDeviceHandle(item->handle); current_audio.impl.FreeDeviceHandle(item->handle);
} }
/* these two pointers are the same if not a duplicate devname */
if (item->name != item->original_name) {
SDL_free(item->name);
}
SDL_free(item->original_name);
SDL_free(item); SDL_free(item);
} }
*devices = NULL; *devices = NULL;
@ -977,6 +1018,11 @@ clean_out_device_list(SDL_AudioDeviceItem **devices, int *devCount, SDL_bool *re
} else { } else {
*devices = next; *devices = next;
} }
/* these two pointers are the same if not a duplicate devname */
if (item->name != item->original_name) {
SDL_free(item->name);
}
SDL_free(item->original_name);
SDL_free(item); SDL_free(item);
} }
item = next; item = next;
@ -1003,7 +1049,6 @@ SDL_GetNumAudioDevices(int iscapture)
if (!iscapture && current_audio.outputDevicesRemoved) { if (!iscapture && current_audio.outputDevicesRemoved) {
clean_out_device_list(&current_audio.outputDevices, &current_audio.outputDeviceCount, &current_audio.outputDevicesRemoved); clean_out_device_list(&current_audio.outputDevices, &current_audio.outputDeviceCount, &current_audio.outputDevicesRemoved);
current_audio.outputDevicesRemoved = SDL_FALSE;
} }
retval = iscapture ? current_audio.inputDeviceCount : current_audio.outputDeviceCount; retval = iscapture ? current_audio.inputDeviceCount : current_audio.outputDeviceCount;
@ -1130,8 +1175,9 @@ prepare_audiospec(const SDL_AudioSpec * orig, SDL_AudioSpec * prepared)
} }
case 1: /* Mono */ case 1: /* Mono */
case 2: /* Stereo */ case 2: /* Stereo */
case 4: /* surround */ case 4: /* Quadrophonic */
case 6: /* surround with center and lfe */ case 6: /* 5.1 surround */
case 8: /* 7.1 surround */
break; break;
default: default:
SDL_SetError("Unsupported number of audio channels."); SDL_SetError("Unsupported number of audio channels.");
@ -1324,15 +1370,12 @@ open_audio_device(const char *devname, int iscapture,
build_stream = SDL_TRUE; build_stream = SDL_TRUE;
} }
} }
/* !!! FIXME in 2.1: add SDL_AUDIO_ALLOW_SAMPLES_CHANGE flag?
As of 2.0.6, we will build a stream to buffer the difference between
what the app wants to feed and the device wants to eat, so everyone
gets their way. In prior releases, SDL would force the callback to
feed at the rate the device requested, adjusted for resampling.
*/
if (device->spec.samples != obtained->samples) { if (device->spec.samples != obtained->samples) {
build_stream = SDL_TRUE; if (allowed_changes & SDL_AUDIO_ALLOW_SAMPLES_CHANGE) {
obtained->samples = device->spec.samples;
} else {
build_stream = SDL_TRUE;
}
} }
SDL_CalculateAudioSpec(obtained); /* recalc after possible changes. */ SDL_CalculateAudioSpec(obtained); /* recalc after possible changes. */

View File

@ -18,6 +18,10 @@
misrepresented as being the original software. misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution. 3. This notice may not be removed or altered from any source distribution.
*/ */
#ifndef SDL_audiodev_c_h_
#define SDL_audiodev_c_h_
#include "SDL.h" #include "SDL.h"
#include "../SDL_internal.h" #include "../SDL_internal.h"
#include "SDL_sysaudio.h" #include "SDL_sysaudio.h"
@ -35,4 +39,6 @@
extern void SDL_EnumUnixAudioDevices(const int classic, int (*test)(int)); extern void SDL_EnumUnixAudioDevices(const int classic, int (*test)(int));
#endif /* SDL_audiodev_c_h_ */
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */

View File

@ -25,7 +25,8 @@
#include "SDL_cpuinfo.h" #include "SDL_cpuinfo.h"
#include "SDL_assert.h" #include "SDL_assert.h"
#ifdef __ARM_NEON__ /* !!! FIXME: disabled until we fix https://bugzilla.libsdl.org/show_bug.cgi?id=4186 */
#if 0 /*def __ARM_NEON__*/
#define HAVE_NEON_INTRINSICS 1 #define HAVE_NEON_INTRINSICS 1
#endif #endif

View File

@ -98,8 +98,10 @@ typedef struct SDL_AudioDriverImpl
typedef struct SDL_AudioDeviceItem typedef struct SDL_AudioDeviceItem
{ {
void *handle; void *handle;
char *name;
char *original_name;
int dupenum;
struct SDL_AudioDeviceItem *next; struct SDL_AudioDeviceItem *next;
char name[SDL_VARIABLE_LENGTH_ARRAY];
} SDL_AudioDeviceItem; } SDL_AudioDeviceItem;

View File

@ -445,7 +445,7 @@ static void
ALSA_CloseDevice(_THIS) ALSA_CloseDevice(_THIS)
{ {
if (this->hidden->pcm_handle) { if (this->hidden->pcm_handle) {
/* Wait for the submitted audio to drain /* Wait for the submitted audio to drain
ALSA_snd_pcm_drop() can hang, so don't use that. ALSA_snd_pcm_drop() can hang, so don't use that.
*/ */
Uint32 delay = ((this->spec.samples * 1000) / this->spec.freq) * 2; Uint32 delay = ((this->spec.samples * 1000) / this->spec.freq) * 2;

View File

@ -57,7 +57,9 @@ ANDROIDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
test_format = SDL_FirstAudioFormat(this->spec.format); test_format = SDL_FirstAudioFormat(this->spec.format);
while (test_format != 0) { /* no "UNKNOWN" constant */ while (test_format != 0) { /* no "UNKNOWN" constant */
if ((test_format == AUDIO_U8) || (test_format == AUDIO_S16LSB)) { if ((test_format == AUDIO_U8) ||
(test_format == AUDIO_S16) ||
(test_format == AUDIO_F32)) {
this->spec.format = test_format; this->spec.format = test_format;
break; break;
} }
@ -69,25 +71,8 @@ ANDROIDAUDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
return SDL_SetError("No compatible audio format!"); return SDL_SetError("No compatible audio format!");
} }
if (this->spec.channels > 1) { if (Android_JNI_OpenAudioDevice(iscapture, &this->spec) < 0) {
this->spec.channels = 2; return -1;
} else {
this->spec.channels = 1;
}
if (this->spec.freq < 8000) {
this->spec.freq = 8000;
}
if (this->spec.freq > 48000) {
this->spec.freq = 48000;
}
/* TODO: pass in/return a (Java) device ID */
this->spec.samples = Android_JNI_OpenAudioDevice(iscapture, this->spec.freq, this->spec.format == AUDIO_U8 ? 0 : 1, this->spec.channels, this->spec.samples);
if (this->spec.samples == 0) {
/* Init failed? */
return SDL_SetError("Java-side initialization failed!");
} }
SDL_CalculateAudioSpec(&this->spec); SDL_CalculateAudioSpec(&this->spec);

View File

@ -39,7 +39,7 @@
#include "SDL_name.h" #include "SDL_name.h"
#include "SDL_loadso.h" #include "SDL_loadso.h"
#else #else
#define SDL_NAME(X) X #define SDL_NAME(X) X
#endif #endif
#ifdef SDL_AUDIO_DRIVER_ARTS_DYNAMIC #ifdef SDL_AUDIO_DRIVER_ARTS_DYNAMIC

View File

@ -477,8 +477,8 @@ DSOUND_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
SDL_bool tried_format = SDL_FALSE; SDL_bool tried_format = SDL_FALSE;
SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format); SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
LPGUID guid = (LPGUID) handle; LPGUID guid = (LPGUID) handle;
DWORD bufsize; DWORD bufsize;
/* Initialize all variables that we clean on shutdown */ /* Initialize all variables that we clean on shutdown */
this->hidden = (struct SDL_PrivateAudioData *) this->hidden = (struct SDL_PrivateAudioData *)
SDL_malloc((sizeof *this->hidden)); SDL_malloc((sizeof *this->hidden));
@ -526,7 +526,7 @@ DSOUND_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
(int) (DSBSIZE_MAX / numchunks)); (int) (DSBSIZE_MAX / numchunks));
} else { } else {
int rc; int rc;
WAVEFORMATEX wfmt; WAVEFORMATEX wfmt;
SDL_zero(wfmt); SDL_zero(wfmt);
if (SDL_AUDIO_ISFLOAT(this->spec.format)) { if (SDL_AUDIO_ISFLOAT(this->spec.format)) {
wfmt.wFormatTag = WAVE_FORMAT_IEEE_FLOAT; wfmt.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;

View File

@ -109,7 +109,7 @@ static pa_operation * (*PULSEAUDIO_pa_stream_drain) (pa_stream *,
pa_stream_success_cb_t, void *); pa_stream_success_cb_t, void *);
static int (*PULSEAUDIO_pa_stream_peek) (pa_stream *, const void **, size_t *); static int (*PULSEAUDIO_pa_stream_peek) (pa_stream *, const void **, size_t *);
static int (*PULSEAUDIO_pa_stream_drop) (pa_stream *); static int (*PULSEAUDIO_pa_stream_drop) (pa_stream *);
static pa_operation * (*PULSEAUDIO_pa_stream_flush) (pa_stream *, static pa_operation * (*PULSEAUDIO_pa_stream_flush) (pa_stream *,
pa_stream_success_cb_t, void *); pa_stream_success_cb_t, void *);
static int (*PULSEAUDIO_pa_stream_disconnect) (pa_stream *); static int (*PULSEAUDIO_pa_stream_disconnect) (pa_stream *);
static void (*PULSEAUDIO_pa_stream_unref) (pa_stream *); static void (*PULSEAUDIO_pa_stream_unref) (pa_stream *);

View File

@ -725,6 +725,12 @@ WASAPI_ThreadDeinit(_THIS)
WASAPI_PlatformThreadDeinit(this); WASAPI_PlatformThreadDeinit(this);
} }
void
WASAPI_BeginLoopIteration(_THIS)
{
/* no-op. */
}
static void static void
WASAPI_Deinitialize(void) WASAPI_Deinitialize(void)
{ {

View File

@ -351,10 +351,42 @@ WASAPI_ActivateDevice(_THIS, const SDL_bool isrecovery)
} }
typedef struct
{
LPWSTR devid;
char *devname;
} EndpointItem;
static int sort_endpoints(const void *_a, const void *_b)
{
LPWSTR a = ((const EndpointItem *) _a)->devid;
LPWSTR b = ((const EndpointItem *) _b)->devid;
if (!a && b) {
return -1;
} else if (a && !b) {
return 1;
}
while (SDL_TRUE) {
if (*a < *b) {
return -1;
} else if (*a > *b) {
return 1;
} else if (*a == 0) {
break;
}
a++;
b++;
}
return 0;
}
static void static void
WASAPI_EnumerateEndpointsForFlow(const SDL_bool iscapture) WASAPI_EnumerateEndpointsForFlow(const SDL_bool iscapture)
{ {
IMMDeviceCollection *collection = NULL; IMMDeviceCollection *collection = NULL;
EndpointItem *items;
UINT i, total; UINT i, total;
/* Note that WASAPI separates "adapter devices" from "audio endpoint devices" /* Note that WASAPI separates "adapter devices" from "audio endpoint devices"
@ -369,22 +401,36 @@ WASAPI_EnumerateEndpointsForFlow(const SDL_bool iscapture)
return; return;
} }
items = (EndpointItem *) SDL_calloc(total, sizeof (EndpointItem));
if (!items) {
return; /* oh well. */
}
for (i = 0; i < total; i++) { for (i = 0; i < total; i++) {
EndpointItem *item = items + i;
IMMDevice *device = NULL; IMMDevice *device = NULL;
if (SUCCEEDED(IMMDeviceCollection_Item(collection, i, &device))) { if (SUCCEEDED(IMMDeviceCollection_Item(collection, i, &device))) {
LPWSTR devid = NULL; if (SUCCEEDED(IMMDevice_GetId(device, &item->devid))) {
if (SUCCEEDED(IMMDevice_GetId(device, &devid))) { item->devname = GetWasapiDeviceName(device);
char *devname = GetWasapiDeviceName(device);
if (devname) {
WASAPI_AddDevice(iscapture, devname, devid);
SDL_free(devname);
}
CoTaskMemFree(devid);
} }
IMMDevice_Release(device); IMMDevice_Release(device);
} }
} }
/* sort the list of devices by their guid so list is consistent between runs */
SDL_qsort(items, total, sizeof (*items), sort_endpoints);
/* Send the sorted list on to the SDL's higher level. */
for (i = 0; i < total; i++) {
EndpointItem *item = items + i;
if ((item->devid) && (item->devname)) {
WASAPI_AddDevice(iscapture, item->devname, item->devid);
}
SDL_free(item->devname);
CoTaskMemFree(item->devid);
}
SDL_free(items);
IMMDeviceCollection_Release(collection); IMMDeviceCollection_Release(collection);
} }
@ -405,12 +451,6 @@ WASAPI_PlatformDeleteActivationHandler(void *handler)
SDL_assert(!"This function should have only been called on WinRT."); SDL_assert(!"This function should have only been called on WinRT.");
} }
void
WASAPI_BeginLoopIteration(_THIS)
{
/* no-op. */
}
#endif /* SDL_AUDIO_DRIVER_WASAPI && !defined(__WINRT__) */ #endif /* SDL_AUDIO_DRIVER_WASAPI && !defined(__WINRT__) */
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */

View File

@ -185,20 +185,9 @@ struct SDL_WasapiActivationHandler : public RuntimeClass< RuntimeClassFlags< Cla
HRESULT HRESULT
SDL_WasapiActivationHandler::ActivateCompleted(IActivateAudioInterfaceAsyncOperation *async) SDL_WasapiActivationHandler::ActivateCompleted(IActivateAudioInterfaceAsyncOperation *async)
{ {
HRESULT result = S_OK; // Just set a flag, since we're probably in a different thread. We'll pick it up and init everything on our own thread to prevent races.
IUnknown *iunknown = nullptr; SDL_AtomicSet(&device->hidden->just_activated, 1);
const HRESULT ret = async->GetActivateResult(&result, &iunknown);
if (SUCCEEDED(ret) && SUCCEEDED(result)) {
iunknown->QueryInterface(IID_PPV_ARGS(&device->hidden->client));
if (device->hidden->client) {
// Just set a flag, since we're probably in a different thread. We'll pick it up and init everything on our own thread to prevent races.
SDL_AtomicSet(&device->hidden->just_activated, 1);
}
}
WASAPI_UnrefDevice(device); WASAPI_UnrefDevice(device);
return S_OK; return S_OK;
} }
@ -236,27 +225,47 @@ WASAPI_ActivateDevice(_THIS, const SDL_bool isrecovery)
IActivateAudioInterfaceAsyncOperation *async = nullptr; IActivateAudioInterfaceAsyncOperation *async = nullptr;
const HRESULT ret = ActivateAudioInterfaceAsync(devid, __uuidof(IAudioClient), nullptr, handler.Get(), &async); const HRESULT ret = ActivateAudioInterfaceAsync(devid, __uuidof(IAudioClient), nullptr, handler.Get(), &async);
if (async != nullptr) { if (FAILED(ret) || async == nullptr) {
async->Release(); if (async != nullptr) {
} async->Release();
}
if (FAILED(ret)) {
handler.Get()->Release(); handler.Get()->Release();
WASAPI_UnrefDevice(_this); WASAPI_UnrefDevice(_this);
return WIN_SetErrorFromHRESULT("WASAPI can't activate requested audio endpoint", ret); return WIN_SetErrorFromHRESULT("WASAPI can't activate requested audio endpoint", ret);
} }
return 0; /* Spin until the async operation is complete.
} * If we don't PrepDevice before leaving this function, the bug list gets LONG:
* - device.spec is not filled with the correct information
void * - The 'obtained' spec will be wrong for ALLOW_CHANGE properties
WASAPI_BeginLoopIteration(_THIS) * - SDL_AudioStreams will/will not be allocated at the right time
{ * - SDL_assert(device->callbackspec.size == device->spec.size) will fail
if (SDL_AtomicCAS(&_this->hidden->just_activated, 1, 0)) { * - When the assert is ignored, skipping or a buffer overflow will occur
if (WASAPI_PrepDevice(_this, SDL_TRUE) == -1) { */
SDL_OpenedAudioDeviceDisconnected(_this); while (!SDL_AtomicCAS(&_this->hidden->just_activated, 1, 0)) {
} SDL_Delay(1);
} }
HRESULT activateRes = S_OK;
IUnknown *iunknown = nullptr;
const HRESULT getActivateRes = async->GetActivateResult(&activateRes, &iunknown);
async->Release();
if (FAILED(getActivateRes)) {
return WIN_SetErrorFromHRESULT("Failed to get WASAPI activate result", getActivateRes);
} else if (FAILED(activateRes)) {
return WIN_SetErrorFromHRESULT("Failed to activate WASAPI device", activateRes);
}
iunknown->QueryInterface(IID_PPV_ARGS(&_this->hidden->client));
if (!_this->hidden->client) {
return SDL_SetError("Failed to query WASAPI client interface");
}
if (WASAPI_PrepDevice(_this, isrecovery) == -1) {
return -1;
}
return 0;
} }
void void

View File

@ -78,7 +78,7 @@ static void DetectWave##typ##Devs(void) { \
capstyp##2W caps; \ capstyp##2W caps; \
UINT i; \ UINT i; \
for (i = 0; i < devcount; i++) { \ for (i = 0; i < devcount; i++) { \
if (wave##typ##GetDevCaps(i,(LP##capstyp##W)&caps,sizeof(caps))==MMSYSERR_NOERROR) { \ if (wave##typ##GetDevCaps(i,(LP##capstyp##W)&caps,sizeof(caps))==MMSYSERR_NOERROR) { \
char *name = WIN_LookupAudioDeviceName(caps.szPname,&caps.NameGuid); \ char *name = WIN_LookupAudioDeviceName(caps.szPname,&caps.NameGuid); \
if (name != NULL) { \ if (name != NULL) { \
SDL_AddAudioDevice((int) iscapture, name, (void *) ((size_t) i+1)); \ SDL_AddAudioDevice((int) iscapture, name, (void *) ((size_t) i+1)); \
@ -375,8 +375,7 @@ WINMM_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
#endif #endif
/* Create the audio buffer semaphore */ /* Create the audio buffer semaphore */
this->hidden->audio_sem = this->hidden->audio_sem = CreateSemaphore(NULL, iscapture ? 0 : NUM_BUFFERS - 1, NUM_BUFFERS, NULL);
CreateSemaphore(NULL, iscapture ? 0 : NUM_BUFFERS - 1, NUM_BUFFERS, NULL);
if (this->hidden->audio_sem == NULL) { if (this->hidden->audio_sem == NULL) {
return SDL_SetError("Couldn't create semaphore"); return SDL_SetError("Couldn't create semaphore");
} }

View File

@ -61,6 +61,10 @@
#define SDL_JAVA_CONTROLLER_INTERFACE(function) CONCAT1(SDL_JAVA_PREFIX, SDLControllerManager, function) #define SDL_JAVA_CONTROLLER_INTERFACE(function) CONCAT1(SDL_JAVA_PREFIX, SDLControllerManager, function)
#define SDL_JAVA_INTERFACE_INPUT_CONNECTION(function) CONCAT1(SDL_JAVA_PREFIX, SDLInputConnection, function) #define SDL_JAVA_INTERFACE_INPUT_CONNECTION(function) CONCAT1(SDL_JAVA_PREFIX, SDLInputConnection, function)
/* Audio encoding definitions */
#define ENCODING_PCM_8BIT 3
#define ENCODING_PCM_16BIT 2
#define ENCODING_PCM_FLOAT 4
/* Java class SDLActivity */ /* Java class SDLActivity */
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)( JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(
@ -77,7 +81,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeDropFile)(
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeResize)( JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeResize)(
JNIEnv* env, jclass jcls, JNIEnv* env, jclass jcls,
jint surfaceWidth, jint surfaceHeight, jint surfaceWidth, jint surfaceHeight,
jint deviceWidth, jint deviceHeight, jint format, jfloat rate); jint deviceWidth, jint deviceHeight, jint format, jfloat rate);
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceChanged)( JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceChanged)(
JNIEnv* env, jclass jcls); JNIEnv* env, jclass jcls);
@ -144,6 +148,10 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeCommitText)(
JNIEnv* env, jclass cls, JNIEnv* env, jclass cls,
jstring text, jint newCursorPosition); jstring text, jint newCursorPosition);
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeGenerateScancodeForUnichar)(
JNIEnv* env, jclass cls,
jchar chUnicode);
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeSetComposingText)( JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeSetComposingText)(
JNIEnv* env, jclass cls, JNIEnv* env, jclass cls,
jstring text, jint newCursorPosition); jstring text, jint newCursorPosition);
@ -195,6 +203,7 @@ JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveHaptic)(
/* #define DEBUG_JNI */ /* #define DEBUG_JNI */
static void Android_JNI_ThreadDestroyed(void*); static void Android_JNI_ThreadDestroyed(void*);
static void checkJNIReady(void);
/******************************************************************************* /*******************************************************************************
This file links the Java side of Android with libsdl This file links the Java side of Android with libsdl
@ -243,12 +252,14 @@ static jclass mAudioManagerClass;
/* method signatures */ /* method signatures */
static jmethodID midAudioOpen; static jmethodID midAudioOpen;
static jmethodID midAudioWriteShortBuffer;
static jmethodID midAudioWriteByteBuffer; static jmethodID midAudioWriteByteBuffer;
static jmethodID midAudioWriteShortBuffer;
static jmethodID midAudioWriteFloatBuffer;
static jmethodID midAudioClose; static jmethodID midAudioClose;
static jmethodID midCaptureOpen; static jmethodID midCaptureOpen;
static jmethodID midCaptureReadShortBuffer;
static jmethodID midCaptureReadByteBuffer; static jmethodID midCaptureReadByteBuffer;
static jmethodID midCaptureReadShortBuffer;
static jmethodID midCaptureReadFloatBuffer;
static jmethodID midCaptureClose; static jmethodID midCaptureClose;
/* controller manager */ /* controller manager */
@ -392,24 +403,28 @@ JNIEXPORT void JNICALL SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI)(JNIEnv* mEnv, jc
mAudioManagerClass = (jclass)((*mEnv)->NewGlobalRef(mEnv, cls)); mAudioManagerClass = (jclass)((*mEnv)->NewGlobalRef(mEnv, cls));
midAudioOpen = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, midAudioOpen = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
"audioOpen", "(IZZI)I"); "audioOpen", "(IIII)[I");
midAudioWriteShortBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
"audioWriteShortBuffer", "([S)V");
midAudioWriteByteBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, midAudioWriteByteBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
"audioWriteByteBuffer", "([B)V"); "audioWriteByteBuffer", "([B)V");
midAudioWriteShortBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
"audioWriteShortBuffer", "([S)V");
midAudioWriteFloatBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
"audioWriteFloatBuffer", "([F)V");
midAudioClose = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, midAudioClose = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
"audioClose", "()V"); "audioClose", "()V");
midCaptureOpen = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, midCaptureOpen = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
"captureOpen", "(IZZI)I"); "captureOpen", "(IIII)[I");
midCaptureReadShortBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
"captureReadShortBuffer", "([SZ)I");
midCaptureReadByteBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, midCaptureReadByteBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
"captureReadByteBuffer", "([BZ)I"); "captureReadByteBuffer", "([BZ)I");
midCaptureReadShortBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
"captureReadShortBuffer", "([SZ)I");
midCaptureReadFloatBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
"captureReadFloatBuffer", "([FZ)I");
midCaptureClose = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, midCaptureClose = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass,
"captureClose", "()V"); "captureClose", "()V");
if (!midAudioOpen || !midAudioWriteShortBuffer || !midAudioWriteByteBuffer || !midAudioClose || if (!midAudioOpen || !midAudioWriteByteBuffer || !midAudioWriteShortBuffer || !midAudioWriteFloatBuffer || !midAudioClose ||
!midCaptureOpen || !midCaptureReadShortBuffer || !midCaptureReadByteBuffer || !midCaptureClose) { !midCaptureOpen || !midCaptureReadByteBuffer || !midCaptureReadShortBuffer || !midCaptureReadFloatBuffer || !midCaptureClose) {
__android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLAudioManager.java?"); __android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLAudioManager.java?");
} }
@ -430,7 +445,7 @@ JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI)(JNIEnv* mEn
midPollHapticDevices = (*mEnv)->GetStaticMethodID(mEnv, mControllerManagerClass, midPollHapticDevices = (*mEnv)->GetStaticMethodID(mEnv, mControllerManagerClass,
"pollHapticDevices", "()V"); "pollHapticDevices", "()V");
midHapticRun = (*mEnv)->GetStaticMethodID(mEnv, mControllerManagerClass, midHapticRun = (*mEnv)->GetStaticMethodID(mEnv, mControllerManagerClass,
"hapticRun", "(II)V"); "hapticRun", "(IFI)V");
midHapticStop = (*mEnv)->GetStaticMethodID(mEnv, mControllerManagerClass, midHapticStop = (*mEnv)->GetStaticMethodID(mEnv, mControllerManagerClass,
"hapticStop", "(I)V"); "hapticStop", "(I)V");
@ -538,7 +553,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeDropFile)(
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeResize)( JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeResize)(
JNIEnv* env, jclass jcls, JNIEnv* env, jclass jcls,
jint surfaceWidth, jint surfaceHeight, jint surfaceWidth, jint surfaceHeight,
jint deviceWidth, jint deviceHeight, jint format, jfloat rate) jint deviceWidth, jint deviceHeight, jint format, jfloat rate)
{ {
Android_SetScreenResolution(surfaceWidth, surfaceHeight, deviceWidth, deviceHeight, format, rate); Android_SetScreenResolution(surfaceWidth, surfaceHeight, deviceWidth, deviceHeight, format, rate);
} }
@ -1039,17 +1054,19 @@ int Android_JNI_SetupThread(void)
/* /*
* Audio support * Audio support
*/ */
static jboolean audioBuffer16Bit = JNI_FALSE; static int audioBufferFormat = 0;
static jobject audioBuffer = NULL; static jobject audioBuffer = NULL;
static void* audioBufferPinned = NULL; static void* audioBufferPinned = NULL;
static jboolean captureBuffer16Bit = JNI_FALSE; static int captureBufferFormat = 0;
static jobject captureBuffer = NULL; static jobject captureBuffer = NULL;
int Android_JNI_OpenAudioDevice(int iscapture, int sampleRate, int is16Bit, int channelCount, int desiredBufferFrames) int Android_JNI_OpenAudioDevice(int iscapture, SDL_AudioSpec *spec)
{ {
jboolean audioBufferStereo; int audioformat;
int audioBufferFrames; int numBufferFrames;
jobject jbufobj = NULL; jobject jbufobj = NULL;
jobject result;
int *resultElements;
jboolean isCopy; jboolean isCopy;
JNIEnv *env = Android_JNI_GetEnv(); JNIEnv *env = Android_JNI_GetEnv();
@ -1059,74 +1076,123 @@ int Android_JNI_OpenAudioDevice(int iscapture, int sampleRate, int is16Bit, int
} }
Android_JNI_SetupThread(); Android_JNI_SetupThread();
audioBufferStereo = channelCount > 1; switch (spec->format) {
case AUDIO_U8:
audioformat = ENCODING_PCM_8BIT;
break;
case AUDIO_S16:
audioformat = ENCODING_PCM_16BIT;
break;
case AUDIO_F32:
audioformat = ENCODING_PCM_FLOAT;
break;
default:
return SDL_SetError("Unsupported audio format: 0x%x", spec->format);
}
if (iscapture) { if (iscapture) {
__android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device for capture"); __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device for capture");
captureBuffer16Bit = is16Bit; result = (*env)->CallStaticObjectMethod(env, mAudioManagerClass, midCaptureOpen, spec->freq, audioformat, spec->channels, spec->samples);
if ((*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureOpen, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames) != 0) {
/* Error during audio initialization */
__android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: error on AudioRecord initialization!");
return 0;
}
} else { } else {
__android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device for output"); __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device for output");
audioBuffer16Bit = is16Bit; result = (*env)->CallStaticObjectMethod(env, mAudioManagerClass, midAudioOpen, spec->freq, audioformat, spec->channels, spec->samples);
if ((*env)->CallStaticIntMethod(env, mAudioManagerClass, midAudioOpen, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames) != 0) {
/* Error during audio initialization */
__android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: error on AudioTrack initialization!");
return 0;
}
} }
if (result == NULL) {
/* Error during audio initialization, error printed from Java */
return SDL_SetError("Java-side initialization failed");
}
if ((*env)->GetArrayLength(env, (jintArray)result) != 4) {
return SDL_SetError("Unexpected results from Java, expected 4, got %d", (*env)->GetArrayLength(env, (jintArray)result));
}
isCopy = JNI_FALSE;
resultElements = (*env)->GetIntArrayElements(env, (jintArray)result, &isCopy);
spec->freq = resultElements[0];
audioformat = resultElements[1];
switch (audioformat) {
case ENCODING_PCM_8BIT:
spec->format = AUDIO_U8;
break;
case ENCODING_PCM_16BIT:
spec->format = AUDIO_S16;
break;
case ENCODING_PCM_FLOAT:
spec->format = AUDIO_F32;
break;
default:
return SDL_SetError("Unexpected audio format from Java: %d\n", audioformat);
}
spec->channels = resultElements[2];
spec->samples = resultElements[3];
(*env)->ReleaseIntArrayElements(env, (jintArray)result, resultElements, JNI_ABORT);
(*env)->DeleteLocalRef(env, result);
/* Allocating the audio buffer from the Java side and passing it as the return value for audioInit no longer works on /* Allocating the audio buffer from the Java side and passing it as the return value for audioInit no longer works on
* Android >= 4.2 due to a "stale global reference" error. So now we allocate this buffer directly from this side. */ * Android >= 4.2 due to a "stale global reference" error. So now we allocate this buffer directly from this side. */
switch (audioformat) {
if (is16Bit) { case ENCODING_PCM_8BIT:
jshortArray audioBufferLocal = (*env)->NewShortArray(env, desiredBufferFrames * (audioBufferStereo ? 2 : 1)); {
if (audioBufferLocal) { jbyteArray audioBufferLocal = (*env)->NewByteArray(env, spec->samples * spec->channels);
jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal); if (audioBufferLocal) {
(*env)->DeleteLocalRef(env, audioBufferLocal); jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal);
(*env)->DeleteLocalRef(env, audioBufferLocal);
}
} }
} break;
else { case ENCODING_PCM_16BIT:
jbyteArray audioBufferLocal = (*env)->NewByteArray(env, desiredBufferFrames * (audioBufferStereo ? 2 : 1)); {
if (audioBufferLocal) { jshortArray audioBufferLocal = (*env)->NewShortArray(env, spec->samples * spec->channels);
jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal); if (audioBufferLocal) {
(*env)->DeleteLocalRef(env, audioBufferLocal); jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal);
(*env)->DeleteLocalRef(env, audioBufferLocal);
}
} }
break;
case ENCODING_PCM_FLOAT:
{
jfloatArray audioBufferLocal = (*env)->NewFloatArray(env, spec->samples * spec->channels);
if (audioBufferLocal) {
jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal);
(*env)->DeleteLocalRef(env, audioBufferLocal);
}
}
break;
default:
return SDL_SetError("Unexpected audio format from Java: %d\n", audioformat);
} }
if (jbufobj == NULL) { if (jbufobj == NULL) {
__android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: could not allocate an audio buffer!"); __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: could not allocate an audio buffer");
return 0; return SDL_OutOfMemory();
} }
if (iscapture) { if (iscapture) {
captureBufferFormat = audioformat;
captureBuffer = jbufobj; captureBuffer = jbufobj;
} else { } else {
audioBufferFormat = audioformat;
audioBuffer = jbufobj; audioBuffer = jbufobj;
} }
numBufferFrames = (*env)->GetArrayLength(env, (jarray)jbufobj);
isCopy = JNI_FALSE; if (!iscapture) {
isCopy = JNI_FALSE;
if (is16Bit) { switch (audioformat) {
if (!iscapture) { case ENCODING_PCM_8BIT:
audioBufferPinned = (*env)->GetShortArrayElements(env, (jshortArray)audioBuffer, &isCopy);
}
audioBufferFrames = (*env)->GetArrayLength(env, (jshortArray)audioBuffer);
} else {
if (!iscapture) {
audioBufferPinned = (*env)->GetByteArrayElements(env, (jbyteArray)audioBuffer, &isCopy); audioBufferPinned = (*env)->GetByteArrayElements(env, (jbyteArray)audioBuffer, &isCopy);
break;
case ENCODING_PCM_16BIT:
audioBufferPinned = (*env)->GetShortArrayElements(env, (jshortArray)audioBuffer, &isCopy);
break;
case ENCODING_PCM_FLOAT:
audioBufferPinned = (*env)->GetFloatArrayElements(env, (jfloatArray)audioBuffer, &isCopy);
break;
default:
return SDL_SetError("Unexpected audio format from Java: %d\n", audioformat);
} }
audioBufferFrames = (*env)->GetArrayLength(env, (jbyteArray)audioBuffer);
} }
return 0;
if (audioBufferStereo) {
audioBufferFrames /= 2;
}
return audioBufferFrames;
} }
int Android_JNI_GetDisplayDPI(float *ddpi, float *xdpi, float *ydpi) int Android_JNI_GetDisplayDPI(float *ddpi, float *xdpi, float *ydpi)
@ -1170,12 +1236,22 @@ void Android_JNI_WriteAudioBuffer(void)
{ {
JNIEnv *mAudioEnv = Android_JNI_GetEnv(); JNIEnv *mAudioEnv = Android_JNI_GetEnv();
if (audioBuffer16Bit) { switch (audioBufferFormat) {
(*mAudioEnv)->ReleaseShortArrayElements(mAudioEnv, (jshortArray)audioBuffer, (jshort *)audioBufferPinned, JNI_COMMIT); case ENCODING_PCM_8BIT:
(*mAudioEnv)->CallStaticVoidMethod(mAudioEnv, mAudioManagerClass, midAudioWriteShortBuffer, (jshortArray)audioBuffer);
} else {
(*mAudioEnv)->ReleaseByteArrayElements(mAudioEnv, (jbyteArray)audioBuffer, (jbyte *)audioBufferPinned, JNI_COMMIT); (*mAudioEnv)->ReleaseByteArrayElements(mAudioEnv, (jbyteArray)audioBuffer, (jbyte *)audioBufferPinned, JNI_COMMIT);
(*mAudioEnv)->CallStaticVoidMethod(mAudioEnv, mAudioManagerClass, midAudioWriteByteBuffer, (jbyteArray)audioBuffer); (*mAudioEnv)->CallStaticVoidMethod(mAudioEnv, mAudioManagerClass, midAudioWriteByteBuffer, (jbyteArray)audioBuffer);
break;
case ENCODING_PCM_16BIT:
(*mAudioEnv)->ReleaseShortArrayElements(mAudioEnv, (jshortArray)audioBuffer, (jshort *)audioBufferPinned, JNI_COMMIT);
(*mAudioEnv)->CallStaticVoidMethod(mAudioEnv, mAudioManagerClass, midAudioWriteShortBuffer, (jshortArray)audioBuffer);
break;
case ENCODING_PCM_FLOAT:
(*mAudioEnv)->ReleaseFloatArrayElements(mAudioEnv, (jfloatArray)audioBuffer, (jfloat *)audioBufferPinned, JNI_COMMIT);
(*mAudioEnv)->CallStaticVoidMethod(mAudioEnv, mAudioManagerClass, midAudioWriteFloatBuffer, (jfloatArray)audioBuffer);
break;
default:
__android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: unhandled audio buffer format");
break;
} }
/* JNI_COMMIT means the changes are committed to the VM but the buffer remains pinned */ /* JNI_COMMIT means the changes are committed to the VM but the buffer remains pinned */
@ -1187,16 +1263,8 @@ int Android_JNI_CaptureAudioBuffer(void *buffer, int buflen)
jboolean isCopy = JNI_FALSE; jboolean isCopy = JNI_FALSE;
jint br; jint br;
if (captureBuffer16Bit) { switch (captureBufferFormat) {
SDL_assert((*env)->GetArrayLength(env, (jshortArray)captureBuffer) == (buflen / 2)); case ENCODING_PCM_8BIT:
br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_TRUE);
if (br > 0) {
jshort *ptr = (*env)->GetShortArrayElements(env, (jshortArray)captureBuffer, &isCopy);
br *= 2;
SDL_memcpy(buffer, ptr, br);
(*env)->ReleaseShortArrayElements(env, (jshortArray)captureBuffer, (jshort *)ptr, JNI_ABORT);
}
} else {
SDL_assert((*env)->GetArrayLength(env, (jshortArray)captureBuffer) == buflen); SDL_assert((*env)->GetArrayLength(env, (jshortArray)captureBuffer) == buflen);
br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_TRUE); br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_TRUE);
if (br > 0) { if (br > 0) {
@ -1204,27 +1272,75 @@ int Android_JNI_CaptureAudioBuffer(void *buffer, int buflen)
SDL_memcpy(buffer, ptr, br); SDL_memcpy(buffer, ptr, br);
(*env)->ReleaseByteArrayElements(env, (jbyteArray)captureBuffer, (jbyte *)ptr, JNI_ABORT); (*env)->ReleaseByteArrayElements(env, (jbyteArray)captureBuffer, (jbyte *)ptr, JNI_ABORT);
} }
break;
case ENCODING_PCM_16BIT:
SDL_assert((*env)->GetArrayLength(env, (jshortArray)captureBuffer) == (buflen / sizeof(Sint16)));
br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_TRUE);
if (br > 0) {
jshort *ptr = (*env)->GetShortArrayElements(env, (jshortArray)captureBuffer, &isCopy);
br *= sizeof(Sint16);
SDL_memcpy(buffer, ptr, br);
(*env)->ReleaseShortArrayElements(env, (jshortArray)captureBuffer, (jshort *)ptr, JNI_ABORT);
}
break;
case ENCODING_PCM_FLOAT:
SDL_assert((*env)->GetArrayLength(env, (jfloatArray)captureBuffer) == (buflen / sizeof(float)));
br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadFloatBuffer, (jfloatArray)captureBuffer, JNI_TRUE);
if (br > 0) {
jfloat *ptr = (*env)->GetFloatArrayElements(env, (jfloatArray)captureBuffer, &isCopy);
br *= sizeof(float);
SDL_memcpy(buffer, ptr, br);
(*env)->ReleaseFloatArrayElements(env, (jfloatArray)captureBuffer, (jfloat *)ptr, JNI_ABORT);
}
break;
default:
__android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: unhandled capture buffer format");
break;
} }
return br;
return (int) br;
} }
void Android_JNI_FlushCapturedAudio(void) void Android_JNI_FlushCapturedAudio(void)
{ {
JNIEnv *env = Android_JNI_GetEnv(); JNIEnv *env = Android_JNI_GetEnv();
#if 0 /* !!! FIXME: this needs API 23, or it'll do blocking reads and never end. */ #if 0 /* !!! FIXME: this needs API 23, or it'll do blocking reads and never end. */
if (captureBuffer16Bit) { switch (captureBufferFormat) {
const jint len = (*env)->GetArrayLength(env, (jshortArray)captureBuffer); case ENCODING_PCM_8BIT:
while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE) == len) { /* spin */ } {
} else { const jint len = (*env)->GetArrayLength(env, (jbyteArray)captureBuffer);
const jint len = (*env)->GetArrayLength(env, (jbyteArray)captureBuffer); while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_FALSE) == len) { /* spin */ }
while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_FALSE) == len) { /* spin */ } }
break;
case ENCODING_PCM_16BIT:
{
const jint len = (*env)->GetArrayLength(env, (jshortArray)captureBuffer);
while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE) == len) { /* spin */ }
}
break;
case ENCODING_PCM_FLOAT:
{
const jint len = (*env)->GetArrayLength(env, (jfloatArray)captureBuffer);
while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadFloatBuffer, (jfloatArray)captureBuffer, JNI_FALSE) == len) { /* spin */ }
}
break;
default:
__android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: flushing unhandled capture buffer format");
break;
} }
#else #else
if (captureBuffer16Bit) { switch (captureBufferFormat) {
(*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE); case ENCODING_PCM_8BIT:
} else {
(*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_FALSE); (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_FALSE);
break;
case ENCODING_PCM_16BIT:
(*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE);
break;
case ENCODING_PCM_FLOAT:
(*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadFloatBuffer, (jfloatArray)captureBuffer, JNI_FALSE);
break;
default:
__android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: flushing unhandled capture buffer format");
break;
} }
#endif #endif
} }
@ -1890,10 +2006,10 @@ void Android_JNI_PollHapticDevices(void)
(*env)->CallStaticVoidMethod(env, mControllerManagerClass, midPollHapticDevices); (*env)->CallStaticVoidMethod(env, mControllerManagerClass, midPollHapticDevices);
} }
void Android_JNI_HapticRun(int device_id, int length) void Android_JNI_HapticRun(int device_id, float intensity, int length)
{ {
JNIEnv *env = Android_JNI_GetEnv(); JNIEnv *env = Android_JNI_GetEnv();
(*env)->CallStaticVoidMethod(env, mControllerManagerClass, midHapticRun, device_id, length); (*env)->CallStaticVoidMethod(env, mControllerManagerClass, midHapticRun, device_id, intensity, length);
} }
void Android_JNI_HapticStop(int device_id) void Android_JNI_HapticStop(int device_id)

View File

@ -19,6 +19,7 @@
3. This notice may not be removed or altered from any source distribution. 3. This notice may not be removed or altered from any source distribution.
*/ */
#include "../../SDL_internal.h" #include "../../SDL_internal.h"
#include "SDL_system.h"
/* Set up for C function definitions, even when using C++ */ /* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus #ifdef __cplusplus
@ -30,6 +31,7 @@ extern "C" {
#include <EGL/eglplatform.h> #include <EGL/eglplatform.h>
#include <android/native_window_jni.h> #include <android/native_window_jni.h>
#include "SDL_audio.h"
#include "SDL_rect.h" #include "SDL_rect.h"
/* Interface from the SDL library into the Android Java activity */ /* Interface from the SDL library into the Android Java activity */
@ -46,13 +48,17 @@ extern ANativeWindow* Android_JNI_GetNativeWindow(void);
extern int Android_JNI_GetDisplayDPI(float *ddpi, float *xdpi, float *ydpi); extern int Android_JNI_GetDisplayDPI(float *ddpi, float *xdpi, float *ydpi);
/* Audio support */ /* Audio support */
extern int Android_JNI_OpenAudioDevice(int iscapture, int sampleRate, int is16Bit, int channelCount, int desiredBufferFrames); extern int Android_JNI_OpenAudioDevice(int iscapture, SDL_AudioSpec *spec);
extern void* Android_JNI_GetAudioBuffer(void); extern void* Android_JNI_GetAudioBuffer(void);
extern void Android_JNI_WriteAudioBuffer(void); extern void Android_JNI_WriteAudioBuffer(void);
extern int Android_JNI_CaptureAudioBuffer(void *buffer, int buflen); extern int Android_JNI_CaptureAudioBuffer(void *buffer, int buflen);
extern void Android_JNI_FlushCapturedAudio(void); extern void Android_JNI_FlushCapturedAudio(void);
extern void Android_JNI_CloseAudioDevice(const int iscapture); extern void Android_JNI_CloseAudioDevice(const int iscapture);
/* Detecting device type */
extern SDL_bool Android_IsDeXMode();
extern SDL_bool Android_IsChromebook();
#include "SDL_rwops.h" #include "SDL_rwops.h"
int Android_JNI_FileOpen(SDL_RWops* ctx, const char* fileName, const char* mode); int Android_JNI_FileOpen(SDL_RWops* ctx, const char* fileName, const char* mode);
@ -78,15 +84,16 @@ void Android_JNI_PollInputDevices(void);
/* Haptic support */ /* Haptic support */
void Android_JNI_PollHapticDevices(void); void Android_JNI_PollHapticDevices(void);
void Android_JNI_HapticRun(int device_id, int length); void Android_JNI_HapticRun(int device_id, float intensity, int length);
void Android_JNI_HapticStop(int device_id); void Android_JNI_HapticStop(int device_id);
/* Video */ /* Video */
void Android_JNI_SuspendScreenSaver(SDL_bool suspend); void Android_JNI_SuspendScreenSaver(SDL_bool suspend);
/* Touch support */ /* Touch support */
int Android_JNI_GetTouchDeviceIds(int **ids); int Android_JNI_InitTouch(void);
void Android_JNI_SetSeparateMouseAndTouch(SDL_bool new_value); void Android_JNI_SetSeparateMouseAndTouch(SDL_bool new_value);
int Android_JNI_GetTouchDeviceIds(int **ids);
/* Threads */ /* Threads */
#include <jni.h> #include <jni.h>
@ -109,9 +116,15 @@ SDL_bool Android_JNI_SetCustomCursor(int cursorID);
SDL_bool Android_JNI_SetSystemCursor(int cursorID); SDL_bool Android_JNI_SetSystemCursor(int cursorID);
/* Relative mouse support */ /* Relative mouse support */
SDL_bool Android_JNI_SupportsRelativeMouse(); SDL_bool Android_JNI_SupportsRelativeMouse(void);
SDL_bool Android_JNI_SetRelativeMouseEnabled(SDL_bool enabled); SDL_bool Android_JNI_SetRelativeMouseEnabled(SDL_bool enabled);
SDL_bool SDL_IsAndroidTablet(void);
SDL_bool SDL_IsAndroidTV(void);
SDL_bool SDL_IsChromebook(void);
SDL_bool SDL_IsDeXMode(void);
/* Ends C function definitions when using C++ */ /* Ends C function definitions when using C++ */
#ifdef __cplusplus #ifdef __cplusplus
/* *INDENT-OFF* */ /* *INDENT-OFF* */

View File

@ -39,9 +39,8 @@ typedef struct SDL_DBusContext {
void (*bus_add_match)(DBusConnection *, const char *, DBusError *); void (*bus_add_match)(DBusConnection *, const char *, DBusError *);
DBusConnection * (*connection_open_private)(const char *, DBusError *); DBusConnection * (*connection_open_private)(const char *, DBusError *);
void (*connection_set_exit_on_disconnect)(DBusConnection *, dbus_bool_t); void (*connection_set_exit_on_disconnect)(DBusConnection *, dbus_bool_t);
dbus_bool_t (*connection_get_is_connected)(DBusConnection *); dbus_bool_t (*connection_get_is_connected)(DBusConnection *);
dbus_bool_t (*connection_add_filter)(DBusConnection *, DBusHandleMessageFunction, dbus_bool_t (*connection_add_filter)(DBusConnection *, DBusHandleMessageFunction, void *, DBusFreeFunction);
void *, DBusFreeFunction);
dbus_bool_t (*connection_try_register_object_path)(DBusConnection *, const char *, dbus_bool_t (*connection_try_register_object_path)(DBusConnection *, const char *,
const DBusObjectPathVTable *, void *, DBusError *); const DBusObjectPathVTable *, void *, DBusError *);
dbus_bool_t (*connection_send)(DBusConnection *, DBusMessage *, dbus_uint32_t *); dbus_bool_t (*connection_send)(DBusConnection *, DBusMessage *, dbus_uint32_t *);
@ -51,7 +50,7 @@ typedef struct SDL_DBusContext {
void (*connection_flush)(DBusConnection *); void (*connection_flush)(DBusConnection *);
dbus_bool_t (*connection_read_write)(DBusConnection *, int); dbus_bool_t (*connection_read_write)(DBusConnection *, int);
DBusDispatchStatus (*connection_dispatch)(DBusConnection *); DBusDispatchStatus (*connection_dispatch)(DBusConnection *);
dbus_bool_t (*message_is_signal)(DBusMessage *, const char *, const char *); dbus_bool_t (*message_is_signal)(DBusMessage *, const char *, const char *);
DBusMessage *(*message_new_method_call)(const char *, const char *, const char *, const char *); DBusMessage *(*message_new_method_call)(const char *, const char *, const char *, const char *);
dbus_bool_t (*message_append_args)(DBusMessage *, int, ...); dbus_bool_t (*message_append_args)(DBusMessage *, int, ...);
dbus_bool_t (*message_append_args_valist)(DBusMessage *, int, va_list); dbus_bool_t (*message_append_args_valist)(DBusMessage *, int, va_list);
@ -61,7 +60,7 @@ typedef struct SDL_DBusContext {
dbus_bool_t (*message_iter_next)(DBusMessageIter *); dbus_bool_t (*message_iter_next)(DBusMessageIter *);
void (*message_iter_get_basic)(DBusMessageIter *, void *); void (*message_iter_get_basic)(DBusMessageIter *, void *);
int (*message_iter_get_arg_type)(DBusMessageIter *); int (*message_iter_get_arg_type)(DBusMessageIter *);
void (*message_iter_recurse)(DBusMessageIter *, DBusMessageIter *); void (*message_iter_recurse)(DBusMessageIter *, DBusMessageIter *);
void (*message_unref)(DBusMessage *); void (*message_unref)(DBusMessage *);
void (*error_init)(DBusError *); void (*error_init)(DBusError *);
dbus_bool_t (*error_is_set)(const DBusError *); dbus_bool_t (*error_is_set)(const DBusError *);

View File

@ -198,7 +198,7 @@ static SDL_EVDEV_keyboard_state * kbd_cleanup_state = NULL;
static int kbd_cleanup_sigactions_installed = 0; static int kbd_cleanup_sigactions_installed = 0;
static int kbd_cleanup_atexit_installed = 0; static int kbd_cleanup_atexit_installed = 0;
static struct sigaction old_sigaction[NSIG] = { 0 }; static struct sigaction old_sigaction[NSIG];
static int fatal_signals[] = static int fatal_signals[] =
{ {
@ -510,17 +510,19 @@ static unsigned int handle_diacr(SDL_EVDEV_keyboard_state *kbd, unsigned int ch)
static int vc_kbd_led(SDL_EVDEV_keyboard_state *kbd, int flag) static int vc_kbd_led(SDL_EVDEV_keyboard_state *kbd, int flag)
{ {
return ((kbd->ledflagstate >> flag) & 1); return (kbd->ledflagstate & flag) != 0;
} }
static void set_vc_kbd_led(SDL_EVDEV_keyboard_state *kbd, int flag) static void set_vc_kbd_led(SDL_EVDEV_keyboard_state *kbd, int flag)
{ {
kbd->ledflagstate |= 1 << flag; kbd->ledflagstate |= flag;
ioctl(kbd->console_fd, KDSETLED, (unsigned long)(kbd->ledflagstate));
} }
static void clr_vc_kbd_led(SDL_EVDEV_keyboard_state *kbd, int flag) static void clr_vc_kbd_led(SDL_EVDEV_keyboard_state *kbd, int flag)
{ {
kbd->ledflagstate &= ~(1 << flag); kbd->ledflagstate &= ~flag;
ioctl(kbd->console_fd, KDSETLED, (unsigned long)(kbd->ledflagstate));
} }
static void chg_vc_kbd_lock(SDL_EVDEV_keyboard_state *kbd, int flag) static void chg_vc_kbd_lock(SDL_EVDEV_keyboard_state *kbd, int flag)
@ -535,7 +537,8 @@ static void chg_vc_kbd_slock(SDL_EVDEV_keyboard_state *kbd, int flag)
static void chg_vc_kbd_led(SDL_EVDEV_keyboard_state *kbd, int flag) static void chg_vc_kbd_led(SDL_EVDEV_keyboard_state *kbd, int flag)
{ {
kbd->ledflagstate ^= 1 << flag; kbd->ledflagstate ^= flag;
ioctl(kbd->console_fd, KDSETLED, (unsigned long)(kbd->ledflagstate));
} }
/* /*

View File

@ -19,6 +19,9 @@
3. This notice may not be removed or altered from any source distribution. 3. This notice may not be removed or altered from any source distribution.
*/ */
#ifndef SDL_evdev_kbd_h_
#define SDL_evdev_kbd_h_
struct SDL_EVDEV_keyboard_state; struct SDL_EVDEV_keyboard_state;
typedef struct SDL_EVDEV_keyboard_state SDL_EVDEV_keyboard_state; typedef struct SDL_EVDEV_keyboard_state SDL_EVDEV_keyboard_state;
@ -26,4 +29,6 @@ extern SDL_EVDEV_keyboard_state *SDL_EVDEV_kbd_init(void);
extern void SDL_EVDEV_kbd_keycode(SDL_EVDEV_keyboard_state *state, unsigned int keycode, int down); extern void SDL_EVDEV_kbd_keycode(SDL_EVDEV_keyboard_state *state, unsigned int keycode, int down);
extern void SDL_EVDEV_kbd_quit(SDL_EVDEV_keyboard_state *state); extern void SDL_EVDEV_kbd_quit(SDL_EVDEV_keyboard_state *state);
#endif /* SDL_evdev_kbd_h_ */
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */

View File

@ -63,7 +63,7 @@ SDL_UDEV_load_syms(void)
{ {
/* cast funcs to char* first, to please GCC's strict aliasing rules. */ /* cast funcs to char* first, to please GCC's strict aliasing rules. */
#define SDL_UDEV_SYM(x) \ #define SDL_UDEV_SYM(x) \
if (!SDL_UDEV_load_sym(#x, (void **) (char *) & _this->x)) return -1 if (!SDL_UDEV_load_sym(#x, (void **) (char *) & _this->syms.x)) return -1
SDL_UDEV_SYM(udev_device_get_action); SDL_UDEV_SYM(udev_device_get_action);
SDL_UDEV_SYM(udev_device_get_devnode); SDL_UDEV_SYM(udev_device_get_devnode);
@ -100,7 +100,7 @@ static SDL_bool
SDL_UDEV_hotplug_update_available(void) SDL_UDEV_hotplug_update_available(void)
{ {
if (_this->udev_mon != NULL) { if (_this->udev_mon != NULL) {
const int fd = _this->udev_monitor_get_fd(_this->udev_mon); const int fd = _this->syms.udev_monitor_get_fd(_this->udev_mon);
if (SDL_IOReady(fd, SDL_FALSE, 0)) { if (SDL_IOReady(fd, SDL_FALSE, 0)) {
return SDL_TRUE; return SDL_TRUE;
} }
@ -130,21 +130,21 @@ SDL_UDEV_Init(void)
* Listen for input devices (mouse, keyboard, joystick, etc) and sound devices * Listen for input devices (mouse, keyboard, joystick, etc) and sound devices
*/ */
_this->udev = _this->udev_new(); _this->udev = _this->syms.udev_new();
if (_this->udev == NULL) { if (_this->udev == NULL) {
SDL_UDEV_Quit(); SDL_UDEV_Quit();
return SDL_SetError("udev_new() failed"); return SDL_SetError("udev_new() failed");
} }
_this->udev_mon = _this->udev_monitor_new_from_netlink(_this->udev, "udev"); _this->udev_mon = _this->syms.udev_monitor_new_from_netlink(_this->udev, "udev");
if (_this->udev_mon == NULL) { if (_this->udev_mon == NULL) {
SDL_UDEV_Quit(); SDL_UDEV_Quit();
return SDL_SetError("udev_monitor_new_from_netlink() failed"); return SDL_SetError("udev_monitor_new_from_netlink() failed");
} }
_this->udev_monitor_filter_add_match_subsystem_devtype(_this->udev_mon, "input", NULL); _this->syms.udev_monitor_filter_add_match_subsystem_devtype(_this->udev_mon, "input", NULL);
_this->udev_monitor_filter_add_match_subsystem_devtype(_this->udev_mon, "sound", NULL); _this->syms.udev_monitor_filter_add_match_subsystem_devtype(_this->udev_mon, "sound", NULL);
_this->udev_monitor_enable_receiving(_this->udev_mon); _this->syms.udev_monitor_enable_receiving(_this->udev_mon);
/* Do an initial scan of existing devices */ /* Do an initial scan of existing devices */
SDL_UDEV_Scan(); SDL_UDEV_Scan();
@ -170,11 +170,11 @@ SDL_UDEV_Quit(void)
if (_this->ref_count < 1) { if (_this->ref_count < 1) {
if (_this->udev_mon != NULL) { if (_this->udev_mon != NULL) {
_this->udev_monitor_unref(_this->udev_mon); _this->syms.udev_monitor_unref(_this->udev_mon);
_this->udev_mon = NULL; _this->udev_mon = NULL;
} }
if (_this->udev != NULL) { if (_this->udev != NULL) {
_this->udev_unref(_this->udev); _this->syms.udev_unref(_this->udev);
_this->udev = NULL; _this->udev = NULL;
} }
@ -202,28 +202,28 @@ SDL_UDEV_Scan(void)
return; return;
} }
enumerate = _this->udev_enumerate_new(_this->udev); enumerate = _this->syms.udev_enumerate_new(_this->udev);
if (enumerate == NULL) { if (enumerate == NULL) {
SDL_UDEV_Quit(); SDL_UDEV_Quit();
SDL_SetError("udev_enumerate_new() failed"); SDL_SetError("udev_enumerate_new() failed");
return; return;
} }
_this->udev_enumerate_add_match_subsystem(enumerate, "input"); _this->syms.udev_enumerate_add_match_subsystem(enumerate, "input");
_this->udev_enumerate_add_match_subsystem(enumerate, "sound"); _this->syms.udev_enumerate_add_match_subsystem(enumerate, "sound");
_this->udev_enumerate_scan_devices(enumerate); _this->syms.udev_enumerate_scan_devices(enumerate);
devs = _this->udev_enumerate_get_list_entry(enumerate); devs = _this->syms.udev_enumerate_get_list_entry(enumerate);
for (item = devs; item; item = _this->udev_list_entry_get_next(item)) { for (item = devs; item; item = _this->syms.udev_list_entry_get_next(item)) {
const char *path = _this->udev_list_entry_get_name(item); const char *path = _this->syms.udev_list_entry_get_name(item);
struct udev_device *dev = _this->udev_device_new_from_syspath(_this->udev, path); struct udev_device *dev = _this->syms.udev_device_new_from_syspath(_this->udev, path);
if (dev != NULL) { if (dev != NULL) {
device_event(SDL_UDEV_DEVICEADDED, dev); device_event(SDL_UDEV_DEVICEADDED, dev);
_this->udev_device_unref(dev); _this->syms.udev_device_unref(dev);
} }
} }
_this->udev_enumerate_unref(enumerate); _this->syms.udev_enumerate_unref(enumerate);
} }
@ -305,7 +305,7 @@ static void get_caps(struct udev_device *dev, struct udev_device *pdev, const ch
unsigned long v; unsigned long v;
SDL_memset(bitmask, 0, bitmask_len*sizeof(*bitmask)); SDL_memset(bitmask, 0, bitmask_len*sizeof(*bitmask));
value = _this->udev_device_get_sysattr_value(pdev, attr); value = _this->syms.udev_device_get_sysattr_value(pdev, attr);
if (!value) { if (!value) {
return; return;
} }
@ -340,8 +340,8 @@ guess_device_class(struct udev_device *dev)
/* walk up the parental chain until we find the real input device; the /* walk up the parental chain until we find the real input device; the
* argument is very likely a subdevice of this, like eventN */ * argument is very likely a subdevice of this, like eventN */
pdev = dev; pdev = dev;
while (pdev && !_this->udev_device_get_sysattr_value(pdev, "capabilities/ev")) { while (pdev && !_this->syms.udev_device_get_sysattr_value(pdev, "capabilities/ev")) {
pdev = _this->udev_device_get_parent_with_subsystem_devtype(pdev, "input", NULL); pdev = _this->syms.udev_device_get_parent_with_subsystem_devtype(pdev, "input", NULL);
} }
if (!pdev) { if (!pdev) {
return 0; return 0;
@ -405,28 +405,28 @@ device_event(SDL_UDEV_deviceevent type, struct udev_device *dev)
const char *path; const char *path;
SDL_UDEV_CallbackList *item; SDL_UDEV_CallbackList *item;
path = _this->udev_device_get_devnode(dev); path = _this->syms.udev_device_get_devnode(dev);
if (path == NULL) { if (path == NULL) {
return; return;
} }
subsystem = _this->udev_device_get_subsystem(dev); subsystem = _this->syms.udev_device_get_subsystem(dev);
if (SDL_strcmp(subsystem, "sound") == 0) { if (SDL_strcmp(subsystem, "sound") == 0) {
devclass = SDL_UDEV_DEVICE_SOUND; devclass = SDL_UDEV_DEVICE_SOUND;
} else if (SDL_strcmp(subsystem, "input") == 0) { } else if (SDL_strcmp(subsystem, "input") == 0) {
/* udev rules reference: http://cgit.freedesktop.org/systemd/systemd/tree/src/udev/udev-builtin-input_id.c */ /* udev rules reference: http://cgit.freedesktop.org/systemd/systemd/tree/src/udev/udev-builtin-input_id.c */
val = _this->udev_device_get_property_value(dev, "ID_INPUT_JOYSTICK"); val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_JOYSTICK");
if (val != NULL && SDL_strcmp(val, "1") == 0 ) { if (val != NULL && SDL_strcmp(val, "1") == 0 ) {
devclass |= SDL_UDEV_DEVICE_JOYSTICK; devclass |= SDL_UDEV_DEVICE_JOYSTICK;
} }
val = _this->udev_device_get_property_value(dev, "ID_INPUT_MOUSE"); val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_MOUSE");
if (val != NULL && SDL_strcmp(val, "1") == 0 ) { if (val != NULL && SDL_strcmp(val, "1") == 0 ) {
devclass |= SDL_UDEV_DEVICE_MOUSE; devclass |= SDL_UDEV_DEVICE_MOUSE;
} }
val = _this->udev_device_get_property_value(dev, "ID_INPUT_TOUCHSCREEN"); val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_TOUCHSCREEN");
if (val != NULL && SDL_strcmp(val, "1") == 0 ) { if (val != NULL && SDL_strcmp(val, "1") == 0 ) {
devclass |= SDL_UDEV_DEVICE_TOUCHSCREEN; devclass |= SDL_UDEV_DEVICE_TOUCHSCREEN;
} }
@ -437,14 +437,14 @@ device_event(SDL_UDEV_deviceevent type, struct udev_device *dev)
Ref: http://cgit.freedesktop.org/systemd/systemd/tree/src/udev/udev-builtin-input_id.c#n183 Ref: http://cgit.freedesktop.org/systemd/systemd/tree/src/udev/udev-builtin-input_id.c#n183
*/ */
val = _this->udev_device_get_property_value(dev, "ID_INPUT_KEY"); val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_KEY");
if (val != NULL && SDL_strcmp(val, "1") == 0 ) { if (val != NULL && SDL_strcmp(val, "1") == 0 ) {
devclass |= SDL_UDEV_DEVICE_KEYBOARD; devclass |= SDL_UDEV_DEVICE_KEYBOARD;
} }
if (devclass == 0) { if (devclass == 0) {
/* Fall back to old style input classes */ /* Fall back to old style input classes */
val = _this->udev_device_get_property_value(dev, "ID_CLASS"); val = _this->syms.udev_device_get_property_value(dev, "ID_CLASS");
if (val != NULL) { if (val != NULL) {
if (SDL_strcmp(val, "joystick") == 0) { if (SDL_strcmp(val, "joystick") == 0) {
devclass = SDL_UDEV_DEVICE_JOYSTICK; devclass = SDL_UDEV_DEVICE_JOYSTICK;
@ -481,11 +481,11 @@ SDL_UDEV_Poll(void)
} }
while (SDL_UDEV_hotplug_update_available()) { while (SDL_UDEV_hotplug_update_available()) {
dev = _this->udev_monitor_receive_device(_this->udev_mon); dev = _this->syms.udev_monitor_receive_device(_this->udev_mon);
if (dev == NULL) { if (dev == NULL) {
break; break;
} }
action = _this->udev_device_get_action(dev); action = _this->syms.udev_device_get_action(dev);
if (SDL_strcmp(action, "add") == 0) { if (SDL_strcmp(action, "add") == 0) {
/* Wait for the device to finish initialization */ /* Wait for the device to finish initialization */
@ -496,7 +496,7 @@ SDL_UDEV_Poll(void)
device_event(SDL_UDEV_DEVICEREMOVED, dev); device_event(SDL_UDEV_DEVICEREMOVED, dev);
} }
_this->udev_device_unref(dev); _this->syms.udev_device_unref(dev);
} }
} }
@ -547,6 +547,22 @@ SDL_UDEV_DelCallback(SDL_UDEV_Callback cb)
} }
const SDL_UDEV_Symbols *
SDL_UDEV_GetUdevSyms(void)
{
if (SDL_UDEV_Init() < 0) {
SDL_SetError("Could not initialize UDEV");
return NULL;
}
return &_this->syms;
}
void
SDL_UDEV_ReleaseUdevSyms(void)
{
SDL_UDEV_Quit();
}
#endif /* SDL_USE_LIBUDEV */ #endif /* SDL_USE_LIBUDEV */

View File

@ -64,22 +64,13 @@ typedef struct SDL_UDEV_CallbackList {
struct SDL_UDEV_CallbackList *next; struct SDL_UDEV_CallbackList *next;
} SDL_UDEV_CallbackList; } SDL_UDEV_CallbackList;
typedef struct SDL_UDEV_PrivateData typedef struct SDL_UDEV_Symbols {
{
const char *udev_library;
void *udev_handle;
struct udev *udev;
struct udev_monitor *udev_mon;
int ref_count;
SDL_UDEV_CallbackList *first, *last;
/* Function pointers */
const char *(*udev_device_get_action)(struct udev_device *); const char *(*udev_device_get_action)(struct udev_device *);
const char *(*udev_device_get_devnode)(struct udev_device *); const char *(*udev_device_get_devnode)(struct udev_device *);
const char *(*udev_device_get_subsystem)(struct udev_device *); const char *(*udev_device_get_subsystem)(struct udev_device *);
struct udev_device *(*udev_device_get_parent_with_subsystem_devtype)(struct udev_device *udev_device, const char *subsystem, const char *devtype); struct udev_device *(*udev_device_get_parent_with_subsystem_devtype)(struct udev_device *udev_device, const char *subsystem, const char *devtype);
const char *(*udev_device_get_property_value)(struct udev_device *, const char *); const char *(*udev_device_get_property_value)(struct udev_device *, const char *);
const char *(*udev_device_get_sysattr_value)(struct udev_device *udev_device, const char *sysattr); const char *(*udev_device_get_sysattr_value)(struct udev_device *udev_device, const char *sysattr);
struct udev_device *(*udev_device_new_from_syspath)(struct udev *, const char *); struct udev_device *(*udev_device_new_from_syspath)(struct udev *, const char *);
void (*udev_device_unref)(struct udev_device *); void (*udev_device_unref)(struct udev_device *);
int (*udev_enumerate_add_match_property)(struct udev_enumerate *, const char *, const char *); int (*udev_enumerate_add_match_property)(struct udev_enumerate *, const char *, const char *);
@ -100,6 +91,19 @@ typedef struct SDL_UDEV_PrivateData
void (*udev_unref)(struct udev *); void (*udev_unref)(struct udev *);
struct udev_device * (*udev_device_new_from_devnum)(struct udev *udev, char type, dev_t devnum); struct udev_device * (*udev_device_new_from_devnum)(struct udev *udev, char type, dev_t devnum);
dev_t (*udev_device_get_devnum) (struct udev_device *udev_device); dev_t (*udev_device_get_devnum) (struct udev_device *udev_device);
} SDL_UDEV_Symbols;
typedef struct SDL_UDEV_PrivateData
{
const char *udev_library;
void *udev_handle;
struct udev *udev;
struct udev_monitor *udev_mon;
int ref_count;
SDL_UDEV_CallbackList *first, *last;
/* Function pointers */
SDL_UDEV_Symbols syms;
} SDL_UDEV_PrivateData; } SDL_UDEV_PrivateData;
extern int SDL_UDEV_Init(void); extern int SDL_UDEV_Init(void);
@ -110,8 +114,8 @@ extern void SDL_UDEV_Poll(void);
extern void SDL_UDEV_Scan(void); extern void SDL_UDEV_Scan(void);
extern int SDL_UDEV_AddCallback(SDL_UDEV_Callback cb); extern int SDL_UDEV_AddCallback(SDL_UDEV_Callback cb);
extern void SDL_UDEV_DelCallback(SDL_UDEV_Callback cb); extern void SDL_UDEV_DelCallback(SDL_UDEV_Callback cb);
extern const SDL_UDEV_Symbols *SDL_UDEV_GetUdevSyms(void);
extern void SDL_UDEV_ReleaseUdevSyms(void);
#endif /* HAVE_LIBUDEV_H */ #endif /* HAVE_LIBUDEV_H */

View File

@ -44,7 +44,7 @@ SDL_bool WINRT_XAMLWasEnabled = SDL_FALSE;
#if WINAPI_FAMILY == WINAPI_FAMILY_APP #if WINAPI_FAMILY == WINAPI_FAMILY_APP
extern "C" extern "C"
ISwapChainBackgroundPanelNative * WINRT_GlobalSwapChainBackgroundPanelNative = NULL; ISwapChainBackgroundPanelNative * WINRT_GlobalSwapChainBackgroundPanelNative = NULL;
static Windows::Foundation::EventRegistrationToken WINRT_XAMLAppEventToken; static Windows::Foundation::EventRegistrationToken WINRT_XAMLAppEventToken;
#endif #endif

View File

@ -22,6 +22,7 @@
#include "SDL_config.h" #include "SDL_config.h"
#else #else
#include "../SDL_internal.h" #include "../SDL_internal.h"
#include "SDL_simd.h"
#endif #endif
#if defined(__WIN32__) #if defined(__WIN32__)

View File

@ -27,6 +27,7 @@
#if defined(__OS2__) #if defined(__OS2__)
#define INCL_DOS #define INCL_DOS
#define INCL_DOSERRORS #define INCL_DOSERRORS
#include <os2.h>
#include <dos.h> #include <dos.h>
#endif #endif

View File

@ -696,6 +696,11 @@
#define SDL_SensorUpdate SDL_SensorUpdate_REAL #define SDL_SensorUpdate SDL_SensorUpdate_REAL
#define SDL_IsTablet SDL_IsTablet_REAL #define SDL_IsTablet SDL_IsTablet_REAL
#define SDL_GetDisplayOrientation SDL_GetDisplayOrientation_REAL #define SDL_GetDisplayOrientation SDL_GetDisplayOrientation_REAL
#define SDL_HasColorKey SDL_HasColorKey_REAL
#define SDL_CreateThreadWithStackSize SDL_CreateThreadWithStackSize_REAL
#define SDL_JoystickGetDevicePlayerIndex SDL_JoystickGetDevicePlayerIndex_REAL
#define SDL_JoystickGetPlayerIndex SDL_JoystickGetPlayerIndex_REAL
#define SDL_GameControllerGetPlayerIndex SDL_GameControllerGetPlayerIndex_REAL
#define SDL_RenderFlush SDL_RenderFlush_REAL #define SDL_RenderFlush SDL_RenderFlush_REAL
#define SDL_RenderDrawPointF SDL_RenderDrawPointF_REAL #define SDL_RenderDrawPointF SDL_RenderDrawPointF_REAL
#define SDL_RenderDrawPointsF SDL_RenderDrawPointsF_REAL #define SDL_RenderDrawPointsF SDL_RenderDrawPointsF_REAL

View File

@ -738,6 +738,23 @@ SDL_DYNAPI_PROC(void,SDL_SensorClose,(SDL_Sensor *a),(a),)
SDL_DYNAPI_PROC(void,SDL_SensorUpdate,(void),(),) SDL_DYNAPI_PROC(void,SDL_SensorUpdate,(void),(),)
SDL_DYNAPI_PROC(SDL_bool,SDL_IsTablet,(void),(),return) SDL_DYNAPI_PROC(SDL_bool,SDL_IsTablet,(void),(),return)
SDL_DYNAPI_PROC(SDL_DisplayOrientation,SDL_GetDisplayOrientation,(int a),(a),return) SDL_DYNAPI_PROC(SDL_DisplayOrientation,SDL_GetDisplayOrientation,(int a),(a),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_HasColorKey,(SDL_Surface *a),(a),return)
#ifdef SDL_CreateThreadWithStackSize
#undef SDL_CreateThreadWithStackSize
#endif
#if defined(__WIN32__) && !defined(HAVE_LIBC)
SDL_DYNAPI_PROC(SDL_Thread*,SDL_CreateThreadWithStackSize,(SDL_ThreadFunction a, const char *b, const size_t c, void *d, pfnSDL_CurrentBeginThread e, pfnSDL_CurrentEndThread f),(a,b,c,d,e,f),return)
#elif defined(__OS2__)
SDL_DYNAPI_PROC(SDL_Thread*,SDL_CreateThreadWithStackSize,(SDL_ThreadFunction a, const char *b, const size_t c, void *d, pfnSDL_CurrentBeginThread e, pfnSDL_CurrentEndThread f),(a,b,c,d,e,f),return)
#else
SDL_DYNAPI_PROC(SDL_Thread*,SDL_CreateThreadWithStackSize,(SDL_ThreadFunction a, const char *b, const size_t c, void *d),(a,b,c,d),return)
#endif
SDL_DYNAPI_PROC(int,SDL_JoystickGetDevicePlayerIndex,(int a),(a),return)
SDL_DYNAPI_PROC(int,SDL_JoystickGetPlayerIndex,(SDL_Joystick *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_GameControllerGetPlayerIndex,(SDL_GameController *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_RenderFlush,(SDL_Renderer *a),(a),return) SDL_DYNAPI_PROC(int,SDL_RenderFlush,(SDL_Renderer *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_RenderDrawPointF,(SDL_Renderer *a, float b, float c),(a,b,c),return) SDL_DYNAPI_PROC(int,SDL_RenderDrawPointF,(SDL_Renderer *a, float b, float c),(a,b,c),return)
SDL_DYNAPI_PROC(int,SDL_RenderDrawPointsF,(SDL_Renderer *a, const SDL_FPoint *b, int c),(a,b,c),return) SDL_DYNAPI_PROC(int,SDL_RenderDrawPointsF,(SDL_Renderer *a, const SDL_FPoint *b, int c),(a,b,c),return)

View File

@ -417,8 +417,10 @@ SDL_StartEventLoop(void)
SDL_EventState(SDL_TEXTINPUT, SDL_DISABLE); SDL_EventState(SDL_TEXTINPUT, SDL_DISABLE);
SDL_EventState(SDL_TEXTEDITING, SDL_DISABLE); SDL_EventState(SDL_TEXTEDITING, SDL_DISABLE);
SDL_EventState(SDL_SYSWMEVENT, SDL_DISABLE); SDL_EventState(SDL_SYSWMEVENT, SDL_DISABLE);
#if 0 /* Leave these events enabled so apps can respond to items being dragged onto them at startup */
SDL_EventState(SDL_DROPFILE, SDL_DISABLE); SDL_EventState(SDL_DROPFILE, SDL_DISABLE);
SDL_EventState(SDL_DROPTEXT, SDL_DISABLE); SDL_EventState(SDL_DROPTEXT, SDL_DISABLE);
#endif
SDL_AtomicSet(&SDL_EventQ.active, 1); SDL_AtomicSet(&SDL_EventQ.active, 1);

View File

@ -18,6 +18,10 @@
misrepresented as being the original software. misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution. 3. This notice may not be removed or altered from any source distribution.
*/ */
#ifndef SDL_events_c_h_
#define SDL_events_c_h_
#include "../SDL_internal.h" #include "../SDL_internal.h"
/* Useful functions and variables from SDL_events.c */ /* Useful functions and variables from SDL_events.c */
@ -49,4 +53,6 @@ extern void SDL_QuitQuit(void);
extern void SDL_SendPendingQuit(void); extern void SDL_SendPendingQuit(void);
#endif /* SDL_events_c_h_ */
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */

View File

@ -33,12 +33,38 @@
/* The mouse state */ /* The mouse state */
static SDL_Mouse SDL_mouse; static SDL_Mouse SDL_mouse;
static Uint32 SDL_double_click_time = 500;
static int SDL_double_click_radius = 1;
static int static int
SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relative, int x, int y); SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relative, int x, int y);
static void SDLCALL
SDL_MouseDoubleClickTimeChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
SDL_Mouse *mouse = (SDL_Mouse *)userdata;
if (hint && *hint) {
mouse->double_click_time = SDL_atoi(hint);
} else {
#ifdef __WIN32__
mouse->double_click_time = GetDoubleClickTime();
#else
mouse->double_click_time = 500;
#endif
}
}
static void SDLCALL
SDL_MouseDoubleClickRadiusChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
SDL_Mouse *mouse = (SDL_Mouse *)userdata;
if (hint && *hint) {
mouse->double_click_radius = SDL_atoi(hint);
} else {
mouse->double_click_radius = 32; /* 32 pixels seems about right for touch interfaces */
}
}
static void SDLCALL static void SDLCALL
SDL_MouseNormalSpeedScaleChanged(void *userdata, const char *name, const char *oldValue, const char *hint) SDL_MouseNormalSpeedScaleChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{ {
@ -83,6 +109,12 @@ SDL_MouseInit(void)
SDL_zerop(mouse); SDL_zerop(mouse);
SDL_AddHintCallback(SDL_HINT_MOUSE_DOUBLE_CLICK_TIME,
SDL_MouseDoubleClickTimeChanged, mouse);
SDL_AddHintCallback(SDL_HINT_MOUSE_DOUBLE_CLICK_RADIUS,
SDL_MouseDoubleClickRadiusChanged, mouse);
SDL_AddHintCallback(SDL_HINT_MOUSE_NORMAL_SPEED_SCALE, SDL_AddHintCallback(SDL_HINT_MOUSE_NORMAL_SPEED_SCALE,
SDL_MouseNormalSpeedScaleChanged, mouse); SDL_MouseNormalSpeedScaleChanged, mouse);
@ -114,12 +146,6 @@ SDL_GetMouse(void)
return &SDL_mouse; return &SDL_mouse;
} }
void
SDL_SetDoubleClickTime(Uint32 interval)
{
SDL_double_click_time = interval;
}
SDL_Window * SDL_Window *
SDL_GetMouseFocus(void) SDL_GetMouseFocus(void)
{ {
@ -454,9 +480,9 @@ SDL_PrivateSendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state
if (state == SDL_PRESSED) { if (state == SDL_PRESSED) {
Uint32 now = SDL_GetTicks(); Uint32 now = SDL_GetTicks();
if (SDL_TICKS_PASSED(now, clickstate->last_timestamp + SDL_double_click_time) || if (SDL_TICKS_PASSED(now, clickstate->last_timestamp + mouse->double_click_time) ||
SDL_abs(mouse->x - clickstate->last_x) > SDL_double_click_radius || SDL_abs(mouse->x - clickstate->last_x) > mouse->double_click_radius ||
SDL_abs(mouse->y - clickstate->last_y) > SDL_double_click_radius) { SDL_abs(mouse->y - clickstate->last_y) > mouse->double_click_radius) {
clickstate->click_count = 0; clickstate->click_count = 0;
} }
clickstate->last_timestamp = now; clickstate->last_timestamp = now;

View File

@ -90,6 +90,8 @@ typedef struct
float relative_speed_scale; float relative_speed_scale;
float scale_accum_x; float scale_accum_x;
float scale_accum_y; float scale_accum_y;
Uint32 double_click_time;
int double_click_radius;
SDL_bool touch_mouse_events; SDL_bool touch_mouse_events;
/* Data for double-click tracking */ /* Data for double-click tracking */
@ -112,9 +114,6 @@ extern int SDL_MouseInit(void);
/* Get the mouse state structure */ /* Get the mouse state structure */
SDL_Mouse *SDL_GetMouse(void); SDL_Mouse *SDL_GetMouse(void);
/* Set the default double-click interval */
extern void SDL_SetDoubleClickTime(Uint32 interval);
/* Set the default mouse cursor */ /* Set the default mouse cursor */
extern void SDL_SetDefaultCursor(SDL_Cursor * cursor); extern void SDL_SetDefaultCursor(SDL_Cursor * cursor);

View File

@ -28,26 +28,13 @@
static int SDLCALL static int SDLCALL
RemovePendingResizedEvents(void * userdata, SDL_Event *event) RemovePendingSizeChangedAndResizedEvents(void * userdata, SDL_Event *event)
{ {
SDL_Event *new_event = (SDL_Event *)userdata; SDL_Event *new_event = (SDL_Event *)userdata;
if (event->type == SDL_WINDOWEVENT && if (event->type == SDL_WINDOWEVENT &&
event->window.event == SDL_WINDOWEVENT_RESIZED && (event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED ||
event->window.windowID == new_event->window.windowID) { event->window.event == SDL_WINDOWEVENT_RESIZED) &&
/* We're about to post a new size event, drop the old one */
return 0;
}
return 1;
}
static int SDLCALL
RemovePendingSizeChangedEvents(void * userdata, SDL_Event *event)
{
SDL_Event *new_event = (SDL_Event *)userdata;
if (event->type == SDL_WINDOWEVENT &&
event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED &&
event->window.windowID == new_event->window.windowID) { event->window.windowID == new_event->window.windowID) {
/* We're about to post a new size event, drop the old one */ /* We're about to post a new size event, drop the old one */
return 0; return 0;
@ -199,11 +186,8 @@ SDL_SendWindowEvent(SDL_Window * window, Uint8 windowevent, int data1,
event.window.windowID = window->id; event.window.windowID = window->id;
/* Fixes queue overflow with resize events that aren't processed */ /* Fixes queue overflow with resize events that aren't processed */
if (windowevent == SDL_WINDOWEVENT_RESIZED) {
SDL_FilterEvents(RemovePendingResizedEvents, &event);
}
if (windowevent == SDL_WINDOWEVENT_SIZE_CHANGED) { if (windowevent == SDL_WINDOWEVENT_SIZE_CHANGED) {
SDL_FilterEvents(RemovePendingSizeChangedEvents, &event); SDL_FilterEvents(RemovePendingSizeChangedAndResizedEvents, &event);
} }
if (windowevent == SDL_WINDOWEVENT_MOVED) { if (windowevent == SDL_WINDOWEVENT_MOVED) {
SDL_FilterEvents(RemovePendingMoveEvents, &event); SDL_FilterEvents(RemovePendingMoveEvents, &event);

View File

@ -18,6 +18,10 @@
misrepresented as being the original software. misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution. 3. This notice may not be removed or altered from any source distribution.
*/ */
#ifndef scancodes_xfree86_h_
#define scancodes_xfree86_h_
#include "../../include/SDL_scancode.h" #include "../../include/SDL_scancode.h"
/* XFree86 key code to SDL scancode mapping table /* XFree86 key code to SDL scancode mapping table
@ -503,4 +507,6 @@ static const SDL_Scancode xvnc_scancode_table[] = {
/* 80 */ SDL_SCANCODE_F12, /* 80 */ SDL_SCANCODE_F12,
}; };
#endif /* scancodes_xfree86_h_ */
/* *INDENT-ON* */ /* *INDENT-ON* */

View File

@ -389,9 +389,11 @@ SDL_HapticClose(SDL_Haptic * haptic)
void void
SDL_HapticQuit(void) SDL_HapticQuit(void)
{ {
while (SDL_haptics) {
SDL_HapticClose(SDL_haptics);
}
SDL_SYS_HapticQuit(); SDL_SYS_HapticQuit();
SDL_assert(SDL_haptics == NULL);
SDL_haptics = NULL;
} }
/* /*

View File

@ -19,7 +19,12 @@
3. This notice may not be removed or altered from any source distribution. 3. This notice may not be removed or altered from any source distribution.
*/ */
#ifndef SDL_haptic_c_h_
#define SDL_haptic_c_h_
extern int SDL_HapticInit(void); extern int SDL_HapticInit(void);
extern void SDL_HapticQuit(void); extern void SDL_HapticQuit(void);
#endif /* SDL_haptic_c_h_ */
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */

View File

@ -195,6 +195,10 @@ SDL_SYS_HapticClose(SDL_Haptic * haptic)
void void
SDL_SYS_HapticQuit(void) SDL_SYS_HapticQuit(void)
{ {
/* We don't have any way to scan for joysticks (and their vibrators) at init, so don't wipe the list
* of joysticks here in case this is a reinit.
*/
#if 0
SDL_hapticlist_item *item = NULL; SDL_hapticlist_item *item = NULL;
SDL_hapticlist_item *next = NULL; SDL_hapticlist_item *next = NULL;
@ -206,6 +210,7 @@ SDL_SYS_HapticQuit(void)
SDL_hapticlist = SDL_hapticlist_tail = NULL; SDL_hapticlist = SDL_hapticlist_tail = NULL;
numhaptics = 0; numhaptics = 0;
return; return;
#endif
} }
@ -230,7 +235,12 @@ int
SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect, SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect,
Uint32 iterations) Uint32 iterations)
{ {
Android_JNI_HapticRun (((SDL_hapticlist_item *)haptic->hwdata)->device_id, effect->effect.leftright.length); float large = effect->effect.leftright.large_magnitude / 32767.0f;
float small = effect->effect.leftright.small_magnitude / 32767.0f;
float total = (large * 0.6f) + (small * 0.4f);
Android_JNI_HapticRun (((SDL_hapticlist_item *)haptic->hwdata)->device_id, total, effect->effect.leftright.length);
return 0; return 0;
} }

View File

@ -801,7 +801,8 @@ SDL_SYS_ToFFEffect(struct ff_effect *dest, SDL_HapticEffect * src)
else if (periodic->type == SDL_HAPTIC_SAWTOOTHDOWN) else if (periodic->type == SDL_HAPTIC_SAWTOOTHDOWN)
dest->u.periodic.waveform = FF_SAW_DOWN; dest->u.periodic.waveform = FF_SAW_DOWN;
dest->u.periodic.period = CLAMP(periodic->period); dest->u.periodic.period = CLAMP(periodic->period);
dest->u.periodic.magnitude = periodic->magnitude; /* Linux expects 0-65535, so multiply by 2 */
dest->u.periodic.magnitude = CLAMP(periodic->magnitude) * 2;
dest->u.periodic.offset = periodic->offset; dest->u.periodic.offset = periodic->offset;
/* Linux phase is defined in interval "[0x0000, 0x10000[", corresponds with "[0deg, 360deg[" phase shift. */ /* Linux phase is defined in interval "[0x0000, 0x10000[", corresponds with "[0deg, 360deg[" phase shift. */
dest->u.periodic.phase = ((Uint32)periodic->phase * 0x10000U) / 36000; dest->u.periodic.phase = ((Uint32)periodic->phase * 0x10000U) / 36000;
@ -908,9 +909,9 @@ SDL_SYS_ToFFEffect(struct ff_effect *dest, SDL_HapticEffect * src)
dest->trigger.button = 0; dest->trigger.button = 0;
dest->trigger.interval = 0; dest->trigger.interval = 0;
/* Rumble */ /* Rumble (Linux expects 0-65535, so multiply by 2) */
dest->u.rumble.strong_magnitude = leftright->large_magnitude; dest->u.rumble.strong_magnitude = CLAMP(leftright->large_magnitude) * 2;
dest->u.rumble.weak_magnitude = leftright->small_magnitude; dest->u.rumble.weak_magnitude = CLAMP(leftright->small_magnitude) * 2;
break; break;

View File

@ -11,8 +11,13 @@
#include <pthread.h> #include <pthread.h>
#include <errno.h> // For ETIMEDOUT and ECONNRESET #include <errno.h> // For ETIMEDOUT and ECONNRESET
#include <stdlib.h> // For malloc() and free() #include <stdlib.h> // For malloc() and free()
#include <string.h> // For memcpy()
#define TAG "hidapi" #define TAG "hidapi"
// Have error log always available
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
#ifdef DEBUG #ifdef DEBUG
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG, __VA_ARGS__) #define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG, __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__) #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
@ -27,13 +32,15 @@
#define HID_DEVICE_MANAGER_JAVA_INTERFACE(function) CONCAT1(SDL_JAVA_PREFIX, HIDDeviceManager, function) #define HID_DEVICE_MANAGER_JAVA_INTERFACE(function) CONCAT1(SDL_JAVA_PREFIX, HIDDeviceManager, function)
#include "../hidapi/hidapi.h" #include "../hidapi/hidapi.h"
typedef uint32_t uint32; typedef uint32_t uint32;
typedef uint64_t uint64; typedef uint64_t uint64;
struct hid_device_ struct hid_device_
{ {
int nId; int m_nId;
int m_nDeviceRefCount;
}; };
static JavaVM *g_JVM; static JavaVM *g_JVM;
@ -333,7 +340,7 @@ static jmethodID g_midHIDDeviceManagerSendFeatureReport;
static jmethodID g_midHIDDeviceManagerGetFeatureReport; static jmethodID g_midHIDDeviceManagerGetFeatureReport;
static jmethodID g_midHIDDeviceManagerClose; static jmethodID g_midHIDDeviceManagerClose;
uint64_t get_timespec_ms( const struct timespec &ts ) static uint64_t get_timespec_ms( const struct timespec &ts )
{ {
return (uint64_t)ts.tv_sec * 1000 + ts.tv_nsec / 1000000; return (uint64_t)ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
} }
@ -364,12 +371,20 @@ public:
int IncrementRefCount() int IncrementRefCount()
{ {
return ++m_nRefCount; int nValue;
pthread_mutex_lock( &m_refCountLock );
nValue = ++m_nRefCount;
pthread_mutex_unlock( &m_refCountLock );
return nValue;
} }
int DecrementRefCount() int DecrementRefCount()
{ {
return --m_nRefCount; int nValue;
pthread_mutex_lock( &m_refCountLock );
nValue = --m_nRefCount;
pthread_mutex_unlock( &m_refCountLock );
return nValue;
} }
int GetId() int GetId()
@ -387,19 +402,31 @@ public:
return m_pDevice; return m_pDevice;
} }
int GetDeviceRefCount() void ExceptionCheck( JNIEnv *env, const char *pszMethodName )
{ {
return m_nDeviceRefCount; if ( env->ExceptionCheck() )
} {
// Get our exception
jthrowable jExcept = env->ExceptionOccurred();
int IncrementDeviceRefCount() // Clear the exception so we can call JNI again
{ env->ExceptionClear();
return ++m_nDeviceRefCount;
}
int DecrementDeviceRefCount() // Get our exception message
{ jclass jExceptClass = env->GetObjectClass( jExcept );
return --m_nDeviceRefCount; jmethodID jMessageMethod = env->GetMethodID( jExceptClass, "getMessage", "()Ljava/lang/String;" );
jstring jMessage = (jstring)( env->CallObjectMethod( jExcept, jMessageMethod ) );
const char *pszMessage = env->GetStringUTFChars( jMessage, NULL );
// ...and log it.
LOGE( "CHIDDevice::%s threw an exception: %s", pszMethodName, pszMessage );
// Cleanup
env->ReleaseStringUTFChars( jMessage, pszMessage );
env->DeleteLocalRef( jMessage );
env->DeleteLocalRef( jExceptClass );
env->DeleteLocalRef( jExcept );
}
} }
bool BOpen() bool BOpen()
@ -411,6 +438,7 @@ public:
m_bIsWaitingForOpen = false; m_bIsWaitingForOpen = false;
m_bOpenResult = env->CallBooleanMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerOpen, m_nId ); m_bOpenResult = env->CallBooleanMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerOpen, m_nId );
ExceptionCheck( env, "BOpen" );
if ( m_bIsWaitingForOpen ) if ( m_bIsWaitingForOpen )
{ {
@ -445,8 +473,9 @@ public:
} }
m_pDevice = new hid_device; m_pDevice = new hid_device;
m_pDevice->nId = m_nId; m_pDevice->m_nId = m_nId;
m_nDeviceRefCount = 1; m_pDevice->m_nDeviceRefCount = 1;
LOGD("Creating device %d (%p), refCount = 1\n", m_pDevice->m_nId, m_pDevice);
return true; return true;
} }
@ -518,6 +547,8 @@ public:
jbyteArray pBuf = NewByteArray( env, pData, nDataLen ); jbyteArray pBuf = NewByteArray( env, pData, nDataLen );
int nRet = env->CallIntMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerSendOutputReport, m_nId, pBuf ); int nRet = env->CallIntMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerSendOutputReport, m_nId, pBuf );
ExceptionCheck( env, "SendOutputReport" );
env->DeleteLocalRef( pBuf ); env->DeleteLocalRef( pBuf );
return nRet; return nRet;
} }
@ -531,6 +562,7 @@ public:
jbyteArray pBuf = NewByteArray( env, pData, nDataLen ); jbyteArray pBuf = NewByteArray( env, pData, nDataLen );
int nRet = env->CallIntMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerSendFeatureReport, m_nId, pBuf ); int nRet = env->CallIntMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerSendFeatureReport, m_nId, pBuf );
ExceptionCheck( env, "SendFeatureReport" );
env->DeleteLocalRef( pBuf ); env->DeleteLocalRef( pBuf );
return nRet; return nRet;
} }
@ -567,6 +599,7 @@ public:
jbyteArray pBuf = NewByteArray( env, pData, nDataLen ); jbyteArray pBuf = NewByteArray( env, pData, nDataLen );
int nRet = env->CallBooleanMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerGetFeatureReport, m_nId, pBuf ) ? 0 : -1; int nRet = env->CallBooleanMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerGetFeatureReport, m_nId, pBuf ) ? 0 : -1;
ExceptionCheck( env, "GetFeatureReport" );
env->DeleteLocalRef( pBuf ); env->DeleteLocalRef( pBuf );
if ( nRet < 0 ) if ( nRet < 0 )
{ {
@ -625,7 +658,8 @@ public:
pthread_setspecific( g_ThreadKey, (void*)env ); pthread_setspecific( g_ThreadKey, (void*)env );
env->CallVoidMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerClose, m_nId ); env->CallVoidMethod( g_HIDDeviceManagerCallbackHandler, g_midHIDDeviceManagerClose, m_nId );
ExceptionCheck( env, "Close" );
hid_mutex_guard dataLock( &m_dataLock ); hid_mutex_guard dataLock( &m_dataLock );
m_vecData.clear(); m_vecData.clear();
@ -644,12 +678,12 @@ public:
} }
private: private:
pthread_mutex_t m_refCountLock = PTHREAD_MUTEX_INITIALIZER;
int m_nRefCount = 0; int m_nRefCount = 0;
int m_nId = 0; int m_nId = 0;
hid_device_info *m_pInfo = nullptr; hid_device_info *m_pInfo = nullptr;
hid_device *m_pDevice = nullptr; hid_device *m_pDevice = nullptr;
bool m_bIsBLESteamController = false; bool m_bIsBLESteamController = false;
int m_nDeviceRefCount = 0;
pthread_mutex_t m_dataLock = PTHREAD_MUTEX_INITIALIZER; // This lock has to be held to access m_vecData pthread_mutex_t m_dataLock = PTHREAD_MUTEX_INITIALIZER; // This lock has to be held to access m_vecData
hid_buffer_pool m_vecData; hid_buffer_pool m_vecData;
@ -669,6 +703,7 @@ public:
class CHIDDevice; class CHIDDevice;
static pthread_mutex_t g_DevicesMutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t g_DevicesMutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t g_DevicesRefCountMutex = PTHREAD_MUTEX_INITIALIZER;
static hid_device_ref<CHIDDevice> g_Devices; static hid_device_ref<CHIDDevice> g_Devices;
static hid_device_ref<CHIDDevice> FindDevice( int nDeviceId ) static hid_device_ref<CHIDDevice> FindDevice( int nDeviceId )
@ -696,8 +731,34 @@ static void ThreadDestroyed(void* value)
} }
} }
extern "C" extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceRegisterCallback)(JNIEnv *env, jobject thiz, jobject callbackHandler) JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceRegisterCallback)(JNIEnv *env, jobject thiz);
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReleaseCallback)(JNIEnv *env, jobject thiz);
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceConnected)(JNIEnv *env, jobject thiz, int nDeviceID, jstring sIdentifier, int nVendorId, int nProductId, jstring sSerialNumber, int nReleaseNumber, jstring sManufacturer, jstring sProduct, int nInterface );
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenPending)(JNIEnv *env, jobject thiz, int nDeviceID);
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenResult)(JNIEnv *env, jobject thiz, int nDeviceID, bool bOpened);
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceDisconnected)(JNIEnv *env, jobject thiz, int nDeviceID);
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceInputReport)(JNIEnv *env, jobject thiz, int nDeviceID, jbyteArray value);
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceFeatureReport)(JNIEnv *env, jobject thiz, int nDeviceID, jbyteArray value);
extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceRegisterCallback)(JNIEnv *env, jobject thiz )
{ {
LOGV( "HIDDeviceRegisterCallback()"); LOGV( "HIDDeviceRegisterCallback()");
@ -711,11 +772,19 @@ JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceRegisterCallba
__android_log_print(ANDROID_LOG_ERROR, TAG, "Error initializing pthread key"); __android_log_print(ANDROID_LOG_ERROR, TAG, "Error initializing pthread key");
} }
g_HIDDeviceManagerCallbackHandler = env->NewGlobalRef( callbackHandler ); if ( g_HIDDeviceManagerCallbackHandler != NULL )
jclass objClass = env->GetObjectClass( callbackHandler ); {
env->DeleteGlobalRef( g_HIDDeviceManagerCallbackClass );
g_HIDDeviceManagerCallbackClass = NULL;
env->DeleteGlobalRef( g_HIDDeviceManagerCallbackHandler );
g_HIDDeviceManagerCallbackHandler = NULL;
}
g_HIDDeviceManagerCallbackHandler = env->NewGlobalRef( thiz );
jclass objClass = env->GetObjectClass( thiz );
if ( objClass ) if ( objClass )
{ {
g_HIDDeviceManagerCallbackClass = reinterpret_cast< jclass >( env->NewGlobalRef(objClass) ); g_HIDDeviceManagerCallbackClass = reinterpret_cast< jclass >( env->NewGlobalRef( objClass ) );
g_midHIDDeviceManagerOpen = env->GetMethodID( g_HIDDeviceManagerCallbackClass, "openDevice", "(I)Z" ); g_midHIDDeviceManagerOpen = env->GetMethodID( g_HIDDeviceManagerCallbackClass, "openDevice", "(I)Z" );
if ( !g_midHIDDeviceManagerOpen ) if ( !g_midHIDDeviceManagerOpen )
{ {
@ -749,8 +818,13 @@ extern "C"
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReleaseCallback)(JNIEnv *env, jobject thiz) JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReleaseCallback)(JNIEnv *env, jobject thiz)
{ {
LOGV("HIDDeviceReleaseCallback"); LOGV("HIDDeviceReleaseCallback");
env->DeleteGlobalRef( g_HIDDeviceManagerCallbackClass ); if ( env->IsSameObject( thiz, g_HIDDeviceManagerCallbackHandler ) )
env->DeleteGlobalRef( g_HIDDeviceManagerCallbackHandler ); {
env->DeleteGlobalRef( g_HIDDeviceManagerCallbackClass );
g_HIDDeviceManagerCallbackClass = NULL;
env->DeleteGlobalRef( g_HIDDeviceManagerCallbackHandler );
g_HIDDeviceManagerCallbackHandler = NULL;
}
} }
extern "C" extern "C"
@ -924,14 +998,18 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path, int bEx
hid_device_ref< CHIDDevice > pDevice; hid_device_ref< CHIDDevice > pDevice;
{ {
hid_mutex_guard r( &g_DevicesRefCountMutex );
hid_mutex_guard l( &g_DevicesMutex ); hid_mutex_guard l( &g_DevicesMutex );
for ( hid_device_ref<CHIDDevice> pCurr = g_Devices; pCurr; pCurr = pCurr->next ) for ( hid_device_ref<CHIDDevice> pCurr = g_Devices; pCurr; pCurr = pCurr->next )
{ {
if ( strcmp( pCurr->GetDeviceInfo()->path, path ) == 0 ) if ( strcmp( pCurr->GetDeviceInfo()->path, path ) == 0 )
{ {
if ( pCurr->GetDevice() ) { hid_device *pValue = pCurr->GetDevice();
pCurr->IncrementDeviceRefCount(); if ( pValue )
return pCurr->GetDevice(); {
++pValue->m_nDeviceRefCount;
LOGD("Incrementing device %d (%p), refCount = %d\n", pValue->m_nId, pValue, pValue->m_nDeviceRefCount);
return pValue;
} }
// Hold a shared pointer to the controller for the duration // Hold a shared pointer to the controller for the duration
@ -949,8 +1027,8 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path, int bEx
int HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned char *data, size_t length) int HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned char *data, size_t length)
{ {
LOGV( "hid_write id=%d length=%u", device->nId, length ); LOGV( "hid_write id=%d length=%u", device->m_nId, length );
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->nId ); hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
if ( pDevice ) if ( pDevice )
{ {
return pDevice->SendOutputReport( data, length ); return pDevice->SendOutputReport( data, length );
@ -961,8 +1039,8 @@ int HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned ch
// TODO: Implement timeout? // TODO: Implement timeout?
int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *device, unsigned char *data, size_t length, int milliseconds) int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *device, unsigned char *data, size_t length, int milliseconds)
{ {
// LOGV( "hid_read_timeout id=%d length=%u timeout=%d", device->nId, length, milliseconds ); // LOGV( "hid_read_timeout id=%d length=%u timeout=%d", device->m_nId, length, milliseconds );
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->nId ); hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
if ( pDevice ) if ( pDevice )
{ {
return pDevice->GetInput( data, length ); return pDevice->GetInput( data, length );
@ -974,7 +1052,7 @@ int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *device, unsigned ch
// TODO: Implement blocking // TODO: Implement blocking
int HID_API_EXPORT HID_API_CALL hid_read(hid_device *device, unsigned char *data, size_t length) int HID_API_EXPORT HID_API_CALL hid_read(hid_device *device, unsigned char *data, size_t length)
{ {
LOGV( "hid_read id=%d length=%u", device->nId, length ); LOGV( "hid_read id=%d length=%u", device->m_nId, length );
return hid_read_timeout( device, data, length, 0 ); return hid_read_timeout( device, data, length, 0 );
} }
@ -986,8 +1064,8 @@ int HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *device, int non
int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *device, const unsigned char *data, size_t length) int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *device, const unsigned char *data, size_t length)
{ {
LOGV( "hid_send_feature_report id=%d length=%u", device->nId, length ); LOGV( "hid_send_feature_report id=%d length=%u", device->m_nId, length );
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->nId ); hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
if ( pDevice ) if ( pDevice )
{ {
return pDevice->SendFeatureReport( data, length ); return pDevice->SendFeatureReport( data, length );
@ -999,8 +1077,8 @@ int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *device, cons
// Synchronous operation. Will block until completed. // Synchronous operation. Will block until completed.
int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *device, unsigned char *data, size_t length) int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *device, unsigned char *data, size_t length)
{ {
LOGV( "hid_get_feature_report id=%d length=%u", device->nId, length ); LOGV( "hid_get_feature_report id=%d length=%u", device->m_nId, length );
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->nId ); hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
if ( pDevice ) if ( pDevice )
{ {
return pDevice->GetFeatureReport( data, length ); return pDevice->GetFeatureReport( data, length );
@ -1011,26 +1089,28 @@ int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *device, unsig
void HID_API_EXPORT HID_API_CALL hid_close(hid_device *device) void HID_API_EXPORT HID_API_CALL hid_close(hid_device *device)
{ {
LOGV( "hid_close id=%d", device->nId ); LOGV( "hid_close id=%d", device->m_nId );
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->nId ); hid_mutex_guard r( &g_DevicesRefCountMutex );
if ( pDevice ) LOGD("Decrementing device %d (%p), refCount = %d\n", device->m_nId, device, device->m_nDeviceRefCount - 1);
if ( --device->m_nDeviceRefCount == 0 )
{ {
pDevice->DecrementDeviceRefCount(); hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
if ( pDevice->GetDeviceRefCount() == 0 ) { if ( pDevice )
{
pDevice->Close( true ); pDevice->Close( true );
} }
} else
else {
{ delete device;
// Couldn't find it, it's already closed }
delete device; LOGD("Deleted device %p\n", device);
} }
} }
int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *device, wchar_t *string, size_t maxlen) int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *device, wchar_t *string, size_t maxlen)
{ {
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->nId ); hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
if ( pDevice ) if ( pDevice )
{ {
wcsncpy( string, pDevice->GetDeviceInfo()->manufacturer_string, maxlen ); wcsncpy( string, pDevice->GetDeviceInfo()->manufacturer_string, maxlen );
@ -1041,7 +1121,7 @@ int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *device, wchar_t
int HID_API_EXPORT_CALL hid_get_product_string(hid_device *device, wchar_t *string, size_t maxlen) int HID_API_EXPORT_CALL hid_get_product_string(hid_device *device, wchar_t *string, size_t maxlen)
{ {
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->nId ); hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
if ( pDevice ) if ( pDevice )
{ {
wcsncpy( string, pDevice->GetDeviceInfo()->product_string, maxlen ); wcsncpy( string, pDevice->GetDeviceInfo()->product_string, maxlen );
@ -1052,7 +1132,7 @@ int HID_API_EXPORT_CALL hid_get_product_string(hid_device *device, wchar_t *stri
int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *device, wchar_t *string, size_t maxlen) int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *device, wchar_t *string, size_t maxlen)
{ {
hid_device_ref<CHIDDevice> pDevice = FindDevice( device->nId ); hid_device_ref<CHIDDevice> pDevice = FindDevice( device->m_nId );
if ( pDevice ) if ( pDevice )
{ {
wcsncpy( string, pDevice->GetDeviceInfo()->serial_number, maxlen ); wcsncpy( string, pDevice->GetDeviceInfo()->serial_number, maxlen );

View File

@ -29,7 +29,7 @@
#include <wchar.h> #include <wchar.h>
#if defined(_WIN32) && !defined(NAMESPACE) #if defined(_WIN32) && !defined(NAMESPACE) && (0) /* SDL: don't export hidapi syms */
#define HID_API_EXPORT __declspec(dllexport) #define HID_API_EXPORT __declspec(dllexport)
#define HID_API_CALL #define HID_API_CALL
#else #else
@ -225,7 +225,7 @@ namespace NAMESPACE {
-1 on error. If no packet was available to be read within -1 on error. If no packet was available to be read within
the timeout period, this function returns 0. the timeout period, this function returns 0.
*/ */
int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds); int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *device, unsigned char *data, size_t length, int milliseconds);
/** @brief Read an Input report from a HID device. /** @brief Read an Input report from a HID device.

View File

@ -3,6 +3,9 @@
// Purpose: HID device abstraction temporary stub // Purpose: HID device abstraction temporary stub
// //
//============================================================================= //=============================================================================
#include "../../SDL_internal.h"
#ifdef SDL_JOYSTICK_HIDAPI
#include <CoreBluetooth/CoreBluetooth.h> #include <CoreBluetooth/CoreBluetooth.h>
#include <QuartzCore/QuartzCore.h> #include <QuartzCore/QuartzCore.h>
@ -907,3 +910,5 @@ int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t
#endif #endif
return result; return result;
} }
#endif /* SDL_JOYSTICK_HIDAPI */

View File

@ -22,6 +22,9 @@
code repository located at: code repository located at:
http://github.com/signal11/hidapi . http://github.com/signal11/hidapi .
********************************************************/ ********************************************************/
#include "../../SDL_internal.h"
#ifdef SDL_JOYSTICK_HIDAPI
#ifndef _GNU_SOURCE #ifndef _GNU_SOURCE
#define _GNU_SOURCE /* needed for wcsdup() before glibc 2.10 */ #define _GNU_SOURCE /* needed for wcsdup() before glibc 2.10 */
@ -1613,3 +1616,5 @@ uint16_t get_usb_code_for_current_locale(void)
#ifdef NAMESPACE #ifdef NAMESPACE
} }
#endif #endif
#endif /* SDL_JOYSTICK_HIDAPI */

View File

@ -20,6 +20,9 @@
code repository located at: code repository located at:
http://github.com/signal11/hidapi . http://github.com/signal11/hidapi .
********************************************************/ ********************************************************/
#include "../../SDL_internal.h"
#ifdef SDL_JOYSTICK_HIDAPI
#ifndef _GNU_SOURCE #ifndef _GNU_SOURCE
#define _GNU_SOURCE /* needed for wcsdup() before glibc 2.10 */ #define _GNU_SOURCE /* needed for wcsdup() before glibc 2.10 */
@ -891,3 +894,5 @@ HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev)
#ifdef NAMESPACE #ifdef NAMESPACE
} }
#endif #endif
#endif /* SDL_JOYSTICK_HIDAPI */

View File

@ -19,6 +19,9 @@
code repository located at: code repository located at:
http://github.com/signal11/hidapi . http://github.com/signal11/hidapi .
********************************************************/ ********************************************************/
#include "../../SDL_internal.h"
#ifdef SDL_JOYSTICK_HIDAPI
/* See Apple Technical Note TN2187 for details on IOHidManager. */ /* See Apple Technical Note TN2187 for details on IOHidManager. */
@ -1184,3 +1187,5 @@ int main(void)
return 0; return 0;
} }
#endif #endif
#endif /* SDL_JOYSTICK_HIDAPI */

View File

@ -19,13 +19,13 @@
code repository located at: code repository located at:
http://github.com/signal11/hidapi . http://github.com/signal11/hidapi .
********************************************************/ ********************************************************/
#include "../../SDL_internal.h"
#ifdef SDL_JOYSTICK_HIDAPI
#include <windows.h> #include <windows.h>
#ifndef _NTDEF_ #if 0 /* can cause redefinition errors on some toolchains */
typedef LONG NTSTATUS;
#endif
#ifdef __MINGW32__ #ifdef __MINGW32__
#include <ntdef.h> #include <ntdef.h>
#include <winbase.h> #include <winbase.h>
@ -35,6 +35,11 @@ typedef LONG NTSTATUS;
#include <ntdef.h> #include <ntdef.h>
#define _wcsdup wcsdup #define _wcsdup wcsdup
#endif #endif
#endif /* */
#ifndef _NTDEF_
typedef LONG NTSTATUS;
#endif
/* SDL C runtime functions */ /* SDL C runtime functions */
#include "SDL_stdinc.h" #include "SDL_stdinc.h"
@ -905,17 +910,18 @@ int HID_API_EXPORT_CALL HID_API_CALL hid_get_indexed_string(hid_device *dev, int
return 0; return 0;
} }
HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev) HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev)
{ {
return (wchar_t*)dev->last_error_str; return (wchar_t*)dev->last_error_str;
} }
#if 0
/*#define PICPGM*/ /*#define PICPGM*/
/*#define S11*/ /*#define S11*/
#define P32 #define P32
#ifdef S11 #ifdef S11
unsigned short VendorID = 0xa0a0; unsigned short VendorID = 0xa0a0;
unsigned short ProductID = 0x0001; unsigned short ProductID = 0x0001;
#endif #endif
@ -925,14 +931,11 @@ HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev)
unsigned short ProductID = 0x3f; unsigned short ProductID = 0x3f;
#endif #endif
#ifdef PICPGM #ifdef PICPGM
unsigned short VendorID = 0x04d8; unsigned short VendorID = 0x04d8;
unsigned short ProductID = 0x0033; unsigned short ProductID = 0x0033;
#endif #endif
#if 0
int __cdecl main(int argc, char* argv[]) int __cdecl main(int argc, char* argv[])
{ {
int res; int res;
@ -981,3 +984,5 @@ int __cdecl main(int argc, char* argv[])
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */
#endif #endif
#endif /* SDL_JOYSTICK_HIDAPI */

View File

@ -111,7 +111,6 @@ struct _SDL_GameController
SDL_Joystick *joystick; /* underlying joystick device */ SDL_Joystick *joystick; /* underlying joystick device */
int ref_count; int ref_count;
SDL_JoystickGUID guid;
const char *name; const char *name;
int num_bindings; int num_bindings;
SDL_ExtendedGameControllerBind *bindings; SDL_ExtendedGameControllerBind *bindings;
@ -433,12 +432,12 @@ static ControllerMapping_t *SDL_PrivateGetControllerMappingForGUID(SDL_JoystickG
pSupportedController = pSupportedController->next; pSupportedController = pSupportedController->next;
} }
if (!exact_match) { if (!exact_match) {
if (guid->data[14] == 'h') { if (SDL_IsJoystickHIDAPI(*guid)) {
/* This is a HIDAPI device */ /* This is a HIDAPI device */
return s_pHIDAPIMapping; return s_pHIDAPIMapping;
} }
#if SDL_JOYSTICK_XINPUT #if SDL_JOYSTICK_XINPUT
if (guid->data[14] == 'x') { if (SDL_IsJoystickXInput(*guid)) {
/* This is an XInput device */ /* This is an XInput device */
return s_pXInputMapping; return s_pXInputMapping;
} }
@ -684,11 +683,10 @@ SDL_PrivateGameControllerParseControllerConfigString(SDL_GameController *gamecon
/* /*
* Make a new button mapping struct * Make a new button mapping struct
*/ */
static void SDL_PrivateLoadButtonMapping(SDL_GameController *gamecontroller, SDL_JoystickGUID guid, const char *pchName, const char *pchMapping) static void SDL_PrivateLoadButtonMapping(SDL_GameController *gamecontroller, const char *pchName, const char *pchMapping)
{ {
int i; int i;
gamecontroller->guid = guid;
gamecontroller->name = pchName; gamecontroller->name = pchName;
gamecontroller->num_bindings = 0; gamecontroller->num_bindings = 0;
SDL_memset(gamecontroller->last_match_axis, 0, gamecontroller->joystick->naxes * sizeof(*gamecontroller->last_match_axis)); SDL_memset(gamecontroller->last_match_axis, 0, gamecontroller->joystick->naxes * sizeof(*gamecontroller->last_match_axis));
@ -802,14 +800,16 @@ static void SDL_PrivateGameControllerRefreshMapping(ControllerMapping_t *pContro
{ {
SDL_GameController *gamecontrollerlist = SDL_gamecontrollers; SDL_GameController *gamecontrollerlist = SDL_gamecontrollers;
while (gamecontrollerlist) { while (gamecontrollerlist) {
if (!SDL_memcmp(&gamecontrollerlist->guid, &pControllerMapping->guid, sizeof(pControllerMapping->guid))) { if (!SDL_memcmp(&gamecontrollerlist->joystick->guid, &pControllerMapping->guid, sizeof(pControllerMapping->guid))) {
SDL_Event event;
event.type = SDL_CONTROLLERDEVICEREMAPPED;
event.cdevice.which = gamecontrollerlist->joystick->instance_id;
SDL_PushEvent(&event);
/* Not really threadsafe. Should this lock access within SDL_GameControllerEventWatcher? */ /* Not really threadsafe. Should this lock access within SDL_GameControllerEventWatcher? */
SDL_PrivateLoadButtonMapping(gamecontrollerlist, pControllerMapping->guid, pControllerMapping->name, pControllerMapping->mapping); SDL_PrivateLoadButtonMapping(gamecontrollerlist, pControllerMapping->name, pControllerMapping->mapping);
{
SDL_Event event;
event.type = SDL_CONTROLLERDEVICEREMAPPED;
event.cdevice.which = gamecontrollerlist->joystick->instance_id;
SDL_PushEvent(&event);
}
} }
gamecontrollerlist = gamecontrollerlist->next; gamecontrollerlist = gamecontrollerlist->next;
@ -1027,7 +1027,7 @@ static ControllerMapping_t *SDL_PrivateGetControllerMappingForNameAndGUID(const
} }
} }
#ifdef __ANDROID__ #ifdef __ANDROID__
if (!mapping) { if (!mapping && name && !SDL_IsJoystickHIDAPI(guid)) {
mapping = SDL_CreateMappingForAndroidController(name, guid); mapping = SDL_CreateMappingForAndroidController(name, guid);
} }
#endif #endif
@ -1274,7 +1274,7 @@ SDL_GameControllerMapping(SDL_GameController * gamecontroller)
return NULL; return NULL;
} }
return SDL_GameControllerMappingForGUID(gamecontroller->guid); return SDL_GameControllerMappingForGUID(gamecontroller->joystick->guid);
} }
static void static void
@ -1463,6 +1463,7 @@ SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid)
int i; int i;
Uint16 vendor; Uint16 vendor;
Uint16 product; Uint16 product;
Uint16 version;
Uint32 vidpid; Uint32 vidpid;
if (SDL_allowed_controllers.num_entries == 0 && if (SDL_allowed_controllers.num_entries == 0 &&
@ -1470,7 +1471,7 @@ SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid)
return SDL_FALSE; return SDL_FALSE;
} }
SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL); SDL_GetJoystickGUIDInfo(guid, &vendor, &product, &version);
if (SDL_GetHintBoolean("SDL_GAMECONTROLLER_ALLOW_STEAM_VIRTUAL_GAMEPAD", SDL_FALSE)) { if (SDL_GetHintBoolean("SDL_GAMECONTROLLER_ALLOW_STEAM_VIRTUAL_GAMEPAD", SDL_FALSE)) {
/* We shouldn't ignore Steam's virtual gamepad since it's using the hints to filter out the real controllers so it can remap input for the virtual controller */ /* We shouldn't ignore Steam's virtual gamepad since it's using the hints to filter out the real controllers so it can remap input for the virtual controller */
@ -1478,7 +1479,7 @@ SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid)
#if defined(__LINUX__) #if defined(__LINUX__)
bSteamVirtualGamepad = (vendor == 0x28DE && product == 0x11FF); bSteamVirtualGamepad = (vendor == 0x28DE && product == 0x11FF);
#elif defined(__MACOSX__) #elif defined(__MACOSX__)
bSteamVirtualGamepad = (SDL_strncmp(name, "GamePad-", 8) == 0); bSteamVirtualGamepad = (vendor == 0x045E && product == 0x028E && version == 1);
#elif defined(__WIN32__) #elif defined(__WIN32__)
/* We can't tell on Windows, but Steam will block others in input hooks */ /* We can't tell on Windows, but Steam will block others in input hooks */
bSteamVirtualGamepad = SDL_TRUE; bSteamVirtualGamepad = SDL_TRUE;
@ -1582,7 +1583,7 @@ SDL_GameControllerOpen(int device_index)
} }
} }
SDL_PrivateLoadButtonMapping(gamecontroller, pSupportedController->guid, pSupportedController->name, pSupportedController->mapping); SDL_PrivateLoadButtonMapping(gamecontroller, pSupportedController->name, pSupportedController->mapping);
/* Add the controller to list */ /* Add the controller to list */
++gamecontroller->ref_count; ++gamecontroller->ref_count;
@ -1716,6 +1717,12 @@ SDL_GameControllerName(SDL_GameController * gamecontroller)
} }
} }
int
SDL_GameControllerGetPlayerIndex(SDL_GameController *gamecontroller)
{
return SDL_JoystickGetPlayerIndex(SDL_GameControllerGetJoystick(gamecontroller));
}
Uint16 Uint16
SDL_GameControllerGetVendor(SDL_GameController * gamecontroller) SDL_GameControllerGetVendor(SDL_GameController * gamecontroller)
{ {

View File

@ -362,6 +362,7 @@ static const char *s_ControllerMappings [] =
"03000000022000000090000011010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,", "03000000022000000090000011010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,",
"05000000203800000900000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,", "05000000203800000900000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,",
"05000000c82d00002038000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,", "05000000c82d00002038000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,",
"05000000c82d00000061000000010000,8Bitdo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,",
"05000000102800000900000000010000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,", "05000000102800000900000000010000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,",
"05000000c82d00003028000000010000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,", "05000000c82d00003028000000010000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,",
"05000000a00500003232000001000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,", "05000000a00500003232000001000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,",
@ -548,6 +549,7 @@ static const char *s_ControllerMappings [] =
"0000000058626f782047616d65706100,Xbox Gamepad (userspace driver),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,", "0000000058626f782047616d65706100,Xbox Gamepad (userspace driver),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,",
"050000005e040000e002000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,", "050000005e040000e002000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
"050000005e040000fd02000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,", "050000005e040000fd02000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
"030000005e040000ea02000001030000,Xbox One Wireless Controller (Model 1708),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,",
"05000000172700004431000029010000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,", "05000000172700004431000029010000,XiaoMi Game Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b20,leftshoulder:b6,leftstick:b13,lefttrigger:a7,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a5,start:b11,x:b3,y:b4,",
"03000000c0160000e105000001010000,Xin-Mo Xin-Mo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,", "03000000c0160000e105000001010000,Xin-Mo Xin-Mo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,",
"03000000120c0000100e000011010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "03000000120c0000100e000011010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",

View File

@ -227,6 +227,21 @@ SDL_JoystickNameForIndex(int device_index)
return name; return name;
} }
int
SDL_JoystickGetDevicePlayerIndex(int device_index)
{
SDL_JoystickDriver *driver;
int player_index = -1;
SDL_LockJoysticks();
if (SDL_GetDriverAndJoystickIndex(device_index, &driver, &device_index)) {
player_index = driver->GetDevicePlayerIndex(device_index);
}
SDL_UnlockJoysticks();
return player_index;
}
/* /*
* Return true if this joystick is known to have all axes centered at zero * Return true if this joystick is known to have all axes centered at zero
* This isn't generally needed unless the joystick never generates an initial axis value near zero, * This isn't generally needed unless the joystick never generates an initial axis value near zero,
@ -307,6 +322,7 @@ SDL_JoystickOpen(int device_index)
joystick->driver = driver; joystick->driver = driver;
joystick->instance_id = instance_id; joystick->instance_id = instance_id;
joystick->attached = SDL_TRUE; joystick->attached = SDL_TRUE;
joystick->player_index = -1;
if (driver->Open(joystick, device_index) < 0) { if (driver->Open(joystick, device_index) < 0) {
SDL_free(joystick); SDL_free(joystick);
@ -602,6 +618,15 @@ SDL_JoystickName(SDL_Joystick * joystick)
return SDL_FixupJoystickName(joystick->name); return SDL_FixupJoystickName(joystick->name);
} }
int
SDL_JoystickGetPlayerIndex(SDL_Joystick * joystick)
{
if (!SDL_PrivateJoystickValid(joystick)) {
return -1;
}
return joystick->player_index;
}
int int
SDL_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms) SDL_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms)
{ {
@ -1136,19 +1161,19 @@ SDL_IsJoystickNintendoSwitchPro(Uint16 vendor, Uint16 product)
SDL_bool SDL_bool
SDL_IsJoystickSteamController(Uint16 vendor, Uint16 product) SDL_IsJoystickSteamController(Uint16 vendor, Uint16 product)
{ {
return BIsSteamController(GuessControllerType(vendor, product)) ? SDL_TRUE : SDL_FALSE; return BIsSteamController(GuessControllerType(vendor, product));
} }
SDL_bool SDL_bool
SDL_IsJoystickXbox360(Uint16 vendor, Uint16 product) SDL_IsJoystickXbox360(Uint16 vendor, Uint16 product)
{ {
/* Filter out some bogus values here */ /* Filter out some bogus values here */
if (vendor == 0x0000 && product == 0x0000) { if (vendor == 0x0000 && product == 0x0000) {
return SDL_FALSE; return SDL_FALSE;
} }
if (vendor == 0x0001 && product == 0x0001) { if (vendor == 0x0001 && product == 0x0001) {
return SDL_FALSE; return SDL_FALSE;
} }
return (GuessControllerType(vendor, product) == k_eControllerType_XBox360Controller); return (GuessControllerType(vendor, product) == k_eControllerType_XBox360Controller);
} }
@ -1158,6 +1183,18 @@ SDL_IsJoystickXboxOne(Uint16 vendor, Uint16 product)
return (GuessControllerType(vendor, product) == k_eControllerType_XBoxOneController); return (GuessControllerType(vendor, product) == k_eControllerType_XBoxOneController);
} }
SDL_bool
SDL_IsJoystickXInput(SDL_JoystickGUID guid)
{
return (guid.data[14] == 'x') ? SDL_TRUE : SDL_FALSE;
}
SDL_bool
SDL_IsJoystickHIDAPI(SDL_JoystickGUID guid)
{
return (guid.data[14] == 'h') ? SDL_TRUE : SDL_FALSE;
}
static SDL_bool SDL_IsJoystickProductWheel(Uint32 vidpid) static SDL_bool SDL_IsJoystickProductWheel(Uint32 vidpid)
{ {
static Uint32 wheel_joysticks[] = { static Uint32 wheel_joysticks[] = {
@ -1223,7 +1260,7 @@ static SDL_JoystickType SDL_GetJoystickGUIDType(SDL_JoystickGUID guid)
Uint16 product; Uint16 product;
Uint32 vidpid; Uint32 vidpid;
if (guid.data[14] == 'x') { if (SDL_IsJoystickXInput(guid)) {
/* XInput GUID, get the type based on the XInput device subtype */ /* XInput GUID, get the type based on the XInput device subtype */
switch (guid.data[15]) { switch (guid.data[15]) {
case 0x01: /* XINPUT_DEVSUBTYPE_GAMEPAD */ case 0x01: /* XINPUT_DEVSUBTYPE_GAMEPAD */

View File

@ -18,6 +18,10 @@
misrepresented as being the original software. misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution. 3. This notice may not be removed or altered from any source distribution.
*/ */
#ifndef SDL_joystick_c_h_
#define SDL_joystick_c_h_
#include "../SDL_internal.h" #include "../SDL_internal.h"
/* Useful functions and variables from SDL_joystick.c */ /* Useful functions and variables from SDL_joystick.c */
@ -62,6 +66,12 @@ extern SDL_bool SDL_IsJoystickXbox360(Uint16 vendor_id, Uint16 product_id);
/* Function to return whether a joystick is an Xbox One controller */ /* Function to return whether a joystick is an Xbox One controller */
extern SDL_bool SDL_IsJoystickXboxOne(Uint16 vendor_id, Uint16 product_id); extern SDL_bool SDL_IsJoystickXboxOne(Uint16 vendor_id, Uint16 product_id);
/* Function to return whether a joystick guid comes from the XInput driver */
extern SDL_bool SDL_IsJoystickXInput(SDL_JoystickGUID guid);
/* Function to return whether a joystick guid comes from the HIDAPI driver */
extern SDL_bool SDL_IsJoystickHIDAPI(SDL_JoystickGUID guid);
/* Function to return whether a joystick should be ignored */ /* Function to return whether a joystick should be ignored */
extern SDL_bool SDL_ShouldIgnoreJoystick(const char *name, SDL_JoystickGUID guid); extern SDL_bool SDL_ShouldIgnoreJoystick(const char *name, SDL_JoystickGUID guid);
@ -91,4 +101,6 @@ extern void SDL_PrivateJoystickBatteryLevel(SDL_Joystick * joystick,
/* Internal sanity checking functions */ /* Internal sanity checking functions */
extern int SDL_PrivateJoystickValid(SDL_Joystick * joystick); extern int SDL_PrivateJoystickValid(SDL_Joystick * joystick);
#endif /* SDL_joystick_c_h_ */
/* vi: set ts=4 sw=4 expandtab: */ /* vi: set ts=4 sw=4 expandtab: */

View File

@ -42,6 +42,7 @@ struct _SDL_Joystick
{ {
SDL_JoystickID instance_id; /* Device instance, monotonically increasing from 0 */ SDL_JoystickID instance_id; /* Device instance, monotonically increasing from 0 */
char *name; /* Joystick name - system dependent */ char *name; /* Joystick name - system dependent */
int player_index; /* Joystick player index, or -1 if unavailable */
SDL_JoystickGUID guid; /* Joystick guid */ SDL_JoystickGUID guid; /* Joystick guid */
int naxes; /* Number of axis controls on the joystick */ int naxes; /* Number of axis controls on the joystick */
@ -105,6 +106,9 @@ typedef struct _SDL_JoystickDriver
/* Function to get the device-dependent name of a joystick */ /* Function to get the device-dependent name of a joystick */
const char *(*GetDeviceName)(int device_index); const char *(*GetDeviceName)(int device_index);
/* Function to get the player index of a joystick */
int (*GetDevicePlayerIndex)(int device_index);
/* Function to return the stable GUID for a plugged in device */ /* Function to return the stable GUID for a plugged in device */
SDL_JoystickGUID (*GetDeviceGUID)(int device_index); SDL_JoystickGUID (*GetDeviceGUID)(int device_index);

View File

@ -581,6 +581,12 @@ ANDROID_JoystickGetDeviceName(int device_index)
return JoystickByDevIndex(device_index)->name; return JoystickByDevIndex(device_index)->name;
} }
static int
ANDROID_JoystickGetDevicePlayerIndex(int device_index)
{
return -1;
}
static SDL_JoystickGUID static SDL_JoystickGUID
ANDROID_JoystickGetDeviceGUID(int device_index) ANDROID_JoystickGetDeviceGUID(int device_index)
{ {
@ -689,6 +695,7 @@ SDL_JoystickDriver SDL_ANDROID_JoystickDriver =
ANDROID_JoystickGetCount, ANDROID_JoystickGetCount,
ANDROID_JoystickDetect, ANDROID_JoystickDetect,
ANDROID_JoystickGetDeviceName, ANDROID_JoystickGetDeviceName,
ANDROID_JoystickGetDevicePlayerIndex,
ANDROID_JoystickGetDeviceGUID, ANDROID_JoystickGetDeviceGUID,
ANDROID_JoystickGetDeviceInstanceID, ANDROID_JoystickGetDeviceInstanceID,
ANDROID_JoystickOpen, ANDROID_JoystickOpen,

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