forked from Green-Sky/tomato
sdl (master post 3.1 preview) Merge commit 'e4f454091a943345938608570b104400f62fd625'
This commit is contained in:
147
external/sdl/SDL/src/SDL.c
vendored
147
external/sdl/SDL/src/SDL.c
vendored
@@ -21,33 +21,39 @@
|
||||
#include "SDL_internal.h"
|
||||
#include "SDL3/SDL_revision.h"
|
||||
|
||||
#if defined(__WIN32__) || defined(__GDK__)
|
||||
#if defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_GDK)
|
||||
#include "core/windows/SDL_windows.h"
|
||||
#elif !defined(__WINRT__)
|
||||
#elif !defined(SDL_PLATFORM_WINRT)
|
||||
#include <unistd.h> /* _exit(), etc. */
|
||||
#endif
|
||||
|
||||
/* this checks for HAVE_DBUS_DBUS_H internally. */
|
||||
#include "core/linux/SDL_dbus.h"
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#ifdef SDL_PLATFORM_EMSCRIPTEN
|
||||
#include <emscripten.h>
|
||||
#endif
|
||||
|
||||
/* Initialization code for SDL */
|
||||
|
||||
#include "SDL_assert_c.h"
|
||||
#include "SDL_hints_c.h"
|
||||
#include "SDL_log_c.h"
|
||||
#include "SDL_properties_c.h"
|
||||
#include "audio/SDL_sysaudio.h"
|
||||
#include "cpuinfo/SDL_cpuinfo_c.h"
|
||||
#include "video/SDL_video_c.h"
|
||||
#include "events/SDL_events_c.h"
|
||||
#include "haptic/SDL_haptic_c.h"
|
||||
#include "joystick/SDL_gamepad_c.h"
|
||||
#include "joystick/SDL_joystick_c.h"
|
||||
#include "sensor/SDL_sensor_c.h"
|
||||
#include "camera/SDL_camera_c.h"
|
||||
|
||||
#define SDL_INIT_EVERYTHING ~0U
|
||||
|
||||
/* Initialization/Cleanup routines */
|
||||
#include "time/SDL_time_c.h"
|
||||
#include "timer/SDL_timer_c.h"
|
||||
#ifdef SDL_VIDEO_DRIVER_WINDOWS
|
||||
extern int SDL_HelperWindowCreate(void);
|
||||
@@ -64,11 +70,11 @@ SDL_COMPILE_TIME_ASSERT(SDL_BUILD_MICRO_VERSION,
|
||||
#endif
|
||||
|
||||
SDL_COMPILE_TIME_ASSERT(SDL_MAJOR_VERSION_min, SDL_MAJOR_VERSION >= 0);
|
||||
/* Limited only by the need to fit in SDL_version */
|
||||
/* Limited only by the need to fit in SDL_Version */
|
||||
SDL_COMPILE_TIME_ASSERT(SDL_MAJOR_VERSION_max, SDL_MAJOR_VERSION <= 255);
|
||||
|
||||
SDL_COMPILE_TIME_ASSERT(SDL_MINOR_VERSION_min, SDL_MINOR_VERSION >= 0);
|
||||
/* Limited only by the need to fit in SDL_version */
|
||||
/* Limited only by the need to fit in SDL_Version */
|
||||
SDL_COMPILE_TIME_ASSERT(SDL_MINOR_VERSION_max, SDL_MINOR_VERSION <= 255);
|
||||
|
||||
SDL_COMPILE_TIME_ASSERT(SDL_PATCHLEVEL_min, SDL_PATCHLEVEL >= 0);
|
||||
@@ -81,7 +87,7 @@ SDL_COMPILE_TIME_ASSERT(SDL_PATCHLEVEL_max, SDL_PATCHLEVEL <= 99);
|
||||
extern SDL_NORETURN void SDL_ExitProcess(int exitcode);
|
||||
SDL_NORETURN void SDL_ExitProcess(int exitcode)
|
||||
{
|
||||
#if defined(__WIN32__) || defined(__GDK__)
|
||||
#if defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_GDK)
|
||||
/* "if you do not know the state of all threads in your process, it is
|
||||
better to call TerminateProcess than ExitProcess"
|
||||
https://msdn.microsoft.com/en-us/library/windows/desktop/ms682658(v=vs.85).aspx */
|
||||
@@ -89,11 +95,11 @@ SDL_NORETURN void SDL_ExitProcess(int exitcode)
|
||||
/* MingW doesn't have TerminateProcess marked as noreturn, so add an
|
||||
ExitProcess here that will never be reached but make MingW happy. */
|
||||
ExitProcess(exitcode);
|
||||
#elif defined(__EMSCRIPTEN__)
|
||||
#elif defined(SDL_PLATFORM_EMSCRIPTEN)
|
||||
emscripten_cancel_main_loop(); /* this should "kill" the app. */
|
||||
emscripten_force_exit(exitcode); /* this should "kill" the app. */
|
||||
exit(exitcode);
|
||||
#elif defined(__HAIKU__) /* Haiku has _Exit, but it's not marked noreturn. */
|
||||
#elif defined(SDL_PLATFORM_HAIKU) /* Haiku has _Exit, but it's not marked noreturn. */
|
||||
_exit(exitcode);
|
||||
#elif defined(HAVE__EXIT) /* Upper case _Exit() */
|
||||
_Exit(exitcode);
|
||||
@@ -126,7 +132,11 @@ static void SDL_DecrementSubsystemRefCount(Uint32 subsystem)
|
||||
{
|
||||
const int subsystem_index = SDL_MostSignificantBitIndex32(subsystem);
|
||||
if ((subsystem_index >= 0) && (SDL_SubsystemRefCount[subsystem_index] > 0)) {
|
||||
--SDL_SubsystemRefCount[subsystem_index];
|
||||
if (SDL_bInMainQuit) {
|
||||
SDL_SubsystemRefCount[subsystem_index] = 0;
|
||||
} else {
|
||||
--SDL_SubsystemRefCount[subsystem_index];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,11 +210,11 @@ int SDL_InitSubSystem(Uint32 flags)
|
||||
}
|
||||
#endif
|
||||
|
||||
SDL_InitTime();
|
||||
SDL_InitTicks();
|
||||
|
||||
/* Initialize the event subsystem */
|
||||
if (flags & SDL_INIT_EVENTS) {
|
||||
#ifndef SDL_EVENTS_DISABLED
|
||||
if (SDL_ShouldInitSubsystem(SDL_INIT_EVENTS)) {
|
||||
SDL_IncrementSubsystemRefCount(SDL_INIT_EVENTS);
|
||||
if (SDL_InitEvents() < 0) {
|
||||
@@ -215,10 +225,6 @@ int SDL_InitSubSystem(Uint32 flags)
|
||||
SDL_IncrementSubsystemRefCount(SDL_INIT_EVENTS);
|
||||
}
|
||||
flags_initialized |= SDL_INIT_EVENTS;
|
||||
#else
|
||||
SDL_SetError("SDL not built with events support");
|
||||
goto quit_and_error;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Initialize the timer subsystem */
|
||||
@@ -368,6 +374,30 @@ int SDL_InitSubSystem(Uint32 flags)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Initialize the camera subsystem */
|
||||
if (flags & SDL_INIT_CAMERA) {
|
||||
#ifndef SDL_CAMERA_DISABLED
|
||||
if (SDL_ShouldInitSubsystem(SDL_INIT_CAMERA)) {
|
||||
/* camera implies events */
|
||||
if (!SDL_InitOrIncrementSubsystem(SDL_INIT_EVENTS)) {
|
||||
goto quit_and_error;
|
||||
}
|
||||
|
||||
SDL_IncrementSubsystemRefCount(SDL_INIT_CAMERA);
|
||||
if (SDL_CameraInit(NULL) < 0) {
|
||||
SDL_DecrementSubsystemRefCount(SDL_INIT_CAMERA);
|
||||
goto quit_and_error;
|
||||
}
|
||||
} else {
|
||||
SDL_IncrementSubsystemRefCount(SDL_INIT_CAMERA);
|
||||
}
|
||||
flags_initialized |= SDL_INIT_CAMERA;
|
||||
#else
|
||||
SDL_SetError("SDL not built with camera support");
|
||||
goto quit_and_error;
|
||||
#endif
|
||||
}
|
||||
|
||||
(void)flags_initialized; /* make static analysis happy, since this only gets used in error cases. */
|
||||
|
||||
return 0;
|
||||
@@ -385,6 +415,18 @@ int SDL_Init(Uint32 flags)
|
||||
void SDL_QuitSubSystem(Uint32 flags)
|
||||
{
|
||||
/* Shut down requested initialized subsystems */
|
||||
|
||||
#ifndef SDL_CAMERA_DISABLED
|
||||
if (flags & SDL_INIT_CAMERA) {
|
||||
if (SDL_ShouldQuitSubsystem(SDL_INIT_CAMERA)) {
|
||||
SDL_QuitCamera();
|
||||
/* camera implies events */
|
||||
SDL_QuitSubSystem(SDL_INIT_EVENTS);
|
||||
}
|
||||
SDL_DecrementSubsystemRefCount(SDL_INIT_CAMERA);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SDL_SENSOR_DISABLED
|
||||
if (flags & SDL_INIT_SENSOR) {
|
||||
if (SDL_ShouldQuitSubsystem(SDL_INIT_SENSOR)) {
|
||||
@@ -452,14 +494,12 @@ void SDL_QuitSubSystem(Uint32 flags)
|
||||
SDL_DecrementSubsystemRefCount(SDL_INIT_TIMER);
|
||||
}
|
||||
|
||||
#ifndef SDL_EVENTS_DISABLED
|
||||
if (flags & SDL_INIT_EVENTS) {
|
||||
if (SDL_ShouldQuitSubsystem(SDL_INIT_EVENTS)) {
|
||||
SDL_QuitEvents();
|
||||
}
|
||||
SDL_DecrementSubsystemRefCount(SDL_INIT_EVENTS);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Uint32 SDL_WasInit(Uint32 flags)
|
||||
@@ -503,6 +543,7 @@ void SDL_Quit(void)
|
||||
SDL_QuitSubSystem(SDL_INIT_EVERYTHING);
|
||||
|
||||
SDL_QuitTicks();
|
||||
SDL_QuitTime();
|
||||
|
||||
#ifdef SDL_USE_LIBDBUS
|
||||
SDL_DBus_Quit();
|
||||
@@ -511,6 +552,8 @@ void SDL_Quit(void)
|
||||
SDL_ClearHints();
|
||||
SDL_AssertionsQuit();
|
||||
|
||||
SDL_QuitCPUInfo();
|
||||
|
||||
SDL_QuitProperties();
|
||||
SDL_QuitLog();
|
||||
|
||||
@@ -539,7 +582,7 @@ Uint32 SDL_GetNextObjectID(void)
|
||||
}
|
||||
|
||||
/* Get the library version number */
|
||||
int SDL_GetVersion(SDL_version *ver)
|
||||
int SDL_GetVersion(SDL_Version *ver)
|
||||
{
|
||||
static SDL_bool check_hint = SDL_TRUE;
|
||||
static SDL_bool legacy_version = SDL_FALSE;
|
||||
@@ -572,69 +615,65 @@ const char *SDL_GetRevision(void)
|
||||
/* Get the name of the platform */
|
||||
const char *SDL_GetPlatform(void)
|
||||
{
|
||||
#ifdef __AIX__
|
||||
#if defined(SDL_PLATFORM_AIX)
|
||||
return "AIX";
|
||||
#elif defined(__ANDROID__)
|
||||
#elif defined(SDL_PLATFORM_ANDROID)
|
||||
return "Android";
|
||||
#elif defined(__BSDI__)
|
||||
#elif defined(SDL_PLATFORM_BSDI)
|
||||
return "BSDI";
|
||||
#elif defined(__DREAMCAST__)
|
||||
return "Dreamcast";
|
||||
#elif defined(__EMSCRIPTEN__)
|
||||
#elif defined(SDL_PLATFORM_EMSCRIPTEN)
|
||||
return "Emscripten";
|
||||
#elif defined(__FREEBSD__)
|
||||
#elif defined(SDL_PLATFORM_FREEBSD)
|
||||
return "FreeBSD";
|
||||
#elif defined(__HAIKU__)
|
||||
#elif defined(SDL_PLATFORM_HAIKU)
|
||||
return "Haiku";
|
||||
#elif defined(__HPUX__)
|
||||
#elif defined(SDL_PLATFORM_HPUX)
|
||||
return "HP-UX";
|
||||
#elif defined(__IRIX__)
|
||||
#elif defined(SDL_PLATFORM_IRIX)
|
||||
return "Irix";
|
||||
#elif defined(__LINUX__)
|
||||
#elif defined(SDL_PLATFORM_LINUX)
|
||||
return "Linux";
|
||||
#elif defined(__MINT__)
|
||||
return "Atari MiNT";
|
||||
#elif defined(__MACOS__)
|
||||
#elif defined(SDL_PLATFORM_MACOS)
|
||||
return "macOS";
|
||||
#elif defined(__NACL__)
|
||||
return "NaCl";
|
||||
#elif defined(__NETBSD__)
|
||||
#elif defined(SDL_PLATFORM_NETBSD)
|
||||
return "NetBSD";
|
||||
#elif defined(__OPENBSD__)
|
||||
#elif defined(SDL_PLATFORM_OPENBSD)
|
||||
return "OpenBSD";
|
||||
#elif defined(__OS2__)
|
||||
#elif defined(SDL_PLATFORM_OS2)
|
||||
return "OS/2";
|
||||
#elif defined(__OSF__)
|
||||
#elif defined(SDL_PLATFORM_OSF)
|
||||
return "OSF/1";
|
||||
#elif defined(__QNXNTO__)
|
||||
#elif defined(SDL_PLATFORM_QNXNTO)
|
||||
return "QNX Neutrino";
|
||||
#elif defined(__RISCOS__)
|
||||
#elif defined(SDL_PLATFORM_RISCOS)
|
||||
return "RISC OS";
|
||||
#elif defined(__SOLARIS__)
|
||||
#elif defined(SDL_PLATFORM_SOLARIS)
|
||||
return "Solaris";
|
||||
#elif defined(__WIN32__)
|
||||
#elif defined(SDL_PLATFORM_WIN32)
|
||||
return "Windows";
|
||||
#elif defined(__WINRT__)
|
||||
#elif defined(SDL_PLATFORM_WINRT)
|
||||
return "WinRT";
|
||||
#elif defined(__WINGDK__)
|
||||
#elif defined(SDL_PLATFORM_WINGDK)
|
||||
return "WinGDK";
|
||||
#elif defined(__XBOXONE__)
|
||||
#elif defined(SDL_PLATFORM_XBOXONE)
|
||||
return "Xbox One";
|
||||
#elif defined(__XBOXSERIES__)
|
||||
#elif defined(SDL_PLATFORM_XBOXSERIES)
|
||||
return "Xbox Series X|S";
|
||||
#elif defined(__IOS__)
|
||||
#elif defined(SDL_PLATFORM_IOS)
|
||||
return "iOS";
|
||||
#elif defined(__TVOS__)
|
||||
#elif defined(SDL_PLATFORM_TVOS)
|
||||
return "tvOS";
|
||||
#elif defined(__PS2__)
|
||||
#elif defined(SDL_PLATFORM_PS2)
|
||||
return "PlayStation 2";
|
||||
#elif defined(__PSP__)
|
||||
#elif defined(SDL_PLATFORM_PSP)
|
||||
return "PlayStation Portable";
|
||||
#elif defined(__VITA__)
|
||||
#elif defined(SDL_PLATFORM_VITA)
|
||||
return "PlayStation Vita";
|
||||
#elif defined(__NGAGE__)
|
||||
#elif defined(SDL_PLATFORM_NGAGE)
|
||||
return "Nokia N-Gage";
|
||||
#elif defined(__3DS__)
|
||||
#elif defined(SDL_PLATFORM_3DS)
|
||||
return "Nintendo 3DS";
|
||||
#elif defined(__managarm__)
|
||||
return "Managarm";
|
||||
@@ -645,10 +684,10 @@ const char *SDL_GetPlatform(void)
|
||||
|
||||
SDL_bool SDL_IsTablet(void)
|
||||
{
|
||||
#ifdef __ANDROID__
|
||||
#ifdef SDL_PLATFORM_ANDROID
|
||||
extern SDL_bool SDL_IsAndroidTablet(void);
|
||||
return SDL_IsAndroidTablet();
|
||||
#elif defined(__IOS__)
|
||||
#elif defined(SDL_PLATFORM_IOS)
|
||||
extern SDL_bool SDL_IsIPad(void);
|
||||
return SDL_IsIPad();
|
||||
#else
|
||||
@@ -656,7 +695,7 @@ SDL_bool SDL_IsTablet(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __WIN32__
|
||||
#ifdef SDL_PLATFORM_WIN32
|
||||
|
||||
#if (!defined(HAVE_LIBC) || defined(__WATCOMC__)) && !defined(SDL_STATIC_LIB)
|
||||
/* FIXME: Still need to include DllMain() on Watcom C ? */
|
||||
@@ -674,4 +713,4 @@ BOOL APIENTRY MINGW32_FORCEALIGN _DllMainCRTStartup(HANDLE hModule, DWORD ul_rea
|
||||
}
|
||||
#endif /* Building DLL */
|
||||
|
||||
#endif /* defined(__WIN32__) || defined(__GDK__) */
|
||||
#endif /* defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_GDK) */
|
||||
|
||||
16
external/sdl/SDL/src/SDL_assert.c
vendored
16
external/sdl/SDL/src/SDL_assert.c
vendored
@@ -20,20 +20,20 @@
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#if defined(__WIN32__) || defined(__GDK__)
|
||||
#if defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_GDK)
|
||||
#include "core/windows/SDL_windows.h"
|
||||
#endif
|
||||
|
||||
#include "SDL_assert_c.h"
|
||||
#include "video/SDL_sysvideo.h"
|
||||
|
||||
#if defined(__WIN32__) || defined(__GDK__)
|
||||
#if defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_GDK)
|
||||
#ifndef WS_OVERLAPPEDWINDOW
|
||||
#define WS_OVERLAPPEDWINDOW 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#ifdef SDL_PLATFORM_EMSCRIPTEN
|
||||
#include <emscripten.h>
|
||||
/* older Emscriptens don't have this, but we need to for wasm64 compatibility. */
|
||||
#ifndef MAIN_THREAD_EM_ASM_PTR
|
||||
@@ -86,7 +86,7 @@ static void SDL_AddAssertionToReport(SDL_AssertData *data)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__WIN32__) || defined(__GDK__)
|
||||
#if defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_GDK)
|
||||
#define ENDLINE "\r\n"
|
||||
#else
|
||||
#define ENDLINE "\n"
|
||||
@@ -246,7 +246,7 @@ static SDL_AssertState SDLCALL SDL_PromptAssertion(const SDL_AssertData *data, v
|
||||
state = (SDL_AssertState)selected;
|
||||
}
|
||||
} else {
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#ifdef SDL_PLATFORM_EMSCRIPTEN
|
||||
/* This is nasty, but we can't block on a custom UI. */
|
||||
for (;;) {
|
||||
SDL_bool okay = SDL_TRUE;
|
||||
@@ -333,15 +333,15 @@ SDL_AssertState SDL_ReportAssertion(SDL_AssertData *data, const char *func, cons
|
||||
|
||||
#ifndef SDL_THREADS_DISABLED
|
||||
static SDL_SpinLock spinlock = 0;
|
||||
SDL_AtomicLock(&spinlock);
|
||||
SDL_LockSpinlock(&spinlock);
|
||||
if (!assertion_mutex) { /* never called SDL_Init()? */
|
||||
assertion_mutex = SDL_CreateMutex();
|
||||
if (!assertion_mutex) {
|
||||
SDL_AtomicUnlock(&spinlock);
|
||||
SDL_UnlockSpinlock(&spinlock);
|
||||
return SDL_ASSERTION_IGNORE; /* oh well, I guess. */
|
||||
}
|
||||
}
|
||||
SDL_AtomicUnlock(&spinlock);
|
||||
SDL_UnlockSpinlock(&spinlock);
|
||||
|
||||
SDL_LockMutex(assertion_mutex);
|
||||
#endif /* !SDL_THREADS_DISABLED */
|
||||
|
||||
1
external/sdl/SDL/src/SDL_hints_c.h
vendored
1
external/sdl/SDL/src/SDL_hints_c.h
vendored
@@ -27,5 +27,6 @@
|
||||
|
||||
extern SDL_bool SDL_GetStringBoolean(const char *value, SDL_bool default_value);
|
||||
extern int SDL_GetStringInteger(const char *value, int default_value);
|
||||
extern void SDL_ClearHints(void);
|
||||
|
||||
#endif /* SDL_hints_c_h_ */
|
||||
|
||||
80
external/sdl/SDL/src/SDL_internal.h
vendored
80
external/sdl/SDL/src/SDL_internal.h
vendored
@@ -74,7 +74,7 @@
|
||||
#define DECLSPEC
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#ifdef SDL_PLATFORM_APPLE
|
||||
#ifndef _DARWIN_C_SOURCE
|
||||
#define _DARWIN_C_SOURCE 1 /* for memset_pattern4() */
|
||||
#endif
|
||||
@@ -137,13 +137,13 @@
|
||||
#endif
|
||||
|
||||
/* Optimized functions from 'SDL_blit_0.c'
|
||||
- blit with source BitsPerPixel < 8, palette */
|
||||
- blit with source bits_per_pixel < 8, palette */
|
||||
#ifndef SDL_HAVE_BLIT_0
|
||||
#define SDL_HAVE_BLIT_0 !SDL_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
/* Optimized functions from 'SDL_blit_1.c'
|
||||
- blit with source BytesPerPixel == 1, palette */
|
||||
- blit with source bytes_per_pixel == 1, palette */
|
||||
#ifndef SDL_HAVE_BLIT_1
|
||||
#define SDL_HAVE_BLIT_1 !SDL_LEAN_AND_MEAN
|
||||
#endif
|
||||
@@ -194,6 +194,80 @@
|
||||
#define SDL_HAVE_YUV !SDL_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#ifndef SDL_RENDER_DISABLED
|
||||
/* define the not defined ones as 0 */
|
||||
#ifndef SDL_VIDEO_RENDER_D3D
|
||||
#define SDL_VIDEO_RENDER_D3D 0
|
||||
#endif
|
||||
#ifndef SDL_VIDEO_RENDER_D3D11
|
||||
#define SDL_VIDEO_RENDER_D3D11 0
|
||||
#endif
|
||||
#ifndef SDL_VIDEO_RENDER_D3D12
|
||||
#define SDL_VIDEO_RENDER_D3D12 0
|
||||
#endif
|
||||
#ifndef SDL_VIDEO_RENDER_METAL
|
||||
#define SDL_VIDEO_RENDER_METAL 0
|
||||
#endif
|
||||
#ifndef SDL_VIDEO_RENDER_OGL
|
||||
#define SDL_VIDEO_RENDER_OGL 0
|
||||
#endif
|
||||
#ifndef SDL_VIDEO_RENDER_OGL_ES2
|
||||
#define SDL_VIDEO_RENDER_OGL_ES2 0
|
||||
#endif
|
||||
#ifndef SDL_VIDEO_RENDER_PS2
|
||||
#define SDL_VIDEO_RENDER_PS2 0
|
||||
#endif
|
||||
#ifndef SDL_VIDEO_RENDER_PSP
|
||||
#define SDL_VIDEO_RENDER_PSP 0
|
||||
#endif
|
||||
#ifndef SDL_VIDEO_RENDER_VITA_GXM
|
||||
#define SDL_VIDEO_RENDER_VITA_GXM 0
|
||||
#endif
|
||||
#ifndef SDL_VIDEO_RENDER_VULKAN
|
||||
#define SDL_VIDEO_RENDER_VULKAN 0
|
||||
#endif
|
||||
#else /* define all as 0 */
|
||||
#undef SDL_VIDEO_RENDER_SW
|
||||
#define SDL_VIDEO_RENDER_SW 0
|
||||
#undef SDL_VIDEO_RENDER_D3D
|
||||
#define SDL_VIDEO_RENDER_D3D 0
|
||||
#undef SDL_VIDEO_RENDER_D3D11
|
||||
#define SDL_VIDEO_RENDER_D3D11 0
|
||||
#undef SDL_VIDEO_RENDER_D3D12
|
||||
#define SDL_VIDEO_RENDER_D3D12 0
|
||||
#undef SDL_VIDEO_RENDER_METAL
|
||||
#define SDL_VIDEO_RENDER_METAL 0
|
||||
#undef SDL_VIDEO_RENDER_OGL
|
||||
#define SDL_VIDEO_RENDER_OGL 0
|
||||
#undef SDL_VIDEO_RENDER_OGL_ES2
|
||||
#define SDL_VIDEO_RENDER_OGL_ES2 0
|
||||
#undef SDL_VIDEO_RENDER_PS2
|
||||
#define SDL_VIDEO_RENDER_PS2 0
|
||||
#undef SDL_VIDEO_RENDER_PSP
|
||||
#define SDL_VIDEO_RENDER_PSP 0
|
||||
#undef SDL_VIDEO_RENDER_VITA_GXM
|
||||
#define SDL_VIDEO_RENDER_VITA_GXM 0
|
||||
#undef SDL_VIDEO_RENDER_VULKAN
|
||||
#define SDL_VIDEO_RENDER_VULKAN 0
|
||||
#endif /* SDL_RENDER_DISABLED */
|
||||
|
||||
#define SDL_HAS_RENDER_DRIVER \
|
||||
(SDL_VIDEO_RENDER_SW | \
|
||||
SDL_VIDEO_RENDER_D3D | \
|
||||
SDL_VIDEO_RENDER_D3D11 | \
|
||||
SDL_VIDEO_RENDER_D3D12 | \
|
||||
SDL_VIDEO_RENDER_METAL | \
|
||||
SDL_VIDEO_RENDER_OGL | \
|
||||
SDL_VIDEO_RENDER_OGL_ES2 | \
|
||||
SDL_VIDEO_RENDER_PS2 | \
|
||||
SDL_VIDEO_RENDER_PSP | \
|
||||
SDL_VIDEO_RENDER_VITA_GXM | \
|
||||
SDL_VIDEO_RENDER_VULKAN )
|
||||
|
||||
#if !defined(SDL_RENDER_DISABLED) && !SDL_HAS_RENDER_DRIVER
|
||||
#error SDL_RENDER enabled without any backend drivers.
|
||||
#endif
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_intrin.h>
|
||||
|
||||
|
||||
2
external/sdl/SDL/src/SDL_list.c
vendored
2
external/sdl/SDL/src/SDL_list.c
vendored
@@ -25,7 +25,7 @@
|
||||
/* Push */
|
||||
int SDL_ListAdd(SDL_ListNode **head, void *ent)
|
||||
{
|
||||
SDL_ListNode *node = SDL_malloc(sizeof(*node));
|
||||
SDL_ListNode *node = (SDL_ListNode *)SDL_malloc(sizeof(*node));
|
||||
|
||||
if (!node) {
|
||||
return -1;
|
||||
|
||||
205
external/sdl/SDL/src/SDL_log.c
vendored
205
external/sdl/SDL/src/SDL_log.c
vendored
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#if defined(__WIN32__) || defined(__WINRT__) || defined(__GDK__)
|
||||
#if defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_WINRT) || defined(SDL_PLATFORM_GDK)
|
||||
#include "core/windows/SDL_windows.h"
|
||||
#endif
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#ifdef SDL_PLATFORM_ANDROID
|
||||
#include <android/log.h>
|
||||
#endif
|
||||
|
||||
@@ -41,10 +41,7 @@
|
||||
/* The size of the stack buffer to use for rendering log messages. */
|
||||
#define SDL_MAX_LOG_MESSAGE_STACK 256
|
||||
|
||||
#define DEFAULT_PRIORITY SDL_LOG_PRIORITY_ERROR
|
||||
#define DEFAULT_ASSERT_PRIORITY SDL_LOG_PRIORITY_WARN
|
||||
#define DEFAULT_APPLICATION_PRIORITY SDL_LOG_PRIORITY_INFO
|
||||
#define DEFAULT_TEST_PRIORITY SDL_LOG_PRIORITY_VERBOSE
|
||||
#define DEFAULT_CATEGORY -1
|
||||
|
||||
typedef struct SDL_LogLevel
|
||||
{
|
||||
@@ -57,10 +54,8 @@ typedef struct SDL_LogLevel
|
||||
static void SDLCALL SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority, const char *message);
|
||||
|
||||
static SDL_LogLevel *SDL_loglevels;
|
||||
static SDL_LogPriority SDL_default_priority = DEFAULT_PRIORITY;
|
||||
static SDL_LogPriority SDL_assert_priority = DEFAULT_ASSERT_PRIORITY;
|
||||
static SDL_LogPriority SDL_application_priority = DEFAULT_APPLICATION_PRIORITY;
|
||||
static SDL_LogPriority SDL_test_priority = DEFAULT_TEST_PRIORITY;
|
||||
static SDL_bool SDL_forced_priority = SDL_FALSE;
|
||||
static SDL_LogPriority SDL_forced_priority_level;
|
||||
static SDL_LogOutputFunction SDL_log_function = SDL_LogOutput;
|
||||
static void *SDL_log_userdata = NULL;
|
||||
static SDL_Mutex *log_function_mutex = NULL;
|
||||
@@ -70,7 +65,8 @@ static SDL_Mutex *log_function_mutex = NULL;
|
||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
#endif
|
||||
|
||||
static const char *SDL_priority_prefixes[SDL_NUM_LOG_PRIORITIES] = {
|
||||
/* If this list changes, update the documentation for SDL_HINT_LOGGING */
|
||||
static const char *SDL_priority_prefixes[] = {
|
||||
NULL,
|
||||
"VERBOSE",
|
||||
"DEBUG",
|
||||
@@ -79,12 +75,9 @@ static const char *SDL_priority_prefixes[SDL_NUM_LOG_PRIORITIES] = {
|
||||
"ERROR",
|
||||
"CRITICAL"
|
||||
};
|
||||
SDL_COMPILE_TIME_ASSERT(priority_prefixes, SDL_arraysize(SDL_priority_prefixes) == SDL_NUM_LOG_PRIORITIES);
|
||||
|
||||
#ifdef HAVE_GCC_DIAGNOSTIC_PRAGMA
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#ifdef __ANDROID__
|
||||
/* If this list changes, update the documentation for SDL_HINT_LOGGING */
|
||||
static const char *SDL_category_prefixes[] = {
|
||||
"APP",
|
||||
"ERROR",
|
||||
@@ -96,9 +89,13 @@ static const char *SDL_category_prefixes[] = {
|
||||
"INPUT",
|
||||
"TEST"
|
||||
};
|
||||
SDL_COMPILE_TIME_ASSERT(category_prefixes, SDL_arraysize(SDL_category_prefixes) == SDL_LOG_CATEGORY_RESERVED1);
|
||||
|
||||
SDL_COMPILE_TIME_ASSERT(category_prefixes_enum, SDL_TABLESIZE(SDL_category_prefixes) == SDL_LOG_CATEGORY_RESERVED1);
|
||||
#ifdef HAVE_GCC_DIAGNOSTIC_PRAGMA
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#ifdef SDL_PLATFORM_ANDROID
|
||||
static int SDL_android_priority[SDL_NUM_LOG_PRIORITIES] = {
|
||||
ANDROID_LOG_UNKNOWN,
|
||||
ANDROID_LOG_VERBOSE,
|
||||
@@ -108,7 +105,7 @@ static int SDL_android_priority[SDL_NUM_LOG_PRIORITIES] = {
|
||||
ANDROID_LOG_ERROR,
|
||||
ANDROID_LOG_FATAL
|
||||
};
|
||||
#endif /* __ANDROID__ */
|
||||
#endif /* SDL_PLATFORM_ANDROID */
|
||||
|
||||
void SDL_InitLog(void)
|
||||
{
|
||||
@@ -134,9 +131,9 @@ void SDL_LogSetAllPriority(SDL_LogPriority priority)
|
||||
for (entry = SDL_loglevels; entry; entry = entry->next) {
|
||||
entry->priority = priority;
|
||||
}
|
||||
SDL_default_priority = priority;
|
||||
SDL_assert_priority = priority;
|
||||
SDL_application_priority = priority;
|
||||
|
||||
SDL_forced_priority = SDL_TRUE;
|
||||
SDL_forced_priority_level = priority;
|
||||
}
|
||||
|
||||
void SDL_LogSetPriority(int category, SDL_LogPriority priority)
|
||||
@@ -160,6 +157,122 @@ void SDL_LogSetPriority(int category, SDL_LogPriority priority)
|
||||
}
|
||||
}
|
||||
|
||||
static SDL_bool SDL_ParseLogCategory(const char *string, size_t length, int *category)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (SDL_isdigit(*string)) {
|
||||
*category = SDL_atoi(string);
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
if (*string == '*') {
|
||||
*category = DEFAULT_CATEGORY;
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
for (i = 0; i < SDL_arraysize(SDL_category_prefixes); ++i) {
|
||||
if (SDL_strncasecmp(string, SDL_category_prefixes[i], length) == 0) {
|
||||
*category = i;
|
||||
return SDL_TRUE;
|
||||
}
|
||||
}
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
static SDL_bool SDL_ParseLogPriority(const char *string, size_t length, SDL_LogPriority *priority)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (SDL_isdigit(*string)) {
|
||||
i = SDL_atoi(string);
|
||||
if (i == 0) {
|
||||
/* 0 has a special meaning of "disable this category" */
|
||||
*priority = SDL_NUM_LOG_PRIORITIES;
|
||||
return SDL_TRUE;
|
||||
}
|
||||
if (i >= SDL_LOG_PRIORITY_VERBOSE && i < SDL_NUM_LOG_PRIORITIES) {
|
||||
*priority = (SDL_LogPriority)i;
|
||||
return SDL_TRUE;
|
||||
}
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (SDL_strncasecmp(string, "quiet", length) == 0) {
|
||||
*priority = SDL_NUM_LOG_PRIORITIES;
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
for (i = SDL_LOG_PRIORITY_VERBOSE; i < SDL_NUM_LOG_PRIORITIES; ++i) {
|
||||
if (SDL_strncasecmp(string, SDL_priority_prefixes[i], length) == 0) {
|
||||
*priority = (SDL_LogPriority)i;
|
||||
return SDL_TRUE;
|
||||
}
|
||||
}
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
static SDL_bool SDL_ParseLogCategoryPriority(const char *hint, int category, SDL_LogPriority *priority)
|
||||
{
|
||||
const char *name, *next;
|
||||
int current_category;
|
||||
|
||||
if (category == DEFAULT_CATEGORY && SDL_strchr(hint, '=') == NULL) {
|
||||
return SDL_ParseLogPriority(hint, SDL_strlen(hint), priority);
|
||||
}
|
||||
|
||||
for (name = hint; name; name = next) {
|
||||
const char *sep = SDL_strchr(name, '=');
|
||||
if (!sep) {
|
||||
break;
|
||||
}
|
||||
next = SDL_strchr(sep, ',');
|
||||
if (next) {
|
||||
++next;
|
||||
}
|
||||
|
||||
if (SDL_ParseLogCategory(name, (sep - name), ¤t_category)) {
|
||||
if (current_category == category) {
|
||||
const char *value = sep + 1;
|
||||
size_t len;
|
||||
if (next) {
|
||||
len = (next - value - 1);
|
||||
} else {
|
||||
len = SDL_strlen(value);
|
||||
}
|
||||
return SDL_ParseLogPriority(value, len, priority);
|
||||
}
|
||||
}
|
||||
}
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
static SDL_LogPriority SDL_GetDefaultLogPriority(int category)
|
||||
{
|
||||
const char *hint = SDL_GetHint(SDL_HINT_LOGGING);
|
||||
if (hint) {
|
||||
SDL_LogPriority priority;
|
||||
|
||||
if (SDL_ParseLogCategoryPriority(hint, category, &priority)) {
|
||||
return priority;
|
||||
}
|
||||
if (SDL_ParseLogCategoryPriority(hint, DEFAULT_CATEGORY, &priority)) {
|
||||
return priority;
|
||||
}
|
||||
}
|
||||
|
||||
switch (category) {
|
||||
case SDL_LOG_CATEGORY_APPLICATION:
|
||||
return SDL_LOG_PRIORITY_INFO;
|
||||
case SDL_LOG_CATEGORY_ASSERT:
|
||||
return SDL_LOG_PRIORITY_WARN;
|
||||
case SDL_LOG_CATEGORY_TEST:
|
||||
return SDL_LOG_PRIORITY_VERBOSE;
|
||||
default:
|
||||
return SDL_LOG_PRIORITY_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_LogPriority SDL_LogGetPriority(int category)
|
||||
{
|
||||
SDL_LogLevel *entry;
|
||||
@@ -170,15 +283,11 @@ SDL_LogPriority SDL_LogGetPriority(int category)
|
||||
}
|
||||
}
|
||||
|
||||
if (category == SDL_LOG_CATEGORY_TEST) {
|
||||
return SDL_test_priority;
|
||||
} else if (category == SDL_LOG_CATEGORY_APPLICATION) {
|
||||
return SDL_application_priority;
|
||||
} else if (category == SDL_LOG_CATEGORY_ASSERT) {
|
||||
return SDL_assert_priority;
|
||||
} else {
|
||||
return SDL_default_priority;
|
||||
if (SDL_forced_priority) {
|
||||
return SDL_forced_priority_level;
|
||||
}
|
||||
|
||||
return SDL_GetDefaultLogPriority(category);
|
||||
}
|
||||
|
||||
void SDL_LogResetPriorities(void)
|
||||
@@ -190,11 +299,7 @@ void SDL_LogResetPriorities(void)
|
||||
SDL_loglevels = entry->next;
|
||||
SDL_free(entry);
|
||||
}
|
||||
|
||||
SDL_default_priority = DEFAULT_PRIORITY;
|
||||
SDL_assert_priority = DEFAULT_ASSERT_PRIORITY;
|
||||
SDL_application_priority = DEFAULT_APPLICATION_PRIORITY;
|
||||
SDL_test_priority = DEFAULT_TEST_PRIORITY;
|
||||
SDL_forced_priority = SDL_FALSE;
|
||||
}
|
||||
|
||||
void SDL_Log(SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
|
||||
@@ -269,7 +374,7 @@ void SDL_LogMessage(int category, SDL_LogPriority priority, SDL_PRINTF_FORMAT_ST
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#ifdef SDL_PLATFORM_ANDROID
|
||||
static const char *GetCategoryPrefix(int category)
|
||||
{
|
||||
if (category < SDL_LOG_CATEGORY_RESERVED1) {
|
||||
@@ -280,7 +385,7 @@ static const char *GetCategoryPrefix(int category)
|
||||
}
|
||||
return "CUSTOM";
|
||||
}
|
||||
#endif /* __ANDROID__ */
|
||||
#endif /* SDL_PLATFORM_ANDROID */
|
||||
|
||||
void SDL_LogMessageV(int category, SDL_LogPriority priority, SDL_PRINTF_FORMAT_STRING const char *fmt, va_list ap)
|
||||
{
|
||||
@@ -351,7 +456,7 @@ void SDL_LogMessageV(int category, SDL_LogPriority priority, SDL_PRINTF_FORMAT_S
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__WIN32__) && !defined(HAVE_STDIO_H) && !defined(__WINRT__) && !defined(__GDK__)
|
||||
#if defined(SDL_PLATFORM_WIN32) && !defined(HAVE_STDIO_H) && !defined(SDL_PLATFORM_WINRT) && !defined(SDL_PLATFORM_GDK)
|
||||
/* Flag tracking the attachment of the console: 0=unattached, 1=attached to a console, 2=attached to a file, -1=error */
|
||||
static int consoleAttached = 0;
|
||||
|
||||
@@ -362,7 +467,7 @@ static HANDLE stderrHandle = NULL;
|
||||
static void SDLCALL SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority,
|
||||
const char *message)
|
||||
{
|
||||
#if defined(__WIN32__) || defined(__WINRT__) || defined(__GDK__)
|
||||
#if defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_WINRT) || defined(SDL_PLATFORM_GDK)
|
||||
/* Way too many allocations here, urgh */
|
||||
/* Note: One can't call SDL_SetError here, since that function itself logs. */
|
||||
{
|
||||
@@ -371,7 +476,7 @@ static void SDLCALL SDL_LogOutput(void *userdata, int category, SDL_LogPriority
|
||||
LPTSTR tstr;
|
||||
SDL_bool isstack;
|
||||
|
||||
#if !defined(HAVE_STDIO_H) && !defined(__WINRT__) && !defined(__GDK__)
|
||||
#if !defined(HAVE_STDIO_H) && !defined(SDL_PLATFORM_WINRT) && !defined(SDL_PLATFORM_GDK)
|
||||
BOOL attachResult;
|
||||
DWORD attachError;
|
||||
DWORD charsWritten;
|
||||
@@ -410,7 +515,7 @@ static void SDLCALL SDL_LogOutput(void *userdata, int category, SDL_LogPriority
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* !defined(HAVE_STDIO_H) && !defined(__WINRT__) && !defined(__GDK__) */
|
||||
#endif /* !defined(HAVE_STDIO_H) && !defined(SDL_PLATFORM_WINRT) && !defined(SDL_PLATFORM_GDK) */
|
||||
|
||||
length = SDL_strlen(SDL_priority_prefixes[priority]) + 2 + SDL_strlen(message) + 1 + 1 + 1;
|
||||
output = SDL_small_alloc(char, length, &isstack);
|
||||
@@ -420,7 +525,7 @@ static void SDLCALL SDL_LogOutput(void *userdata, int category, SDL_LogPriority
|
||||
/* Output to debugger */
|
||||
OutputDebugString(tstr);
|
||||
|
||||
#if !defined(HAVE_STDIO_H) && !defined(__WINRT__) && !defined(__GDK__)
|
||||
#if !defined(HAVE_STDIO_H) && !defined(SDL_PLATFORM_WINRT) && !defined(SDL_PLATFORM_GDK)
|
||||
/* Screen output to stderr, if console was attached. */
|
||||
if (consoleAttached == 1) {
|
||||
if (!WriteConsole(stderrHandle, tstr, (DWORD)SDL_tcslen(tstr), &charsWritten, NULL)) {
|
||||
@@ -435,19 +540,19 @@ static void SDLCALL SDL_LogOutput(void *userdata, int category, SDL_LogPriority
|
||||
OutputDebugString(TEXT("Error calling WriteFile\r\n"));
|
||||
}
|
||||
}
|
||||
#endif /* !defined(HAVE_STDIO_H) && !defined(__WINRT__) && !defined(__GDK__) */
|
||||
#endif /* !defined(HAVE_STDIO_H) && !defined(SDL_PLATFORM_WINRT) && !defined(SDL_PLATFORM_GDK) */
|
||||
|
||||
SDL_free(tstr);
|
||||
SDL_small_free(output, isstack);
|
||||
}
|
||||
#elif defined(__ANDROID__)
|
||||
#elif defined(SDL_PLATFORM_ANDROID)
|
||||
{
|
||||
char tag[32];
|
||||
|
||||
SDL_snprintf(tag, SDL_arraysize(tag), "SDL/%s", GetCategoryPrefix(category));
|
||||
__android_log_write(SDL_android_priority[priority], tag, message);
|
||||
}
|
||||
#elif defined(__APPLE__) && (defined(SDL_VIDEO_DRIVER_COCOA) || defined(SDL_VIDEO_DRIVER_UIKIT))
|
||||
#elif defined(SDL_PLATFORM_APPLE) && (defined(SDL_VIDEO_DRIVER_COCOA) || defined(SDL_VIDEO_DRIVER_UIKIT))
|
||||
/* Technically we don't need Cocoa/UIKit, but that's where this function is defined for now.
|
||||
*/
|
||||
extern void SDL_NSLog(const char *prefix, const char *text);
|
||||
@@ -455,7 +560,7 @@ static void SDLCALL SDL_LogOutput(void *userdata, int category, SDL_LogPriority
|
||||
SDL_NSLog(SDL_priority_prefixes[priority], message);
|
||||
return;
|
||||
}
|
||||
#elif defined(__PSP__) || defined(__PS2__)
|
||||
#elif defined(SDL_PLATFORM_PSP) || defined(SDL_PLATFORM_PS2)
|
||||
{
|
||||
FILE *pFile;
|
||||
pFile = fopen("SDL_Log.txt", "a");
|
||||
@@ -464,7 +569,7 @@ static void SDLCALL SDL_LogOutput(void *userdata, int category, SDL_LogPriority
|
||||
(void)fclose(pFile);
|
||||
}
|
||||
}
|
||||
#elif defined(__VITA__)
|
||||
#elif defined(SDL_PLATFORM_VITA)
|
||||
{
|
||||
FILE *pFile;
|
||||
pFile = fopen("ux0:/data/SDL_Log.txt", "a");
|
||||
@@ -473,7 +578,7 @@ static void SDLCALL SDL_LogOutput(void *userdata, int category, SDL_LogPriority
|
||||
(void)fclose(pFile);
|
||||
}
|
||||
}
|
||||
#elif defined(__3DS__)
|
||||
#elif defined(SDL_PLATFORM_3DS)
|
||||
{
|
||||
FILE *pFile;
|
||||
pFile = fopen("sdmc:/3ds/SDL_Log.txt", "a");
|
||||
@@ -484,12 +589,12 @@ static void SDLCALL SDL_LogOutput(void *userdata, int category, SDL_LogPriority
|
||||
}
|
||||
#endif
|
||||
#if defined(HAVE_STDIO_H) && \
|
||||
!(defined(__APPLE__) && (defined(SDL_VIDEO_DRIVER_COCOA) || defined(SDL_VIDEO_DRIVER_UIKIT)))
|
||||
!(defined(SDL_PLATFORM_APPLE) && (defined(SDL_VIDEO_DRIVER_COCOA) || defined(SDL_VIDEO_DRIVER_UIKIT)))
|
||||
(void)fprintf(stderr, "%s: %s\n", SDL_priority_prefixes[priority], message);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SDL_LogGetOutputFunction(SDL_LogOutputFunction *callback, void **userdata)
|
||||
void SDL_GetLogOutputFunction(SDL_LogOutputFunction *callback, void **userdata)
|
||||
{
|
||||
if (callback) {
|
||||
*callback = SDL_log_function;
|
||||
@@ -499,7 +604,7 @@ void SDL_LogGetOutputFunction(SDL_LogOutputFunction *callback, void **userdata)
|
||||
}
|
||||
}
|
||||
|
||||
void SDL_LogSetOutputFunction(SDL_LogOutputFunction callback, void *userdata)
|
||||
void SDL_SetLogOutputFunction(SDL_LogOutputFunction callback, void *userdata)
|
||||
{
|
||||
SDL_log_function = callback;
|
||||
SDL_log_userdata = userdata;
|
||||
|
||||
139
external/sdl/SDL/src/SDL_properties.c
vendored
139
external/sdl/SDL/src/SDL_properties.c
vendored
@@ -150,7 +150,7 @@ SDL_PropertiesID SDL_CreateProperties(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
properties = SDL_calloc(1, sizeof(*properties));
|
||||
properties = (SDL_Properties *)SDL_calloc(1, sizeof(*properties));
|
||||
if (!properties) {
|
||||
goto error;
|
||||
}
|
||||
@@ -188,6 +188,78 @@ error:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDL_CopyProperties(SDL_PropertiesID src, SDL_PropertiesID dst)
|
||||
{
|
||||
SDL_Properties *src_properties = NULL;
|
||||
SDL_Properties *dst_properties = NULL;
|
||||
int result = 0;
|
||||
|
||||
if (!src) {
|
||||
return SDL_InvalidParamError("src");
|
||||
}
|
||||
if (!dst) {
|
||||
return SDL_InvalidParamError("dst");
|
||||
}
|
||||
|
||||
SDL_LockMutex(SDL_properties_lock);
|
||||
SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)src, (const void **)&src_properties);
|
||||
SDL_FindInHashTable(SDL_properties, (const void *)(uintptr_t)dst, (const void **)&dst_properties);
|
||||
SDL_UnlockMutex(SDL_properties_lock);
|
||||
|
||||
if (!src_properties) {
|
||||
return SDL_InvalidParamError("src");
|
||||
}
|
||||
if (!dst_properties) {
|
||||
return SDL_InvalidParamError("dst");
|
||||
}
|
||||
|
||||
SDL_LockMutex(src_properties->lock);
|
||||
SDL_LockMutex(dst_properties->lock);
|
||||
{
|
||||
void *iter;
|
||||
const void *key, *value;
|
||||
|
||||
iter = NULL;
|
||||
while (SDL_IterateHashTable(src_properties->props, &key, &value, &iter)) {
|
||||
const char *src_name = (const char *)key;
|
||||
const SDL_Property *src_property = (const SDL_Property *)value;
|
||||
char *dst_name;
|
||||
SDL_Property *dst_property;
|
||||
|
||||
if (src_property->cleanup) {
|
||||
/* Can't copy properties with cleanup functions, we don't know how to duplicate the data */
|
||||
continue;
|
||||
}
|
||||
|
||||
SDL_RemoveFromHashTable(dst_properties->props, src_name);
|
||||
|
||||
dst_name = SDL_strdup(src_name);
|
||||
if (!dst_name) {
|
||||
result = -1;
|
||||
continue;
|
||||
}
|
||||
dst_property = (SDL_Property *)SDL_malloc(sizeof(*dst_property));
|
||||
if (!dst_property) {
|
||||
SDL_free(dst_name);
|
||||
result = -1;
|
||||
continue;
|
||||
}
|
||||
SDL_copyp(dst_property, src_property);
|
||||
if (src_property->type == SDL_PROPERTY_TYPE_STRING) {
|
||||
dst_property->value.string_value = SDL_strdup(src_property->value.string_value);
|
||||
}
|
||||
if (!SDL_InsertIntoHashTable(dst_properties->props, dst_name, dst_property)) {
|
||||
SDL_FreePropertyWithCleanup(dst_name, dst_property, NULL, SDL_FALSE);
|
||||
result = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
SDL_UnlockMutex(dst_properties->lock);
|
||||
SDL_UnlockMutex(src_properties->lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int SDL_LockProperties(SDL_PropertiesID props)
|
||||
{
|
||||
SDL_Properties *properties = NULL;
|
||||
@@ -276,6 +348,7 @@ int SDL_SetPropertyWithCleanup(SDL_PropertiesID props, const char *name, void *v
|
||||
|
||||
property = (SDL_Property *)SDL_calloc(1, sizeof(*property));
|
||||
if (!property) {
|
||||
SDL_FreePropertyWithCleanup(NULL, property, NULL, SDL_FALSE);
|
||||
return -1;
|
||||
}
|
||||
property->type = SDL_PROPERTY_TYPE_POINTER;
|
||||
@@ -302,6 +375,27 @@ int SDL_SetProperty(SDL_PropertiesID props, const char *name, void *value)
|
||||
return SDL_PrivateSetProperty(props, name, property);
|
||||
}
|
||||
|
||||
static void SDLCALL CleanupFreeableProperty(void *userdata, void *value)
|
||||
{
|
||||
SDL_free(value);
|
||||
}
|
||||
|
||||
int SDL_SetFreeableProperty(SDL_PropertiesID props, const char *name, void *value)
|
||||
{
|
||||
return SDL_SetPropertyWithCleanup(props, name, value, CleanupFreeableProperty, NULL);
|
||||
}
|
||||
|
||||
static void SDLCALL CleanupSurface(void *userdata, void *value)
|
||||
{
|
||||
SDL_Surface *surface = (SDL_Surface *)value;
|
||||
|
||||
SDL_DestroySurface(surface);
|
||||
}
|
||||
|
||||
int SDL_SetSurfaceProperty(SDL_PropertiesID props, const char *name, SDL_Surface *surface)
|
||||
{
|
||||
return SDL_SetPropertyWithCleanup(props, name, surface, CleanupSurface, NULL);
|
||||
}
|
||||
|
||||
int SDL_SetStringProperty(SDL_PropertiesID props, const char *name, const char *value)
|
||||
{
|
||||
@@ -357,17 +451,20 @@ int SDL_SetBooleanProperty(SDL_PropertiesID props, const char *name, SDL_bool va
|
||||
return SDL_PrivateSetProperty(props, name, property);
|
||||
}
|
||||
|
||||
SDL_bool SDL_HasProperty(SDL_PropertiesID props, const char *name)
|
||||
{
|
||||
return (SDL_GetPropertyType(props, name) != SDL_PROPERTY_TYPE_INVALID);
|
||||
}
|
||||
|
||||
SDL_PropertyType SDL_GetPropertyType(SDL_PropertiesID props, const char *name)
|
||||
{
|
||||
SDL_Properties *properties = NULL;
|
||||
SDL_PropertyType type = SDL_PROPERTY_TYPE_INVALID;
|
||||
|
||||
if (!props) {
|
||||
SDL_InvalidParamError("props");
|
||||
return SDL_PROPERTY_TYPE_INVALID;
|
||||
}
|
||||
if (!name || !*name) {
|
||||
SDL_InvalidParamError("name");
|
||||
return SDL_PROPERTY_TYPE_INVALID;
|
||||
}
|
||||
|
||||
@@ -376,7 +473,6 @@ SDL_PropertyType SDL_GetPropertyType(SDL_PropertiesID props, const char *name)
|
||||
SDL_UnlockMutex(SDL_properties_lock);
|
||||
|
||||
if (!properties) {
|
||||
SDL_InvalidParamError("props");
|
||||
return SDL_PROPERTY_TYPE_INVALID;
|
||||
}
|
||||
|
||||
@@ -385,8 +481,6 @@ SDL_PropertyType SDL_GetPropertyType(SDL_PropertiesID props, const char *name)
|
||||
SDL_Property *property = NULL;
|
||||
if (SDL_FindInHashTable(properties->props, name, (const void **)&property)) {
|
||||
type = property->type;
|
||||
} else {
|
||||
SDL_SetError("Couldn't find property named %s", name);
|
||||
}
|
||||
}
|
||||
SDL_UnlockMutex(properties->lock);
|
||||
@@ -400,11 +494,9 @@ void *SDL_GetProperty(SDL_PropertiesID props, const char *name, void *default_va
|
||||
void *value = default_value;
|
||||
|
||||
if (!props) {
|
||||
SDL_InvalidParamError("props");
|
||||
return value;
|
||||
}
|
||||
if (!name || !*name) {
|
||||
SDL_InvalidParamError("name");
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -413,7 +505,6 @@ void *SDL_GetProperty(SDL_PropertiesID props, const char *name, void *default_va
|
||||
SDL_UnlockMutex(SDL_properties_lock);
|
||||
|
||||
if (!properties) {
|
||||
SDL_InvalidParamError("props");
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -427,11 +518,7 @@ void *SDL_GetProperty(SDL_PropertiesID props, const char *name, void *default_va
|
||||
if (SDL_FindInHashTable(properties->props, name, (const void **)&property)) {
|
||||
if (property->type == SDL_PROPERTY_TYPE_POINTER) {
|
||||
value = property->value.pointer_value;
|
||||
} else {
|
||||
SDL_SetError("Property %s isn't a pointer value", name);
|
||||
}
|
||||
} else {
|
||||
SDL_SetError("Couldn't find property named %s", name);
|
||||
}
|
||||
}
|
||||
SDL_UnlockMutex(properties->lock);
|
||||
@@ -445,11 +532,9 @@ const char *SDL_GetStringProperty(SDL_PropertiesID props, const char *name, cons
|
||||
const char *value = default_value;
|
||||
|
||||
if (!props) {
|
||||
SDL_InvalidParamError("props");
|
||||
return value;
|
||||
}
|
||||
if (!name || !*name) {
|
||||
SDL_InvalidParamError("name");
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -458,7 +543,6 @@ const char *SDL_GetStringProperty(SDL_PropertiesID props, const char *name, cons
|
||||
SDL_UnlockMutex(SDL_properties_lock);
|
||||
|
||||
if (!properties) {
|
||||
SDL_InvalidParamError("props");
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -480,7 +564,7 @@ const char *SDL_GetStringProperty(SDL_PropertiesID props, const char *name, cons
|
||||
if (property->string_storage) {
|
||||
value = property->string_storage;
|
||||
} else {
|
||||
SDL_asprintf(&property->string_storage, "%" SDL_PRIs64 "", property->value.number_value);
|
||||
SDL_asprintf(&property->string_storage, "%" SDL_PRIs64, property->value.number_value);
|
||||
if (property->string_storage) {
|
||||
value = property->string_storage;
|
||||
}
|
||||
@@ -500,11 +584,8 @@ const char *SDL_GetStringProperty(SDL_PropertiesID props, const char *name, cons
|
||||
value = property->value.boolean_value ? "true" : "false";
|
||||
break;
|
||||
default:
|
||||
SDL_SetError("Property %s isn't a string value", name);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
SDL_SetError("Couldn't find property named %s", name);
|
||||
}
|
||||
}
|
||||
SDL_UnlockMutex(properties->lock);
|
||||
@@ -518,11 +599,9 @@ Sint64 SDL_GetNumberProperty(SDL_PropertiesID props, const char *name, Sint64 de
|
||||
Sint64 value = default_value;
|
||||
|
||||
if (!props) {
|
||||
SDL_InvalidParamError("props");
|
||||
return value;
|
||||
}
|
||||
if (!name || !*name) {
|
||||
SDL_InvalidParamError("name");
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -531,7 +610,6 @@ Sint64 SDL_GetNumberProperty(SDL_PropertiesID props, const char *name, Sint64 de
|
||||
SDL_UnlockMutex(SDL_properties_lock);
|
||||
|
||||
if (!properties) {
|
||||
SDL_InvalidParamError("props");
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -553,11 +631,8 @@ Sint64 SDL_GetNumberProperty(SDL_PropertiesID props, const char *name, Sint64 de
|
||||
value = property->value.boolean_value;
|
||||
break;
|
||||
default:
|
||||
SDL_SetError("Property %s isn't a number value", name);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
SDL_SetError("Couldn't find property named %s", name);
|
||||
}
|
||||
}
|
||||
SDL_UnlockMutex(properties->lock);
|
||||
@@ -571,11 +646,9 @@ float SDL_GetFloatProperty(SDL_PropertiesID props, const char *name, float defau
|
||||
float value = default_value;
|
||||
|
||||
if (!props) {
|
||||
SDL_InvalidParamError("props");
|
||||
return value;
|
||||
}
|
||||
if (!name || !*name) {
|
||||
SDL_InvalidParamError("name");
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -584,7 +657,6 @@ float SDL_GetFloatProperty(SDL_PropertiesID props, const char *name, float defau
|
||||
SDL_UnlockMutex(SDL_properties_lock);
|
||||
|
||||
if (!properties) {
|
||||
SDL_InvalidParamError("props");
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -606,11 +678,8 @@ float SDL_GetFloatProperty(SDL_PropertiesID props, const char *name, float defau
|
||||
value = (float)property->value.boolean_value;
|
||||
break;
|
||||
default:
|
||||
SDL_SetError("Property %s isn't a float value", name);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
SDL_SetError("Couldn't find property named %s", name);
|
||||
}
|
||||
}
|
||||
SDL_UnlockMutex(properties->lock);
|
||||
@@ -624,11 +693,9 @@ SDL_bool SDL_GetBooleanProperty(SDL_PropertiesID props, const char *name, SDL_bo
|
||||
SDL_bool value = default_value;
|
||||
|
||||
if (!props) {
|
||||
SDL_InvalidParamError("props");
|
||||
return value;
|
||||
}
|
||||
if (!name || !*name) {
|
||||
SDL_InvalidParamError("name");
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -637,7 +704,6 @@ SDL_bool SDL_GetBooleanProperty(SDL_PropertiesID props, const char *name, SDL_bo
|
||||
SDL_UnlockMutex(SDL_properties_lock);
|
||||
|
||||
if (!properties) {
|
||||
SDL_InvalidParamError("props");
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -659,11 +725,8 @@ SDL_bool SDL_GetBooleanProperty(SDL_PropertiesID props, const char *name, SDL_bo
|
||||
value = property->value.boolean_value;
|
||||
break;
|
||||
default:
|
||||
SDL_SetError("Property %s isn't a boolean value", name);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
SDL_SetError("Couldn't find property named %s", name);
|
||||
}
|
||||
}
|
||||
SDL_UnlockMutex(properties->lock);
|
||||
|
||||
2
external/sdl/SDL/src/SDL_properties_c.h
vendored
2
external/sdl/SDL/src/SDL_properties_c.h
vendored
@@ -20,4 +20,6 @@
|
||||
*/
|
||||
|
||||
extern int SDL_InitProperties(void);
|
||||
extern int SDL_SetFreeableProperty(SDL_PropertiesID props, const char *name, void *value);
|
||||
extern int SDL_SetSurfaceProperty(SDL_PropertiesID props, const char *name, SDL_Surface *surface);
|
||||
extern void SDL_QuitProperties(void);
|
||||
|
||||
48
external/sdl/SDL/src/atomic/SDL_atomic.c
vendored
48
external/sdl/SDL/src/atomic/SDL_atomic.c
vendored
@@ -25,11 +25,11 @@
|
||||
#define HAVE_MSC_ATOMICS 1
|
||||
#endif
|
||||
|
||||
#ifdef __MACOS__ /* !!! FIXME: should we favor gcc atomics? */
|
||||
#ifdef SDL_PLATFORM_MACOS /* !!! FIXME: should we favor gcc atomics? */
|
||||
#include <libkern/OSAtomic.h>
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_GCC_ATOMICS) && defined(__SOLARIS__)
|
||||
#if !defined(HAVE_GCC_ATOMICS) && defined(SDL_PLATFORM_SOLARIS)
|
||||
#include <atomic.h>
|
||||
#endif
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
#if __has_builtin(__atomic_load_n) || defined(HAVE_GCC_ATOMICS)
|
||||
/* !!! FIXME: this advertises as available in the NDK but uses an external symbol we don't have.
|
||||
It might be in a later NDK or we might need an extra library? --ryan. */
|
||||
#ifndef __ANDROID__
|
||||
#ifndef SDL_PLATFORM_ANDROID
|
||||
#define HAVE_ATOMIC_LOAD_N 1
|
||||
#endif
|
||||
#endif
|
||||
@@ -100,7 +100,7 @@ extern __inline int _SDL_xadd_watcom(volatile int *a, int v);
|
||||
Contributed by Bob Pendleton, bob@pendleton.com
|
||||
*/
|
||||
|
||||
#if !defined(HAVE_MSC_ATOMICS) && !defined(HAVE_GCC_ATOMICS) && !defined(__MACOS__) && !defined(__SOLARIS__) && !defined(HAVE_WATCOM_ATOMICS)
|
||||
#if !defined(HAVE_MSC_ATOMICS) && !defined(HAVE_GCC_ATOMICS) && !defined(SDL_PLATFORM_MACOS) && !defined(SDL_PLATFORM_SOLARIS) && !defined(HAVE_WATCOM_ATOMICS)
|
||||
#define EMULATE_CAS 1
|
||||
#endif
|
||||
|
||||
@@ -111,18 +111,18 @@ static SDL_INLINE void enterLock(void *a)
|
||||
{
|
||||
uintptr_t index = ((((uintptr_t)a) >> 3) & 0x1f);
|
||||
|
||||
SDL_AtomicLock(&locks[index]);
|
||||
SDL_LockSpinlock(&locks[index]);
|
||||
}
|
||||
|
||||
static SDL_INLINE void leaveLock(void *a)
|
||||
{
|
||||
uintptr_t index = ((((uintptr_t)a) >> 3) & 0x1f);
|
||||
|
||||
SDL_AtomicUnlock(&locks[index]);
|
||||
SDL_UnlockSpinlock(&locks[index]);
|
||||
}
|
||||
#endif
|
||||
|
||||
SDL_bool SDL_AtomicCAS(SDL_AtomicInt *a, int oldval, int newval)
|
||||
SDL_bool SDL_AtomicCompareAndSwap(SDL_AtomicInt *a, int oldval, int newval)
|
||||
{
|
||||
#ifdef HAVE_MSC_ATOMICS
|
||||
SDL_COMPILE_TIME_ASSERT(atomic_cas, sizeof(long) == sizeof(a->value));
|
||||
@@ -131,9 +131,9 @@ SDL_bool SDL_AtomicCAS(SDL_AtomicInt *a, int oldval, int newval)
|
||||
return _SDL_cmpxchg_watcom(&a->value, newval, oldval);
|
||||
#elif defined(HAVE_GCC_ATOMICS)
|
||||
return __sync_bool_compare_and_swap(&a->value, oldval, newval);
|
||||
#elif defined(__MACOS__) /* this is deprecated in 10.12 sdk; favor gcc atomics. */
|
||||
#elif defined(SDL_PLATFORM_MACOS) /* this is deprecated in 10.12 sdk; favor gcc atomics. */
|
||||
return OSAtomicCompareAndSwap32Barrier(oldval, newval, &a->value);
|
||||
#elif defined(__SOLARIS__)
|
||||
#elif defined(SDL_PLATFORM_SOLARIS)
|
||||
return ((int)atomic_cas_uint((volatile uint_t *)&a->value, (uint_t)oldval, (uint_t)newval) == oldval);
|
||||
#elif defined(EMULATE_CAS)
|
||||
SDL_bool retval = SDL_FALSE;
|
||||
@@ -151,7 +151,7 @@ SDL_bool SDL_AtomicCAS(SDL_AtomicInt *a, int oldval, int newval)
|
||||
#endif
|
||||
}
|
||||
|
||||
SDL_bool SDL_AtomicCASPtr(void **a, void *oldval, void *newval)
|
||||
SDL_bool SDL_AtomicCompareAndSwapPointer(void **a, void *oldval, void *newval)
|
||||
{
|
||||
#ifdef HAVE_MSC_ATOMICS
|
||||
return _InterlockedCompareExchangePointer(a, newval, oldval) == oldval;
|
||||
@@ -159,11 +159,11 @@ SDL_bool SDL_AtomicCASPtr(void **a, void *oldval, void *newval)
|
||||
return _SDL_cmpxchg_watcom((int *)a, (long)newval, (long)oldval);
|
||||
#elif defined(HAVE_GCC_ATOMICS)
|
||||
return __sync_bool_compare_and_swap(a, oldval, newval);
|
||||
#elif defined(__MACOS__) && defined(__LP64__) /* this is deprecated in 10.12 sdk; favor gcc atomics. */
|
||||
#elif defined(SDL_PLATFORM_MACOS) && defined(__LP64__) /* this is deprecated in 10.12 sdk; favor gcc atomics. */
|
||||
return OSAtomicCompareAndSwap64Barrier((int64_t)oldval, (int64_t)newval, (int64_t *)a);
|
||||
#elif defined(__MACOS__) && !defined(__LP64__) /* this is deprecated in 10.12 sdk; favor gcc atomics. */
|
||||
#elif defined(SDL_PLATFORM_MACOS) && !defined(__LP64__) /* this is deprecated in 10.12 sdk; favor gcc atomics. */
|
||||
return OSAtomicCompareAndSwap32Barrier((int32_t)oldval, (int32_t)newval, (int32_t *)a);
|
||||
#elif defined(__SOLARIS__)
|
||||
#elif defined(SDL_PLATFORM_SOLARIS)
|
||||
return (atomic_cas_ptr(a, oldval, newval) == oldval);
|
||||
#elif defined(EMULATE_CAS)
|
||||
SDL_bool retval = SDL_FALSE;
|
||||
@@ -190,13 +190,13 @@ int SDL_AtomicSet(SDL_AtomicInt *a, int v)
|
||||
return _SDL_xchg_watcom(&a->value, v);
|
||||
#elif defined(HAVE_GCC_ATOMICS)
|
||||
return __sync_lock_test_and_set(&a->value, v);
|
||||
#elif defined(__SOLARIS__)
|
||||
#elif defined(SDL_PLATFORM_SOLARIS)
|
||||
return (int)atomic_swap_uint((volatile uint_t *)&a->value, v);
|
||||
#else
|
||||
int value;
|
||||
do {
|
||||
value = a->value;
|
||||
} while (!SDL_AtomicCAS(a, value, v));
|
||||
} while (!SDL_AtomicCompareAndSwap(a, value, v));
|
||||
return value;
|
||||
#endif
|
||||
}
|
||||
@@ -209,13 +209,13 @@ void *SDL_AtomicSetPtr(void **a, void *v)
|
||||
return (void *)_SDL_xchg_watcom((int *)a, (long)v);
|
||||
#elif defined(HAVE_GCC_ATOMICS)
|
||||
return __sync_lock_test_and_set(a, v);
|
||||
#elif defined(__SOLARIS__)
|
||||
#elif defined(SDL_PLATFORM_SOLARIS)
|
||||
return atomic_swap_ptr(a, v);
|
||||
#else
|
||||
void *value;
|
||||
do {
|
||||
value = *a;
|
||||
} while (!SDL_AtomicCASPtr(a, value, v));
|
||||
} while (!SDL_AtomicCompareAndSwapPointer(a, value, v));
|
||||
return value;
|
||||
#endif
|
||||
}
|
||||
@@ -229,7 +229,7 @@ int SDL_AtomicAdd(SDL_AtomicInt *a, int v)
|
||||
return _SDL_xadd_watcom(&a->value, v);
|
||||
#elif defined(HAVE_GCC_ATOMICS)
|
||||
return __sync_fetch_and_add(&a->value, v);
|
||||
#elif defined(__SOLARIS__)
|
||||
#elif defined(SDL_PLATFORM_SOLARIS)
|
||||
int pv = a->value;
|
||||
membar_consumer();
|
||||
atomic_add_int((volatile uint_t *)&a->value, v);
|
||||
@@ -238,7 +238,7 @@ int SDL_AtomicAdd(SDL_AtomicInt *a, int v)
|
||||
int value;
|
||||
do {
|
||||
value = a->value;
|
||||
} while (!SDL_AtomicCAS(a, value, (value + v)));
|
||||
} while (!SDL_AtomicCompareAndSwap(a, value, (value + v)));
|
||||
return value;
|
||||
#endif
|
||||
}
|
||||
@@ -254,15 +254,15 @@ int SDL_AtomicGet(SDL_AtomicInt *a)
|
||||
return _SDL_xadd_watcom(&a->value, 0);
|
||||
#elif defined(HAVE_GCC_ATOMICS)
|
||||
return __sync_or_and_fetch(&a->value, 0);
|
||||
#elif defined(__MACOS__) /* this is deprecated in 10.12 sdk; favor gcc atomics. */
|
||||
#elif defined(SDL_PLATFORM_MACOS) /* this is deprecated in 10.12 sdk; favor gcc atomics. */
|
||||
return sizeof(a->value) == sizeof(uint32_t) ? OSAtomicOr32Barrier(0, (volatile uint32_t *)&a->value) : OSAtomicAdd64Barrier(0, (volatile int64_t *)&a->value);
|
||||
#elif defined(__SOLARIS__)
|
||||
#elif defined(SDL_PLATFORM_SOLARIS)
|
||||
return atomic_or_uint((volatile uint_t *)&a->value, 0);
|
||||
#else
|
||||
int value;
|
||||
do {
|
||||
value = a->value;
|
||||
} while (!SDL_AtomicCAS(a, value, value));
|
||||
} while (!SDL_AtomicCompareAndSwap(a, value, value));
|
||||
return value;
|
||||
#endif
|
||||
}
|
||||
@@ -275,13 +275,13 @@ void *SDL_AtomicGetPtr(void **a)
|
||||
return _InterlockedCompareExchangePointer(a, NULL, NULL);
|
||||
#elif defined(HAVE_GCC_ATOMICS)
|
||||
return __sync_val_compare_and_swap(a, (void *)0, (void *)0);
|
||||
#elif defined(__SOLARIS__)
|
||||
#elif defined(SDL_PLATFORM_SOLARIS)
|
||||
return atomic_cas_ptr(a, (void *)0, (void *)0);
|
||||
#else
|
||||
void *value;
|
||||
do {
|
||||
value = *a;
|
||||
} while (!SDL_AtomicCASPtr(a, value, value));
|
||||
} while (!SDL_AtomicCompareAndSwapPointer(a, value, value));
|
||||
return value;
|
||||
#endif
|
||||
}
|
||||
|
||||
64
external/sdl/SDL/src/atomic/SDL_spinlock.c
vendored
64
external/sdl/SDL/src/atomic/SDL_spinlock.c
vendored
@@ -20,15 +20,15 @@
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#if defined(__WIN32__) || defined(__WINRT__) || defined(__GDK__)
|
||||
#if defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_WINRT) || defined(SDL_PLATFORM_GDK)
|
||||
#include "../core/windows/SDL_windows.h"
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_GCC_ATOMICS) && defined(__SOLARIS__)
|
||||
#if !defined(HAVE_GCC_ATOMICS) && defined(SDL_PLATFORM_SOLARIS)
|
||||
#include <atomic.h>
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_GCC_ATOMICS) && defined(__RISCOS__)
|
||||
#if !defined(HAVE_GCC_ATOMICS) && defined(SDL_PLATFORM_RISCOS)
|
||||
#include <unixlib/local.h>
|
||||
#endif
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
#include <kernel.h>
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_GCC_ATOMICS) && defined(__MACOS__)
|
||||
#if !defined(HAVE_GCC_ATOMICS) && defined(SDL_PLATFORM_MACOS)
|
||||
#include <libkern/OSAtomic.h>
|
||||
#endif
|
||||
|
||||
@@ -57,27 +57,9 @@ extern __inline int _SDL_xchg_watcom(volatile int *a, int v);
|
||||
/* *INDENT-ON* */ /* clang-format on */
|
||||
|
||||
/* This function is where all the magic happens... */
|
||||
SDL_bool SDL_AtomicTryLock(SDL_SpinLock *lock)
|
||||
SDL_bool SDL_TryLockSpinlock(SDL_SpinLock *lock)
|
||||
{
|
||||
#ifdef SDL_ATOMIC_DISABLED
|
||||
/* Terrible terrible damage */
|
||||
static SDL_Mutex *_spinlock_mutex;
|
||||
|
||||
if (!_spinlock_mutex) {
|
||||
/* Race condition on first lock... */
|
||||
_spinlock_mutex = SDL_CreateMutex();
|
||||
}
|
||||
SDL_LockMutex(_spinlock_mutex);
|
||||
if (*lock == 0) {
|
||||
*lock = 1;
|
||||
SDL_UnlockMutex(_spinlock_mutex);
|
||||
return SDL_TRUE;
|
||||
} else {
|
||||
SDL_UnlockMutex(_spinlock_mutex);
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
#elif defined(HAVE_GCC_ATOMICS) || defined(HAVE_GCC_SYNC_LOCK_TEST_AND_SET)
|
||||
#if defined(HAVE_GCC_ATOMICS) || defined(HAVE_GCC_SYNC_LOCK_TEST_AND_SET)
|
||||
return __sync_lock_test_and_set(lock, 1) == 0;
|
||||
|
||||
#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64))
|
||||
@@ -97,7 +79,7 @@ SDL_bool SDL_AtomicTryLock(SDL_SpinLock *lock)
|
||||
defined(__ARM_ARCH_5TEJ__))
|
||||
int result;
|
||||
|
||||
#ifdef __RISCOS__
|
||||
#ifdef SDL_PLATFORM_RISCOS
|
||||
if (__cpucap_have_rex()) {
|
||||
__asm__ __volatile__(
|
||||
"ldrex %0, [%2]\nteq %0, #0\nstrexeq %0, %1, [%2]"
|
||||
@@ -133,15 +115,15 @@ SDL_bool SDL_AtomicTryLock(SDL_SpinLock *lock)
|
||||
: "cc", "memory");
|
||||
return result == 0;
|
||||
|
||||
#elif defined(__MACOS__) || defined(__IOS__) || defined(__TVOS__)
|
||||
#elif defined(SDL_PLATFORM_MACOS) || defined(SDL_PLATFORM_IOS) || defined(SDL_PLATFORM_TVOS)
|
||||
/* Maybe used for PowerPC, but the Intel asm or gcc atomics are favored. */
|
||||
return OSAtomicCompareAndSwap32Barrier(0, 1, lock);
|
||||
|
||||
#elif defined(__SOLARIS__) && defined(_LP64)
|
||||
#elif defined(SDL_PLATFORM_SOLARIS) && defined(_LP64)
|
||||
/* Used for Solaris with non-gcc compilers. */
|
||||
return ((int)atomic_cas_64((volatile uint64_t *)lock, 0, 1) == 0);
|
||||
|
||||
#elif defined(__SOLARIS__) && !defined(_LP64)
|
||||
#elif defined(SDL_PLATFORM_SOLARIS) && !defined(_LP64)
|
||||
/* Used for Solaris with non-gcc compilers. */
|
||||
return ((int)atomic_cas_32((volatile uint32_t *)lock, 0, 1) == 0);
|
||||
#elif defined(PS2)
|
||||
@@ -160,16 +142,30 @@ SDL_bool SDL_AtomicTryLock(SDL_SpinLock *lock)
|
||||
}
|
||||
return res;
|
||||
#else
|
||||
#error Please implement for your platform.
|
||||
return SDL_FALSE;
|
||||
/* Terrible terrible damage */
|
||||
static SDL_Mutex *_spinlock_mutex;
|
||||
|
||||
if (!_spinlock_mutex) {
|
||||
/* Race condition on first lock... */
|
||||
_spinlock_mutex = SDL_CreateMutex();
|
||||
}
|
||||
SDL_LockMutex(_spinlock_mutex);
|
||||
if (*lock == 0) {
|
||||
*lock = 1;
|
||||
SDL_UnlockMutex(_spinlock_mutex);
|
||||
return SDL_TRUE;
|
||||
} else {
|
||||
SDL_UnlockMutex(_spinlock_mutex);
|
||||
return SDL_FALSE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void SDL_AtomicLock(SDL_SpinLock *lock)
|
||||
void SDL_LockSpinlock(SDL_SpinLock *lock)
|
||||
{
|
||||
int iterations = 0;
|
||||
/* FIXME: Should we have an eventual timeout? */
|
||||
while (!SDL_AtomicTryLock(lock)) {
|
||||
while (!SDL_TryLockSpinlock(lock)) {
|
||||
if (iterations < 32) {
|
||||
iterations++;
|
||||
SDL_CPUPauseInstruction();
|
||||
@@ -180,7 +176,7 @@ void SDL_AtomicLock(SDL_SpinLock *lock)
|
||||
}
|
||||
}
|
||||
|
||||
void SDL_AtomicUnlock(SDL_SpinLock *lock)
|
||||
void SDL_UnlockSpinlock(SDL_SpinLock *lock)
|
||||
{
|
||||
#if defined(HAVE_GCC_ATOMICS) || defined(HAVE_GCC_SYNC_LOCK_TEST_AND_SET)
|
||||
__sync_lock_release(lock);
|
||||
@@ -196,7 +192,7 @@ void SDL_AtomicUnlock(SDL_SpinLock *lock)
|
||||
SDL_CompilerBarrier();
|
||||
*lock = 0;
|
||||
|
||||
#elif defined(__SOLARIS__)
|
||||
#elif defined(SDL_PLATFORM_SOLARIS)
|
||||
/* Used for Solaris when not using gcc. */
|
||||
*lock = 0;
|
||||
membar_producer();
|
||||
|
||||
61
external/sdl/SDL/src/audio/SDL_audio.c
vendored
61
external/sdl/SDL/src/audio/SDL_audio.c
vendored
@@ -306,17 +306,17 @@ static void ReleaseAudioDevice(SDL_AudioDevice *device) SDL_NO_THREAD_SAFETY_ANA
|
||||
}
|
||||
|
||||
// If found, this locks _the physical device_ this logical device is associated with, before returning.
|
||||
static SDL_LogicalAudioDevice *ObtainLogicalAudioDevice(SDL_AudioDeviceID devid, SDL_AudioDevice **device) SDL_NO_THREAD_SAFETY_ANALYSIS // !!! FIXME: SDL_ACQUIRE
|
||||
static SDL_LogicalAudioDevice *ObtainLogicalAudioDevice(SDL_AudioDeviceID devid, SDL_AudioDevice **_device) SDL_NO_THREAD_SAFETY_ANALYSIS // !!! FIXME: SDL_ACQUIRE
|
||||
{
|
||||
SDL_assert(device != NULL);
|
||||
|
||||
*device = NULL;
|
||||
SDL_assert(_device != NULL);
|
||||
|
||||
if (!SDL_GetCurrentAudioDriver()) {
|
||||
SDL_SetError("Audio subsystem is not initialized");
|
||||
*_device = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SDL_AudioDevice *device = NULL;
|
||||
SDL_LogicalAudioDevice *logdev = NULL;
|
||||
|
||||
// bit #1 of devid is set for physical devices and unset for logical.
|
||||
@@ -325,19 +325,36 @@ static SDL_LogicalAudioDevice *ObtainLogicalAudioDevice(SDL_AudioDeviceID devid,
|
||||
SDL_LockRWLockForReading(current_audio.device_hash_lock);
|
||||
SDL_FindInHashTable(current_audio.device_hash, (const void *) (uintptr_t) devid, (const void **) &logdev);
|
||||
if (logdev) {
|
||||
*device = logdev->physical_device;
|
||||
RefPhysicalAudioDevice(*device); // reference it, in case the logical device migrates to a new default.
|
||||
device = logdev->physical_device;
|
||||
SDL_assert(device != NULL);
|
||||
RefPhysicalAudioDevice(device); // reference it, in case the logical device migrates to a new default.
|
||||
}
|
||||
SDL_UnlockRWLock(current_audio.device_hash_lock);
|
||||
|
||||
if (logdev) {
|
||||
// we have to release the device_hash_lock before we take the device lock, to avoid deadlocks, so do a loop
|
||||
// to make sure the correct physical device gets locked, in case we're in a race with the default changing.
|
||||
while (SDL_TRUE) {
|
||||
SDL_LockMutex(device->lock);
|
||||
SDL_AudioDevice *recheck_device = (SDL_AudioDevice *) SDL_AtomicGetPtr((void **) &logdev->physical_device);
|
||||
if (device == recheck_device) {
|
||||
break;
|
||||
}
|
||||
|
||||
// default changed from under us! Try again!
|
||||
RefPhysicalAudioDevice(recheck_device);
|
||||
SDL_UnlockMutex(device->lock);
|
||||
UnrefPhysicalAudioDevice(device);
|
||||
device = recheck_device;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!logdev) {
|
||||
SDL_SetError("Invalid audio device instance ID");
|
||||
} else {
|
||||
SDL_assert(*device != NULL);
|
||||
SDL_LockMutex((*device)->lock);
|
||||
}
|
||||
|
||||
*_device = device;
|
||||
return logdev;
|
||||
}
|
||||
|
||||
@@ -635,7 +652,7 @@ void SDL_AudioDeviceDisconnected(SDL_AudioDevice *device)
|
||||
const SDL_bool is_default_device = ((devid == current_audio.default_output_device_id) || (devid == current_audio.default_capture_device_id));
|
||||
SDL_UnlockRWLock(current_audio.device_hash_lock);
|
||||
|
||||
const SDL_bool first_disconnect = SDL_AtomicCAS(&device->zombie, 0, 1);
|
||||
const SDL_bool first_disconnect = SDL_AtomicCompareAndSwap(&device->zombie, 0, 1);
|
||||
if (first_disconnect) { // if already disconnected this device, don't do it twice.
|
||||
// Swap in "Zombie" versions of the usual platform interfaces, so the device will keep
|
||||
// making progress until the app closes it. Otherwise, streams might continue to
|
||||
@@ -809,7 +826,7 @@ int SDL_InitAudio(const char *driver_name)
|
||||
}
|
||||
|
||||
// make sure device IDs start at 2 (because of SDL2 legacy interface), but don't reset the counter on each init, in case the app is holding an old device ID somewhere.
|
||||
SDL_AtomicCAS(&last_device_instance_id, 0, 2);
|
||||
SDL_AtomicCompareAndSwap(&last_device_instance_id, 0, 2);
|
||||
|
||||
SDL_ChooseAudioConverters();
|
||||
SDL_SetupAudioResampler();
|
||||
@@ -1775,15 +1792,11 @@ int SDL_BindAudioStreams(SDL_AudioDeviceID devid, SDL_AudioStream **streams, int
|
||||
|
||||
if (retval != 0) {
|
||||
int j;
|
||||
for (j = 0; j <= i; j++) {
|
||||
#ifdef _MSC_VER /* Visual Studio analyzer can't tell that we've already verified streams[j] isn't NULL */
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 28182)
|
||||
#endif
|
||||
for (j = 0; j < i; j++) {
|
||||
SDL_UnlockMutex(streams[j]->lock);
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
}
|
||||
if (stream) {
|
||||
SDL_UnlockMutex(stream->lock);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1890,7 +1903,7 @@ void SDL_UnbindAudioStreams(SDL_AudioStream **streams, int num_streams)
|
||||
// Finalize and unlock everything.
|
||||
for (int i = 0; i < num_streams; i++) {
|
||||
SDL_AudioStream *stream = streams[i];
|
||||
if (stream && stream->bound_device) {
|
||||
if (stream) {
|
||||
SDL_LogicalAudioDevice *logdev = stream->bound_device;
|
||||
stream->bound_device = NULL;
|
||||
SDL_UnlockMutex(stream->lock);
|
||||
@@ -1945,12 +1958,18 @@ SDL_AudioStream *SDL_OpenAudioDeviceStream(SDL_AudioDeviceID devid, const SDL_Au
|
||||
stream = SDL_CreateAudioStream(spec, &device->spec);
|
||||
}
|
||||
|
||||
if (!stream || (SDL_BindAudioStream(logdevid, stream) == -1)) {
|
||||
if (!stream) {
|
||||
failed = SDL_TRUE;
|
||||
} else {
|
||||
// don't do all the complicated validation and locking of SDL_BindAudioStream just to set a few fields here.
|
||||
logdev->bound_streams = stream;
|
||||
logdev->simplified = SDL_TRUE; // forbid further binding changes on this logical device.
|
||||
|
||||
stream->bound_device = logdev;
|
||||
stream->simplified = SDL_TRUE; // so we know to close the audio device when this is destroyed.
|
||||
|
||||
UpdateAudioStreamFormatsPhysical(device);
|
||||
|
||||
if (callback) {
|
||||
int rc;
|
||||
if (iscapture) {
|
||||
|
||||
6
external/sdl/SDL/src/audio/SDL_audiocvt.c
vendored
6
external/sdl/SDL/src/audio/SDL_audiocvt.c
vendored
@@ -666,7 +666,7 @@ int SDL_PutAudioStreamData(SDL_AudioStream *stream, const void *buf, int len)
|
||||
SDL_UnlockMutex(stream->lock);
|
||||
|
||||
size_t chunk_size = SDL_GetAudioQueueChunkSize(stream->queue);
|
||||
track = SDL_CreateChunkedAudioTrack(&src_spec, buf, len, chunk_size);
|
||||
track = SDL_CreateChunkedAudioTrack(&src_spec, (const Uint8 *)buf, len, chunk_size);
|
||||
|
||||
if (!track) {
|
||||
return -1;
|
||||
@@ -682,7 +682,7 @@ int SDL_PutAudioStreamData(SDL_AudioStream *stream, const void *buf, int len)
|
||||
if (track) {
|
||||
SDL_AddTrackToAudioQueue(stream->queue, track);
|
||||
} else {
|
||||
retval = SDL_WriteToAudioQueue(stream->queue, &stream->src_spec, buf, len);
|
||||
retval = SDL_WriteToAudioQueue(stream->queue, &stream->src_spec, (const Uint8 *)buf, len);
|
||||
}
|
||||
|
||||
if (retval == 0) {
|
||||
@@ -874,7 +874,7 @@ static int GetAudioStreamDataInternal(SDL_AudioStream *stream, void *buf, int ou
|
||||
// Note, this is just to avoid extra copies.
|
||||
// Some other formats may fit directly into the output buffer, but i'd rather process data in a SIMD-aligned buffer.
|
||||
if ((src_format == dst_format) && (src_channels == dst_channels)) {
|
||||
input_buffer = buf;
|
||||
input_buffer = (Uint8 *)buf;
|
||||
} else {
|
||||
input_buffer = EnsureAudioStreamWorkBufferSize(stream, output_frames * max_frame_size);
|
||||
|
||||
|
||||
10
external/sdl/SDL/src/audio/SDL_audiodev.c
vendored
10
external/sdl/SDL/src/audio/SDL_audiodev.c
vendored
@@ -32,7 +32,7 @@
|
||||
#include "SDL_audiodev_c.h"
|
||||
|
||||
#ifndef SDL_PATH_DEV_DSP
|
||||
#if defined(__NETBSD__) || defined(__OPENBSD__)
|
||||
#if defined(SDL_PLATFORM_NETBSD) || defined(SDL_PLATFORM_OPENBSD)
|
||||
#define SDL_PATH_DEV_DSP "/dev/audio"
|
||||
#else
|
||||
#define SDL_PATH_DEV_DSP "/dev/dsp"
|
||||
@@ -48,9 +48,9 @@
|
||||
static void test_device(const SDL_bool iscapture, const char *fname, int flags, SDL_bool (*test)(int fd))
|
||||
{
|
||||
struct stat sb;
|
||||
if ((stat(fname, &sb) == 0) && (S_ISCHR(sb.st_mode))) {
|
||||
const int audio_fd = open(fname, flags | O_CLOEXEC, 0);
|
||||
if (audio_fd >= 0) {
|
||||
const int audio_fd = open(fname, flags | O_CLOEXEC, 0);
|
||||
if (audio_fd >= 0) {
|
||||
if ((fstat(audio_fd, &sb) == 0) && (S_ISCHR(sb.st_mode))) {
|
||||
const SDL_bool okay = test(audio_fd);
|
||||
close(audio_fd);
|
||||
if (okay) {
|
||||
@@ -65,6 +65,8 @@ static void test_device(const SDL_bool iscapture, const char *fname, int flags,
|
||||
*/
|
||||
SDL_AddAudioDevice(iscapture, fname, NULL, (void *)(uintptr_t)dummyhandle);
|
||||
}
|
||||
} else {
|
||||
close(audio_fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
10
external/sdl/SDL/src/audio/SDL_audioqueue.c
vendored
10
external/sdl/SDL/src/audio/SDL_audioqueue.c
vendored
@@ -134,14 +134,14 @@ static SDL_AudioChunk *CreateAudioTrackChunk(SDL_ChunkedAudioTrack *track)
|
||||
|
||||
static size_t AvailChunkedAudioTrack(void *ctx)
|
||||
{
|
||||
SDL_ChunkedAudioTrack *track = ctx;
|
||||
SDL_ChunkedAudioTrack *track = (SDL_ChunkedAudioTrack *)ctx;
|
||||
|
||||
return track->queued_bytes;
|
||||
}
|
||||
|
||||
static int WriteToChunkedAudioTrack(void *ctx, const Uint8 *data, size_t len)
|
||||
{
|
||||
SDL_ChunkedAudioTrack *track = ctx;
|
||||
SDL_ChunkedAudioTrack *track = (SDL_ChunkedAudioTrack *)ctx;
|
||||
|
||||
SDL_AudioChunk *chunk = track->tail;
|
||||
|
||||
@@ -200,7 +200,7 @@ static int WriteToChunkedAudioTrack(void *ctx, const Uint8 *data, size_t len)
|
||||
|
||||
static size_t ReadFromChunkedAudioTrack(void *ctx, Uint8 *data, size_t len, SDL_bool advance)
|
||||
{
|
||||
SDL_ChunkedAudioTrack *track = ctx;
|
||||
SDL_ChunkedAudioTrack *track = (SDL_ChunkedAudioTrack *)ctx;
|
||||
SDL_AudioChunk *chunk = track->head;
|
||||
|
||||
size_t total = 0;
|
||||
@@ -245,7 +245,7 @@ static size_t ReadFromChunkedAudioTrack(void *ctx, Uint8 *data, size_t len, SDL_
|
||||
|
||||
static void DestroyChunkedAudioTrack(void *ctx)
|
||||
{
|
||||
SDL_ChunkedAudioTrack *track = ctx;
|
||||
SDL_ChunkedAudioTrack *track = (SDL_ChunkedAudioTrack *)ctx;
|
||||
DestroyAudioChunks(track->head);
|
||||
DestroyAudioChunks(track->free_chunks);
|
||||
SDL_free(track);
|
||||
@@ -420,7 +420,7 @@ void *SDL_BeginAudioQueueIter(SDL_AudioQueue *queue)
|
||||
|
||||
size_t SDL_NextAudioQueueIter(SDL_AudioQueue *queue, void **inout_iter, SDL_AudioSpec *out_spec, SDL_bool *out_flushed)
|
||||
{
|
||||
SDL_AudioTrack *iter = *inout_iter;
|
||||
SDL_AudioTrack *iter = (SDL_AudioTrack *)(*inout_iter);
|
||||
SDL_assert(iter != NULL);
|
||||
|
||||
SDL_copyp(out_spec, &iter->spec);
|
||||
|
||||
23
external/sdl/SDL/src/audio/SDL_audiotypecvt.c
vendored
23
external/sdl/SDL/src/audio/SDL_audiotypecvt.c
vendored
@@ -25,26 +25,9 @@
|
||||
// TODO: NEON is disabled until https://github.com/libsdl-org/SDL/issues/8352 can be fixed
|
||||
#undef SDL_NEON_INTRINSICS
|
||||
|
||||
#ifndef SDL_CPUINFO_DISABLED
|
||||
#if defined(__x86_64__) && defined(SDL_SSE2_INTRINSICS)
|
||||
#define NEED_SCALAR_CONVERTER_FALLBACKS 0 // x86_64 guarantees SSE2.
|
||||
#elif defined(__MACOS__) && defined(SDL_SSE2_INTRINSICS)
|
||||
#define NEED_SCALAR_CONVERTER_FALLBACKS 0 // macOS/Intel guarantees SSE2.
|
||||
#elif defined(__ARM_ARCH) && (__ARM_ARCH >= 8) && defined(SDL_NEON_INTRINSICS)
|
||||
#define NEED_SCALAR_CONVERTER_FALLBACKS 0 // ARMv8+ promise NEON.
|
||||
#elif defined(__APPLE__) && defined(__ARM_ARCH) && (__ARM_ARCH >= 7) && defined(SDL_NEON_INTRINSICS)
|
||||
#define NEED_SCALAR_CONVERTER_FALLBACKS 0 // All Apple ARMv7 chips promise NEON support.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Set to zero if platform is guaranteed to use a SIMD codepath here.
|
||||
#if !defined(NEED_SCALAR_CONVERTER_FALLBACKS) || defined(SDL_CPUINFO_DISABLED)
|
||||
#define NEED_SCALAR_CONVERTER_FALLBACKS 1
|
||||
#endif
|
||||
|
||||
#define DIVBY2147483648 0.0000000004656612873077392578125f // 0x1p-31f
|
||||
|
||||
#if NEED_SCALAR_CONVERTER_FALLBACKS
|
||||
// start fallback scalar converters
|
||||
|
||||
// This code requires that floats are in the IEEE-754 binary32 format
|
||||
SDL_COMPILE_TIME_ASSERT(float_bits, sizeof(float) == sizeof(Uint32));
|
||||
@@ -201,7 +184,7 @@ static void SDL_Convert_F32_to_S32_Scalar(Sint32 *dst, const float *src, int num
|
||||
|
||||
#undef SIGNMASK
|
||||
|
||||
#endif // NEED_SCALAR_CONVERTER_FALLBACKS
|
||||
// end fallback scalar converters
|
||||
|
||||
#ifdef SDL_SSE2_INTRINSICS
|
||||
static void SDL_TARGETING("sse2") SDL_Convert_S8_to_F32_SSE2(float *dst, const Sint8 *src, int num_samples)
|
||||
@@ -999,9 +982,7 @@ void SDL_ChooseAudioConverters(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if NEED_SCALAR_CONVERTER_FALLBACKS
|
||||
SET_CONVERTER_FUNCS(Scalar);
|
||||
#endif
|
||||
|
||||
#undef SET_CONVERTER_FUNCS
|
||||
|
||||
|
||||
50
external/sdl/SDL/src/audio/SDL_wave.c
vendored
50
external/sdl/SDL/src/audio/SDL_wave.c
vendored
@@ -1502,7 +1502,7 @@ static void WaveFreeChunkData(WaveChunk *chunk)
|
||||
chunk->size = 0;
|
||||
}
|
||||
|
||||
static int WaveNextChunk(SDL_RWops *src, WaveChunk *chunk)
|
||||
static int WaveNextChunk(SDL_IOStream *src, WaveChunk *chunk)
|
||||
{
|
||||
Uint32 chunkheader[2];
|
||||
Sint64 nextposition = chunk->position + chunk->length;
|
||||
@@ -1520,10 +1520,10 @@ static int WaveNextChunk(SDL_RWops *src, WaveChunk *chunk)
|
||||
nextposition++;
|
||||
}
|
||||
|
||||
if (SDL_RWseek(src, nextposition, SDL_RW_SEEK_SET) != nextposition) {
|
||||
if (SDL_SeekIO(src, nextposition, SDL_IO_SEEK_SET) != nextposition) {
|
||||
/* Not sure how we ended up here. Just abort. */
|
||||
return -2;
|
||||
} else if (SDL_RWread(src, chunkheader, sizeof(Uint32) * 2) != (sizeof(Uint32) * 2)) {
|
||||
} else if (SDL_ReadIO(src, chunkheader, sizeof(Uint32) * 2) != (sizeof(Uint32) * 2)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1534,7 +1534,7 @@ static int WaveNextChunk(SDL_RWops *src, WaveChunk *chunk)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int WaveReadPartialChunkData(SDL_RWops *src, WaveChunk *chunk, size_t length)
|
||||
static int WaveReadPartialChunkData(SDL_IOStream *src, WaveChunk *chunk, size_t length)
|
||||
{
|
||||
WaveFreeChunkData(chunk);
|
||||
|
||||
@@ -1548,12 +1548,12 @@ static int WaveReadPartialChunkData(SDL_RWops *src, WaveChunk *chunk, size_t len
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (SDL_RWseek(src, chunk->position, SDL_RW_SEEK_SET) != chunk->position) {
|
||||
if (SDL_SeekIO(src, chunk->position, SDL_IO_SEEK_SET) != chunk->position) {
|
||||
/* Not sure how we ended up here. Just abort. */
|
||||
return -2;
|
||||
}
|
||||
|
||||
chunk->size = SDL_RWread(src, chunk->data, length);
|
||||
chunk->size = SDL_ReadIO(src, chunk->data, length);
|
||||
if (chunk->size != length) {
|
||||
/* Expected to be handled by the caller. */
|
||||
}
|
||||
@@ -1562,7 +1562,7 @@ static int WaveReadPartialChunkData(SDL_RWops *src, WaveChunk *chunk, size_t len
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int WaveReadChunkData(SDL_RWops *src, WaveChunk *chunk)
|
||||
static int WaveReadChunkData(SDL_IOStream *src, WaveChunk *chunk)
|
||||
{
|
||||
return WaveReadPartialChunkData(src, chunk, chunk->length);
|
||||
}
|
||||
@@ -1602,14 +1602,14 @@ static int WaveReadFormat(WaveFile *file)
|
||||
{
|
||||
WaveChunk *chunk = &file->chunk;
|
||||
WaveFormat *format = &file->format;
|
||||
SDL_RWops *fmtsrc;
|
||||
SDL_IOStream *fmtsrc;
|
||||
size_t fmtlen = chunk->size;
|
||||
|
||||
if (fmtlen > SDL_MAX_SINT32) {
|
||||
/* Limit given by SDL_RWFromConstMem. */
|
||||
/* Limit given by SDL_IOFromConstMem. */
|
||||
return SDL_SetError("Data of WAVE fmt chunk too big");
|
||||
}
|
||||
fmtsrc = SDL_RWFromConstMem(chunk->data, (int)chunk->size);
|
||||
fmtsrc = SDL_IOFromConstMem(chunk->data, (int)chunk->size);
|
||||
if (!fmtsrc) {
|
||||
return -1;
|
||||
}
|
||||
@@ -1629,7 +1629,7 @@ static int WaveReadFormat(WaveFile *file)
|
||||
return -1;
|
||||
}
|
||||
} else if (format->encoding == PCM_CODE) {
|
||||
SDL_RWclose(fmtsrc);
|
||||
SDL_CloseIO(fmtsrc);
|
||||
return SDL_SetError("Missing wBitsPerSample field in WAVE fmt chunk");
|
||||
}
|
||||
|
||||
@@ -1649,19 +1649,19 @@ static int WaveReadFormat(WaveFile *file)
|
||||
|
||||
/* Extensible header must be at least 22 bytes. */
|
||||
if (fmtlen < 40 || format->extsize < 22) {
|
||||
SDL_RWclose(fmtsrc);
|
||||
SDL_CloseIO(fmtsrc);
|
||||
return SDL_SetError("Extensible WAVE header too small");
|
||||
}
|
||||
|
||||
if (!SDL_ReadU16LE(fmtsrc, &format->validsamplebits) ||
|
||||
!SDL_ReadU32LE(fmtsrc, &format->channelmask) ||
|
||||
SDL_RWread(fmtsrc, format->subformat, 16) != 16) {
|
||||
SDL_ReadIO(fmtsrc, format->subformat, 16) != 16) {
|
||||
}
|
||||
format->samplesperblock = format->validsamplebits;
|
||||
format->encoding = WaveGetFormatGUIDEncoding(format);
|
||||
}
|
||||
|
||||
SDL_RWclose(fmtsrc);
|
||||
SDL_CloseIO(fmtsrc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1769,7 +1769,7 @@ static int WaveCheckFormat(WaveFile *file, size_t datalength)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int WaveLoad(SDL_RWops *src, WaveFile *file, SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len)
|
||||
static int WaveLoad(SDL_IOStream *src, WaveFile *file, SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len)
|
||||
{
|
||||
int result;
|
||||
Uint32 chunkcount = 0;
|
||||
@@ -1795,7 +1795,7 @@ static int WaveLoad(SDL_RWops *src, WaveFile *file, SDL_AudioSpec *spec, Uint8 *
|
||||
}
|
||||
}
|
||||
|
||||
RIFFstart = SDL_RWtell(src);
|
||||
RIFFstart = SDL_TellIO(src);
|
||||
if (RIFFstart < 0) {
|
||||
return SDL_SetError("Could not seek in file");
|
||||
}
|
||||
@@ -1897,7 +1897,7 @@ static int WaveLoad(SDL_RWops *src, WaveFile *file, SDL_AudioSpec *spec, Uint8 *
|
||||
file->fact.status = -1;
|
||||
} else {
|
||||
/* Let's use src directly, it's just too convenient. */
|
||||
Sint64 position = SDL_RWseek(src, chunk->position, SDL_RW_SEEK_SET);
|
||||
Sint64 position = SDL_SeekIO(src, chunk->position, SDL_IO_SEEK_SET);
|
||||
if (position == chunk->position && SDL_ReadU32LE(src, &file->fact.samplelength)) {
|
||||
file->fact.status = 1;
|
||||
} else {
|
||||
@@ -1940,7 +1940,7 @@ static int WaveLoad(SDL_RWops *src, WaveFile *file, SDL_AudioSpec *spec, Uint8 *
|
||||
if (chunk->fourcc != DATA && chunk->length > 0) {
|
||||
Uint8 tmp;
|
||||
Uint64 position = (Uint64)chunk->position + chunk->length - 1;
|
||||
if (position > SDL_MAX_SINT64 || SDL_RWseek(src, (Sint64)position, SDL_RW_SEEK_SET) != (Sint64)position) {
|
||||
if (position > SDL_MAX_SINT64 || SDL_SeekIO(src, (Sint64)position, SDL_IO_SEEK_SET) != (Sint64)position) {
|
||||
return SDL_SetError("Could not seek to WAVE chunk data");
|
||||
} else if (!SDL_ReadU8(src, &tmp)) {
|
||||
return SDL_SetError("RIFF size truncates chunk");
|
||||
@@ -2075,14 +2075,14 @@ static int WaveLoad(SDL_RWops *src, WaveFile *file, SDL_AudioSpec *spec, Uint8 *
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDL_LoadWAV_RW(SDL_RWops *src, SDL_bool freesrc, SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len)
|
||||
int SDL_LoadWAV_IO(SDL_IOStream *src, SDL_bool closeio, SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len)
|
||||
{
|
||||
int result = -1;
|
||||
WaveFile file;
|
||||
|
||||
/* Make sure we are passed a valid data source */
|
||||
if (!src) {
|
||||
goto done; /* Error may come from RWops. */
|
||||
goto done; /* Error may come from SDL_IOStream. */
|
||||
} else if (!spec) {
|
||||
SDL_InvalidParamError("spec");
|
||||
goto done;
|
||||
@@ -2110,20 +2110,20 @@ int SDL_LoadWAV_RW(SDL_RWops *src, SDL_bool freesrc, SDL_AudioSpec *spec, Uint8
|
||||
}
|
||||
|
||||
/* Cleanup */
|
||||
if (!freesrc) {
|
||||
SDL_RWseek(src, file.chunk.position, SDL_RW_SEEK_SET);
|
||||
if (!closeio) {
|
||||
SDL_SeekIO(src, file.chunk.position, SDL_IO_SEEK_SET);
|
||||
}
|
||||
WaveFreeChunkData(&file.chunk);
|
||||
SDL_free(file.decoderdata);
|
||||
done:
|
||||
if (freesrc && src) {
|
||||
SDL_RWclose(src);
|
||||
if (closeio && src) {
|
||||
SDL_CloseIO(src);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int SDL_LoadWAV(const char *path, SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len)
|
||||
{
|
||||
return SDL_LoadWAV_RW(SDL_RWFromFile(path, "rb"), 1, spec, audio_buf, audio_len);
|
||||
return SDL_LoadWAV_IO(SDL_IOFromFile(path, "rb"), 1, spec, audio_buf, audio_len);
|
||||
}
|
||||
|
||||
|
||||
19
external/sdl/SDL/src/audio/aaudio/SDL_aaudio.c
vendored
19
external/sdl/SDL/src/audio/aaudio/SDL_aaudio.c
vendored
@@ -381,6 +381,12 @@ static int BuildAAudioStream(SDL_AudioDevice *device)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// !!! FIXME: make this non-blocking!
|
||||
static void SDLCALL AndroidRequestPermissionBlockingCallback(void *userdata, const char *permission, SDL_bool granted)
|
||||
{
|
||||
SDL_AtomicSet((SDL_AtomicInt *) userdata, granted ? 1 : -1);
|
||||
}
|
||||
|
||||
static int AAUDIO_OpenDevice(SDL_AudioDevice *device)
|
||||
{
|
||||
#if ALLOW_MULTIPLE_ANDROID_AUDIO_DEVICES
|
||||
@@ -390,7 +396,18 @@ static int AAUDIO_OpenDevice(SDL_AudioDevice *device)
|
||||
LOGI(__func__);
|
||||
|
||||
if (device->iscapture) {
|
||||
if (!Android_JNI_RequestPermission("android.permission.RECORD_AUDIO")) {
|
||||
// !!! FIXME: make this non-blocking!
|
||||
SDL_AtomicInt permission_response;
|
||||
SDL_AtomicSet(&permission_response, 0);
|
||||
if (SDL_AndroidRequestPermission("android.permission.RECORD_AUDIO", AndroidRequestPermissionBlockingCallback, &permission_response) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (SDL_AtomicGet(&permission_response) == 0) {
|
||||
SDL_Delay(10);
|
||||
}
|
||||
|
||||
if (SDL_AtomicGet(&permission_response) < 0) {
|
||||
LOGI("This app doesn't have RECORD_AUDIO permission");
|
||||
return SDL_SetError("This app doesn't have RECORD_AUDIO permission");
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
#include "../SDL_sysaudio.h"
|
||||
|
||||
#ifndef __IOS__
|
||||
#ifndef SDL_PLATFORM_IOS
|
||||
#define MACOSX_COREAUDIO
|
||||
#endif
|
||||
|
||||
|
||||
@@ -417,7 +417,7 @@ static SDL_bool UpdateAudioSession(SDL_AudioDevice *device, SDL_bool open, SDL_b
|
||||
category = AVAudioSessionCategoryRecord;
|
||||
}
|
||||
|
||||
#if !TARGET_OS_TV
|
||||
#ifndef SDL_PLATFORM_TVOS
|
||||
if (category == AVAudioSessionCategoryPlayAndRecord) {
|
||||
options |= AVAudioSessionCategoryOptionDefaultToSpeaker;
|
||||
}
|
||||
@@ -753,7 +753,7 @@ static int PrepareAudioQueue(SDL_AudioDevice *device)
|
||||
|
||||
// Make sure we can feed the device a minimum amount of time
|
||||
double MINIMUM_AUDIO_BUFFER_TIME_MS = 15.0;
|
||||
#ifdef __IOS__
|
||||
#ifdef SDL_PLATFORM_IOS
|
||||
if (SDL_floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_7_1) {
|
||||
// Older iOS hardware, use 40 ms as a minimum time
|
||||
MINIMUM_AUDIO_BUFFER_TIME_MS = 40.0;
|
||||
@@ -846,17 +846,17 @@ static int COREAUDIO_OpenDevice(SDL_AudioDevice *device)
|
||||
AVAudioSession *session = [AVAudioSession sharedInstance];
|
||||
[session setPreferredSampleRate:device->spec.freq error:nil];
|
||||
device->spec.freq = (int)session.sampleRate;
|
||||
#if TARGET_OS_TV
|
||||
#ifdef SDL_PLATFORM_TVOS
|
||||
if (device->iscapture) {
|
||||
[session setPreferredInputNumberOfChannels:device->spec.channels error:nil];
|
||||
device->spec.channels = session.preferredInputNumberOfChannels;
|
||||
device->spec.channels = (int)session.preferredInputNumberOfChannels;
|
||||
} else {
|
||||
[session setPreferredOutputNumberOfChannels:device->spec.channels error:nil];
|
||||
device->spec.channels = session.preferredOutputNumberOfChannels;
|
||||
device->spec.channels = (int)session.preferredOutputNumberOfChannels;
|
||||
}
|
||||
#else
|
||||
// Calling setPreferredOutputNumberOfChannels seems to break audio output on iOS
|
||||
#endif // TARGET_OS_TV
|
||||
#endif /* SDL_PLATFORM_TVOS */
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -51,6 +51,10 @@ static fnDirectSoundCaptureCreate8 pDirectSoundCaptureCreate8 = NULL;
|
||||
static fnDirectSoundCaptureEnumerateW pDirectSoundCaptureEnumerateW = NULL;
|
||||
static fnGetDeviceID pGetDeviceID = NULL;
|
||||
|
||||
#include <initguid.h>
|
||||
DEFINE_GUID(SDL_DSDEVID_DefaultPlayback, 0xdef00000, 0x9c6d, 0x47ed, 0xaa, 0xf1, 0x4d, 0xda, 0x8f, 0x2b, 0x5c, 0x03);
|
||||
DEFINE_GUID(SDL_DSDEVID_DefaultCapture, 0xdef00001, 0x9c6d, 0x47ed, 0xaa, 0xf1, 0x4d, 0xda, 0x8f, 0x2b, 0x5c, 0x03);
|
||||
|
||||
static const GUID SDL_KSDATAFORMAT_SUBTYPE_PCM = { 0x00000001, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } };
|
||||
static const GUID SDL_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = { 0x00000003, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } };
|
||||
|
||||
@@ -214,12 +218,12 @@ static void DSOUND_DetectDevices(SDL_AudioDevice **default_output, SDL_AudioDevi
|
||||
|
||||
data.iscapture = SDL_TRUE;
|
||||
data.default_device = default_capture;
|
||||
data.default_device_guid = (pGetDeviceID(&DSDEVID_DefaultCapture, &guid) == DS_OK) ? &guid : NULL;
|
||||
data.default_device_guid = (pGetDeviceID(&SDL_DSDEVID_DefaultCapture, &guid) == DS_OK) ? &guid : NULL;
|
||||
pDirectSoundCaptureEnumerateW(FindAllDevs, &data);
|
||||
|
||||
data.iscapture = SDL_FALSE;
|
||||
data.default_device = default_output;
|
||||
data.default_device_guid = (pGetDeviceID(&DSDEVID_DefaultPlayback, &guid) == DS_OK) ? &guid : NULL;
|
||||
data.default_device_guid = (pGetDeviceID(&SDL_DSDEVID_DefaultPlayback, &guid) == DS_OK) ? &guid : NULL;
|
||||
pDirectSoundEnumerateW(FindAllDevs, &data);
|
||||
}
|
||||
|
||||
@@ -528,6 +532,7 @@ static int DSOUND_OpenDevice(SDL_AudioDevice *device)
|
||||
}
|
||||
|
||||
const DWORD numchunks = 8;
|
||||
DWORD bufsize;
|
||||
SDL_bool tried_format = SDL_FALSE;
|
||||
SDL_AudioFormat test_format;
|
||||
const SDL_AudioFormat *closefmts = SDL_ClosestAudioFormats(device->spec.format);
|
||||
@@ -544,7 +549,7 @@ static int DSOUND_OpenDevice(SDL_AudioDevice *device)
|
||||
// Update the fragment size as size in bytes
|
||||
SDL_UpdatedAudioDeviceFormat(device);
|
||||
|
||||
const DWORD bufsize = numchunks * device->buffer_size;
|
||||
bufsize = numchunks * device->buffer_size;
|
||||
if ((bufsize < DSBSIZE_MIN) || (bufsize > DSBSIZE_MAX)) {
|
||||
SDL_SetError("Sound buffer size must be between %d and %d",
|
||||
(int)((DSBSIZE_MIN < numchunks) ? 1 : DSBSIZE_MIN / numchunks),
|
||||
@@ -583,7 +588,7 @@ static int DSOUND_OpenDevice(SDL_AudioDevice *device)
|
||||
wfmt.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT;
|
||||
break;
|
||||
default:
|
||||
SDL_assert(0 && "Unsupported channel count!");
|
||||
SDL_assert(!"Unsupported channel count!");
|
||||
break;
|
||||
}
|
||||
} else if (SDL_AUDIO_ISFLOAT(device->spec.format)) {
|
||||
|
||||
10
external/sdl/SDL/src/audio/disk/SDL_diskaudio.c
vendored
10
external/sdl/SDL/src/audio/disk/SDL_diskaudio.c
vendored
@@ -43,7 +43,7 @@ static int DISKAUDIO_WaitDevice(SDL_AudioDevice *device)
|
||||
|
||||
static int DISKAUDIO_PlayDevice(SDL_AudioDevice *device, const Uint8 *buffer, int buffer_size)
|
||||
{
|
||||
const int written = (int)SDL_RWwrite(device->hidden->io, buffer, (size_t)buffer_size);
|
||||
const int written = (int)SDL_WriteIO(device->hidden->io, buffer, (size_t)buffer_size);
|
||||
if (written != buffer_size) { // If we couldn't write, assume fatal error for now
|
||||
return -1;
|
||||
}
|
||||
@@ -64,11 +64,11 @@ static int DISKAUDIO_CaptureFromDevice(SDL_AudioDevice *device, void *buffer, in
|
||||
const int origbuflen = buflen;
|
||||
|
||||
if (h->io) {
|
||||
const int br = (int)SDL_RWread(h->io, buffer, (size_t)buflen);
|
||||
const int br = (int)SDL_ReadIO(h->io, buffer, (size_t)buflen);
|
||||
buflen -= br;
|
||||
buffer = ((Uint8 *)buffer) + br;
|
||||
if (buflen > 0) { // EOF (or error, but whatever).
|
||||
SDL_RWclose(h->io);
|
||||
SDL_CloseIO(h->io);
|
||||
h->io = NULL;
|
||||
}
|
||||
}
|
||||
@@ -88,7 +88,7 @@ static void DISKAUDIO_CloseDevice(SDL_AudioDevice *device)
|
||||
{
|
||||
if (device->hidden) {
|
||||
if (device->hidden->io) {
|
||||
SDL_RWclose(device->hidden->io);
|
||||
SDL_CloseIO(device->hidden->io);
|
||||
}
|
||||
SDL_free(device->hidden->mixbuf);
|
||||
SDL_free(device->hidden);
|
||||
@@ -123,7 +123,7 @@ static int DISKAUDIO_OpenDevice(SDL_AudioDevice *device)
|
||||
}
|
||||
|
||||
// Open the "audio device"
|
||||
device->hidden->io = SDL_RWFromFile(fname, iscapture ? "rb" : "wb");
|
||||
device->hidden->io = SDL_IOFromFile(fname, iscapture ? "rb" : "wb");
|
||||
if (!device->hidden->io) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
struct SDL_PrivateAudioData
|
||||
{
|
||||
// The file descriptor for the audio device
|
||||
SDL_RWops *io;
|
||||
SDL_IOStream *io;
|
||||
Uint32 io_delay;
|
||||
Uint8 *mixbuf;
|
||||
};
|
||||
|
||||
@@ -416,6 +416,7 @@ static SDL_bool JACK_Init(SDL_AudioDriverImpl *impl)
|
||||
jack_client_t *client = JACK_jack_client_open("SDL", JackNoStartServer, &status, NULL);
|
||||
if (!client) {
|
||||
UnloadJackLibrary();
|
||||
SDL_SetError("Can't open JACK client");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
JACK_jack_client_close(client);
|
||||
|
||||
@@ -228,6 +228,12 @@ static void OPENSLES_DestroyPCMRecorder(SDL_AudioDevice *device)
|
||||
}
|
||||
}
|
||||
|
||||
// !!! FIXME: make this non-blocking!
|
||||
static void SDLCALL AndroidRequestPermissionBlockingCallback(void *userdata, const char *permission, SDL_bool granted)
|
||||
{
|
||||
SDL_AtomicSet((SDL_AtomicInt *) userdata, granted ? 1 : -1);
|
||||
}
|
||||
|
||||
static int OPENSLES_CreatePCMRecorder(SDL_AudioDevice *device)
|
||||
{
|
||||
struct SDL_PrivateAudioData *audiodata = device->hidden;
|
||||
@@ -241,9 +247,22 @@ static int OPENSLES_CreatePCMRecorder(SDL_AudioDevice *device)
|
||||
SLresult result;
|
||||
int i;
|
||||
|
||||
if (!Android_JNI_RequestPermission("android.permission.RECORD_AUDIO")) {
|
||||
LOGE("This app doesn't have RECORD_AUDIO permission");
|
||||
return SDL_SetError("This app doesn't have RECORD_AUDIO permission");
|
||||
// !!! FIXME: make this non-blocking!
|
||||
{
|
||||
SDL_AtomicInt permission_response;
|
||||
SDL_AtomicSet(&permission_response, 0);
|
||||
if (SDL_AndroidRequestPermission("android.permission.RECORD_AUDIO", AndroidRequestPermissionBlockingCallback, &permission_response) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (SDL_AtomicGet(&permission_response) == 0) {
|
||||
SDL_Delay(10);
|
||||
}
|
||||
|
||||
if (SDL_AtomicGet(&permission_response) < 0) {
|
||||
LOGE("This app doesn't have RECORD_AUDIO permission");
|
||||
return SDL_SetError("This app doesn't have RECORD_AUDIO permission");
|
||||
}
|
||||
}
|
||||
|
||||
// Just go with signed 16-bit audio as it's the most compatible
|
||||
|
||||
@@ -826,11 +826,13 @@ static void PIPEWIRE_DetectDevices(SDL_AudioDevice **default_output, SDL_AudioDe
|
||||
spa_list_for_each (io, &hotplug_io_list, link) {
|
||||
SDL_AudioDevice *device = SDL_AddAudioDevice(io->is_capture, io->name, &io->spec, PW_ID_TO_HANDLE(io->id));
|
||||
if (pipewire_default_sink_id && SDL_strcmp(io->path, pipewire_default_sink_id) == 0) {
|
||||
SDL_assert(!io->is_capture);
|
||||
*default_output = device;
|
||||
if (!io->is_capture) {
|
||||
*default_output = device;
|
||||
}
|
||||
} else if (pipewire_default_source_id && SDL_strcmp(io->path, pipewire_default_source_id) == 0) {
|
||||
SDL_assert(io->is_capture);
|
||||
*default_capture = device;
|
||||
if (io->is_capture) {
|
||||
*default_capture = device;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
31
external/sdl/SDL/src/audio/wasapi/SDL_wasapi.c
vendored
31
external/sdl/SDL/src/audio/wasapi/SDL_wasapi.c
vendored
@@ -71,7 +71,7 @@ static void ManagementThreadMainloop(void)
|
||||
{
|
||||
SDL_LockMutex(ManagementThreadLock);
|
||||
ManagementThreadPendingTask *task;
|
||||
while (((task = SDL_AtomicGetPtr((void **) &ManagementThreadPendingTasks)) != NULL) || !SDL_AtomicGet(&ManagementThreadShutdown)) {
|
||||
while (((task = (ManagementThreadPendingTask *)SDL_AtomicGetPtr((void **)&ManagementThreadPendingTasks)) != NULL) || !SDL_AtomicGet(&ManagementThreadShutdown)) {
|
||||
if (!task) {
|
||||
SDL_WaitCondition(ManagementThreadCondition, ManagementThreadLock); // block until there's something to do.
|
||||
} else {
|
||||
@@ -93,7 +93,7 @@ static void ManagementThreadMainloop(void)
|
||||
int WASAPI_ProxyToManagementThread(ManagementThreadTask task, void *userdata, int *wait_on_result)
|
||||
{
|
||||
// We want to block for a result, but we are already running from the management thread! Just run the task now so we don't deadlock.
|
||||
if ((wait_on_result) && (SDL_ThreadID() == SDL_GetThreadID(ManagementThread))) {
|
||||
if ((wait_on_result) && (SDL_GetCurrentThreadID() == SDL_GetThreadID(ManagementThread))) {
|
||||
*wait_on_result = task(userdata);
|
||||
return 0; // completed!
|
||||
}
|
||||
@@ -102,7 +102,7 @@ int WASAPI_ProxyToManagementThread(ManagementThreadTask task, void *userdata, in
|
||||
return SDL_SetError("Can't add task, we're shutting down");
|
||||
}
|
||||
|
||||
ManagementThreadPendingTask *pending = SDL_calloc(1, sizeof(ManagementThreadPendingTask));
|
||||
ManagementThreadPendingTask *pending = (ManagementThreadPendingTask *)SDL_calloc(1, sizeof(ManagementThreadPendingTask));
|
||||
if (!pending) {
|
||||
return -1;
|
||||
}
|
||||
@@ -124,7 +124,7 @@ int WASAPI_ProxyToManagementThread(ManagementThreadTask task, void *userdata, in
|
||||
|
||||
// add to end of task list.
|
||||
ManagementThreadPendingTask *prev = NULL;
|
||||
for (ManagementThreadPendingTask *i = SDL_AtomicGetPtr((void **) &ManagementThreadPendingTasks); i; i = i->next) {
|
||||
for (ManagementThreadPendingTask *i = (ManagementThreadPendingTask *)SDL_AtomicGetPtr((void **)&ManagementThreadPendingTasks); i; i = i->next) {
|
||||
prev = i;
|
||||
}
|
||||
|
||||
@@ -265,7 +265,9 @@ static void WASAPI_DetectDevices(SDL_AudioDevice **default_output, SDL_AudioDevi
|
||||
{
|
||||
int rc;
|
||||
// this blocks because it needs to finish before the audio subsystem inits
|
||||
mgmtthrtask_DetectDevicesData data = { default_output, default_capture };
|
||||
mgmtthrtask_DetectDevicesData data;
|
||||
data.default_output = default_output;
|
||||
data.default_capture = default_capture;
|
||||
WASAPI_ProxyToManagementThread(mgmtthrtask_DetectDevices, &data, &rc);
|
||||
}
|
||||
|
||||
@@ -432,7 +434,11 @@ static Uint8 *WASAPI_GetDeviceBuf(SDL_AudioDevice *device, int *buffer_size)
|
||||
BYTE *buffer = NULL;
|
||||
|
||||
if (device->hidden->render) {
|
||||
if (WasapiFailed(device, IAudioRenderClient_GetBuffer(device->hidden->render, device->sample_frames, &buffer))) {
|
||||
const HRESULT ret = IAudioRenderClient_GetBuffer(device->hidden->render, device->sample_frames, &buffer);
|
||||
if (ret == AUDCLNT_E_BUFFER_TOO_LARGE) {
|
||||
SDL_assert(buffer == NULL);
|
||||
*buffer_size = 0; // just go back to WaitDevice and try again after the hardware has consumed some more data.
|
||||
} else if (WasapiFailed(device, ret)) {
|
||||
SDL_assert(buffer == NULL);
|
||||
if (device->hidden->device_lost) { // just use an available buffer, we won't be playing it anyhow.
|
||||
*buffer_size = 0; // we'll recover during WaitDevice and try again.
|
||||
@@ -564,7 +570,7 @@ static int mgmtthrtask_PrepDevice(void *userdata)
|
||||
IAudioClient *client = device->hidden->client;
|
||||
SDL_assert(client != NULL);
|
||||
|
||||
#if defined(__WINRT__) || defined(__GDK__) // CreateEventEx() arrived in Vista, so we need an #ifdef for XP.
|
||||
#if defined(SDL_PLATFORM_WINRT) || defined(SDL_PLATFORM_GDK) // CreateEventEx() arrived in Vista, so we need an #ifdef for XP.
|
||||
device->hidden->event = CreateEventEx(NULL, NULL, 0, EVENT_ALL_ACCESS);
|
||||
#else
|
||||
device->hidden->event = CreateEventW(NULL, 0, 0, NULL);
|
||||
@@ -642,11 +648,16 @@ static int mgmtthrtask_PrepDevice(void *userdata)
|
||||
return WIN_SetErrorFromHRESULT("WASAPI can't determine buffer size", ret);
|
||||
}
|
||||
|
||||
/* Match the callback size to the period size to cut down on the number of
|
||||
interrupts waited for in each call to WaitDevice */
|
||||
// Match the callback size to the period size to cut down on the number of
|
||||
// interrupts waited for in each call to WaitDevice
|
||||
const float period_millis = default_period / 10000.0f;
|
||||
const float period_frames = period_millis * newspec.freq / 1000.0f;
|
||||
const int new_sample_frames = (int) SDL_ceilf(period_frames);
|
||||
int new_sample_frames = (int) SDL_ceilf(period_frames);
|
||||
|
||||
// regardless of what we calculated for the period size, clamp it to the expected hardware buffer size.
|
||||
if (new_sample_frames > (int) bufsize) {
|
||||
new_sample_frames = (int) bufsize;
|
||||
}
|
||||
|
||||
// Update the fragment size as size in bytes
|
||||
if (SDL_AudioDeviceFormatChangedAlreadyLocked(device, &newspec, new_sample_frames) < 0) {
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
The code in SDL_wasapi.c is used by both standard Windows and WinRT builds
|
||||
to deal with audio and calls into these functions. */
|
||||
|
||||
#if defined(SDL_AUDIO_DRIVER_WASAPI) && !defined(__WINRT__)
|
||||
#if defined(SDL_AUDIO_DRIVER_WASAPI) && !defined(SDL_PLATFORM_WINRT)
|
||||
|
||||
#include "../../core/windows/SDL_windows.h"
|
||||
#include "../../core/windows/SDL_immdevice.h"
|
||||
@@ -202,4 +202,4 @@ void WASAPI_PlatformFreeDeviceHandle(SDL_AudioDevice *device)
|
||||
SDL_IMMDevice_FreeDeviceHandle(device);
|
||||
}
|
||||
|
||||
#endif // SDL_AUDIO_DRIVER_WASAPI && !defined(__WINRT__)
|
||||
#endif // SDL_AUDIO_DRIVER_WASAPI && !defined(SDL_PLATFORM_WINRT)
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
// is in SDL_wasapi_win32.c. The code in SDL_wasapi.c is used by both standard
|
||||
// Windows and WinRT builds to deal with audio and calls into these functions.
|
||||
|
||||
#if defined(SDL_AUDIO_DRIVER_WASAPI) && defined(__WINRT__)
|
||||
#if defined(SDL_AUDIO_DRIVER_WASAPI) && defined(SDL_PLATFORM_WINRT)
|
||||
|
||||
#include <Windows.h>
|
||||
#include <windows.ui.core.h>
|
||||
@@ -357,4 +357,4 @@ void WASAPI_PlatformFreeDeviceHandle(SDL_AudioDevice *device)
|
||||
SDL_free(device->handle);
|
||||
}
|
||||
|
||||
#endif // SDL_AUDIO_DRIVER_WASAPI && defined(__WINRT__)
|
||||
#endif // SDL_AUDIO_DRIVER_WASAPI && defined(SDL_PLATFORM_WINRT)
|
||||
|
||||
1505
external/sdl/SDL/src/camera/SDL_camera.c
vendored
Normal file
1505
external/sdl/SDL/src/camera/SDL_camera.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -19,15 +19,17 @@
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../SDL_internal.h"
|
||||
#include "../../include/SDL3/SDL_video_capture.h"
|
||||
|
||||
#ifndef SDL_video_capture_c_h_
|
||||
#define SDL_video_capture_c_h_
|
||||
#ifndef SDL_camera_c_h_
|
||||
#define SDL_camera_c_h_
|
||||
|
||||
/* Initialize the video_capture subsystem */
|
||||
int SDL_VideoCaptureInit(void);
|
||||
// Initialize the camera subsystem
|
||||
int SDL_CameraInit(const char *driver_name);
|
||||
|
||||
/* Shutdown the video_capture subsystem */
|
||||
void SDL_QuitVideoCapture(void);
|
||||
// Shutdown the camera subsystem
|
||||
void SDL_QuitCamera(void);
|
||||
|
||||
#endif /* SDL_video_capture_c_h_ */
|
||||
// "Pump" the event queue.
|
||||
extern void SDL_UpdateCamera(void);
|
||||
|
||||
#endif // SDL_camera_c_h_
|
||||
213
external/sdl/SDL/src/camera/SDL_syscamera.h
vendored
Normal file
213
external/sdl/SDL/src/camera/SDL_syscamera.h
vendored
Normal file
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../SDL_internal.h"
|
||||
|
||||
#ifndef SDL_syscamera_h_
|
||||
#define SDL_syscamera_h_
|
||||
|
||||
#include "../SDL_hashtable.h"
|
||||
|
||||
#define DEBUG_CAMERA 0
|
||||
|
||||
typedef struct SDL_CameraDevice SDL_CameraDevice;
|
||||
|
||||
/* Backends should call this as devices are added to the system (such as
|
||||
a USB camera being plugged in), and should also be called for
|
||||
for every device found during DetectDevices(). */
|
||||
extern SDL_CameraDevice *SDL_AddCameraDevice(const char *name, SDL_CameraPosition position, int num_specs, const SDL_CameraSpec *specs, void *handle);
|
||||
|
||||
/* Backends should call this if an opened camera device is lost.
|
||||
This can happen due to i/o errors, or a device being unplugged, etc. */
|
||||
extern void SDL_CameraDeviceDisconnected(SDL_CameraDevice *device);
|
||||
|
||||
// Find an SDL_CameraDevice, selected by a callback. NULL if not found. DOES NOT LOCK THE DEVICE.
|
||||
extern SDL_CameraDevice *SDL_FindPhysicalCameraDeviceByCallback(SDL_bool (*callback)(SDL_CameraDevice *device, void *userdata), void *userdata);
|
||||
|
||||
// Backends should call this when the user has approved/denied access to a camera.
|
||||
extern void SDL_CameraDevicePermissionOutcome(SDL_CameraDevice *device, SDL_bool approved);
|
||||
|
||||
// Backends can call this to get a standardized name for a thread to power a specific camera device.
|
||||
extern char *SDL_GetCameraThreadName(SDL_CameraDevice *device, char *buf, size_t buflen);
|
||||
|
||||
// Backends can call these to change a device's refcount.
|
||||
extern void RefPhysicalCameraDevice(SDL_CameraDevice *device);
|
||||
extern void UnrefPhysicalCameraDevice(SDL_CameraDevice *device);
|
||||
|
||||
// These functions are the heart of the camera threads. Backends can call them directly if they aren't using the SDL-provided thread.
|
||||
extern void SDL_CameraThreadSetup(SDL_CameraDevice *device);
|
||||
extern SDL_bool SDL_CameraThreadIterate(SDL_CameraDevice *device);
|
||||
extern void SDL_CameraThreadShutdown(SDL_CameraDevice *device);
|
||||
|
||||
// common utility functionality to gather up camera specs. Not required!
|
||||
typedef struct CameraFormatAddData
|
||||
{
|
||||
SDL_CameraSpec *specs;
|
||||
int num_specs;
|
||||
int allocated_specs;
|
||||
} CameraFormatAddData;
|
||||
|
||||
int SDL_AddCameraFormat(CameraFormatAddData *data, SDL_PixelFormatEnum fmt, int w, int h, int interval_numerator, int interval_denominator);
|
||||
|
||||
typedef struct SurfaceList
|
||||
{
|
||||
SDL_Surface *surface;
|
||||
Uint64 timestampNS;
|
||||
struct SurfaceList *next;
|
||||
} SurfaceList;
|
||||
|
||||
// Define the SDL camera driver structure
|
||||
struct SDL_CameraDevice
|
||||
{
|
||||
// A mutex for locking
|
||||
SDL_Mutex *lock;
|
||||
|
||||
// Human-readable device name.
|
||||
char *name;
|
||||
|
||||
// Position of camera (front-facing, back-facing, etc).
|
||||
SDL_CameraPosition position;
|
||||
|
||||
// When refcount hits zero, we destroy the device object.
|
||||
SDL_AtomicInt refcount;
|
||||
|
||||
// These are, initially, set from camera_driver, but we might swap them out with Zombie versions on disconnect/failure.
|
||||
int (*WaitDevice)(SDL_CameraDevice *device);
|
||||
int (*AcquireFrame)(SDL_CameraDevice *device, SDL_Surface *frame, Uint64 *timestampNS);
|
||||
void (*ReleaseFrame)(SDL_CameraDevice *device, SDL_Surface *frame);
|
||||
|
||||
// All supported formats/dimensions for this device.
|
||||
SDL_CameraSpec *all_specs;
|
||||
|
||||
// Elements in all_specs.
|
||||
int num_specs;
|
||||
|
||||
// The device's actual specification that the camera is outputting, before conversion.
|
||||
SDL_CameraSpec actual_spec;
|
||||
|
||||
// The device's current camera specification, after conversions.
|
||||
SDL_CameraSpec spec;
|
||||
|
||||
// Unique value assigned at creation time.
|
||||
SDL_CameraDeviceID instance_id;
|
||||
|
||||
// Driver-specific hardware data on how to open device (`hidden` is driver-specific data _when opened_).
|
||||
void *handle;
|
||||
|
||||
// Dropping the first frame(s) after open seems to help timing on some platforms.
|
||||
int drop_frames;
|
||||
|
||||
// Backend timestamp of first acquired frame, so we can keep these meaningful regardless of epoch.
|
||||
Uint64 base_timestamp;
|
||||
|
||||
// SDL timestamp of first acquired frame, so we can roughly convert to SDL ticks.
|
||||
Uint64 adjust_timestamp;
|
||||
|
||||
// Pixel data flows from the driver into these, then gets converted for the app if necessary.
|
||||
SDL_Surface *acquire_surface;
|
||||
|
||||
// acquire_surface converts or scales to this surface before landing in output_surfaces, if necessary.
|
||||
SDL_Surface *conversion_surface;
|
||||
|
||||
// A queue of surfaces that buffer converted/scaled frames of video until the app claims them.
|
||||
SurfaceList output_surfaces[8];
|
||||
SurfaceList filled_output_surfaces; // this is FIFO
|
||||
SurfaceList empty_output_surfaces; // this is LIFO
|
||||
SurfaceList app_held_output_surfaces;
|
||||
|
||||
// A fake video frame we allocate if the camera fails/disconnects.
|
||||
Uint8 *zombie_pixels;
|
||||
|
||||
// non-zero if acquire_surface needs to be scaled for final output.
|
||||
int needs_scaling; // -1: downscale, 0: no scaling, 1: upscale
|
||||
|
||||
// SDL_TRUE if acquire_surface needs to be converted for final output.
|
||||
SDL_bool needs_conversion;
|
||||
|
||||
// Current state flags
|
||||
SDL_AtomicInt shutdown;
|
||||
SDL_AtomicInt zombie;
|
||||
|
||||
// A thread to feed the camera device
|
||||
SDL_Thread *thread;
|
||||
|
||||
// Optional properties.
|
||||
SDL_PropertiesID props;
|
||||
|
||||
// -1: user denied permission, 0: waiting for user response, 1: user approved permission.
|
||||
int permission;
|
||||
|
||||
// Data private to this driver, used when device is opened and running.
|
||||
struct SDL_PrivateCameraData *hidden;
|
||||
};
|
||||
|
||||
typedef struct SDL_CameraDriverImpl
|
||||
{
|
||||
void (*DetectDevices)(void);
|
||||
int (*OpenDevice)(SDL_CameraDevice *device, const SDL_CameraSpec *spec);
|
||||
void (*CloseDevice)(SDL_CameraDevice *device);
|
||||
int (*WaitDevice)(SDL_CameraDevice *device);
|
||||
int (*AcquireFrame)(SDL_CameraDevice *device, SDL_Surface *frame, Uint64 *timestampNS); // set frame->pixels, frame->pitch, and *timestampNS!
|
||||
void (*ReleaseFrame)(SDL_CameraDevice *device, SDL_Surface *frame); // Reclaim frame->pixels and frame->pitch!
|
||||
void (*FreeDeviceHandle)(SDL_CameraDevice *device); // SDL is done with this device; free the handle from SDL_AddCameraDevice()
|
||||
void (*Deinitialize)(void);
|
||||
|
||||
SDL_bool ProvidesOwnCallbackThread;
|
||||
} SDL_CameraDriverImpl;
|
||||
|
||||
typedef struct SDL_PendingCameraDeviceEvent
|
||||
{
|
||||
Uint32 type;
|
||||
SDL_CameraDeviceID devid;
|
||||
struct SDL_PendingCameraDeviceEvent *next;
|
||||
} SDL_PendingCameraDeviceEvent;
|
||||
|
||||
typedef struct SDL_CameraDriver
|
||||
{
|
||||
const char *name; // The name of this camera driver
|
||||
const char *desc; // The description of this camera driver
|
||||
SDL_CameraDriverImpl impl; // the backend's interface
|
||||
|
||||
SDL_RWLock *device_hash_lock; // A rwlock that protects `device_hash`
|
||||
SDL_HashTable *device_hash; // the collection of currently-available camera devices
|
||||
SDL_PendingCameraDeviceEvent pending_events;
|
||||
SDL_PendingCameraDeviceEvent *pending_events_tail;
|
||||
|
||||
SDL_AtomicInt device_count;
|
||||
SDL_AtomicInt shutting_down; // non-zero during SDL_Quit, so we known not to accept any last-minute device hotplugs.
|
||||
} SDL_CameraDriver;
|
||||
|
||||
typedef struct CameraBootStrap
|
||||
{
|
||||
const char *name;
|
||||
const char *desc;
|
||||
SDL_bool (*init)(SDL_CameraDriverImpl *impl);
|
||||
SDL_bool demand_only; // if SDL_TRUE: request explicitly, or it won't be available.
|
||||
} CameraBootStrap;
|
||||
|
||||
// Not all of these are available in a given build. Use #ifdefs, etc.
|
||||
extern CameraBootStrap DUMMYCAMERA_bootstrap;
|
||||
extern CameraBootStrap V4L2_bootstrap;
|
||||
extern CameraBootStrap COREMEDIA_bootstrap;
|
||||
extern CameraBootStrap ANDROIDCAMERA_bootstrap;
|
||||
extern CameraBootStrap EMSCRIPTENCAMERA_bootstrap;
|
||||
extern CameraBootStrap MEDIAFOUNDATION_bootstrap;
|
||||
|
||||
#endif // SDL_syscamera_h_
|
||||
891
external/sdl/SDL/src/camera/android/SDL_camera_android.c
vendored
Normal file
891
external/sdl/SDL/src/camera/android/SDL_camera_android.c
vendored
Normal file
@@ -0,0 +1,891 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#include "../SDL_syscamera.h"
|
||||
#include "../SDL_camera_c.h"
|
||||
#include "../../video/SDL_pixels_c.h"
|
||||
#include "../../thread/SDL_systhread.h"
|
||||
|
||||
#ifdef SDL_CAMERA_DRIVER_ANDROID
|
||||
|
||||
/*
|
||||
* AndroidManifest.xml:
|
||||
* <uses-permission android:name="android.permission.CAMERA"></uses-permission>
|
||||
* <uses-feature android:name="android.hardware.camera" />
|
||||
*
|
||||
* Very likely SDL must be build with YUV support (done by default)
|
||||
*
|
||||
* https://developer.android.com/reference/android/hardware/camera2/CameraManager
|
||||
* "All camera devices intended to be operated concurrently, must be opened using openCamera(String, CameraDevice.StateCallback, Handler),
|
||||
* before configuring sessions on any of the camera devices."
|
||||
*/
|
||||
|
||||
// this is kinda gross, but on older NDK headers all the camera stuff is
|
||||
// gated behind __ANDROID_API__. We'll dlopen() it at runtime, so we'll do
|
||||
// the right thing on pre-Android 7.0 devices, but we still
|
||||
// need the struct declarations and such in those headers.
|
||||
// The other option is to make a massive jump in minimum Android version we
|
||||
// support--going from ancient to merely really old--but this seems less
|
||||
// distasteful and using dlopen matches practices on other SDL platforms.
|
||||
// We'll see if it works out.
|
||||
#if __ANDROID_API__ < 24
|
||||
#undef __ANDROID_API__
|
||||
#define __ANDROID_API__ 24
|
||||
#endif
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <camera/NdkCameraDevice.h>
|
||||
#include <camera/NdkCameraManager.h>
|
||||
#include <media/NdkImage.h>
|
||||
#include <media/NdkImageReader.h>
|
||||
|
||||
#include "../../core/android/SDL_android.h"
|
||||
|
||||
static void *libcamera2ndk = NULL;
|
||||
typedef ACameraManager* (*pfnACameraManager_create)(void);
|
||||
typedef camera_status_t (*pfnACameraManager_registerAvailabilityCallback)(ACameraManager*, const ACameraManager_AvailabilityCallbacks*);
|
||||
typedef camera_status_t (*pfnACameraManager_unregisterAvailabilityCallback)(ACameraManager*, const ACameraManager_AvailabilityCallbacks*);
|
||||
typedef camera_status_t (*pfnACameraManager_getCameraIdList)(ACameraManager*, ACameraIdList**);
|
||||
typedef void (*pfnACameraManager_deleteCameraIdList)(ACameraIdList*);
|
||||
typedef void (*pfnACameraCaptureSession_close)(ACameraCaptureSession*);
|
||||
typedef void (*pfnACaptureRequest_free)(ACaptureRequest*);
|
||||
typedef void (*pfnACameraOutputTarget_free)(ACameraOutputTarget*);
|
||||
typedef camera_status_t (*pfnACameraDevice_close)(ACameraDevice*);
|
||||
typedef void (*pfnACameraManager_delete)(ACameraManager*);
|
||||
typedef void (*pfnACaptureSessionOutputContainer_free)(ACaptureSessionOutputContainer*);
|
||||
typedef void (*pfnACaptureSessionOutput_free)(ACaptureSessionOutput*);
|
||||
typedef camera_status_t (*pfnACameraManager_openCamera)(ACameraManager*, const char*, ACameraDevice_StateCallbacks*, ACameraDevice**);
|
||||
typedef camera_status_t (*pfnACameraDevice_createCaptureRequest)(const ACameraDevice*, ACameraDevice_request_template, ACaptureRequest**);
|
||||
typedef camera_status_t (*pfnACameraDevice_createCaptureSession)(ACameraDevice*, const ACaptureSessionOutputContainer*, const ACameraCaptureSession_stateCallbacks*,ACameraCaptureSession**);
|
||||
typedef camera_status_t (*pfnACameraManager_getCameraCharacteristics)(ACameraManager*, const char*, ACameraMetadata**);
|
||||
typedef void (*pfnACameraMetadata_free)(ACameraMetadata*);
|
||||
typedef camera_status_t (*pfnACameraMetadata_getConstEntry)(const ACameraMetadata*, uint32_t tag, ACameraMetadata_const_entry*);
|
||||
typedef camera_status_t (*pfnACameraCaptureSession_setRepeatingRequest)(ACameraCaptureSession*, ACameraCaptureSession_captureCallbacks*, int numRequests, ACaptureRequest**, int*);
|
||||
typedef camera_status_t (*pfnACameraOutputTarget_create)(ACameraWindowType*,ACameraOutputTarget**);
|
||||
typedef camera_status_t (*pfnACaptureRequest_addTarget)(ACaptureRequest*, const ACameraOutputTarget*);
|
||||
typedef camera_status_t (*pfnACaptureSessionOutputContainer_add)(ACaptureSessionOutputContainer*, const ACaptureSessionOutput*);
|
||||
typedef camera_status_t (*pfnACaptureSessionOutputContainer_create)(ACaptureSessionOutputContainer**);
|
||||
typedef camera_status_t (*pfnACaptureSessionOutput_create)(ACameraWindowType*, ACaptureSessionOutput**);
|
||||
static pfnACameraManager_create pACameraManager_create = NULL;
|
||||
static pfnACameraManager_registerAvailabilityCallback pACameraManager_registerAvailabilityCallback = NULL;
|
||||
static pfnACameraManager_unregisterAvailabilityCallback pACameraManager_unregisterAvailabilityCallback = NULL;
|
||||
static pfnACameraManager_getCameraIdList pACameraManager_getCameraIdList = NULL;
|
||||
static pfnACameraManager_deleteCameraIdList pACameraManager_deleteCameraIdList = NULL;
|
||||
static pfnACameraCaptureSession_close pACameraCaptureSession_close = NULL;
|
||||
static pfnACaptureRequest_free pACaptureRequest_free = NULL;
|
||||
static pfnACameraOutputTarget_free pACameraOutputTarget_free = NULL;
|
||||
static pfnACameraDevice_close pACameraDevice_close = NULL;
|
||||
static pfnACameraManager_delete pACameraManager_delete = NULL;
|
||||
static pfnACaptureSessionOutputContainer_free pACaptureSessionOutputContainer_free = NULL;
|
||||
static pfnACaptureSessionOutput_free pACaptureSessionOutput_free = NULL;
|
||||
static pfnACameraManager_openCamera pACameraManager_openCamera = NULL;
|
||||
static pfnACameraDevice_createCaptureRequest pACameraDevice_createCaptureRequest = NULL;
|
||||
static pfnACameraDevice_createCaptureSession pACameraDevice_createCaptureSession = NULL;
|
||||
static pfnACameraManager_getCameraCharacteristics pACameraManager_getCameraCharacteristics = NULL;
|
||||
static pfnACameraMetadata_free pACameraMetadata_free = NULL;
|
||||
static pfnACameraMetadata_getConstEntry pACameraMetadata_getConstEntry = NULL;
|
||||
static pfnACameraCaptureSession_setRepeatingRequest pACameraCaptureSession_setRepeatingRequest = NULL;
|
||||
static pfnACameraOutputTarget_create pACameraOutputTarget_create = NULL;
|
||||
static pfnACaptureRequest_addTarget pACaptureRequest_addTarget = NULL;
|
||||
static pfnACaptureSessionOutputContainer_add pACaptureSessionOutputContainer_add = NULL;
|
||||
static pfnACaptureSessionOutputContainer_create pACaptureSessionOutputContainer_create = NULL;
|
||||
static pfnACaptureSessionOutput_create pACaptureSessionOutput_create = NULL;
|
||||
|
||||
static void *libmediandk = NULL;
|
||||
typedef void (*pfnAImage_delete)(AImage*);
|
||||
typedef media_status_t (*pfnAImage_getTimestamp)(const AImage*, int64_t*);
|
||||
typedef media_status_t (*pfnAImage_getNumberOfPlanes)(const AImage*, int32_t*);
|
||||
typedef media_status_t (*pfnAImage_getPlaneRowStride)(const AImage*, int, int32_t*);
|
||||
typedef media_status_t (*pfnAImage_getPlaneData)(const AImage*, int, uint8_t**, int*);
|
||||
typedef media_status_t (*pfnAImageReader_acquireNextImage)(AImageReader*, AImage**);
|
||||
typedef void (*pfnAImageReader_delete)(AImageReader*);
|
||||
typedef media_status_t (*pfnAImageReader_setImageListener)(AImageReader*, AImageReader_ImageListener*);
|
||||
typedef media_status_t (*pfnAImageReader_getWindow)(AImageReader*, ANativeWindow**);
|
||||
typedef media_status_t (*pfnAImageReader_new)(int32_t, int32_t, int32_t, int32_t, AImageReader**);
|
||||
static pfnAImage_delete pAImage_delete = NULL;
|
||||
static pfnAImage_getTimestamp pAImage_getTimestamp = NULL;
|
||||
static pfnAImage_getNumberOfPlanes pAImage_getNumberOfPlanes = NULL;
|
||||
static pfnAImage_getPlaneRowStride pAImage_getPlaneRowStride = NULL;
|
||||
static pfnAImage_getPlaneData pAImage_getPlaneData = NULL;
|
||||
static pfnAImageReader_acquireNextImage pAImageReader_acquireNextImage = NULL;
|
||||
static pfnAImageReader_delete pAImageReader_delete = NULL;
|
||||
static pfnAImageReader_setImageListener pAImageReader_setImageListener = NULL;
|
||||
static pfnAImageReader_getWindow pAImageReader_getWindow = NULL;
|
||||
static pfnAImageReader_new pAImageReader_new = NULL;
|
||||
|
||||
typedef media_status_t (*pfnAImage_getWidth)(const AImage*, int32_t*);
|
||||
typedef media_status_t (*pfnAImage_getHeight)(const AImage*, int32_t*);
|
||||
static pfnAImage_getWidth pAImage_getWidth = NULL;
|
||||
static pfnAImage_getHeight pAImage_getHeight = NULL;
|
||||
|
||||
struct SDL_PrivateCameraData
|
||||
{
|
||||
ACameraDevice *device;
|
||||
AImageReader *reader;
|
||||
ANativeWindow *window;
|
||||
ACaptureSessionOutput *sessionOutput;
|
||||
ACaptureSessionOutputContainer *sessionOutputContainer;
|
||||
ACameraOutputTarget *outputTarget;
|
||||
ACaptureRequest *request;
|
||||
ACameraCaptureSession *session;
|
||||
SDL_CameraSpec requested_spec;
|
||||
};
|
||||
|
||||
static int SetErrorStr(const char *what, const char *errstr, const int rc)
|
||||
{
|
||||
char errbuf[128];
|
||||
if (!errstr) {
|
||||
SDL_snprintf(errbuf, sizeof (errbuf), "Unknown error #%d", rc);
|
||||
errstr = errbuf;
|
||||
}
|
||||
return SDL_SetError("%s: %s", what, errstr);
|
||||
}
|
||||
|
||||
static const char *CameraStatusStr(const camera_status_t rc)
|
||||
{
|
||||
switch (rc) {
|
||||
case ACAMERA_OK: return "no error";
|
||||
case ACAMERA_ERROR_UNKNOWN: return "unknown error";
|
||||
case ACAMERA_ERROR_INVALID_PARAMETER: return "invalid parameter";
|
||||
case ACAMERA_ERROR_CAMERA_DISCONNECTED: return "camera disconnected";
|
||||
case ACAMERA_ERROR_NOT_ENOUGH_MEMORY: return "not enough memory";
|
||||
case ACAMERA_ERROR_METADATA_NOT_FOUND: return "metadata not found";
|
||||
case ACAMERA_ERROR_CAMERA_DEVICE: return "camera device error";
|
||||
case ACAMERA_ERROR_CAMERA_SERVICE: return "camera service error";
|
||||
case ACAMERA_ERROR_SESSION_CLOSED: return "session closed";
|
||||
case ACAMERA_ERROR_INVALID_OPERATION: return "invalid operation";
|
||||
case ACAMERA_ERROR_STREAM_CONFIGURE_FAIL: return "configure failure";
|
||||
case ACAMERA_ERROR_CAMERA_IN_USE: return "camera in use";
|
||||
case ACAMERA_ERROR_MAX_CAMERA_IN_USE: return "max cameras in use";
|
||||
case ACAMERA_ERROR_CAMERA_DISABLED: return "camera disabled";
|
||||
case ACAMERA_ERROR_PERMISSION_DENIED: return "permission denied";
|
||||
case ACAMERA_ERROR_UNSUPPORTED_OPERATION: return "unsupported operation";
|
||||
default: break;
|
||||
}
|
||||
|
||||
return NULL; // unknown error
|
||||
}
|
||||
|
||||
static int SetCameraError(const char *what, const camera_status_t rc)
|
||||
{
|
||||
return SetErrorStr(what, CameraStatusStr(rc), (int) rc);
|
||||
}
|
||||
|
||||
static const char *MediaStatusStr(const media_status_t rc)
|
||||
{
|
||||
switch (rc) {
|
||||
case AMEDIA_OK: return "no error";
|
||||
case AMEDIACODEC_ERROR_INSUFFICIENT_RESOURCE: return "insuffient resources";
|
||||
case AMEDIACODEC_ERROR_RECLAIMED: return "reclaimed";
|
||||
case AMEDIA_ERROR_UNKNOWN: return "unknown error";
|
||||
case AMEDIA_ERROR_MALFORMED: return "malformed";
|
||||
case AMEDIA_ERROR_UNSUPPORTED: return "unsupported";
|
||||
case AMEDIA_ERROR_INVALID_OBJECT: return "invalid object";
|
||||
case AMEDIA_ERROR_INVALID_PARAMETER: return "invalid parameter";
|
||||
case AMEDIA_ERROR_INVALID_OPERATION: return "invalid operation";
|
||||
case AMEDIA_ERROR_END_OF_STREAM: return "end of stream";
|
||||
case AMEDIA_ERROR_IO: return "i/o error";
|
||||
case AMEDIA_ERROR_WOULD_BLOCK: return "operation would block";
|
||||
case AMEDIA_DRM_NOT_PROVISIONED: return "DRM not provisioned";
|
||||
case AMEDIA_DRM_RESOURCE_BUSY: return "DRM resource busy";
|
||||
case AMEDIA_DRM_DEVICE_REVOKED: return "DRM device revoked";
|
||||
case AMEDIA_DRM_SHORT_BUFFER: return "DRM short buffer";
|
||||
case AMEDIA_DRM_SESSION_NOT_OPENED: return "DRM session not opened";
|
||||
case AMEDIA_DRM_TAMPER_DETECTED: return "DRM tampering detected";
|
||||
case AMEDIA_DRM_VERIFY_FAILED: return "DRM verify failed";
|
||||
case AMEDIA_DRM_NEED_KEY: return "DRM need key";
|
||||
case AMEDIA_DRM_LICENSE_EXPIRED: return "DRM license expired";
|
||||
case AMEDIA_IMGREADER_NO_BUFFER_AVAILABLE: return "no buffer available";
|
||||
case AMEDIA_IMGREADER_MAX_IMAGES_ACQUIRED: return "maximum images acquired";
|
||||
case AMEDIA_IMGREADER_CANNOT_LOCK_IMAGE: return "cannot lock image";
|
||||
case AMEDIA_IMGREADER_CANNOT_UNLOCK_IMAGE: return "cannot unlock image";
|
||||
case AMEDIA_IMGREADER_IMAGE_NOT_LOCKED: return "image not locked";
|
||||
default: break;
|
||||
}
|
||||
|
||||
return NULL; // unknown error
|
||||
}
|
||||
|
||||
static int SetMediaError(const char *what, const media_status_t rc)
|
||||
{
|
||||
return SetErrorStr(what, MediaStatusStr(rc), (int) rc);
|
||||
}
|
||||
|
||||
|
||||
static ACameraManager *cameraMgr = NULL;
|
||||
|
||||
static int CreateCameraManager(void)
|
||||
{
|
||||
SDL_assert(cameraMgr == NULL);
|
||||
|
||||
cameraMgr = pACameraManager_create();
|
||||
if (!cameraMgr) {
|
||||
return SDL_SetError("Error creating ACameraManager");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void DestroyCameraManager(void)
|
||||
{
|
||||
if (cameraMgr) {
|
||||
pACameraManager_delete(cameraMgr);
|
||||
cameraMgr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static Uint32 format_android_to_sdl(Uint32 fmt)
|
||||
{
|
||||
switch (fmt) {
|
||||
#define CASE(x, y) case x: return y
|
||||
CASE(AIMAGE_FORMAT_YUV_420_888, SDL_PIXELFORMAT_NV12);
|
||||
CASE(AIMAGE_FORMAT_RGB_565, SDL_PIXELFORMAT_RGB565);
|
||||
CASE(AIMAGE_FORMAT_RGB_888, SDL_PIXELFORMAT_XRGB8888);
|
||||
CASE(AIMAGE_FORMAT_RGBA_8888, SDL_PIXELFORMAT_RGBA8888);
|
||||
CASE(AIMAGE_FORMAT_RGBX_8888, SDL_PIXELFORMAT_RGBX8888);
|
||||
//CASE(AIMAGE_FORMAT_RGBA_FP16, SDL_PIXELFORMAT_UNKNOWN); // 64bits
|
||||
//CASE(AIMAGE_FORMAT_RAW_PRIVATE, SDL_PIXELFORMAT_UNKNOWN);
|
||||
//CASE(AIMAGE_FORMAT_JPEG, SDL_PIXELFORMAT_UNKNOWN);
|
||||
#undef CASE
|
||||
default: break;
|
||||
}
|
||||
|
||||
#if DEBUG_CAMERA
|
||||
//SDL_Log("Unknown format AIMAGE_FORMAT '%d'", fmt);
|
||||
#endif
|
||||
|
||||
return SDL_PIXELFORMAT_UNKNOWN;
|
||||
}
|
||||
|
||||
static Uint32 format_sdl_to_android(Uint32 fmt)
|
||||
{
|
||||
switch (fmt) {
|
||||
#define CASE(x, y) case y: return x
|
||||
CASE(AIMAGE_FORMAT_YUV_420_888, SDL_PIXELFORMAT_NV12);
|
||||
CASE(AIMAGE_FORMAT_RGB_565, SDL_PIXELFORMAT_RGB565);
|
||||
CASE(AIMAGE_FORMAT_RGB_888, SDL_PIXELFORMAT_XRGB8888);
|
||||
CASE(AIMAGE_FORMAT_RGBA_8888, SDL_PIXELFORMAT_RGBA8888);
|
||||
CASE(AIMAGE_FORMAT_RGBX_8888, SDL_PIXELFORMAT_RGBX8888);
|
||||
#undef CASE
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int ANDROIDCAMERA_WaitDevice(SDL_CameraDevice *device)
|
||||
{
|
||||
return 0; // this isn't used atm, since we run our own thread via onImageAvailable callbacks.
|
||||
}
|
||||
|
||||
static int ANDROIDCAMERA_AcquireFrame(SDL_CameraDevice *device, SDL_Surface *frame, Uint64 *timestampNS)
|
||||
{
|
||||
int retval = 1;
|
||||
media_status_t res;
|
||||
AImage *image = NULL;
|
||||
|
||||
res = pAImageReader_acquireNextImage(device->hidden->reader, &image);
|
||||
// We could also use this one:
|
||||
//res = AImageReader_acquireLatestImage(device->hidden->reader, &image);
|
||||
|
||||
SDL_assert(res != AMEDIA_IMGREADER_NO_BUFFER_AVAILABLE); // we should only be here if onImageAvailable was called.
|
||||
|
||||
if (res != AMEDIA_OK) {
|
||||
return SetMediaError("Error AImageReader_acquireNextImage", res);
|
||||
}
|
||||
|
||||
int64_t atimestamp = 0;
|
||||
if (pAImage_getTimestamp(image, &atimestamp) == AMEDIA_OK) {
|
||||
*timestampNS = (Uint64) atimestamp;
|
||||
} else {
|
||||
*timestampNS = 0;
|
||||
}
|
||||
|
||||
// !!! FIXME: this currently copies the data to the surface (see FIXME about non-contiguous planar surfaces, but in theory we could just keep this locked until ReleaseFrame...
|
||||
int32_t num_planes = 0;
|
||||
pAImage_getNumberOfPlanes(image, &num_planes);
|
||||
|
||||
if ((num_planes == 3) && (device->spec.format == SDL_PIXELFORMAT_NV12)) {
|
||||
num_planes--; // treat the interleaved planes as one.
|
||||
}
|
||||
|
||||
// !!! FIXME: we have an open issue in SDL3 to allow SDL_Surface to support non-contiguous planar data, but we don't have it yet.
|
||||
size_t buflen = 0;
|
||||
for (int i = 0; (i < num_planes) && (i < 3); i++) {
|
||||
uint8_t *data = NULL;
|
||||
int32_t datalen = 0;
|
||||
pAImage_getPlaneData(image, i, &data, &datalen);
|
||||
buflen += (int) datalen;
|
||||
}
|
||||
|
||||
frame->pixels = SDL_aligned_alloc(SDL_SIMDGetAlignment(), buflen);
|
||||
if (frame->pixels == NULL) {
|
||||
retval = -1;
|
||||
} else {
|
||||
int32_t row_stride = 0;
|
||||
Uint8 *dst = frame->pixels;
|
||||
pAImage_getPlaneRowStride(image, 0, &row_stride);
|
||||
frame->pitch = (int) row_stride; // this is what SDL3 currently expects, probably incorrectly.
|
||||
|
||||
for (int i = 0; (i < num_planes) && (i < 3); i++) {
|
||||
uint8_t *data = NULL;
|
||||
int32_t datalen = 0;
|
||||
pAImage_getPlaneData(image, i, &data, &datalen);
|
||||
const void *src = data;
|
||||
SDL_memcpy(dst, src, datalen);
|
||||
dst += datalen;
|
||||
}
|
||||
}
|
||||
|
||||
pAImage_delete(image);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void ANDROIDCAMERA_ReleaseFrame(SDL_CameraDevice *device, SDL_Surface *frame)
|
||||
{
|
||||
// !!! FIXME: this currently copies the data to the surface, but in theory we could just keep the AImage until ReleaseFrame...
|
||||
SDL_aligned_free(frame->pixels);
|
||||
}
|
||||
|
||||
static void onImageAvailable(void *context, AImageReader *reader)
|
||||
{
|
||||
#if DEBUG_CAMERA
|
||||
SDL_Log("CAMERA: CB onImageAvailable");
|
||||
#endif
|
||||
SDL_CameraDevice *device = (SDL_CameraDevice *) context;
|
||||
SDL_CameraThreadIterate(device);
|
||||
}
|
||||
|
||||
static void onDisconnected(void *context, ACameraDevice *device)
|
||||
{
|
||||
#if DEBUG_CAMERA
|
||||
SDL_Log("CAMERA: CB onDisconnected");
|
||||
#endif
|
||||
SDL_CameraDeviceDisconnected((SDL_CameraDevice *) context);
|
||||
}
|
||||
|
||||
static void onError(void *context, ACameraDevice *device, int error)
|
||||
{
|
||||
#if DEBUG_CAMERA
|
||||
SDL_Log("CAMERA: CB onError");
|
||||
#endif
|
||||
SDL_CameraDeviceDisconnected((SDL_CameraDevice *) context);
|
||||
}
|
||||
|
||||
static void onClosed(void* context, ACameraCaptureSession *session)
|
||||
{
|
||||
// SDL_CameraDevice *_this = (SDL_CameraDevice *) context;
|
||||
#if DEBUG_CAMERA
|
||||
SDL_Log("CAMERA: CB onClosed");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void onReady(void* context, ACameraCaptureSession *session)
|
||||
{
|
||||
// SDL_CameraDevice *_this = (SDL_CameraDevice *) context;
|
||||
#if DEBUG_CAMERA
|
||||
SDL_Log("CAMERA: CB onReady");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void onActive(void* context, ACameraCaptureSession *session)
|
||||
{
|
||||
// SDL_CameraDevice *_this = (SDL_CameraDevice *) context;
|
||||
#if DEBUG_CAMERA
|
||||
SDL_Log("CAMERA: CB onActive");
|
||||
#endif
|
||||
}
|
||||
|
||||
static void ANDROIDCAMERA_CloseDevice(SDL_CameraDevice *device)
|
||||
{
|
||||
if (device && device->hidden) {
|
||||
struct SDL_PrivateCameraData *hidden = device->hidden;
|
||||
device->hidden = NULL;
|
||||
|
||||
if (hidden->reader) {
|
||||
pAImageReader_setImageListener(hidden->reader, NULL);
|
||||
}
|
||||
|
||||
if (hidden->session) {
|
||||
pACameraCaptureSession_close(hidden->session);
|
||||
}
|
||||
|
||||
if (hidden->request) {
|
||||
pACaptureRequest_free(hidden->request);
|
||||
}
|
||||
|
||||
if (hidden->outputTarget) {
|
||||
pACameraOutputTarget_free(hidden->outputTarget);
|
||||
}
|
||||
|
||||
if (hidden->sessionOutputContainer) {
|
||||
pACaptureSessionOutputContainer_free(hidden->sessionOutputContainer);
|
||||
}
|
||||
|
||||
if (hidden->sessionOutput) {
|
||||
pACaptureSessionOutput_free(hidden->sessionOutput);
|
||||
}
|
||||
|
||||
// we don't free hidden->window here, it'll be cleaned up by AImageReader_delete.
|
||||
|
||||
if (hidden->reader) {
|
||||
pAImageReader_delete(hidden->reader);
|
||||
}
|
||||
|
||||
if (hidden->device) {
|
||||
pACameraDevice_close(hidden->device);
|
||||
}
|
||||
|
||||
SDL_free(hidden);
|
||||
}
|
||||
}
|
||||
|
||||
// this is where the "opening" of the camera happens, after permission is granted.
|
||||
static int PrepareCamera(SDL_CameraDevice *device)
|
||||
{
|
||||
SDL_assert(device->hidden != NULL);
|
||||
|
||||
camera_status_t res;
|
||||
media_status_t res2;
|
||||
|
||||
ACameraDevice_StateCallbacks dev_callbacks;
|
||||
SDL_zero(dev_callbacks);
|
||||
dev_callbacks.context = device;
|
||||
dev_callbacks.onDisconnected = onDisconnected;
|
||||
dev_callbacks.onError = onError;
|
||||
|
||||
ACameraCaptureSession_stateCallbacks capture_callbacks;
|
||||
SDL_zero(capture_callbacks);
|
||||
capture_callbacks.context = device;
|
||||
capture_callbacks.onClosed = onClosed;
|
||||
capture_callbacks.onReady = onReady;
|
||||
capture_callbacks.onActive = onActive;
|
||||
|
||||
AImageReader_ImageListener imglistener;
|
||||
SDL_zero(imglistener);
|
||||
imglistener.context = device;
|
||||
imglistener.onImageAvailable = onImageAvailable;
|
||||
|
||||
// just in case SDL_OpenCameraDevice is overwriting device->spec as CameraPermissionCallback runs, we work from a different copy.
|
||||
const SDL_CameraSpec *spec = &device->hidden->requested_spec;
|
||||
|
||||
if ((res = pACameraManager_openCamera(cameraMgr, (const char *) device->handle, &dev_callbacks, &device->hidden->device)) != ACAMERA_OK) {
|
||||
return SetCameraError("Failed to open camera", res);
|
||||
} else if ((res2 = pAImageReader_new(spec->width, spec->height, format_sdl_to_android(spec->format), 10 /* nb buffers */, &device->hidden->reader)) != AMEDIA_OK) {
|
||||
return SetMediaError("Error AImageReader_new", res2);
|
||||
} else if ((res2 = pAImageReader_getWindow(device->hidden->reader, &device->hidden->window)) != AMEDIA_OK) {
|
||||
return SetMediaError("Error AImageReader_getWindow", res2);
|
||||
} else if ((res = pACaptureSessionOutput_create(device->hidden->window, &device->hidden->sessionOutput)) != ACAMERA_OK) {
|
||||
return SetCameraError("Error ACaptureSessionOutput_create", res);
|
||||
} else if ((res = pACaptureSessionOutputContainer_create(&device->hidden->sessionOutputContainer)) != ACAMERA_OK) {
|
||||
return SetCameraError("Error ACaptureSessionOutputContainer_create", res);
|
||||
} else if ((res = pACaptureSessionOutputContainer_add(device->hidden->sessionOutputContainer, device->hidden->sessionOutput)) != ACAMERA_OK) {
|
||||
return SetCameraError("Error ACaptureSessionOutputContainer_add", res);
|
||||
} else if ((res = pACameraOutputTarget_create(device->hidden->window, &device->hidden->outputTarget)) != ACAMERA_OK) {
|
||||
return SetCameraError("Error ACameraOutputTarget_create", res);
|
||||
} else if ((res = pACameraDevice_createCaptureRequest(device->hidden->device, TEMPLATE_RECORD, &device->hidden->request)) != ACAMERA_OK) {
|
||||
return SetCameraError("Error ACameraDevice_createCaptureRequest", res);
|
||||
} else if ((res = pACaptureRequest_addTarget(device->hidden->request, device->hidden->outputTarget)) != ACAMERA_OK) {
|
||||
return SetCameraError("Error ACaptureRequest_addTarget", res);
|
||||
} else if ((res = pACameraDevice_createCaptureSession(device->hidden->device, device->hidden->sessionOutputContainer, &capture_callbacks, &device->hidden->session)) != ACAMERA_OK) {
|
||||
return SetCameraError("Error ACameraDevice_createCaptureSession", res);
|
||||
} else if ((res = pACameraCaptureSession_setRepeatingRequest(device->hidden->session, NULL, 1, &device->hidden->request, NULL)) != ACAMERA_OK) {
|
||||
return SetCameraError("Error ACameraCaptureSession_setRepeatingRequest", res);
|
||||
} else if ((res2 = pAImageReader_setImageListener(device->hidden->reader, &imglistener)) != AMEDIA_OK) {
|
||||
return SetMediaError("Error AImageReader_setImageListener", res2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void SDLCALL CameraPermissionCallback(void *userdata, const char *permission, SDL_bool granted)
|
||||
{
|
||||
SDL_CameraDevice *device = (SDL_CameraDevice *) userdata;
|
||||
if (device->hidden != NULL) { // if device was already closed, don't send an event.
|
||||
if (!granted) {
|
||||
SDL_CameraDevicePermissionOutcome(device, SDL_FALSE); // sorry, permission denied.
|
||||
} else if (PrepareCamera(device) < 0) { // permission given? Actually open the camera now.
|
||||
// uhoh, setup failed; since the app thinks we already "opened" the device, mark it as disconnected and don't report the permission.
|
||||
SDL_CameraDeviceDisconnected(device);
|
||||
} else {
|
||||
// okay! We have permission to use the camera _and_ opening the hardware worked out, report that the camera is usable!
|
||||
SDL_CameraDevicePermissionOutcome(device, SDL_TRUE); // go go go!
|
||||
}
|
||||
}
|
||||
|
||||
UnrefPhysicalCameraDevice(device); // we ref'd this in OpenDevice, release the extra reference.
|
||||
}
|
||||
|
||||
|
||||
static int ANDROIDCAMERA_OpenDevice(SDL_CameraDevice *device, const SDL_CameraSpec *spec)
|
||||
{
|
||||
#if 0 // !!! FIXME: for now, we'll just let this fail if it is going to fail, without checking for this
|
||||
/* Cannot open a second camera, while the first one is opened.
|
||||
* If you want to play several camera, they must all be opened first, then played.
|
||||
*
|
||||
* https://developer.android.com/reference/android/hardware/camera2/CameraManager
|
||||
* "All camera devices intended to be operated concurrently, must be opened using openCamera(String, CameraDevice.StateCallback, Handler),
|
||||
* before configuring sessions on any of the camera devices. * "
|
||||
*
|
||||
*/
|
||||
if (CheckDevicePlaying()) {
|
||||
return SDL_SetError("A camera is already playing");
|
||||
}
|
||||
#endif
|
||||
|
||||
device->hidden = (struct SDL_PrivateCameraData *) SDL_calloc(1, sizeof (struct SDL_PrivateCameraData));
|
||||
if (device->hidden == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
RefPhysicalCameraDevice(device); // ref'd until permission callback fires.
|
||||
|
||||
// just in case SDL_OpenCameraDevice is overwriting device->spec as CameraPermissionCallback runs, we work from a different copy.
|
||||
SDL_copyp(&device->hidden->requested_spec, spec);
|
||||
if (SDL_AndroidRequestPermission("android.permission.CAMERA", CameraPermissionCallback, device) < 0) {
|
||||
UnrefPhysicalCameraDevice(device);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0; // we don't open the camera until permission is granted, so always succeed for now.
|
||||
}
|
||||
|
||||
static void ANDROIDCAMERA_FreeDeviceHandle(SDL_CameraDevice *device)
|
||||
{
|
||||
if (device) {
|
||||
SDL_free(device->handle);
|
||||
}
|
||||
}
|
||||
|
||||
static void GatherCameraSpecs(const char *devid, CameraFormatAddData *add_data, char **fullname, SDL_CameraPosition *position)
|
||||
{
|
||||
SDL_zerop(add_data);
|
||||
|
||||
ACameraMetadata *metadata = NULL;
|
||||
ACameraMetadata_const_entry cfgentry;
|
||||
ACameraMetadata_const_entry durentry;
|
||||
ACameraMetadata_const_entry infoentry;
|
||||
|
||||
// This can fail with an "unknown error" (with `adb logcat` reporting "no such file or directory")
|
||||
// for "LEGACY" level cameras. I saw this happen on a 30-dollar budget phone I have for testing
|
||||
// (but a different brand budget phone worked, so it's not strictly the low-end of Android devices).
|
||||
// LEGACY devices are seen by onCameraAvailable, but are not otherwise accessible through
|
||||
// libcamera2ndk. The Java camera2 API apparently _can_ access these cameras, but we're going on
|
||||
// without them here for now, in hopes that such hardware is a dying breed.
|
||||
if (pACameraManager_getCameraCharacteristics(cameraMgr, devid, &metadata) != ACAMERA_OK) {
|
||||
return; // oh well.
|
||||
} else if (pACameraMetadata_getConstEntry(metadata, ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, &cfgentry) != ACAMERA_OK) {
|
||||
pACameraMetadata_free(metadata);
|
||||
return; // oh well.
|
||||
} else if (pACameraMetadata_getConstEntry(metadata, ACAMERA_SCALER_AVAILABLE_MIN_FRAME_DURATIONS, &durentry) != ACAMERA_OK) {
|
||||
pACameraMetadata_free(metadata);
|
||||
return; // oh well.
|
||||
}
|
||||
|
||||
*fullname = NULL;
|
||||
if (pACameraMetadata_getConstEntry(metadata, ACAMERA_INFO_VERSION, &infoentry) == ACAMERA_OK) {
|
||||
*fullname = (char *) SDL_malloc(infoentry.count + 1);
|
||||
if (*fullname) {
|
||||
SDL_strlcpy(*fullname, (const char *) infoentry.data.u8, infoentry.count + 1);
|
||||
}
|
||||
}
|
||||
|
||||
ACameraMetadata_const_entry posentry;
|
||||
if (pACameraMetadata_getConstEntry(metadata, ACAMERA_LENS_FACING, &posentry) == ACAMERA_OK) { // ignore this if it fails.
|
||||
if (*posentry.data.u8 == ACAMERA_LENS_FACING_FRONT) {
|
||||
*position = SDL_CAMERA_POSITION_FRONT_FACING;
|
||||
if (!*fullname) {
|
||||
*fullname = SDL_strdup("Front-facing camera");
|
||||
}
|
||||
} else if (*posentry.data.u8 == ACAMERA_LENS_FACING_BACK) {
|
||||
*position = SDL_CAMERA_POSITION_BACK_FACING;
|
||||
if (!*fullname) {
|
||||
*fullname = SDL_strdup("Back-facing camera");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!*fullname) {
|
||||
*fullname = SDL_strdup("Generic camera"); // we tried.
|
||||
}
|
||||
|
||||
const int32_t *i32ptr = cfgentry.data.i32;
|
||||
for (int i = 0; i < cfgentry.count; i++, i32ptr += 4) {
|
||||
const int32_t fmt = i32ptr[0];
|
||||
const int w = (int) i32ptr[1];
|
||||
const int h = (int) i32ptr[2];
|
||||
const int32_t type = i32ptr[3];
|
||||
Uint32 sdlfmt;
|
||||
|
||||
if (type == ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT) {
|
||||
continue;
|
||||
} else if ((w <= 0) || (h <= 0)) {
|
||||
continue;
|
||||
} else if ((sdlfmt = format_android_to_sdl(fmt)) == SDL_PIXELFORMAT_UNKNOWN) {
|
||||
continue;
|
||||
}
|
||||
|
||||
#if 0 // !!! FIXME: these all come out with 0 durations on my test phone. :(
|
||||
const int64_t *i64ptr = durentry.data.i64;
|
||||
for (int j = 0; j < durentry.count; j++, i64ptr += 4) {
|
||||
const int32_t fpsfmt = (int32_t) i64ptr[0];
|
||||
const int fpsw = (int) i64ptr[1];
|
||||
const int fpsh = (int) i64ptr[2];
|
||||
const long long duration = (long long) i64ptr[3];
|
||||
SDL_Log("CAMERA: possible fps %s %dx%d duration=%lld", SDL_GetPixelFormatName(format_android_to_sdl(fpsfmt)), fpsw, fpsh, duration);
|
||||
if ((duration > 0) && (fpsfmt == fmt) && (fpsw == w) && (fpsh == h)) {
|
||||
SDL_AddCameraFormat(add_data, sdlfmt, w, h, duration, 1000000000);
|
||||
}
|
||||
}
|
||||
#else
|
||||
SDL_AddCameraFormat(add_data, sdlfmt, w, h, 1, 30);
|
||||
#endif
|
||||
}
|
||||
|
||||
pACameraMetadata_free(metadata);
|
||||
}
|
||||
|
||||
static SDL_bool FindAndroidCameraDeviceByID(SDL_CameraDevice *device, void *userdata)
|
||||
{
|
||||
const char *devid = (const char *) userdata;
|
||||
return (SDL_strcmp(devid, (const char *) device->handle) == 0);
|
||||
}
|
||||
|
||||
static void MaybeAddDevice(const char *devid)
|
||||
{
|
||||
#if DEBUG_CAMERA
|
||||
SDL_Log("CAMERA: MaybeAddDevice('%s')", devid);
|
||||
#endif
|
||||
|
||||
if (SDL_FindPhysicalCameraDeviceByCallback(FindAndroidCameraDeviceByID, (void *) devid)) {
|
||||
return; // already have this one.
|
||||
}
|
||||
|
||||
SDL_CameraPosition position = SDL_CAMERA_POSITION_UNKNOWN;
|
||||
char *fullname = NULL;
|
||||
CameraFormatAddData add_data;
|
||||
GatherCameraSpecs(devid, &add_data, &fullname, &position);
|
||||
if (add_data.num_specs > 0) {
|
||||
char *namecpy = SDL_strdup(devid);
|
||||
if (namecpy) {
|
||||
SDL_CameraDevice *device = SDL_AddCameraDevice(fullname, position, add_data.num_specs, add_data.specs, namecpy);
|
||||
if (!device) {
|
||||
SDL_free(namecpy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SDL_free(fullname);
|
||||
SDL_free(add_data.specs);
|
||||
}
|
||||
|
||||
// note that camera "availability" covers both hotplugging and whether another
|
||||
// has the device opened, but for something like Android, it's probably fine
|
||||
// to treat both unplugging and loss of access as disconnection events. When
|
||||
// the other app closes the camera, we get an available event as if it was
|
||||
// just plugged back in.
|
||||
|
||||
static void onCameraAvailable(void *context, const char *cameraId)
|
||||
{
|
||||
#if DEBUG_CAMERA
|
||||
SDL_Log("CAMERA: CB onCameraAvailable('%s')", cameraId);
|
||||
#endif
|
||||
SDL_assert(cameraId != NULL);
|
||||
MaybeAddDevice(cameraId);
|
||||
}
|
||||
|
||||
static void onCameraUnavailable(void *context, const char *cameraId)
|
||||
{
|
||||
#if DEBUG_CAMERA
|
||||
SDL_Log("CAMERA: CB onCameraUnvailable('%s')", cameraId);
|
||||
#endif
|
||||
|
||||
SDL_assert(cameraId != NULL);
|
||||
|
||||
// THIS CALLBACK FIRES WHEN YOU OPEN THE DEVICE YOURSELF. :(
|
||||
// Make sure we don't have the device opened, in which case onDisconnected will fire instead if actually lost.
|
||||
SDL_CameraDevice *device = SDL_FindPhysicalCameraDeviceByCallback(FindAndroidCameraDeviceByID, (void *) cameraId);
|
||||
if (device && !device->hidden) {
|
||||
SDL_CameraDeviceDisconnected(device);
|
||||
}
|
||||
}
|
||||
|
||||
static const ACameraManager_AvailabilityCallbacks camera_availability_listener = {
|
||||
NULL,
|
||||
onCameraAvailable,
|
||||
onCameraUnavailable
|
||||
};
|
||||
|
||||
static void ANDROIDCAMERA_DetectDevices(void)
|
||||
{
|
||||
ACameraIdList *list = NULL;
|
||||
camera_status_t res = pACameraManager_getCameraIdList(cameraMgr, &list);
|
||||
|
||||
if ((res == ACAMERA_OK) && list) {
|
||||
const int total = list->numCameras;
|
||||
for (int i = 0; i < total; i++) {
|
||||
MaybeAddDevice(list->cameraIds[i]);
|
||||
}
|
||||
|
||||
pACameraManager_deleteCameraIdList(list);
|
||||
}
|
||||
|
||||
pACameraManager_registerAvailabilityCallback(cameraMgr, &camera_availability_listener);
|
||||
}
|
||||
|
||||
static void ANDROIDCAMERA_Deinitialize(void)
|
||||
{
|
||||
pACameraManager_unregisterAvailabilityCallback(cameraMgr, &camera_availability_listener);
|
||||
DestroyCameraManager();
|
||||
|
||||
dlclose(libcamera2ndk);
|
||||
libcamera2ndk = NULL;
|
||||
pACameraManager_create = NULL;
|
||||
pACameraManager_registerAvailabilityCallback = NULL;
|
||||
pACameraManager_unregisterAvailabilityCallback = NULL;
|
||||
pACameraManager_getCameraIdList = NULL;
|
||||
pACameraManager_deleteCameraIdList = NULL;
|
||||
pACameraCaptureSession_close = NULL;
|
||||
pACaptureRequest_free = NULL;
|
||||
pACameraOutputTarget_free = NULL;
|
||||
pACameraDevice_close = NULL;
|
||||
pACameraManager_delete = NULL;
|
||||
pACaptureSessionOutputContainer_free = NULL;
|
||||
pACaptureSessionOutput_free = NULL;
|
||||
pACameraManager_openCamera = NULL;
|
||||
pACameraDevice_createCaptureRequest = NULL;
|
||||
pACameraDevice_createCaptureSession = NULL;
|
||||
pACameraManager_getCameraCharacteristics = NULL;
|
||||
pACameraMetadata_free = NULL;
|
||||
pACameraMetadata_getConstEntry = NULL;
|
||||
pACameraCaptureSession_setRepeatingRequest = NULL;
|
||||
pACameraOutputTarget_create = NULL;
|
||||
pACaptureRequest_addTarget = NULL;
|
||||
pACaptureSessionOutputContainer_add = NULL;
|
||||
pACaptureSessionOutputContainer_create = NULL;
|
||||
pACaptureSessionOutput_create = NULL;
|
||||
|
||||
dlclose(libmediandk);
|
||||
libmediandk = NULL;
|
||||
pAImage_delete = NULL;
|
||||
pAImage_getTimestamp = NULL;
|
||||
pAImage_getNumberOfPlanes = NULL;
|
||||
pAImage_getPlaneRowStride = NULL;
|
||||
pAImage_getPlaneData = NULL;
|
||||
pAImageReader_acquireNextImage = NULL;
|
||||
pAImageReader_delete = NULL;
|
||||
pAImageReader_setImageListener = NULL;
|
||||
pAImageReader_getWindow = NULL;
|
||||
pAImageReader_new = NULL;
|
||||
}
|
||||
|
||||
static SDL_bool ANDROIDCAMERA_Init(SDL_CameraDriverImpl *impl)
|
||||
{
|
||||
// !!! FIXME: slide this off into a subroutine
|
||||
// system libraries are in android-24 and later; we currently target android-16 and later, so check if they exist at runtime.
|
||||
void *libcamera2 = dlopen("libcamera2ndk.so", RTLD_NOW | RTLD_LOCAL);
|
||||
if (!libcamera2) {
|
||||
SDL_Log("CAMERA: libcamera2ndk.so can't be loaded: %s", dlerror());
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
void *libmedia = dlopen("libmediandk.so", RTLD_NOW | RTLD_LOCAL);
|
||||
if (!libmedia) {
|
||||
SDL_Log("CAMERA: libmediandk.so can't be loaded: %s", dlerror());
|
||||
dlclose(libcamera2);
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
SDL_bool okay = SDL_TRUE;
|
||||
#define LOADSYM(lib, fn) if (okay) { p##fn = (pfn##fn) dlsym(lib, #fn); if (!p##fn) { SDL_Log("CAMERA: symbol '%s' can't be found in %s: %s", #fn, #lib "ndk.so", dlerror()); okay = SDL_FALSE; } }
|
||||
//#define LOADSYM(lib, fn) p##fn = (pfn##fn) fn
|
||||
LOADSYM(libcamera2, ACameraManager_create);
|
||||
LOADSYM(libcamera2, ACameraManager_registerAvailabilityCallback);
|
||||
LOADSYM(libcamera2, ACameraManager_unregisterAvailabilityCallback);
|
||||
LOADSYM(libcamera2, ACameraManager_getCameraIdList);
|
||||
LOADSYM(libcamera2, ACameraManager_deleteCameraIdList);
|
||||
LOADSYM(libcamera2, ACameraCaptureSession_close);
|
||||
LOADSYM(libcamera2, ACaptureRequest_free);
|
||||
LOADSYM(libcamera2, ACameraOutputTarget_free);
|
||||
LOADSYM(libcamera2, ACameraDevice_close);
|
||||
LOADSYM(libcamera2, ACameraManager_delete);
|
||||
LOADSYM(libcamera2, ACaptureSessionOutputContainer_free);
|
||||
LOADSYM(libcamera2, ACaptureSessionOutput_free);
|
||||
LOADSYM(libcamera2, ACameraManager_openCamera);
|
||||
LOADSYM(libcamera2, ACameraDevice_createCaptureRequest);
|
||||
LOADSYM(libcamera2, ACameraDevice_createCaptureSession);
|
||||
LOADSYM(libcamera2, ACameraManager_getCameraCharacteristics);
|
||||
LOADSYM(libcamera2, ACameraMetadata_free);
|
||||
LOADSYM(libcamera2, ACameraMetadata_getConstEntry);
|
||||
LOADSYM(libcamera2, ACameraCaptureSession_setRepeatingRequest);
|
||||
LOADSYM(libcamera2, ACameraOutputTarget_create);
|
||||
LOADSYM(libcamera2, ACaptureRequest_addTarget);
|
||||
LOADSYM(libcamera2, ACaptureSessionOutputContainer_add);
|
||||
LOADSYM(libcamera2, ACaptureSessionOutputContainer_create);
|
||||
LOADSYM(libcamera2, ACaptureSessionOutput_create);
|
||||
LOADSYM(libmedia, AImage_delete);
|
||||
LOADSYM(libmedia, AImage_getTimestamp);
|
||||
LOADSYM(libmedia, AImage_getNumberOfPlanes);
|
||||
LOADSYM(libmedia, AImage_getPlaneRowStride);
|
||||
LOADSYM(libmedia, AImage_getPlaneData);
|
||||
LOADSYM(libmedia, AImageReader_acquireNextImage);
|
||||
LOADSYM(libmedia, AImageReader_delete);
|
||||
LOADSYM(libmedia, AImageReader_setImageListener);
|
||||
LOADSYM(libmedia, AImageReader_getWindow);
|
||||
LOADSYM(libmedia, AImageReader_new);
|
||||
LOADSYM(libmedia, AImage_getWidth);
|
||||
LOADSYM(libmedia, AImage_getHeight);
|
||||
|
||||
#undef LOADSYM
|
||||
|
||||
if (!okay) {
|
||||
dlclose(libmedia);
|
||||
dlclose(libcamera2);
|
||||
}
|
||||
|
||||
if (CreateCameraManager() < 0) {
|
||||
dlclose(libmedia);
|
||||
dlclose(libcamera2);
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
libcamera2ndk = libcamera2;
|
||||
libmediandk = libmedia;
|
||||
|
||||
impl->DetectDevices = ANDROIDCAMERA_DetectDevices;
|
||||
impl->OpenDevice = ANDROIDCAMERA_OpenDevice;
|
||||
impl->CloseDevice = ANDROIDCAMERA_CloseDevice;
|
||||
impl->WaitDevice = ANDROIDCAMERA_WaitDevice;
|
||||
impl->AcquireFrame = ANDROIDCAMERA_AcquireFrame;
|
||||
impl->ReleaseFrame = ANDROIDCAMERA_ReleaseFrame;
|
||||
impl->FreeDeviceHandle = ANDROIDCAMERA_FreeDeviceHandle;
|
||||
impl->Deinitialize = ANDROIDCAMERA_Deinitialize;
|
||||
|
||||
impl->ProvidesOwnCallbackThread = SDL_TRUE;
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
CameraBootStrap ANDROIDCAMERA_bootstrap = {
|
||||
"android", "SDL Android camera driver", ANDROIDCAMERA_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
#endif
|
||||
479
external/sdl/SDL/src/camera/coremedia/SDL_camera_coremedia.m
vendored
Normal file
479
external/sdl/SDL/src/camera/coremedia/SDL_camera_coremedia.m
vendored
Normal file
@@ -0,0 +1,479 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifdef SDL_CAMERA_DRIVER_COREMEDIA
|
||||
|
||||
#include "../SDL_syscamera.h"
|
||||
#include "../SDL_camera_c.h"
|
||||
#include "../../thread/SDL_systhread.h"
|
||||
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#import <CoreMedia/CoreMedia.h>
|
||||
|
||||
/*
|
||||
* Need to link with:: CoreMedia CoreVideo
|
||||
*
|
||||
* Add in pInfo.list:
|
||||
* <key>NSCameraUsageDescription</key> <string>Access camera</string>
|
||||
*
|
||||
*
|
||||
* MACOSX:
|
||||
* Add to the Code Sign Entitlement file:
|
||||
* <key>com.apple.security.device.camera</key> <true/>
|
||||
*/
|
||||
|
||||
static Uint32 CoreMediaFormatToSDL(FourCharCode fmt)
|
||||
{
|
||||
switch (fmt) {
|
||||
#define CASE(x, y) case x: return y
|
||||
// the 16LE ones should use 16BE if we're on a Bigendian system like PowerPC,
|
||||
// but at current time there is no bigendian Apple platform that has CoreMedia.
|
||||
CASE(kCMPixelFormat_16LE555, SDL_PIXELFORMAT_RGB555);
|
||||
CASE(kCMPixelFormat_16LE5551, SDL_PIXELFORMAT_RGBA5551);
|
||||
CASE(kCMPixelFormat_16LE565, SDL_PIXELFORMAT_RGB565);
|
||||
CASE(kCMPixelFormat_24RGB, SDL_PIXELFORMAT_RGB24);
|
||||
CASE(kCMPixelFormat_32ARGB, SDL_PIXELFORMAT_ARGB32);
|
||||
CASE(kCMPixelFormat_32BGRA, SDL_PIXELFORMAT_BGRA32);
|
||||
CASE(kCMPixelFormat_422YpCbCr8, SDL_PIXELFORMAT_YUY2);
|
||||
CASE(kCMPixelFormat_422YpCbCr8_yuvs, SDL_PIXELFORMAT_UYVY);
|
||||
#undef CASE
|
||||
default:
|
||||
#if DEBUG_CAMERA
|
||||
SDL_Log("CAMERA: Unknown format FourCharCode '%d'", (int) fmt);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
return SDL_PIXELFORMAT_UNKNOWN;
|
||||
}
|
||||
|
||||
@class SDLCaptureVideoDataOutputSampleBufferDelegate;
|
||||
|
||||
// just a simple wrapper to help ARC manage memory...
|
||||
@interface SDLPrivateCameraData : NSObject
|
||||
@property(nonatomic, retain) AVCaptureSession *session;
|
||||
@property(nonatomic, retain) SDLCaptureVideoDataOutputSampleBufferDelegate *delegate;
|
||||
@property(nonatomic, assign) CMSampleBufferRef current_sample;
|
||||
@end
|
||||
|
||||
@implementation SDLPrivateCameraData
|
||||
@end
|
||||
|
||||
|
||||
static SDL_bool CheckCameraPermissions(SDL_CameraDevice *device)
|
||||
{
|
||||
if (device->permission == 0) { // still expecting a permission result.
|
||||
if (@available(macOS 14, *)) {
|
||||
const AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
|
||||
if (status != AVAuthorizationStatusNotDetermined) { // NotDetermined == still waiting for an answer from the user.
|
||||
SDL_CameraDevicePermissionOutcome(device, (status == AVAuthorizationStatusAuthorized) ? SDL_TRUE : SDL_FALSE);
|
||||
}
|
||||
} else {
|
||||
SDL_CameraDevicePermissionOutcome(device, SDL_TRUE); // always allowed (or just unqueryable...?) on older macOS.
|
||||
}
|
||||
}
|
||||
|
||||
return (device->permission > 0);
|
||||
}
|
||||
|
||||
// this delegate just receives new video frames on a Grand Central Dispatch queue, and fires off the
|
||||
// main device thread iterate function directly to consume it.
|
||||
@interface SDLCaptureVideoDataOutputSampleBufferDelegate : NSObject<AVCaptureVideoDataOutputSampleBufferDelegate>
|
||||
@property SDL_CameraDevice *device;
|
||||
-(id) init:(SDL_CameraDevice *) dev;
|
||||
-(void) captureOutput:(AVCaptureOutput *)output didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection;
|
||||
@end
|
||||
|
||||
@implementation SDLCaptureVideoDataOutputSampleBufferDelegate
|
||||
|
||||
-(id) init:(SDL_CameraDevice *) dev {
|
||||
if ( self = [super init] ) {
|
||||
_device = dev;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) captureOutput:(AVCaptureOutput *)output didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
|
||||
{
|
||||
SDL_CameraDevice *device = self.device;
|
||||
if (!device || !device->hidden) {
|
||||
return; // oh well.
|
||||
}
|
||||
|
||||
if (!CheckCameraPermissions(device)) {
|
||||
return; // nothing to do right now, dump what is probably a completely black frame.
|
||||
}
|
||||
|
||||
SDLPrivateCameraData *hidden = (__bridge SDLPrivateCameraData *) device->hidden;
|
||||
hidden.current_sample = sampleBuffer;
|
||||
SDL_CameraThreadIterate(device);
|
||||
hidden.current_sample = NULL;
|
||||
}
|
||||
|
||||
- (void)captureOutput:(AVCaptureOutput *)output didDropSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
|
||||
{
|
||||
#if DEBUG_CAMERA
|
||||
SDL_Log("CAMERA: Drop frame.");
|
||||
#endif
|
||||
}
|
||||
@end
|
||||
|
||||
static int COREMEDIA_WaitDevice(SDL_CameraDevice *device)
|
||||
{
|
||||
return 0; // this isn't used atm, since we run our own thread out of Grand Central Dispatch.
|
||||
}
|
||||
|
||||
static int COREMEDIA_AcquireFrame(SDL_CameraDevice *device, SDL_Surface *frame, Uint64 *timestampNS)
|
||||
{
|
||||
int retval = 1;
|
||||
SDLPrivateCameraData *hidden = (__bridge SDLPrivateCameraData *) device->hidden;
|
||||
CMSampleBufferRef sample_buffer = hidden.current_sample;
|
||||
hidden.current_sample = NULL;
|
||||
SDL_assert(sample_buffer != NULL); // should only have been called from our delegate with a new frame.
|
||||
|
||||
CMSampleTimingInfo timinginfo;
|
||||
if (CMSampleBufferGetSampleTimingInfo(sample_buffer, 0, &timinginfo) == noErr) {
|
||||
*timestampNS = (Uint64) (CMTimeGetSeconds(timinginfo.presentationTimeStamp) * ((Float64) SDL_NS_PER_SECOND));
|
||||
} else {
|
||||
SDL_assert(!"this shouldn't happen, I think.");
|
||||
*timestampNS = 0;
|
||||
}
|
||||
|
||||
CVImageBufferRef image = CMSampleBufferGetImageBuffer(sample_buffer); // does not retain `image` (and we don't want it to).
|
||||
const int numPlanes = (int) CVPixelBufferGetPlaneCount(image);
|
||||
const int planar = (int) CVPixelBufferIsPlanar(image);
|
||||
|
||||
#if DEBUG_CAMERA
|
||||
const int w = (int) CVPixelBufferGetWidth(image);
|
||||
const int h = (int) CVPixelBufferGetHeight(image);
|
||||
const int sz = (int) CVPixelBufferGetDataSize(image);
|
||||
const int pitch = (int) CVPixelBufferGetBytesPerRow(image);
|
||||
SDL_Log("CAMERA: buffer planar=%d numPlanes=%d %d x %d sz=%d pitch=%d", planar, numPlanes, w, h, sz, pitch);
|
||||
#endif
|
||||
|
||||
// !!! FIXME: this currently copies the data to the surface (see FIXME about non-contiguous planar surfaces, but in theory we could just keep this locked until ReleaseFrame...
|
||||
CVPixelBufferLockBaseAddress(image, 0);
|
||||
|
||||
if ((planar == 0) && (numPlanes == 0)) {
|
||||
const int pitch = (int) CVPixelBufferGetBytesPerRow(image);
|
||||
const size_t buflen = pitch * frame->h;
|
||||
frame->pixels = SDL_aligned_alloc(SDL_SIMDGetAlignment(), buflen);
|
||||
if (frame->pixels == NULL) {
|
||||
retval = -1;
|
||||
} else {
|
||||
frame->pitch = pitch;
|
||||
SDL_memcpy(frame->pixels, CVPixelBufferGetBaseAddress(image), buflen);
|
||||
}
|
||||
} else {
|
||||
// !!! FIXME: we have an open issue in SDL3 to allow SDL_Surface to support non-contiguous planar data, but we don't have it yet.
|
||||
size_t buflen = 0;
|
||||
for (int i = 0; (i < numPlanes) && (i < 3); i++) {
|
||||
buflen += CVPixelBufferGetBytesPerRowOfPlane(image, i);
|
||||
}
|
||||
buflen *= frame->h;
|
||||
|
||||
frame->pixels = SDL_aligned_alloc(SDL_SIMDGetAlignment(), buflen);
|
||||
if (frame->pixels == NULL) {
|
||||
retval = -1;
|
||||
} else {
|
||||
Uint8 *dst = frame->pixels;
|
||||
frame->pitch = (int) CVPixelBufferGetBytesPerRowOfPlane(image, 0); // this is what SDL3 currently expects, probably incorrectly.
|
||||
for (int i = 0; (i < numPlanes) && (i < 3); i++) {
|
||||
const void *src = CVPixelBufferGetBaseAddressOfPlane(image, i);
|
||||
const size_t pitch = CVPixelBufferGetBytesPerRowOfPlane(image, i);
|
||||
SDL_memcpy(dst, src, pitch * frame->h);
|
||||
dst += pitch * frame->h;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CVPixelBufferUnlockBaseAddress(image, 0);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void COREMEDIA_ReleaseFrame(SDL_CameraDevice *device, SDL_Surface *frame)
|
||||
{
|
||||
// !!! FIXME: this currently copies the data to the surface, but in theory we could just keep this locked until ReleaseFrame...
|
||||
SDL_aligned_free(frame->pixels);
|
||||
}
|
||||
|
||||
static void COREMEDIA_CloseDevice(SDL_CameraDevice *device)
|
||||
{
|
||||
if (device && device->hidden) {
|
||||
SDLPrivateCameraData *hidden = (SDLPrivateCameraData *) CFBridgingRelease(device->hidden);
|
||||
device->hidden = NULL;
|
||||
|
||||
AVCaptureSession *session = hidden.session;
|
||||
if (session) {
|
||||
hidden.session = nil;
|
||||
[session stopRunning];
|
||||
[session removeInput:[session.inputs objectAtIndex:0]];
|
||||
[session removeOutput:(AVCaptureVideoDataOutput*)[session.outputs objectAtIndex:0]];
|
||||
session = nil;
|
||||
}
|
||||
|
||||
hidden.delegate = NULL;
|
||||
hidden.current_sample = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int COREMEDIA_OpenDevice(SDL_CameraDevice *device, const SDL_CameraSpec *spec)
|
||||
{
|
||||
AVCaptureDevice *avdevice = (__bridge AVCaptureDevice *) device->handle;
|
||||
|
||||
// Pick format that matches the spec
|
||||
const Uint32 sdlfmt = spec->format;
|
||||
const int w = spec->width;
|
||||
const int h = spec->height;
|
||||
const int rate = spec->interval_denominator;
|
||||
AVCaptureDeviceFormat *spec_format = nil;
|
||||
NSArray<AVCaptureDeviceFormat *> *formats = [avdevice formats];
|
||||
for (AVCaptureDeviceFormat *format in formats) {
|
||||
CMFormatDescriptionRef formatDescription = [format formatDescription];
|
||||
if (CoreMediaFormatToSDL(CMFormatDescriptionGetMediaSubType(formatDescription)) != sdlfmt) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const CMVideoDimensions dim = CMVideoFormatDescriptionGetDimensions(formatDescription);
|
||||
if ( ((int) dim.width != w) || (((int) dim.height) != h) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (AVFrameRateRange *framerate in format.videoSupportedFrameRateRanges) {
|
||||
if ((rate == (int) SDL_ceil((double) framerate.minFrameRate)) || (rate == (int) SDL_floor((double) framerate.maxFrameRate))) {
|
||||
spec_format = format;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (spec_format != nil) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (spec_format == nil) {
|
||||
return SDL_SetError("camera spec format not available");
|
||||
} else if (![avdevice lockForConfiguration:NULL]) {
|
||||
return SDL_SetError("Cannot lockForConfiguration");
|
||||
}
|
||||
|
||||
avdevice.activeFormat = spec_format;
|
||||
[avdevice unlockForConfiguration];
|
||||
|
||||
AVCaptureSession *session = [[AVCaptureSession alloc] init];
|
||||
if (session == nil) {
|
||||
return SDL_SetError("Failed to allocate/init AVCaptureSession");
|
||||
}
|
||||
|
||||
session.sessionPreset = AVCaptureSessionPresetHigh;
|
||||
|
||||
NSError *error = nil;
|
||||
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:avdevice error:&error];
|
||||
if (!input) {
|
||||
return SDL_SetError("Cannot create AVCaptureDeviceInput");
|
||||
}
|
||||
|
||||
AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init];
|
||||
if (!output) {
|
||||
return SDL_SetError("Cannot create AVCaptureVideoDataOutput");
|
||||
}
|
||||
|
||||
char threadname[64];
|
||||
SDL_GetCameraThreadName(device, threadname, sizeof (threadname));
|
||||
dispatch_queue_t queue = dispatch_queue_create(threadname, NULL);
|
||||
//dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
|
||||
if (!queue) {
|
||||
return SDL_SetError("dispatch_queue_create() failed");
|
||||
}
|
||||
|
||||
SDLCaptureVideoDataOutputSampleBufferDelegate *delegate = [[SDLCaptureVideoDataOutputSampleBufferDelegate alloc] init:device];
|
||||
if (delegate == nil) {
|
||||
return SDL_SetError("Cannot create SDLCaptureVideoDataOutputSampleBufferDelegate");
|
||||
}
|
||||
[output setSampleBufferDelegate:delegate queue:queue];
|
||||
|
||||
if (![session canAddInput:input]) {
|
||||
return SDL_SetError("Cannot add AVCaptureDeviceInput");
|
||||
}
|
||||
[session addInput:input];
|
||||
|
||||
if (![session canAddOutput:output]) {
|
||||
return SDL_SetError("Cannot add AVCaptureVideoDataOutput");
|
||||
}
|
||||
[session addOutput:output];
|
||||
|
||||
[session commitConfiguration];
|
||||
|
||||
SDLPrivateCameraData *hidden = [[SDLPrivateCameraData alloc] init];
|
||||
if (hidden == nil) {
|
||||
return SDL_SetError("Cannot create SDLPrivateCameraData");
|
||||
}
|
||||
|
||||
hidden.session = session;
|
||||
hidden.delegate = delegate;
|
||||
hidden.current_sample = NULL;
|
||||
device->hidden = (struct SDL_PrivateCameraData *)CFBridgingRetain(hidden);
|
||||
|
||||
[session startRunning]; // !!! FIXME: docs say this can block while camera warms up and shouldn't be done on main thread. Maybe push through `queue`?
|
||||
|
||||
CheckCameraPermissions(device); // check right away, in case the process is already granted permission.
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void COREMEDIA_FreeDeviceHandle(SDL_CameraDevice *device)
|
||||
{
|
||||
if (device && device->handle) {
|
||||
CFBridgingRelease(device->handle);
|
||||
}
|
||||
}
|
||||
|
||||
static void GatherCameraSpecs(AVCaptureDevice *device, CameraFormatAddData *add_data)
|
||||
{
|
||||
SDL_zerop(add_data);
|
||||
|
||||
for (AVCaptureDeviceFormat *fmt in device.formats) {
|
||||
if (CMFormatDescriptionGetMediaType(fmt.formatDescription) != kCMMediaType_Video) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const Uint32 sdlfmt = CoreMediaFormatToSDL(CMFormatDescriptionGetMediaSubType(fmt.formatDescription));
|
||||
if (sdlfmt == SDL_PIXELFORMAT_UNKNOWN) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const CMVideoDimensions dims = CMVideoFormatDescriptionGetDimensions(fmt.formatDescription);
|
||||
const int w = (int) dims.width;
|
||||
const int h = (int) dims.height;
|
||||
for (AVFrameRateRange *framerate in fmt.videoSupportedFrameRateRanges) {
|
||||
int rate;
|
||||
|
||||
rate = (int) SDL_ceil((double) framerate.minFrameRate);
|
||||
if (rate) {
|
||||
SDL_AddCameraFormat(add_data, sdlfmt, w, h, 1, rate);
|
||||
}
|
||||
rate = (int) SDL_floor((double) framerate.maxFrameRate);
|
||||
if (rate) {
|
||||
SDL_AddCameraFormat(add_data, sdlfmt, w, h, 1, rate);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static SDL_bool FindCoreMediaCameraDeviceByUniqueID(SDL_CameraDevice *device, void *userdata)
|
||||
{
|
||||
NSString *uniqueid = (__bridge NSString *) userdata;
|
||||
AVCaptureDevice *avdev = (__bridge AVCaptureDevice *) device->handle;
|
||||
return ([uniqueid isEqualToString:avdev.uniqueID]) ? SDL_TRUE : SDL_FALSE;
|
||||
}
|
||||
|
||||
static void MaybeAddDevice(AVCaptureDevice *avdevice)
|
||||
{
|
||||
if (!avdevice.connected) {
|
||||
return; // not connected.
|
||||
} else if (![avdevice hasMediaType:AVMediaTypeVideo]) {
|
||||
return; // not a camera.
|
||||
} else if (SDL_FindPhysicalCameraDeviceByCallback(FindCoreMediaCameraDeviceByUniqueID, (__bridge void *) avdevice.uniqueID)) {
|
||||
return; // already have this one.
|
||||
}
|
||||
|
||||
CameraFormatAddData add_data;
|
||||
GatherCameraSpecs(avdevice, &add_data);
|
||||
if (add_data.num_specs > 0) {
|
||||
SDL_CameraPosition position = SDL_CAMERA_POSITION_UNKNOWN;
|
||||
if (avdevice.position == AVCaptureDevicePositionFront) {
|
||||
position = SDL_CAMERA_POSITION_FRONT_FACING;
|
||||
} else if (avdevice.position == AVCaptureDevicePositionBack) {
|
||||
position = SDL_CAMERA_POSITION_BACK_FACING;
|
||||
}
|
||||
SDL_AddCameraDevice(avdevice.localizedName.UTF8String, position, add_data.num_specs, add_data.specs, (void *) CFBridgingRetain(avdevice));
|
||||
}
|
||||
|
||||
SDL_free(add_data.specs);
|
||||
}
|
||||
|
||||
static void COREMEDIA_DetectDevices(void)
|
||||
{
|
||||
NSArray<AVCaptureDevice *> *devices = nil;
|
||||
|
||||
if (@available(macOS 10.15, iOS 13, *)) {
|
||||
// kind of annoying that there isn't a "give me anything that looks like a camera" option,
|
||||
// so this list will need to be updated when Apple decides to add
|
||||
// AVCaptureDeviceTypeBuiltInQuadrupleCamera some day.
|
||||
NSArray *device_types = @[
|
||||
#ifdef SDL_PLATFORM_IOS
|
||||
AVCaptureDeviceTypeBuiltInTelephotoCamera,
|
||||
AVCaptureDeviceTypeBuiltInDualCamera,
|
||||
AVCaptureDeviceTypeBuiltInDualWideCamera,
|
||||
AVCaptureDeviceTypeBuiltInTripleCamera,
|
||||
AVCaptureDeviceTypeBuiltInUltraWideCamera,
|
||||
#else
|
||||
AVCaptureDeviceTypeExternalUnknown,
|
||||
#endif
|
||||
AVCaptureDeviceTypeBuiltInWideAngleCamera
|
||||
];
|
||||
|
||||
AVCaptureDeviceDiscoverySession *discoverySession = [AVCaptureDeviceDiscoverySession
|
||||
discoverySessionWithDeviceTypes:device_types
|
||||
mediaType:AVMediaTypeVideo
|
||||
position:AVCaptureDevicePositionUnspecified];
|
||||
|
||||
devices = discoverySession.devices;
|
||||
// !!! FIXME: this can use Key Value Observation to get hotplug events.
|
||||
} else {
|
||||
// this is deprecated but works back to macOS 10.7; 10.15 added AVCaptureDeviceDiscoverySession as a replacement.
|
||||
devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
|
||||
// !!! FIXME: this can use AVCaptureDeviceWasConnectedNotification and AVCaptureDeviceWasDisconnectedNotification with NSNotificationCenter to get hotplug events.
|
||||
}
|
||||
|
||||
for (AVCaptureDevice *device in devices) {
|
||||
MaybeAddDevice(device);
|
||||
}
|
||||
}
|
||||
|
||||
static void COREMEDIA_Deinitialize(void)
|
||||
{
|
||||
// !!! FIXME: disable hotplug.
|
||||
}
|
||||
|
||||
static SDL_bool COREMEDIA_Init(SDL_CameraDriverImpl *impl)
|
||||
{
|
||||
impl->DetectDevices = COREMEDIA_DetectDevices;
|
||||
impl->OpenDevice = COREMEDIA_OpenDevice;
|
||||
impl->CloseDevice = COREMEDIA_CloseDevice;
|
||||
impl->WaitDevice = COREMEDIA_WaitDevice;
|
||||
impl->AcquireFrame = COREMEDIA_AcquireFrame;
|
||||
impl->ReleaseFrame = COREMEDIA_ReleaseFrame;
|
||||
impl->FreeDeviceHandle = COREMEDIA_FreeDeviceHandle;
|
||||
impl->Deinitialize = COREMEDIA_Deinitialize;
|
||||
|
||||
impl->ProvidesOwnCallbackThread = SDL_TRUE;
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
CameraBootStrap COREMEDIA_bootstrap = {
|
||||
"coremedia", "SDL Apple CoreMedia camera driver", COREMEDIA_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
#endif // SDL_CAMERA_DRIVER_COREMEDIA
|
||||
|
||||
80
external/sdl/SDL/src/camera/dummy/SDL_camera_dummy.c
vendored
Normal file
80
external/sdl/SDL/src/camera/dummy/SDL_camera_dummy.c
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifdef SDL_CAMERA_DRIVER_DUMMY
|
||||
|
||||
#include "../SDL_syscamera.h"
|
||||
|
||||
static int DUMMYCAMERA_OpenDevice(SDL_CameraDevice *device, const SDL_CameraSpec *spec)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static void DUMMYCAMERA_CloseDevice(SDL_CameraDevice *device)
|
||||
{
|
||||
}
|
||||
|
||||
static int DUMMYCAMERA_WaitDevice(SDL_CameraDevice *device)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static int DUMMYCAMERA_AcquireFrame(SDL_CameraDevice *device, SDL_Surface *frame, Uint64 *timestampNS)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static void DUMMYCAMERA_ReleaseFrame(SDL_CameraDevice *device, SDL_Surface *frame)
|
||||
{
|
||||
}
|
||||
|
||||
static void DUMMYCAMERA_DetectDevices(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void DUMMYCAMERA_FreeDeviceHandle(SDL_CameraDevice *device)
|
||||
{
|
||||
}
|
||||
|
||||
static void DUMMYCAMERA_Deinitialize(void)
|
||||
{
|
||||
}
|
||||
|
||||
static SDL_bool DUMMYCAMERA_Init(SDL_CameraDriverImpl *impl)
|
||||
{
|
||||
impl->DetectDevices = DUMMYCAMERA_DetectDevices;
|
||||
impl->OpenDevice = DUMMYCAMERA_OpenDevice;
|
||||
impl->CloseDevice = DUMMYCAMERA_CloseDevice;
|
||||
impl->WaitDevice = DUMMYCAMERA_WaitDevice;
|
||||
impl->AcquireFrame = DUMMYCAMERA_AcquireFrame;
|
||||
impl->ReleaseFrame = DUMMYCAMERA_ReleaseFrame;
|
||||
impl->FreeDeviceHandle = DUMMYCAMERA_FreeDeviceHandle;
|
||||
impl->Deinitialize = DUMMYCAMERA_Deinitialize;
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
CameraBootStrap DUMMYCAMERA_bootstrap = {
|
||||
"dummy", "SDL dummy camera driver", DUMMYCAMERA_Init, SDL_TRUE
|
||||
};
|
||||
|
||||
#endif // SDL_CAMERA_DRIVER_DUMMY
|
||||
265
external/sdl/SDL/src/camera/emscripten/SDL_camera_emscripten.c
vendored
Normal file
265
external/sdl/SDL/src/camera/emscripten/SDL_camera_emscripten.c
vendored
Normal file
@@ -0,0 +1,265 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifdef SDL_CAMERA_DRIVER_EMSCRIPTEN
|
||||
|
||||
#include "../SDL_syscamera.h"
|
||||
#include "../SDL_camera_c.h"
|
||||
#include "../../video/SDL_pixels_c.h"
|
||||
|
||||
#include <emscripten/emscripten.h>
|
||||
|
||||
// just turn off clang-format for this whole file, this INDENT_OFF stuff on
|
||||
// each EM_ASM section is ugly.
|
||||
/* *INDENT-OFF* */ /* clang-format off */
|
||||
|
||||
EM_JS_DEPS(sdlcamera, "$dynCall");
|
||||
|
||||
static int EMSCRIPTENCAMERA_WaitDevice(SDL_CameraDevice *device)
|
||||
{
|
||||
SDL_assert(!"This shouldn't be called"); // we aren't using SDL's internal thread.
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int EMSCRIPTENCAMERA_AcquireFrame(SDL_CameraDevice *device, SDL_Surface *frame, Uint64 *timestampNS)
|
||||
{
|
||||
void *rgba = SDL_malloc(device->actual_spec.width * device->actual_spec.height * 4);
|
||||
if (!rgba) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
*timestampNS = SDL_GetTicksNS(); // best we can do here.
|
||||
|
||||
const int rc = MAIN_THREAD_EM_ASM_INT({
|
||||
const w = $0;
|
||||
const h = $1;
|
||||
const rgba = $2;
|
||||
const SDL3 = Module['SDL3'];
|
||||
if ((typeof(SDL3) === 'undefined') || (typeof(SDL3.camera) === 'undefined') || (typeof(SDL3.camera.ctx2d) === 'undefined')) {
|
||||
return 0; // don't have something we need, oh well.
|
||||
}
|
||||
|
||||
SDL3.camera.ctx2d.drawImage(SDL3.camera.video, 0, 0, w, h);
|
||||
const imgrgba = SDL3.camera.ctx2d.getImageData(0, 0, w, h).data;
|
||||
Module.HEAPU8.set(imgrgba, rgba);
|
||||
|
||||
return 1;
|
||||
}, device->actual_spec.width, device->actual_spec.height, rgba);
|
||||
|
||||
if (!rc) {
|
||||
SDL_free(rgba);
|
||||
return 0; // something went wrong, maybe shutting down; just don't return a frame.
|
||||
}
|
||||
|
||||
frame->pixels = rgba;
|
||||
frame->pitch = device->actual_spec.width * 4;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void EMSCRIPTENCAMERA_ReleaseFrame(SDL_CameraDevice *device, SDL_Surface *frame)
|
||||
{
|
||||
SDL_free(frame->pixels);
|
||||
}
|
||||
|
||||
static void EMSCRIPTENCAMERA_CloseDevice(SDL_CameraDevice *device)
|
||||
{
|
||||
if (device) {
|
||||
MAIN_THREAD_EM_ASM({
|
||||
const SDL3 = Module['SDL3'];
|
||||
if ((typeof(SDL3) === 'undefined') || (typeof(SDL3.camera) === 'undefined') || (typeof(SDL3.camera.stream) === 'undefined')) {
|
||||
return; // camera was closed and/or subsystem was shut down, we're already done.
|
||||
}
|
||||
SDL3.camera.stream.getTracks().forEach(track => track.stop()); // stop all recording.
|
||||
_SDL_free(SDL3.camera.rgba);
|
||||
SDL3.camera = {}; // dump our references to everything.
|
||||
});
|
||||
SDL_free(device->hidden);
|
||||
device->hidden = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void SDLEmscriptenCameraDevicePermissionOutcome(SDL_CameraDevice *device, int approved, int w, int h, int fps)
|
||||
{
|
||||
device->spec.width = device->actual_spec.width = w;
|
||||
device->spec.height = device->actual_spec.height = h;
|
||||
device->spec.interval_numerator = device->actual_spec.interval_numerator = 1;
|
||||
device->spec.interval_denominator = device->actual_spec.interval_denominator = fps;
|
||||
SDL_CameraDevicePermissionOutcome(device, approved ? SDL_TRUE : SDL_FALSE);
|
||||
}
|
||||
|
||||
static int EMSCRIPTENCAMERA_OpenDevice(SDL_CameraDevice *device, const SDL_CameraSpec *spec)
|
||||
{
|
||||
MAIN_THREAD_EM_ASM({
|
||||
// Since we can't get actual specs until we make a move that prompts the user for
|
||||
// permission, we don't list any specs for the device and wrangle it during device open.
|
||||
const device = $0;
|
||||
const w = $1;
|
||||
const h = $2;
|
||||
const interval_numerator = $3;
|
||||
const interval_denominator = $4;
|
||||
const outcome = $5;
|
||||
const iterate = $6;
|
||||
|
||||
const constraints = {};
|
||||
if ((w <= 0) || (h <= 0)) {
|
||||
constraints.video = true; // didn't ask for anything, let the system choose.
|
||||
} else {
|
||||
constraints.video = {}; // asked for a specific thing: request it as "ideal" but take closest hardware will offer.
|
||||
constraints.video.width = w;
|
||||
constraints.video.height = h;
|
||||
}
|
||||
|
||||
if ((interval_numerator > 0) && (interval_denominator > 0)) {
|
||||
var fps = interval_denominator / interval_numerator;
|
||||
constraints.video.frameRate = { ideal: fps };
|
||||
}
|
||||
|
||||
function grabNextCameraFrame() { // !!! FIXME: this (currently) runs as a requestAnimationFrame callback, for lack of a better option.
|
||||
const SDL3 = Module['SDL3'];
|
||||
if ((typeof(SDL3) === 'undefined') || (typeof(SDL3.camera) === 'undefined') || (typeof(SDL3.camera.stream) === 'undefined')) {
|
||||
return; // camera was closed and/or subsystem was shut down, stop iterating here.
|
||||
}
|
||||
|
||||
// time for a new frame from the camera?
|
||||
const nextframems = SDL3.camera.next_frame_time;
|
||||
const now = performance.now();
|
||||
if (now >= nextframems) {
|
||||
dynCall('vi', iterate, [device]); // calls SDL_CameraThreadIterate, which will call our AcquireFrame implementation.
|
||||
|
||||
// bump ahead but try to stay consistent on timing, in case we dropped frames.
|
||||
while (SDL3.camera.next_frame_time < now) {
|
||||
SDL3.camera.next_frame_time += SDL3.camera.fpsincrms;
|
||||
}
|
||||
}
|
||||
|
||||
requestAnimationFrame(grabNextCameraFrame); // run this function again at the display framerate. (!!! FIXME: would this be better as requestIdleCallback?)
|
||||
}
|
||||
|
||||
navigator.mediaDevices.getUserMedia(constraints)
|
||||
.then((stream) => {
|
||||
const settings = stream.getVideoTracks()[0].getSettings();
|
||||
const actualw = settings.width;
|
||||
const actualh = settings.height;
|
||||
const actualfps = settings.frameRate;
|
||||
console.log("Camera is opened! Actual spec: (" + actualw + "x" + actualh + "), fps=" + actualfps);
|
||||
|
||||
dynCall('viiiii', outcome, [device, 1, actualw, actualh, actualfps]);
|
||||
|
||||
const video = document.createElement("video");
|
||||
video.width = actualw;
|
||||
video.height = actualh;
|
||||
video.style.display = 'none'; // we need to attach this to a hidden video node so we can read it as pixels.
|
||||
video.srcObject = stream;
|
||||
|
||||
const canvas = document.createElement("canvas");
|
||||
canvas.width = actualw;
|
||||
canvas.height = actualh;
|
||||
canvas.style.display = 'none'; // we need to attach this to a hidden video node so we can read it as pixels.
|
||||
|
||||
const ctx2d = canvas.getContext('2d');
|
||||
|
||||
const SDL3 = Module['SDL3'];
|
||||
SDL3.camera.width = actualw;
|
||||
SDL3.camera.height = actualh;
|
||||
SDL3.camera.fps = actualfps;
|
||||
SDL3.camera.fpsincrms = 1000.0 / actualfps;
|
||||
SDL3.camera.stream = stream;
|
||||
SDL3.camera.video = video;
|
||||
SDL3.camera.canvas = canvas;
|
||||
SDL3.camera.ctx2d = ctx2d;
|
||||
SDL3.camera.rgba = 0;
|
||||
SDL3.camera.next_frame_time = performance.now();
|
||||
|
||||
video.play();
|
||||
video.addEventListener('loadedmetadata', () => {
|
||||
grabNextCameraFrame(); // start this loop going.
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error("Tried to open camera but it threw an error! " + err.name + ": " + err.message);
|
||||
dynCall('viiiii', outcome, [device, 0, 0, 0, 0]); // we call this a permission error, because it probably is.
|
||||
});
|
||||
}, device, spec->width, spec->height, spec->interval_numerator, spec->interval_denominator, SDLEmscriptenCameraDevicePermissionOutcome, SDL_CameraThreadIterate);
|
||||
|
||||
return 0; // the real work waits until the user approves a camera.
|
||||
}
|
||||
|
||||
static void EMSCRIPTENCAMERA_FreeDeviceHandle(SDL_CameraDevice *device)
|
||||
{
|
||||
// no-op.
|
||||
}
|
||||
|
||||
static void EMSCRIPTENCAMERA_Deinitialize(void)
|
||||
{
|
||||
MAIN_THREAD_EM_ASM({
|
||||
if (typeof(Module['SDL3']) !== 'undefined') {
|
||||
Module['SDL3'].camera = undefined;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void EMSCRIPTENCAMERA_DetectDevices(void)
|
||||
{
|
||||
// `navigator.mediaDevices` is not defined if unsupported or not in a secure context!
|
||||
const int supported = MAIN_THREAD_EM_ASM_INT({ return (navigator.mediaDevices === undefined) ? 0 : 1; });
|
||||
|
||||
// if we have support at all, report a single generic camera with no specs.
|
||||
// We'll find out if there really _is_ a camera when we try to open it, but querying it for real here
|
||||
// will pop up a user permission dialog warning them we're trying to access the camera, and we generally
|
||||
// don't want that during SDL_Init().
|
||||
if (supported) {
|
||||
SDL_AddCameraDevice("Web browser's camera", SDL_CAMERA_POSITION_UNKNOWN, 0, NULL, (void *) (size_t) 0x1);
|
||||
}
|
||||
}
|
||||
|
||||
static SDL_bool EMSCRIPTENCAMERA_Init(SDL_CameraDriverImpl *impl)
|
||||
{
|
||||
MAIN_THREAD_EM_ASM({
|
||||
if (typeof(Module['SDL3']) === 'undefined') {
|
||||
Module['SDL3'] = {};
|
||||
}
|
||||
Module['SDL3'].camera = {};
|
||||
});
|
||||
|
||||
impl->DetectDevices = EMSCRIPTENCAMERA_DetectDevices;
|
||||
impl->OpenDevice = EMSCRIPTENCAMERA_OpenDevice;
|
||||
impl->CloseDevice = EMSCRIPTENCAMERA_CloseDevice;
|
||||
impl->WaitDevice = EMSCRIPTENCAMERA_WaitDevice;
|
||||
impl->AcquireFrame = EMSCRIPTENCAMERA_AcquireFrame;
|
||||
impl->ReleaseFrame = EMSCRIPTENCAMERA_ReleaseFrame;
|
||||
impl->FreeDeviceHandle = EMSCRIPTENCAMERA_FreeDeviceHandle;
|
||||
impl->Deinitialize = EMSCRIPTENCAMERA_Deinitialize;
|
||||
|
||||
impl->ProvidesOwnCallbackThread = SDL_TRUE;
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
CameraBootStrap EMSCRIPTENCAMERA_bootstrap = {
|
||||
"emscripten", "SDL Emscripten MediaStream camera driver", EMSCRIPTENCAMERA_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
/* *INDENT-ON* */ /* clang-format on */
|
||||
|
||||
#endif // SDL_CAMERA_DRIVER_EMSCRIPTEN
|
||||
|
||||
933
external/sdl/SDL/src/camera/mediafoundation/SDL_camera_mediafoundation.c
vendored
Normal file
933
external/sdl/SDL/src/camera/mediafoundation/SDL_camera_mediafoundation.c
vendored
Normal file
@@ -0,0 +1,933 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
// the Windows Media Foundation API
|
||||
|
||||
#ifdef SDL_CAMERA_DRIVER_MEDIAFOUNDATION
|
||||
|
||||
#define COBJMACROS
|
||||
|
||||
// this seems to be a bug in mfidl.h, just define this to avoid the problem section.
|
||||
#define __IMFVideoProcessorControl3_INTERFACE_DEFINED__
|
||||
|
||||
#include "../../core/windows/SDL_windows.h"
|
||||
|
||||
#include <mfapi.h>
|
||||
#include <mfidl.h>
|
||||
#include <mfreadwrite.h>
|
||||
|
||||
#include "../SDL_syscamera.h"
|
||||
#include "../SDL_camera_c.h"
|
||||
|
||||
static const IID SDL_IID_IMFMediaSource = { 0x279a808d, 0xaec7, 0x40c8, { 0x9c, 0x6b, 0xa6, 0xb4, 0x92, 0xc7, 0x8a, 0x66 } };
|
||||
static const IID SDL_IID_IMF2DBuffer = { 0x7dc9d5f9, 0x9ed9, 0x44ec, { 0x9b, 0xbf, 0x06, 0x00, 0xbb, 0x58, 0x9f, 0xbb } };
|
||||
static const IID SDL_IID_IMF2DBuffer2 = { 0x33ae5ea6, 0x4316, 0x436f, { 0x8d, 0xdd, 0xd7, 0x3d, 0x22, 0xf8, 0x29, 0xec } };
|
||||
static const GUID SDL_MF_MT_DEFAULT_STRIDE = { 0x644b4e48, 0x1e02, 0x4516, { 0xb0, 0xeb, 0xc0, 0x1c, 0xa9, 0xd4, 0x9a, 0xc6 } };
|
||||
static const GUID SDL_MF_MT_MAJOR_TYPE = { 0x48eba18e, 0xf8c9, 0x4687, { 0xbf, 0x11, 0x0a, 0x74, 0xc9, 0xf9, 0x6a, 0x8f } };
|
||||
static const GUID SDL_MF_MT_SUBTYPE = { 0xf7e34c9a, 0x42e8, 0x4714, { 0xb7, 0x4b, 0xcb, 0x29, 0xd7, 0x2c, 0x35, 0xe5 } };
|
||||
static const GUID SDL_MF_MT_FRAME_SIZE = { 0x1652c33d, 0xd6b2, 0x4012, { 0xb8, 0x34, 0x72, 0x03, 0x08, 0x49, 0xa3, 0x7d } };
|
||||
static const GUID SDL_MF_MT_FRAME_RATE = { 0xc459a2e8, 0x3d2c, 0x4e44, { 0xb1, 0x32, 0xfe, 0xe5, 0x15, 0x6c, 0x7b, 0xb0 } };
|
||||
static const GUID SDL_MFMediaType_Video = { 0x73646976, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71 } };
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wmultichar"
|
||||
#endif
|
||||
|
||||
#define SDL_DEFINE_MEDIATYPE_GUID(name, fmt) static const GUID SDL_##name = { fmt, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 } }
|
||||
SDL_DEFINE_MEDIATYPE_GUID(MFVideoFormat_RGB555, 24);
|
||||
SDL_DEFINE_MEDIATYPE_GUID(MFVideoFormat_RGB565, 23);
|
||||
SDL_DEFINE_MEDIATYPE_GUID(MFVideoFormat_RGB24, 20);
|
||||
SDL_DEFINE_MEDIATYPE_GUID(MFVideoFormat_RGB32, 22);
|
||||
SDL_DEFINE_MEDIATYPE_GUID(MFVideoFormat_ARGB32, 21);
|
||||
SDL_DEFINE_MEDIATYPE_GUID(MFVideoFormat_A2R10G10B10, 31);
|
||||
SDL_DEFINE_MEDIATYPE_GUID(MFVideoFormat_YV12, FCC('YV12'));
|
||||
SDL_DEFINE_MEDIATYPE_GUID(MFVideoFormat_IYUV, FCC('IYUV'));
|
||||
SDL_DEFINE_MEDIATYPE_GUID(MFVideoFormat_YUY2, FCC('YUY2'));
|
||||
SDL_DEFINE_MEDIATYPE_GUID(MFVideoFormat_UYVY, FCC('UYVY'));
|
||||
SDL_DEFINE_MEDIATYPE_GUID(MFVideoFormat_YVYU, FCC('YVYU'));
|
||||
SDL_DEFINE_MEDIATYPE_GUID(MFVideoFormat_NV12, FCC('NV12'));
|
||||
SDL_DEFINE_MEDIATYPE_GUID(MFVideoFormat_NV21, FCC('NV21'));
|
||||
#undef SDL_DEFINE_MEDIATYPE_GUID
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
static const struct
|
||||
{
|
||||
const GUID *guid;
|
||||
const SDL_PixelFormatEnum sdlfmt;
|
||||
} fmtmappings[] = {
|
||||
// This is not every possible format, just popular ones that SDL can reasonably handle.
|
||||
// (and we should probably trim this list more.)
|
||||
{ &SDL_MFVideoFormat_RGB555, SDL_PIXELFORMAT_XRGB1555 },
|
||||
{ &SDL_MFVideoFormat_RGB565, SDL_PIXELFORMAT_RGB565 },
|
||||
{ &SDL_MFVideoFormat_RGB24, SDL_PIXELFORMAT_RGB24 },
|
||||
{ &SDL_MFVideoFormat_RGB32, SDL_PIXELFORMAT_XRGB8888 },
|
||||
{ &SDL_MFVideoFormat_ARGB32, SDL_PIXELFORMAT_ARGB8888 },
|
||||
{ &SDL_MFVideoFormat_A2R10G10B10, SDL_PIXELFORMAT_ARGB2101010 },
|
||||
{ &SDL_MFVideoFormat_YV12, SDL_PIXELFORMAT_YV12 },
|
||||
{ &SDL_MFVideoFormat_IYUV, SDL_PIXELFORMAT_IYUV },
|
||||
{ &SDL_MFVideoFormat_YUY2, SDL_PIXELFORMAT_YUY2 },
|
||||
{ &SDL_MFVideoFormat_UYVY, SDL_PIXELFORMAT_UYVY },
|
||||
{ &SDL_MFVideoFormat_YVYU, SDL_PIXELFORMAT_YVYU },
|
||||
{ &SDL_MFVideoFormat_NV12, SDL_PIXELFORMAT_NV12 },
|
||||
{ &SDL_MFVideoFormat_NV21, SDL_PIXELFORMAT_NV21 }
|
||||
};
|
||||
|
||||
static SDL_PixelFormatEnum MFVidFmtGuidToSDLFmt(const GUID *guid)
|
||||
{
|
||||
for (size_t i = 0; i < SDL_arraysize(fmtmappings); i++) {
|
||||
if (WIN_IsEqualGUID(guid, fmtmappings[i].guid)) {
|
||||
return fmtmappings[i].sdlfmt;
|
||||
}
|
||||
}
|
||||
return SDL_PIXELFORMAT_UNKNOWN;
|
||||
}
|
||||
|
||||
static const GUID *SDLFmtToMFVidFmtGuid(SDL_PixelFormatEnum sdlfmt)
|
||||
{
|
||||
for (size_t i = 0; i < SDL_arraysize(fmtmappings); i++) {
|
||||
if (fmtmappings[i].sdlfmt == sdlfmt) {
|
||||
return fmtmappings[i].guid;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// handle to Media Foundation libs--Vista and later!--for access to the Media Foundation API.
|
||||
|
||||
// mf.dll ...
|
||||
static HMODULE libmf = NULL;
|
||||
typedef HRESULT(WINAPI *pfnMFEnumDeviceSources)(IMFAttributes *,IMFActivate ***,UINT32 *);
|
||||
typedef HRESULT(WINAPI *pfnMFCreateDeviceSource)(IMFAttributes *, IMFMediaSource **);
|
||||
static pfnMFEnumDeviceSources pMFEnumDeviceSources = NULL;
|
||||
static pfnMFCreateDeviceSource pMFCreateDeviceSource = NULL;
|
||||
|
||||
// mfplat.dll ...
|
||||
static HMODULE libmfplat = NULL;
|
||||
typedef HRESULT(WINAPI *pfnMFStartup)(ULONG, DWORD);
|
||||
typedef HRESULT(WINAPI *pfnMFShutdown)(void);
|
||||
typedef HRESULT(WINAPI *pfnMFCreateAttributes)(IMFAttributes **, UINT32);
|
||||
typedef HRESULT(WINAPI *pfnMFCreateMediaType)(IMFMediaType **);
|
||||
typedef HRESULT(WINAPI *pfnMFGetStrideForBitmapInfoHeader)(DWORD, DWORD, LONG *);
|
||||
|
||||
static pfnMFStartup pMFStartup = NULL;
|
||||
static pfnMFShutdown pMFShutdown = NULL;
|
||||
static pfnMFCreateAttributes pMFCreateAttributes = NULL;
|
||||
static pfnMFCreateMediaType pMFCreateMediaType = NULL;
|
||||
static pfnMFGetStrideForBitmapInfoHeader pMFGetStrideForBitmapInfoHeader = NULL;
|
||||
|
||||
// mfreadwrite.dll ...
|
||||
static HMODULE libmfreadwrite = NULL;
|
||||
typedef HRESULT(WINAPI *pfnMFCreateSourceReaderFromMediaSource)(IMFMediaSource *, IMFAttributes *, IMFSourceReader **);
|
||||
static pfnMFCreateSourceReaderFromMediaSource pMFCreateSourceReaderFromMediaSource = NULL;
|
||||
|
||||
|
||||
typedef struct SDL_PrivateCameraData
|
||||
{
|
||||
IMFSourceReader *srcreader;
|
||||
IMFSample *current_sample;
|
||||
int pitch;
|
||||
} SDL_PrivateCameraData;
|
||||
|
||||
static int MEDIAFOUNDATION_WaitDevice(SDL_CameraDevice *device)
|
||||
{
|
||||
SDL_assert(device->hidden->current_sample == NULL);
|
||||
|
||||
IMFSourceReader *srcreader = device->hidden->srcreader;
|
||||
IMFSample *sample = NULL;
|
||||
|
||||
while (!SDL_AtomicGet(&device->shutdown)) {
|
||||
DWORD stream_flags = 0;
|
||||
const HRESULT ret = IMFSourceReader_ReadSample(srcreader, (DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, NULL, &stream_flags, NULL, &sample);
|
||||
if (FAILED(ret)) {
|
||||
return -1; // ruh roh.
|
||||
}
|
||||
|
||||
// we currently ignore stream_flags format changes, but my _hope_ is that IMFSourceReader is handling this and
|
||||
// will continue to give us the explictly-specified format we requested when opening the device, though, and
|
||||
// we don't have to manually deal with it.
|
||||
|
||||
if (sample != NULL) {
|
||||
break;
|
||||
} else if (stream_flags & (MF_SOURCE_READERF_ERROR | MF_SOURCE_READERF_ENDOFSTREAM)) {
|
||||
return -1; // apparently this camera has gone down. :/
|
||||
}
|
||||
|
||||
// otherwise, there was some minor burp, probably; just try again.
|
||||
}
|
||||
|
||||
device->hidden->current_sample = sample;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef KEEP_ACQUIRED_BUFFERS_LOCKED
|
||||
|
||||
#define PROP_SURFACE_IMFOBJS_POINTER "SDL.camera.mediafoundation.imfobjs"
|
||||
|
||||
typedef struct SDL_IMFObjects
|
||||
{
|
||||
IMF2DBuffer2 *buffer2d2;
|
||||
IMF2DBuffer *buffer2d;
|
||||
IMFMediaBuffer *buffer;
|
||||
IMFSample *sample;
|
||||
} SDL_IMFObjects;
|
||||
|
||||
static void SDLCALL CleanupIMF2DBuffer2(void *userdata, void *value)
|
||||
{
|
||||
SDL_IMFObjects *objs = (SDL_IMFObjects *)value;
|
||||
IMF2DBuffer2_Unlock2D(objs->buffer2d2);
|
||||
IMF2DBuffer2_Release(objs->buffer2d2);
|
||||
IMFMediaBuffer_Release(objs->buffer);
|
||||
IMFSample_Release(objs->sample);
|
||||
SDL_free(objs);
|
||||
}
|
||||
|
||||
static void SDLCALL CleanupIMF2DBuffer(void *userdata, void *value)
|
||||
{
|
||||
SDL_IMFObjects *objs = (SDL_IMFObjects *)value;
|
||||
IMF2DBuffer_Unlock2D(objs->buffer2d);
|
||||
IMF2DBuffer_Release(objs->buffer2d);
|
||||
IMFMediaBuffer_Release(objs->buffer);
|
||||
IMFSample_Release(objs->sample);
|
||||
SDL_free(objs);
|
||||
}
|
||||
|
||||
static void SDLCALL CleanupIMFMediaBuffer(void *userdata, void *value)
|
||||
{
|
||||
SDL_IMFObjects *objs = (SDL_IMFObjects *)value;
|
||||
IMFMediaBuffer_Unlock(objs->buffer);
|
||||
IMFMediaBuffer_Release(objs->buffer);
|
||||
IMFSample_Release(objs->sample);
|
||||
SDL_free(objs);
|
||||
}
|
||||
|
||||
static int MEDIAFOUNDATION_AcquireFrame(SDL_CameraDevice *device, SDL_Surface *frame, Uint64 *timestampNS)
|
||||
{
|
||||
SDL_assert(device->hidden->current_sample != NULL);
|
||||
|
||||
int retval = 1;
|
||||
HRESULT ret;
|
||||
LONGLONG timestamp100NS = 0;
|
||||
SDL_IMFObjects *objs = (SDL_IMFObjects *) SDL_calloc(1, sizeof (SDL_IMFObjects));
|
||||
|
||||
if (objs == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
objs->sample = device->hidden->current_sample;
|
||||
device->hidden->current_sample = NULL;
|
||||
|
||||
const SDL_PropertiesID surfprops = SDL_GetSurfaceProperties(frame);
|
||||
if (!surfprops) {
|
||||
retval = -1;
|
||||
} else {
|
||||
ret = IMFSample_GetSampleTime(objs->sample, ×tamp100NS);
|
||||
if (FAILED(ret)) {
|
||||
retval = -1;
|
||||
}
|
||||
|
||||
*timestampNS = timestamp100NS * 100; // the timestamps are in 100-nanosecond increments; move to full nanoseconds.
|
||||
}
|
||||
|
||||
ret = (retval < 0) ? E_FAIL : IMFSample_ConvertToContiguousBuffer(objs->sample, &objs->buffer); /*IMFSample_GetBufferByIndex(objs->sample, 0, &objs->buffer);*/
|
||||
|
||||
if (FAILED(ret)) {
|
||||
SDL_free(objs);
|
||||
retval = -1;
|
||||
} else {
|
||||
BYTE *pixels = NULL;
|
||||
LONG pitch = 0;
|
||||
|
||||
if (SUCCEEDED(IMFMediaBuffer_QueryInterface(objs->buffer, &SDL_IID_IMF2DBuffer2, (void **)&objs->buffer2d2))) {
|
||||
BYTE *bufstart = NULL;
|
||||
DWORD buflen = 0;
|
||||
ret = IMF2DBuffer2_Lock2DSize(objs->buffer2d2, MF2DBuffer_LockFlags_Read, &pixels, &pitch, &bufstart, &buflen);
|
||||
if (FAILED(ret)) {
|
||||
retval = -1;
|
||||
CleanupIMF2DBuffer2(NULL, objs);
|
||||
} else {
|
||||
frame->pixels = pixels;
|
||||
frame->pitch = (int) pitch;
|
||||
if (SDL_SetPropertyWithCleanup(surfprops, PROP_SURFACE_IMFOBJS_POINTER, objs, CleanupIMF2DBuffer2, NULL) == -1) {
|
||||
CleanupIMF2DBuffer2(NULL, objs);
|
||||
retval = -1;
|
||||
}
|
||||
}
|
||||
} else if (SUCCEEDED(IMFMediaBuffer_QueryInterface(objs->buffer, &SDL_IID_IMF2DBuffer, (void **)&objs->buffer2d))) {
|
||||
ret = IMF2DBuffer_Lock2D(objs->buffer2d, &pixels, &pitch);
|
||||
if (FAILED(ret)) {
|
||||
CleanupIMF2DBuffer(NULL, objs);
|
||||
retval = -1;
|
||||
} else {
|
||||
frame->pixels = pixels;
|
||||
frame->pitch = (int) pitch;
|
||||
if (SDL_SetPropertyWithCleanup(surfprops, PROP_SURFACE_IMFOBJS_POINTER, objs, CleanupIMF2DBuffer, NULL) == -1) {
|
||||
CleanupIMF2DBuffer(NULL, objs);
|
||||
retval = -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
DWORD maxlen = 0, currentlen = 0;
|
||||
ret = IMFMediaBuffer_Lock(objs->buffer, &pixels, &maxlen, ¤tlen);
|
||||
if (FAILED(ret)) {
|
||||
CleanupIMFMediaBuffer(NULL, objs);
|
||||
retval = -1;
|
||||
} else {
|
||||
pitch = (LONG) device->hidden->pitch;
|
||||
if (pitch < 0) { // image rows are reversed.
|
||||
pixels += -pitch * (frame->h - 1);
|
||||
}
|
||||
frame->pixels = pixels;
|
||||
frame->pitch = (int) pitch;
|
||||
if (SDL_SetPropertyWithCleanup(surfprops, PROP_SURFACE_IMFOBJS_POINTER, objs, CleanupIMFMediaBuffer, NULL) == -1) {
|
||||
CleanupIMFMediaBuffer(NULL, objs);
|
||||
retval = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (retval < 0) {
|
||||
*timestampNS = 0;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void MEDIAFOUNDATION_ReleaseFrame(SDL_CameraDevice *device, SDL_Surface *frame)
|
||||
{
|
||||
const SDL_PropertiesID surfprops = SDL_GetSurfaceProperties(frame);
|
||||
if (surfprops) {
|
||||
// this will release the IMFBuffer and IMFSample objects for this frame.
|
||||
SDL_ClearProperty(surfprops, PROP_SURFACE_IMFOBJS_POINTER);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static int MEDIAFOUNDATION_AcquireFrame(SDL_CameraDevice *device, SDL_Surface *frame, Uint64 *timestampNS)
|
||||
{
|
||||
SDL_assert(device->hidden->current_sample != NULL);
|
||||
|
||||
int retval = 1;
|
||||
HRESULT ret;
|
||||
LONGLONG timestamp100NS = 0;
|
||||
|
||||
IMFSample *sample = device->hidden->current_sample;
|
||||
device->hidden->current_sample = NULL;
|
||||
|
||||
const SDL_PropertiesID surfprops = SDL_GetSurfaceProperties(frame);
|
||||
if (!surfprops) {
|
||||
retval = -1;
|
||||
} else {
|
||||
ret = IMFSample_GetSampleTime(sample, ×tamp100NS);
|
||||
if (FAILED(ret)) {
|
||||
retval = -1;
|
||||
}
|
||||
|
||||
*timestampNS = timestamp100NS * 100; // the timestamps are in 100-nanosecond increments; move to full nanoseconds.
|
||||
}
|
||||
|
||||
IMFMediaBuffer *buffer = NULL;
|
||||
ret = (retval < 0) ? E_FAIL : IMFSample_ConvertToContiguousBuffer(sample, &buffer); /*IMFSample_GetBufferByIndex(sample, 0, &buffer);*/
|
||||
|
||||
if (FAILED(ret)) {
|
||||
retval = -1;
|
||||
} else {
|
||||
IMF2DBuffer *buffer2d = NULL;
|
||||
IMF2DBuffer2 *buffer2d2 = NULL;
|
||||
BYTE *pixels = NULL;
|
||||
LONG pitch = 0;
|
||||
|
||||
if (SUCCEEDED(IMFMediaBuffer_QueryInterface(buffer, &SDL_IID_IMF2DBuffer2, (void **)&buffer2d2))) {
|
||||
BYTE *bufstart = NULL;
|
||||
DWORD buflen = 0;
|
||||
ret = IMF2DBuffer2_Lock2DSize(buffer2d2, MF2DBuffer_LockFlags_Read, &pixels, &pitch, &bufstart, &buflen);
|
||||
if (FAILED(ret)) {
|
||||
retval = -1;
|
||||
} else {
|
||||
frame->pixels = SDL_aligned_alloc(SDL_SIMDGetAlignment(), buflen);
|
||||
if (frame->pixels == NULL) {
|
||||
retval = -1;
|
||||
} else {
|
||||
SDL_memcpy(frame->pixels, pixels, buflen);
|
||||
frame->pitch = (int)pitch;
|
||||
}
|
||||
IMF2DBuffer2_Unlock2D(buffer2d2);
|
||||
}
|
||||
IMF2DBuffer2_Release(buffer2d2);
|
||||
} else if (SUCCEEDED(IMFMediaBuffer_QueryInterface(buffer, &SDL_IID_IMF2DBuffer, (void **)&buffer2d))) {
|
||||
ret = IMF2DBuffer_Lock2D(buffer2d, &pixels, &pitch);
|
||||
if (FAILED(ret)) {
|
||||
retval = -1;
|
||||
} else {
|
||||
BYTE *bufstart = pixels;
|
||||
const DWORD buflen = (SDL_abs((int)pitch) * frame->w) * frame->h;
|
||||
if (pitch < 0) { // image rows are reversed.
|
||||
bufstart += -pitch * (frame->h - 1);
|
||||
}
|
||||
frame->pixels = SDL_aligned_alloc(SDL_SIMDGetAlignment(), buflen);
|
||||
if (frame->pixels == NULL) {
|
||||
retval = -1;
|
||||
} else {
|
||||
SDL_memcpy(frame->pixels, bufstart, buflen);
|
||||
frame->pitch = (int)pitch;
|
||||
}
|
||||
IMF2DBuffer_Unlock2D(buffer2d);
|
||||
}
|
||||
IMF2DBuffer_Release(buffer2d);
|
||||
} else {
|
||||
DWORD maxlen = 0, currentlen = 0;
|
||||
ret = IMFMediaBuffer_Lock(buffer, &pixels, &maxlen, ¤tlen);
|
||||
if (FAILED(ret)) {
|
||||
retval = -1;
|
||||
} else {
|
||||
BYTE *bufstart = pixels;
|
||||
pitch = (LONG)device->hidden->pitch;
|
||||
const DWORD buflen = (SDL_abs((int)pitch) * frame->w) * frame->h;
|
||||
if (pitch < 0) { // image rows are reversed.
|
||||
bufstart += -pitch * (frame->h - 1);
|
||||
}
|
||||
frame->pixels = SDL_aligned_alloc(SDL_SIMDGetAlignment(), buflen);
|
||||
if (frame->pixels == NULL) {
|
||||
retval = -1;
|
||||
} else {
|
||||
SDL_memcpy(frame->pixels, bufstart, buflen);
|
||||
frame->pitch = (int)pitch;
|
||||
}
|
||||
IMFMediaBuffer_Unlock(buffer);
|
||||
}
|
||||
}
|
||||
IMFMediaBuffer_Release(buffer);
|
||||
}
|
||||
|
||||
IMFSample_Release(sample);
|
||||
|
||||
if (retval < 0) {
|
||||
*timestampNS = 0;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void MEDIAFOUNDATION_ReleaseFrame(SDL_CameraDevice *device, SDL_Surface *frame)
|
||||
{
|
||||
SDL_aligned_free(frame->pixels);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void MEDIAFOUNDATION_CloseDevice(SDL_CameraDevice *device)
|
||||
{
|
||||
if (device && device->hidden) {
|
||||
if (device->hidden->srcreader) {
|
||||
IMFSourceReader_Release(device->hidden->srcreader);
|
||||
}
|
||||
if (device->hidden->current_sample) {
|
||||
IMFSample_Release(device->hidden->current_sample);
|
||||
}
|
||||
SDL_free(device->hidden);
|
||||
device->hidden = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// this function is from https://learn.microsoft.com/en-us/windows/win32/medfound/uncompressed-video-buffers
|
||||
static HRESULT GetDefaultStride(IMFMediaType *pType, LONG *plStride)
|
||||
{
|
||||
LONG lStride = 0;
|
||||
|
||||
// Try to get the default stride from the media type.
|
||||
HRESULT ret = IMFMediaType_GetUINT32(pType, &SDL_MF_MT_DEFAULT_STRIDE, (UINT32*)&lStride);
|
||||
if (FAILED(ret)) {
|
||||
// Attribute not set. Try to calculate the default stride.
|
||||
|
||||
GUID subtype = GUID_NULL;
|
||||
UINT32 width = 0;
|
||||
/* UINT32 height = 0; */
|
||||
UINT64 val = 0;
|
||||
|
||||
// Get the subtype and the image size.
|
||||
ret = IMFMediaType_GetGUID(pType, &SDL_MF_MT_SUBTYPE, &subtype);
|
||||
if (FAILED(ret)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = IMFMediaType_GetUINT64(pType, &SDL_MF_MT_FRAME_SIZE, &val);
|
||||
if (FAILED(ret)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
width = (UINT32) (val >> 32);
|
||||
/* height = (UINT32) val; */
|
||||
|
||||
ret = pMFGetStrideForBitmapInfoHeader(subtype.Data1, width, &lStride);
|
||||
if (FAILED(ret)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
// Set the attribute for later reference.
|
||||
IMFMediaType_SetUINT32(pType, &SDL_MF_MT_DEFAULT_STRIDE, (UINT32) lStride);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(ret)) {
|
||||
*plStride = lStride;
|
||||
}
|
||||
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int MEDIAFOUNDATION_OpenDevice(SDL_CameraDevice *device, const SDL_CameraSpec *spec)
|
||||
{
|
||||
const char *utf8symlink = (const char *) device->handle;
|
||||
IMFAttributes *attrs = NULL;
|
||||
LPWSTR wstrsymlink = NULL;
|
||||
IMFMediaSource *source = NULL;
|
||||
IMFMediaType *mediatype = NULL;
|
||||
IMFSourceReader *srcreader = NULL;
|
||||
#if 0
|
||||
DWORD num_streams = 0;
|
||||
#endif
|
||||
LONG lstride = 0;
|
||||
//PROPVARIANT var;
|
||||
HRESULT ret;
|
||||
|
||||
#if 0
|
||||
IMFStreamDescriptor *streamdesc = NULL;
|
||||
IMFPresentationDescriptor *presentdesc = NULL;
|
||||
IMFMediaTypeHandler *handler = NULL;
|
||||
#endif
|
||||
|
||||
#if DEBUG_CAMERA
|
||||
SDL_Log("CAMERA: opening device with symlink of '%s'", utf8symlink);
|
||||
#endif
|
||||
|
||||
wstrsymlink = WIN_UTF8ToString(utf8symlink);
|
||||
if (!wstrsymlink) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
#define CHECK_HRESULT(what, r) if (FAILED(r)) { WIN_SetErrorFromHRESULT(what " failed", r); goto failed; }
|
||||
|
||||
ret = pMFCreateAttributes(&attrs, 1);
|
||||
CHECK_HRESULT("MFCreateAttributes", ret);
|
||||
|
||||
ret = IMFAttributes_SetGUID(attrs, &MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, &MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID);
|
||||
CHECK_HRESULT("IMFAttributes_SetGUID(srctype)", ret);
|
||||
|
||||
ret = IMFAttributes_SetString(attrs, &MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, wstrsymlink);
|
||||
CHECK_HRESULT("IMFAttributes_SetString(symlink)", ret);
|
||||
|
||||
ret = pMFCreateDeviceSource(attrs, &source);
|
||||
CHECK_HRESULT("MFCreateDeviceSource", ret);
|
||||
|
||||
IMFAttributes_Release(attrs);
|
||||
SDL_free(wstrsymlink);
|
||||
attrs = NULL;
|
||||
wstrsymlink = NULL;
|
||||
|
||||
// !!! FIXME: I think it'd be nice to do this without an IMFSourceReader,
|
||||
// since it's just utility code that has to handle more complex media streams
|
||||
// than we're dealing with, but this will do for now. The docs are slightly
|
||||
// insistent that you should use one, though...Maybe it's extremely hard
|
||||
// to handle directly at the IMFMediaSource layer...?
|
||||
ret = pMFCreateSourceReaderFromMediaSource(source, NULL, &srcreader);
|
||||
CHECK_HRESULT("MFCreateSourceReaderFromMediaSource", ret);
|
||||
|
||||
// !!! FIXME: do we actually have to find the media type object in the source reader or can we just roll our own like this?
|
||||
ret = pMFCreateMediaType(&mediatype);
|
||||
CHECK_HRESULT("MFCreateMediaType", ret);
|
||||
|
||||
ret = IMFMediaType_SetGUID(mediatype, &SDL_MF_MT_MAJOR_TYPE, &SDL_MFMediaType_Video);
|
||||
CHECK_HRESULT("IMFMediaType_SetGUID(major_type)", ret);
|
||||
|
||||
ret = IMFMediaType_SetGUID(mediatype, &SDL_MF_MT_SUBTYPE, SDLFmtToMFVidFmtGuid(spec->format));
|
||||
CHECK_HRESULT("IMFMediaType_SetGUID(subtype)", ret);
|
||||
|
||||
ret = IMFMediaType_SetUINT64(mediatype, &SDL_MF_MT_FRAME_SIZE, (((UINT64)spec->width) << 32) | ((UINT64)spec->height));
|
||||
CHECK_HRESULT("MFSetAttributeSize(frame_size)", ret);
|
||||
|
||||
ret = IMFMediaType_SetUINT64(mediatype, &SDL_MF_MT_FRAME_RATE, (((UINT64)spec->interval_numerator) << 32) | ((UINT64)spec->interval_denominator));
|
||||
CHECK_HRESULT("MFSetAttributeRatio(frame_rate)", ret);
|
||||
|
||||
ret = IMFSourceReader_SetCurrentMediaType(srcreader, (DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, NULL, mediatype);
|
||||
CHECK_HRESULT("IMFSourceReader_SetCurrentMediaType", ret);
|
||||
|
||||
#if 0 // this (untested thing) is what we would do to get started with a IMFMediaSource that _doesn't_ use IMFSourceReader...
|
||||
ret = IMFMediaSource_CreatePresentationDescriptor(source, &presentdesc);
|
||||
CHECK_HRESULT("IMFMediaSource_CreatePresentationDescriptor", ret);
|
||||
|
||||
ret = IMFPresentationDescriptor_GetStreamDescriptorCount(presentdesc, &num_streams);
|
||||
CHECK_HRESULT("IMFPresentationDescriptor_GetStreamDescriptorCount", ret);
|
||||
|
||||
for (DWORD i = 0; i < num_streams; i++) {
|
||||
BOOL selected = FALSE;
|
||||
ret = IMFPresentationDescriptor_GetStreamDescriptorByIndex(presentdesc, i, &selected, &streamdesc);
|
||||
CHECK_HRESULT("IMFPresentationDescriptor_GetStreamDescriptorByIndex", ret);
|
||||
|
||||
if (selected) {
|
||||
ret = IMFStreamDescriptor_GetMediaTypeHandler(streamdesc, &handler);
|
||||
CHECK_HRESULT("IMFStreamDescriptor_GetMediaTypeHandler", ret);
|
||||
IMFMediaTypeHandler_SetCurrentMediaType(handler, mediatype);
|
||||
IMFMediaTypeHandler_Release(handler);
|
||||
handler = NULL;
|
||||
}
|
||||
|
||||
IMFStreamDescriptor_Release(streamdesc);
|
||||
streamdesc = NULL;
|
||||
}
|
||||
|
||||
PropVariantInit(&var);
|
||||
var.vt = VT_EMPTY;
|
||||
ret = IMFMediaSource_Start(source, presentdesc, NULL, &var);
|
||||
PropVariantClear(&var);
|
||||
CHECK_HRESULT("IMFMediaSource_Start", ret);
|
||||
|
||||
IMFPresentationDescriptor_Release(presentdesc);
|
||||
presentdesc = NULL;
|
||||
#endif
|
||||
|
||||
ret = GetDefaultStride(mediatype, &lstride);
|
||||
CHECK_HRESULT("GetDefaultStride", ret);
|
||||
|
||||
IMFMediaType_Release(mediatype);
|
||||
mediatype = NULL;
|
||||
|
||||
device->hidden = (SDL_PrivateCameraData *) SDL_calloc(1, sizeof (SDL_PrivateCameraData));
|
||||
if (!device->hidden) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
device->hidden->pitch = (int) lstride;
|
||||
device->hidden->srcreader = srcreader;
|
||||
IMFMediaSource_Release(source); // srcreader is holding a reference to this.
|
||||
|
||||
// There is no user permission prompt for camera access (I think?)
|
||||
SDL_CameraDevicePermissionOutcome(device, SDL_TRUE);
|
||||
|
||||
#undef CHECK_HRESULT
|
||||
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
|
||||
if (srcreader) {
|
||||
IMFSourceReader_Release(srcreader);
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (handler) {
|
||||
IMFMediaTypeHandler_Release(handler);
|
||||
}
|
||||
|
||||
if (streamdesc) {
|
||||
IMFStreamDescriptor_Release(streamdesc);
|
||||
}
|
||||
|
||||
if (presentdesc) {
|
||||
IMFPresentationDescriptor_Release(presentdesc);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (source) {
|
||||
IMFMediaSource_Shutdown(source);
|
||||
IMFMediaSource_Release(source);
|
||||
}
|
||||
|
||||
if (mediatype) {
|
||||
IMFMediaType_Release(mediatype);
|
||||
}
|
||||
|
||||
if (attrs) {
|
||||
IMFAttributes_Release(attrs);
|
||||
}
|
||||
SDL_free(wstrsymlink);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void MEDIAFOUNDATION_FreeDeviceHandle(SDL_CameraDevice *device)
|
||||
{
|
||||
if (device) {
|
||||
SDL_free(device->handle); // the device's symlink string.
|
||||
}
|
||||
}
|
||||
|
||||
static char *QueryActivationObjectString(IMFActivate *activation, const GUID *pguid)
|
||||
{
|
||||
LPWSTR wstr = NULL;
|
||||
UINT32 wlen = 0;
|
||||
HRESULT ret = IMFActivate_GetAllocatedString(activation, pguid, &wstr, &wlen);
|
||||
if (FAILED(ret)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *utf8str = WIN_StringToUTF8(wstr);
|
||||
CoTaskMemFree(wstr);
|
||||
return utf8str;
|
||||
}
|
||||
|
||||
static void GatherCameraSpecs(IMFMediaSource *source, CameraFormatAddData *add_data)
|
||||
{
|
||||
HRESULT ret;
|
||||
|
||||
// this has like a thousand steps. :/
|
||||
|
||||
SDL_zerop(add_data);
|
||||
|
||||
IMFPresentationDescriptor *presentdesc = NULL;
|
||||
ret = IMFMediaSource_CreatePresentationDescriptor(source, &presentdesc);
|
||||
if (FAILED(ret) || !presentdesc) {
|
||||
return;
|
||||
}
|
||||
|
||||
DWORD num_streams = 0;
|
||||
ret = IMFPresentationDescriptor_GetStreamDescriptorCount(presentdesc, &num_streams);
|
||||
if (FAILED(ret)) {
|
||||
num_streams = 0;
|
||||
}
|
||||
|
||||
for (DWORD i = 0; i < num_streams; i++) {
|
||||
IMFStreamDescriptor *streamdesc = NULL;
|
||||
BOOL selected = FALSE;
|
||||
ret = IMFPresentationDescriptor_GetStreamDescriptorByIndex(presentdesc, i, &selected, &streamdesc);
|
||||
if (FAILED(ret) || !streamdesc) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (selected) {
|
||||
IMFMediaTypeHandler *handler = NULL;
|
||||
ret = IMFStreamDescriptor_GetMediaTypeHandler(streamdesc, &handler);
|
||||
if (SUCCEEDED(ret) && handler) {
|
||||
DWORD num_mediatype = 0;
|
||||
ret = IMFMediaTypeHandler_GetMediaTypeCount(handler, &num_mediatype);
|
||||
if (FAILED(ret)) {
|
||||
num_mediatype = 0;
|
||||
}
|
||||
|
||||
for (DWORD j = 0; j < num_mediatype; j++) {
|
||||
IMFMediaType *mediatype = NULL;
|
||||
ret = IMFMediaTypeHandler_GetMediaTypeByIndex(handler, j, &mediatype);
|
||||
if (SUCCEEDED(ret) && mediatype) {
|
||||
GUID type;
|
||||
ret = IMFMediaType_GetGUID(mediatype, &SDL_MF_MT_MAJOR_TYPE, &type);
|
||||
if (SUCCEEDED(ret) && WIN_IsEqualGUID(&type, &SDL_MFMediaType_Video)) {
|
||||
ret = IMFMediaType_GetGUID(mediatype, &SDL_MF_MT_SUBTYPE, &type);
|
||||
if (SUCCEEDED(ret)) {
|
||||
const SDL_PixelFormatEnum sdlfmt = MFVidFmtGuidToSDLFmt(&type);
|
||||
if (sdlfmt != SDL_PIXELFORMAT_UNKNOWN) {
|
||||
UINT64 val = 0;
|
||||
UINT32 w = 0, h = 0;
|
||||
ret = IMFMediaType_GetUINT64(mediatype, &SDL_MF_MT_FRAME_SIZE, &val);
|
||||
w = (UINT32)(val >> 32);
|
||||
h = (UINT32)val;
|
||||
if (SUCCEEDED(ret) && w && h) {
|
||||
UINT32 interval_numerator = 0, interval_denominator = 0;
|
||||
ret = IMFMediaType_GetUINT64(mediatype, &SDL_MF_MT_FRAME_RATE, &val);
|
||||
interval_numerator = (UINT32)(val >> 32);
|
||||
interval_denominator = (UINT32)val;
|
||||
if (SUCCEEDED(ret) && interval_numerator && interval_denominator) {
|
||||
SDL_AddCameraFormat(add_data, sdlfmt, (int) w, (int) h, (int) interval_numerator, (int) interval_denominator); // whew.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
IMFMediaType_Release(mediatype);
|
||||
}
|
||||
}
|
||||
IMFMediaTypeHandler_Release(handler);
|
||||
}
|
||||
}
|
||||
IMFStreamDescriptor_Release(streamdesc);
|
||||
}
|
||||
|
||||
IMFPresentationDescriptor_Release(presentdesc);
|
||||
}
|
||||
|
||||
static SDL_bool FindMediaFoundationCameraDeviceBySymlink(SDL_CameraDevice *device, void *userdata)
|
||||
{
|
||||
return (SDL_strcmp((const char *) device->handle, (const char *) userdata) == 0);
|
||||
}
|
||||
|
||||
static void MaybeAddDevice(IMFActivate *activation)
|
||||
{
|
||||
char *symlink = QueryActivationObjectString(activation, &MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK);
|
||||
|
||||
if (SDL_FindPhysicalCameraDeviceByCallback(FindMediaFoundationCameraDeviceBySymlink, symlink)) {
|
||||
SDL_free(symlink);
|
||||
return; // already have this one.
|
||||
}
|
||||
|
||||
char *name = QueryActivationObjectString(activation, &MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME);
|
||||
if (name && symlink) {
|
||||
IMFMediaSource *source = NULL;
|
||||
// "activating" here only creates an object, it doesn't open the actual camera hardware or start recording.
|
||||
HRESULT ret = IMFActivate_ActivateObject(activation, &SDL_IID_IMFMediaSource, (void**)&source);
|
||||
if (SUCCEEDED(ret) && source) {
|
||||
CameraFormatAddData add_data;
|
||||
GatherCameraSpecs(source, &add_data);
|
||||
if (add_data.num_specs > 0) {
|
||||
SDL_AddCameraDevice(name, SDL_CAMERA_POSITION_UNKNOWN, add_data.num_specs, add_data.specs, symlink);
|
||||
}
|
||||
SDL_free(add_data.specs);
|
||||
IMFActivate_ShutdownObject(activation);
|
||||
IMFMediaSource_Release(source);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_free(name);
|
||||
}
|
||||
|
||||
static void MEDIAFOUNDATION_DetectDevices(void)
|
||||
{
|
||||
// !!! FIXME: use CM_Register_Notification (Win8+) to get device notifications.
|
||||
// !!! FIXME: Earlier versions can use RegisterDeviceNotification, but I'm not bothering: no hotplug for you!
|
||||
HRESULT ret;
|
||||
|
||||
IMFAttributes *attrs = NULL;
|
||||
ret = pMFCreateAttributes(&attrs, 1);
|
||||
if (FAILED(ret)) {
|
||||
return; // oh well, no cameras for you.
|
||||
}
|
||||
|
||||
// !!! FIXME: We need these GUIDs hardcoded in this file.
|
||||
ret = IMFAttributes_SetGUID(attrs, &MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, &MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID);
|
||||
if (FAILED(ret)) {
|
||||
IMFAttributes_Release(attrs);
|
||||
return; // oh well, no cameras for you.
|
||||
}
|
||||
|
||||
IMFActivate **activations = NULL;
|
||||
UINT32 total = 0;
|
||||
ret = pMFEnumDeviceSources(attrs, &activations, &total);
|
||||
IMFAttributes_Release(attrs);
|
||||
if (FAILED(ret)) {
|
||||
return; // oh well, no cameras for you.
|
||||
}
|
||||
|
||||
for (UINT32 i = 0; i < total; i++) {
|
||||
MaybeAddDevice(activations[i]);
|
||||
IMFActivate_Release(activations[i]);
|
||||
}
|
||||
|
||||
CoTaskMemFree(activations);
|
||||
}
|
||||
|
||||
static void MEDIAFOUNDATION_Deinitialize(void)
|
||||
{
|
||||
pMFShutdown();
|
||||
|
||||
FreeLibrary(libmfreadwrite);
|
||||
libmfreadwrite = NULL;
|
||||
FreeLibrary(libmfplat);
|
||||
libmfplat = NULL;
|
||||
FreeLibrary(libmf);
|
||||
libmf = NULL;
|
||||
|
||||
pMFEnumDeviceSources = NULL;
|
||||
pMFCreateDeviceSource = NULL;
|
||||
pMFStartup = NULL;
|
||||
pMFShutdown = NULL;
|
||||
pMFCreateAttributes = NULL;
|
||||
pMFCreateMediaType = NULL;
|
||||
pMFCreateSourceReaderFromMediaSource = NULL;
|
||||
pMFGetStrideForBitmapInfoHeader = NULL;
|
||||
}
|
||||
|
||||
static SDL_bool MEDIAFOUNDATION_Init(SDL_CameraDriverImpl *impl)
|
||||
{
|
||||
// !!! FIXME: slide this off into a subroutine
|
||||
HMODULE mf = LoadLibrary(TEXT("Mf.dll")); // this library is available in Vista and later, but also can be on XP with service packs and Windows
|
||||
if (!mf) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
HMODULE mfplat = LoadLibrary(TEXT("Mfplat.dll")); // this library is available in Vista and later. No WinXP, so have to LoadLibrary to use it for now!
|
||||
if (!mfplat) {
|
||||
FreeLibrary(mf);
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
HMODULE mfreadwrite = LoadLibrary(TEXT("Mfreadwrite.dll")); // this library is available in Vista and later. No WinXP, so have to LoadLibrary to use it for now!
|
||||
if (!mfreadwrite) {
|
||||
FreeLibrary(mfplat);
|
||||
FreeLibrary(mf);
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
SDL_bool okay = SDL_TRUE;
|
||||
#define LOADSYM(lib, fn) if (okay) { p##fn = (pfn##fn) GetProcAddress(lib, #fn); if (!p##fn) { okay = SDL_FALSE; } }
|
||||
LOADSYM(mf, MFEnumDeviceSources);
|
||||
LOADSYM(mf, MFCreateDeviceSource);
|
||||
LOADSYM(mfplat, MFStartup);
|
||||
LOADSYM(mfplat, MFShutdown);
|
||||
LOADSYM(mfplat, MFCreateAttributes);
|
||||
LOADSYM(mfplat, MFCreateMediaType);
|
||||
LOADSYM(mfplat, MFGetStrideForBitmapInfoHeader);
|
||||
LOADSYM(mfreadwrite, MFCreateSourceReaderFromMediaSource);
|
||||
#undef LOADSYM
|
||||
|
||||
if (!okay) {
|
||||
FreeLibrary(mfreadwrite);
|
||||
FreeLibrary(mfplat);
|
||||
FreeLibrary(mf);
|
||||
}
|
||||
|
||||
libmf = mf;
|
||||
libmfplat = mfplat;
|
||||
libmfreadwrite = mfreadwrite;
|
||||
|
||||
const HRESULT ret = pMFStartup(MF_VERSION, MFSTARTUP_LITE);
|
||||
if (FAILED(ret)) {
|
||||
FreeLibrary(libmfplat);
|
||||
libmfplat = NULL;
|
||||
FreeLibrary(libmf);
|
||||
libmf = NULL;
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
impl->DetectDevices = MEDIAFOUNDATION_DetectDevices;
|
||||
impl->OpenDevice = MEDIAFOUNDATION_OpenDevice;
|
||||
impl->CloseDevice = MEDIAFOUNDATION_CloseDevice;
|
||||
impl->WaitDevice = MEDIAFOUNDATION_WaitDevice;
|
||||
impl->AcquireFrame = MEDIAFOUNDATION_AcquireFrame;
|
||||
impl->ReleaseFrame = MEDIAFOUNDATION_ReleaseFrame;
|
||||
impl->FreeDeviceHandle = MEDIAFOUNDATION_FreeDeviceHandle;
|
||||
impl->Deinitialize = MEDIAFOUNDATION_Deinitialize;
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
CameraBootStrap MEDIAFOUNDATION_bootstrap = {
|
||||
"mediafoundation", "SDL Windows Media Foundation camera driver", MEDIAFOUNDATION_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
#endif // SDL_CAMERA_DRIVER_MEDIAFOUNDATION
|
||||
|
||||
890
external/sdl/SDL/src/camera/v4l2/SDL_camera_v4l2.c
vendored
Normal file
890
external/sdl/SDL/src/camera/v4l2/SDL_camera_v4l2.c
vendored
Normal file
@@ -0,0 +1,890 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifdef SDL_CAMERA_DRIVER_V4L2
|
||||
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h> // low-level i/o
|
||||
#include <errno.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <linux/videodev2.h>
|
||||
|
||||
#ifndef V4L2_CAP_DEVICE_CAPS
|
||||
// device_caps was added to struct v4l2_capability as of kernel 3.4.
|
||||
#define device_caps reserved[0]
|
||||
SDL_COMPILE_TIME_ASSERT(v4l2devicecaps, offsetof(struct v4l2_capability,device_caps) == offsetof(struct v4l2_capability,capabilities) + 4);
|
||||
#endif
|
||||
|
||||
#include "../SDL_syscamera.h"
|
||||
#include "../SDL_camera_c.h"
|
||||
#include "../../video/SDL_pixels_c.h"
|
||||
#include "../../thread/SDL_systhread.h"
|
||||
#include "../../core/linux/SDL_evdev_capabilities.h"
|
||||
#include "../../core/linux/SDL_udev.h"
|
||||
|
||||
#ifndef SDL_USE_LIBUDEV
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
typedef struct V4L2DeviceHandle
|
||||
{
|
||||
char *bus_info;
|
||||
char *path;
|
||||
} V4L2DeviceHandle;
|
||||
|
||||
|
||||
typedef enum io_method {
|
||||
IO_METHOD_INVALID,
|
||||
IO_METHOD_READ,
|
||||
IO_METHOD_MMAP,
|
||||
IO_METHOD_USERPTR
|
||||
} io_method;
|
||||
|
||||
struct buffer {
|
||||
void *start;
|
||||
size_t length;
|
||||
int available; // Is available in userspace
|
||||
};
|
||||
|
||||
struct SDL_PrivateCameraData
|
||||
{
|
||||
int fd;
|
||||
io_method io;
|
||||
int nb_buffers;
|
||||
struct buffer *buffers;
|
||||
int driver_pitch;
|
||||
};
|
||||
|
||||
static int xioctl(int fh, int request, void *arg)
|
||||
{
|
||||
int r;
|
||||
|
||||
do {
|
||||
r = ioctl(fh, request, arg);
|
||||
} while ((r == -1) && (errno == EINTR));
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int V4L2_WaitDevice(SDL_CameraDevice *device)
|
||||
{
|
||||
const int fd = device->hidden->fd;
|
||||
|
||||
int retval;
|
||||
|
||||
do {
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(fd, &fds);
|
||||
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 100 * 1000;
|
||||
|
||||
retval = select(fd + 1, &fds, NULL, NULL, &tv);
|
||||
if ((retval == -1) && (errno == EINTR)) {
|
||||
retval = 0; // pretend it was a timeout, keep looping.
|
||||
}
|
||||
} while (retval == 0);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int V4L2_AcquireFrame(SDL_CameraDevice *device, SDL_Surface *frame, Uint64 *timestampNS)
|
||||
{
|
||||
const int fd = device->hidden->fd;
|
||||
const io_method io = device->hidden->io;
|
||||
size_t size = device->hidden->buffers[0].length;
|
||||
struct v4l2_buffer buf;
|
||||
|
||||
switch (io) {
|
||||
case IO_METHOD_READ:
|
||||
if (read(fd, device->hidden->buffers[0].start, size) == -1) {
|
||||
switch (errno) {
|
||||
case EAGAIN:
|
||||
return 0;
|
||||
|
||||
case EIO:
|
||||
// Could ignore EIO, see spec.
|
||||
// fall through
|
||||
|
||||
default:
|
||||
return SDL_SetError("read");
|
||||
}
|
||||
}
|
||||
|
||||
*timestampNS = SDL_GetTicksNS(); // oh well, close enough.
|
||||
frame->pixels = device->hidden->buffers[0].start;
|
||||
frame->pitch = device->hidden->driver_pitch;
|
||||
break;
|
||||
|
||||
case IO_METHOD_MMAP:
|
||||
SDL_zero(buf);
|
||||
|
||||
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
buf.memory = V4L2_MEMORY_MMAP;
|
||||
|
||||
if (xioctl(fd, VIDIOC_DQBUF, &buf) == -1) {
|
||||
switch (errno) {
|
||||
case EAGAIN:
|
||||
return 0;
|
||||
|
||||
case EIO:
|
||||
// Could ignore EIO, see spec.
|
||||
// fall through
|
||||
|
||||
default:
|
||||
return SDL_SetError("VIDIOC_DQBUF: %d", errno);
|
||||
}
|
||||
}
|
||||
|
||||
if ((int)buf.index < 0 || (int)buf.index >= device->hidden->nb_buffers) {
|
||||
return SDL_SetError("invalid buffer index");
|
||||
}
|
||||
|
||||
frame->pixels = device->hidden->buffers[buf.index].start;
|
||||
frame->pitch = device->hidden->driver_pitch;
|
||||
device->hidden->buffers[buf.index].available = 1;
|
||||
|
||||
*timestampNS = (((Uint64) buf.timestamp.tv_sec) * SDL_NS_PER_SECOND) + SDL_US_TO_NS(buf.timestamp.tv_usec);
|
||||
|
||||
#if DEBUG_CAMERA
|
||||
SDL_Log("CAMERA: debug mmap: image %d/%d data[0]=%p", buf.index, device->hidden->nb_buffers, (void*)frame->pixels);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case IO_METHOD_USERPTR:
|
||||
SDL_zero(buf);
|
||||
|
||||
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
buf.memory = V4L2_MEMORY_USERPTR;
|
||||
|
||||
if (xioctl(fd, VIDIOC_DQBUF, &buf) == -1) {
|
||||
switch (errno) {
|
||||
case EAGAIN:
|
||||
return 0;
|
||||
|
||||
case EIO:
|
||||
// Could ignore EIO, see spec.
|
||||
|
||||
// fall through
|
||||
|
||||
default:
|
||||
return SDL_SetError("VIDIOC_DQBUF");
|
||||
}
|
||||
}
|
||||
|
||||
int i;
|
||||
for (i = 0; i < device->hidden->nb_buffers; ++i) {
|
||||
if (buf.m.userptr == (unsigned long)device->hidden->buffers[i].start && buf.length == size) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= device->hidden->nb_buffers) {
|
||||
return SDL_SetError("invalid buffer index");
|
||||
}
|
||||
|
||||
frame->pixels = (void*)buf.m.userptr;
|
||||
frame->pitch = device->hidden->driver_pitch;
|
||||
device->hidden->buffers[i].available = 1;
|
||||
|
||||
*timestampNS = (((Uint64) buf.timestamp.tv_sec) * SDL_NS_PER_SECOND) + SDL_US_TO_NS(buf.timestamp.tv_usec);
|
||||
|
||||
#if DEBUG_CAMERA
|
||||
SDL_Log("CAMERA: debug userptr: image %d/%d data[0]=%p", buf.index, device->hidden->nb_buffers, (void*)frame->pixels);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case IO_METHOD_INVALID:
|
||||
SDL_assert(!"Shouldn't have hit this");
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void V4L2_ReleaseFrame(SDL_CameraDevice *device, SDL_Surface *frame)
|
||||
{
|
||||
struct v4l2_buffer buf;
|
||||
const int fd = device->hidden->fd;
|
||||
const io_method io = device->hidden->io;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < device->hidden->nb_buffers; ++i) {
|
||||
if (frame->pixels == device->hidden->buffers[i].start) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= device->hidden->nb_buffers) {
|
||||
return; // oh well, we didn't own this.
|
||||
}
|
||||
|
||||
switch (io) {
|
||||
case IO_METHOD_READ:
|
||||
break;
|
||||
|
||||
case IO_METHOD_MMAP:
|
||||
SDL_zero(buf);
|
||||
|
||||
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
buf.memory = V4L2_MEMORY_MMAP;
|
||||
buf.index = i;
|
||||
|
||||
if (xioctl(fd, VIDIOC_QBUF, &buf) == -1) {
|
||||
// !!! FIXME: disconnect the device.
|
||||
return; //SDL_SetError("VIDIOC_QBUF");
|
||||
}
|
||||
device->hidden->buffers[i].available = 0;
|
||||
break;
|
||||
|
||||
case IO_METHOD_USERPTR:
|
||||
SDL_zero(buf);
|
||||
|
||||
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
buf.memory = V4L2_MEMORY_USERPTR;
|
||||
buf.index = i;
|
||||
buf.m.userptr = (unsigned long)frame->pixels;
|
||||
buf.length = (int) device->hidden->buffers[i].length;
|
||||
|
||||
if (xioctl(fd, VIDIOC_QBUF, &buf) == -1) {
|
||||
// !!! FIXME: disconnect the device.
|
||||
return; //SDL_SetError("VIDIOC_QBUF");
|
||||
}
|
||||
device->hidden->buffers[i].available = 0;
|
||||
break;
|
||||
|
||||
case IO_METHOD_INVALID:
|
||||
SDL_assert(!"Shouldn't have hit this");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int EnqueueBuffers(SDL_CameraDevice *device)
|
||||
{
|
||||
const int fd = device->hidden->fd;
|
||||
const io_method io = device->hidden->io;
|
||||
switch (io) {
|
||||
case IO_METHOD_READ:
|
||||
break;
|
||||
|
||||
case IO_METHOD_MMAP:
|
||||
for (int i = 0; i < device->hidden->nb_buffers; ++i) {
|
||||
if (device->hidden->buffers[i].available == 0) {
|
||||
struct v4l2_buffer buf;
|
||||
|
||||
SDL_zero(buf);
|
||||
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
buf.memory = V4L2_MEMORY_MMAP;
|
||||
buf.index = i;
|
||||
|
||||
if (xioctl(fd, VIDIOC_QBUF, &buf) == -1) {
|
||||
return SDL_SetError("VIDIOC_QBUF");
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IO_METHOD_USERPTR:
|
||||
for (int i = 0; i < device->hidden->nb_buffers; ++i) {
|
||||
if (device->hidden->buffers[i].available == 0) {
|
||||
struct v4l2_buffer buf;
|
||||
|
||||
SDL_zero(buf);
|
||||
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
buf.memory = V4L2_MEMORY_USERPTR;
|
||||
buf.index = i;
|
||||
buf.m.userptr = (unsigned long)device->hidden->buffers[i].start;
|
||||
buf.length = (int) device->hidden->buffers[i].length;
|
||||
|
||||
if (xioctl(fd, VIDIOC_QBUF, &buf) == -1) {
|
||||
return SDL_SetError("VIDIOC_QBUF");
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IO_METHOD_INVALID: SDL_assert(!"Shouldn't have hit this"); break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int AllocBufferRead(SDL_CameraDevice *device, size_t buffer_size)
|
||||
{
|
||||
device->hidden->buffers[0].length = buffer_size;
|
||||
device->hidden->buffers[0].start = SDL_calloc(1, buffer_size);
|
||||
return device->hidden->buffers[0].start ? 0 : -1;
|
||||
}
|
||||
|
||||
static int AllocBufferMmap(SDL_CameraDevice *device)
|
||||
{
|
||||
const int fd = device->hidden->fd;
|
||||
int i;
|
||||
for (i = 0; i < device->hidden->nb_buffers; ++i) {
|
||||
struct v4l2_buffer buf;
|
||||
|
||||
SDL_zero(buf);
|
||||
|
||||
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
buf.memory = V4L2_MEMORY_MMAP;
|
||||
buf.index = i;
|
||||
|
||||
if (xioctl(fd, VIDIOC_QUERYBUF, &buf) == -1) {
|
||||
return SDL_SetError("VIDIOC_QUERYBUF");
|
||||
}
|
||||
|
||||
device->hidden->buffers[i].length = buf.length;
|
||||
device->hidden->buffers[i].start =
|
||||
mmap(NULL /* start anywhere */,
|
||||
buf.length,
|
||||
PROT_READ | PROT_WRITE /* required */,
|
||||
MAP_SHARED /* recommended */,
|
||||
fd, buf.m.offset);
|
||||
|
||||
if (MAP_FAILED == device->hidden->buffers[i].start) {
|
||||
return SDL_SetError("mmap");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int AllocBufferUserPtr(SDL_CameraDevice *device, size_t buffer_size)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < device->hidden->nb_buffers; ++i) {
|
||||
device->hidden->buffers[i].length = buffer_size;
|
||||
device->hidden->buffers[i].start = SDL_calloc(1, buffer_size);
|
||||
|
||||
if (!device->hidden->buffers[i].start) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Uint32 format_v4l2_to_sdl(Uint32 fmt)
|
||||
{
|
||||
switch (fmt) {
|
||||
#define CASE(x, y) case x: return y
|
||||
CASE(V4L2_PIX_FMT_YUYV, SDL_PIXELFORMAT_YUY2);
|
||||
CASE(V4L2_PIX_FMT_MJPEG, SDL_PIXELFORMAT_UNKNOWN);
|
||||
#undef CASE
|
||||
default:
|
||||
#if DEBUG_CAMERA
|
||||
SDL_Log("CAMERA: Unknown format V4L2_PIX_FORMAT '%d'", fmt);
|
||||
#endif
|
||||
return SDL_PIXELFORMAT_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
static Uint32 format_sdl_to_v4l2(Uint32 fmt)
|
||||
{
|
||||
switch (fmt) {
|
||||
#define CASE(y, x) case x: return y
|
||||
CASE(V4L2_PIX_FMT_YUYV, SDL_PIXELFORMAT_YUY2);
|
||||
CASE(V4L2_PIX_FMT_MJPEG, SDL_PIXELFORMAT_UNKNOWN);
|
||||
#undef CASE
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void V4L2_CloseDevice(SDL_CameraDevice *device)
|
||||
{
|
||||
if (!device) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (device->hidden) {
|
||||
const io_method io = device->hidden->io;
|
||||
const int fd = device->hidden->fd;
|
||||
|
||||
if ((io == IO_METHOD_MMAP) || (io == IO_METHOD_USERPTR)) {
|
||||
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
xioctl(fd, VIDIOC_STREAMOFF, &type);
|
||||
}
|
||||
|
||||
if (device->hidden->buffers) {
|
||||
switch (io) {
|
||||
case IO_METHOD_INVALID:
|
||||
break;
|
||||
|
||||
case IO_METHOD_READ:
|
||||
SDL_free(device->hidden->buffers[0].start);
|
||||
break;
|
||||
|
||||
case IO_METHOD_MMAP:
|
||||
for (int i = 0; i < device->hidden->nb_buffers; ++i) {
|
||||
if (munmap(device->hidden->buffers[i].start, device->hidden->buffers[i].length) == -1) {
|
||||
SDL_SetError("munmap");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case IO_METHOD_USERPTR:
|
||||
for (int i = 0; i < device->hidden->nb_buffers; ++i) {
|
||||
SDL_free(device->hidden->buffers[i].start);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
SDL_free(device->hidden->buffers);
|
||||
}
|
||||
|
||||
if (fd != -1) {
|
||||
close(fd);
|
||||
}
|
||||
SDL_free(device->hidden);
|
||||
|
||||
device->hidden = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int V4L2_OpenDevice(SDL_CameraDevice *device, const SDL_CameraSpec *spec)
|
||||
{
|
||||
const V4L2DeviceHandle *handle = (const V4L2DeviceHandle *) device->handle;
|
||||
struct stat st;
|
||||
struct v4l2_capability cap;
|
||||
const int fd = open(handle->path, O_RDWR /* required */ | O_NONBLOCK, 0);
|
||||
|
||||
// most of this probably shouldn't fail unless the filesystem node changed out from under us since MaybeAddDevice().
|
||||
if (fd == -1) {
|
||||
return SDL_SetError("Cannot open '%s': %d, %s", handle->path, errno, strerror(errno));
|
||||
} else if (fstat(fd, &st) == -1) {
|
||||
close(fd);
|
||||
return SDL_SetError("Cannot identify '%s': %d, %s", handle->path, errno, strerror(errno));
|
||||
} else if (!S_ISCHR(st.st_mode)) {
|
||||
close(fd);
|
||||
return SDL_SetError("%s is not a character device", handle->path);
|
||||
} else if (xioctl(fd, VIDIOC_QUERYCAP, &cap) == -1) {
|
||||
const int err = errno;
|
||||
close(fd);
|
||||
if (err == EINVAL) {
|
||||
return SDL_SetError("%s is unexpectedly not a V4L2 device", handle->path);
|
||||
}
|
||||
return SDL_SetError("Error VIDIOC_QUERYCAP errno=%d device%s is no V4L2 device", err, handle->path);
|
||||
} else if ((cap.device_caps & V4L2_CAP_VIDEO_CAPTURE) == 0) {
|
||||
close(fd);
|
||||
return SDL_SetError("%s is unexpectedly not a video capture device", handle->path);
|
||||
}
|
||||
|
||||
device->hidden = (struct SDL_PrivateCameraData *) SDL_calloc(1, sizeof (struct SDL_PrivateCameraData));
|
||||
if (device->hidden == NULL) {
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
device->hidden->fd = fd;
|
||||
device->hidden->io = IO_METHOD_INVALID;
|
||||
|
||||
// Select video input, video standard and tune here.
|
||||
// errors in the crop code are not fatal.
|
||||
struct v4l2_cropcap cropcap;
|
||||
SDL_zero(cropcap);
|
||||
cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
if (xioctl(fd, VIDIOC_CROPCAP, &cropcap) == 0) {
|
||||
struct v4l2_crop crop;
|
||||
SDL_zero(crop);
|
||||
crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
crop.c = cropcap.defrect; // reset to default
|
||||
xioctl(fd, VIDIOC_S_CROP, &crop);
|
||||
}
|
||||
|
||||
struct v4l2_format fmt;
|
||||
SDL_zero(fmt);
|
||||
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
fmt.fmt.pix.width = spec->width;
|
||||
fmt.fmt.pix.height = spec->height;
|
||||
fmt.fmt.pix.pixelformat = format_sdl_to_v4l2(spec->format);
|
||||
//fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
|
||||
fmt.fmt.pix.field = V4L2_FIELD_ANY;
|
||||
|
||||
#if DEBUG_CAMERA
|
||||
SDL_Log("CAMERA: set SDL format %s", SDL_GetPixelFormatName(spec->format));
|
||||
{ const Uint32 f = fmt.fmt.pix.pixelformat; SDL_Log("CAMERA: set format V4L2_format=%d %c%c%c%c", f, (f >> 0) & 0xff, (f >> 8) & 0xff, (f >> 16) & 0xff, (f >> 24) & 0xff); }
|
||||
#endif
|
||||
|
||||
if (xioctl(fd, VIDIOC_S_FMT, &fmt) == -1) {
|
||||
return SDL_SetError("Error VIDIOC_S_FMT");
|
||||
}
|
||||
|
||||
if (spec->interval_numerator && spec->interval_denominator) {
|
||||
struct v4l2_streamparm setfps;
|
||||
SDL_zero(setfps);
|
||||
setfps.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
if (xioctl(fd, VIDIOC_G_PARM, &setfps) == 0) {
|
||||
if ( (setfps.parm.capture.timeperframe.numerator != spec->interval_numerator) ||
|
||||
(setfps.parm.capture.timeperframe.denominator = spec->interval_denominator) ) {
|
||||
setfps.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
setfps.parm.capture.timeperframe.numerator = spec->interval_numerator;
|
||||
setfps.parm.capture.timeperframe.denominator = spec->interval_denominator;
|
||||
if (xioctl(fd, VIDIOC_S_PARM, &setfps) == -1) {
|
||||
return SDL_SetError("Error VIDIOC_S_PARM");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SDL_zero(fmt);
|
||||
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
if (xioctl(fd, VIDIOC_G_FMT, &fmt) == -1) {
|
||||
return SDL_SetError("Error VIDIOC_G_FMT");
|
||||
}
|
||||
device->hidden->driver_pitch = fmt.fmt.pix.bytesperline;
|
||||
|
||||
io_method io = IO_METHOD_INVALID;
|
||||
if ((io == IO_METHOD_INVALID) && (cap.device_caps & V4L2_CAP_STREAMING)) {
|
||||
struct v4l2_requestbuffers req;
|
||||
SDL_zero(req);
|
||||
req.count = 8;
|
||||
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
req.memory = V4L2_MEMORY_MMAP;
|
||||
if ((xioctl(fd, VIDIOC_REQBUFS, &req) == 0) && (req.count >= 2)) {
|
||||
io = IO_METHOD_MMAP;
|
||||
device->hidden->nb_buffers = req.count;
|
||||
} else { // mmap didn't work out? Try USERPTR.
|
||||
SDL_zero(req);
|
||||
req.count = 8;
|
||||
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
req.memory = V4L2_MEMORY_USERPTR;
|
||||
if (xioctl(fd, VIDIOC_REQBUFS, &req) == 0) {
|
||||
io = IO_METHOD_USERPTR;
|
||||
device->hidden->nb_buffers = 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((io == IO_METHOD_INVALID) && (cap.device_caps & V4L2_CAP_READWRITE)) {
|
||||
io = IO_METHOD_READ;
|
||||
device->hidden->nb_buffers = 1;
|
||||
}
|
||||
|
||||
if (io == IO_METHOD_INVALID) {
|
||||
return SDL_SetError("Don't have a way to talk to this device");
|
||||
}
|
||||
|
||||
device->hidden->io = io;
|
||||
|
||||
device->hidden->buffers = SDL_calloc(device->hidden->nb_buffers, sizeof(*device->hidden->buffers));
|
||||
if (!device->hidden->buffers) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t size, pitch;
|
||||
SDL_CalculateSurfaceSize(device->spec.format, device->spec.width, device->spec.height, &size, &pitch, SDL_FALSE);
|
||||
|
||||
int rc = 0;
|
||||
switch (io) {
|
||||
case IO_METHOD_READ:
|
||||
rc = AllocBufferRead(device, size);
|
||||
break;
|
||||
|
||||
case IO_METHOD_MMAP:
|
||||
rc = AllocBufferMmap(device);
|
||||
break;
|
||||
|
||||
case IO_METHOD_USERPTR:
|
||||
rc = AllocBufferUserPtr(device, size);
|
||||
break;
|
||||
|
||||
case IO_METHOD_INVALID:
|
||||
SDL_assert(!"Shouldn't have hit this");
|
||||
break;
|
||||
}
|
||||
|
||||
if (rc < 0) {
|
||||
return -1;
|
||||
} else if (EnqueueBuffers(device) < 0) {
|
||||
return -1;
|
||||
} else if (io != IO_METHOD_READ) {
|
||||
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
if (xioctl(fd, VIDIOC_STREAMON, &type) == -1) {
|
||||
return SDL_SetError("VIDIOC_STREAMON");
|
||||
}
|
||||
}
|
||||
|
||||
// Currently there is no user permission prompt for camera access, but maybe there will be a D-Bus portal interface at some point.
|
||||
SDL_CameraDevicePermissionOutcome(device, SDL_TRUE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SDL_bool FindV4L2CameraDeviceByBusInfoCallback(SDL_CameraDevice *device, void *userdata)
|
||||
{
|
||||
const V4L2DeviceHandle *handle = (const V4L2DeviceHandle *) device->handle;
|
||||
return (SDL_strcmp(handle->bus_info, (const char *) userdata) == 0);
|
||||
}
|
||||
|
||||
static int AddCameraFormat(const int fd, CameraFormatAddData *data, Uint32 sdlfmt, Uint32 v4l2fmt, int w, int h)
|
||||
{
|
||||
struct v4l2_frmivalenum frmivalenum;
|
||||
SDL_zero(frmivalenum);
|
||||
frmivalenum.pixel_format = v4l2fmt;
|
||||
frmivalenum.width = (Uint32) w;
|
||||
frmivalenum.height = (Uint32) h;
|
||||
|
||||
while (ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &frmivalenum) == 0) {
|
||||
if (frmivalenum.type == V4L2_FRMIVAL_TYPE_DISCRETE) {
|
||||
const int numerator = (int) frmivalenum.discrete.numerator;
|
||||
const int denominator = (int) frmivalenum.discrete.denominator;
|
||||
#if DEBUG_CAMERA
|
||||
const float fps = (float) denominator / (float) numerator;
|
||||
SDL_Log("CAMERA: * Has discrete frame interval (%d / %d), fps=%f", numerator, denominator, fps);
|
||||
#endif
|
||||
if (SDL_AddCameraFormat(data, sdlfmt, w, h, numerator, denominator) == -1) {
|
||||
return -1; // Probably out of memory; we'll go with what we have, if anything.
|
||||
}
|
||||
frmivalenum.index++; // set up for the next one.
|
||||
} else if ((frmivalenum.type == V4L2_FRMIVAL_TYPE_STEPWISE) || (frmivalenum.type == V4L2_FRMIVAL_TYPE_CONTINUOUS)) {
|
||||
int d = frmivalenum.stepwise.min.denominator;
|
||||
// !!! FIXME: should we step by the numerator...?
|
||||
for (int n = (int) frmivalenum.stepwise.min.numerator; n <= (int) frmivalenum.stepwise.max.numerator; n += (int) frmivalenum.stepwise.step.numerator) {
|
||||
#if DEBUG_CAMERA
|
||||
const float fps = (float) d / (float) n;
|
||||
SDL_Log("CAMERA: * Has %s frame interval (%d / %d), fps=%f", (frmivalenum.type == V4L2_FRMIVAL_TYPE_STEPWISE) ? "stepwise" : "continuous", n, d, fps);
|
||||
#endif
|
||||
if (SDL_AddCameraFormat(data, sdlfmt, w, h, n, d) == -1) {
|
||||
return -1; // Probably out of memory; we'll go with what we have, if anything.
|
||||
}
|
||||
d += (int) frmivalenum.stepwise.step.denominator;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void MaybeAddDevice(const char *path)
|
||||
{
|
||||
if (!path) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct stat st;
|
||||
const int fd = open(path, O_RDWR /* required */ | O_NONBLOCK, 0);
|
||||
if (fd == -1) {
|
||||
return; // can't open it? skip it.
|
||||
} else if (fstat(fd, &st) == -1) {
|
||||
close(fd);
|
||||
return; // can't stat it? skip it.
|
||||
} else if (!S_ISCHR(st.st_mode)) {
|
||||
close(fd);
|
||||
return; // not a character device.
|
||||
}
|
||||
|
||||
struct v4l2_capability vcap;
|
||||
const int rc = ioctl(fd, VIDIOC_QUERYCAP, &vcap);
|
||||
if (rc != 0) {
|
||||
close(fd);
|
||||
return; // probably not a v4l2 device at all.
|
||||
} else if ((vcap.device_caps & V4L2_CAP_VIDEO_CAPTURE) == 0) {
|
||||
close(fd);
|
||||
return; // not a video capture device.
|
||||
} else if (SDL_FindPhysicalCameraDeviceByCallback(FindV4L2CameraDeviceByBusInfoCallback, vcap.bus_info)) {
|
||||
close(fd);
|
||||
return; // already have it.
|
||||
}
|
||||
|
||||
#if DEBUG_CAMERA
|
||||
SDL_Log("CAMERA: V4L2 camera path='%s' bus_info='%s' name='%s'", path, (const char *) vcap.bus_info, vcap.card);
|
||||
#endif
|
||||
|
||||
CameraFormatAddData add_data;
|
||||
SDL_zero(add_data);
|
||||
|
||||
struct v4l2_fmtdesc fmtdesc;
|
||||
SDL_zero(fmtdesc);
|
||||
fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
while (ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc) == 0) {
|
||||
const Uint32 sdlfmt = format_v4l2_to_sdl(fmtdesc.pixelformat);
|
||||
|
||||
#if DEBUG_CAMERA
|
||||
SDL_Log("CAMERA: - Has format '%s'%s%s", SDL_GetPixelFormatName(sdlfmt),
|
||||
(fmtdesc.flags & V4L2_FMT_FLAG_EMULATED) ? " [EMULATED]" : "",
|
||||
(fmtdesc.flags & V4L2_FMT_FLAG_COMPRESSED) ? " [COMPRESSED]" : "");
|
||||
#endif
|
||||
|
||||
fmtdesc.index++; // prepare for next iteration.
|
||||
|
||||
if (sdlfmt == SDL_PIXELFORMAT_UNKNOWN) {
|
||||
continue; // unsupported by SDL atm.
|
||||
}
|
||||
|
||||
struct v4l2_frmsizeenum frmsizeenum;
|
||||
SDL_zero(frmsizeenum);
|
||||
frmsizeenum.pixel_format = fmtdesc.pixelformat;
|
||||
|
||||
while (ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frmsizeenum) == 0) {
|
||||
if (frmsizeenum.type == V4L2_FRMSIZE_TYPE_DISCRETE) {
|
||||
const int w = (int) frmsizeenum.discrete.width;
|
||||
const int h = (int) frmsizeenum.discrete.height;
|
||||
#if DEBUG_CAMERA
|
||||
SDL_Log("CAMERA: * Has discrete size %dx%d", w, h);
|
||||
#endif
|
||||
if (AddCameraFormat(fd, &add_data, sdlfmt, fmtdesc.pixelformat, w, h) == -1) {
|
||||
break; // Probably out of memory; we'll go with what we have, if anything.
|
||||
}
|
||||
frmsizeenum.index++; // set up for the next one.
|
||||
} else if ((frmsizeenum.type == V4L2_FRMSIZE_TYPE_STEPWISE) || (frmsizeenum.type == V4L2_FRMSIZE_TYPE_CONTINUOUS)) {
|
||||
const int minw = (int) frmsizeenum.stepwise.min_width;
|
||||
const int minh = (int) frmsizeenum.stepwise.min_height;
|
||||
const int maxw = (int) frmsizeenum.stepwise.max_width;
|
||||
const int maxh = (int) frmsizeenum.stepwise.max_height;
|
||||
const int stepw = (int) frmsizeenum.stepwise.step_width;
|
||||
const int steph = (int) frmsizeenum.stepwise.step_height;
|
||||
for (int w = minw; w <= maxw; w += stepw) {
|
||||
for (int h = minh; w <= maxh; w += steph) {
|
||||
#if DEBUG_CAMERA
|
||||
SDL_Log("CAMERA: * Has %s size %dx%d", (frmsizeenum.type == V4L2_FRMSIZE_TYPE_STEPWISE) ? "stepwise" : "continuous", w, h);
|
||||
#endif
|
||||
if (AddCameraFormat(fd, &add_data, sdlfmt, fmtdesc.pixelformat, w, h) == -1) {
|
||||
break; // Probably out of memory; we'll go with what we have, if anything.
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
#if DEBUG_CAMERA
|
||||
SDL_Log("CAMERA: (total specs: %d)", add_data.num_specs);
|
||||
#endif
|
||||
|
||||
if (add_data.num_specs > 0) {
|
||||
V4L2DeviceHandle *handle = (V4L2DeviceHandle *) SDL_calloc(1, sizeof (V4L2DeviceHandle));
|
||||
if (handle) {
|
||||
handle->path = SDL_strdup(path);
|
||||
if (handle->path) {
|
||||
handle->bus_info = SDL_strdup((char *)vcap.bus_info);
|
||||
if (handle->bus_info) {
|
||||
if (SDL_AddCameraDevice((const char *) vcap.card, SDL_CAMERA_POSITION_UNKNOWN, add_data.num_specs, add_data.specs, handle)) {
|
||||
SDL_free(add_data.specs);
|
||||
return; // good to go.
|
||||
}
|
||||
SDL_free(handle->bus_info);
|
||||
}
|
||||
SDL_free(handle->path);
|
||||
}
|
||||
SDL_free(handle);
|
||||
}
|
||||
}
|
||||
SDL_free(add_data.specs);
|
||||
}
|
||||
|
||||
static void V4L2_FreeDeviceHandle(SDL_CameraDevice *device)
|
||||
{
|
||||
if (device) {
|
||||
V4L2DeviceHandle *handle = (V4L2DeviceHandle *) device->handle;
|
||||
SDL_free(handle->path);
|
||||
SDL_free(handle->bus_info);
|
||||
SDL_free(handle);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SDL_USE_LIBUDEV
|
||||
static SDL_bool FindV4L2CameraDeviceByPathCallback(SDL_CameraDevice *device, void *userdata)
|
||||
{
|
||||
const V4L2DeviceHandle *handle = (const V4L2DeviceHandle *) device->handle;
|
||||
return (SDL_strcmp(handle->path, (const char *) userdata) == 0);
|
||||
}
|
||||
|
||||
static void MaybeRemoveDevice(const char *path)
|
||||
{
|
||||
if (path) {
|
||||
SDL_CameraDeviceDisconnected(SDL_FindPhysicalCameraDeviceByCallback(FindV4L2CameraDeviceByPathCallback, (void *) path));
|
||||
}
|
||||
}
|
||||
|
||||
static void CameraUdevCallback(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath)
|
||||
{
|
||||
if (devpath && (udev_class & SDL_UDEV_DEVICE_VIDEO_CAPTURE)) {
|
||||
if (udev_type == SDL_UDEV_DEVICEADDED) {
|
||||
MaybeAddDevice(devpath);
|
||||
} else if (udev_type == SDL_UDEV_DEVICEREMOVED) {
|
||||
MaybeRemoveDevice(devpath);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // SDL_USE_LIBUDEV
|
||||
|
||||
static void V4L2_Deinitialize(void)
|
||||
{
|
||||
#ifdef SDL_USE_LIBUDEV
|
||||
SDL_UDEV_DelCallback(CameraUdevCallback);
|
||||
SDL_UDEV_Quit();
|
||||
#endif // SDL_USE_LIBUDEV
|
||||
}
|
||||
|
||||
static void V4L2_DetectDevices(void)
|
||||
{
|
||||
#ifdef SDL_USE_LIBUDEV
|
||||
if (SDL_UDEV_Init() == 0) {
|
||||
if (SDL_UDEV_AddCallback(CameraUdevCallback) == 0) {
|
||||
SDL_UDEV_Scan(); // Force a scan to build the initial device list
|
||||
}
|
||||
}
|
||||
#else
|
||||
DIR *dirp = opendir("/dev");
|
||||
if (dirp) {
|
||||
struct dirent *dent;
|
||||
while ((dent = readdir(dirp)) != NULL) {
|
||||
int num = 0;
|
||||
if (SDL_sscanf(dent->d_name, "video%d", &num) == 1) {
|
||||
char fullpath[64];
|
||||
SDL_snprintf(fullpath, sizeof (fullpath), "/dev/video%d", num);
|
||||
MaybeAddDevice(fullpath);
|
||||
}
|
||||
}
|
||||
closedir(dirp);
|
||||
}
|
||||
#endif // SDL_USE_LIBUDEV
|
||||
}
|
||||
|
||||
static SDL_bool V4L2_Init(SDL_CameraDriverImpl *impl)
|
||||
{
|
||||
impl->DetectDevices = V4L2_DetectDevices;
|
||||
impl->OpenDevice = V4L2_OpenDevice;
|
||||
impl->CloseDevice = V4L2_CloseDevice;
|
||||
impl->WaitDevice = V4L2_WaitDevice;
|
||||
impl->AcquireFrame = V4L2_AcquireFrame;
|
||||
impl->ReleaseFrame = V4L2_ReleaseFrame;
|
||||
impl->FreeDeviceHandle = V4L2_FreeDeviceHandle;
|
||||
impl->Deinitialize = V4L2_Deinitialize;
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
CameraBootStrap V4L2_bootstrap = {
|
||||
"v4l2", "SDL Video4Linux2 camera driver", V4L2_Init, SDL_FALSE
|
||||
};
|
||||
|
||||
#endif // SDL_CAMERA_DRIVER_V4L2
|
||||
|
||||
22
external/sdl/SDL/src/core/SDL_core_unsupported.c
vendored
22
external/sdl/SDL/src/core/SDL_core_unsupported.c
vendored
@@ -28,7 +28,7 @@ DECLSPEC void SDLCALL SDL_SetX11EventHook(SDL_X11EventHook callback, void *userd
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __LINUX__
|
||||
#ifndef SDL_PLATFORM_LINUX
|
||||
|
||||
DECLSPEC int SDLCALL SDL_LinuxSetThreadPriority(Sint64 threadID, int priority);
|
||||
int SDL_LinuxSetThreadPriority(Sint64 threadID, int priority)
|
||||
@@ -49,7 +49,7 @@ int SDL_LinuxSetThreadPriorityAndPolicy(Sint64 threadID, int sdlPriority, int sc
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __GDK__
|
||||
#ifndef SDL_PLATFORM_GDK
|
||||
|
||||
DECLSPEC void SDLCALL SDL_GDKSuspendComplete(void);
|
||||
void SDL_GDKSuspendComplete(void)
|
||||
@@ -65,7 +65,7 @@ int SDL_GDKGetDefaultUser(void *outUserHandle)
|
||||
|
||||
#endif
|
||||
|
||||
#if !(defined(__WIN32__) || defined(__WINRT__) || defined(__GDK__))
|
||||
#if !(defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_WINRT) || defined(SDL_PLATFORM_GDK))
|
||||
|
||||
DECLSPEC int SDLCALL SDL_RegisterApp(const char *name, Uint32 style, void *hInst);
|
||||
int SDL_RegisterApp(const char *name, Uint32 style, void *hInst)
|
||||
@@ -92,7 +92,7 @@ void SDL_UnregisterApp(void)
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __WINRT__
|
||||
#ifndef SDL_PLATFORM_WINRT
|
||||
|
||||
/* Returns SDL_WinRT_DeviceFamily enum */
|
||||
DECLSPEC int SDLCALL SDL_WinRTGetDeviceFamily(void);
|
||||
@@ -119,7 +119,7 @@ const char *SDL_WinRTGetFSPathUTF8(int pathType)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __ANDROID__
|
||||
#ifndef SDL_PLATFORM_ANDROID
|
||||
|
||||
DECLSPEC void SDLCALL SDL_AndroidBackButton(void);
|
||||
void SDL_AndroidBackButton()
|
||||
@@ -161,12 +161,14 @@ void *SDL_AndroidGetJNIEnv()
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DECLSPEC SDL_bool SDLCALL SDL_AndroidRequestPermission(const char *permission);
|
||||
SDL_bool SDL_AndroidRequestPermission(const char *permission)
|
||||
typedef void (SDLCALL *SDL_AndroidRequestPermissionCallback)(void *userdata, const char *permission, SDL_bool granted);
|
||||
DECLSPEC int SDLCALL SDL_AndroidRequestPermission(const char *permission, SDL_AndroidRequestPermissionCallback cb, void *userdata);
|
||||
int SDL_AndroidRequestPermission(const char *permission, SDL_AndroidRequestPermissionCallback cb, void *userdata)
|
||||
{
|
||||
(void)permission;
|
||||
SDL_Unsupported();
|
||||
return SDL_FALSE;
|
||||
(void)cb;
|
||||
(void)userdata;
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
DECLSPEC int SDLCALL SDL_AndroidSendMessage(Uint32 command, int param);
|
||||
@@ -225,7 +227,7 @@ Sint32 JNI_OnLoad(void *vm, void *reserved)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__XBOXONE__) || defined(__XBOXSERIES__)
|
||||
#if defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)
|
||||
char *SDL_GetUserFolder(SDL_Folder folder)
|
||||
{
|
||||
(void)folder;
|
||||
|
||||
2
external/sdl/SDL/src/core/SDL_runapp.c
vendored
2
external/sdl/SDL/src/core/SDL_runapp.c
vendored
@@ -22,7 +22,7 @@
|
||||
|
||||
/* Most platforms that use/need SDL_main have their own SDL_RunApp() implementation.
|
||||
* If not, you can special case it here by appending || defined(__YOUR_PLATFORM__) */
|
||||
#if ( !defined(SDL_MAIN_NEEDED) && !defined(SDL_MAIN_AVAILABLE) ) || defined(__ANDROID__)
|
||||
#if ( !defined(SDL_MAIN_NEEDED) && !defined(SDL_MAIN_AVAILABLE) ) || defined(SDL_PLATFORM_ANDROID)
|
||||
|
||||
DECLSPEC int
|
||||
SDL_RunApp(int argc, char* argv[], SDL_main_func mainFunction, void * reserved)
|
||||
|
||||
149
external/sdl/SDL/src/core/android/SDL_android.c
vendored
149
external/sdl/SDL/src/core/android/SDL_android.c
vendored
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#ifdef SDL_PLATFORM_ANDROID
|
||||
|
||||
#include "SDL_android.h"
|
||||
|
||||
@@ -269,7 +269,7 @@ JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeHat)(
|
||||
JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddJoystick)(
|
||||
JNIEnv *env, jclass jcls,
|
||||
jint device_id, jstring device_name, jstring device_desc, jint vendor_id, jint product_id,
|
||||
jboolean is_accelerometer, jint button_mask, jint naxes, jint axis_mask, jint nhats);
|
||||
jint button_mask, jint naxes, jint axis_mask, jint nhats);
|
||||
|
||||
JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveJoystick)(
|
||||
JNIEnv *env, jclass jcls,
|
||||
@@ -289,7 +289,7 @@ static JNINativeMethod SDLControllerManager_tab[] = {
|
||||
{ "onNativePadUp", "(II)I", SDL_JAVA_CONTROLLER_INTERFACE(onNativePadUp) },
|
||||
{ "onNativeJoy", "(IIF)V", SDL_JAVA_CONTROLLER_INTERFACE(onNativeJoy) },
|
||||
{ "onNativeHat", "(IIII)V", SDL_JAVA_CONTROLLER_INTERFACE(onNativeHat) },
|
||||
{ "nativeAddJoystick", "(ILjava/lang/String;Ljava/lang/String;IIZIIII)I", SDL_JAVA_CONTROLLER_INTERFACE(nativeAddJoystick) },
|
||||
{ "nativeAddJoystick", "(ILjava/lang/String;Ljava/lang/String;IIIIII)I", SDL_JAVA_CONTROLLER_INTERFACE(nativeAddJoystick) },
|
||||
{ "nativeRemoveJoystick", "(I)I", SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveJoystick) },
|
||||
{ "nativeAddHaptic", "(ILjava/lang/String;)I", SDL_JAVA_CONTROLLER_INTERFACE(nativeAddHaptic) },
|
||||
{ "nativeRemoveHaptic", "(I)I", SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveHaptic) }
|
||||
@@ -381,9 +381,6 @@ static SDL_bool bHasNewData;
|
||||
|
||||
static SDL_bool bHasEnvironmentVariables;
|
||||
|
||||
static SDL_AtomicInt bPermissionRequestPending;
|
||||
static SDL_bool bPermissionRequestResult;
|
||||
|
||||
/* Android AssetManager */
|
||||
static void Internal_Android_Create_AssetManager(void);
|
||||
static void Internal_Android_Destroy_AssetManager(void);
|
||||
@@ -823,7 +820,7 @@ JNIEXPORT int JNICALL SDL_JAVA_INTERFACE(nativeRunMain)(JNIEnv *env, jclass cls,
|
||||
argv = SDL_small_alloc(char *, 1 + len + 1, &isstack); /* !!! FIXME: check for NULL */
|
||||
argc = 0;
|
||||
/* Use the name "app_process" so PHYSFS_platformCalcBaseDir() works.
|
||||
https://bitbucket.org/MartinFelis/love-android-sdl2/issue/23/release-build-crash-on-start
|
||||
https://github.com/love2d/love-android/issues/24
|
||||
*/
|
||||
argv[argc++] = SDL_strdup("app_process");
|
||||
for (i = 0; i < len; ++i) {
|
||||
@@ -997,14 +994,6 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeAddTouch)(
|
||||
(*env)->ReleaseStringUTFChars(env, name, utfname);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativePermissionResult)(
|
||||
JNIEnv *env, jclass cls,
|
||||
jint requestCode, jboolean result)
|
||||
{
|
||||
bPermissionRequestResult = result;
|
||||
SDL_AtomicSet(&bPermissionRequestPending, SDL_FALSE);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
SDL_JAVA_AUDIO_INTERFACE(addAudioDevice)(JNIEnv *env, jclass jcls, jboolean is_capture,
|
||||
jstring name, jint device_id)
|
||||
@@ -1068,14 +1057,14 @@ JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeHat)(
|
||||
JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddJoystick)(
|
||||
JNIEnv *env, jclass jcls,
|
||||
jint device_id, jstring device_name, jstring device_desc,
|
||||
jint vendor_id, jint product_id, jboolean is_accelerometer,
|
||||
jint vendor_id, jint product_id,
|
||||
jint button_mask, jint naxes, jint axis_mask, jint nhats)
|
||||
{
|
||||
int retval;
|
||||
const char *name = (*env)->GetStringUTFChars(env, device_name, NULL);
|
||||
const char *desc = (*env)->GetStringUTFChars(env, device_desc, NULL);
|
||||
|
||||
retval = Android_AddJoystick(device_id, name, desc, vendor_id, product_id, is_accelerometer, button_mask, naxes, axis_mask, nhats);
|
||||
retval = Android_AddJoystick(device_id, name, desc, vendor_id, product_id, button_mask, naxes, axis_mask, nhats);
|
||||
|
||||
(*env)->ReleaseStringUTFChars(env, device_name, name);
|
||||
(*env)->ReleaseStringUTFChars(env, device_desc, desc);
|
||||
@@ -1967,11 +1956,12 @@ static void Internal_Android_Destroy_AssetManager()
|
||||
}
|
||||
}
|
||||
|
||||
int Android_JNI_FileOpen(SDL_RWops *ctx,
|
||||
const char *fileName, const char *mode)
|
||||
int Android_JNI_FileOpen(void **puserdata, const char *fileName, const char *mode)
|
||||
{
|
||||
SDL_assert(puserdata != NULL);
|
||||
|
||||
AAsset *asset = NULL;
|
||||
ctx->hidden.androidio.asset = NULL;
|
||||
*puserdata = NULL;
|
||||
|
||||
if (!asset_manager) {
|
||||
Internal_Android_Create_AssetManager();
|
||||
@@ -1986,14 +1976,13 @@ int Android_JNI_FileOpen(SDL_RWops *ctx,
|
||||
return SDL_SetError("Couldn't open asset '%s'", fileName);
|
||||
}
|
||||
|
||||
ctx->hidden.androidio.asset = (void *)asset;
|
||||
*puserdata = (void *)asset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t Android_JNI_FileRead(SDL_RWops *ctx, void *buffer, size_t size)
|
||||
size_t Android_JNI_FileRead(void *userdata, void *buffer, size_t size, SDL_IOStatus *status)
|
||||
{
|
||||
AAsset *asset = (AAsset *)ctx->hidden.androidio.asset;
|
||||
int bytes = AAsset_read(asset, buffer, size);
|
||||
const int bytes = AAsset_read((AAsset *)userdata, buffer, size);
|
||||
if (bytes < 0) {
|
||||
SDL_SetError("AAsset_read() failed");
|
||||
return 0;
|
||||
@@ -2001,31 +1990,24 @@ size_t Android_JNI_FileRead(SDL_RWops *ctx, void *buffer, size_t size)
|
||||
return (size_t)bytes;
|
||||
}
|
||||
|
||||
size_t Android_JNI_FileWrite(SDL_RWops *ctx, const void *buffer, size_t size)
|
||||
size_t Android_JNI_FileWrite(void *userdata, const void *buffer, size_t size, SDL_IOStatus *status)
|
||||
{
|
||||
return SDL_SetError("Cannot write to Android package filesystem");
|
||||
}
|
||||
|
||||
Sint64 Android_JNI_FileSize(SDL_RWops *ctx)
|
||||
Sint64 Android_JNI_FileSize(void *userdata)
|
||||
{
|
||||
off64_t result;
|
||||
AAsset *asset = (AAsset *)ctx->hidden.androidio.asset;
|
||||
result = AAsset_getLength64(asset);
|
||||
return result;
|
||||
return (Sint64) AAsset_getLength64((AAsset *)userdata);
|
||||
}
|
||||
|
||||
Sint64 Android_JNI_FileSeek(SDL_RWops *ctx, Sint64 offset, int whence)
|
||||
Sint64 Android_JNI_FileSeek(void *userdata, Sint64 offset, int whence)
|
||||
{
|
||||
off64_t result;
|
||||
AAsset *asset = (AAsset *)ctx->hidden.androidio.asset;
|
||||
result = AAsset_seek64(asset, offset, whence);
|
||||
return result;
|
||||
return (Sint64) AAsset_seek64((AAsset *)userdata, offset, whence);
|
||||
}
|
||||
|
||||
int Android_JNI_FileClose(SDL_RWops *ctx)
|
||||
int Android_JNI_FileClose(void *userdata)
|
||||
{
|
||||
AAsset *asset = (AAsset *)ctx->hidden.androidio.asset;
|
||||
AAsset_close(asset);
|
||||
AAsset_close((AAsset *)userdata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2264,7 +2246,7 @@ SDL_bool Android_JNI_IsScreenKeyboardShown(void)
|
||||
return is_shown;
|
||||
}
|
||||
|
||||
int Android_JNI_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
|
||||
int Android_JNI_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID)
|
||||
{
|
||||
JNIEnv *env;
|
||||
jclass clazz;
|
||||
@@ -2304,7 +2286,7 @@ int Android_JNI_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *bu
|
||||
|
||||
temp = sdlButton->flags;
|
||||
(*env)->SetIntArrayRegion(env, button_flags, i, 1, &temp);
|
||||
temp = sdlButton->buttonid;
|
||||
temp = sdlButton->buttonID;
|
||||
(*env)->SetIntArrayRegion(env, button_ids, i, 1, &temp);
|
||||
text = (*env)->NewStringUTF(env, sdlButton->text);
|
||||
(*env)->SetObjectArrayElement(env, button_texts, i, text);
|
||||
@@ -2333,7 +2315,7 @@ int Android_JNI_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *bu
|
||||
|
||||
mid = (*env)->GetMethodID(env, clazz,
|
||||
"messageboxShowMessageBox", "(ILjava/lang/String;Ljava/lang/String;[I[I[Ljava/lang/String;[I)I");
|
||||
*buttonid = (*env)->CallIntMethod(env, context, mid,
|
||||
*buttonID = (*env)->CallIntMethod(env, context, mid,
|
||||
messageboxdata->flags,
|
||||
title,
|
||||
message,
|
||||
@@ -2568,11 +2550,6 @@ const char *SDL_AndroidGetExternalStoragePath(void)
|
||||
return s_AndroidExternalFilesPath;
|
||||
}
|
||||
|
||||
SDL_bool SDL_AndroidRequestPermission(const char *permission)
|
||||
{
|
||||
return Android_JNI_RequestPermission(permission);
|
||||
}
|
||||
|
||||
int SDL_AndroidShowToast(const char *message, int duration, int gravity, int xOffset, int yOffset)
|
||||
{
|
||||
return Android_JNI_ShowToast(message, duration, gravity, xOffset, yOffset);
|
||||
@@ -2640,27 +2617,75 @@ SDL_bool Android_JNI_SetRelativeMouseEnabled(SDL_bool enabled)
|
||||
return (*env)->CallStaticBooleanMethod(env, mActivityClass, midSetRelativeMouseEnabled, (enabled == 1));
|
||||
}
|
||||
|
||||
SDL_bool Android_JNI_RequestPermission(const char *permission)
|
||||
typedef struct NativePermissionRequestInfo
|
||||
{
|
||||
JNIEnv *env = Android_JNI_GetEnv();
|
||||
jstring jpermission;
|
||||
const int requestCode = 1;
|
||||
int request_code;
|
||||
char *permission;
|
||||
SDL_AndroidRequestPermissionCallback callback;
|
||||
void *userdata;
|
||||
struct NativePermissionRequestInfo *next;
|
||||
} NativePermissionRequestInfo;
|
||||
|
||||
/* Wait for any pending request on another thread */
|
||||
while (SDL_AtomicGet(&bPermissionRequestPending) == SDL_TRUE) {
|
||||
SDL_Delay(10);
|
||||
static NativePermissionRequestInfo pending_permissions;
|
||||
|
||||
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativePermissionResult)(
|
||||
JNIEnv *env, jclass cls,
|
||||
jint requestCode, jboolean result)
|
||||
{
|
||||
SDL_LockMutex(Android_ActivityMutex);
|
||||
NativePermissionRequestInfo *prev = &pending_permissions;
|
||||
for (NativePermissionRequestInfo *info = prev->next; info != NULL; info = info->next) {
|
||||
if (info->request_code == (int) requestCode) {
|
||||
prev->next = info->next;
|
||||
SDL_UnlockMutex(Android_ActivityMutex);
|
||||
info->callback(info->userdata, info->permission, result ? SDL_TRUE : SDL_FALSE);
|
||||
SDL_free(info->permission);
|
||||
SDL_free(info);
|
||||
return;
|
||||
}
|
||||
prev = info;
|
||||
}
|
||||
SDL_AtomicSet(&bPermissionRequestPending, SDL_TRUE);
|
||||
|
||||
jpermission = (*env)->NewStringUTF(env, permission);
|
||||
(*env)->CallStaticVoidMethod(env, mActivityClass, midRequestPermission, jpermission, requestCode);
|
||||
SDL_UnlockMutex(Android_ActivityMutex);
|
||||
SDL_assert(!"Shouldn't have hit this code"); // we had a permission response for a request we never made...?
|
||||
}
|
||||
|
||||
int SDL_AndroidRequestPermission(const char *permission, SDL_AndroidRequestPermissionCallback cb, void *userdata)
|
||||
{
|
||||
if (!permission) {
|
||||
return SDL_InvalidParamError("permission");
|
||||
} else if (!cb) {
|
||||
return SDL_InvalidParamError("cb");
|
||||
}
|
||||
|
||||
NativePermissionRequestInfo *info = (NativePermissionRequestInfo *) SDL_calloc(1, sizeof (NativePermissionRequestInfo));
|
||||
if (!info) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
info->permission = SDL_strdup(permission);
|
||||
if (!info->permission) {
|
||||
SDL_free(info);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static SDL_AtomicInt next_request_code;
|
||||
info->request_code = SDL_AtomicAdd(&next_request_code, 1);
|
||||
|
||||
info->callback = cb;
|
||||
info->userdata = userdata;
|
||||
|
||||
SDL_LockMutex(Android_ActivityMutex);
|
||||
info->next = pending_permissions.next;
|
||||
pending_permissions.next = info;
|
||||
SDL_UnlockMutex(Android_ActivityMutex);
|
||||
|
||||
JNIEnv *env = Android_JNI_GetEnv();
|
||||
jstring jpermission = (*env)->NewStringUTF(env, permission);
|
||||
(*env)->CallStaticVoidMethod(env, mActivityClass, midRequestPermission, jpermission, info->request_code);
|
||||
(*env)->DeleteLocalRef(env, jpermission);
|
||||
|
||||
/* Wait for the request to complete */
|
||||
while (SDL_AtomicGet(&bPermissionRequestPending) == SDL_TRUE) {
|
||||
SDL_Delay(10);
|
||||
}
|
||||
return bPermissionRequestResult;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Show toast notification */
|
||||
@@ -2741,4 +2766,4 @@ int Android_JNI_OpenURL(const char *url)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* __ANDROID__ */
|
||||
#endif /* SDL_PLATFORM_ANDROID */
|
||||
|
||||
17
external/sdl/SDL/src/core/android/SDL_android.h
vendored
17
external/sdl/SDL/src/core/android/SDL_android.h
vendored
@@ -66,12 +66,12 @@ extern void Android_JNI_CloseAudioDevice(const int iscapture);
|
||||
extern SDL_bool Android_IsDeXMode(void);
|
||||
extern SDL_bool Android_IsChromebook(void);
|
||||
|
||||
int Android_JNI_FileOpen(SDL_RWops *ctx, const char *fileName, const char *mode);
|
||||
Sint64 Android_JNI_FileSize(SDL_RWops *ctx);
|
||||
Sint64 Android_JNI_FileSeek(SDL_RWops *ctx, Sint64 offset, int whence);
|
||||
size_t Android_JNI_FileRead(SDL_RWops *ctx, void *buffer, size_t size);
|
||||
size_t Android_JNI_FileWrite(SDL_RWops *ctx, const void *buffer, size_t size);
|
||||
int Android_JNI_FileClose(SDL_RWops *ctx);
|
||||
int Android_JNI_FileOpen(void **puserdata, const char *fileName, const char *mode);
|
||||
Sint64 Android_JNI_FileSize(void *userdata);
|
||||
Sint64 Android_JNI_FileSeek(void *userdata, Sint64 offset, int whence);
|
||||
size_t Android_JNI_FileRead(void *userdata, void *buffer, size_t size, SDL_IOStatus *status);
|
||||
size_t Android_JNI_FileWrite(void *userdata, const void *buffer, size_t size, SDL_IOStatus *status);
|
||||
int Android_JNI_FileClose(void *userdata);
|
||||
|
||||
/* Environment support */
|
||||
void Android_JNI_GetManifestEnvironmentVariables(void);
|
||||
@@ -113,7 +113,7 @@ int Android_JNI_SendMessage(int command, int param);
|
||||
JNIEXPORT void JNICALL SDL_Android_Init(JNIEnv *mEnv, jclass cls);
|
||||
|
||||
/* MessageBox */
|
||||
int Android_JNI_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid);
|
||||
int Android_JNI_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID);
|
||||
|
||||
/* Cursor support */
|
||||
int Android_JNI_CreateCustomCursor(SDL_Surface *surface, int hot_x, int hot_y);
|
||||
@@ -125,9 +125,6 @@ SDL_bool Android_JNI_SetSystemCursor(int cursorID);
|
||||
SDL_bool Android_JNI_SupportsRelativeMouse(void);
|
||||
SDL_bool Android_JNI_SetRelativeMouseEnabled(SDL_bool enabled);
|
||||
|
||||
/* Request permission */
|
||||
SDL_bool Android_JNI_RequestPermission(const char *permission);
|
||||
|
||||
/* Show toast notification */
|
||||
int Android_JNI_ShowToast(const char *message, int duration, int gravity, int xOffset, int yOffset);
|
||||
|
||||
|
||||
@@ -542,6 +542,7 @@ void SDL_EVDEV_kbd_keycode(SDL_EVDEV_keyboard_state *kbd, unsigned int keycode,
|
||||
if (down == 0) {
|
||||
chg_vc_kbd_led(kbd, ALKED);
|
||||
}
|
||||
SDL_FALLTHROUGH;
|
||||
case LSH: /* left shift */
|
||||
case RSH: /* right shift */
|
||||
k_shift(kbd, 0, down == 0);
|
||||
@@ -551,6 +552,7 @@ void SDL_EVDEV_kbd_keycode(SDL_EVDEV_keyboard_state *kbd, unsigned int keycode,
|
||||
if (down == 0) {
|
||||
chg_vc_kbd_led(kbd, ALKED);
|
||||
}
|
||||
SDL_FALLTHROUGH;
|
||||
case LCTR: /* left ctrl */
|
||||
case RCTR: /* right ctrl */
|
||||
k_shift(kbd, 1, down == 0);
|
||||
@@ -560,6 +562,7 @@ void SDL_EVDEV_kbd_keycode(SDL_EVDEV_keyboard_state *kbd, unsigned int keycode,
|
||||
if (down == 0) {
|
||||
chg_vc_kbd_led(kbd, ALKED);
|
||||
}
|
||||
SDL_FALLTHROUGH;
|
||||
case LALT: /* left alt */
|
||||
case RALT: /* right alt */
|
||||
k_shift(kbd, 2, down == 0);
|
||||
|
||||
2
external/sdl/SDL/src/core/gdk/SDL_gdk.cpp
vendored
2
external/sdl/SDL/src/core/gdk/SDL_gdk.cpp
vendored
@@ -190,7 +190,7 @@ SDL_RunApp(int, char**, SDL_main_func mainFunction, void *reserved)
|
||||
|
||||
XGameRuntimeUninitialize();
|
||||
} else {
|
||||
#ifdef __WINGDK__
|
||||
#ifdef SDL_PLATFORM_WINGDK
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", "[GDK] Could not initialize - aborting", NULL);
|
||||
#else
|
||||
SDL_assert_always(0 && "[GDK] Could not initialize - aborting");
|
||||
|
||||
15
external/sdl/SDL/src/core/haiku/SDL_BApp.h
vendored
15
external/sdl/SDL/src/core/haiku/SDL_BApp.h
vendored
@@ -46,6 +46,7 @@ extern "C" {
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
/* Forward declarations */
|
||||
class SDL_BLooper;
|
||||
class SDL_BWin;
|
||||
@@ -248,12 +249,12 @@ class SDL_BLooper : public BLooper
|
||||
SDL_GetWindowPosition(win, &winPosX, &winPosY);
|
||||
int dx = x - (winWidth / 2);
|
||||
int dy = y - (winHeight / 2);
|
||||
SDL_SendMouseMotion(0, win, 0, SDL_GetMouse()->relative_mode, (float)dx, (float)dy);
|
||||
SDL_SendMouseMotion(0, win, SDL_DEFAULT_MOUSE_ID, SDL_GetMouse()->relative_mode, (float)dx, (float)dy);
|
||||
set_mouse_position((winPosX + winWidth / 2), (winPosY + winHeight / 2));
|
||||
if (!be_app->IsCursorHidden())
|
||||
be_app->HideCursor();
|
||||
} else {
|
||||
SDL_SendMouseMotion(0, win, 0, 0, (float)x, (float)y);
|
||||
SDL_SendMouseMotion(0, win, SDL_DEFAULT_MOUSE_ID, SDL_FALSE, (float)x, (float)y);
|
||||
if (SDL_CursorVisible() && be_app->IsCursorHidden())
|
||||
be_app->ShowCursor();
|
||||
}
|
||||
@@ -271,7 +272,7 @@ class SDL_BLooper : public BLooper
|
||||
return;
|
||||
}
|
||||
win = GetSDLWindow(winID);
|
||||
SDL_SendMouseButton(0, win, 0, state, button);
|
||||
SDL_SendMouseButton(0, win, SDL_DEFAULT_MOUSE_ID, state, button);
|
||||
}
|
||||
|
||||
void _HandleMouseWheel(BMessage *msg)
|
||||
@@ -286,7 +287,7 @@ class SDL_BLooper : public BLooper
|
||||
return;
|
||||
}
|
||||
win = GetSDLWindow(winID);
|
||||
SDL_SendMouseWheel(0, win, 0, xTicks, -yTicks, SDL_MOUSEWHEEL_NORMAL);
|
||||
SDL_SendMouseWheel(0, win, SDL_DEFAULT_MOUSE_ID, xTicks, -yTicks, SDL_MOUSEWHEEL_NORMAL);
|
||||
}
|
||||
|
||||
void _HandleKey(BMessage *msg)
|
||||
@@ -303,13 +304,13 @@ class SDL_BLooper : public BLooper
|
||||
return;
|
||||
}
|
||||
HAIKU_SetKeyState(scancode, state);
|
||||
SDL_SendKeyboardKey(0, state, HAIKU_GetScancodeFromBeKey(scancode));
|
||||
SDL_SendKeyboardKey(0, SDL_DEFAULT_KEYBOARD_ID, state, HAIKU_GetScancodeFromBeKey(scancode));
|
||||
|
||||
if (state == SDL_PRESSED && SDL_EventEnabled(SDL_EVENT_TEXT_INPUT)) {
|
||||
if (state == SDL_PRESSED && SDL_TextInputActive()) {
|
||||
const int8 *keyUtf8;
|
||||
ssize_t count;
|
||||
if (msg->FindData("key-utf8", B_INT8_TYPE, (const void **)&keyUtf8, &count) == B_OK) {
|
||||
char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];
|
||||
char text[64];
|
||||
SDL_zeroa(text);
|
||||
SDL_memcpy(text, keyUtf8, count);
|
||||
SDL_SendKeyboardText(text);
|
||||
|
||||
4
external/sdl/SDL/src/core/haiku/SDL_BeApp.cc
vendored
4
external/sdl/SDL/src/core/haiku/SDL_BeApp.cc
vendored
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifdef __HAIKU__
|
||||
#ifdef SDL_PLATFORM_HAIKU
|
||||
|
||||
/* Handle the BeApp specific portions of the application */
|
||||
|
||||
@@ -192,4 +192,4 @@ void SDL_BLooper::ClearID(SDL_BWin *bwin) {
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* __HAIKU__ */
|
||||
#endif /* SDL_PLATFORM_HAIKU */
|
||||
|
||||
6
external/sdl/SDL/src/core/linux/SDL_dbus.c
vendored
6
external/sdl/SDL/src/core/linux/SDL_dbus.c
vendored
@@ -53,6 +53,7 @@ static int LoadDBUSSyms(void)
|
||||
SDL_DBUS_SYM(void (*)(DBusConnection *, dbus_bool_t), connection_set_exit_on_disconnect);
|
||||
SDL_DBUS_SYM(dbus_bool_t (*)(DBusConnection *), connection_get_is_connected);
|
||||
SDL_DBUS_SYM(dbus_bool_t (*)(DBusConnection *, DBusHandleMessageFunction, void *, DBusFreeFunction), connection_add_filter);
|
||||
SDL_DBUS_SYM(dbus_bool_t (*)(DBusConnection *, DBusHandleMessageFunction, void *), connection_remove_filter);
|
||||
SDL_DBUS_SYM(dbus_bool_t (*)(DBusConnection *, const char *, const DBusObjectPathVTable *, void *, DBusError *), connection_try_register_object_path);
|
||||
SDL_DBUS_SYM(dbus_bool_t (*)(DBusConnection *, DBusMessage *, dbus_uint32_t *), connection_send);
|
||||
SDL_DBUS_SYM(DBusMessage *(*)(DBusConnection *, DBusMessage *, int, DBusError *), connection_send_with_reply_and_block);
|
||||
@@ -63,6 +64,7 @@ static int LoadDBUSSyms(void)
|
||||
SDL_DBUS_SYM(dbus_bool_t (*)(DBusConnection *, int), connection_read_write);
|
||||
SDL_DBUS_SYM(DBusDispatchStatus (*)(DBusConnection *), connection_dispatch);
|
||||
SDL_DBUS_SYM(dbus_bool_t (*)(DBusMessage *, const char *, const char *), message_is_signal);
|
||||
SDL_DBUS_SYM(dbus_bool_t (*)(DBusMessage *, const char *), message_has_path);
|
||||
SDL_DBUS_SYM(DBusMessage *(*)(const char *, const char *, const char *, const char *), message_new_method_call);
|
||||
SDL_DBUS_SYM(dbus_bool_t (*)(DBusMessage *, int, ...), message_append_args);
|
||||
SDL_DBUS_SYM(dbus_bool_t (*)(DBusMessage *, int, va_list), message_append_args_valist);
|
||||
@@ -168,9 +170,9 @@ static void SDL_DBus_Init_Spinlocked(void)
|
||||
|
||||
void SDL_DBus_Init(void)
|
||||
{
|
||||
SDL_AtomicLock(&spinlock_dbus_init); /* make sure two threads can't init at same time, since this can happen before SDL_Init. */
|
||||
SDL_LockSpinlock(&spinlock_dbus_init); /* make sure two threads can't init at same time, since this can happen before SDL_Init. */
|
||||
SDL_DBus_Init_Spinlocked();
|
||||
SDL_AtomicUnlock(&spinlock_dbus_init);
|
||||
SDL_UnlockSpinlock(&spinlock_dbus_init);
|
||||
}
|
||||
|
||||
void SDL_DBus_Quit(void)
|
||||
|
||||
5
external/sdl/SDL/src/core/linux/SDL_dbus.h
vendored
5
external/sdl/SDL/src/core/linux/SDL_dbus.h
vendored
@@ -31,6 +31,9 @@
|
||||
#ifndef DBUS_TIMEOUT_USE_DEFAULT
|
||||
#define DBUS_TIMEOUT_USE_DEFAULT -1
|
||||
#endif
|
||||
#ifndef DBUS_TIMEOUT_INFINITE
|
||||
#define DBUS_TIMEOUT_INFINITE ((int) 0x7fffffff)
|
||||
#endif
|
||||
|
||||
typedef struct SDL_DBusContext
|
||||
{
|
||||
@@ -44,6 +47,7 @@ typedef struct SDL_DBusContext
|
||||
void (*connection_set_exit_on_disconnect)(DBusConnection *, dbus_bool_t);
|
||||
dbus_bool_t (*connection_get_is_connected)(DBusConnection *);
|
||||
dbus_bool_t (*connection_add_filter)(DBusConnection *, DBusHandleMessageFunction, void *, DBusFreeFunction);
|
||||
dbus_bool_t (*connection_remove_filter)(DBusConnection *, DBusHandleMessageFunction, void *);
|
||||
dbus_bool_t (*connection_try_register_object_path)(DBusConnection *, const char *,
|
||||
const DBusObjectPathVTable *, void *, DBusError *);
|
||||
dbus_bool_t (*connection_send)(DBusConnection *, DBusMessage *, dbus_uint32_t *);
|
||||
@@ -55,6 +59,7 @@ typedef struct SDL_DBusContext
|
||||
dbus_bool_t (*connection_read_write)(DBusConnection *, int);
|
||||
DBusDispatchStatus (*connection_dispatch)(DBusConnection *);
|
||||
dbus_bool_t (*message_is_signal)(DBusMessage *, const char *, const char *);
|
||||
dbus_bool_t (*message_has_path)(DBusMessage *, 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_valist)(DBusMessage *, int, va_list);
|
||||
|
||||
68
external/sdl/SDL/src/core/linux/SDL_evdev.c
vendored
68
external/sdl/SDL/src/core/linux/SDL_evdev.c
vendored
@@ -375,9 +375,9 @@ void SDL_EVDEV_Poll(void)
|
||||
scan_code = SDL_EVDEV_translate_keycode(event->code);
|
||||
if (scan_code != SDL_SCANCODE_UNKNOWN) {
|
||||
if (event->value == 0) {
|
||||
SDL_SendKeyboardKey(SDL_EVDEV_GetEventTimestamp(event), SDL_RELEASED, scan_code);
|
||||
SDL_SendKeyboardKey(SDL_EVDEV_GetEventTimestamp(event), (SDL_KeyboardID)item->fd, SDL_RELEASED, scan_code);
|
||||
} else if (event->value == 1 || event->value == 2 /* key repeated */) {
|
||||
SDL_SendKeyboardKey(SDL_EVDEV_GetEventTimestamp(event), SDL_PRESSED, scan_code);
|
||||
SDL_SendKeyboardKey(SDL_EVDEV_GetEventTimestamp(event), (SDL_KeyboardID)item->fd, SDL_PRESSED, scan_code);
|
||||
}
|
||||
}
|
||||
SDL_EVDEV_kbd_keycode(_this->kbd, event->code, event->value);
|
||||
@@ -395,7 +395,7 @@ void SDL_EVDEV_Poll(void)
|
||||
break;
|
||||
}
|
||||
if (event->value >= 0) {
|
||||
item->touchscreen_data->slots[item->touchscreen_data->current_slot].tracking_id = event->value;
|
||||
item->touchscreen_data->slots[item->touchscreen_data->current_slot].tracking_id = event->value + 1;
|
||||
item->touchscreen_data->slots[item->touchscreen_data->current_slot].delta = EVDEV_TOUCH_SLOTDELTA_DOWN;
|
||||
} else {
|
||||
item->touchscreen_data->slots[item->touchscreen_data->current_slot].delta = EVDEV_TOUCH_SLOTDELTA_UP;
|
||||
@@ -551,7 +551,7 @@ void SDL_EVDEV_Poll(void)
|
||||
break;
|
||||
case EVDEV_TOUCH_SLOTDELTA_UP:
|
||||
SDL_SendTouch(SDL_EVDEV_GetEventTimestamp(event), item->fd, item->touchscreen_data->slots[j].tracking_id, NULL, SDL_FALSE, norm_x, norm_y, norm_pressure);
|
||||
item->touchscreen_data->slots[j].tracking_id = -1;
|
||||
item->touchscreen_data->slots[j].tracking_id = 0;
|
||||
item->touchscreen_data->slots[j].delta = EVDEV_TOUCH_SLOTDELTA_NONE;
|
||||
break;
|
||||
case EVDEV_TOUCH_SLOTDELTA_MOVE:
|
||||
@@ -605,11 +605,34 @@ static SDL_Scancode SDL_EVDEV_translate_keycode(int keycode)
|
||||
return scancode;
|
||||
}
|
||||
|
||||
static int SDL_EVDEV_init_keyboard(SDL_evdevlist_item *item, int udev_class)
|
||||
{
|
||||
char name[128];
|
||||
|
||||
name[0] = '\0';
|
||||
ioctl(item->fd, EVIOCGNAME(sizeof(name)), name);
|
||||
|
||||
SDL_AddKeyboard((SDL_KeyboardID)item->fd, name, SDL_TRUE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void SDL_EVDEV_destroy_keyboard(SDL_evdevlist_item *item)
|
||||
{
|
||||
SDL_RemoveKeyboard((SDL_KeyboardID)item->fd);
|
||||
}
|
||||
|
||||
static int SDL_EVDEV_init_mouse(SDL_evdevlist_item *item, int udev_class)
|
||||
{
|
||||
char name[128];
|
||||
int ret;
|
||||
struct input_absinfo abs_info;
|
||||
|
||||
name[0] = '\0';
|
||||
ioctl(item->fd, EVIOCGNAME(sizeof(name)), name);
|
||||
|
||||
SDL_AddMouse((SDL_MouseID)item->fd, name, SDL_TRUE);
|
||||
|
||||
ret = ioctl(item->fd, EVIOCGABS(ABS_X), &abs_info);
|
||||
if (ret < 0) {
|
||||
// no absolute mode info, continue
|
||||
@@ -631,9 +654,14 @@ static int SDL_EVDEV_init_mouse(SDL_evdevlist_item *item, int udev_class)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void SDL_EVDEV_destroy_mouse(SDL_evdevlist_item *item)
|
||||
{
|
||||
SDL_RemoveMouse((SDL_MouseID)item->fd);
|
||||
}
|
||||
|
||||
static int SDL_EVDEV_init_touchscreen(SDL_evdevlist_item *item, int udev_class)
|
||||
{
|
||||
int ret, i;
|
||||
int ret;
|
||||
unsigned long xreq, yreq;
|
||||
char name[64];
|
||||
struct input_absinfo abs_info;
|
||||
@@ -715,10 +743,6 @@ static int SDL_EVDEV_init_touchscreen(SDL_evdevlist_item *item, int udev_class)
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < item->touchscreen_data->max_slots; i++) {
|
||||
item->touchscreen_data->slots[i].tracking_id = -1;
|
||||
}
|
||||
|
||||
ret = SDL_AddTouch(item->fd, /* I guess our fd is unique enough */
|
||||
(udev_class & SDL_UDEV_DEVICE_TOUCHPAD) ? SDL_TOUCH_DEVICE_INDIRECT_ABSOLUTE : SDL_TOUCH_DEVICE_DIRECT,
|
||||
item->touchscreen_data->name);
|
||||
@@ -792,13 +816,13 @@ static void SDL_EVDEV_sync_device(SDL_evdevlist_item *item)
|
||||
* SDL_EVDEV_Poll to tell SDL, the current structure of this code doesn't
|
||||
* allow it. Lets just pray to God it doesn't happen.
|
||||
*/
|
||||
if (item->touchscreen_data->slots[i].tracking_id < 0 &&
|
||||
if (item->touchscreen_data->slots[i].tracking_id == 0 &&
|
||||
mt_req_values[i] >= 0) {
|
||||
item->touchscreen_data->slots[i].tracking_id = mt_req_values[i];
|
||||
item->touchscreen_data->slots[i].tracking_id = mt_req_values[i] + 1;
|
||||
item->touchscreen_data->slots[i].delta = EVDEV_TOUCH_SLOTDELTA_DOWN;
|
||||
} else if (item->touchscreen_data->slots[i].tracking_id >= 0 &&
|
||||
} else if (item->touchscreen_data->slots[i].tracking_id != 0 &&
|
||||
mt_req_values[i] < 0) {
|
||||
item->touchscreen_data->slots[i].tracking_id = -1;
|
||||
item->touchscreen_data->slots[i].tracking_id = 0;
|
||||
item->touchscreen_data->slots[i].delta = EVDEV_TOUCH_SLOTDELTA_UP;
|
||||
}
|
||||
}
|
||||
@@ -810,7 +834,7 @@ static void SDL_EVDEV_sync_device(SDL_evdevlist_item *item)
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < item->touchscreen_data->max_slots; i++) {
|
||||
if (item->touchscreen_data->slots[i].tracking_id >= 0 &&
|
||||
if (item->touchscreen_data->slots[i].tracking_id != 0 &&
|
||||
item->touchscreen_data->slots[i].x != mt_req_values[i]) {
|
||||
item->touchscreen_data->slots[i].x = mt_req_values[i];
|
||||
if (item->touchscreen_data->slots[i].delta ==
|
||||
@@ -828,7 +852,7 @@ static void SDL_EVDEV_sync_device(SDL_evdevlist_item *item)
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < item->touchscreen_data->max_slots; i++) {
|
||||
if (item->touchscreen_data->slots[i].tracking_id >= 0 &&
|
||||
if (item->touchscreen_data->slots[i].tracking_id != 0 &&
|
||||
item->touchscreen_data->slots[i].y != mt_req_values[i]) {
|
||||
item->touchscreen_data->slots[i].y = mt_req_values[i];
|
||||
if (item->touchscreen_data->slots[i].delta ==
|
||||
@@ -846,7 +870,7 @@ static void SDL_EVDEV_sync_device(SDL_evdevlist_item *item)
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < item->touchscreen_data->max_slots; i++) {
|
||||
if (item->touchscreen_data->slots[i].tracking_id >= 0 &&
|
||||
if (item->touchscreen_data->slots[i].tracking_id != 0 &&
|
||||
item->touchscreen_data->slots[i].pressure != mt_req_values[i]) {
|
||||
item->touchscreen_data->slots[i].pressure = mt_req_values[i];
|
||||
if (item->touchscreen_data->slots[i].delta ==
|
||||
@@ -926,6 +950,14 @@ static int SDL_EVDEV_device_added(const char *dev_path, int udev_class)
|
||||
SDL_free(item);
|
||||
return ret;
|
||||
}
|
||||
} else if (udev_class & SDL_UDEV_DEVICE_KEYBOARD) {
|
||||
int ret = SDL_EVDEV_init_keyboard(item, udev_class);
|
||||
if (ret < 0) {
|
||||
close(item->fd);
|
||||
SDL_free(item->path);
|
||||
SDL_free(item);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_this->last) {
|
||||
@@ -961,6 +993,10 @@ static int SDL_EVDEV_device_removed(const char *dev_path)
|
||||
}
|
||||
if (item->is_touchscreen) {
|
||||
SDL_EVDEV_destroy_touchscreen(item);
|
||||
} else if (item->udev_class & SDL_UDEV_DEVICE_MOUSE) {
|
||||
SDL_EVDEV_destroy_mouse(item);
|
||||
} else if (item->udev_class & SDL_UDEV_DEVICE_KEYBOARD) {
|
||||
SDL_EVDEV_destroy_keyboard(item);
|
||||
}
|
||||
close(item->fd);
|
||||
SDL_free(item->path);
|
||||
|
||||
@@ -416,7 +416,7 @@ static void kbd_vt_update(SDL_EVDEV_keyboard_state *state)
|
||||
}
|
||||
ioctl(state->console_fd, VT_RELDISP, VT_ACKACQ);
|
||||
}
|
||||
SDL_AtomicCAS(&vt_signal_pending, signal_pending, VT_SIGNAL_NONE);
|
||||
SDL_AtomicCompareAndSwap(&vt_signal_pending, signal_pending, VT_SIGNAL_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
26
external/sdl/SDL/src/core/linux/SDL_fcitx.c
vendored
26
external/sdl/SDL/src/core/linux/SDL_fcitx.c
vendored
@@ -54,15 +54,15 @@ static FcitxClient fcitx_client;
|
||||
|
||||
static char *GetAppName(void)
|
||||
{
|
||||
#if defined(__LINUX__) || defined(__FREEBSD__)
|
||||
#if defined(SDL_PLATFORM_LINUX) || defined(SDL_PLATFORM_FREEBSD)
|
||||
char *spot;
|
||||
char procfile[1024];
|
||||
char linkfile[1024];
|
||||
int linksize;
|
||||
|
||||
#ifdef __LINUX__
|
||||
#ifdef SDL_PLATFORM_LINUX
|
||||
(void)SDL_snprintf(procfile, sizeof(procfile), "/proc/%d/exe", getpid());
|
||||
#elif defined(__FREEBSD__)
|
||||
#elif defined(SDL_PLATFORM_FREEBSD)
|
||||
(void)SDL_snprintf(procfile, sizeof(procfile), "/proc/%d/file", getpid());
|
||||
#endif
|
||||
linksize = readlink(procfile, linkfile, sizeof(linkfile) - 1);
|
||||
@@ -75,7 +75,7 @@ static char *GetAppName(void)
|
||||
return SDL_strdup(linkfile);
|
||||
}
|
||||
}
|
||||
#endif /* __LINUX__ || __FREEBSD__ */
|
||||
#endif /* SDL_PLATFORM_LINUX || SDL_PLATFORM_FREEBSD */
|
||||
|
||||
return SDL_strdup("SDL_App");
|
||||
}
|
||||
@@ -191,17 +191,7 @@ static DBusHandlerResult DBus_MessageFilter(DBusConnection *conn, DBusMessage *m
|
||||
dbus->message_iter_init(msg, &iter);
|
||||
dbus->message_iter_get_basic(&iter, &text);
|
||||
|
||||
if (text && *text) {
|
||||
char buf[SDL_TEXTINPUTEVENT_TEXT_SIZE];
|
||||
size_t text_bytes = SDL_strlen(text), i = 0;
|
||||
|
||||
while (i < text_bytes) {
|
||||
size_t sz = SDL_utf8strlcpy(buf, text + i, sizeof(buf));
|
||||
SDL_SendKeyboardText(buf);
|
||||
|
||||
i += sz;
|
||||
}
|
||||
}
|
||||
SDL_SendKeyboardText(text);
|
||||
|
||||
return DBUS_HANDLER_RESULT_HANDLED;
|
||||
}
|
||||
@@ -428,9 +418,9 @@ void SDL_Fcitx_UpdateTextRect(const SDL_Rect *rect)
|
||||
#ifdef SDL_VIDEO_DRIVER_X11
|
||||
{
|
||||
SDL_PropertiesID props = SDL_GetWindowProperties(focused_win);
|
||||
Display *x_disp = (Display *)SDL_GetProperty(props, SDL_PROPERTY_WINDOW_X11_DISPLAY_POINTER, NULL);
|
||||
int x_screen = SDL_GetNumberProperty(props, SDL_PROPERTY_WINDOW_X11_SCREEN_NUMBER, 0);
|
||||
Window x_win = SDL_GetNumberProperty(props, SDL_PROPERTY_WINDOW_X11_WINDOW_NUMBER, 0);
|
||||
Display *x_disp = (Display *)SDL_GetProperty(props, SDL_PROP_WINDOW_X11_DISPLAY_POINTER, NULL);
|
||||
int x_screen = SDL_GetNumberProperty(props, SDL_PROP_WINDOW_X11_SCREEN_NUMBER, 0);
|
||||
Window x_win = SDL_GetNumberProperty(props, SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0);
|
||||
Window unused;
|
||||
if (x_disp && x_win) {
|
||||
X11_XTranslateCoordinates(x_disp, x_win, RootWindow(x_disp, x_screen), 0, 0, &x, &y, &unused);
|
||||
|
||||
18
external/sdl/SDL/src/core/linux/SDL_ibus.c
vendored
18
external/sdl/SDL/src/core/linux/SDL_ibus.c
vendored
@@ -228,17 +228,7 @@ static DBusHandlerResult IBus_MessageHandler(DBusConnection *conn, DBusMessage *
|
||||
dbus->message_iter_init(msg, &iter);
|
||||
text = IBus_GetVariantText(conn, &iter, dbus);
|
||||
|
||||
if (text && *text) {
|
||||
char buf[SDL_TEXTINPUTEVENT_TEXT_SIZE];
|
||||
size_t text_bytes = SDL_strlen(text), i = 0;
|
||||
|
||||
while (i < text_bytes) {
|
||||
size_t sz = SDL_utf8strlcpy(buf, text + i, sizeof(buf));
|
||||
SDL_SendKeyboardText(buf);
|
||||
|
||||
i += sz;
|
||||
}
|
||||
}
|
||||
SDL_SendKeyboardText(text);
|
||||
|
||||
return DBUS_HANDLER_RESULT_HANDLED;
|
||||
}
|
||||
@@ -705,9 +695,9 @@ void SDL_IBus_UpdateTextRect(const SDL_Rect *rect)
|
||||
#ifdef SDL_VIDEO_DRIVER_X11
|
||||
{
|
||||
SDL_PropertiesID props = SDL_GetWindowProperties(focused_win);
|
||||
Display *x_disp = (Display *)SDL_GetProperty(props, SDL_PROPERTY_WINDOW_X11_DISPLAY_POINTER, NULL);
|
||||
int x_screen = SDL_GetNumberProperty(props, SDL_PROPERTY_WINDOW_X11_SCREEN_NUMBER, 0);
|
||||
Window x_win = SDL_GetNumberProperty(props, SDL_PROPERTY_WINDOW_X11_WINDOW_NUMBER, 0);
|
||||
Display *x_disp = (Display *)SDL_GetProperty(props, SDL_PROP_WINDOW_X11_DISPLAY_POINTER, NULL);
|
||||
int x_screen = SDL_GetNumberProperty(props, SDL_PROP_WINDOW_X11_SCREEN_NUMBER, 0);
|
||||
Window x_win = SDL_GetNumberProperty(props, SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0);
|
||||
Window unused;
|
||||
|
||||
if (x_disp && x_win) {
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
#include "SDL_dbus.h"
|
||||
#include "SDL_system_theme.h"
|
||||
#include "../SDL_sysvideo.h"
|
||||
#include "../../video/SDL_sysvideo.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifdef __LINUX__
|
||||
#ifdef SDL_PLATFORM_LINUX
|
||||
|
||||
#ifndef SDL_THREADS_DISABLED
|
||||
#include <sys/time.h>
|
||||
@@ -342,4 +342,4 @@ int SDL_LinuxSetThreadPriorityAndPolicy(Sint64 threadID, int sdlPriority, int sc
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* __LINUX__ */
|
||||
#endif /* SDL_PLATFORM_LINUX */
|
||||
|
||||
94
external/sdl/SDL/src/core/linux/SDL_udev.c
vendored
94
external/sdl/SDL/src/core/linux/SDL_udev.c
vendored
@@ -31,6 +31,7 @@
|
||||
#ifdef SDL_USE_LIBUDEV
|
||||
|
||||
#include <linux/input.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "SDL_evdev_capabilities.h"
|
||||
#include "../unix/SDL_poll.h"
|
||||
@@ -223,61 +224,59 @@ int SDL_UDEV_Scan(void)
|
||||
|
||||
SDL_bool SDL_UDEV_GetProductInfo(const char *device_path, Uint16 *vendor, Uint16 *product, Uint16 *version, int *class)
|
||||
{
|
||||
struct udev_enumerate *enumerate = NULL;
|
||||
struct udev_list_entry *devs = NULL;
|
||||
struct udev_list_entry *item = NULL;
|
||||
SDL_bool found = SDL_FALSE;
|
||||
struct stat statbuf;
|
||||
char type;
|
||||
struct udev_device *dev;
|
||||
const char* val;
|
||||
int class_temp;
|
||||
|
||||
if (!_this) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
enumerate = _this->syms.udev_enumerate_new(_this->udev);
|
||||
if (!enumerate) {
|
||||
SDL_SetError("udev_enumerate_new() failed");
|
||||
if (stat(device_path, &statbuf) == -1) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
_this->syms.udev_enumerate_scan_devices(enumerate);
|
||||
devs = _this->syms.udev_enumerate_get_list_entry(enumerate);
|
||||
for (item = devs; item && !found; item = _this->syms.udev_list_entry_get_next(item)) {
|
||||
const char *path = _this->syms.udev_list_entry_get_name(item);
|
||||
struct udev_device *dev = _this->syms.udev_device_new_from_syspath(_this->udev, path);
|
||||
if (dev) {
|
||||
const char *val = NULL;
|
||||
const char *existing_path;
|
||||
|
||||
existing_path = _this->syms.udev_device_get_devnode(dev);
|
||||
if (existing_path && SDL_strcmp(device_path, existing_path) == 0) {
|
||||
int class_temp;
|
||||
found = SDL_TRUE;
|
||||
|
||||
val = _this->syms.udev_device_get_property_value(dev, "ID_VENDOR_ID");
|
||||
if (val) {
|
||||
*vendor = (Uint16)SDL_strtol(val, NULL, 16);
|
||||
}
|
||||
|
||||
val = _this->syms.udev_device_get_property_value(dev, "ID_MODEL_ID");
|
||||
if (val) {
|
||||
*product = (Uint16)SDL_strtol(val, NULL, 16);
|
||||
}
|
||||
|
||||
val = _this->syms.udev_device_get_property_value(dev, "ID_REVISION");
|
||||
if (val) {
|
||||
*version = (Uint16)SDL_strtol(val, NULL, 16);
|
||||
}
|
||||
|
||||
class_temp = device_class(dev);
|
||||
if (class_temp) {
|
||||
*class = class_temp;
|
||||
}
|
||||
}
|
||||
_this->syms.udev_device_unref(dev);
|
||||
}
|
||||
if (S_ISBLK(statbuf.st_mode)) {
|
||||
type = 'b';
|
||||
}
|
||||
else if (S_ISCHR(statbuf.st_mode)) {
|
||||
type = 'c';
|
||||
}
|
||||
else {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
_this->syms.udev_enumerate_unref(enumerate);
|
||||
|
||||
return found;
|
||||
dev = _this->syms.udev_device_new_from_devnum(_this->udev, type, statbuf.st_rdev);
|
||||
|
||||
if (!dev) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
val = _this->syms.udev_device_get_property_value(dev, "ID_VENDOR_ID");
|
||||
if (val) {
|
||||
*vendor = (Uint16)SDL_strtol(val, NULL, 16);
|
||||
}
|
||||
|
||||
val = _this->syms.udev_device_get_property_value(dev, "ID_MODEL_ID");
|
||||
if (val) {
|
||||
*product = (Uint16)SDL_strtol(val, NULL, 16);
|
||||
}
|
||||
|
||||
val = _this->syms.udev_device_get_property_value(dev, "ID_REVISION");
|
||||
if (val) {
|
||||
*version = (Uint16)SDL_strtol(val, NULL, 16);
|
||||
}
|
||||
|
||||
class_temp = device_class(dev);
|
||||
if (class_temp) {
|
||||
*class = class_temp;
|
||||
}
|
||||
|
||||
_this->syms.udev_device_unref(dev);
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
void SDL_UDEV_UnloadLibrary(void)
|
||||
@@ -429,9 +428,8 @@ static int device_class(struct udev_device *dev)
|
||||
}
|
||||
|
||||
val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_ACCELEROMETER");
|
||||
if (SDL_GetHintBoolean(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, SDL_TRUE) &&
|
||||
val && SDL_strcmp(val, "1") == 0) {
|
||||
devclass |= SDL_UDEV_DEVICE_JOYSTICK;
|
||||
if (val && SDL_strcmp(val, "1") == 0) {
|
||||
devclass |= SDL_UDEV_DEVICE_ACCELEROMETER;
|
||||
}
|
||||
|
||||
val = _this->syms.udev_device_get_property_value(dev, "ID_INPUT_MOUSE");
|
||||
|
||||
2
external/sdl/SDL/src/core/n3ds/SDL_n3ds.c
vendored
2
external/sdl/SDL/src/core/n3ds/SDL_n3ds.c
vendored
@@ -21,7 +21,7 @@
|
||||
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifdef __3DS__
|
||||
#ifdef SDL_PLATFORM_3DS
|
||||
|
||||
#include <3ds.h>
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifdef __NGAGE__
|
||||
#ifdef SDL_PLATFORM_NGAGE
|
||||
|
||||
#include <e32std.h>
|
||||
#include <e32def.h>
|
||||
@@ -75,4 +75,4 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif // __NGAGE__
|
||||
#endif // SDL_PLATFORM_NGAGE
|
||||
|
||||
@@ -33,8 +33,9 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "../../events/SDL_events_c.h"
|
||||
#include "../../events/SDL_keyboard_c.h"
|
||||
|
||||
#ifdef __NetBSD__
|
||||
#ifdef SDL_PLATFORM_NETBSD
|
||||
#define KS_GROUP_Ascii KS_GROUP_Plain
|
||||
#define KS_Cmd_ScrollBack KS_Cmd_ScrollFastUp
|
||||
#define KS_Cmd_ScrollFwd KS_Cmd_ScrollFastDown
|
||||
@@ -224,7 +225,7 @@ static struct SDL_wscons_compose_tab_s
|
||||
{ { KS_asciicircum, KS_u }, KS_ucircumflex },
|
||||
{ { KS_grave, KS_u }, KS_ugrave },
|
||||
{ { KS_acute, KS_y }, KS_yacute },
|
||||
#ifndef __NetBSD__
|
||||
#ifndef SDL_PLATFORM_NETBSD
|
||||
{ { KS_dead_caron, KS_space }, KS_L2_caron },
|
||||
{ { KS_dead_caron, KS_S }, KS_L2_Scaron },
|
||||
{ { KS_dead_caron, KS_Z }, KS_L2_Zcaron },
|
||||
@@ -319,7 +320,7 @@ static struct wscons_keycode_to_SDL
|
||||
{ KS_f18, SDL_SCANCODE_F18 },
|
||||
{ KS_f19, SDL_SCANCODE_F19 },
|
||||
{ KS_f20, SDL_SCANCODE_F20 },
|
||||
#ifndef __NetBSD__
|
||||
#ifndef SDL_PLATFORM_NETBSD
|
||||
{ KS_f21, SDL_SCANCODE_F21 },
|
||||
{ KS_f22, SDL_SCANCODE_F22 },
|
||||
{ KS_f23, SDL_SCANCODE_F23 },
|
||||
@@ -388,6 +389,7 @@ static struct wscons_keycode_to_SDL
|
||||
typedef struct
|
||||
{
|
||||
int fd;
|
||||
SDL_KeyboardID keyboardID;
|
||||
struct wskbd_map_data keymap;
|
||||
int ledstate;
|
||||
int origledstate;
|
||||
@@ -420,14 +422,19 @@ static SDL_WSCONS_input_data *SDL_WSCONS_Init_Keyboard(const char *dev)
|
||||
SDL_WSCONS_input_data *input = (SDL_WSCONS_input_data *)SDL_calloc(1, sizeof(SDL_WSCONS_input_data));
|
||||
|
||||
if (!input) {
|
||||
return input;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
input->fd = open(dev, O_RDWR | O_NONBLOCK | O_CLOEXEC);
|
||||
if (input->fd == -1) {
|
||||
SDL_free(input);
|
||||
input = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
input->keyboardID = SDL_GetNextObjectID();
|
||||
SDL_AddKeyboard(input->keyboardID, NULL, SDL_FALSE);
|
||||
|
||||
input->keymap.map = SDL_calloc(sizeof(struct wscons_keymap), KS_NUMKEYCODES);
|
||||
if (!input->keymap.map) {
|
||||
SDL_free(input);
|
||||
@@ -553,22 +560,22 @@ static void Translate_to_keycode(SDL_WSCONS_input_data *input, int type, keysym_
|
||||
switch (keyDesc.command) {
|
||||
case KS_Cmd_ScrollBack:
|
||||
{
|
||||
SDL_SendKeyboardKey(0, type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, SDL_SCANCODE_PAGEUP);
|
||||
SDL_SendKeyboardKey(0, input->keyboardID, type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, SDL_SCANCODE_PAGEUP);
|
||||
return;
|
||||
}
|
||||
case KS_Cmd_ScrollFwd:
|
||||
{
|
||||
SDL_SendKeyboardKey(0, type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, SDL_SCANCODE_PAGEDOWN);
|
||||
SDL_SendKeyboardKey(0, input->keyboardID, type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, SDL_SCANCODE_PAGEDOWN);
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < sizeof(conversion_table) / sizeof(struct wscons_keycode_to_SDL); i++) {
|
||||
if (conversion_table[i].sourcekey == group[0]) {
|
||||
SDL_SendKeyboardKey(0, type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, conversion_table[i].targetKey);
|
||||
SDL_SendKeyboardKey(0, input->keyboardID, type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, conversion_table[i].targetKey);
|
||||
return;
|
||||
}
|
||||
}
|
||||
SDL_SendKeyboardKey(0, type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, SDL_SCANCODE_UNKNOWN);
|
||||
SDL_SendKeyboardKey(0, input->keyboardID, type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, SDL_SCANCODE_UNKNOWN);
|
||||
}
|
||||
|
||||
static void updateKeyboard(SDL_WSCONS_input_data *input)
|
||||
@@ -620,7 +627,7 @@ static void updateKeyboard(SDL_WSCONS_input_data *input)
|
||||
input->lockheldstate[2] = 1;
|
||||
break;
|
||||
}
|
||||
#ifndef __NetBSD__
|
||||
#ifndef SDL_PLATFORM_NETBSD
|
||||
case KS_Mode_Lock:
|
||||
{
|
||||
if (input->lockheldstate[3] >= 1) {
|
||||
@@ -728,7 +735,7 @@ static void updateKeyboard(SDL_WSCONS_input_data *input)
|
||||
input->lockheldstate[2] = 0;
|
||||
}
|
||||
} break;
|
||||
#ifndef __NetBSD__
|
||||
#ifndef SDL_PLATFORM_NETBSD
|
||||
case KS_Mode_Lock:
|
||||
{
|
||||
if (input->lockheldstate[3]) {
|
||||
@@ -802,13 +809,13 @@ static void updateKeyboard(SDL_WSCONS_input_data *input)
|
||||
} break;
|
||||
case WSCONS_EVENT_ALL_KEYS_UP:
|
||||
for (i = 0; i < SDL_NUM_SCANCODES; i++) {
|
||||
SDL_SendKeyboardKey(0, SDL_RELEASED, i);
|
||||
SDL_SendKeyboardKey(0, input->keyboardID, SDL_RELEASED, i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (input->type == WSKBD_TYPE_USB && events[i].value <= 0xE7)
|
||||
SDL_SendKeyboardKey(0, type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, (SDL_Scancode)events[i].value);
|
||||
SDL_SendKeyboardKey(0, input->keyboardID, type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, (SDL_Scancode)events[i].value);
|
||||
else
|
||||
Translate_to_keycode(input, type, events[i].value);
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
typedef struct SDL_WSCONS_mouse_input_data
|
||||
{
|
||||
int fd;
|
||||
SDL_MouseID mouseID;
|
||||
} SDL_WSCONS_mouse_input_data;
|
||||
|
||||
SDL_WSCONS_mouse_input_data *SDL_WSCONS_Init_Mouse()
|
||||
@@ -39,32 +40,36 @@ SDL_WSCONS_mouse_input_data *SDL_WSCONS_Init_Mouse()
|
||||
#ifdef WSMOUSEIO_SETVERSION
|
||||
int version = WSMOUSE_EVENT_VERSION;
|
||||
#endif
|
||||
SDL_WSCONS_mouse_input_data *mouseInputData = SDL_calloc(1, sizeof(SDL_WSCONS_mouse_input_data));
|
||||
SDL_WSCONS_mouse_input_data *input = SDL_calloc(1, sizeof(SDL_WSCONS_mouse_input_data));
|
||||
|
||||
if (!mouseInputData) {
|
||||
if (!input) {
|
||||
return NULL;
|
||||
}
|
||||
mouseInputData->fd = open("/dev/wsmouse", O_RDWR | O_NONBLOCK | O_CLOEXEC);
|
||||
if (mouseInputData->fd == -1) {
|
||||
SDL_free(mouseInputData);
|
||||
input->fd = open("/dev/wsmouse", O_RDWR | O_NONBLOCK | O_CLOEXEC);
|
||||
if (input->fd == -1) {
|
||||
SDL_free(input);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
input->mouseID = SDL_GetNextObjectID();
|
||||
SDL_AddMouse(input->mouseID, NULL, SDL_FALSE);
|
||||
|
||||
#ifdef WSMOUSEIO_SETMODE
|
||||
ioctl(mouseInputData->fd, WSMOUSEIO_SETMODE, WSMOUSE_COMPAT);
|
||||
ioctl(input->fd, WSMOUSEIO_SETMODE, WSMOUSE_COMPAT);
|
||||
#endif
|
||||
#ifdef WSMOUSEIO_SETVERSION
|
||||
ioctl(mouseInputData->fd, WSMOUSEIO_SETVERSION, &version);
|
||||
ioctl(input->fd, WSMOUSEIO_SETVERSION, &version);
|
||||
#endif
|
||||
return mouseInputData;
|
||||
return input;
|
||||
}
|
||||
|
||||
void updateMouse(SDL_WSCONS_mouse_input_data *inputData)
|
||||
void updateMouse(SDL_WSCONS_mouse_input_data *input)
|
||||
{
|
||||
struct wscons_event events[64];
|
||||
int n;
|
||||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
|
||||
if ((n = read(inputData->fd, events, sizeof(events))) > 0) {
|
||||
if ((n = read(input->fd, events, sizeof(events))) > 0) {
|
||||
int i;
|
||||
n /= sizeof(struct wscons_event);
|
||||
for (i = 0; i < n; i++) {
|
||||
@@ -74,13 +79,13 @@ void updateMouse(SDL_WSCONS_mouse_input_data *inputData)
|
||||
{
|
||||
switch (events[i].value) {
|
||||
case 0: /* Left Mouse Button. */
|
||||
SDL_SendMouseButton(0, mouse->focus, mouse->mouseID, SDL_PRESSED, SDL_BUTTON_LEFT);
|
||||
SDL_SendMouseButton(0, mouse->focus, input->mouseID, SDL_PRESSED, SDL_BUTTON_LEFT);
|
||||
break;
|
||||
case 1: /* Middle Mouse Button. */
|
||||
SDL_SendMouseButton(0, mouse->focus, mouse->mouseID, SDL_PRESSED, SDL_BUTTON_MIDDLE);
|
||||
SDL_SendMouseButton(0, mouse->focus, input->mouseID, SDL_PRESSED, SDL_BUTTON_MIDDLE);
|
||||
break;
|
||||
case 2: /* Right Mouse Button. */
|
||||
SDL_SendMouseButton(0, mouse->focus, mouse->mouseID, SDL_PRESSED, SDL_BUTTON_RIGHT);
|
||||
SDL_SendMouseButton(0, mouse->focus, input->mouseID, SDL_PRESSED, SDL_BUTTON_RIGHT);
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
@@ -88,34 +93,34 @@ void updateMouse(SDL_WSCONS_mouse_input_data *inputData)
|
||||
{
|
||||
switch (events[i].value) {
|
||||
case 0: /* Left Mouse Button. */
|
||||
SDL_SendMouseButton(0, mouse->focus, mouse->mouseID, SDL_RELEASED, SDL_BUTTON_LEFT);
|
||||
SDL_SendMouseButton(0, mouse->focus, input->mouseID, SDL_RELEASED, SDL_BUTTON_LEFT);
|
||||
break;
|
||||
case 1: /* Middle Mouse Button. */
|
||||
SDL_SendMouseButton(0, mouse->focus, mouse->mouseID, SDL_RELEASED, SDL_BUTTON_MIDDLE);
|
||||
SDL_SendMouseButton(0, mouse->focus, input->mouseID, SDL_RELEASED, SDL_BUTTON_MIDDLE);
|
||||
break;
|
||||
case 2: /* Right Mouse Button. */
|
||||
SDL_SendMouseButton(0, mouse->focus, mouse->mouseID, SDL_RELEASED, SDL_BUTTON_RIGHT);
|
||||
SDL_SendMouseButton(0, mouse->focus, input->mouseID, SDL_RELEASED, SDL_BUTTON_RIGHT);
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
case WSCONS_EVENT_MOUSE_DELTA_X:
|
||||
{
|
||||
SDL_SendMouseMotion(0, mouse->focus, mouse->mouseID, 1, (float)events[i].value, 0.0f);
|
||||
SDL_SendMouseMotion(0, mouse->focus, input->mouseID, 1, (float)events[i].value, 0.0f);
|
||||
break;
|
||||
}
|
||||
case WSCONS_EVENT_MOUSE_DELTA_Y:
|
||||
{
|
||||
SDL_SendMouseMotion(0, mouse->focus, mouse->mouseID, 1, 0.0f, -(float)events[i].value);
|
||||
SDL_SendMouseMotion(0, mouse->focus, input->mouseID, 1, 0.0f, -(float)events[i].value);
|
||||
break;
|
||||
}
|
||||
case WSCONS_EVENT_MOUSE_DELTA_W:
|
||||
{
|
||||
SDL_SendMouseWheel(0, mouse->focus, mouse->mouseID, events[i].value, 0, SDL_MOUSEWHEEL_NORMAL);
|
||||
SDL_SendMouseWheel(0, mouse->focus, input->mouseID, events[i].value, 0, SDL_MOUSEWHEEL_NORMAL);
|
||||
break;
|
||||
}
|
||||
case WSCONS_EVENT_MOUSE_DELTA_Z:
|
||||
{
|
||||
SDL_SendMouseWheel(0, mouse->focus, mouse->mouseID, 0, -events[i].value, SDL_MOUSEWHEEL_NORMAL);
|
||||
SDL_SendMouseWheel(0, mouse->focus, input->mouseID, 0, -events[i].value, SDL_MOUSEWHEEL_NORMAL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -123,11 +128,11 @@ void updateMouse(SDL_WSCONS_mouse_input_data *inputData)
|
||||
}
|
||||
}
|
||||
|
||||
void SDL_WSCONS_Quit_Mouse(SDL_WSCONS_mouse_input_data *inputData)
|
||||
void SDL_WSCONS_Quit_Mouse(SDL_WSCONS_mouse_input_data *input)
|
||||
{
|
||||
if (!inputData) {
|
||||
if (!input) {
|
||||
return;
|
||||
}
|
||||
close(inputData->fd);
|
||||
SDL_free(inputData);
|
||||
close(input->fd);
|
||||
SDL_free(input);
|
||||
}
|
||||
|
||||
4
external/sdl/SDL/src/core/ps2/SDL_ps2.c
vendored
4
external/sdl/SDL/src/core/ps2/SDL_ps2.c
vendored
@@ -21,7 +21,7 @@
|
||||
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifdef __PS2__
|
||||
#ifdef SDL_PLATFORM_PS2
|
||||
|
||||
/* SDL_RunApp() code for PS2 based on SDL_ps2_main.c, fjtrujy@gmail.com */
|
||||
|
||||
@@ -82,4 +82,4 @@ SDL_RunApp(int argc, char* argv[], SDL_main_func mainFunction, void * reserved)
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif /* __PS2__ */
|
||||
#endif /* SDL_PLATFORM_PS2 */
|
||||
|
||||
4
external/sdl/SDL/src/core/psp/SDL_psp.c
vendored
4
external/sdl/SDL/src/core/psp/SDL_psp.c
vendored
@@ -21,7 +21,7 @@
|
||||
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifdef __PSP__
|
||||
#ifdef SDL_PLATFORM_PSP
|
||||
|
||||
/* SDL_RunApp() for PSP based on SDL_psp_main.c, placed in the public domain by Sam Lantinga 3/13/14 */
|
||||
|
||||
@@ -79,4 +79,4 @@ SDL_RunApp(int argc, char* argv[], SDL_main_func mainFunction, void * reserved)
|
||||
return mainFunction(argc, argv);
|
||||
}
|
||||
|
||||
#endif /* __PSP__ */
|
||||
#endif /* SDL_PLATFORM_PSP */
|
||||
|
||||
8
external/sdl/SDL/src/core/unix/SDL_appid.c
vendored
8
external/sdl/SDL/src/core/unix/SDL_appid.c
vendored
@@ -30,15 +30,15 @@ const char *SDL_GetExeName()
|
||||
|
||||
/* TODO: Use a fallback if BSD has no mounted procfs (OpenBSD has no procfs at all) */
|
||||
if (!proc_name) {
|
||||
#if defined(__LINUX__) || defined(__FREEBSD__) || defined (__NETBSD__)
|
||||
#if defined(SDL_PLATFORM_LINUX) || defined(SDL_PLATFORM_FREEBSD) || defined (SDL_PLATFORM_NETBSD)
|
||||
static char linkfile[1024];
|
||||
int linksize;
|
||||
|
||||
#if defined(__LINUX__)
|
||||
#if defined(SDL_PLATFORM_LINUX)
|
||||
const char *proc_path = "/proc/self/exe";
|
||||
#elif defined(__FREEBSD__)
|
||||
#elif defined(SDL_PLATFORM_FREEBSD)
|
||||
const char *proc_path = "/proc/curproc/file";
|
||||
#elif defined(__NETBSD__)
|
||||
#elif defined(SDL_PLATFORM_NETBSD)
|
||||
const char *proc_path = "/proc/curproc/exe";
|
||||
#endif
|
||||
linksize = readlink(proc_path, linkfile, sizeof(linkfile) - 1);
|
||||
|
||||
176
external/sdl/SDL/src/core/windows/SDL_hid.c
vendored
176
external/sdl/SDL/src/core/windows/SDL_hid.c
vendored
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifndef __WINRT__
|
||||
#ifndef SDL_PLATFORM_WINRT
|
||||
|
||||
#include "SDL_hid.h"
|
||||
|
||||
@@ -35,6 +35,7 @@ HidP_GetData_t SDL_HidP_GetData;
|
||||
static HMODULE s_pHIDDLL = 0;
|
||||
static int s_HIDDLLRefCount = 0;
|
||||
|
||||
|
||||
int WIN_LoadHIDDLL(void)
|
||||
{
|
||||
if (s_pHIDDLL) {
|
||||
@@ -81,4 +82,175 @@ void WIN_UnloadHIDDLL(void)
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* !__WINRT__ */
|
||||
#endif /* !SDL_PLATFORM_WINRT */
|
||||
|
||||
#if !defined(SDL_PLATFORM_WINRT) && !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
|
||||
|
||||
/* CM_Register_Notification definitions */
|
||||
|
||||
#define CR_SUCCESS 0
|
||||
|
||||
DECLARE_HANDLE(HCMNOTIFICATION);
|
||||
typedef HCMNOTIFICATION *PHCMNOTIFICATION;
|
||||
|
||||
typedef enum _CM_NOTIFY_FILTER_TYPE
|
||||
{
|
||||
CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE = 0,
|
||||
CM_NOTIFY_FILTER_TYPE_DEVICEHANDLE,
|
||||
CM_NOTIFY_FILTER_TYPE_DEVICEINSTANCE,
|
||||
CM_NOTIFY_FILTER_TYPE_MAX
|
||||
} CM_NOTIFY_FILTER_TYPE, *PCM_NOTIFY_FILTER_TYPE;
|
||||
|
||||
typedef struct _CM_NOTIFY_FILTER
|
||||
{
|
||||
DWORD cbSize;
|
||||
DWORD Flags;
|
||||
CM_NOTIFY_FILTER_TYPE FilterType;
|
||||
DWORD Reserved;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
GUID ClassGuid;
|
||||
} DeviceInterface;
|
||||
struct
|
||||
{
|
||||
HANDLE hTarget;
|
||||
} DeviceHandle;
|
||||
struct
|
||||
{
|
||||
WCHAR InstanceId[200];
|
||||
} DeviceInstance;
|
||||
} u;
|
||||
} CM_NOTIFY_FILTER, *PCM_NOTIFY_FILTER;
|
||||
|
||||
typedef enum _CM_NOTIFY_ACTION
|
||||
{
|
||||
CM_NOTIFY_ACTION_DEVICEINTERFACEARRIVAL = 0,
|
||||
CM_NOTIFY_ACTION_DEVICEINTERFACEREMOVAL,
|
||||
CM_NOTIFY_ACTION_DEVICEQUERYREMOVE,
|
||||
CM_NOTIFY_ACTION_DEVICEQUERYREMOVEFAILED,
|
||||
CM_NOTIFY_ACTION_DEVICEREMOVEPENDING,
|
||||
CM_NOTIFY_ACTION_DEVICEREMOVECOMPLETE,
|
||||
CM_NOTIFY_ACTION_DEVICECUSTOMEVENT,
|
||||
CM_NOTIFY_ACTION_DEVICEINSTANCEENUMERATED,
|
||||
CM_NOTIFY_ACTION_DEVICEINSTANCESTARTED,
|
||||
CM_NOTIFY_ACTION_DEVICEINSTANCEREMOVED,
|
||||
CM_NOTIFY_ACTION_MAX
|
||||
} CM_NOTIFY_ACTION, *PCM_NOTIFY_ACTION;
|
||||
|
||||
typedef struct _CM_NOTIFY_EVENT_DATA
|
||||
{
|
||||
CM_NOTIFY_FILTER_TYPE FilterType;
|
||||
DWORD Reserved;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
GUID ClassGuid;
|
||||
WCHAR SymbolicLink[ANYSIZE_ARRAY];
|
||||
} DeviceInterface;
|
||||
struct
|
||||
{
|
||||
GUID EventGuid;
|
||||
LONG NameOffset;
|
||||
DWORD DataSize;
|
||||
BYTE Data[ANYSIZE_ARRAY];
|
||||
} DeviceHandle;
|
||||
struct
|
||||
{
|
||||
WCHAR InstanceId[ANYSIZE_ARRAY];
|
||||
} DeviceInstance;
|
||||
} u;
|
||||
} CM_NOTIFY_EVENT_DATA, *PCM_NOTIFY_EVENT_DATA;
|
||||
|
||||
typedef DWORD (CALLBACK *PCM_NOTIFY_CALLBACK)(HCMNOTIFICATION hNotify, PVOID Context, CM_NOTIFY_ACTION Action, PCM_NOTIFY_EVENT_DATA EventData, DWORD EventDataSize);
|
||||
|
||||
typedef DWORD (WINAPI *CM_Register_NotificationFunc)(PCM_NOTIFY_FILTER pFilter, PVOID pContext, PCM_NOTIFY_CALLBACK pCallback, PHCMNOTIFICATION pNotifyContext);
|
||||
typedef DWORD (WINAPI *CM_Unregister_NotificationFunc)(HCMNOTIFICATION NotifyContext);
|
||||
|
||||
static GUID GUID_DEVINTERFACE_HID = { 0x4D1E55B2L, 0xF16F, 0x11CF, { 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } };
|
||||
|
||||
static int s_DeviceNotificationsRequested;
|
||||
static HMODULE cfgmgr32_lib_handle;
|
||||
static CM_Register_NotificationFunc CM_Register_Notification;
|
||||
static CM_Unregister_NotificationFunc CM_Unregister_Notification;
|
||||
static HCMNOTIFICATION s_DeviceNotificationFuncHandle;
|
||||
static Uint64 s_LastDeviceNotification = 1;
|
||||
|
||||
static DWORD CALLBACK SDL_DeviceNotificationFunc(HCMNOTIFICATION hNotify, PVOID context, CM_NOTIFY_ACTION action, PCM_NOTIFY_EVENT_DATA eventData, DWORD event_data_size)
|
||||
{
|
||||
if (action == CM_NOTIFY_ACTION_DEVICEINTERFACEARRIVAL ||
|
||||
action == CM_NOTIFY_ACTION_DEVICEINTERFACEREMOVAL) {
|
||||
s_LastDeviceNotification = SDL_GetTicksNS();
|
||||
}
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
void WIN_InitDeviceNotification(void)
|
||||
{
|
||||
++s_DeviceNotificationsRequested;
|
||||
if (s_DeviceNotificationsRequested > 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
cfgmgr32_lib_handle = LoadLibraryA("cfgmgr32.dll");
|
||||
if (cfgmgr32_lib_handle) {
|
||||
CM_Register_Notification = (CM_Register_NotificationFunc)GetProcAddress(cfgmgr32_lib_handle, "CM_Register_Notification");
|
||||
CM_Unregister_Notification = (CM_Unregister_NotificationFunc)GetProcAddress(cfgmgr32_lib_handle, "CM_Unregister_Notification");
|
||||
if (CM_Register_Notification && CM_Unregister_Notification) {
|
||||
CM_NOTIFY_FILTER notify_filter;
|
||||
|
||||
SDL_zero(notify_filter);
|
||||
notify_filter.cbSize = sizeof(notify_filter);
|
||||
notify_filter.FilterType = CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE;
|
||||
notify_filter.u.DeviceInterface.ClassGuid = GUID_DEVINTERFACE_HID;
|
||||
if (CM_Register_Notification(¬ify_filter, NULL, SDL_DeviceNotificationFunc, &s_DeviceNotificationFuncHandle) == CR_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Should we log errors?
|
||||
}
|
||||
|
||||
Uint64 WIN_GetLastDeviceNotification(void)
|
||||
{
|
||||
return s_LastDeviceNotification;
|
||||
}
|
||||
|
||||
void WIN_QuitDeviceNotification(void)
|
||||
{
|
||||
if (--s_DeviceNotificationsRequested > 0) {
|
||||
return;
|
||||
}
|
||||
/* Make sure we have balanced calls to init/quit */
|
||||
SDL_assert(s_DeviceNotificationsRequested == 0);
|
||||
|
||||
if (cfgmgr32_lib_handle) {
|
||||
if (s_DeviceNotificationFuncHandle && CM_Unregister_Notification) {
|
||||
CM_Unregister_Notification(s_DeviceNotificationFuncHandle);
|
||||
s_DeviceNotificationFuncHandle = NULL;
|
||||
}
|
||||
|
||||
FreeLibrary(cfgmgr32_lib_handle);
|
||||
cfgmgr32_lib_handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void WIN_InitDeviceNotification(void)
|
||||
{
|
||||
}
|
||||
|
||||
Uint64 WIN_GetLastDeviceNotification( void )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WIN_QuitDeviceNotification(void)
|
||||
{
|
||||
}
|
||||
|
||||
#endif // !SDL_PLATFORM_WINRT && !SDL_PLATFORM_XBOXONE && !SDL_PLATFORM_XBOXSERIES
|
||||
|
||||
21
external/sdl/SDL/src/core/windows/SDL_hid.h
vendored
21
external/sdl/SDL/src/core/windows/SDL_hid.h
vendored
@@ -25,7 +25,7 @@
|
||||
|
||||
#include "SDL_windows.h"
|
||||
|
||||
#ifndef __WINRT__
|
||||
#ifndef SDL_PLATFORM_WINRT
|
||||
|
||||
typedef LONG NTSTATUS;
|
||||
typedef USHORT USAGE;
|
||||
@@ -193,12 +193,12 @@ typedef struct
|
||||
extern int WIN_LoadHIDDLL(void);
|
||||
extern void WIN_UnloadHIDDLL(void);
|
||||
|
||||
typedef BOOLEAN(WINAPI *HidD_GetString_t)(HANDLE HidDeviceObject, PVOID Buffer, ULONG BufferLength);
|
||||
typedef NTSTATUS(WINAPI *HidP_GetCaps_t)(PHIDP_PREPARSED_DATA PreparsedData, PHIDP_CAPS Capabilities);
|
||||
typedef NTSTATUS(WINAPI *HidP_GetButtonCaps_t)(HIDP_REPORT_TYPE ReportType, PHIDP_BUTTON_CAPS ButtonCaps, PUSHORT ButtonCapsLength, PHIDP_PREPARSED_DATA PreparsedData);
|
||||
typedef NTSTATUS(WINAPI *HidP_GetValueCaps_t)(HIDP_REPORT_TYPE ReportType, PHIDP_VALUE_CAPS ValueCaps, PUSHORT ValueCapsLength, PHIDP_PREPARSED_DATA PreparsedData);
|
||||
typedef ULONG(WINAPI *HidP_MaxDataListLength_t)(HIDP_REPORT_TYPE ReportType, PHIDP_PREPARSED_DATA PreparsedData);
|
||||
typedef NTSTATUS(WINAPI *HidP_GetData_t)(HIDP_REPORT_TYPE ReportType, PHIDP_DATA DataList, PULONG DataLength, PHIDP_PREPARSED_DATA PreparsedData, PCHAR Report, ULONG ReportLength);
|
||||
typedef BOOLEAN (WINAPI *HidD_GetString_t)(HANDLE HidDeviceObject, PVOID Buffer, ULONG BufferLength);
|
||||
typedef NTSTATUS (WINAPI *HidP_GetCaps_t)(PHIDP_PREPARSED_DATA PreparsedData, PHIDP_CAPS Capabilities);
|
||||
typedef NTSTATUS (WINAPI *HidP_GetButtonCaps_t)(HIDP_REPORT_TYPE ReportType, PHIDP_BUTTON_CAPS ButtonCaps, PUSHORT ButtonCapsLength, PHIDP_PREPARSED_DATA PreparsedData);
|
||||
typedef NTSTATUS (WINAPI *HidP_GetValueCaps_t)(HIDP_REPORT_TYPE ReportType, PHIDP_VALUE_CAPS ValueCaps, PUSHORT ValueCapsLength, PHIDP_PREPARSED_DATA PreparsedData);
|
||||
typedef ULONG (WINAPI *HidP_MaxDataListLength_t)(HIDP_REPORT_TYPE ReportType, PHIDP_PREPARSED_DATA PreparsedData);
|
||||
typedef NTSTATUS (WINAPI *HidP_GetData_t)(HIDP_REPORT_TYPE ReportType, PHIDP_DATA DataList, PULONG DataLength, PHIDP_PREPARSED_DATA PreparsedData, PCHAR Report, ULONG ReportLength);
|
||||
|
||||
extern HidD_GetString_t SDL_HidD_GetManufacturerString;
|
||||
extern HidD_GetString_t SDL_HidD_GetProductString;
|
||||
@@ -208,6 +208,11 @@ extern HidP_GetValueCaps_t SDL_HidP_GetValueCaps;
|
||||
extern HidP_MaxDataListLength_t SDL_HidP_MaxDataListLength;
|
||||
extern HidP_GetData_t SDL_HidP_GetData;
|
||||
|
||||
#endif /* !__WINRT__ */
|
||||
#endif /* !SDL_PLATFORM_WINRT */
|
||||
|
||||
|
||||
void WIN_InitDeviceNotification(void);
|
||||
Uint64 WIN_GetLastDeviceNotification(void);
|
||||
void WIN_QuitDeviceNotification(void);
|
||||
|
||||
#endif /* SDL_hid_h_ */
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#if (defined(__WIN32__) || defined(__GDK__)) && defined(HAVE_MMDEVICEAPI_H)
|
||||
#if (defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_GDK)) && defined(HAVE_MMDEVICEAPI_H)
|
||||
|
||||
#include "SDL_windows.h"
|
||||
#include "SDL_immdevice.h"
|
||||
@@ -147,7 +147,7 @@ static SDL_AudioDevice *SDL_IMMDevice_Add(const SDL_bool iscapture, const char *
|
||||
|
||||
if (!device) {
|
||||
// handle is freed by SDL_IMMDevice_FreeDeviceHandle!
|
||||
SDL_IMMDevice_HandleData *handle = SDL_malloc(sizeof(SDL_IMMDevice_HandleData));
|
||||
SDL_IMMDevice_HandleData *handle = (SDL_IMMDevice_HandleData *)SDL_malloc(sizeof(SDL_IMMDevice_HandleData));
|
||||
if (!handle) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -429,4 +429,4 @@ void SDL_IMMDevice_EnumerateEndpoints(SDL_AudioDevice **default_output, SDL_Audi
|
||||
IMMDeviceEnumerator_RegisterEndpointNotificationCallback(enumerator, (IMMNotificationClient *)¬ification_client);
|
||||
}
|
||||
|
||||
#endif /* (defined(__WIN32__) || defined(__GDK__)) && defined(HAVE_MMDEVICEAPI_H) */
|
||||
#endif /* (defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_GDK)) && defined(HAVE_MMDEVICEAPI_H) */
|
||||
|
||||
131
external/sdl/SDL/src/core/windows/SDL_windows.c
vendored
131
external/sdl/SDL/src/core/windows/SDL_windows.c
vendored
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#if defined(__WIN32__) || defined(__WINRT__) || defined(__GDK__)
|
||||
#if defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_WINRT) || defined(SDL_PLATFORM_GDK)
|
||||
|
||||
#include "SDL_windows.h"
|
||||
|
||||
@@ -49,6 +49,10 @@ typedef enum RO_INIT_TYPE
|
||||
#define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800
|
||||
#endif
|
||||
|
||||
#ifndef WC_ERR_INVALID_CHARS
|
||||
#define WC_ERR_INVALID_CHARS 0x00000080
|
||||
#endif
|
||||
|
||||
/* Sets an error message based on an HRESULT */
|
||||
int WIN_SetErrorFromHRESULT(const char *prefix, HRESULT hr)
|
||||
{
|
||||
@@ -86,14 +90,14 @@ WIN_CoInitialize(void)
|
||||
|
||||
If you need multi-threaded mode, call CoInitializeEx() before SDL_Init()
|
||||
*/
|
||||
#ifdef __WINRT__
|
||||
#ifdef SDL_PLATFORM_WINRT
|
||||
/* DLudwig: On WinRT, it is assumed that COM was initialized in main().
|
||||
CoInitializeEx is available (not CoInitialize though), however
|
||||
on WinRT, main() is typically declared with the [MTAThread]
|
||||
attribute, which, AFAIK, should initialize COM.
|
||||
*/
|
||||
return S_OK;
|
||||
#elif defined(__XBOXONE__) || defined(__XBOXSERIES__)
|
||||
#elif defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)
|
||||
/* On Xbox, there's no need to call CoInitializeEx (and it's not implemented) */
|
||||
return S_OK;
|
||||
#else
|
||||
@@ -114,13 +118,13 @@ WIN_CoInitialize(void)
|
||||
|
||||
void WIN_CoUninitialize(void)
|
||||
{
|
||||
#ifndef __WINRT__
|
||||
#ifndef SDL_PLATFORM_WINRT
|
||||
CoUninitialize();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef __WINRT__
|
||||
void *WIN_LoadComBaseFunction(const char *name)
|
||||
#ifndef SDL_PLATFORM_WINRT
|
||||
FARPROC WIN_LoadComBaseFunction(const char *name)
|
||||
{
|
||||
static SDL_bool s_bLoaded;
|
||||
static HMODULE s_hComBase;
|
||||
@@ -140,7 +144,7 @@ void *WIN_LoadComBaseFunction(const char *name)
|
||||
HRESULT
|
||||
WIN_RoInitialize(void)
|
||||
{
|
||||
#ifdef __WINRT__
|
||||
#ifdef SDL_PLATFORM_WINRT
|
||||
return S_OK;
|
||||
#else
|
||||
typedef HRESULT(WINAPI * RoInitialize_t)(RO_INIT_TYPE initType);
|
||||
@@ -167,7 +171,7 @@ WIN_RoInitialize(void)
|
||||
|
||||
void WIN_RoUninitialize(void)
|
||||
{
|
||||
#ifndef __WINRT__
|
||||
#ifndef SDL_PLATFORM_WINRT
|
||||
typedef void(WINAPI * RoUninitialize_t)(void);
|
||||
RoUninitialize_t RoUninitializeFunc = (RoUninitialize_t)WIN_LoadComBaseFunction("RoUninitialize");
|
||||
if (RoUninitializeFunc) {
|
||||
@@ -176,7 +180,7 @@ void WIN_RoUninitialize(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(__WINRT__) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
|
||||
#if !defined(SDL_PLATFORM_WINRT) && !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
|
||||
static BOOL IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor)
|
||||
{
|
||||
OSVERSIONINFOEXW osvi;
|
||||
@@ -197,33 +201,47 @@ static BOOL IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WO
|
||||
}
|
||||
#endif
|
||||
|
||||
// apply some static variables so we only call into the Win32 API once per process for each check.
|
||||
#if defined(SDL_PLATFORM_WINRT) || defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)
|
||||
#define CHECKWINVER(notdesktop_platform_result, test) return (notdesktop_platform_result);
|
||||
#else
|
||||
#define CHECKWINVER(notdesktop_platform_result, test) \
|
||||
static SDL_bool checked = SDL_FALSE; \
|
||||
static BOOL retval = FALSE; \
|
||||
if (!checked) { \
|
||||
retval = (test); \
|
||||
checked = SDL_TRUE; \
|
||||
} \
|
||||
return retval;
|
||||
#endif
|
||||
|
||||
// this is the oldest thing we run on (and we may lose support for this in SDL3 at any time!),
|
||||
// so there's no "OrGreater" as that would always be TRUE. The other functions are here to
|
||||
// ask "can we support a specific feature?" but this function is here to ask "do we need to do
|
||||
// something different for an OS version we probably should abandon?" :)
|
||||
BOOL WIN_IsWindowsXP(void)
|
||||
{
|
||||
CHECKWINVER(FALSE, !WIN_IsWindowsVistaOrGreater() && IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP), LOBYTE(_WIN32_WINNT_WINXP), 0));
|
||||
}
|
||||
|
||||
BOOL WIN_IsWindowsVistaOrGreater(void)
|
||||
{
|
||||
#if defined(__WINRT__) || defined(__XBOXONE__) || defined(__XBOXSERIES__)
|
||||
return TRUE;
|
||||
#else
|
||||
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 0);
|
||||
#endif
|
||||
CHECKWINVER(TRUE, IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), LOBYTE(_WIN32_WINNT_VISTA), 0));
|
||||
}
|
||||
|
||||
BOOL WIN_IsWindows7OrGreater(void)
|
||||
{
|
||||
#if defined(__WINRT__) || defined(__XBOXONE__) || defined(__XBOXSERIES__)
|
||||
return TRUE;
|
||||
#else
|
||||
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 0);
|
||||
#endif
|
||||
CHECKWINVER(TRUE, IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), LOBYTE(_WIN32_WINNT_WIN7), 0));
|
||||
}
|
||||
|
||||
BOOL WIN_IsWindows8OrGreater(void)
|
||||
{
|
||||
#if defined(__WINRT__) || defined(__XBOXONE__) || defined(__XBOXSERIES__)
|
||||
return TRUE;
|
||||
#else
|
||||
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN8), LOBYTE(_WIN32_WINNT_WIN8), 0);
|
||||
#endif
|
||||
CHECKWINVER(TRUE, IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN8), LOBYTE(_WIN32_WINNT_WIN8), 0));
|
||||
}
|
||||
|
||||
#undef CHECKWINVER
|
||||
|
||||
|
||||
/*
|
||||
WAVExxxCAPS gives you 31 bytes for the device name, and just truncates if it's
|
||||
longer. However, since WinXP, you can use the WAVExxxCAPS2 structure, which
|
||||
@@ -247,7 +265,7 @@ WASAPI doesn't need this. This is just for DirectSound/WinMM.
|
||||
*/
|
||||
char *WIN_LookupAudioDeviceName(const WCHAR *name, const GUID *guid)
|
||||
{
|
||||
#if defined(__WINRT__) || defined(__XBOXONE__) || defined(__XBOXSERIES__)
|
||||
#if defined(SDL_PLATFORM_WINRT) || defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)
|
||||
return WIN_StringToUTF8(name); /* No registry access on WinRT/UWP and Xbox, go with what we've got. */
|
||||
#else
|
||||
static const GUID nullguid = { 0 };
|
||||
@@ -300,7 +318,7 @@ char *WIN_LookupAudioDeviceName(const WCHAR *name, const GUID *guid)
|
||||
retval = WIN_StringToUTF8(strw);
|
||||
SDL_free(strw);
|
||||
return retval ? retval : WIN_StringToUTF8(name);
|
||||
#endif /* if __WINRT__ / else */
|
||||
#endif /* if SDL_PLATFORM_WINRT / else */
|
||||
}
|
||||
|
||||
BOOL WIN_IsEqualGUID(const GUID *a, const GUID *b)
|
||||
@@ -362,9 +380,19 @@ SDL_AudioFormat SDL_WaveFormatExToSDLFormat(WAVEFORMATEX *waveformat)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int WIN_WideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWCH lpWideCharStr, int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, LPCCH lpDefaultChar, LPBOOL lpUsedDefaultChar)
|
||||
{
|
||||
if (WIN_IsWindowsXP()) {
|
||||
dwFlags &= ~WC_ERR_INVALID_CHARS; // not supported before Vista. Without this flag, it will just replace bogus chars with U+FFFD. You're on your own, WinXP.
|
||||
}
|
||||
return WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, lpMultiByteStr, cbMultiByte, lpDefaultChar, lpUsedDefaultChar);
|
||||
}
|
||||
|
||||
|
||||
/* Win32-specific SDL_RunApp(), which does most of the SDL_main work,
|
||||
based on SDL_windows_main.c, placed in the public domain by Sam Lantinga 4/13/98 */
|
||||
#ifdef __WIN32__
|
||||
#ifdef SDL_PLATFORM_WIN32
|
||||
|
||||
#include <shellapi.h> /* CommandLineToArgvW() */
|
||||
|
||||
@@ -433,51 +461,6 @@ DECLSPEC int MINGW32_FORCEALIGN SDL_RunApp(int _argc, char* _argv[], SDL_main_fu
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* __WIN32__ */
|
||||
#endif /* SDL_PLATFORM_WIN32 */
|
||||
|
||||
#endif /* defined(__WIN32__) || defined(__WINRT__) || defined(__GDK__) */
|
||||
|
||||
/*
|
||||
* Public APIs
|
||||
*/
|
||||
#ifndef SDL_VIDEO_DRIVER_WINDOWS
|
||||
|
||||
#if defined(__WIN32__) || defined(__GDK__)
|
||||
int SDL_RegisterApp(const char *name, Uint32 style, void *hInst)
|
||||
{
|
||||
(void)name;
|
||||
(void)style;
|
||||
(void)hInst;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SDL_UnregisterApp(void)
|
||||
{
|
||||
}
|
||||
|
||||
void SDL_SetWindowsMessageHook(SDL_WindowsMessageHook callback, void *userdata)
|
||||
{
|
||||
}
|
||||
#endif /* __WIN32__ || __GDK__ */
|
||||
|
||||
#if defined(__WIN32__) || defined(__WINGDK__)
|
||||
int SDL_Direct3D9GetAdapterIndex(SDL_DisplayID displayID)
|
||||
{
|
||||
(void)displayID;
|
||||
return 0; /* D3DADAPTER_DEFAULT */
|
||||
}
|
||||
|
||||
SDL_bool SDL_DXGIGetOutputInfo(SDL_DisplayID displayID, int *adapterIndex, int *outputIndex)
|
||||
{
|
||||
(void)displayID;
|
||||
if (adapterIndex) {
|
||||
*adapterIndex = -1;
|
||||
}
|
||||
if (outputIndex) {
|
||||
*outputIndex = -1;
|
||||
}
|
||||
return SDL_FALSE;
|
||||
}
|
||||
#endif /* __WIN32__ || __WINGDK__ */
|
||||
|
||||
#endif /* !SDL_VIDEO_DRIVER_WINDOWS */
|
||||
#endif /* defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_WINRT) || defined(SDL_PLATFORM_GDK) */
|
||||
|
||||
28
external/sdl/SDL/src/core/windows/SDL_windows.h
vendored
28
external/sdl/SDL/src/core/windows/SDL_windows.h
vendored
@@ -24,7 +24,7 @@
|
||||
#ifndef _INCLUDED_WINDOWS_H
|
||||
#define _INCLUDED_WINDOWS_H
|
||||
|
||||
#ifdef __WIN32__
|
||||
#ifdef SDL_PLATFORM_WIN32
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#endif
|
||||
@@ -36,7 +36,7 @@
|
||||
#endif
|
||||
#undef WINVER
|
||||
#undef _WIN32_WINNT
|
||||
#ifdef SDL_VIDEO_RENDER_D3D12
|
||||
#if SDL_VIDEO_RENDER_D3D12
|
||||
#define _WIN32_WINNT 0xA00 /* For D3D12, 0xA00 is required */
|
||||
#elif defined(HAVE_SHELLSCALINGAPI_H)
|
||||
#define _WIN32_WINNT 0x603 /* For DPI support */
|
||||
@@ -45,7 +45,7 @@
|
||||
#endif
|
||||
#define WINVER _WIN32_WINNT
|
||||
|
||||
#elif defined(__WINGDK__)
|
||||
#elif defined(SDL_PLATFORM_WINGDK)
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#endif
|
||||
@@ -60,7 +60,7 @@
|
||||
#define _WIN32_WINNT 0xA00
|
||||
#define WINVER _WIN32_WINNT
|
||||
|
||||
#elif defined(__XBOXONE__) || defined(__XBOXSERIES__)
|
||||
#elif defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#endif
|
||||
@@ -93,16 +93,6 @@
|
||||
#include <basetyps.h> /* for REFIID with broken mingw.org headers */
|
||||
#include <mmreg.h>
|
||||
|
||||
/* Older Visual C++ headers don't have the Win64-compatible typedefs... */
|
||||
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
|
||||
#ifndef DWORD_PTR
|
||||
#define DWORD_PTR DWORD
|
||||
#endif
|
||||
#ifndef LONG_PTR
|
||||
#define LONG_PTR LONG
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Routines to convert from UTF8 to native Windows text */
|
||||
#define WIN_StringToUTF8W(S) SDL_iconv_string("UTF-8", "UTF-16LE", (const char *)(S), (SDL_wcslen(S) + 1) * sizeof(WCHAR))
|
||||
#define WIN_UTF8ToStringW(S) (WCHAR *)SDL_iconv_string("UTF-16LE", "UTF-8", (const char *)(S), SDL_strlen(S) + 1)
|
||||
@@ -132,9 +122,9 @@ extern int WIN_SetErrorFromHRESULT(const char *prefix, HRESULT hr);
|
||||
/* Sets an error message based on GetLastError(). Always return -1. */
|
||||
extern int WIN_SetError(const char *prefix);
|
||||
|
||||
#ifndef __WINRT__
|
||||
#ifndef SDL_PLATFORM_WINRT
|
||||
/* Load a function from combase.dll */
|
||||
void *WIN_LoadComBaseFunction(const char *name);
|
||||
FARPROC WIN_LoadComBaseFunction(const char *name);
|
||||
#endif
|
||||
|
||||
/* Wrap up the oddities of CoInitialize() into a common function. */
|
||||
@@ -145,6 +135,9 @@ extern void WIN_CoUninitialize(void);
|
||||
extern HRESULT WIN_RoInitialize(void);
|
||||
extern void WIN_RoUninitialize(void);
|
||||
|
||||
/* Returns SDL_TRUE if we're running on Windows XP (any service pack). DOES NOT CHECK XP "OR GREATER"! */
|
||||
extern BOOL WIN_IsWindowsXP(void);
|
||||
|
||||
/* Returns SDL_TRUE if we're running on Windows Vista and newer */
|
||||
extern BOOL WIN_IsWindowsVistaOrGreater(void);
|
||||
|
||||
@@ -170,6 +163,9 @@ extern BOOL WIN_IsRectEmpty(const RECT *rect);
|
||||
|
||||
extern SDL_AudioFormat SDL_WaveFormatExToSDLFormat(WAVEFORMATEX *waveformat);
|
||||
|
||||
/* WideCharToMultiByte, but with some WinXP manangement. */
|
||||
extern int WIN_WideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWCH lpWideCharStr, int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, LPCCH lpDefaultChar, LPBOOL lpUsedDefaultChar);
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ DWORD SDL_XInputVersion = 0;
|
||||
static HMODULE s_pXInputDLL = NULL;
|
||||
static int s_XInputDLLRefCount = 0;
|
||||
|
||||
#if defined(__WINRT__) || defined(__XBOXONE__) || defined(__XBOXSERIES__)
|
||||
#if defined(SDL_PLATFORM_WINRT) || defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)
|
||||
|
||||
int WIN_LoadXInputDLL(void)
|
||||
{
|
||||
@@ -68,7 +68,7 @@ void WIN_UnloadXInputDLL(void)
|
||||
{
|
||||
}
|
||||
|
||||
#else /* !(defined(__WINRT__) || defined(__XBOXONE__) || defined(__XBOXSERIES__)) */
|
||||
#else /* !(defined(SDL_PLATFORM_WINRT) || defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)) */
|
||||
|
||||
int WIN_LoadXInputDLL(void)
|
||||
{
|
||||
@@ -136,7 +136,7 @@ void WIN_UnloadXInputDLL(void)
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* __WINRT__ */
|
||||
#endif /* SDL_PLATFORM_WINRT */
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "SDL_windows.h"
|
||||
|
||||
#ifdef HAVE_XINPUT_H
|
||||
#if defined(__XBOXONE__) || defined(__XBOXSERIES__)
|
||||
#if defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)
|
||||
/* Xbox supports an XInput wrapper which is a C++-only header... */
|
||||
#include <math.h> /* Required to compile with recent MSVC... */
|
||||
#include <XInputOnGameInput.h>
|
||||
@@ -212,7 +212,7 @@ typedef struct
|
||||
#endif /* HAVE_XINPUT_H */
|
||||
|
||||
/* This struct is not defined in XInput headers. */
|
||||
typedef struct _XINPUT_CAPABILITIES_EX
|
||||
typedef struct
|
||||
{
|
||||
XINPUT_CAPABILITIES Capabilities;
|
||||
WORD VendorId;
|
||||
@@ -220,7 +220,7 @@ typedef struct _XINPUT_CAPABILITIES_EX
|
||||
WORD ProductVersion;
|
||||
WORD unk1;
|
||||
DWORD unk2;
|
||||
} XINPUT_CAPABILITIES_EX, *PXINPUT_CAPABILITIES_EX;
|
||||
} SDL_XINPUT_CAPABILITIES_EX;
|
||||
|
||||
/* Forward decl's for XInput API's we load dynamically and use if available */
|
||||
typedef DWORD(WINAPI *XInputGetState_t)(
|
||||
@@ -244,7 +244,7 @@ typedef DWORD(WINAPI *XInputGetCapabilitiesEx_t)(
|
||||
DWORD dwReserved, /* [in] Must be 1 */
|
||||
DWORD dwUserIndex, /* [in] Index of the gamer associated with the device */
|
||||
DWORD dwFlags, /* [in] Input flags that identify the device type */
|
||||
XINPUT_CAPABILITIES_EX *pCapabilitiesEx /* [out] Receives the capabilities */
|
||||
SDL_XINPUT_CAPABILITIES_EX *pCapabilitiesEx /* [out] Receives the capabilities */
|
||||
);
|
||||
|
||||
typedef DWORD(WINAPI *XInputGetBatteryInformation_t)(
|
||||
|
||||
8
external/sdl/SDL/src/core/windows/version.rc
vendored
8
external/sdl/SDL/src/core/windows/version.rc
vendored
@@ -9,8 +9,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 3,0,0,0
|
||||
PRODUCTVERSION 3,0,0,0
|
||||
FILEVERSION 3,1,0,0
|
||||
PRODUCTVERSION 3,1,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
FILEFLAGS 0x0L
|
||||
FILEOS 0x40004L
|
||||
@@ -23,12 +23,12 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "\0"
|
||||
VALUE "FileDescription", "SDL\0"
|
||||
VALUE "FileVersion", "3, 0, 0, 0\0"
|
||||
VALUE "FileVersion", "3, 1, 0, 0\0"
|
||||
VALUE "InternalName", "SDL\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2024 Sam Lantinga\0"
|
||||
VALUE "OriginalFilename", "SDL3.dll\0"
|
||||
VALUE "ProductName", "Simple DirectMedia Layer\0"
|
||||
VALUE "ProductVersion", "3, 0, 0, 0\0"
|
||||
VALUE "ProductVersion", "3, 1, 0, 0\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
@@ -20,12 +20,6 @@
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
/* Standard C++11 includes */
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
using namespace std;
|
||||
|
||||
/* Windows includes */
|
||||
#include "ppltasks.h"
|
||||
using namespace concurrency;
|
||||
@@ -59,7 +53,7 @@ extern "C" {
|
||||
#include "SDL_winrtapp_common.h"
|
||||
#include "SDL_winrtapp_direct3d.h"
|
||||
|
||||
#if defined(SDL_VIDEO_RENDER_D3D11) && !defined(SDL_RENDER_DISABLED)
|
||||
#if SDL_VIDEO_RENDER_D3D11
|
||||
/* Calling IDXGIDevice3::Trim on the active Direct3D 11.x device is necessary
|
||||
* when Windows 8.1 apps are about to get suspended.
|
||||
*/
|
||||
@@ -544,7 +538,7 @@ void SDL_WinRTApp::OnWindowActivated(CoreWindow ^ sender, WindowActivatedEventAr
|
||||
*/
|
||||
#if !SDL_WINAPI_FAMILY_PHONE || NTDDI_VERSION >= NTDDI_WINBLUE
|
||||
Point cursorPos = WINRT_TransformCursorPosition(window, sender->PointerPosition, TransformToSDLWindowSize);
|
||||
SDL_SendMouseMotion(0, window, 0, 0, cursorPos.X, cursorPos.Y);
|
||||
SDL_SendMouseMotion(0, window, SDL_GLOBAL_MOUSE_ID, SDL_FALSE, cursorPos.X, cursorPos.Y);
|
||||
#endif
|
||||
|
||||
/* TODO, WinRT: see if the Win32 bugfix from https://hg.libsdl.org/SDL/rev/d278747da408 needs to be applied (on window activation) */
|
||||
@@ -615,7 +609,7 @@ void SDL_WinRTApp::OnSuspending(Platform::Object ^ sender, SuspendingEventArgs ^
|
||||
// Let the Direct3D 11 renderer prepare for the app to be backgrounded.
|
||||
// This is necessary for Windows 8.1, possibly elsewhere in the future.
|
||||
// More details at: http://msdn.microsoft.com/en-us/library/windows/apps/Hh994929.aspx
|
||||
#if defined(SDL_VIDEO_RENDER_D3D11) && !defined(SDL_RENDER_DISABLED)
|
||||
#if SDL_VIDEO_RENDER_D3D11
|
||||
if (WINRT_GlobalSDLWindow) {
|
||||
SDL_Renderer *renderer = SDL_GetRenderer(WINRT_GlobalSDLWindow);
|
||||
if (renderer && (SDL_strcmp(renderer->info.name, "direct3d11") == 0)) {
|
||||
@@ -730,8 +724,8 @@ void SDL_WinRTApp::OnCharacterReceived(Windows::UI::Core::CoreWindow ^ sender, W
|
||||
template <typename BackButtonEventArgs>
|
||||
static void WINRT_OnBackButtonPressed(BackButtonEventArgs ^ args)
|
||||
{
|
||||
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_AC_BACK);
|
||||
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_AC_BACK);
|
||||
SDL_SendKeyboardKey(0, SDL_GLOBAL_KEYBOARD_ID, SDL_PRESSED, SDL_SCANCODE_AC_BACK);
|
||||
SDL_SendKeyboardKey(0, SDL_GLOBAL_KEYBOARD_ID, SDL_RELEASED, SDL_SCANCODE_AC_BACK);
|
||||
|
||||
if (SDL_GetHintBoolean(SDL_HINT_WINRT_HANDLE_BACK_BUTTON, SDL_FALSE)) {
|
||||
args->Handled = true;
|
||||
|
||||
162
external/sdl/SDL/src/cpuinfo/SDL_cpuinfo.c
vendored
162
external/sdl/SDL/src/cpuinfo/SDL_cpuinfo.c
vendored
@@ -18,9 +18,10 @@
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#if defined(__WIN32__) || defined(__WINRT__) || defined(__GDK__)
|
||||
#if defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_WINRT) || defined(SDL_PLATFORM_GDK)
|
||||
#include "../core/windows/SDL_windows.h"
|
||||
#endif
|
||||
|
||||
@@ -33,13 +34,13 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
#if defined(__MACOS__) && (defined(__ppc__) || defined(__ppc64__))
|
||||
#if defined(SDL_PLATFORM_MACOS) && (defined(__ppc__) || defined(__ppc64__))
|
||||
#include <sys/sysctl.h> /* For AltiVec check */
|
||||
#elif defined(__OpenBSD__) && defined(__powerpc__)
|
||||
#elif defined(SDL_PLATFORM_OPENBSD) && defined(__powerpc__)
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h> /* For AltiVec check */
|
||||
#include <machine/cpu.h>
|
||||
#elif defined(__FreeBSD__) && defined(__powerpc__)
|
||||
#elif defined(SDL_PLATFORM_FREEBSD) && defined(__powerpc__)
|
||||
#include <machine/cpu.h>
|
||||
#include <sys/auxv.h>
|
||||
#elif defined(SDL_ALTIVEC_BLITTERS) && defined(HAVE_SETJMP)
|
||||
@@ -47,7 +48,7 @@
|
||||
#include <setjmp.h>
|
||||
#endif
|
||||
|
||||
#if (defined(__LINUX__) || defined(__ANDROID__)) && defined(__arm__)
|
||||
#if (defined(SDL_PLATFORM_LINUX) || defined(SDL_PLATFORM_ANDROID)) && defined(__arm__)
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -66,7 +67,7 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__ANDROID__) && defined(__arm__) && !defined(HAVE_GETAUXVAL)
|
||||
#if defined(SDL_PLATFORM_ANDROID) && defined(__arm__) && !defined(HAVE_GETAUXVAL)
|
||||
#include <cpu-features.h>
|
||||
#endif
|
||||
|
||||
@@ -74,16 +75,16 @@
|
||||
#include <sys/auxv.h>
|
||||
#endif
|
||||
|
||||
#ifdef __RISCOS__
|
||||
#ifdef SDL_PLATFORM_RISCOS
|
||||
#include <kernel.h>
|
||||
#include <swis.h>
|
||||
#endif
|
||||
|
||||
#ifdef __PS2__
|
||||
#ifdef SDL_PLATFORM_PS2
|
||||
#include <kernel.h>
|
||||
#endif
|
||||
|
||||
#ifdef __HAIKU__
|
||||
#ifdef SDL_PLATFORM_HAIKU
|
||||
#include <kernel/OS.h>
|
||||
#endif
|
||||
|
||||
@@ -106,7 +107,7 @@
|
||||
#define CPU_CFG2_LSX (1 << 6)
|
||||
#define CPU_CFG2_LASX (1 << 7)
|
||||
|
||||
#if defined(SDL_ALTIVEC_BLITTERS) && defined(HAVE_SETJMP) && !defined(__MACOS__) && !defined(__OpenBSD__) && !defined(__FreeBSD__)
|
||||
#if defined(SDL_ALTIVEC_BLITTERS) && defined(HAVE_SETJMP) && !defined(SDL_PLATFORM_MACOS) && !defined(SDL_PLATFORM_OPENBSD) && !defined(SDL_PLATFORM_FREEBSD)
|
||||
/* This is the brute force way of detecting instruction sets...
|
||||
the idea is borrowed from the libmpeg2 library - thanks!
|
||||
*/
|
||||
@@ -122,7 +123,7 @@ static int CPU_haveCPUID(void)
|
||||
int has_CPUID = 0;
|
||||
|
||||
/* *INDENT-OFF* */ /* clang-format off */
|
||||
#ifndef SDL_CPUINFO_DISABLED
|
||||
#ifndef SDL_PLATFORM_EMSCRIPTEN
|
||||
#if (defined(__GNUC__) || defined(__llvm__)) && defined(__i386__)
|
||||
__asm__ (
|
||||
" pushfl # Get original EFLAGS \n"
|
||||
@@ -209,7 +210,7 @@ done:
|
||||
"1: \n"
|
||||
);
|
||||
#endif
|
||||
#endif
|
||||
#endif /* !SDL_PLATFORM_EMSCRIPTEN */
|
||||
/* *INDENT-ON* */ /* clang-format on */
|
||||
return has_CPUID;
|
||||
}
|
||||
@@ -318,8 +319,8 @@ static int CPU_haveAltiVec(void)
|
||||
{
|
||||
volatile int altivec = 0;
|
||||
#ifndef SDL_CPUINFO_DISABLED
|
||||
#if (defined(__MACOS__) && (defined(__ppc__) || defined(__ppc64__))) || (defined(__OpenBSD__) && defined(__powerpc__))
|
||||
#ifdef __OpenBSD__
|
||||
#if (defined(SDL_PLATFORM_MACOS) && (defined(__ppc__) || defined(__ppc64__))) || (defined(SDL_PLATFORM_OPENBSD) && defined(__powerpc__))
|
||||
#ifdef SDL_PLATFORM_OPENBSD
|
||||
int selectors[2] = { CTL_MACHDEP, CPU_ALTIVEC };
|
||||
#else
|
||||
int selectors[2] = { CTL_HW, HW_VECTORUNIT };
|
||||
@@ -330,7 +331,7 @@ static int CPU_haveAltiVec(void)
|
||||
if (0 == error) {
|
||||
altivec = (hasVectorUnit != 0);
|
||||
}
|
||||
#elif defined(__FreeBSD__) && defined(__powerpc__)
|
||||
#elif defined(SDL_PLATFORM_FREEBSD) && defined(__powerpc__)
|
||||
unsigned long cpufeatures = 0;
|
||||
elf_aux_info(AT_HWCAP, &cpufeatures, sizeof(cpufeatures));
|
||||
altivec = cpufeatures & PPC_FEATURE_HAS_ALTIVEC;
|
||||
@@ -361,7 +362,7 @@ static int CPU_haveARMSIMD(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#elif defined(__LINUX__)
|
||||
#elif defined(SDL_PLATFORM_LINUX)
|
||||
static int CPU_haveARMSIMD(void)
|
||||
{
|
||||
int arm_simd = 0;
|
||||
@@ -384,7 +385,7 @@ static int CPU_haveARMSIMD(void)
|
||||
return arm_simd;
|
||||
}
|
||||
|
||||
#elif defined(__RISCOS__)
|
||||
#elif defined(SDL_PLATFORM_RISCOS)
|
||||
static int CPU_haveARMSIMD(void)
|
||||
{
|
||||
_kernel_swi_regs regs;
|
||||
@@ -414,7 +415,7 @@ static int CPU_haveARMSIMD(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__LINUX__) && defined(__arm__) && !defined(HAVE_GETAUXVAL)
|
||||
#if defined(SDL_PLATFORM_LINUX) && defined(__arm__) && !defined(HAVE_GETAUXVAL)
|
||||
static int readProcAuxvForNeon(void)
|
||||
{
|
||||
int neon = 0;
|
||||
@@ -439,9 +440,7 @@ static int CPU_haveNEON(void)
|
||||
{
|
||||
/* The way you detect NEON is a privileged instruction on ARM, so you have
|
||||
query the OS kernel in a platform-specific way. :/ */
|
||||
#ifdef SDL_CPUINFO_DISABLED
|
||||
return 0; /* disabled */
|
||||
#elif (defined(__WINDOWS__) || defined(__WINRT__) || defined(__GDK__)) && (defined(_M_ARM) || defined(_M_ARM64))
|
||||
#if defined(SDL_PLATFORM_WINDOWS) && (defined(_M_ARM) || defined(_M_ARM64))
|
||||
/* Visual Studio, for ARM, doesn't define __ARM_ARCH. Handle this first. */
|
||||
/* Seems to have been removed */
|
||||
#ifndef PF_ARM_NEON_INSTRUCTIONS_AVAILABLE
|
||||
@@ -451,18 +450,18 @@ static int CPU_haveNEON(void)
|
||||
return IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE) != 0;
|
||||
#elif (defined(__ARM_ARCH) && (__ARM_ARCH >= 8)) || defined(__aarch64__)
|
||||
return 1; /* ARMv8 always has non-optional NEON support. */
|
||||
#elif defined(__VITA__)
|
||||
#elif defined(SDL_PLATFORM_VITA)
|
||||
return 1;
|
||||
#elif defined(__3DS__)
|
||||
#elif defined(SDL_PLATFORM_3DS)
|
||||
return 0;
|
||||
#elif defined(__APPLE__) && defined(__ARM_ARCH) && (__ARM_ARCH >= 7)
|
||||
#elif defined(SDL_PLATFORM_APPLE) && defined(__ARM_ARCH) && (__ARM_ARCH >= 7)
|
||||
/* (note that sysctlbyname("hw.optional.neon") doesn't work!) */
|
||||
return 1; /* all Apple ARMv7 chips and later have NEON. */
|
||||
#elif defined(__APPLE__)
|
||||
#elif defined(SDL_PLATFORM_APPLE)
|
||||
return 0; /* assume anything else from Apple doesn't have NEON. */
|
||||
#elif !defined(__arm__)
|
||||
return 0; /* not an ARM CPU at all. */
|
||||
#elif defined(__OpenBSD__)
|
||||
#elif defined(SDL_PLATFORM_OPENBSD)
|
||||
return 1; /* OpenBSD only supports ARMv7 CPUs that have NEON. */
|
||||
#elif defined(HAVE_ELF_AUX_INFO)
|
||||
unsigned long hasneon = 0;
|
||||
@@ -470,11 +469,11 @@ static int CPU_haveNEON(void)
|
||||
return 0;
|
||||
}
|
||||
return (hasneon & HWCAP_NEON) == HWCAP_NEON;
|
||||
#elif (defined(__LINUX__) || defined(__ANDROID__)) && defined(HAVE_GETAUXVAL)
|
||||
#elif (defined(SDL_PLATFORM_LINUX) || defined(SDL_PLATFORM_ANDROID)) && defined(HAVE_GETAUXVAL)
|
||||
return (getauxval(AT_HWCAP) & HWCAP_NEON) == HWCAP_NEON;
|
||||
#elif defined(__LINUX__)
|
||||
#elif defined(SDL_PLATFORM_LINUX)
|
||||
return readProcAuxvForNeon();
|
||||
#elif defined(__ANDROID__)
|
||||
#elif defined(SDL_PLATFORM_ANDROID)
|
||||
/* Use NDK cpufeatures to read either /proc/self/auxv or /proc/cpuinfo */
|
||||
{
|
||||
AndroidCpuFamily cpu_family = android_getCpuFamily();
|
||||
@@ -486,7 +485,7 @@ static int CPU_haveNEON(void)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#elif defined(__RISCOS__)
|
||||
#elif defined(SDL_PLATFORM_RISCOS)
|
||||
/* Use the VFPSupport_Features SWI to access the MVFR registers */
|
||||
{
|
||||
_kernel_swi_regs regs;
|
||||
@@ -498,6 +497,8 @@ static int CPU_haveNEON(void)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#elif defined(SDL_PLATFORM_EMSCRIPTEN)
|
||||
return 0;
|
||||
#else
|
||||
#warning SDL_HasNEON is not implemented for this ARM platform. Write me.
|
||||
return 0;
|
||||
@@ -618,7 +619,6 @@ static int SDL_CPUCount = 0;
|
||||
int SDL_GetCPUCount(void)
|
||||
{
|
||||
if (!SDL_CPUCount) {
|
||||
#ifndef SDL_CPUINFO_DISABLED
|
||||
#if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
|
||||
if (SDL_CPUCount <= 0) {
|
||||
SDL_CPUCount = (int)sysconf(_SC_NPROCESSORS_ONLN);
|
||||
@@ -630,13 +630,12 @@ int SDL_GetCPUCount(void)
|
||||
sysctlbyname("hw.ncpu", &SDL_CPUCount, &size, NULL, 0);
|
||||
}
|
||||
#endif
|
||||
#if defined(__WIN32__) || defined(__GDK__)
|
||||
#if defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_GDK)
|
||||
if (SDL_CPUCount <= 0) {
|
||||
SYSTEM_INFO info;
|
||||
GetSystemInfo(&info);
|
||||
SDL_CPUCount = info.dwNumberOfProcessors;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
/* There has to be at least 1, right? :) */
|
||||
if (SDL_CPUCount <= 0) {
|
||||
@@ -857,12 +856,88 @@ int SDL_GetCPUCacheLineSize(void)
|
||||
}
|
||||
}
|
||||
|
||||
static Uint32 SDL_CPUFeatures = 0xFFFFFFFF;
|
||||
#define SDL_CPUFEATURES_RESET_VALUE 0xFFFFFFFF
|
||||
|
||||
static Uint32 SDL_CPUFeatures = SDL_CPUFEATURES_RESET_VALUE;
|
||||
static Uint32 SDL_SIMDAlignment = 0xFFFFFFFF;
|
||||
|
||||
static SDL_bool ref_string_equals(const char *ref, const char *test, const char *end_test) {
|
||||
size_t len_test = end_test - test;
|
||||
return SDL_strncmp(ref, test, len_test) == 0 && ref[len_test] == '\0' && (test[len_test] == '\0' || test[len_test] == ',');
|
||||
}
|
||||
|
||||
static Uint32 SDLCALL SDL_CPUFeatureMaskFromHint(void)
|
||||
{
|
||||
Uint32 result_mask = SDL_CPUFEATURES_RESET_VALUE;
|
||||
|
||||
const char *hint = SDL_GetHint(SDL_HINT_CPU_FEATURE_MASK);
|
||||
|
||||
if (hint) {
|
||||
for (const char *spot = hint, *next; *spot; spot = next) {
|
||||
const char *end = SDL_strchr(spot, ',');
|
||||
Uint32 spot_mask;
|
||||
SDL_bool add_spot_mask = SDL_TRUE;
|
||||
if (end) {
|
||||
next = end + 1;
|
||||
} else {
|
||||
size_t len = SDL_strlen(spot);
|
||||
end = spot + len;
|
||||
next = end;
|
||||
}
|
||||
if (spot[0] == '+') {
|
||||
add_spot_mask = SDL_TRUE;
|
||||
spot += 1;
|
||||
} else if (spot[0] == '-') {
|
||||
add_spot_mask = SDL_FALSE;
|
||||
spot += 1;
|
||||
}
|
||||
if (ref_string_equals("all", spot, end)) {
|
||||
spot_mask = SDL_CPUFEATURES_RESET_VALUE;
|
||||
} else if (ref_string_equals("altivec", spot, end)) {
|
||||
spot_mask= CPU_HAS_ALTIVEC;
|
||||
} else if (ref_string_equals("mmx", spot, end)) {
|
||||
spot_mask = CPU_HAS_MMX;
|
||||
} else if (ref_string_equals("sse", spot, end)) {
|
||||
spot_mask = CPU_HAS_SSE;
|
||||
} else if (ref_string_equals("sse2", spot, end)) {
|
||||
spot_mask = CPU_HAS_SSE2;
|
||||
} else if (ref_string_equals("sse3", spot, end)) {
|
||||
spot_mask = CPU_HAS_SSE3;
|
||||
} else if (ref_string_equals("sse41", spot, end)) {
|
||||
spot_mask = CPU_HAS_SSE41;
|
||||
} else if (ref_string_equals("sse42", spot, end)) {
|
||||
spot_mask = CPU_HAS_SSE42;
|
||||
} else if (ref_string_equals("avx", spot, end)) {
|
||||
spot_mask = CPU_HAS_AVX;
|
||||
} else if (ref_string_equals("avx2", spot, end)) {
|
||||
spot_mask = CPU_HAS_AVX2;
|
||||
} else if (ref_string_equals("avx512f", spot, end)) {
|
||||
spot_mask = CPU_HAS_AVX512F;
|
||||
} else if (ref_string_equals("arm-simd", spot, end)) {
|
||||
spot_mask = CPU_HAS_ARM_SIMD;
|
||||
} else if (ref_string_equals("neon", spot, end)) {
|
||||
spot_mask = CPU_HAS_NEON;
|
||||
} else if (ref_string_equals("lsx", spot, end)) {
|
||||
spot_mask = CPU_HAS_LSX;
|
||||
} else if (ref_string_equals("lasx", spot, end)) {
|
||||
spot_mask = CPU_HAS_LASX;
|
||||
} else {
|
||||
/* Ignore unknown/incorrect cpu feature(s) */
|
||||
continue;
|
||||
}
|
||||
if (add_spot_mask) {
|
||||
result_mask |= spot_mask;
|
||||
} else {
|
||||
result_mask &= ~spot_mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result_mask;
|
||||
}
|
||||
|
||||
static Uint32 SDL_GetCPUFeatures(void)
|
||||
{
|
||||
if (SDL_CPUFeatures == 0xFFFFFFFF) {
|
||||
if (SDL_CPUFeatures == SDL_CPUFEATURES_RESET_VALUE) {
|
||||
CPU_calcCPUIDFeatures();
|
||||
SDL_CPUFeatures = 0;
|
||||
SDL_SIMDAlignment = sizeof(void *); /* a good safe base value */
|
||||
@@ -922,10 +997,15 @@ static Uint32 SDL_GetCPUFeatures(void)
|
||||
SDL_CPUFeatures |= CPU_HAS_LASX;
|
||||
SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 32);
|
||||
}
|
||||
SDL_CPUFeatures &= SDL_CPUFeatureMaskFromHint();
|
||||
}
|
||||
return SDL_CPUFeatures;
|
||||
}
|
||||
|
||||
void SDL_QuitCPUInfo(void) {
|
||||
SDL_CPUFeatures = SDL_CPUFEATURES_RESET_VALUE;
|
||||
}
|
||||
|
||||
#define CPU_FEATURE_AVAILABLE(f) ((SDL_GetCPUFeatures() & (f)) ? SDL_TRUE : SDL_FALSE)
|
||||
|
||||
SDL_bool SDL_HasAltiVec(void)
|
||||
@@ -1003,7 +1083,6 @@ static int SDL_SystemRAM = 0;
|
||||
int SDL_GetSystemRAM(void)
|
||||
{
|
||||
if (!SDL_SystemRAM) {
|
||||
#ifndef SDL_CPUINFO_DISABLED
|
||||
#if defined(HAVE_SYSCONF) && defined(_SC_PHYS_PAGES) && defined(_SC_PAGESIZE)
|
||||
if (SDL_SystemRAM <= 0) {
|
||||
SDL_SystemRAM = (int)((Sint64)sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE) / (1024 * 1024));
|
||||
@@ -1032,7 +1111,7 @@ int SDL_GetSystemRAM(void)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(__WIN32__) || defined(__GDK__)
|
||||
#if defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_GDK)
|
||||
if (SDL_SystemRAM <= 0) {
|
||||
MEMORYSTATUSEX stat;
|
||||
stat.dwLength = sizeof(stat);
|
||||
@@ -1041,7 +1120,7 @@ int SDL_GetSystemRAM(void)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef __RISCOS__
|
||||
#ifdef SDL_PLATFORM_RISCOS
|
||||
if (SDL_SystemRAM <= 0) {
|
||||
_kernel_swi_regs regs;
|
||||
regs.r[0] = 0x108;
|
||||
@@ -1050,20 +1129,20 @@ int SDL_GetSystemRAM(void)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef __VITA__
|
||||
#ifdef SDL_PLATFORM_VITA
|
||||
if (SDL_SystemRAM <= 0) {
|
||||
/* Vita has 512MiB on SoC, that's split into 256MiB(+109MiB in extended memory mode) for app
|
||||
+26MiB of physically continuous memory, +112MiB of CDRAM(VRAM) + system reserved memory. */
|
||||
SDL_SystemRAM = 536870912;
|
||||
}
|
||||
#endif
|
||||
#ifdef __PS2__
|
||||
#ifdef SDL_PLATFORM_PS2
|
||||
if (SDL_SystemRAM <= 0) {
|
||||
/* PlayStation 2 has 32MiB however there are some special models with 64 and 128 */
|
||||
SDL_SystemRAM = GetMemorySize();
|
||||
}
|
||||
#endif
|
||||
#ifdef __HAIKU__
|
||||
#ifdef SDL_PLATFORM_HAIKU
|
||||
if (SDL_SystemRAM <= 0) {
|
||||
system_info info;
|
||||
if (get_system_info(&info) == B_OK) {
|
||||
@@ -1072,7 +1151,6 @@ int SDL_GetSystemRAM(void)
|
||||
SDL_SystemRAM = (int)SDL_round((info.max_pages + info.ignored_pages > 0 ? info.ignored_pages : 0) * B_PAGE_SIZE / 1048576.0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
return SDL_SystemRAM;
|
||||
|
||||
27
external/sdl/SDL/src/cpuinfo/SDL_cpuinfo_c.h
vendored
Normal file
27
external/sdl/SDL/src/cpuinfo/SDL_cpuinfo_c.h
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2024 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_cpuinfo_c_h_
|
||||
#define SDL_cpuinfo_c_h_
|
||||
|
||||
extern void SDL_QuitCPUInfo(void);
|
||||
|
||||
#endif /* SDL_cpuinfo_c_h_ */
|
||||
169
external/sdl/SDL/src/dialog/cocoa/SDL_cocoadialog.m
vendored
Normal file
169
external/sdl/SDL/src/dialog/cocoa/SDL_cocoadialog.m
vendored
Normal file
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
/* TODO: Macro? */
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FDT_SAVE,
|
||||
FDT_OPEN,
|
||||
FDT_OPENFOLDER
|
||||
} cocoa_FileDialogType;
|
||||
|
||||
void show_file_dialog(cocoa_FileDialogType type, SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many)
|
||||
{
|
||||
/* NSOpenPanel inherits from NSSavePanel */
|
||||
NSSavePanel *dialog;
|
||||
NSOpenPanel *dialog_as_open;
|
||||
|
||||
switch (type) {
|
||||
case FDT_SAVE:
|
||||
dialog = [NSSavePanel savePanel];
|
||||
break;
|
||||
case FDT_OPEN:
|
||||
dialog_as_open = [NSOpenPanel openPanel];
|
||||
[dialog_as_open setAllowsMultipleSelection:((allow_many == SDL_TRUE) ? YES : NO)];
|
||||
dialog = dialog_as_open;
|
||||
break;
|
||||
case FDT_OPENFOLDER:
|
||||
dialog_as_open = [NSOpenPanel openPanel];
|
||||
[dialog_as_open setCanChooseFiles:NO];
|
||||
[dialog_as_open setCanChooseDirectories:YES];
|
||||
[dialog_as_open setAllowsMultipleSelection:((allow_many == SDL_TRUE) ? YES : NO)];
|
||||
dialog = dialog_as_open;
|
||||
break;
|
||||
};
|
||||
|
||||
int n = -1;
|
||||
while (filters[++n].name && filters[n].pattern);
|
||||
NSMutableArray *types = [[NSMutableArray alloc] initWithCapacity:n ];
|
||||
|
||||
int has_all_files = 0;
|
||||
for (int i = 0; i < n; i++) {
|
||||
char *pattern = SDL_strdup(filters[i].pattern);
|
||||
char *pattern_ptr = pattern;
|
||||
|
||||
if (!pattern_ptr) {
|
||||
SDL_OutOfMemory();
|
||||
callback(userdata, NULL, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
for (char *c = pattern; *c; c++) {
|
||||
if (*c == ';') {
|
||||
*c = '\0';
|
||||
[types addObject: [NSString stringWithFormat: @"%s", pattern_ptr]];
|
||||
pattern_ptr = c + 1;
|
||||
} else if (!((*c >= 'a' && *c <= 'z') || (*c >= 'A' && *c <= 'Z') || (*c >= '0' && *c <= '9') || *c == '.' || *c == '_' || *c == '-' || (*c == '*' && (c[1] == '\0' || c[1] == ';')))) {
|
||||
SDL_SetError("Illegal character in pattern name: %c (Only alphanumeric characters, periods, underscores and hyphens allowed)", *c);
|
||||
callback(userdata, NULL, -1);
|
||||
SDL_free(pattern);
|
||||
} else if (*c == '*') {
|
||||
has_all_files = 1;
|
||||
}
|
||||
}
|
||||
[types addObject: [NSString stringWithFormat: @"%s", pattern_ptr]];
|
||||
|
||||
SDL_free(pattern);
|
||||
}
|
||||
|
||||
if (!has_all_files) {
|
||||
if (@available(macOS 11.0, *)) {
|
||||
[dialog setAllowedContentTypes:types];
|
||||
} else {
|
||||
[dialog setAllowedFileTypes:types];
|
||||
}
|
||||
}
|
||||
|
||||
/* Keep behavior consistent with other platforms */
|
||||
[dialog setAllowsOtherFileTypes:YES];
|
||||
|
||||
if (default_location) {
|
||||
[dialog setDirectoryURL:[NSURL fileURLWithPath:[NSString stringWithUTF8String:default_location]]];
|
||||
}
|
||||
|
||||
NSWindow *w = NULL;
|
||||
|
||||
if (window) {
|
||||
w = (__bridge NSWindow *)SDL_GetProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_COCOA_WINDOW_POINTER, NULL);
|
||||
}
|
||||
|
||||
if (w) {
|
||||
// [dialog beginWithCompletionHandler:^(NSInteger result) {
|
||||
[dialog beginSheetModalForWindow:w completionHandler:^(NSInteger result) {
|
||||
// NSModalResponseOK for >= 10.13
|
||||
if (result == NSFileHandlingPanelOKButton) {
|
||||
if (dialog_as_open) {
|
||||
NSArray* urls = [dialog_as_open URLs];
|
||||
const char *files[[urls count] + 1];
|
||||
for (int i = 0; i < [urls count]; i++) {
|
||||
files[i] = [[[urls objectAtIndex:i] path] UTF8String];
|
||||
}
|
||||
files[[urls count]] = NULL;
|
||||
callback(userdata, files, -1);
|
||||
} else {
|
||||
const char *files[2] = { [[[dialog URL] path] UTF8String], NULL };
|
||||
callback(userdata, files, -1);
|
||||
}
|
||||
} else if (result == NSModalResponseCancel) {
|
||||
const char *files[1] = { NULL };
|
||||
callback(userdata, files, -1);
|
||||
}
|
||||
}];
|
||||
} else {
|
||||
// NSModalResponseOK for >= 10.10
|
||||
if ([dialog runModal] == NSOKButton) {
|
||||
if (dialog_as_open) {
|
||||
NSArray* urls = [dialog_as_open URLs];
|
||||
const char *files[[urls count] + 1];
|
||||
for (int i = 0; i < [urls count]; i++) {
|
||||
files[i] = [[[urls objectAtIndex:i] path] UTF8String];
|
||||
}
|
||||
files[[urls count]] = NULL;
|
||||
callback(userdata, files, -1);
|
||||
} else {
|
||||
const char *files[2] = { [[[dialog URL] path] UTF8String], NULL };
|
||||
callback(userdata, files, -1);
|
||||
}
|
||||
} else {
|
||||
const char *files[1] = { NULL };
|
||||
callback(userdata, files, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many)
|
||||
{
|
||||
show_file_dialog(FDT_OPEN, callback, userdata, window, filters, default_location, allow_many);
|
||||
}
|
||||
|
||||
void SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location)
|
||||
{
|
||||
show_file_dialog(FDT_SAVE, callback, userdata, window, filters, default_location, 0);
|
||||
}
|
||||
|
||||
void SDL_ShowOpenFolderDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const char* default_location, SDL_bool allow_many)
|
||||
{
|
||||
show_file_dialog(FDT_OPENFOLDER, callback, userdata, window, NULL, default_location, allow_many);
|
||||
}
|
||||
41
external/sdl/SDL/src/dialog/dummy/SDL_dummydialog.c
vendored
Normal file
41
external/sdl/SDL/src/dialog/dummy/SDL_dummydialog.c
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
/* TODO: Macro? */
|
||||
|
||||
void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many)
|
||||
{
|
||||
SDL_Unsupported();
|
||||
callback(userdata, NULL, -1);
|
||||
}
|
||||
|
||||
void SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location)
|
||||
{
|
||||
SDL_Unsupported();
|
||||
callback(userdata, NULL, -1);
|
||||
}
|
||||
|
||||
void SDL_ShowOpenFolderDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const char* default_location, SDL_bool allow_many)
|
||||
{
|
||||
SDL_Unsupported();
|
||||
callback(userdata, NULL, -1);
|
||||
}
|
||||
233
external/sdl/SDL/src/dialog/haiku/SDL_haikudialog.cc
vendored
Normal file
233
external/sdl/SDL/src/dialog/haiku/SDL_haikudialog.cc
vendored
Normal file
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
#include "../../core/haiku/SDL_BeApp.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <FilePanel.h>
|
||||
#include <Entry.h>
|
||||
#include <Looper.h>
|
||||
#include <Messenger.h>
|
||||
#include <Path.h>
|
||||
#include <TypeConstants.h>
|
||||
|
||||
bool StringEndsWith(const std::string& str, const std::string& end)
|
||||
{
|
||||
return str.size() >= end.size() && !str.compare(str.size() - end.size(), end.size(), end);
|
||||
}
|
||||
|
||||
std::vector<std::string> StringSplit(const std::string& str, const std::string& split)
|
||||
{
|
||||
std::vector<std::string> retval;
|
||||
std::string s = str;
|
||||
size_t pos = 0;
|
||||
|
||||
while ((pos = s.find(split)) != std::string::npos) {
|
||||
retval.push_back(s.substr(0, pos));
|
||||
s = s.substr(pos + split.size());
|
||||
}
|
||||
|
||||
retval.push_back(s);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
class SDLBRefFilter : public BRefFilter
|
||||
{
|
||||
public:
|
||||
SDLBRefFilter(const SDL_DialogFileFilter *filters) :
|
||||
BRefFilter(),
|
||||
m_filters(filters)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool Filter(const entry_ref *ref, BNode *node, struct stat_beos *stat, const char *mimeType) override
|
||||
{
|
||||
BEntry entry(ref);
|
||||
BPath path;
|
||||
entry.GetPath(&path);
|
||||
std::string result = path.Path();
|
||||
|
||||
if (!m_filters)
|
||||
return true;
|
||||
|
||||
struct stat info;
|
||||
node->GetStat(&info);
|
||||
if (S_ISDIR(info.st_mode))
|
||||
return true;
|
||||
|
||||
const auto *filter = m_filters;
|
||||
while (filter->name && filter->pattern) {
|
||||
for (const auto& suffix : StringSplit(filter->pattern, ";")) {
|
||||
if (StringEndsWith(result, std::string(".") + suffix)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
filter++;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
const SDL_DialogFileFilter * const m_filters;
|
||||
};
|
||||
|
||||
class CallbackLooper : public BLooper
|
||||
{
|
||||
public:
|
||||
CallbackLooper(SDL_DialogFileCallback callback, void *userdata) :
|
||||
m_callback(callback),
|
||||
m_userdata(userdata),
|
||||
m_files(),
|
||||
m_messenger(),
|
||||
m_panel(),
|
||||
m_filter()
|
||||
{
|
||||
}
|
||||
|
||||
~CallbackLooper()
|
||||
{
|
||||
delete m_messenger;
|
||||
delete m_panel;
|
||||
delete m_filter;
|
||||
}
|
||||
|
||||
void SetToBeFreed(BMessenger *messenger, BFilePanel *panel, SDLBRefFilter *filter)
|
||||
{
|
||||
m_messenger = messenger;
|
||||
m_panel = panel;
|
||||
m_filter = filter;
|
||||
}
|
||||
|
||||
virtual void MessageReceived(BMessage *msg) override
|
||||
{
|
||||
entry_ref file;
|
||||
BPath path;
|
||||
BEntry entry;
|
||||
std::string result;
|
||||
const char *filename;
|
||||
int32 nFiles = 0;
|
||||
|
||||
switch (msg->what)
|
||||
{
|
||||
case B_REFS_RECEIVED: // Open
|
||||
msg->GetInfo("refs", NULL, &nFiles);
|
||||
for (int i = 0; i < nFiles; i++) {
|
||||
msg->FindRef("refs", i, &file);
|
||||
entry.SetTo(&file);
|
||||
entry.GetPath(&path);
|
||||
result = path.Path();
|
||||
m_files.push_back(result);
|
||||
}
|
||||
break;
|
||||
|
||||
case B_SAVE_REQUESTED: // Save
|
||||
msg->FindRef("directory", &file);
|
||||
entry.SetTo(&file);
|
||||
entry.GetPath(&path);
|
||||
result = path.Path();
|
||||
result += "/";
|
||||
msg->FindString("name", &filename);
|
||||
result += filename;
|
||||
m_files.push_back(result);
|
||||
break;
|
||||
|
||||
case B_CANCEL: // Whenever the dialog is closed (Cancel but also after Open and Save)
|
||||
{
|
||||
nFiles = m_files.size();
|
||||
const char* files[nFiles + 1];
|
||||
for (int i = 0; i < nFiles; i++) {
|
||||
files[i] = m_files[i].c_str();
|
||||
}
|
||||
files[nFiles] = NULL;
|
||||
m_callback(m_userdata, files, -1);
|
||||
Quit();
|
||||
SDL_QuitBeApp();
|
||||
delete this;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
BHandler::MessageReceived(msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
SDL_DialogFileCallback m_callback;
|
||||
void *m_userdata;
|
||||
std::vector<std::string> m_files;
|
||||
|
||||
// Only to free stuff later
|
||||
BMessenger *m_messenger;
|
||||
BFilePanel *m_panel;
|
||||
SDLBRefFilter *m_filter;
|
||||
};
|
||||
|
||||
void ShowDialog(bool save, SDL_DialogFileCallback callback, void *userdata, bool many, bool modal, const SDL_DialogFileFilter *filters, bool folder, const char *location)
|
||||
{
|
||||
if (SDL_InitBeApp()) {
|
||||
char* err = SDL_strdup(SDL_GetError());
|
||||
SDL_SetError("Couldn't init Be app: %s", err);
|
||||
SDL_free(err);
|
||||
callback(userdata, NULL, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
// No unique_ptr's because they need to survive the end of the function
|
||||
CallbackLooper *looper = new CallbackLooper(callback, userdata);
|
||||
BMessenger *messenger = new BMessenger(NULL, looper);
|
||||
SDLBRefFilter *filter = new SDLBRefFilter(filters);
|
||||
|
||||
BEntry entry;
|
||||
entry_ref entryref;
|
||||
if (location) {
|
||||
entry.SetTo(location);
|
||||
entry.GetRef(&entryref);
|
||||
}
|
||||
|
||||
BFilePanel *panel = new BFilePanel(save ? B_SAVE_PANEL : B_OPEN_PANEL, messenger, location ? &entryref : NULL, folder ? B_DIRECTORY_NODE : B_FILE_NODE, many, NULL, filter, modal);
|
||||
looper->SetToBeFreed(messenger, panel, filter);
|
||||
looper->Run();
|
||||
panel->Show();
|
||||
}
|
||||
|
||||
void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const SDL_DialogFileFilter *filters, const char *default_location, SDL_bool allow_many)
|
||||
{
|
||||
ShowDialog(false, callback, userdata, allow_many == SDL_TRUE, !!window, filters, false, default_location);
|
||||
}
|
||||
|
||||
void SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const SDL_DialogFileFilter *filters, const char *default_location)
|
||||
{
|
||||
ShowDialog(true, callback, userdata, false, !!window, filters, false, default_location);
|
||||
}
|
||||
|
||||
void SDL_ShowOpenFolderDialog(SDL_DialogFileCallback callback, void *userdata, SDL_Window *window, const char* default_location, SDL_bool allow_many)
|
||||
{
|
||||
// Use a dummy filter to avoid showing files in the dialog
|
||||
SDL_DialogFileFilter filter[] = {{}};
|
||||
ShowDialog(false, callback, userdata, allow_many == SDL_TRUE, !!window, filter, true, default_location);
|
||||
}
|
||||
492
external/sdl/SDL/src/dialog/unix/SDL_portaldialog.c
vendored
Normal file
492
external/sdl/SDL/src/dialog/unix/SDL_portaldialog.c
vendored
Normal file
@@ -0,0 +1,492 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
#include "./SDL_dialog.h"
|
||||
|
||||
#include "../../core/linux/SDL_dbus.h"
|
||||
|
||||
#ifdef SDL_USE_LIBDBUS
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define PORTAL_DESTINATION "org.freedesktop.portal.Desktop"
|
||||
#define PORTAL_PATH "/org/freedesktop/portal/desktop"
|
||||
#define PORTAL_INTERFACE "org.freedesktop.portal.FileChooser"
|
||||
|
||||
#define SIGNAL_SENDER "org.freedesktop.portal.Desktop"
|
||||
#define SIGNAL_INTERFACE "org.freedesktop.portal.Request"
|
||||
#define SIGNAL_NAME "Response"
|
||||
#define SIGNAL_FILTER "type='signal', sender='"SIGNAL_SENDER"', interface='"SIGNAL_INTERFACE"', member='"SIGNAL_NAME"', path='"
|
||||
|
||||
#define HANDLE_LEN 10
|
||||
|
||||
#define WAYLAND_HANDLE_PREFIX "wayland:"
|
||||
#define X11_HANDLE_PREFIX "x11:"
|
||||
|
||||
typedef struct {
|
||||
SDL_DialogFileCallback callback;
|
||||
void *userdata;
|
||||
const char *path;
|
||||
} SignalCallback;
|
||||
|
||||
static void DBus_AppendStringOption(SDL_DBusContext *dbus, DBusMessageIter *options, const char *key, const char *value)
|
||||
{
|
||||
DBusMessageIter options_pair, options_value;
|
||||
|
||||
dbus->message_iter_open_container(options, DBUS_TYPE_DICT_ENTRY, NULL, &options_pair);
|
||||
dbus->message_iter_append_basic(&options_pair, DBUS_TYPE_STRING, &key);
|
||||
dbus->message_iter_open_container(&options_pair, DBUS_TYPE_VARIANT, "s", &options_value);
|
||||
dbus->message_iter_append_basic(&options_value, DBUS_TYPE_STRING, &value);
|
||||
dbus->message_iter_close_container(&options_pair, &options_value);
|
||||
dbus->message_iter_close_container(options, &options_pair);
|
||||
}
|
||||
|
||||
static void DBus_AppendBoolOption(SDL_DBusContext *dbus, DBusMessageIter *options, const char *key, int value)
|
||||
{
|
||||
DBusMessageIter options_pair, options_value;
|
||||
|
||||
dbus->message_iter_open_container(options, DBUS_TYPE_DICT_ENTRY, NULL, &options_pair);
|
||||
dbus->message_iter_append_basic(&options_pair, DBUS_TYPE_STRING, &key);
|
||||
dbus->message_iter_open_container(&options_pair, DBUS_TYPE_VARIANT, "b", &options_value);
|
||||
dbus->message_iter_append_basic(&options_value, DBUS_TYPE_BOOLEAN, &value);
|
||||
dbus->message_iter_close_container(&options_pair, &options_value);
|
||||
dbus->message_iter_close_container(options, &options_pair);
|
||||
}
|
||||
|
||||
static void DBus_AppendFilter(SDL_DBusContext *dbus, DBusMessageIter *parent, const SDL_DialogFileFilter *filter)
|
||||
{
|
||||
DBusMessageIter filter_entry, filter_array, filter_array_entry;
|
||||
char *state = NULL, *patterns, *pattern, *glob_pattern;
|
||||
int zero = 0;
|
||||
|
||||
dbus->message_iter_open_container(parent, DBUS_TYPE_STRUCT, NULL, &filter_entry);
|
||||
dbus->message_iter_append_basic(&filter_entry, DBUS_TYPE_STRING, &filter->name);
|
||||
dbus->message_iter_open_container(&filter_entry, DBUS_TYPE_ARRAY, "(us)", &filter_array);
|
||||
|
||||
patterns = SDL_strdup(filter->pattern);
|
||||
if (!patterns) {
|
||||
SDL_OutOfMemory();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
pattern = SDL_strtok_r(patterns, ";", &state);
|
||||
while (pattern) {
|
||||
size_t max_len = SDL_strlen(pattern) + 3;
|
||||
|
||||
dbus->message_iter_open_container(&filter_array, DBUS_TYPE_STRUCT, NULL, &filter_array_entry);
|
||||
dbus->message_iter_append_basic(&filter_array_entry, DBUS_TYPE_UINT32, &zero);
|
||||
|
||||
glob_pattern = SDL_calloc(sizeof(char), max_len);
|
||||
if (!glob_pattern) {
|
||||
SDL_OutOfMemory();
|
||||
goto cleanup;
|
||||
}
|
||||
glob_pattern[0] = '*';
|
||||
/* Special case: The '*' filter doesn't need to be rewritten */
|
||||
if (pattern[0] != '*' || pattern[1]) {
|
||||
glob_pattern[1] = '.';
|
||||
SDL_strlcat(glob_pattern + 2, pattern, max_len);
|
||||
}
|
||||
dbus->message_iter_append_basic(&filter_array_entry, DBUS_TYPE_STRING, &glob_pattern);
|
||||
SDL_free(glob_pattern);
|
||||
|
||||
dbus->message_iter_close_container(&filter_array, &filter_array_entry);
|
||||
pattern = SDL_strtok_r(NULL, ";", &state);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
SDL_free(patterns);
|
||||
|
||||
dbus->message_iter_close_container(&filter_entry, &filter_array);
|
||||
dbus->message_iter_close_container(parent, &filter_entry);
|
||||
}
|
||||
|
||||
static void DBus_AppendFilters(SDL_DBusContext *dbus, DBusMessageIter *options, const SDL_DialogFileFilter *filters)
|
||||
{
|
||||
DBusMessageIter options_pair, options_value, options_value_array;
|
||||
static const char *filters_name = "filters";
|
||||
|
||||
dbus->message_iter_open_container(options, DBUS_TYPE_DICT_ENTRY, NULL, &options_pair);
|
||||
dbus->message_iter_append_basic(&options_pair, DBUS_TYPE_STRING, &filters_name);
|
||||
dbus->message_iter_open_container(&options_pair, DBUS_TYPE_VARIANT, "a(sa(us))", &options_value);
|
||||
dbus->message_iter_open_container(&options_value, DBUS_TYPE_ARRAY, "(sa(us))", &options_value_array);
|
||||
for (const SDL_DialogFileFilter *filter = filters; filter && filter->name && filter->pattern; ++filter) {
|
||||
DBus_AppendFilter(dbus, &options_value_array, filter);
|
||||
}
|
||||
dbus->message_iter_close_container(&options_value, &options_value_array);
|
||||
dbus->message_iter_close_container(&options_pair, &options_value);
|
||||
dbus->message_iter_close_container(options, &options_pair);
|
||||
}
|
||||
|
||||
static void DBus_AppendByteArray(SDL_DBusContext *dbus, DBusMessageIter *options, const char *key, const char *value)
|
||||
{
|
||||
DBusMessageIter options_pair, options_value, options_array;
|
||||
|
||||
dbus->message_iter_open_container(options, DBUS_TYPE_DICT_ENTRY, NULL, &options_pair);
|
||||
dbus->message_iter_append_basic(&options_pair, DBUS_TYPE_STRING, &key);
|
||||
dbus->message_iter_open_container(&options_pair, DBUS_TYPE_VARIANT, "ay", &options_value);
|
||||
dbus->message_iter_open_container(&options_value, DBUS_TYPE_ARRAY, "y", &options_array);
|
||||
do {
|
||||
dbus->message_iter_append_basic(&options_array, DBUS_TYPE_BYTE, value);
|
||||
} while (*value++);
|
||||
dbus->message_iter_close_container(&options_value, &options_array);
|
||||
dbus->message_iter_close_container(&options_pair, &options_value);
|
||||
dbus->message_iter_close_container(options, &options_pair);
|
||||
}
|
||||
|
||||
static DBusHandlerResult DBus_MessageFilter(DBusConnection *conn, DBusMessage *msg, void *data) {
|
||||
SDL_DBusContext *dbus = SDL_DBus_GetContext();
|
||||
SignalCallback *signal_data = (SignalCallback *)data;
|
||||
|
||||
if (dbus->message_is_signal(msg, SIGNAL_INTERFACE, SIGNAL_NAME)
|
||||
&& dbus->message_has_path(msg, signal_data->path)) {
|
||||
DBusMessageIter signal_iter, result_array, array_entry, value_entry, uri_entry;
|
||||
uint32_t result;
|
||||
size_t length = 2, current = 0;
|
||||
const char **path;
|
||||
|
||||
dbus->message_iter_init(msg, &signal_iter);
|
||||
/* Check if the parameters are what we expect */
|
||||
if (dbus->message_iter_get_arg_type(&signal_iter) != DBUS_TYPE_UINT32)
|
||||
goto not_our_signal;
|
||||
dbus->message_iter_get_basic(&signal_iter, &result);
|
||||
|
||||
if (result == 1) {
|
||||
/* cancelled */
|
||||
const char *result_data[] = { NULL };
|
||||
signal_data->callback(signal_data->userdata, result_data, -1); /* TODO: Set this to the last selected filter */
|
||||
goto handled;
|
||||
}
|
||||
else if (result) {
|
||||
/* some error occurred */
|
||||
signal_data->callback(signal_data->userdata, NULL, -1);
|
||||
goto handled;
|
||||
}
|
||||
|
||||
if (!dbus->message_iter_next(&signal_iter))
|
||||
goto not_our_signal;
|
||||
|
||||
if (dbus->message_iter_get_arg_type(&signal_iter) != DBUS_TYPE_ARRAY)
|
||||
goto not_our_signal;
|
||||
dbus->message_iter_recurse(&signal_iter, &result_array);
|
||||
|
||||
while (dbus->message_iter_get_arg_type(&result_array) == DBUS_TYPE_DICT_ENTRY)
|
||||
{
|
||||
const char *method;
|
||||
|
||||
dbus->message_iter_recurse(&result_array, &array_entry);
|
||||
if (dbus->message_iter_get_arg_type(&array_entry) != DBUS_TYPE_STRING)
|
||||
goto not_our_signal;
|
||||
|
||||
dbus->message_iter_get_basic(&array_entry, &method);
|
||||
if (!SDL_strcmp(method, "uris")) {
|
||||
/* we only care about the selected file paths */
|
||||
break;
|
||||
}
|
||||
|
||||
if (!dbus->message_iter_next(&result_array))
|
||||
goto not_our_signal;
|
||||
}
|
||||
|
||||
if (!dbus->message_iter_next(&array_entry))
|
||||
goto not_our_signal;
|
||||
|
||||
if (dbus->message_iter_get_arg_type(&array_entry) != DBUS_TYPE_VARIANT)
|
||||
goto not_our_signal;
|
||||
dbus->message_iter_recurse(&array_entry, &value_entry);
|
||||
|
||||
if (dbus->message_iter_get_arg_type(&value_entry) != DBUS_TYPE_ARRAY)
|
||||
goto not_our_signal;
|
||||
dbus->message_iter_recurse(&value_entry, &uri_entry);
|
||||
|
||||
path = SDL_malloc(sizeof(const char *) * length);
|
||||
if (!path) {
|
||||
SDL_OutOfMemory();
|
||||
signal_data->callback(signal_data->userdata, NULL, -1);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
while (dbus->message_iter_get_arg_type(&uri_entry) == DBUS_TYPE_STRING)
|
||||
{
|
||||
if (current >= length - 1) {
|
||||
++length;
|
||||
path = SDL_realloc(path, sizeof(const char *) * length);
|
||||
if (!path) {
|
||||
SDL_OutOfMemory();
|
||||
signal_data->callback(signal_data->userdata, NULL, -1);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
dbus->message_iter_get_basic(&uri_entry, path + current);
|
||||
|
||||
dbus->message_iter_next(&uri_entry);
|
||||
++current;
|
||||
}
|
||||
path[length - 1] = NULL;
|
||||
signal_data->callback(signal_data->userdata, path, -1); /* TODO: Fetch the index of the filter that was used */
|
||||
cleanup:
|
||||
dbus->connection_remove_filter(conn, &DBus_MessageFilter, signal_data);
|
||||
|
||||
SDL_free(path);
|
||||
SDL_free((void *)signal_data->path);
|
||||
SDL_free(signal_data);
|
||||
handled:
|
||||
return DBUS_HANDLER_RESULT_HANDLED;
|
||||
}
|
||||
not_our_signal:
|
||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
}
|
||||
|
||||
static void DBus_OpenDialog(const char *method, const char *method_title, SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many, int open_folders)
|
||||
{
|
||||
SDL_DBusContext *dbus = SDL_DBus_GetContext();
|
||||
DBusMessage *msg;
|
||||
DBusMessageIter params, options;
|
||||
const char *signal_id = NULL;
|
||||
char *handle_str, *filter;
|
||||
int filter_len;
|
||||
static uint32_t handle_id = 0;
|
||||
static char *default_parent_window = "";
|
||||
SDL_PropertiesID props = SDL_GetWindowProperties(window);
|
||||
|
||||
if (dbus == NULL) {
|
||||
SDL_SetError("Failed to connect to DBus");
|
||||
return;
|
||||
}
|
||||
|
||||
msg = dbus->message_new_method_call(PORTAL_DESTINATION, PORTAL_PATH, PORTAL_INTERFACE, method);
|
||||
if (msg == NULL) {
|
||||
SDL_SetError("Failed to send message to portal");
|
||||
return;
|
||||
}
|
||||
|
||||
dbus->message_iter_init_append(msg, ¶ms);
|
||||
|
||||
handle_str = default_parent_window;
|
||||
if (props) {
|
||||
const char *parent_handle = SDL_GetStringProperty(props, SDL_PROP_WINDOW_WAYLAND_XDG_TOPLEVEL_EXPORT_HANDLE_STRING, NULL);
|
||||
if (parent_handle) {
|
||||
size_t len = SDL_strlen(parent_handle);
|
||||
len += sizeof(WAYLAND_HANDLE_PREFIX) + 1;
|
||||
handle_str = SDL_malloc(len * sizeof(char));
|
||||
if (!handle_str) {
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_snprintf(handle_str, len, "%s%s", WAYLAND_HANDLE_PREFIX, parent_handle);
|
||||
} else {
|
||||
const Uint64 xid = (Uint64)SDL_GetNumberProperty(props, SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0);
|
||||
if (xid) {
|
||||
const size_t len = sizeof(X11_HANDLE_PREFIX) + 24; /* A 64-bit number can be 20 characters max. */
|
||||
handle_str = SDL_malloc(len * sizeof(char));
|
||||
if (!handle_str) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* The portal wants X11 window ID numbers in hex. */
|
||||
SDL_snprintf(handle_str, len, "%s%" SDL_PRIx64, X11_HANDLE_PREFIX, xid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dbus->message_iter_append_basic(¶ms, DBUS_TYPE_STRING, &handle_str);
|
||||
if (handle_str != default_parent_window) {
|
||||
SDL_free(handle_str);
|
||||
}
|
||||
|
||||
dbus->message_iter_append_basic(¶ms, DBUS_TYPE_STRING, &method_title);
|
||||
dbus->message_iter_open_container(¶ms, DBUS_TYPE_ARRAY, "{sv}", &options);
|
||||
|
||||
handle_str = SDL_malloc(sizeof(char) * (HANDLE_LEN + 1));
|
||||
if (!handle_str) {
|
||||
return;
|
||||
}
|
||||
SDL_snprintf(handle_str, HANDLE_LEN, "%u", ++handle_id);
|
||||
DBus_AppendStringOption(dbus, &options, "handle_token", handle_str);
|
||||
SDL_free(handle_str);
|
||||
|
||||
DBus_AppendBoolOption(dbus, &options, "modal", !!window);
|
||||
if (allow_many == SDL_TRUE) {
|
||||
DBus_AppendBoolOption(dbus, &options, "multiple", 1);
|
||||
}
|
||||
if (open_folders) {
|
||||
DBus_AppendBoolOption(dbus, &options, "directory", 1);
|
||||
}
|
||||
if (filters) {
|
||||
DBus_AppendFilters(dbus, &options, filters);
|
||||
}
|
||||
if (default_location) {
|
||||
DBus_AppendByteArray(dbus, &options, "current_folder", default_location);
|
||||
}
|
||||
dbus->message_iter_close_container(¶ms, &options);
|
||||
|
||||
DBusMessage *reply = dbus->connection_send_with_reply_and_block(dbus->session_conn, msg, DBUS_TIMEOUT_INFINITE, NULL);
|
||||
if (reply) {
|
||||
DBusMessageIter reply_iter;
|
||||
dbus->message_iter_init(reply, &reply_iter);
|
||||
|
||||
if (dbus->message_iter_get_arg_type(&reply_iter) == DBUS_TYPE_OBJECT_PATH) {
|
||||
dbus->message_iter_get_basic(&reply_iter, &signal_id);
|
||||
}
|
||||
}
|
||||
|
||||
if (!signal_id) {
|
||||
SDL_SetError("Invalid response received by DBus");
|
||||
goto incorrect_type;
|
||||
}
|
||||
|
||||
dbus->message_unref(msg);
|
||||
|
||||
filter_len = SDL_strlen(SIGNAL_FILTER) + SDL_strlen(signal_id) + 2;
|
||||
filter = SDL_malloc(sizeof(char) * filter_len);
|
||||
if (!filter) {
|
||||
goto incorrect_type;
|
||||
}
|
||||
|
||||
SDL_snprintf(filter, filter_len, SIGNAL_FILTER"%s'", signal_id);
|
||||
dbus->bus_add_match(dbus->session_conn, filter, NULL);
|
||||
SDL_free(filter);
|
||||
|
||||
SignalCallback *data = SDL_malloc(sizeof(SignalCallback));
|
||||
if (!data) {
|
||||
goto incorrect_type;
|
||||
}
|
||||
data->callback = callback;
|
||||
data->userdata = userdata;
|
||||
data->path = SDL_strdup(signal_id);
|
||||
if (!data->path) {
|
||||
SDL_free(data);
|
||||
goto incorrect_type;
|
||||
}
|
||||
|
||||
/* TODO: This should be registered before opening the portal, or the filter will not catch
|
||||
the message if it is sent before we register the filter.
|
||||
*/
|
||||
dbus->connection_add_filter(dbus->session_conn,
|
||||
&DBus_MessageFilter, data, NULL);
|
||||
dbus->connection_flush(dbus->session_conn);
|
||||
|
||||
incorrect_type:
|
||||
dbus->message_unref(reply);
|
||||
}
|
||||
|
||||
void SDL_Portal_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many)
|
||||
{
|
||||
DBus_OpenDialog("OpenFile", "Open File", callback, userdata, window, filters, default_location, allow_many, 0);
|
||||
}
|
||||
|
||||
void SDL_Portal_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location)
|
||||
{
|
||||
DBus_OpenDialog("SaveFile", "Save File", callback, userdata, window, filters, default_location, 0, 0);
|
||||
}
|
||||
|
||||
void SDL_Portal_ShowOpenFolderDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const char* default_location, SDL_bool allow_many)
|
||||
{
|
||||
DBus_OpenDialog("OpenFile", "Open Folder", callback, userdata, window, NULL, default_location, allow_many, 1);
|
||||
}
|
||||
|
||||
int SDL_Portal_detect(void)
|
||||
{
|
||||
SDL_DBusContext *dbus = SDL_DBus_GetContext();
|
||||
DBusMessage *msg = NULL, *reply = NULL;
|
||||
char *reply_str = NULL;
|
||||
DBusMessageIter reply_iter;
|
||||
static int portal_present = -1;
|
||||
|
||||
/* No need for this if the result is cached. */
|
||||
if (portal_present != -1) {
|
||||
return portal_present;
|
||||
}
|
||||
|
||||
portal_present = 0;
|
||||
|
||||
if (!dbus) {
|
||||
SDL_SetError("%s", "Failed to connect to DBus!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Use introspection to get the available services. */
|
||||
msg = dbus->message_new_method_call(PORTAL_DESTINATION, PORTAL_PATH, "org.freedesktop.DBus.Introspectable", "Introspect");
|
||||
if (!msg) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
reply = dbus->connection_send_with_reply_and_block(dbus->session_conn, msg, DBUS_TIMEOUT_INFINITE, NULL);
|
||||
dbus->message_unref(msg);
|
||||
if (!reply) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!dbus->message_iter_init(reply, &reply_iter)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (dbus->message_iter_get_arg_type(&reply_iter) != DBUS_TYPE_STRING) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Introspection gives us a dump of all the services on the destination in XML format, so search the
|
||||
* giant string for the file chooser protocol.
|
||||
*/
|
||||
dbus->message_iter_get_basic(&reply_iter, &reply_str);
|
||||
if (SDL_strstr(reply_str, PORTAL_INTERFACE)) {
|
||||
portal_present = 1; /* Found it! */
|
||||
}
|
||||
|
||||
done:
|
||||
if (reply) {
|
||||
dbus->message_unref(reply);
|
||||
}
|
||||
|
||||
return portal_present;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Dummy implementation to avoid compilation problems */
|
||||
|
||||
void SDL_Portal_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many)
|
||||
{
|
||||
SDL_Unsupported();
|
||||
callback(userdata, NULL, -1);
|
||||
}
|
||||
|
||||
void SDL_Portal_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location)
|
||||
{
|
||||
SDL_Unsupported();
|
||||
callback(userdata, NULL, -1);
|
||||
}
|
||||
|
||||
void SDL_Portal_ShowOpenFolderDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const char* default_location, SDL_bool allow_many)
|
||||
{
|
||||
SDL_Unsupported();
|
||||
callback(userdata, NULL, -1);
|
||||
}
|
||||
|
||||
int SDL_Portal_detect(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* SDL_USE_LIBDBUS */
|
||||
29
external/sdl/SDL/src/dialog/unix/SDL_portaldialog.h
vendored
Normal file
29
external/sdl/SDL/src/dialog/unix/SDL_portaldialog.h
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "SDL_internal.h"
|
||||
|
||||
void SDL_Portal_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many);
|
||||
void SDL_Portal_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location);
|
||||
void SDL_Portal_ShowOpenFolderDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const char* default_location, SDL_bool allow_many);
|
||||
|
||||
/** @returns non-zero if available, zero if unavailable */
|
||||
int SDL_Portal_detect(void);
|
||||
85
external/sdl/SDL/src/dialog/unix/SDL_unixdialog.c
vendored
Normal file
85
external/sdl/SDL/src/dialog/unix/SDL_unixdialog.c
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#include "./SDL_portaldialog.h"
|
||||
#include "./SDL_zenitydialog.h"
|
||||
|
||||
static void (*detected_open)(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many) = NULL;
|
||||
static void (*detected_save)(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location) = NULL;
|
||||
static void (*detected_folder)(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const char* default_location, SDL_bool allow_many) = NULL;
|
||||
|
||||
/* Returns non-zero on success, 0 on failure */
|
||||
static int detect_available_methods(void)
|
||||
{
|
||||
if (SDL_Portal_detect()) {
|
||||
detected_open = SDL_Portal_ShowOpenFileDialog;
|
||||
detected_save = SDL_Portal_ShowSaveFileDialog;
|
||||
detected_folder = SDL_Portal_ShowOpenFolderDialog;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (SDL_Zenity_detect()) {
|
||||
detected_open = SDL_Zenity_ShowOpenFileDialog;
|
||||
detected_save = SDL_Zenity_ShowSaveFileDialog;
|
||||
detected_folder = SDL_Zenity_ShowOpenFolderDialog;
|
||||
return 2;
|
||||
}
|
||||
|
||||
SDL_SetError("No supported method for file dialogs");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many)
|
||||
{
|
||||
/* Call detect_available_methods() again each time in case the situation changed */
|
||||
if (!detected_open && !detect_available_methods()) {
|
||||
/* SetError() done by detect_available_methods() */
|
||||
callback(userdata, NULL, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
detected_open(callback, userdata, window, filters, default_location, allow_many);
|
||||
}
|
||||
|
||||
void SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location)
|
||||
{
|
||||
/* Call detect_available_methods() again each time in case the situation changed */
|
||||
if (!detected_save && !detect_available_methods()) {
|
||||
/* SetError() done by detect_available_methods() */
|
||||
callback(userdata, NULL, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
detected_save(callback, userdata, window, filters, default_location);
|
||||
}
|
||||
|
||||
void SDL_ShowOpenFolderDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const char* default_location, SDL_bool allow_many)
|
||||
{
|
||||
/* Call detect_available_methods() again each time in case the situation changed */
|
||||
if (!detected_folder && !detect_available_methods()) {
|
||||
/* SetError() done by detect_available_methods() */
|
||||
callback(userdata, NULL, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
detected_folder(callback, userdata, window, default_location, allow_many);
|
||||
}
|
||||
488
external/sdl/SDL/src/dialog/unix/SDL_zenitydialog.c
vendored
Normal file
488
external/sdl/SDL/src/dialog/unix/SDL_zenitydialog.c
vendored
Normal file
@@ -0,0 +1,488 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
#include "./SDL_dialog.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ZENITY_MULTIPLE = 0x1,
|
||||
ZENITY_DIRECTORY = 0x2,
|
||||
ZENITY_SAVE = 0x4
|
||||
} zenityFlags;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SDL_DialogFileCallback callback;
|
||||
void* userdata;
|
||||
const char* filename;
|
||||
const SDL_DialogFileFilter *filters;
|
||||
Uint32 flags;
|
||||
} zenityArgs;
|
||||
|
||||
#define CLEAR_AND_RETURN() \
|
||||
{ \
|
||||
while (--nextarg >= 0) { \
|
||||
SDL_free(argv[nextarg]); \
|
||||
} \
|
||||
SDL_free(argv); \
|
||||
return NULL; \
|
||||
}
|
||||
|
||||
#define CHECK_OOM() \
|
||||
{ \
|
||||
if (!argv[nextarg - 1]) { \
|
||||
SDL_OutOfMemory(); \
|
||||
CLEAR_AND_RETURN() \
|
||||
} \
|
||||
\
|
||||
if (nextarg > argc) { \
|
||||
SDL_SetError("Zenity dialog problem: argc (%d) < nextarg (%d)", \
|
||||
argc, nextarg); \
|
||||
CLEAR_AND_RETURN() \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Exec call format:
|
||||
*
|
||||
* /usr/bin/env zenity --file-selection --separator=\n [--multiple]
|
||||
* [--directory] [--save] [--filename FILENAME]
|
||||
* [--file-filter=Filter Name | *.filt *.fn ...]...
|
||||
*/
|
||||
static char** generate_args(const zenityArgs* info)
|
||||
{
|
||||
int argc = 4;
|
||||
int nextarg = 0;
|
||||
char **argv = NULL;
|
||||
|
||||
/* ARGC PASS */
|
||||
if (info->flags & ZENITY_MULTIPLE) {
|
||||
argc++;
|
||||
}
|
||||
|
||||
if (info->flags & ZENITY_DIRECTORY) {
|
||||
argc++;
|
||||
}
|
||||
|
||||
if (info->flags & ZENITY_SAVE) {
|
||||
argc++;
|
||||
}
|
||||
|
||||
if (info->filename) {
|
||||
argc += 2;
|
||||
}
|
||||
|
||||
if (info->filters) {
|
||||
const SDL_DialogFileFilter *filter_ptr = info->filters;
|
||||
|
||||
while (filter_ptr->name && filter_ptr->pattern) {
|
||||
argc++;
|
||||
filter_ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
argv = SDL_malloc(sizeof(char *) * argc + 1);
|
||||
|
||||
if (!argv) {
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
argv[nextarg++] = SDL_strdup("/usr/bin/env");
|
||||
CHECK_OOM()
|
||||
argv[nextarg++] = SDL_strdup("zenity");
|
||||
CHECK_OOM()
|
||||
argv[nextarg++] = SDL_strdup("--file-selection");
|
||||
CHECK_OOM()
|
||||
argv[nextarg++] = SDL_strdup("--separator=\n");
|
||||
CHECK_OOM()
|
||||
|
||||
/* ARGV PASS */
|
||||
if (info->flags & ZENITY_MULTIPLE) {
|
||||
argv[nextarg++] = SDL_strdup("--multiple");
|
||||
CHECK_OOM()
|
||||
}
|
||||
|
||||
if (info->flags & ZENITY_DIRECTORY) {
|
||||
argv[nextarg++] = SDL_strdup("--directory");
|
||||
CHECK_OOM()
|
||||
}
|
||||
|
||||
if (info->flags & ZENITY_SAVE) {
|
||||
argv[nextarg++] = SDL_strdup("--save");
|
||||
CHECK_OOM()
|
||||
}
|
||||
|
||||
if (info->filename) {
|
||||
argv[nextarg++] = SDL_strdup("--filename");
|
||||
CHECK_OOM()
|
||||
|
||||
argv[nextarg++] = SDL_strdup(info->filename);
|
||||
CHECK_OOM()
|
||||
}
|
||||
|
||||
if (info->filters) {
|
||||
const SDL_DialogFileFilter *filter_ptr = info->filters;
|
||||
|
||||
while (filter_ptr->name && filter_ptr->pattern) {
|
||||
/* *Normally*, no filter arg should exceed 4096 bytes. */
|
||||
char buffer[4096];
|
||||
|
||||
SDL_snprintf(buffer, 4096, "--file-filter=%s | *.", filter_ptr->name);
|
||||
size_t i_buf = SDL_strlen(buffer);
|
||||
|
||||
/* "|" is a special character for Zenity */
|
||||
for (char *c = buffer; *c; c++) {
|
||||
if (*c == '|') {
|
||||
*c = ' ';
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i_pat = 0; i_buf < 4095 && filter_ptr->pattern[i_pat]; i_pat++) {
|
||||
const char *c = filter_ptr->pattern + i_pat;
|
||||
|
||||
if (*c == ';') {
|
||||
/* Disallow empty patterns (might bug Zenity) */
|
||||
int at_end = (c[1] == '\0');
|
||||
int at_mid = (c[1] == ';');
|
||||
int at_beg = (i_pat == 0);
|
||||
if (at_end || at_mid || at_beg) {
|
||||
const char *pos_str = "";
|
||||
|
||||
if (at_end) {
|
||||
pos_str = "end";
|
||||
} else if (at_mid) {
|
||||
pos_str = "middle";
|
||||
} else if (at_beg) {
|
||||
pos_str = "beginning";
|
||||
}
|
||||
|
||||
SDL_SetError("Empty pattern file extension (at %s of list)", pos_str);
|
||||
CLEAR_AND_RETURN()
|
||||
}
|
||||
|
||||
if (i_buf + 3 >= 4095) {
|
||||
i_buf += 3;
|
||||
break;
|
||||
}
|
||||
|
||||
buffer[i_buf++] = ' ';
|
||||
buffer[i_buf++] = '*';
|
||||
buffer[i_buf++] = '.';
|
||||
} else if (*c == '*' && (c[1] == '\0' || c[1] == ';') && (i_pat == 0 || *(c - 1) == ';')) {
|
||||
buffer[i_buf++] = '*';
|
||||
} else if (!((*c >= 'a' && *c <= 'z') || (*c >= 'A' && *c <= 'Z') || (*c >= '0' && *c <= '9') || *c == '.' || *c == '_' || *c == '-')) {
|
||||
SDL_SetError("Illegal character in pattern name: %c (Only alphanumeric characters, periods, underscores and hyphens allowed)", *c);
|
||||
CLEAR_AND_RETURN()
|
||||
} else {
|
||||
buffer[i_buf++] = *c;
|
||||
}
|
||||
}
|
||||
|
||||
if (i_buf >= 4095) {
|
||||
SDL_SetError("Filter '%s' wouldn't fit in a 4096 byte buffer; please report your use case if you need filters that long", filter_ptr->name);
|
||||
CLEAR_AND_RETURN()
|
||||
}
|
||||
|
||||
buffer[i_buf] = '\0';
|
||||
|
||||
argv[nextarg++] = SDL_strdup(buffer);
|
||||
CHECK_OOM()
|
||||
|
||||
filter_ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
argv[nextarg++] = NULL;
|
||||
|
||||
return argv;
|
||||
}
|
||||
|
||||
void free_args(char **argv)
|
||||
{
|
||||
char **ptr = argv;
|
||||
|
||||
while (*ptr) {
|
||||
SDL_free(*ptr);
|
||||
ptr++;
|
||||
}
|
||||
|
||||
SDL_free(argv);
|
||||
}
|
||||
|
||||
/* TODO: Zenity survives termination of the parent */
|
||||
|
||||
static void run_zenity(zenityArgs* arg_struct)
|
||||
{
|
||||
SDL_DialogFileCallback callback = arg_struct->callback;
|
||||
void* userdata = arg_struct->userdata;
|
||||
|
||||
int out[2];
|
||||
pid_t process;
|
||||
int status = -1;
|
||||
|
||||
if (pipe(out) < 0) {
|
||||
SDL_SetError("Could not create pipe: %s", strerror(errno));
|
||||
callback(userdata, NULL, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Args are only needed in the forked process, but generating them early
|
||||
allows catching the error messages in the main process */
|
||||
char **args = generate_args(arg_struct);
|
||||
|
||||
if (!args) {
|
||||
/* SDL_SetError will have been called already */
|
||||
callback(userdata, NULL, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
process = fork();
|
||||
|
||||
if (process < 0) {
|
||||
SDL_SetError("Could not fork process: %s", strerror(errno));
|
||||
close(out[0]);
|
||||
close(out[1]);
|
||||
free_args(args);
|
||||
callback(userdata, NULL, -1);
|
||||
return;
|
||||
} else if (process == 0){
|
||||
dup2(out[1], STDOUT_FILENO);
|
||||
close(STDERR_FILENO); /* Hide errors from Zenity to stderr */
|
||||
close(out[0]);
|
||||
close(out[1]);
|
||||
|
||||
/* Recent versions of Zenity have different exit codes, but picks up
|
||||
different codes from the environment */
|
||||
SDL_setenv("ZENITY_OK", "0", 1);
|
||||
SDL_setenv("ZENITY_CANCEL", "1", 1);
|
||||
SDL_setenv("ZENITY_ESC", "1", 1);
|
||||
SDL_setenv("ZENITY_EXTRA", "2", 1);
|
||||
SDL_setenv("ZENITY_ERROR", "2", 1);
|
||||
SDL_setenv("ZENITY_TIMEOUT", "2", 1);
|
||||
|
||||
execv(args[0], args);
|
||||
|
||||
exit(errno + 128);
|
||||
} else {
|
||||
char readbuffer[2048];
|
||||
size_t bytes_read = 0, bytes_last_read;
|
||||
char *container = NULL;
|
||||
close(out[1]);
|
||||
free_args(args);
|
||||
|
||||
while ((bytes_last_read = read(out[0], readbuffer, sizeof(readbuffer)))) {
|
||||
char *new_container = SDL_realloc(container, bytes_read + bytes_last_read);
|
||||
if (!new_container) {
|
||||
SDL_OutOfMemory();
|
||||
SDL_free(container);
|
||||
close(out[0]);
|
||||
callback(userdata, NULL, -1);
|
||||
return;
|
||||
}
|
||||
container = new_container;
|
||||
SDL_memcpy(container + bytes_read, readbuffer, bytes_last_read);
|
||||
bytes_read += bytes_last_read;
|
||||
}
|
||||
close(out[0]);
|
||||
|
||||
if (waitpid(process, &status, 0) == -1) {
|
||||
SDL_SetError("waitpid failed");
|
||||
SDL_free(container);
|
||||
callback(userdata, NULL, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (WIFEXITED(status)) {
|
||||
status = WEXITSTATUS(status);
|
||||
}
|
||||
|
||||
size_t narray = 1;
|
||||
char **array = (char **) SDL_malloc((narray + 1) * sizeof(char *));
|
||||
|
||||
if (!array) {
|
||||
SDL_OutOfMemory();
|
||||
SDL_free(container);
|
||||
callback(userdata, NULL, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
array[0] = container;
|
||||
array[1] = NULL;
|
||||
|
||||
for (int i = 0; i < bytes_read; i++) {
|
||||
if (container[i] == '\n') {
|
||||
container[i] = '\0';
|
||||
/* Reading from a process often leaves a trailing \n, so ignore the last one */
|
||||
if (i < bytes_read - 1) {
|
||||
array[narray] = container + i + 1;
|
||||
narray++;
|
||||
char **new_array = (char **) SDL_realloc(array, (narray + 1) * sizeof(char *));
|
||||
if (!new_array) {
|
||||
SDL_OutOfMemory();
|
||||
SDL_free(container);
|
||||
SDL_free(array);
|
||||
callback(userdata, NULL, -1);
|
||||
return;
|
||||
}
|
||||
array = new_array;
|
||||
array[narray] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 0 = the user chose one or more files, 1 = the user canceled the dialog */
|
||||
if (status == 0 || status == 1) {
|
||||
callback(userdata, (const char * const*) array, -1);
|
||||
} else {
|
||||
SDL_SetError("Could not run zenity: exit code %d (may be zenity or execv+128)", status);
|
||||
callback(userdata, NULL, -1);
|
||||
}
|
||||
|
||||
SDL_free(array);
|
||||
SDL_free(container);
|
||||
}
|
||||
}
|
||||
|
||||
static int run_zenity_thread(void* ptr)
|
||||
{
|
||||
run_zenity(ptr);
|
||||
SDL_free(ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SDL_Zenity_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many)
|
||||
{
|
||||
zenityArgs *args;
|
||||
SDL_Thread *thread;
|
||||
|
||||
args = SDL_malloc(sizeof(*args));
|
||||
if (!args) {
|
||||
SDL_OutOfMemory();
|
||||
callback(userdata, NULL, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
args->callback = callback;
|
||||
args->userdata = userdata;
|
||||
args->filename = default_location;
|
||||
args->filters = filters;
|
||||
args->flags = (allow_many == SDL_TRUE) ? ZENITY_MULTIPLE : 0;
|
||||
|
||||
thread = SDL_CreateThread(run_zenity_thread, "SDL_ShowOpenFileDialog", (void *) args);
|
||||
|
||||
if (thread == NULL) {
|
||||
callback(userdata, NULL, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_DetachThread(thread);
|
||||
}
|
||||
|
||||
void SDL_Zenity_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location)
|
||||
{
|
||||
zenityArgs *args;
|
||||
SDL_Thread *thread;
|
||||
|
||||
args = SDL_malloc(sizeof(zenityArgs));
|
||||
if (args == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
callback(userdata, NULL, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
args->callback = callback;
|
||||
args->userdata = userdata;
|
||||
args->filename = default_location;
|
||||
args->filters = filters;
|
||||
args->flags = ZENITY_SAVE;
|
||||
|
||||
thread = SDL_CreateThread(run_zenity_thread, "SDL_ShowSaveFileDialog", (void *) args);
|
||||
|
||||
if (thread == NULL) {
|
||||
callback(userdata, NULL, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_DetachThread(thread);
|
||||
}
|
||||
|
||||
void SDL_Zenity_ShowOpenFolderDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const char* default_location, SDL_bool allow_many)
|
||||
{
|
||||
zenityArgs *args;
|
||||
SDL_Thread *thread;
|
||||
|
||||
args = SDL_malloc(sizeof(zenityArgs));
|
||||
if (args == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
callback(userdata, NULL, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
args->callback = callback;
|
||||
args->userdata = userdata;
|
||||
args->filename = default_location;
|
||||
args->filters = NULL;
|
||||
args->flags = ((allow_many == SDL_TRUE) ? ZENITY_MULTIPLE : 0) | ZENITY_DIRECTORY;
|
||||
|
||||
thread = SDL_CreateThread(run_zenity_thread, "SDL_ShowOpenFolderDialog", (void *) args);
|
||||
|
||||
if (thread == NULL) {
|
||||
callback(userdata, NULL, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_DetachThread(thread);
|
||||
}
|
||||
|
||||
int SDL_Zenity_detect(void)
|
||||
{
|
||||
pid_t process;
|
||||
int status = -1;
|
||||
|
||||
process = fork();
|
||||
|
||||
if (process < 0) {
|
||||
SDL_SetError("Could not fork process: %s", strerror(errno));
|
||||
return 0;
|
||||
} else if (process == 0){
|
||||
/* Disable output */
|
||||
close(STDERR_FILENO);
|
||||
close(STDOUT_FILENO);
|
||||
execl("/usr/bin/env", "/usr/bin/env", "zenity", "--version", NULL);
|
||||
exit(errno + 128);
|
||||
} else {
|
||||
if (waitpid(process, &status, 0) == -1) {
|
||||
SDL_SetError("waitpid failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (WIFEXITED(status)) {
|
||||
status = WEXITSTATUS(status);
|
||||
}
|
||||
|
||||
return !status;
|
||||
}
|
||||
}
|
||||
29
external/sdl/SDL/src/dialog/unix/SDL_zenitydialog.h
vendored
Normal file
29
external/sdl/SDL/src/dialog/unix/SDL_zenitydialog.h
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "SDL_internal.h"
|
||||
|
||||
void SDL_Zenity_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many);
|
||||
void SDL_Zenity_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location);
|
||||
void SDL_Zenity_ShowOpenFolderDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const char* default_location, SDL_bool allow_many);
|
||||
|
||||
/** @returns non-zero if available, zero if unavailable */
|
||||
int SDL_Zenity_detect(void);
|
||||
489
external/sdl/SDL/src/dialog/windows/SDL_windowsdialog.c
vendored
Normal file
489
external/sdl/SDL/src/dialog/windows/SDL_windowsdialog.c
vendored
Normal file
@@ -0,0 +1,489 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
/* TODO: Macro? */
|
||||
|
||||
/* TODO: Better includes? */
|
||||
#include <windows.h>
|
||||
#include <shlobj.h>
|
||||
#include "../../core/windows/SDL_windows.h"
|
||||
#include "../../thread/SDL_systhread.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int is_save;
|
||||
const SDL_DialogFileFilter *filters;
|
||||
const char* default_file;
|
||||
const char* default_folder;
|
||||
SDL_Window* parent;
|
||||
DWORD flags;
|
||||
SDL_DialogFileCallback callback;
|
||||
void* userdata;
|
||||
} winArgs;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SDL_Window* parent;
|
||||
SDL_DialogFileCallback callback;
|
||||
const char* default_folder;
|
||||
void* userdata;
|
||||
} winFArgs;
|
||||
|
||||
/** Converts dialog.nFilterIndex to SDL-compatible value */
|
||||
int getFilterIndex(int as_reported_by_windows, const SDL_DialogFileFilter *filters)
|
||||
{
|
||||
int filter_index = as_reported_by_windows - 1;
|
||||
|
||||
if (filter_index < 0) {
|
||||
filter_index = 0;
|
||||
for (const SDL_DialogFileFilter *filter = filters; filter && filter->name && filter->pattern; filter++) {
|
||||
filter_index++;
|
||||
}
|
||||
}
|
||||
|
||||
return filter_index;
|
||||
}
|
||||
|
||||
/* TODO: The new version of file dialogs */
|
||||
void windows_ShowFileDialog(void *ptr)
|
||||
{
|
||||
winArgs *args = (winArgs *) ptr;
|
||||
int is_save = args->is_save;
|
||||
const SDL_DialogFileFilter *filters = args->filters;
|
||||
const char* default_file = args->default_file;
|
||||
const char* default_folder = args->default_folder;
|
||||
SDL_Window* parent = args->parent;
|
||||
DWORD flags = args->flags;
|
||||
SDL_DialogFileCallback callback = args->callback;
|
||||
void* userdata = args->userdata;
|
||||
|
||||
/* GetOpenFileName and GetSaveFileName have the same signature
|
||||
(yes, LPOPENFILENAMEW even for the save dialog) */
|
||||
typedef BOOL (WINAPI *pfnGetAnyFileNameW)(LPOPENFILENAMEW);
|
||||
typedef DWORD (WINAPI *pfnCommDlgExtendedError)(void);
|
||||
HMODULE lib = LoadLibraryW(L"Comdlg32.dll");
|
||||
pfnGetAnyFileNameW pGetAnyFileName = NULL;
|
||||
pfnCommDlgExtendedError pCommDlgExtendedError = NULL;
|
||||
|
||||
if (lib) {
|
||||
pGetAnyFileName = (pfnGetAnyFileNameW) GetProcAddress(lib, is_save ? "GetSaveFileNameW" : "GetOpenFileNameW");
|
||||
pCommDlgExtendedError = (pfnCommDlgExtendedError) GetProcAddress(lib, "CommDlgExtendedError");
|
||||
} else {
|
||||
SDL_SetError("Couldn't load Comdlg32.dll");
|
||||
callback(userdata, NULL, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pGetAnyFileName) {
|
||||
SDL_SetError("Couldn't load GetOpenFileName/GetSaveFileName from library");
|
||||
callback(userdata, NULL, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pCommDlgExtendedError) {
|
||||
SDL_SetError("Couldn't load CommDlgExtendedError from library");
|
||||
callback(userdata, NULL, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
HWND window = NULL;
|
||||
|
||||
if (parent) {
|
||||
window = (HWND) SDL_GetProperty(SDL_GetWindowProperties(parent), SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL);
|
||||
}
|
||||
|
||||
wchar_t filebuffer[MAX_PATH] = L"";
|
||||
wchar_t initfolder[MAX_PATH] = L"";
|
||||
|
||||
/* Necessary for the return code below */
|
||||
SDL_memset(filebuffer, 0, MAX_PATH * sizeof(wchar_t));
|
||||
|
||||
if (default_file) {
|
||||
MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, default_file, -1, filebuffer, MAX_PATH);
|
||||
}
|
||||
|
||||
if (default_folder) {
|
||||
MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, default_folder, -1, filebuffer, MAX_PATH);
|
||||
}
|
||||
|
||||
size_t len = 0;
|
||||
for (const SDL_DialogFileFilter *filter = filters; filter && filter->name && filter->pattern; filter++) {
|
||||
const char *pattern_ptr = filter->pattern;
|
||||
len += SDL_strlen(filter->name) + SDL_strlen(filter->pattern) + 4;
|
||||
while (*pattern_ptr) {
|
||||
if (*pattern_ptr == ';') {
|
||||
len += 2;
|
||||
}
|
||||
pattern_ptr++;
|
||||
}
|
||||
}
|
||||
wchar_t *filterlist = SDL_malloc((len + 1) * sizeof(wchar_t));
|
||||
|
||||
if (!filterlist) {
|
||||
SDL_OutOfMemory();
|
||||
callback(userdata, NULL, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
wchar_t *filter_ptr = filterlist;
|
||||
for (const SDL_DialogFileFilter *filter = filters; filter && filter->name && filter->pattern; filter++) {
|
||||
size_t l = SDL_strlen(filter->name);
|
||||
const char *pattern_ptr = filter->pattern;
|
||||
|
||||
MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, filter->name, -1, filter_ptr, MAX_PATH);
|
||||
filter_ptr += l + 1;
|
||||
|
||||
*filter_ptr++ = L'*';
|
||||
*filter_ptr++ = L'.';
|
||||
while (*pattern_ptr) {
|
||||
if (*pattern_ptr == ';') {
|
||||
*filter_ptr++ = L';';
|
||||
*filter_ptr++ = L'*';
|
||||
*filter_ptr++ = L'.';
|
||||
} else if (*pattern_ptr == '*' && (pattern_ptr[1] == '\0' || pattern_ptr[1] == ';')) {
|
||||
*filter_ptr++ = L'*';
|
||||
} else if (!((*pattern_ptr >= 'a' && *pattern_ptr <= 'z') || (*pattern_ptr >= 'A' && *pattern_ptr <= 'Z') || (*pattern_ptr >= '0' && *pattern_ptr <= '9') || *pattern_ptr == '.' || *pattern_ptr == '_' || *pattern_ptr == '-')) {
|
||||
SDL_SetError("Illegal character in pattern name: %c (Only alphanumeric characters, periods, underscores and hyphens allowed)", *pattern_ptr);
|
||||
callback(userdata, NULL, -1);
|
||||
} else {
|
||||
MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, pattern_ptr, 1, filter_ptr, 1);
|
||||
filter_ptr++;
|
||||
}
|
||||
pattern_ptr++;
|
||||
}
|
||||
*filter_ptr++ = '\0';
|
||||
}
|
||||
*filter_ptr = '\0';
|
||||
|
||||
|
||||
OPENFILENAMEW dialog;
|
||||
dialog.lStructSize = sizeof(OPENFILENAME);
|
||||
dialog.hwndOwner = window;
|
||||
dialog.hInstance = 0;
|
||||
dialog.lpstrFilter = filterlist;
|
||||
dialog.lpstrCustomFilter = NULL;
|
||||
dialog.nMaxCustFilter = 0;
|
||||
dialog.nFilterIndex = 0;
|
||||
dialog.lpstrFile = filebuffer;
|
||||
dialog.nMaxFile = MAX_PATH;
|
||||
dialog.lpstrFileTitle = *filebuffer ? filebuffer : NULL;
|
||||
dialog.nMaxFileTitle = MAX_PATH;
|
||||
dialog.lpstrInitialDir = *initfolder ? initfolder : NULL;
|
||||
dialog.lpstrTitle = NULL;
|
||||
dialog.Flags = flags | OFN_EXPLORER | OFN_HIDEREADONLY;
|
||||
dialog.nFileOffset = 0;
|
||||
dialog.nFileExtension = 0;
|
||||
dialog.lpstrDefExt = NULL;
|
||||
dialog.lCustData = 0;
|
||||
dialog.lpfnHook = NULL;
|
||||
dialog.lpTemplateName = NULL;
|
||||
/* Skipped many mac-exclusive and reserved members */
|
||||
dialog.FlagsEx = 0;
|
||||
|
||||
BOOL result = pGetAnyFileName(&dialog);
|
||||
|
||||
SDL_free(filterlist);
|
||||
|
||||
if (result) {
|
||||
if (!(flags & OFN_ALLOWMULTISELECT)) {
|
||||
/* File is a C string stored in dialog.lpstrFile */
|
||||
char *chosen_file = WIN_StringToUTF8W(dialog.lpstrFile);
|
||||
const char* opts[2] = { chosen_file, NULL };
|
||||
callback(userdata, opts, getFilterIndex(dialog.nFilterIndex, filters));
|
||||
SDL_free(chosen_file);
|
||||
} else {
|
||||
/* File is either a C string if the user chose a single file, else
|
||||
it's a series of strings formatted like:
|
||||
|
||||
"C:\\path\\to\\folder\0filename1.ext\0filename2.ext\0\0"
|
||||
|
||||
The code below will only stop on a double NULL in all cases, so
|
||||
it is important that the rest of the buffer has been zeroed. */
|
||||
char chosen_folder[MAX_PATH];
|
||||
char chosen_file[MAX_PATH];
|
||||
wchar_t *file_ptr = dialog.lpstrFile;
|
||||
size_t nfiles = 0;
|
||||
size_t chosen_folder_size;
|
||||
char **chosen_files_list = (char **) SDL_malloc(sizeof(char *) * (nfiles + 1));
|
||||
|
||||
if (!chosen_files_list) {
|
||||
SDL_OutOfMemory();
|
||||
callback(userdata, NULL, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
chosen_files_list[nfiles] = NULL;
|
||||
|
||||
if (WideCharToMultiByte(CP_UTF8, 0, file_ptr, -1, chosen_folder, MAX_PATH, NULL, NULL) >= MAX_PATH) {
|
||||
SDL_SetError("Path too long or invalid character in path");
|
||||
SDL_free(chosen_files_list);
|
||||
callback(userdata, NULL, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
chosen_folder_size = SDL_strlen(chosen_folder);
|
||||
SDL_strlcpy(chosen_file, chosen_folder, MAX_PATH);
|
||||
chosen_file[chosen_folder_size] = '\\';
|
||||
|
||||
file_ptr += SDL_strlen(chosen_folder) + 1;
|
||||
|
||||
while (*file_ptr) {
|
||||
nfiles++;
|
||||
char **new_cfl = (char **) SDL_realloc(chosen_files_list, sizeof(char*) * (nfiles + 1));
|
||||
|
||||
if (!new_cfl) {
|
||||
SDL_OutOfMemory();
|
||||
|
||||
for (size_t i = 0; i < nfiles - 1; i++) {
|
||||
SDL_free(chosen_files_list[i]);
|
||||
}
|
||||
|
||||
SDL_free(chosen_files_list);
|
||||
callback(userdata, NULL, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
chosen_files_list = new_cfl;
|
||||
chosen_files_list[nfiles] = NULL;
|
||||
|
||||
int diff = ((int) chosen_folder_size) + 1;
|
||||
|
||||
if (WideCharToMultiByte(CP_UTF8, 0, file_ptr, -1, chosen_file + diff, MAX_PATH - diff, NULL, NULL) >= MAX_PATH - diff) {
|
||||
SDL_SetError("Path too long or invalid character in path");
|
||||
|
||||
for (size_t i = 0; i < nfiles - 1; i++) {
|
||||
SDL_free(chosen_files_list[i]);
|
||||
}
|
||||
|
||||
SDL_free(chosen_files_list);
|
||||
callback(userdata, NULL, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
file_ptr += SDL_strlen(chosen_file) + 1 - diff;
|
||||
|
||||
chosen_files_list[nfiles - 1] = SDL_strdup(chosen_file);
|
||||
|
||||
if (!chosen_files_list[nfiles - 1]) {
|
||||
SDL_OutOfMemory();
|
||||
|
||||
for (size_t i = 0; i < nfiles - 1; i++) {
|
||||
SDL_free(chosen_files_list[i]);
|
||||
}
|
||||
|
||||
SDL_free(chosen_files_list);
|
||||
callback(userdata, NULL, -1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
callback(userdata, (const char * const*) chosen_files_list, getFilterIndex(dialog.nFilterIndex, filters));
|
||||
|
||||
for (size_t i = 0; i < nfiles; i++) {
|
||||
SDL_free(chosen_files_list[i]);
|
||||
}
|
||||
|
||||
SDL_free(chosen_files_list);
|
||||
}
|
||||
} else {
|
||||
DWORD error = pCommDlgExtendedError();
|
||||
/* Error code 0 means the user clicked the cancel button. */
|
||||
if (error == 0) {
|
||||
/* Unlike SDL's handling of errors, Windows does reset the error
|
||||
code to 0 after calling GetOpenFileName if another Windows
|
||||
function before set a different error code, so it's safe to
|
||||
check for success. */
|
||||
const char* opts[1] = { NULL };
|
||||
callback(userdata, opts, getFilterIndex(dialog.nFilterIndex, filters));
|
||||
} else {
|
||||
SDL_SetError("Windows error, CommDlgExtendedError: %ld", pCommDlgExtendedError());
|
||||
callback(userdata, NULL, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int windows_file_dialog_thread(void* ptr)
|
||||
{
|
||||
windows_ShowFileDialog(ptr);
|
||||
SDL_free(ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CALLBACK browse_callback_proc(
|
||||
HWND hwnd,
|
||||
UINT uMsg,
|
||||
LPARAM lParam,
|
||||
LPARAM lpData)
|
||||
{
|
||||
|
||||
switch (uMsg)
|
||||
{
|
||||
case BFFM_INITIALIZED :
|
||||
if(lpData)
|
||||
{
|
||||
SendMessage(hwnd, BFFM_SETSELECTION, TRUE, lpData);
|
||||
}
|
||||
break;
|
||||
case BFFM_SELCHANGED :
|
||||
break;
|
||||
case BFFM_VALIDATEFAILED :
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void windows_ShowFolderDialog(void* ptr)
|
||||
{
|
||||
winFArgs *args = (winFArgs *) ptr;
|
||||
SDL_Window *window = args->parent;
|
||||
SDL_DialogFileCallback callback = args->callback;
|
||||
void *userdata = args->userdata;
|
||||
|
||||
HWND parent = NULL;
|
||||
|
||||
if (window) {
|
||||
parent = (HWND) SDL_GetProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL);
|
||||
}
|
||||
|
||||
wchar_t buffer[MAX_PATH];
|
||||
|
||||
BROWSEINFOW dialog;
|
||||
dialog.hwndOwner = parent;
|
||||
dialog.pidlRoot = NULL;
|
||||
/* Windows docs say this is `LPTSTR` - apparently it's actually `LPWSTR`*/
|
||||
dialog.pszDisplayName = buffer;
|
||||
dialog.lpszTitle = NULL;
|
||||
dialog.ulFlags = BIF_USENEWUI;
|
||||
dialog.lpfn = browse_callback_proc;
|
||||
dialog.lParam = (LPARAM)args->default_folder;
|
||||
dialog.iImage = 0;
|
||||
|
||||
LPITEMIDLIST lpItem = SHBrowseForFolderW(&dialog);
|
||||
if (lpItem != NULL) {
|
||||
SHGetPathFromIDListW(lpItem, buffer);
|
||||
char *chosen_file = WIN_StringToUTF8W(buffer);
|
||||
const char *files[2] = { chosen_file, NULL };
|
||||
callback(userdata, (const char * const*) files, -1);
|
||||
SDL_free(chosen_file);
|
||||
} else {
|
||||
const char *files[1] = { NULL };
|
||||
callback(userdata, (const char * const*) files, -1);
|
||||
}
|
||||
}
|
||||
|
||||
int windows_folder_dialog_thread(void* ptr)
|
||||
{
|
||||
windows_ShowFolderDialog(ptr);
|
||||
SDL_free(ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SDL_ShowOpenFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location, SDL_bool allow_many)
|
||||
{
|
||||
winArgs *args;
|
||||
SDL_Thread *thread;
|
||||
|
||||
args = SDL_malloc(sizeof(winArgs));
|
||||
if (args == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
callback(userdata, NULL, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
args->is_save = 0;
|
||||
args->filters = filters;
|
||||
args->default_file = default_location;
|
||||
args->default_folder = NULL;
|
||||
args->parent = window;
|
||||
args->flags = (allow_many == SDL_TRUE) ? OFN_ALLOWMULTISELECT : 0;
|
||||
args->callback = callback;
|
||||
args->userdata = userdata;
|
||||
|
||||
thread = SDL_CreateThreadInternal(windows_file_dialog_thread, "SDL_ShowOpenFileDialog", 0, (void *) args);
|
||||
|
||||
if (thread == NULL) {
|
||||
callback(userdata, NULL, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_DetachThread(thread);
|
||||
}
|
||||
|
||||
void SDL_ShowSaveFileDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const SDL_DialogFileFilter *filters, const char* default_location)
|
||||
{
|
||||
winArgs *args;
|
||||
SDL_Thread *thread;
|
||||
|
||||
args = SDL_malloc(sizeof(winArgs));
|
||||
if (args == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
callback(userdata, NULL, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
args->is_save = 1;
|
||||
args->filters = filters;
|
||||
args->default_file = default_location;
|
||||
args->default_folder = NULL;
|
||||
args->parent = window;
|
||||
args->flags = 0;
|
||||
args->callback = callback;
|
||||
args->userdata = userdata;
|
||||
|
||||
thread = SDL_CreateThreadInternal(windows_file_dialog_thread, "SDL_ShowSaveFileDialog", 0, (void *) args);
|
||||
|
||||
if (thread == NULL) {
|
||||
callback(userdata, NULL, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_DetachThread(thread);
|
||||
}
|
||||
|
||||
void SDL_ShowOpenFolderDialog(SDL_DialogFileCallback callback, void* userdata, SDL_Window* window, const char* default_location, SDL_bool allow_many)
|
||||
{
|
||||
winFArgs *args;
|
||||
SDL_Thread *thread;
|
||||
|
||||
args = SDL_malloc(sizeof(winFArgs));
|
||||
if (args == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
callback(userdata, NULL, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
args->parent = window;
|
||||
args->callback = callback;
|
||||
args->default_folder = default_location;
|
||||
args->userdata = userdata;
|
||||
|
||||
thread = SDL_CreateThreadInternal(windows_folder_dialog_thread, "SDL_ShowOpenFolderDialog", 0, (void *) args);
|
||||
|
||||
if (thread == NULL) {
|
||||
callback(userdata, NULL, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_DetachThread(thread);
|
||||
}
|
||||
30
external/sdl/SDL/src/dynapi/SDL_dynapi.c
vendored
30
external/sdl/SDL/src/dynapi/SDL_dynapi.c
vendored
@@ -26,6 +26,9 @@
|
||||
#if SDL_DYNAMIC_API
|
||||
|
||||
#define SDL_DYNAMIC_API_ENVVAR "SDL3_DYNAMIC_API"
|
||||
#define SDL_SLOW_MEMCPY
|
||||
#define SDL_SLOW_MEMMOVE
|
||||
#define SDL_SLOW_MEMSET
|
||||
|
||||
#ifdef HAVE_STDIO_H
|
||||
#include <stdio.h>
|
||||
@@ -143,13 +146,13 @@ static void SDL_InitDynamicAPI(void);
|
||||
va_end(ap); \
|
||||
return retval; \
|
||||
} \
|
||||
_static size_t SDLCALL SDL_RWprintf##name(SDL_RWops *context, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) \
|
||||
_static size_t SDLCALL SDL_IOprintf##name(SDL_IOStream *context, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) \
|
||||
{ \
|
||||
size_t retval; \
|
||||
va_list ap; \
|
||||
initcall; \
|
||||
va_start(ap, fmt); \
|
||||
retval = jump_table.SDL_RWvprintf(context, fmt, ap); \
|
||||
retval = jump_table.SDL_IOvprintf(context, fmt, ap); \
|
||||
va_end(ap); \
|
||||
return retval; \
|
||||
} \
|
||||
@@ -294,13 +297,13 @@ static int SDLCALL SDL_swprintf_LOGSDLCALLS(SDL_OUT_Z_CAP(maxlen) wchar_t *buf,
|
||||
va_end(ap);
|
||||
return retval;
|
||||
}
|
||||
_static size_t SDLCALL SDL_RWprintf_LOGSDLCALLS(SDL_RWops *context, SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
|
||||
_static size_t SDLCALL SDL_IOprintf_LOGSDLCALLS(SDL_IOStream *context, SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
|
||||
{
|
||||
size_t retval;
|
||||
va_list ap;
|
||||
SDL_Log_REAL("SDL3CALL SDL_RWprintf");
|
||||
SDL_Log_REAL("SDL3CALL SDL_IOprintf");
|
||||
va_start(ap, fmt);
|
||||
retval = SDL_RWvprintf_REAL(context, fmt, ap);
|
||||
retval = SDL_IOvprintf_REAL(context, fmt, ap);
|
||||
va_end(ap);
|
||||
return retval;
|
||||
}
|
||||
@@ -407,7 +410,7 @@ Sint32 SDL_DYNAPI_entry(Uint32 apiver, void *table, Uint32 tablesize)
|
||||
|
||||
/* Obviously we can't use SDL_LoadObject() to load SDL. :) */
|
||||
/* Also obviously, we never close the loaded library. */
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__)
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(SDL_PLATFORM_CYGWIN)
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#endif
|
||||
@@ -425,7 +428,7 @@ static SDL_INLINE void *get_sdlapi_entry(const char *fname, const char *sym)
|
||||
return retval;
|
||||
}
|
||||
|
||||
#elif defined(unix) || defined(__unix__) || defined(__APPLE__) || defined(__HAIKU__)
|
||||
#elif defined(SDL_PLATFORM_UNIX) || defined(SDL_PLATFORM_APPLE) || defined(SDL_PLATFORM_HAIKU)
|
||||
#include <dlfcn.h>
|
||||
static SDL_INLINE void *get_sdlapi_entry(const char *fname, const char *sym)
|
||||
{
|
||||
@@ -449,7 +452,7 @@ static void dynapi_warn(const char *msg)
|
||||
const char *caption = "SDL Dynamic API Failure!";
|
||||
(void)caption;
|
||||
/* SDL_ShowSimpleMessageBox() is a too heavy for here. */
|
||||
#if (defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__)) && !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
|
||||
#if (defined(WIN32) || defined(_WIN32) || defined(SDL_PLATFORM_CYGWIN)) && !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
|
||||
MessageBoxA(NULL, msg, caption, MB_OK | MB_ICONERROR);
|
||||
#elif defined(HAVE_STDIO_H)
|
||||
fprintf(stderr, "\n\n%s\n%s\n\n", caption, msg);
|
||||
@@ -535,22 +538,15 @@ static void SDL_InitDynamicAPI(void)
|
||||
*/
|
||||
static SDL_bool already_initialized = SDL_FALSE;
|
||||
|
||||
/* SDL_AtomicLock calls SDL mutex functions to emulate if
|
||||
SDL_ATOMIC_DISABLED, which we can't do here, so in such a
|
||||
configuration, you're on your own. */
|
||||
#ifndef SDL_ATOMIC_DISABLED
|
||||
static SDL_SpinLock lock = 0;
|
||||
SDL_AtomicLock_REAL(&lock);
|
||||
#endif
|
||||
SDL_LockSpinlock_REAL(&lock);
|
||||
|
||||
if (!already_initialized) {
|
||||
SDL_InitDynamicAPILocked();
|
||||
already_initialized = SDL_TRUE;
|
||||
}
|
||||
|
||||
#ifndef SDL_ATOMIC_DISABLED
|
||||
SDL_AtomicUnlock_REAL(&lock);
|
||||
#endif
|
||||
SDL_UnlockSpinlock_REAL(&lock);
|
||||
}
|
||||
|
||||
#else /* SDL_DYNAMIC_API */
|
||||
|
||||
18
external/sdl/SDL/src/dynapi/SDL_dynapi.h
vendored
18
external/sdl/SDL/src/dynapi/SDL_dynapi.h
vendored
@@ -39,31 +39,31 @@
|
||||
#error Nope, you have to edit this file to force this off.
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#ifdef SDL_PLATFORM_APPLE
|
||||
#include "TargetConditionals.h"
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE /* probably not useful on iOS. */
|
||||
#define SDL_DYNAMIC_API 0
|
||||
#elif defined(__ANDROID__) /* probably not useful on Android. */
|
||||
#elif defined(SDL_PLATFORM_ANDROID) /* probably not useful on Android. */
|
||||
#define SDL_DYNAMIC_API 0
|
||||
#elif defined(__EMSCRIPTEN__) && __EMSCRIPTEN__ /* probably not useful on Emscripten. */
|
||||
#elif defined(SDL_PLATFORM_EMSCRIPTEN) /* probably not useful on Emscripten. */
|
||||
#define SDL_DYNAMIC_API 0
|
||||
#elif defined(SDL_BUILDING_WINRT) && SDL_BUILDING_WINRT /* probably not useful on WinRT, given current .dll loading restrictions */
|
||||
#define SDL_DYNAMIC_API 0
|
||||
#elif defined(__PS2__) && __PS2__
|
||||
#elif defined(SDL_PLATFORM_PS2) && SDL_PLATFORM_PS2
|
||||
#define SDL_DYNAMIC_API 0
|
||||
#elif defined(__PSP__) && __PSP__
|
||||
#elif defined(SDL_PLATFORM_PSP) && SDL_PLATFORM_PSP
|
||||
#define SDL_DYNAMIC_API 0
|
||||
#elif defined(__riscos__) && __riscos__ /* probably not useful on RISC OS, since dlopen() can't be used when using static linking. */
|
||||
#elif defined(SDL_PLATFORM_RISCOS) /* probably not useful on RISC OS, since dlopen() can't be used when using static linking. */
|
||||
#define SDL_DYNAMIC_API 0
|
||||
#elif defined(__clang_analyzer__) || defined(SDL_THREAD_SAFETY_ANALYSIS)
|
||||
#define SDL_DYNAMIC_API 0 /* Turn off for static analysis, so reports are more clear. */
|
||||
#elif defined(__VITA__)
|
||||
#elif defined(SDL_PLATFORM_VITA)
|
||||
#define SDL_DYNAMIC_API 0 /* vitasdk doesn't support dynamic linking */
|
||||
#elif defined(__NGAGE__)
|
||||
#elif defined(SDL_PLATFORM_NGAGE)
|
||||
#define SDL_DYNAMIC_API 0 /* The N-Gage doesn't support dynamic linking either */
|
||||
#elif defined(__3DS__)
|
||||
#elif defined(SDL_PLATFORM_3DS)
|
||||
#define SDL_DYNAMIC_API 0 /* devkitARM doesn't support dynamic linking */
|
||||
#elif defined(DYNAPI_NEEDS_DLOPEN) && !defined(HAVE_DLOPEN)
|
||||
#define SDL_DYNAMIC_API 0 /* we need dlopen(), but don't have it.... */
|
||||
|
||||
482
external/sdl/SDL/src/dynapi/SDL_dynapi.sym
vendored
482
external/sdl/SDL/src/dynapi/SDL_dynapi.sym
vendored
@@ -2,11 +2,15 @@ SDL3_0.0.0 {
|
||||
global:
|
||||
JNI_OnLoad;
|
||||
SDL_DYNAPI_entry;
|
||||
SDL_AcquireCameraFrame;
|
||||
SDL_AddEventWatch;
|
||||
SDL_AddGamepadMapping;
|
||||
SDL_AddGamepadMappingsFromRW;
|
||||
SDL_AddGamepadMappingsFromFile;
|
||||
SDL_AddGamepadMappingsFromIO;
|
||||
SDL_AddHintCallback;
|
||||
SDL_AddTimer;
|
||||
SDL_AddVulkanRenderSemaphores;
|
||||
SDL_AllocateEventMemory;
|
||||
SDL_AndroidBackButton;
|
||||
SDL_AndroidGetActivity;
|
||||
SDL_AndroidGetExternalStoragePath;
|
||||
@@ -17,17 +21,17 @@ SDL3_0.0.0 {
|
||||
SDL_AndroidSendMessage;
|
||||
SDL_AndroidShowToast;
|
||||
SDL_AtomicAdd;
|
||||
SDL_AtomicCAS;
|
||||
SDL_AtomicCASPtr;
|
||||
SDL_AtomicCompareAndSwap;
|
||||
SDL_AtomicCompareAndSwapPointer;
|
||||
SDL_AtomicGet;
|
||||
SDL_AtomicGetPtr;
|
||||
SDL_AtomicLock;
|
||||
SDL_AtomicSet;
|
||||
SDL_AtomicSetPtr;
|
||||
SDL_AtomicTryLock;
|
||||
SDL_AtomicUnlock;
|
||||
SDL_AttachVirtualJoystick;
|
||||
SDL_AttachVirtualJoystickEx;
|
||||
SDL_AudioDevicePaused;
|
||||
SDL_BindAudioStream;
|
||||
SDL_BindAudioStreams;
|
||||
SDL_BlitSurface;
|
||||
SDL_BlitSurfaceScaled;
|
||||
SDL_BlitSurfaceUnchecked;
|
||||
@@ -35,35 +39,52 @@ SDL3_0.0.0 {
|
||||
SDL_BroadcastCondition;
|
||||
SDL_CaptureMouse;
|
||||
SDL_CleanupTLS;
|
||||
SDL_ClearAudioStream;
|
||||
SDL_ClearClipboardData;
|
||||
SDL_ClearComposition;
|
||||
SDL_ClearError;
|
||||
SDL_ClearHints;
|
||||
SDL_ClearProperty;
|
||||
SDL_CloseAudioDevice;
|
||||
SDL_CloseCamera;
|
||||
SDL_CloseGamepad;
|
||||
SDL_CloseHaptic;
|
||||
SDL_CloseIO;
|
||||
SDL_CloseJoystick;
|
||||
SDL_CloseSensor;
|
||||
SDL_CloseStorage;
|
||||
SDL_ComposeCustomBlendMode;
|
||||
SDL_ConvertAudioSamples;
|
||||
SDL_ConvertEventToRenderCoordinates;
|
||||
SDL_ConvertPixels;
|
||||
SDL_ConvertPixelsAndColorspace;
|
||||
SDL_ConvertSurface;
|
||||
SDL_ConvertSurfaceFormat;
|
||||
SDL_ConvertSurfaceFormatAndColorspace;
|
||||
SDL_CopyProperties;
|
||||
SDL_CreateAudioStream;
|
||||
SDL_CreateColorCursor;
|
||||
SDL_CreateCondition;
|
||||
SDL_CreateCursor;
|
||||
SDL_CreateDirectory;
|
||||
SDL_CreateHapticEffect;
|
||||
SDL_CreateMutex;
|
||||
SDL_CreatePalette;
|
||||
SDL_CreatePixelFormat;
|
||||
SDL_CreatePopupWindow;
|
||||
SDL_CreateRW;
|
||||
SDL_CreateProperties;
|
||||
SDL_CreateRWLock;
|
||||
SDL_CreateRenderer;
|
||||
SDL_CreateRendererWithProperties;
|
||||
SDL_CreateSemaphore;
|
||||
SDL_CreateSoftwareRenderer;
|
||||
SDL_CreateStorageDirectory;
|
||||
SDL_CreateSurface;
|
||||
SDL_CreateSurfaceFrom;
|
||||
SDL_CreateSystemCursor;
|
||||
SDL_CreateTLS;
|
||||
SDL_CreateTexture;
|
||||
SDL_CreateTextureFromSurface;
|
||||
SDL_CreateTextureWithProperties;
|
||||
SDL_CreateThread;
|
||||
SDL_CreateThreadWithStackSize;
|
||||
SDL_CreateWindow;
|
||||
@@ -71,16 +92,19 @@ SDL3_0.0.0 {
|
||||
SDL_CreateWindowWithProperties;
|
||||
SDL_CursorVisible;
|
||||
SDL_DXGIGetOutputInfo;
|
||||
SDL_DateTimeToTime;
|
||||
SDL_DelEventWatch;
|
||||
SDL_DelHintCallback;
|
||||
SDL_Delay;
|
||||
SDL_DelayNS;
|
||||
SDL_DestroyAudioStream;
|
||||
SDL_DestroyCondition;
|
||||
SDL_DestroyCursor;
|
||||
SDL_DestroyHapticEffect;
|
||||
SDL_DestroyMutex;
|
||||
SDL_DestroyPalette;
|
||||
SDL_DestroyPixelFormat;
|
||||
SDL_DestroyRW;
|
||||
SDL_DestroyProperties;
|
||||
SDL_DestroyRWLock;
|
||||
SDL_DestroyRenderer;
|
||||
SDL_DestroySemaphore;
|
||||
@@ -99,15 +123,22 @@ SDL3_0.0.0 {
|
||||
SDL_EGL_GetWindowEGLSurface;
|
||||
SDL_EGL_SetEGLAttributeCallbacks;
|
||||
SDL_EnableScreenSaver;
|
||||
SDL_EnterAppMainCallbacks;
|
||||
SDL_EnumerateDirectory;
|
||||
SDL_EnumerateProperties;
|
||||
SDL_EnumerateStorageDirectory;
|
||||
SDL_Error;
|
||||
SDL_EventEnabled;
|
||||
SDL_FillSurfaceRect;
|
||||
SDL_FillSurfaceRects;
|
||||
SDL_FilterEvents;
|
||||
SDL_FlashWindow;
|
||||
SDL_FlipSurface;
|
||||
SDL_FlushAudioStream;
|
||||
SDL_FlushEvent;
|
||||
SDL_FlushEvents;
|
||||
SDL_FlushRenderer;
|
||||
SDL_GDKGetDefaultUser;
|
||||
SDL_GDKGetTaskQueue;
|
||||
SDL_GDKSuspendComplete;
|
||||
SDL_GL_CreateContext;
|
||||
@@ -131,25 +162,51 @@ SDL3_0.0.0 {
|
||||
SDL_GamepadEventsEnabled;
|
||||
SDL_GamepadHasAxis;
|
||||
SDL_GamepadHasButton;
|
||||
SDL_GamepadHasLED;
|
||||
SDL_GamepadHasRumble;
|
||||
SDL_GamepadHasRumbleTriggers;
|
||||
SDL_GamepadHasSensor;
|
||||
SDL_GamepadSensorEnabled;
|
||||
SDL_GetAndroidSDKVersion;
|
||||
SDL_GetAssertionHandler;
|
||||
SDL_GetAssertionReport;
|
||||
SDL_GetAudioCaptureDevices;
|
||||
SDL_GetAudioDeviceFormat;
|
||||
SDL_GetAudioDeviceName;
|
||||
SDL_GetAudioDriver;
|
||||
SDL_GetAudioOutputDevices;
|
||||
SDL_GetAudioStreamAvailable;
|
||||
SDL_GetAudioStreamData;
|
||||
SDL_GetAudioStreamDevice;
|
||||
SDL_GetAudioStreamFormat;
|
||||
SDL_GetAudioStreamFrequencyRatio;
|
||||
SDL_GetAudioStreamProperties;
|
||||
SDL_GetAudioStreamQueued;
|
||||
SDL_GetBasePath;
|
||||
SDL_GetBooleanProperty;
|
||||
SDL_GetCPUCacheLineSize;
|
||||
SDL_GetCPUCount;
|
||||
SDL_GetCameraDeviceName;
|
||||
SDL_GetCameraDevicePosition;
|
||||
SDL_GetCameraDeviceSupportedFormats;
|
||||
SDL_GetCameraDevices;
|
||||
SDL_GetCameraDriver;
|
||||
SDL_GetCameraFormat;
|
||||
SDL_GetCameraInstanceID;
|
||||
SDL_GetCameraPermissionState;
|
||||
SDL_GetCameraProperties;
|
||||
SDL_GetClipboardData;
|
||||
SDL_GetClipboardText;
|
||||
SDL_GetClosestFullscreenDisplayMode;
|
||||
SDL_GetCurrentAudioDriver;
|
||||
SDL_GetCurrentCameraDriver;
|
||||
SDL_GetCurrentDisplayMode;
|
||||
SDL_GetCurrentDisplayOrientation;
|
||||
SDL_GetCurrentRenderOutputSize;
|
||||
SDL_GetCurrentThreadID;
|
||||
SDL_GetCurrentTime;
|
||||
SDL_GetCurrentVideoDriver;
|
||||
SDL_GetCursor;
|
||||
SDL_GetDayOfWeek;
|
||||
SDL_GetDayOfYear;
|
||||
SDL_GetDaysInMonth;
|
||||
SDL_GetDefaultAssertionHandler;
|
||||
SDL_GetDefaultCursor;
|
||||
SDL_GetDesktopDisplayMode;
|
||||
@@ -159,10 +216,12 @@ SDL3_0.0.0 {
|
||||
SDL_GetDisplayForRect;
|
||||
SDL_GetDisplayForWindow;
|
||||
SDL_GetDisplayName;
|
||||
SDL_GetDisplayProperties;
|
||||
SDL_GetDisplayUsableBounds;
|
||||
SDL_GetDisplays;
|
||||
SDL_GetError;
|
||||
SDL_GetEventFilter;
|
||||
SDL_GetFloatProperty;
|
||||
SDL_GetFullscreenDisplayModes;
|
||||
SDL_GetGamepadAppleSFSymbolsNameForAxis;
|
||||
SDL_GetGamepadAppleSFSymbolsNameForButton;
|
||||
@@ -171,10 +230,13 @@ SDL3_0.0.0 {
|
||||
SDL_GetGamepadBindings;
|
||||
SDL_GetGamepadButton;
|
||||
SDL_GetGamepadButtonFromString;
|
||||
SDL_GetGamepadButtonLabel;
|
||||
SDL_GetGamepadButtonLabelForType;
|
||||
SDL_GetGamepadFirmwareVersion;
|
||||
SDL_GetGamepadFromInstanceID;
|
||||
SDL_GetGamepadFromPlayerIndex;
|
||||
SDL_GetGamepadInstanceGUID;
|
||||
SDL_GetGamepadInstanceID;
|
||||
SDL_GetGamepadInstanceMapping;
|
||||
SDL_GetGamepadInstanceName;
|
||||
SDL_GetGamepadInstancePath;
|
||||
@@ -186,26 +248,44 @@ SDL3_0.0.0 {
|
||||
SDL_GetGamepadJoystick;
|
||||
SDL_GetGamepadMapping;
|
||||
SDL_GetGamepadMappingForGUID;
|
||||
SDL_GetGamepadMappings;
|
||||
SDL_GetGamepadName;
|
||||
SDL_GetGamepadPath;
|
||||
SDL_GetGamepadPlayerIndex;
|
||||
SDL_GetGamepadPowerLevel;
|
||||
SDL_GetGamepadProduct;
|
||||
SDL_GetGamepadProductVersion;
|
||||
SDL_GetGamepadProperties;
|
||||
SDL_GetGamepadSensorData;
|
||||
SDL_GetGamepadSensorDataRate;
|
||||
SDL_GetGamepadSerial;
|
||||
SDL_GetGamepadSteamHandle;
|
||||
SDL_GetGamepadStringForAxis;
|
||||
SDL_GetGamepadStringForButton;
|
||||
SDL_GetGamepadStringForType;
|
||||
SDL_GetGamepadTouchpadFinger;
|
||||
SDL_GetGamepadType;
|
||||
SDL_GetGamepadTypeFromString;
|
||||
SDL_GetGamepadVendor;
|
||||
SDL_GetGamepads;
|
||||
SDL_GetGlobalMouseState;
|
||||
SDL_GetGlobalProperties;
|
||||
SDL_GetGrabbedWindow;
|
||||
SDL_GetHapticEffectStatus;
|
||||
SDL_GetHapticFeatures;
|
||||
SDL_GetHapticFromInstanceID;
|
||||
SDL_GetHapticInstanceID;
|
||||
SDL_GetHapticInstanceName;
|
||||
SDL_GetHapticName;
|
||||
SDL_GetHaptics;
|
||||
SDL_GetHint;
|
||||
SDL_GetHintBoolean;
|
||||
SDL_GetIOProperties;
|
||||
SDL_GetIOSize;
|
||||
SDL_GetIOStatus;
|
||||
SDL_GetJoystickAxis;
|
||||
SDL_GetJoystickAxisInitialState;
|
||||
SDL_GetJoystickBall;
|
||||
SDL_GetJoystickButton;
|
||||
SDL_GetJoystickFirmwareVersion;
|
||||
SDL_GetJoystickFromInstanceID;
|
||||
@@ -230,6 +310,7 @@ SDL3_0.0.0 {
|
||||
SDL_GetJoystickPowerLevel;
|
||||
SDL_GetJoystickProduct;
|
||||
SDL_GetJoystickProductVersion;
|
||||
SDL_GetJoystickProperties;
|
||||
SDL_GetJoystickSerial;
|
||||
SDL_GetJoystickType;
|
||||
SDL_GetJoystickVendor;
|
||||
@@ -238,24 +319,50 @@ SDL3_0.0.0 {
|
||||
SDL_GetKeyFromScancode;
|
||||
SDL_GetKeyName;
|
||||
SDL_GetKeyboardFocus;
|
||||
SDL_GetKeyboardInstanceName;
|
||||
SDL_GetKeyboardState;
|
||||
SDL_GetKeyboards;
|
||||
SDL_GetLogOutputFunction;
|
||||
SDL_GetMasksForPixelFormatEnum;
|
||||
SDL_GetMaxHapticEffects;
|
||||
SDL_GetMaxHapticEffectsPlaying;
|
||||
SDL_GetMemoryFunctions;
|
||||
SDL_GetMice;
|
||||
SDL_GetModState;
|
||||
SDL_GetMouseFocus;
|
||||
SDL_GetMouseInstanceName;
|
||||
SDL_GetMouseState;
|
||||
SDL_GetNaturalDisplayOrientation;
|
||||
SDL_GetNumAllocations;
|
||||
SDL_GetNumAudioDrivers;
|
||||
SDL_GetNumCameraDrivers;
|
||||
SDL_GetNumGamepadTouchpadFingers;
|
||||
SDL_GetNumGamepadTouchpads;
|
||||
SDL_GetNumHapticAxes;
|
||||
SDL_GetNumJoystickAxes;
|
||||
SDL_GetNumJoystickBalls;
|
||||
SDL_GetNumJoystickButtons;
|
||||
SDL_GetNumJoystickHats;
|
||||
SDL_GetNumRenderDrivers;
|
||||
SDL_GetNumTouchFingers;
|
||||
SDL_GetNumVideoDrivers;
|
||||
SDL_GetNumberProperty;
|
||||
SDL_GetOriginalMemoryFunctions;
|
||||
SDL_GetUserFolder;
|
||||
SDL_GetPathInfo;
|
||||
SDL_GetPenCapabilities;
|
||||
SDL_GetPenCapabilities;
|
||||
SDL_GetPenFromGUID;
|
||||
SDL_GetPenFromGUID;
|
||||
SDL_GetPenGUID;
|
||||
SDL_GetPenGUID;
|
||||
SDL_GetPenName;
|
||||
SDL_GetPenName;
|
||||
SDL_GetPenStatus;
|
||||
SDL_GetPenStatus;
|
||||
SDL_GetPenType;
|
||||
SDL_GetPenType;
|
||||
SDL_GetPens;
|
||||
SDL_GetPens;
|
||||
SDL_GetPerformanceCounter;
|
||||
SDL_GetPerformanceFrequency;
|
||||
SDL_GetPixelFormatEnumForMasks;
|
||||
@@ -266,8 +373,12 @@ SDL3_0.0.0 {
|
||||
SDL_GetPreferredLocales;
|
||||
SDL_GetPrimaryDisplay;
|
||||
SDL_GetPrimarySelectionText;
|
||||
SDL_GetProperty;
|
||||
SDL_GetPropertyType;
|
||||
SDL_GetRGB;
|
||||
SDL_GetRGBA;
|
||||
SDL_GetRealGamepadInstanceType;
|
||||
SDL_GetRealGamepadType;
|
||||
SDL_GetRectAndLineIntersection;
|
||||
SDL_GetRectAndLineIntersectionFloat;
|
||||
SDL_GetRectEnclosingPoints;
|
||||
@@ -279,8 +390,10 @@ SDL3_0.0.0 {
|
||||
SDL_GetRelativeMouseMode;
|
||||
SDL_GetRelativeMouseState;
|
||||
SDL_GetRenderClipRect;
|
||||
SDL_GetRenderColorScale;
|
||||
SDL_GetRenderDrawBlendMode;
|
||||
SDL_GetRenderDrawColor;
|
||||
SDL_GetRenderDrawColorFloat;
|
||||
SDL_GetRenderDriver;
|
||||
SDL_GetRenderLogicalPresentation;
|
||||
SDL_GetRenderMetalCommandEncoder;
|
||||
@@ -292,7 +405,9 @@ SDL3_0.0.0 {
|
||||
SDL_GetRenderViewport;
|
||||
SDL_GetRenderWindow;
|
||||
SDL_GetRenderer;
|
||||
SDL_GetRendererFromTexture;
|
||||
SDL_GetRendererInfo;
|
||||
SDL_GetRendererProperties;
|
||||
SDL_GetRevision;
|
||||
SDL_GetScancodeFromKey;
|
||||
SDL_GetScancodeFromName;
|
||||
@@ -306,26 +421,40 @@ SDL3_0.0.0 {
|
||||
SDL_GetSensorInstanceType;
|
||||
SDL_GetSensorName;
|
||||
SDL_GetSensorNonPortableType;
|
||||
SDL_GetSensorProperties;
|
||||
SDL_GetSensorType;
|
||||
SDL_GetSensors;
|
||||
SDL_GetSilenceValueForFormat;
|
||||
SDL_GetStorageFileSize;
|
||||
SDL_GetStoragePathInfo;
|
||||
SDL_GetStorageSpaceRemaining;
|
||||
SDL_GetStringProperty;
|
||||
SDL_GetSurfaceAlphaMod;
|
||||
SDL_GetSurfaceBlendMode;
|
||||
SDL_GetSurfaceClipRect;
|
||||
SDL_GetSurfaceColorKey;
|
||||
SDL_GetSurfaceColorMod;
|
||||
SDL_GetSurfaceColorspace;
|
||||
SDL_GetSurfaceProperties;
|
||||
SDL_GetSystemRAM;
|
||||
SDL_GetSystemTheme;
|
||||
SDL_GetTLS;
|
||||
SDL_GetTextureAlphaMod;
|
||||
SDL_GetTextureAlphaModFloat;
|
||||
SDL_GetTextureBlendMode;
|
||||
SDL_GetTextureColorMod;
|
||||
SDL_GetTextureColorModFloat;
|
||||
SDL_GetTextureProperties;
|
||||
SDL_GetTextureScaleMode;
|
||||
SDL_GetThreadID;
|
||||
SDL_GetThreadName;
|
||||
SDL_GetTicks;
|
||||
SDL_GetTicksNS;
|
||||
SDL_GetTouchDeviceName;
|
||||
SDL_GetTouchDeviceType;
|
||||
SDL_GetTouchDevices;
|
||||
SDL_GetTouchFinger;
|
||||
SDL_GetUserFolder;
|
||||
SDL_GetVersion;
|
||||
SDL_GetVideoDriver;
|
||||
SDL_GetWindowBordersSize;
|
||||
@@ -333,7 +462,6 @@ SDL3_0.0.0 {
|
||||
SDL_GetWindowFlags;
|
||||
SDL_GetWindowFromID;
|
||||
SDL_GetWindowFullscreenMode;
|
||||
SDL_GetWindowGrab;
|
||||
SDL_GetWindowICCProfile;
|
||||
SDL_GetWindowID;
|
||||
SDL_GetWindowKeyboardGrab;
|
||||
@@ -346,39 +474,13 @@ SDL3_0.0.0 {
|
||||
SDL_GetWindowPixelDensity;
|
||||
SDL_GetWindowPixelFormat;
|
||||
SDL_GetWindowPosition;
|
||||
SDL_GetWindowProperties;
|
||||
SDL_GetWindowSize;
|
||||
SDL_GetWindowSizeInPixels;
|
||||
SDL_GetWindowSurface;
|
||||
SDL_GetWindowTitle;
|
||||
SDL_GetYUVConversionMode;
|
||||
SDL_GetYUVConversionModeForResolution;
|
||||
SDL_HapticClose;
|
||||
SDL_HapticDestroyEffect;
|
||||
SDL_HapticEffectSupported;
|
||||
SDL_HapticGetEffectStatus;
|
||||
SDL_HapticIndex;
|
||||
SDL_HapticName;
|
||||
SDL_HapticNewEffect;
|
||||
SDL_HapticNumAxes;
|
||||
SDL_HapticNumEffects;
|
||||
SDL_HapticNumEffectsPlaying;
|
||||
SDL_HapticOpen;
|
||||
SDL_HapticOpenFromJoystick;
|
||||
SDL_HapticOpenFromMouse;
|
||||
SDL_HapticOpened;
|
||||
SDL_HapticPause;
|
||||
SDL_HapticQuery;
|
||||
SDL_HapticRumbleInit;
|
||||
SDL_HapticRumblePlay;
|
||||
SDL_HapticRumbleStop;
|
||||
SDL_HapticRumbleSupported;
|
||||
SDL_HapticRunEffect;
|
||||
SDL_HapticSetAutocenter;
|
||||
SDL_HapticSetGain;
|
||||
SDL_HapticStopAll;
|
||||
SDL_HapticStopEffect;
|
||||
SDL_HapticUnpause;
|
||||
SDL_HapticUpdateEffect;
|
||||
SDL_HasARMSIMD;
|
||||
SDL_HasAVX2;
|
||||
SDL_HasAVX512F;
|
||||
@@ -388,11 +490,16 @@ SDL3_0.0.0 {
|
||||
SDL_HasClipboardText;
|
||||
SDL_HasEvent;
|
||||
SDL_HasEvents;
|
||||
SDL_HasGamepad;
|
||||
SDL_HasJoystick;
|
||||
SDL_HasKeyboard;
|
||||
SDL_HasLASX;
|
||||
SDL_HasLSX;
|
||||
SDL_HasMMX;
|
||||
SDL_HasMouse;
|
||||
SDL_HasNEON;
|
||||
SDL_HasPrimarySelectionText;
|
||||
SDL_HasProperty;
|
||||
SDL_HasRectIntersection;
|
||||
SDL_HasRectIntersectionFloat;
|
||||
SDL_HasSSE2;
|
||||
@@ -401,35 +508,44 @@ SDL3_0.0.0 {
|
||||
SDL_HasSSE42;
|
||||
SDL_HasSSE;
|
||||
SDL_HasScreenKeyboardSupport;
|
||||
SDL_HasWindowSurface;
|
||||
SDL_HideCursor;
|
||||
SDL_HideWindow;
|
||||
SDL_IOFromConstMem;
|
||||
SDL_IOFromDynamicMem;
|
||||
SDL_IOFromFile;
|
||||
SDL_IOFromMem;
|
||||
SDL_IOprintf;
|
||||
SDL_IOvprintf;
|
||||
SDL_Init;
|
||||
SDL_InitHapticRumble;
|
||||
SDL_InitSubSystem;
|
||||
SDL_IsAndroidTV;
|
||||
SDL_IsChromebook;
|
||||
SDL_IsDeXMode;
|
||||
SDL_IsGamepad;
|
||||
SDL_IsJoystickHaptic;
|
||||
SDL_IsJoystickVirtual;
|
||||
SDL_IsMouseHaptic;
|
||||
SDL_IsTablet;
|
||||
SDL_JoystickConnected;
|
||||
SDL_JoystickEventsEnabled;
|
||||
SDL_JoystickHasLED;
|
||||
SDL_JoystickHasRumble;
|
||||
SDL_JoystickHasRumbleTriggers;
|
||||
SDL_JoystickIsHaptic;
|
||||
SDL_LinuxSetThreadPriority;
|
||||
SDL_LinuxSetThreadPriorityAndPolicy;
|
||||
SDL_LoadBMP;
|
||||
SDL_LoadBMP_RW;
|
||||
SDL_LoadBMP_IO;
|
||||
SDL_LoadFile;
|
||||
SDL_LoadFile_RW;
|
||||
SDL_LoadFile_IO;
|
||||
SDL_LoadFunction;
|
||||
SDL_LoadObject;
|
||||
SDL_LoadWAV;
|
||||
SDL_LoadWAV_IO;
|
||||
SDL_LockAudioStream;
|
||||
SDL_LockJoysticks;
|
||||
SDL_LockMutex;
|
||||
SDL_LockProperties;
|
||||
SDL_LockRWLockForReading;
|
||||
SDL_LockRWLockForWriting;
|
||||
SDL_LockSpinlock;
|
||||
SDL_LockSurface;
|
||||
SDL_LockTexture;
|
||||
SDL_LockTextureToSurface;
|
||||
@@ -437,14 +553,12 @@ SDL3_0.0.0 {
|
||||
SDL_LogCritical;
|
||||
SDL_LogDebug;
|
||||
SDL_LogError;
|
||||
SDL_LogGetOutputFunction;
|
||||
SDL_LogGetPriority;
|
||||
SDL_LogInfo;
|
||||
SDL_LogMessage;
|
||||
SDL_LogMessageV;
|
||||
SDL_LogResetPriorities;
|
||||
SDL_LogSetAllPriority;
|
||||
SDL_LogSetOutputFunction;
|
||||
SDL_LogSetPriority;
|
||||
SDL_LogVerbose;
|
||||
SDL_LogWarn;
|
||||
@@ -457,8 +571,7 @@ SDL3_0.0.0 {
|
||||
SDL_Metal_DestroyView;
|
||||
SDL_Metal_GetLayer;
|
||||
SDL_MinimizeWindow;
|
||||
SDL_MouseIsHaptic;
|
||||
SDL_NumHaptics;
|
||||
SDL_MixAudioFormat;
|
||||
SDL_OnApplicationDidBecomeActive;
|
||||
SDL_OnApplicationDidChangeStatusBarOrientation;
|
||||
SDL_OnApplicationDidEnterBackground;
|
||||
@@ -466,39 +579,62 @@ SDL3_0.0.0 {
|
||||
SDL_OnApplicationWillEnterForeground;
|
||||
SDL_OnApplicationWillResignActive;
|
||||
SDL_OnApplicationWillTerminate;
|
||||
SDL_OpenAudioDevice;
|
||||
SDL_OpenAudioDeviceStream;
|
||||
SDL_OpenCameraDevice;
|
||||
SDL_OpenFileStorage;
|
||||
SDL_OpenGamepad;
|
||||
SDL_OpenHaptic;
|
||||
SDL_OpenHapticFromJoystick;
|
||||
SDL_OpenHapticFromMouse;
|
||||
SDL_OpenIO;
|
||||
SDL_OpenJoystick;
|
||||
SDL_OpenSensor;
|
||||
SDL_OpenStorage;
|
||||
SDL_OpenTitleStorage;
|
||||
SDL_OpenURL;
|
||||
SDL_OpenUserStorage;
|
||||
SDL_PauseAudioDevice;
|
||||
SDL_PauseHaptic;
|
||||
SDL_PeepEvents;
|
||||
SDL_PenConnected;
|
||||
SDL_PenConnected;
|
||||
SDL_PlayHapticRumble;
|
||||
SDL_PollEvent;
|
||||
SDL_PostSemaphore;
|
||||
SDL_PremultiplyAlpha;
|
||||
SDL_PumpEvents;
|
||||
SDL_PushEvent;
|
||||
SDL_PutAudioStreamData;
|
||||
SDL_QueryTexture;
|
||||
SDL_Quit;
|
||||
SDL_QuitSubSystem;
|
||||
SDL_RWFromConstMem;
|
||||
SDL_RWFromFile;
|
||||
SDL_RWFromMem;
|
||||
SDL_RWclose;
|
||||
SDL_RWread;
|
||||
SDL_RWseek;
|
||||
SDL_RWsize;
|
||||
SDL_RWtell;
|
||||
SDL_RWwrite;
|
||||
SDL_RaiseWindow;
|
||||
SDL_ReadIO;
|
||||
SDL_ReadS16BE;
|
||||
SDL_ReadS16LE;
|
||||
SDL_ReadS32BE;
|
||||
SDL_ReadS32LE;
|
||||
SDL_ReadS64BE;
|
||||
SDL_ReadS64LE;
|
||||
SDL_ReadStorageFile;
|
||||
SDL_ReadSurfacePixel;
|
||||
SDL_ReadU16BE;
|
||||
SDL_ReadU32BE;
|
||||
SDL_ReadU64BE;
|
||||
SDL_ReadU16LE;
|
||||
SDL_ReadU32BE;
|
||||
SDL_ReadU32LE;
|
||||
SDL_ReadU64BE;
|
||||
SDL_ReadU64LE;
|
||||
SDL_ReadU8;
|
||||
SDL_RegisterApp;
|
||||
SDL_RegisterEvents;
|
||||
SDL_ReleaseCameraFrame;
|
||||
SDL_ReloadGamepadMappings;
|
||||
SDL_RemovePath;
|
||||
SDL_RemoveStoragePath;
|
||||
SDL_RemoveTimer;
|
||||
SDL_RenamePath;
|
||||
SDL_RenameStoragePath;
|
||||
SDL_RenderClear;
|
||||
SDL_RenderClipEnabled;
|
||||
SDL_RenderCoordinatesFromWindow;
|
||||
@@ -507,6 +643,7 @@ SDL3_0.0.0 {
|
||||
SDL_RenderFillRects;
|
||||
SDL_RenderGeometry;
|
||||
SDL_RenderGeometryRaw;
|
||||
SDL_RenderGeometryRawFloat;
|
||||
SDL_RenderLine;
|
||||
SDL_RenderLines;
|
||||
SDL_RenderPoint;
|
||||
@@ -517,36 +654,51 @@ SDL3_0.0.0 {
|
||||
SDL_RenderRects;
|
||||
SDL_RenderTexture;
|
||||
SDL_RenderTextureRotated;
|
||||
SDL_RenderViewportSet;
|
||||
SDL_ReportAssertion;
|
||||
SDL_ResetAssertionReport;
|
||||
SDL_ResetHint;
|
||||
SDL_ResetHints;
|
||||
SDL_ResetKeyboard;
|
||||
SDL_RestoreWindow;
|
||||
SDL_ResumeAudioDevice;
|
||||
SDL_ResumeHaptic;
|
||||
SDL_RumbleGamepad;
|
||||
SDL_RumbleGamepadTriggers;
|
||||
SDL_RumbleJoystick;
|
||||
SDL_RumbleJoystickTriggers;
|
||||
SDL_RunApp;
|
||||
SDL_RunHapticEffect;
|
||||
SDL_SIMDGetAlignment;
|
||||
SDL_SaveBMP;
|
||||
SDL_SaveBMP_RW;
|
||||
SDL_SaveBMP_IO;
|
||||
SDL_ScreenKeyboardShown;
|
||||
SDL_ScreenSaverEnabled;
|
||||
SDL_SeekIO;
|
||||
SDL_SendGamepadEffect;
|
||||
SDL_SendJoystickEffect;
|
||||
SDL_SetAssertionHandler;
|
||||
SDL_SetAudioPostmixCallback;
|
||||
SDL_SetAudioStreamFormat;
|
||||
SDL_SetAudioStreamFormat;
|
||||
SDL_SetAudioStreamFrequencyRatio;
|
||||
SDL_SetAudioStreamGetCallback;
|
||||
SDL_SetAudioStreamPutCallback;
|
||||
SDL_SetBooleanProperty;
|
||||
SDL_SetClipboardData;
|
||||
SDL_SetClipboardText;
|
||||
SDL_SetCursor;
|
||||
SDL_SetError;
|
||||
SDL_SetEventEnabled;
|
||||
SDL_SetEventFilter;
|
||||
SDL_SetFloatProperty;
|
||||
SDL_SetGamepadEventsEnabled;
|
||||
SDL_SetGamepadLED;
|
||||
SDL_SetGamepadMapping;
|
||||
SDL_SetGamepadPlayerIndex;
|
||||
SDL_SetGamepadSensorEnabled;
|
||||
SDL_SetHapticAutocenter;
|
||||
SDL_SetHapticGain;
|
||||
SDL_SetHint;
|
||||
SDL_SetHintWithPriority;
|
||||
SDL_SetJoystickEventsEnabled;
|
||||
@@ -555,40 +707,50 @@ SDL3_0.0.0 {
|
||||
SDL_SetJoystickVirtualAxis;
|
||||
SDL_SetJoystickVirtualButton;
|
||||
SDL_SetJoystickVirtualHat;
|
||||
SDL_SetLogOutputFunction;
|
||||
SDL_SetMainReady;
|
||||
SDL_SetMemoryFunctions;
|
||||
SDL_SetModState;
|
||||
SDL_SetNumberProperty;
|
||||
SDL_SetPaletteColors;
|
||||
SDL_SetPixelFormatPalette;
|
||||
SDL_SetPrimarySelectionText;
|
||||
SDL_SetProperty;
|
||||
SDL_SetPropertyWithCleanup;
|
||||
SDL_SetRelativeMouseMode;
|
||||
SDL_SetRenderClipRect;
|
||||
SDL_SetRenderColorScale;
|
||||
SDL_SetRenderDrawBlendMode;
|
||||
SDL_SetRenderDrawColor;
|
||||
SDL_SetRenderDrawColorFloat;
|
||||
SDL_SetRenderLogicalPresentation;
|
||||
SDL_SetRenderScale;
|
||||
SDL_SetRenderTarget;
|
||||
SDL_SetRenderVSync;
|
||||
SDL_SetRenderViewport;
|
||||
SDL_SetStringProperty;
|
||||
SDL_SetSurfaceAlphaMod;
|
||||
SDL_SetSurfaceBlendMode;
|
||||
SDL_SetSurfaceClipRect;
|
||||
SDL_SetSurfaceColorKey;
|
||||
SDL_SetSurfaceColorMod;
|
||||
SDL_SetSurfaceColorspace;
|
||||
SDL_SetSurfacePalette;
|
||||
SDL_SetSurfaceRLE;
|
||||
SDL_SetTLS;
|
||||
SDL_SetTextInputRect;
|
||||
SDL_SetTextureAlphaMod;
|
||||
SDL_SetTextureAlphaModFloat;
|
||||
SDL_SetTextureBlendMode;
|
||||
SDL_SetTextureColorMod;
|
||||
SDL_SetTextureColorModFloat;
|
||||
SDL_SetTextureScaleMode;
|
||||
SDL_SetThreadPriority;
|
||||
SDL_SetWindowAlwaysOnTop;
|
||||
SDL_SetWindowBordered;
|
||||
SDL_SetWindowFocusable;
|
||||
SDL_SetWindowFullscreen;
|
||||
SDL_SetWindowFullscreenMode;
|
||||
SDL_SetWindowGrab;
|
||||
SDL_SetWindowHitTest;
|
||||
SDL_SetWindowIcon;
|
||||
SDL_SetWindowInputFocus;
|
||||
@@ -601,35 +763,54 @@ SDL3_0.0.0 {
|
||||
SDL_SetWindowOpacity;
|
||||
SDL_SetWindowPosition;
|
||||
SDL_SetWindowResizable;
|
||||
SDL_SetWindowShape;
|
||||
SDL_SetWindowSize;
|
||||
SDL_SetWindowTitle;
|
||||
SDL_SetWindowsMessageHook;
|
||||
SDL_SetYUVConversionMode;
|
||||
SDL_SetX11EventHook;
|
||||
SDL_ShowCursor;
|
||||
SDL_ShowMessageBox;
|
||||
SDL_ShowOpenFileDialog;
|
||||
SDL_ShowOpenFolderDialog;
|
||||
SDL_ShowSaveFileDialog;
|
||||
SDL_ShowSimpleMessageBox;
|
||||
SDL_ShowWindow;
|
||||
SDL_ShowWindowSystemMenu;
|
||||
SDL_SignalCondition;
|
||||
SDL_SoftStretch;
|
||||
SDL_StartTextInput;
|
||||
SDL_StopHapticEffect;
|
||||
SDL_StopHapticEffects;
|
||||
SDL_StopHapticRumble;
|
||||
SDL_StopTextInput;
|
||||
SDL_StorageReady;
|
||||
SDL_SurfaceHasColorKey;
|
||||
SDL_SurfaceHasRLE;
|
||||
SDL_SyncWindow;
|
||||
SDL_TellIO;
|
||||
SDL_TextInputActive;
|
||||
SDL_TextInputShown;
|
||||
SDL_ThreadID;
|
||||
SDL_TimeFromWindows;
|
||||
SDL_TimeToDateTime;
|
||||
SDL_TimeToWindows;
|
||||
SDL_TryLockMutex;
|
||||
SDL_TryLockRWLockForReading;
|
||||
SDL_TryLockRWLockForWriting;
|
||||
SDL_TryLockSpinlock;
|
||||
SDL_TryWaitSemaphore;
|
||||
SDL_UnbindAudioStream;
|
||||
SDL_UnbindAudioStreams;
|
||||
SDL_UnloadObject;
|
||||
SDL_UnlockAudioStream;
|
||||
SDL_UnlockJoysticks;
|
||||
SDL_UnlockMutex;
|
||||
SDL_UnlockProperties;
|
||||
SDL_UnlockRWLock;
|
||||
SDL_UnlockSpinlock;
|
||||
SDL_UnlockSurface;
|
||||
SDL_UnlockTexture;
|
||||
SDL_UnregisterApp;
|
||||
SDL_UpdateGamepads;
|
||||
SDL_UpdateHapticEffect;
|
||||
SDL_UpdateJoysticks;
|
||||
SDL_UpdateNVTexture;
|
||||
SDL_UpdateSensors;
|
||||
@@ -655,11 +836,19 @@ SDL3_0.0.0 {
|
||||
SDL_WinRTGetDeviceFamily;
|
||||
SDL_WinRTGetFSPathUNICODE;
|
||||
SDL_WinRTGetFSPathUTF8;
|
||||
SDL_WindowHasSurface;
|
||||
SDL_WriteIO;
|
||||
SDL_WriteS16BE;
|
||||
SDL_WriteS16LE;
|
||||
SDL_WriteS32BE;
|
||||
SDL_WriteS32LE;
|
||||
SDL_WriteS64BE;
|
||||
SDL_WriteS64LE;
|
||||
SDL_WriteU16BE;
|
||||
SDL_WriteU32BE;
|
||||
SDL_WriteU64BE;
|
||||
SDL_WriteU16LE;
|
||||
SDL_WriteU32BE;
|
||||
SDL_WriteU32LE;
|
||||
SDL_WriteU64BE;
|
||||
SDL_WriteU64LE;
|
||||
SDL_WriteU8;
|
||||
SDL_abs;
|
||||
@@ -677,6 +866,7 @@ SDL3_0.0.0 {
|
||||
SDL_atof;
|
||||
SDL_atoi;
|
||||
SDL_bsearch;
|
||||
SDL_bsearch_r;
|
||||
SDL_calloc;
|
||||
SDL_ceil;
|
||||
SDL_ceilf;
|
||||
@@ -756,6 +946,7 @@ SDL3_0.0.0 {
|
||||
SDL_pow;
|
||||
SDL_powf;
|
||||
SDL_qsort;
|
||||
SDL_qsort_r;
|
||||
SDL_realloc;
|
||||
SDL_round;
|
||||
SDL_roundf;
|
||||
@@ -779,6 +970,9 @@ SDL3_0.0.0 {
|
||||
SDL_strlwr;
|
||||
SDL_strncasecmp;
|
||||
SDL_strncmp;
|
||||
SDL_strndup;
|
||||
SDL_strnlen;
|
||||
SDL_strnstr;
|
||||
SDL_strrchr;
|
||||
SDL_strrev;
|
||||
SDL_strstr;
|
||||
@@ -814,154 +1008,10 @@ SDL3_0.0.0 {
|
||||
SDL_wcslen;
|
||||
SDL_wcsncasecmp;
|
||||
SDL_wcsncmp;
|
||||
SDL_wcsnlen;
|
||||
SDL_wcsnstr;
|
||||
SDL_wcsstr;
|
||||
SDL_wcstol;
|
||||
SDL_ClearClipboardData;
|
||||
SDL_GetGamepadInstanceID;
|
||||
SDL_GetGamepadPowerLevel;
|
||||
SDL_SetGamepadMapping;
|
||||
SDL_strndup;
|
||||
SDL_GetGamepadTypeFromString;
|
||||
SDL_GetGamepadStringForType;
|
||||
SDL_GetRealGamepadInstanceType;
|
||||
SDL_GetRealGamepadType;
|
||||
SDL_wcsnlen;
|
||||
SDL_strnlen;
|
||||
SDL_AddGamepadMappingsFromFile;
|
||||
SDL_ReloadGamepadMappings;
|
||||
SDL_GetNumAudioDrivers;
|
||||
SDL_GetAudioDriver;
|
||||
SDL_GetCurrentAudioDriver;
|
||||
SDL_GetAudioOutputDevices;
|
||||
SDL_GetAudioCaptureDevices;
|
||||
SDL_GetAudioDeviceName;
|
||||
SDL_GetAudioDeviceFormat;
|
||||
SDL_OpenAudioDevice;
|
||||
SDL_CloseAudioDevice;
|
||||
SDL_BindAudioStreams;
|
||||
SDL_BindAudioStream;
|
||||
SDL_UnbindAudioStreams;
|
||||
SDL_UnbindAudioStream;
|
||||
SDL_CreateAudioStream;
|
||||
SDL_GetAudioStreamFormat;
|
||||
SDL_SetAudioStreamFormat;
|
||||
SDL_PutAudioStreamData;
|
||||
SDL_GetAudioStreamData;
|
||||
SDL_GetAudioStreamAvailable;
|
||||
SDL_FlushAudioStream;
|
||||
SDL_ClearAudioStream;
|
||||
SDL_LockAudioStream;
|
||||
SDL_UnlockAudioStream;
|
||||
SDL_SetAudioStreamGetCallback;
|
||||
SDL_SetAudioStreamPutCallback;
|
||||
SDL_DestroyAudioStream;
|
||||
SDL_OpenAudioDeviceStream;
|
||||
SDL_LoadWAV_RW;
|
||||
SDL_LoadWAV;
|
||||
SDL_MixAudioFormat;
|
||||
SDL_ConvertAudioSamples;
|
||||
SDL_GetSilenceValueForFormat;
|
||||
SDL_PauseAudioDevice;
|
||||
SDL_ResumeAudioDevice;
|
||||
SDL_AudioDevicePaused;
|
||||
SDL_GetAudioStreamDevice;
|
||||
SDL_ShowWindowSystemMenu;
|
||||
SDL_ReadS16LE;
|
||||
SDL_ReadS16BE;
|
||||
SDL_ReadS32LE;
|
||||
SDL_ReadS32BE;
|
||||
SDL_ReadS64LE;
|
||||
SDL_ReadS64BE;
|
||||
SDL_WriteS16LE;
|
||||
SDL_WriteS16BE;
|
||||
SDL_WriteS32LE;
|
||||
SDL_WriteS32BE;
|
||||
SDL_WriteS64LE;
|
||||
SDL_WriteS64BE;
|
||||
SDL_GDKGetDefaultUser;
|
||||
SDL_SetWindowFocusable;
|
||||
SDL_GetAudioStreamFrequencyRatio;
|
||||
SDL_SetAudioStreamFrequencyRatio;
|
||||
SDL_SetAudioPostmixCallback;
|
||||
SDL_GetAudioStreamQueued;
|
||||
SDL_CreateProperties;
|
||||
SDL_LockProperties;
|
||||
SDL_UnlockProperties;
|
||||
SDL_SetProperty;
|
||||
SDL_GetProperty;
|
||||
SDL_DestroyProperties;
|
||||
SDL_GetAudioStreamProperties;
|
||||
SDL_GetGamepadProperties;
|
||||
SDL_GetJoystickProperties;
|
||||
SDL_GetRendererProperties;
|
||||
SDL_GetTextureProperties;
|
||||
SDL_GetRWProperties;
|
||||
SDL_GetSensorProperties;
|
||||
SDL_GetSurfaceProperties;
|
||||
SDL_GetWindowProperties;
|
||||
SDL_ClearProperty;
|
||||
SDL_EnterAppMainCallbacks;
|
||||
SDL_RWprintf;
|
||||
SDL_RWvprintf;
|
||||
SDL_AllocateEventMemory;
|
||||
SDL_GetDisplayProperties;
|
||||
SDL_SetPropertyWithCleanup;
|
||||
SDL_SetX11EventHook;
|
||||
SDL_GetGlobalProperties;
|
||||
SDL_OpenVideoCapture;
|
||||
SDL_SetVideoCaptureSpec;
|
||||
SDL_OpenVideoCaptureWithSpec;
|
||||
SDL_GetVideoCaptureDeviceName;
|
||||
SDL_GetVideoCaptureSpec;
|
||||
SDL_GetVideoCaptureFormat;
|
||||
SDL_GetNumVideoCaptureFormats;
|
||||
SDL_GetVideoCaptureFrameSize;
|
||||
SDL_GetNumVideoCaptureFrameSizes;
|
||||
SDL_GetVideoCaptureStatus;
|
||||
SDL_StartVideoCapture;
|
||||
SDL_AcquireVideoCaptureFrame;
|
||||
SDL_ReleaseVideoCaptureFrame;
|
||||
SDL_StopVideoCapture;
|
||||
SDL_CloseVideoCapture;
|
||||
SDL_GetVideoCaptureDevices;
|
||||
SDL_GetGamepadButtonLabelForType;
|
||||
SDL_GetGamepadButtonLabel;
|
||||
SDL_GetPens;
|
||||
SDL_GetPenStatus;
|
||||
SDL_GetPenFromGUID;
|
||||
SDL_GetPenGUID;
|
||||
SDL_PenConnected;
|
||||
SDL_GetPenName;
|
||||
SDL_GetPenCapabilities;
|
||||
SDL_GetPenType;
|
||||
SDL_GetPens;
|
||||
SDL_GetPenStatus;
|
||||
SDL_GetPenFromGUID;
|
||||
SDL_GetPenGUID;
|
||||
SDL_PenConnected;
|
||||
SDL_GetPenName;
|
||||
SDL_GetPenCapabilities;
|
||||
SDL_GetPenType;
|
||||
SDL_SetStringProperty;
|
||||
SDL_SetNumberProperty;
|
||||
SDL_SetFloatProperty;
|
||||
SDL_GetPropertyType;
|
||||
SDL_GetStringProperty;
|
||||
SDL_GetNumberProperty;
|
||||
SDL_GetFloatProperty;
|
||||
SDL_EnumerateProperties;
|
||||
SDL_SetBooleanProperty;
|
||||
SDL_GetBooleanProperty;
|
||||
SDL_CreateTextureWithProperties;
|
||||
SDL_CreateRendererWithProperties;
|
||||
SDL_GetGamepadMappings;
|
||||
SDL_GetTouchDevices;
|
||||
SDL_GetTouchDeviceName;
|
||||
SDL_strnstr;
|
||||
SDL_wcsnstr;
|
||||
SDL_SyncWindow;
|
||||
SDL_GetGamepadSteamHandle;
|
||||
SDL_GetRendererFromTexture;
|
||||
# extra symbols go here (don't modify this line)
|
||||
local: *;
|
||||
};
|
||||
|
||||
485
external/sdl/SDL/src/dynapi/SDL_dynapi_overrides.h
vendored
485
external/sdl/SDL/src/dynapi/SDL_dynapi_overrides.h
vendored
@@ -26,11 +26,16 @@
|
||||
#error You should not be here.
|
||||
#endif
|
||||
|
||||
/* New API symbols are added at the end */
|
||||
#define SDL_AcquireCameraFrame SDL_AcquireCameraFrame_REAL
|
||||
#define SDL_AddEventWatch SDL_AddEventWatch_REAL
|
||||
#define SDL_AddGamepadMapping SDL_AddGamepadMapping_REAL
|
||||
#define SDL_AddGamepadMappingsFromRW SDL_AddGamepadMappingsFromRW_REAL
|
||||
#define SDL_AddGamepadMappingsFromFile SDL_AddGamepadMappingsFromFile_REAL
|
||||
#define SDL_AddGamepadMappingsFromIO SDL_AddGamepadMappingsFromIO_REAL
|
||||
#define SDL_AddHintCallback SDL_AddHintCallback_REAL
|
||||
#define SDL_AddTimer SDL_AddTimer_REAL
|
||||
#define SDL_AddVulkanRenderSemaphores SDL_AddVulkanRenderSemaphores_REAL
|
||||
#define SDL_AllocateEventMemory SDL_AllocateEventMemory_REAL
|
||||
#define SDL_AndroidBackButton SDL_AndroidBackButton_REAL
|
||||
#define SDL_AndroidGetActivity SDL_AndroidGetActivity_REAL
|
||||
#define SDL_AndroidGetExternalStoragePath SDL_AndroidGetExternalStoragePath_REAL
|
||||
@@ -41,17 +46,17 @@
|
||||
#define SDL_AndroidSendMessage SDL_AndroidSendMessage_REAL
|
||||
#define SDL_AndroidShowToast SDL_AndroidShowToast_REAL
|
||||
#define SDL_AtomicAdd SDL_AtomicAdd_REAL
|
||||
#define SDL_AtomicCAS SDL_AtomicCAS_REAL
|
||||
#define SDL_AtomicCASPtr SDL_AtomicCASPtr_REAL
|
||||
#define SDL_AtomicCompareAndSwap SDL_AtomicCompareAndSwap_REAL
|
||||
#define SDL_AtomicCompareAndSwapPointer SDL_AtomicCompareAndSwapPointer_REAL
|
||||
#define SDL_AtomicGet SDL_AtomicGet_REAL
|
||||
#define SDL_AtomicGetPtr SDL_AtomicGetPtr_REAL
|
||||
#define SDL_AtomicLock SDL_AtomicLock_REAL
|
||||
#define SDL_AtomicSet SDL_AtomicSet_REAL
|
||||
#define SDL_AtomicSetPtr SDL_AtomicSetPtr_REAL
|
||||
#define SDL_AtomicTryLock SDL_AtomicTryLock_REAL
|
||||
#define SDL_AtomicUnlock SDL_AtomicUnlock_REAL
|
||||
#define SDL_AttachVirtualJoystick SDL_AttachVirtualJoystick_REAL
|
||||
#define SDL_AttachVirtualJoystickEx SDL_AttachVirtualJoystickEx_REAL
|
||||
#define SDL_AudioDevicePaused SDL_AudioDevicePaused_REAL
|
||||
#define SDL_BindAudioStream SDL_BindAudioStream_REAL
|
||||
#define SDL_BindAudioStreams SDL_BindAudioStreams_REAL
|
||||
#define SDL_BlitSurface SDL_BlitSurface_REAL
|
||||
#define SDL_BlitSurfaceScaled SDL_BlitSurfaceScaled_REAL
|
||||
#define SDL_BlitSurfaceUnchecked SDL_BlitSurfaceUnchecked_REAL
|
||||
@@ -59,35 +64,52 @@
|
||||
#define SDL_BroadcastCondition SDL_BroadcastCondition_REAL
|
||||
#define SDL_CaptureMouse SDL_CaptureMouse_REAL
|
||||
#define SDL_CleanupTLS SDL_CleanupTLS_REAL
|
||||
#define SDL_ClearAudioStream SDL_ClearAudioStream_REAL
|
||||
#define SDL_ClearClipboardData SDL_ClearClipboardData_REAL
|
||||
#define SDL_ClearComposition SDL_ClearComposition_REAL
|
||||
#define SDL_ClearError SDL_ClearError_REAL
|
||||
#define SDL_ClearHints SDL_ClearHints_REAL
|
||||
#define SDL_ClearProperty SDL_ClearProperty_REAL
|
||||
#define SDL_CloseAudioDevice SDL_CloseAudioDevice_REAL
|
||||
#define SDL_CloseCamera SDL_CloseCamera_REAL
|
||||
#define SDL_CloseGamepad SDL_CloseGamepad_REAL
|
||||
#define SDL_CloseHaptic SDL_CloseHaptic_REAL
|
||||
#define SDL_CloseIO SDL_CloseIO_REAL
|
||||
#define SDL_CloseJoystick SDL_CloseJoystick_REAL
|
||||
#define SDL_CloseSensor SDL_CloseSensor_REAL
|
||||
#define SDL_CloseStorage SDL_CloseStorage_REAL
|
||||
#define SDL_ComposeCustomBlendMode SDL_ComposeCustomBlendMode_REAL
|
||||
#define SDL_ConvertAudioSamples SDL_ConvertAudioSamples_REAL
|
||||
#define SDL_ConvertEventToRenderCoordinates SDL_ConvertEventToRenderCoordinates_REAL
|
||||
#define SDL_ConvertPixels SDL_ConvertPixels_REAL
|
||||
#define SDL_ConvertPixelsAndColorspace SDL_ConvertPixelsAndColorspace_REAL
|
||||
#define SDL_ConvertSurface SDL_ConvertSurface_REAL
|
||||
#define SDL_ConvertSurfaceFormat SDL_ConvertSurfaceFormat_REAL
|
||||
#define SDL_ConvertSurfaceFormatAndColorspace SDL_ConvertSurfaceFormatAndColorspace_REAL
|
||||
#define SDL_CopyProperties SDL_CopyProperties_REAL
|
||||
#define SDL_CreateAudioStream SDL_CreateAudioStream_REAL
|
||||
#define SDL_CreateColorCursor SDL_CreateColorCursor_REAL
|
||||
#define SDL_CreateCondition SDL_CreateCondition_REAL
|
||||
#define SDL_CreateCursor SDL_CreateCursor_REAL
|
||||
#define SDL_CreateDirectory SDL_CreateDirectory_REAL
|
||||
#define SDL_CreateHapticEffect SDL_CreateHapticEffect_REAL
|
||||
#define SDL_CreateMutex SDL_CreateMutex_REAL
|
||||
#define SDL_CreatePalette SDL_CreatePalette_REAL
|
||||
#define SDL_CreatePixelFormat SDL_CreatePixelFormat_REAL
|
||||
#define SDL_CreatePopupWindow SDL_CreatePopupWindow_REAL
|
||||
#define SDL_CreateRW SDL_CreateRW_REAL
|
||||
#define SDL_CreateProperties SDL_CreateProperties_REAL
|
||||
#define SDL_CreateRWLock SDL_CreateRWLock_REAL
|
||||
#define SDL_CreateRenderer SDL_CreateRenderer_REAL
|
||||
#define SDL_CreateRendererWithProperties SDL_CreateRendererWithProperties_REAL
|
||||
#define SDL_CreateSemaphore SDL_CreateSemaphore_REAL
|
||||
#define SDL_CreateSoftwareRenderer SDL_CreateSoftwareRenderer_REAL
|
||||
#define SDL_CreateStorageDirectory SDL_CreateStorageDirectory_REAL
|
||||
#define SDL_CreateSurface SDL_CreateSurface_REAL
|
||||
#define SDL_CreateSurfaceFrom SDL_CreateSurfaceFrom_REAL
|
||||
#define SDL_CreateSystemCursor SDL_CreateSystemCursor_REAL
|
||||
#define SDL_CreateTLS SDL_CreateTLS_REAL
|
||||
#define SDL_CreateTexture SDL_CreateTexture_REAL
|
||||
#define SDL_CreateTextureFromSurface SDL_CreateTextureFromSurface_REAL
|
||||
#define SDL_CreateTextureWithProperties SDL_CreateTextureWithProperties_REAL
|
||||
#define SDL_CreateThread SDL_CreateThread_REAL
|
||||
#define SDL_CreateThreadWithStackSize SDL_CreateThreadWithStackSize_REAL
|
||||
#define SDL_CreateWindow SDL_CreateWindow_REAL
|
||||
@@ -95,16 +117,19 @@
|
||||
#define SDL_CreateWindowWithProperties SDL_CreateWindowWithProperties_REAL
|
||||
#define SDL_CursorVisible SDL_CursorVisible_REAL
|
||||
#define SDL_DXGIGetOutputInfo SDL_DXGIGetOutputInfo_REAL
|
||||
#define SDL_DateTimeToTime SDL_DateTimeToTime_REAL
|
||||
#define SDL_DelEventWatch SDL_DelEventWatch_REAL
|
||||
#define SDL_DelHintCallback SDL_DelHintCallback_REAL
|
||||
#define SDL_Delay SDL_Delay_REAL
|
||||
#define SDL_DelayNS SDL_DelayNS_REAL
|
||||
#define SDL_DestroyAudioStream SDL_DestroyAudioStream_REAL
|
||||
#define SDL_DestroyCondition SDL_DestroyCondition_REAL
|
||||
#define SDL_DestroyCursor SDL_DestroyCursor_REAL
|
||||
#define SDL_DestroyHapticEffect SDL_DestroyHapticEffect_REAL
|
||||
#define SDL_DestroyMutex SDL_DestroyMutex_REAL
|
||||
#define SDL_DestroyPalette SDL_DestroyPalette_REAL
|
||||
#define SDL_DestroyPixelFormat SDL_DestroyPixelFormat_REAL
|
||||
#define SDL_DestroyRW SDL_DestroyRW_REAL
|
||||
#define SDL_DestroyProperties SDL_DestroyProperties_REAL
|
||||
#define SDL_DestroyRWLock SDL_DestroyRWLock_REAL
|
||||
#define SDL_DestroyRenderer SDL_DestroyRenderer_REAL
|
||||
#define SDL_DestroySemaphore SDL_DestroySemaphore_REAL
|
||||
@@ -123,15 +148,22 @@
|
||||
#define SDL_EGL_GetWindowEGLSurface SDL_EGL_GetWindowEGLSurface_REAL
|
||||
#define SDL_EGL_SetEGLAttributeCallbacks SDL_EGL_SetEGLAttributeCallbacks_REAL
|
||||
#define SDL_EnableScreenSaver SDL_EnableScreenSaver_REAL
|
||||
#define SDL_EnterAppMainCallbacks SDL_EnterAppMainCallbacks_REAL
|
||||
#define SDL_EnumerateDirectory SDL_EnumerateDirectory_REAL
|
||||
#define SDL_EnumerateProperties SDL_EnumerateProperties_REAL
|
||||
#define SDL_EnumerateStorageDirectory SDL_EnumerateStorageDirectory_REAL
|
||||
#define SDL_Error SDL_Error_REAL
|
||||
#define SDL_EventEnabled SDL_EventEnabled_REAL
|
||||
#define SDL_FillSurfaceRect SDL_FillSurfaceRect_REAL
|
||||
#define SDL_FillSurfaceRects SDL_FillSurfaceRects_REAL
|
||||
#define SDL_FilterEvents SDL_FilterEvents_REAL
|
||||
#define SDL_FlashWindow SDL_FlashWindow_REAL
|
||||
#define SDL_FlipSurface SDL_FlipSurface_REAL
|
||||
#define SDL_FlushAudioStream SDL_FlushAudioStream_REAL
|
||||
#define SDL_FlushEvent SDL_FlushEvent_REAL
|
||||
#define SDL_FlushEvents SDL_FlushEvents_REAL
|
||||
#define SDL_FlushRenderer SDL_FlushRenderer_REAL
|
||||
#define SDL_GDKGetDefaultUser SDL_GDKGetDefaultUser_REAL
|
||||
#define SDL_GDKGetTaskQueue SDL_GDKGetTaskQueue_REAL
|
||||
#define SDL_GDKSuspendComplete SDL_GDKSuspendComplete_REAL
|
||||
#define SDL_GL_CreateContext SDL_GL_CreateContext_REAL
|
||||
@@ -155,25 +187,51 @@
|
||||
#define SDL_GamepadEventsEnabled SDL_GamepadEventsEnabled_REAL
|
||||
#define SDL_GamepadHasAxis SDL_GamepadHasAxis_REAL
|
||||
#define SDL_GamepadHasButton SDL_GamepadHasButton_REAL
|
||||
#define SDL_GamepadHasLED SDL_GamepadHasLED_REAL
|
||||
#define SDL_GamepadHasRumble SDL_GamepadHasRumble_REAL
|
||||
#define SDL_GamepadHasRumbleTriggers SDL_GamepadHasRumbleTriggers_REAL
|
||||
#define SDL_GamepadHasSensor SDL_GamepadHasSensor_REAL
|
||||
#define SDL_GamepadSensorEnabled SDL_GamepadSensorEnabled_REAL
|
||||
#define SDL_GetAndroidSDKVersion SDL_GetAndroidSDKVersion_REAL
|
||||
#define SDL_GetAssertionHandler SDL_GetAssertionHandler_REAL
|
||||
#define SDL_GetAssertionReport SDL_GetAssertionReport_REAL
|
||||
#define SDL_GetAudioCaptureDevices SDL_GetAudioCaptureDevices_REAL
|
||||
#define SDL_GetAudioDeviceFormat SDL_GetAudioDeviceFormat_REAL
|
||||
#define SDL_GetAudioDeviceName SDL_GetAudioDeviceName_REAL
|
||||
#define SDL_GetAudioDriver SDL_GetAudioDriver_REAL
|
||||
#define SDL_GetAudioOutputDevices SDL_GetAudioOutputDevices_REAL
|
||||
#define SDL_GetAudioStreamAvailable SDL_GetAudioStreamAvailable_REAL
|
||||
#define SDL_GetAudioStreamData SDL_GetAudioStreamData_REAL
|
||||
#define SDL_GetAudioStreamDevice SDL_GetAudioStreamDevice_REAL
|
||||
#define SDL_GetAudioStreamFormat SDL_GetAudioStreamFormat_REAL
|
||||
#define SDL_GetAudioStreamFrequencyRatio SDL_GetAudioStreamFrequencyRatio_REAL
|
||||
#define SDL_GetAudioStreamProperties SDL_GetAudioStreamProperties_REAL
|
||||
#define SDL_GetAudioStreamQueued SDL_GetAudioStreamQueued_REAL
|
||||
#define SDL_GetBasePath SDL_GetBasePath_REAL
|
||||
#define SDL_GetBooleanProperty SDL_GetBooleanProperty_REAL
|
||||
#define SDL_GetCPUCacheLineSize SDL_GetCPUCacheLineSize_REAL
|
||||
#define SDL_GetCPUCount SDL_GetCPUCount_REAL
|
||||
#define SDL_GetCameraDeviceName SDL_GetCameraDeviceName_REAL
|
||||
#define SDL_GetCameraDevicePosition SDL_GetCameraDevicePosition_REAL
|
||||
#define SDL_GetCameraDeviceSupportedFormats SDL_GetCameraDeviceSupportedFormats_REAL
|
||||
#define SDL_GetCameraDevices SDL_GetCameraDevices_REAL
|
||||
#define SDL_GetCameraDriver SDL_GetCameraDriver_REAL
|
||||
#define SDL_GetCameraFormat SDL_GetCameraFormat_REAL
|
||||
#define SDL_GetCameraInstanceID SDL_GetCameraInstanceID_REAL
|
||||
#define SDL_GetCameraPermissionState SDL_GetCameraPermissionState_REAL
|
||||
#define SDL_GetCameraProperties SDL_GetCameraProperties_REAL
|
||||
#define SDL_GetClipboardData SDL_GetClipboardData_REAL
|
||||
#define SDL_GetClipboardText SDL_GetClipboardText_REAL
|
||||
#define SDL_GetClosestFullscreenDisplayMode SDL_GetClosestFullscreenDisplayMode_REAL
|
||||
#define SDL_GetCurrentAudioDriver SDL_GetCurrentAudioDriver_REAL
|
||||
#define SDL_GetCurrentCameraDriver SDL_GetCurrentCameraDriver_REAL
|
||||
#define SDL_GetCurrentDisplayMode SDL_GetCurrentDisplayMode_REAL
|
||||
#define SDL_GetCurrentDisplayOrientation SDL_GetCurrentDisplayOrientation_REAL
|
||||
#define SDL_GetCurrentRenderOutputSize SDL_GetCurrentRenderOutputSize_REAL
|
||||
#define SDL_GetCurrentThreadID SDL_GetCurrentThreadID_REAL
|
||||
#define SDL_GetCurrentTime SDL_GetCurrentTime_REAL
|
||||
#define SDL_GetCurrentVideoDriver SDL_GetCurrentVideoDriver_REAL
|
||||
#define SDL_GetCursor SDL_GetCursor_REAL
|
||||
#define SDL_GetDayOfWeek SDL_GetDayOfWeek_REAL
|
||||
#define SDL_GetDayOfYear SDL_GetDayOfYear_REAL
|
||||
#define SDL_GetDaysInMonth SDL_GetDaysInMonth_REAL
|
||||
#define SDL_GetDefaultAssertionHandler SDL_GetDefaultAssertionHandler_REAL
|
||||
#define SDL_GetDefaultCursor SDL_GetDefaultCursor_REAL
|
||||
#define SDL_GetDesktopDisplayMode SDL_GetDesktopDisplayMode_REAL
|
||||
@@ -183,10 +241,12 @@
|
||||
#define SDL_GetDisplayForRect SDL_GetDisplayForRect_REAL
|
||||
#define SDL_GetDisplayForWindow SDL_GetDisplayForWindow_REAL
|
||||
#define SDL_GetDisplayName SDL_GetDisplayName_REAL
|
||||
#define SDL_GetDisplayProperties SDL_GetDisplayProperties_REAL
|
||||
#define SDL_GetDisplayUsableBounds SDL_GetDisplayUsableBounds_REAL
|
||||
#define SDL_GetDisplays SDL_GetDisplays_REAL
|
||||
#define SDL_GetError SDL_GetError_REAL
|
||||
#define SDL_GetEventFilter SDL_GetEventFilter_REAL
|
||||
#define SDL_GetFloatProperty SDL_GetFloatProperty_REAL
|
||||
#define SDL_GetFullscreenDisplayModes SDL_GetFullscreenDisplayModes_REAL
|
||||
#define SDL_GetGamepadAppleSFSymbolsNameForAxis SDL_GetGamepadAppleSFSymbolsNameForAxis_REAL
|
||||
#define SDL_GetGamepadAppleSFSymbolsNameForButton SDL_GetGamepadAppleSFSymbolsNameForButton_REAL
|
||||
@@ -195,10 +255,13 @@
|
||||
#define SDL_GetGamepadBindings SDL_GetGamepadBindings_REAL
|
||||
#define SDL_GetGamepadButton SDL_GetGamepadButton_REAL
|
||||
#define SDL_GetGamepadButtonFromString SDL_GetGamepadButtonFromString_REAL
|
||||
#define SDL_GetGamepadButtonLabel SDL_GetGamepadButtonLabel_REAL
|
||||
#define SDL_GetGamepadButtonLabelForType SDL_GetGamepadButtonLabelForType_REAL
|
||||
#define SDL_GetGamepadFirmwareVersion SDL_GetGamepadFirmwareVersion_REAL
|
||||
#define SDL_GetGamepadFromInstanceID SDL_GetGamepadFromInstanceID_REAL
|
||||
#define SDL_GetGamepadFromPlayerIndex SDL_GetGamepadFromPlayerIndex_REAL
|
||||
#define SDL_GetGamepadInstanceGUID SDL_GetGamepadInstanceGUID_REAL
|
||||
#define SDL_GetGamepadInstanceID SDL_GetGamepadInstanceID_REAL
|
||||
#define SDL_GetGamepadInstanceMapping SDL_GetGamepadInstanceMapping_REAL
|
||||
#define SDL_GetGamepadInstanceName SDL_GetGamepadInstanceName_REAL
|
||||
#define SDL_GetGamepadInstancePath SDL_GetGamepadInstancePath_REAL
|
||||
@@ -210,26 +273,44 @@
|
||||
#define SDL_GetGamepadJoystick SDL_GetGamepadJoystick_REAL
|
||||
#define SDL_GetGamepadMapping SDL_GetGamepadMapping_REAL
|
||||
#define SDL_GetGamepadMappingForGUID SDL_GetGamepadMappingForGUID_REAL
|
||||
#define SDL_GetGamepadMappings SDL_GetGamepadMappings_REAL
|
||||
#define SDL_GetGamepadName SDL_GetGamepadName_REAL
|
||||
#define SDL_GetGamepadPath SDL_GetGamepadPath_REAL
|
||||
#define SDL_GetGamepadPlayerIndex SDL_GetGamepadPlayerIndex_REAL
|
||||
#define SDL_GetGamepadPowerLevel SDL_GetGamepadPowerLevel_REAL
|
||||
#define SDL_GetGamepadProduct SDL_GetGamepadProduct_REAL
|
||||
#define SDL_GetGamepadProductVersion SDL_GetGamepadProductVersion_REAL
|
||||
#define SDL_GetGamepadProperties SDL_GetGamepadProperties_REAL
|
||||
#define SDL_GetGamepadSensorData SDL_GetGamepadSensorData_REAL
|
||||
#define SDL_GetGamepadSensorDataRate SDL_GetGamepadSensorDataRate_REAL
|
||||
#define SDL_GetGamepadSerial SDL_GetGamepadSerial_REAL
|
||||
#define SDL_GetGamepadSteamHandle SDL_GetGamepadSteamHandle_REAL
|
||||
#define SDL_GetGamepadStringForAxis SDL_GetGamepadStringForAxis_REAL
|
||||
#define SDL_GetGamepadStringForButton SDL_GetGamepadStringForButton_REAL
|
||||
#define SDL_GetGamepadStringForType SDL_GetGamepadStringForType_REAL
|
||||
#define SDL_GetGamepadTouchpadFinger SDL_GetGamepadTouchpadFinger_REAL
|
||||
#define SDL_GetGamepadType SDL_GetGamepadType_REAL
|
||||
#define SDL_GetGamepadTypeFromString SDL_GetGamepadTypeFromString_REAL
|
||||
#define SDL_GetGamepadVendor SDL_GetGamepadVendor_REAL
|
||||
#define SDL_GetGamepads SDL_GetGamepads_REAL
|
||||
#define SDL_GetGlobalMouseState SDL_GetGlobalMouseState_REAL
|
||||
#define SDL_GetGlobalProperties SDL_GetGlobalProperties_REAL
|
||||
#define SDL_GetGrabbedWindow SDL_GetGrabbedWindow_REAL
|
||||
#define SDL_GetHapticEffectStatus SDL_GetHapticEffectStatus_REAL
|
||||
#define SDL_GetHapticFeatures SDL_GetHapticFeatures_REAL
|
||||
#define SDL_GetHapticFromInstanceID SDL_GetHapticFromInstanceID_REAL
|
||||
#define SDL_GetHapticInstanceID SDL_GetHapticInstanceID_REAL
|
||||
#define SDL_GetHapticInstanceName SDL_GetHapticInstanceName_REAL
|
||||
#define SDL_GetHapticName SDL_GetHapticName_REAL
|
||||
#define SDL_GetHaptics SDL_GetHaptics_REAL
|
||||
#define SDL_GetHint SDL_GetHint_REAL
|
||||
#define SDL_GetHintBoolean SDL_GetHintBoolean_REAL
|
||||
#define SDL_GetIOProperties SDL_GetIOProperties_REAL
|
||||
#define SDL_GetIOSize SDL_GetIOSize_REAL
|
||||
#define SDL_GetIOStatus SDL_GetIOStatus_REAL
|
||||
#define SDL_GetJoystickAxis SDL_GetJoystickAxis_REAL
|
||||
#define SDL_GetJoystickAxisInitialState SDL_GetJoystickAxisInitialState_REAL
|
||||
#define SDL_GetJoystickBall SDL_GetJoystickBall_REAL
|
||||
#define SDL_GetJoystickButton SDL_GetJoystickButton_REAL
|
||||
#define SDL_GetJoystickFirmwareVersion SDL_GetJoystickFirmwareVersion_REAL
|
||||
#define SDL_GetJoystickFromInstanceID SDL_GetJoystickFromInstanceID_REAL
|
||||
@@ -254,6 +335,7 @@
|
||||
#define SDL_GetJoystickPowerLevel SDL_GetJoystickPowerLevel_REAL
|
||||
#define SDL_GetJoystickProduct SDL_GetJoystickProduct_REAL
|
||||
#define SDL_GetJoystickProductVersion SDL_GetJoystickProductVersion_REAL
|
||||
#define SDL_GetJoystickProperties SDL_GetJoystickProperties_REAL
|
||||
#define SDL_GetJoystickSerial SDL_GetJoystickSerial_REAL
|
||||
#define SDL_GetJoystickType SDL_GetJoystickType_REAL
|
||||
#define SDL_GetJoystickVendor SDL_GetJoystickVendor_REAL
|
||||
@@ -262,24 +344,50 @@
|
||||
#define SDL_GetKeyFromScancode SDL_GetKeyFromScancode_REAL
|
||||
#define SDL_GetKeyName SDL_GetKeyName_REAL
|
||||
#define SDL_GetKeyboardFocus SDL_GetKeyboardFocus_REAL
|
||||
#define SDL_GetKeyboardInstanceName SDL_GetKeyboardInstanceName_REAL
|
||||
#define SDL_GetKeyboardState SDL_GetKeyboardState_REAL
|
||||
#define SDL_GetKeyboards SDL_GetKeyboards_REAL
|
||||
#define SDL_GetLogOutputFunction SDL_GetLogOutputFunction_REAL
|
||||
#define SDL_GetMasksForPixelFormatEnum SDL_GetMasksForPixelFormatEnum_REAL
|
||||
#define SDL_GetMaxHapticEffects SDL_GetMaxHapticEffects_REAL
|
||||
#define SDL_GetMaxHapticEffectsPlaying SDL_GetMaxHapticEffectsPlaying_REAL
|
||||
#define SDL_GetMemoryFunctions SDL_GetMemoryFunctions_REAL
|
||||
#define SDL_GetMice SDL_GetMice_REAL
|
||||
#define SDL_GetModState SDL_GetModState_REAL
|
||||
#define SDL_GetMouseFocus SDL_GetMouseFocus_REAL
|
||||
#define SDL_GetMouseInstanceName SDL_GetMouseInstanceName_REAL
|
||||
#define SDL_GetMouseState SDL_GetMouseState_REAL
|
||||
#define SDL_GetNaturalDisplayOrientation SDL_GetNaturalDisplayOrientation_REAL
|
||||
#define SDL_GetNumAllocations SDL_GetNumAllocations_REAL
|
||||
#define SDL_GetNumAudioDrivers SDL_GetNumAudioDrivers_REAL
|
||||
#define SDL_GetNumCameraDrivers SDL_GetNumCameraDrivers_REAL
|
||||
#define SDL_GetNumGamepadTouchpadFingers SDL_GetNumGamepadTouchpadFingers_REAL
|
||||
#define SDL_GetNumGamepadTouchpads SDL_GetNumGamepadTouchpads_REAL
|
||||
#define SDL_GetNumHapticAxes SDL_GetNumHapticAxes_REAL
|
||||
#define SDL_GetNumJoystickAxes SDL_GetNumJoystickAxes_REAL
|
||||
#define SDL_GetNumJoystickBalls SDL_GetNumJoystickBalls_REAL
|
||||
#define SDL_GetNumJoystickButtons SDL_GetNumJoystickButtons_REAL
|
||||
#define SDL_GetNumJoystickHats SDL_GetNumJoystickHats_REAL
|
||||
#define SDL_GetNumRenderDrivers SDL_GetNumRenderDrivers_REAL
|
||||
#define SDL_GetNumTouchFingers SDL_GetNumTouchFingers_REAL
|
||||
#define SDL_GetNumVideoDrivers SDL_GetNumVideoDrivers_REAL
|
||||
#define SDL_GetNumberProperty SDL_GetNumberProperty_REAL
|
||||
#define SDL_GetOriginalMemoryFunctions SDL_GetOriginalMemoryFunctions_REAL
|
||||
#define SDL_GetUserFolder SDL_GetUserFolder_REAL
|
||||
#define SDL_GetPathInfo SDL_GetPathInfo_REAL
|
||||
#define SDL_GetPenCapabilities SDL_GetPenCapabilities_REAL
|
||||
#define SDL_GetPenCapabilities SDL_GetPenCapabilities_REAL
|
||||
#define SDL_GetPenFromGUID SDL_GetPenFromGUID_REAL
|
||||
#define SDL_GetPenFromGUID SDL_GetPenFromGUID_REAL
|
||||
#define SDL_GetPenGUID SDL_GetPenGUID_REAL
|
||||
#define SDL_GetPenGUID SDL_GetPenGUID_REAL
|
||||
#define SDL_GetPenName SDL_GetPenName_REAL
|
||||
#define SDL_GetPenName SDL_GetPenName_REAL
|
||||
#define SDL_GetPenStatus SDL_GetPenStatus_REAL
|
||||
#define SDL_GetPenStatus SDL_GetPenStatus_REAL
|
||||
#define SDL_GetPenType SDL_GetPenType_REAL
|
||||
#define SDL_GetPenType SDL_GetPenType_REAL
|
||||
#define SDL_GetPens SDL_GetPens_REAL
|
||||
#define SDL_GetPens SDL_GetPens_REAL
|
||||
#define SDL_GetPerformanceCounter SDL_GetPerformanceCounter_REAL
|
||||
#define SDL_GetPerformanceFrequency SDL_GetPerformanceFrequency_REAL
|
||||
#define SDL_GetPixelFormatEnumForMasks SDL_GetPixelFormatEnumForMasks_REAL
|
||||
@@ -290,8 +398,12 @@
|
||||
#define SDL_GetPreferredLocales SDL_GetPreferredLocales_REAL
|
||||
#define SDL_GetPrimaryDisplay SDL_GetPrimaryDisplay_REAL
|
||||
#define SDL_GetPrimarySelectionText SDL_GetPrimarySelectionText_REAL
|
||||
#define SDL_GetProperty SDL_GetProperty_REAL
|
||||
#define SDL_GetPropertyType SDL_GetPropertyType_REAL
|
||||
#define SDL_GetRGB SDL_GetRGB_REAL
|
||||
#define SDL_GetRGBA SDL_GetRGBA_REAL
|
||||
#define SDL_GetRealGamepadInstanceType SDL_GetRealGamepadInstanceType_REAL
|
||||
#define SDL_GetRealGamepadType SDL_GetRealGamepadType_REAL
|
||||
#define SDL_GetRectAndLineIntersection SDL_GetRectAndLineIntersection_REAL
|
||||
#define SDL_GetRectAndLineIntersectionFloat SDL_GetRectAndLineIntersectionFloat_REAL
|
||||
#define SDL_GetRectEnclosingPoints SDL_GetRectEnclosingPoints_REAL
|
||||
@@ -303,8 +415,10 @@
|
||||
#define SDL_GetRelativeMouseMode SDL_GetRelativeMouseMode_REAL
|
||||
#define SDL_GetRelativeMouseState SDL_GetRelativeMouseState_REAL
|
||||
#define SDL_GetRenderClipRect SDL_GetRenderClipRect_REAL
|
||||
#define SDL_GetRenderColorScale SDL_GetRenderColorScale_REAL
|
||||
#define SDL_GetRenderDrawBlendMode SDL_GetRenderDrawBlendMode_REAL
|
||||
#define SDL_GetRenderDrawColor SDL_GetRenderDrawColor_REAL
|
||||
#define SDL_GetRenderDrawColorFloat SDL_GetRenderDrawColorFloat_REAL
|
||||
#define SDL_GetRenderDriver SDL_GetRenderDriver_REAL
|
||||
#define SDL_GetRenderLogicalPresentation SDL_GetRenderLogicalPresentation_REAL
|
||||
#define SDL_GetRenderMetalCommandEncoder SDL_GetRenderMetalCommandEncoder_REAL
|
||||
@@ -316,7 +430,9 @@
|
||||
#define SDL_GetRenderViewport SDL_GetRenderViewport_REAL
|
||||
#define SDL_GetRenderWindow SDL_GetRenderWindow_REAL
|
||||
#define SDL_GetRenderer SDL_GetRenderer_REAL
|
||||
#define SDL_GetRendererFromTexture SDL_GetRendererFromTexture_REAL
|
||||
#define SDL_GetRendererInfo SDL_GetRendererInfo_REAL
|
||||
#define SDL_GetRendererProperties SDL_GetRendererProperties_REAL
|
||||
#define SDL_GetRevision SDL_GetRevision_REAL
|
||||
#define SDL_GetScancodeFromKey SDL_GetScancodeFromKey_REAL
|
||||
#define SDL_GetScancodeFromName SDL_GetScancodeFromName_REAL
|
||||
@@ -330,26 +446,40 @@
|
||||
#define SDL_GetSensorInstanceType SDL_GetSensorInstanceType_REAL
|
||||
#define SDL_GetSensorName SDL_GetSensorName_REAL
|
||||
#define SDL_GetSensorNonPortableType SDL_GetSensorNonPortableType_REAL
|
||||
#define SDL_GetSensorProperties SDL_GetSensorProperties_REAL
|
||||
#define SDL_GetSensorType SDL_GetSensorType_REAL
|
||||
#define SDL_GetSensors SDL_GetSensors_REAL
|
||||
#define SDL_GetSilenceValueForFormat SDL_GetSilenceValueForFormat_REAL
|
||||
#define SDL_GetStorageFileSize SDL_GetStorageFileSize_REAL
|
||||
#define SDL_GetStoragePathInfo SDL_GetStoragePathInfo_REAL
|
||||
#define SDL_GetStorageSpaceRemaining SDL_GetStorageSpaceRemaining_REAL
|
||||
#define SDL_GetStringProperty SDL_GetStringProperty_REAL
|
||||
#define SDL_GetSurfaceAlphaMod SDL_GetSurfaceAlphaMod_REAL
|
||||
#define SDL_GetSurfaceBlendMode SDL_GetSurfaceBlendMode_REAL
|
||||
#define SDL_GetSurfaceClipRect SDL_GetSurfaceClipRect_REAL
|
||||
#define SDL_GetSurfaceColorKey SDL_GetSurfaceColorKey_REAL
|
||||
#define SDL_GetSurfaceColorMod SDL_GetSurfaceColorMod_REAL
|
||||
#define SDL_GetSurfaceColorspace SDL_GetSurfaceColorspace_REAL
|
||||
#define SDL_GetSurfaceProperties SDL_GetSurfaceProperties_REAL
|
||||
#define SDL_GetSystemRAM SDL_GetSystemRAM_REAL
|
||||
#define SDL_GetSystemTheme SDL_GetSystemTheme_REAL
|
||||
#define SDL_GetTLS SDL_GetTLS_REAL
|
||||
#define SDL_GetTextureAlphaMod SDL_GetTextureAlphaMod_REAL
|
||||
#define SDL_GetTextureAlphaModFloat SDL_GetTextureAlphaModFloat_REAL
|
||||
#define SDL_GetTextureBlendMode SDL_GetTextureBlendMode_REAL
|
||||
#define SDL_GetTextureColorMod SDL_GetTextureColorMod_REAL
|
||||
#define SDL_GetTextureColorModFloat SDL_GetTextureColorModFloat_REAL
|
||||
#define SDL_GetTextureProperties SDL_GetTextureProperties_REAL
|
||||
#define SDL_GetTextureScaleMode SDL_GetTextureScaleMode_REAL
|
||||
#define SDL_GetThreadID SDL_GetThreadID_REAL
|
||||
#define SDL_GetThreadName SDL_GetThreadName_REAL
|
||||
#define SDL_GetTicks SDL_GetTicks_REAL
|
||||
#define SDL_GetTicksNS SDL_GetTicksNS_REAL
|
||||
#define SDL_GetTouchDeviceName SDL_GetTouchDeviceName_REAL
|
||||
#define SDL_GetTouchDeviceType SDL_GetTouchDeviceType_REAL
|
||||
#define SDL_GetTouchDevices SDL_GetTouchDevices_REAL
|
||||
#define SDL_GetTouchFinger SDL_GetTouchFinger_REAL
|
||||
#define SDL_GetUserFolder SDL_GetUserFolder_REAL
|
||||
#define SDL_GetVersion SDL_GetVersion_REAL
|
||||
#define SDL_GetVideoDriver SDL_GetVideoDriver_REAL
|
||||
#define SDL_GetWindowBordersSize SDL_GetWindowBordersSize_REAL
|
||||
@@ -357,7 +487,6 @@
|
||||
#define SDL_GetWindowFlags SDL_GetWindowFlags_REAL
|
||||
#define SDL_GetWindowFromID SDL_GetWindowFromID_REAL
|
||||
#define SDL_GetWindowFullscreenMode SDL_GetWindowFullscreenMode_REAL
|
||||
#define SDL_GetWindowGrab SDL_GetWindowGrab_REAL
|
||||
#define SDL_GetWindowICCProfile SDL_GetWindowICCProfile_REAL
|
||||
#define SDL_GetWindowID SDL_GetWindowID_REAL
|
||||
#define SDL_GetWindowKeyboardGrab SDL_GetWindowKeyboardGrab_REAL
|
||||
@@ -370,39 +499,13 @@
|
||||
#define SDL_GetWindowPixelDensity SDL_GetWindowPixelDensity_REAL
|
||||
#define SDL_GetWindowPixelFormat SDL_GetWindowPixelFormat_REAL
|
||||
#define SDL_GetWindowPosition SDL_GetWindowPosition_REAL
|
||||
#define SDL_GetWindowProperties SDL_GetWindowProperties_REAL
|
||||
#define SDL_GetWindowSize SDL_GetWindowSize_REAL
|
||||
#define SDL_GetWindowSizeInPixels SDL_GetWindowSizeInPixels_REAL
|
||||
#define SDL_GetWindowSurface SDL_GetWindowSurface_REAL
|
||||
#define SDL_GetWindowTitle SDL_GetWindowTitle_REAL
|
||||
#define SDL_GetYUVConversionMode SDL_GetYUVConversionMode_REAL
|
||||
#define SDL_GetYUVConversionModeForResolution SDL_GetYUVConversionModeForResolution_REAL
|
||||
#define SDL_HapticClose SDL_HapticClose_REAL
|
||||
#define SDL_HapticDestroyEffect SDL_HapticDestroyEffect_REAL
|
||||
#define SDL_HapticEffectSupported SDL_HapticEffectSupported_REAL
|
||||
#define SDL_HapticGetEffectStatus SDL_HapticGetEffectStatus_REAL
|
||||
#define SDL_HapticIndex SDL_HapticIndex_REAL
|
||||
#define SDL_HapticName SDL_HapticName_REAL
|
||||
#define SDL_HapticNewEffect SDL_HapticNewEffect_REAL
|
||||
#define SDL_HapticNumAxes SDL_HapticNumAxes_REAL
|
||||
#define SDL_HapticNumEffects SDL_HapticNumEffects_REAL
|
||||
#define SDL_HapticNumEffectsPlaying SDL_HapticNumEffectsPlaying_REAL
|
||||
#define SDL_HapticOpen SDL_HapticOpen_REAL
|
||||
#define SDL_HapticOpenFromJoystick SDL_HapticOpenFromJoystick_REAL
|
||||
#define SDL_HapticOpenFromMouse SDL_HapticOpenFromMouse_REAL
|
||||
#define SDL_HapticOpened SDL_HapticOpened_REAL
|
||||
#define SDL_HapticPause SDL_HapticPause_REAL
|
||||
#define SDL_HapticQuery SDL_HapticQuery_REAL
|
||||
#define SDL_HapticRumbleInit SDL_HapticRumbleInit_REAL
|
||||
#define SDL_HapticRumblePlay SDL_HapticRumblePlay_REAL
|
||||
#define SDL_HapticRumbleStop SDL_HapticRumbleStop_REAL
|
||||
#define SDL_HapticRumbleSupported SDL_HapticRumbleSupported_REAL
|
||||
#define SDL_HapticRunEffect SDL_HapticRunEffect_REAL
|
||||
#define SDL_HapticSetAutocenter SDL_HapticSetAutocenter_REAL
|
||||
#define SDL_HapticSetGain SDL_HapticSetGain_REAL
|
||||
#define SDL_HapticStopAll SDL_HapticStopAll_REAL
|
||||
#define SDL_HapticStopEffect SDL_HapticStopEffect_REAL
|
||||
#define SDL_HapticUnpause SDL_HapticUnpause_REAL
|
||||
#define SDL_HapticUpdateEffect SDL_HapticUpdateEffect_REAL
|
||||
#define SDL_HasARMSIMD SDL_HasARMSIMD_REAL
|
||||
#define SDL_HasAVX SDL_HasAVX_REAL
|
||||
#define SDL_HasAVX2 SDL_HasAVX2_REAL
|
||||
@@ -412,11 +515,16 @@
|
||||
#define SDL_HasClipboardText SDL_HasClipboardText_REAL
|
||||
#define SDL_HasEvent SDL_HasEvent_REAL
|
||||
#define SDL_HasEvents SDL_HasEvents_REAL
|
||||
#define SDL_HasGamepad SDL_HasGamepad_REAL
|
||||
#define SDL_HasJoystick SDL_HasJoystick_REAL
|
||||
#define SDL_HasKeyboard SDL_HasKeyboard_REAL
|
||||
#define SDL_HasLASX SDL_HasLASX_REAL
|
||||
#define SDL_HasLSX SDL_HasLSX_REAL
|
||||
#define SDL_HasMMX SDL_HasMMX_REAL
|
||||
#define SDL_HasMouse SDL_HasMouse_REAL
|
||||
#define SDL_HasNEON SDL_HasNEON_REAL
|
||||
#define SDL_HasPrimarySelectionText SDL_HasPrimarySelectionText_REAL
|
||||
#define SDL_HasProperty SDL_HasProperty_REAL
|
||||
#define SDL_HasRectIntersection SDL_HasRectIntersection_REAL
|
||||
#define SDL_HasRectIntersectionFloat SDL_HasRectIntersectionFloat_REAL
|
||||
#define SDL_HasSSE SDL_HasSSE_REAL
|
||||
@@ -425,35 +533,44 @@
|
||||
#define SDL_HasSSE41 SDL_HasSSE41_REAL
|
||||
#define SDL_HasSSE42 SDL_HasSSE42_REAL
|
||||
#define SDL_HasScreenKeyboardSupport SDL_HasScreenKeyboardSupport_REAL
|
||||
#define SDL_HasWindowSurface SDL_HasWindowSurface_REAL
|
||||
#define SDL_HideCursor SDL_HideCursor_REAL
|
||||
#define SDL_HideWindow SDL_HideWindow_REAL
|
||||
#define SDL_IOFromConstMem SDL_IOFromConstMem_REAL
|
||||
#define SDL_IOFromDynamicMem SDL_IOFromDynamicMem_REAL
|
||||
#define SDL_IOFromFile SDL_IOFromFile_REAL
|
||||
#define SDL_IOFromMem SDL_IOFromMem_REAL
|
||||
#define SDL_IOprintf SDL_IOprintf_REAL
|
||||
#define SDL_IOvprintf SDL_IOvprintf_REAL
|
||||
#define SDL_Init SDL_Init_REAL
|
||||
#define SDL_InitHapticRumble SDL_InitHapticRumble_REAL
|
||||
#define SDL_InitSubSystem SDL_InitSubSystem_REAL
|
||||
#define SDL_IsAndroidTV SDL_IsAndroidTV_REAL
|
||||
#define SDL_IsChromebook SDL_IsChromebook_REAL
|
||||
#define SDL_IsDeXMode SDL_IsDeXMode_REAL
|
||||
#define SDL_IsGamepad SDL_IsGamepad_REAL
|
||||
#define SDL_IsJoystickHaptic SDL_IsJoystickHaptic_REAL
|
||||
#define SDL_IsJoystickVirtual SDL_IsJoystickVirtual_REAL
|
||||
#define SDL_IsMouseHaptic SDL_IsMouseHaptic_REAL
|
||||
#define SDL_IsTablet SDL_IsTablet_REAL
|
||||
#define SDL_JoystickConnected SDL_JoystickConnected_REAL
|
||||
#define SDL_JoystickEventsEnabled SDL_JoystickEventsEnabled_REAL
|
||||
#define SDL_JoystickHasLED SDL_JoystickHasLED_REAL
|
||||
#define SDL_JoystickHasRumble SDL_JoystickHasRumble_REAL
|
||||
#define SDL_JoystickHasRumbleTriggers SDL_JoystickHasRumbleTriggers_REAL
|
||||
#define SDL_JoystickIsHaptic SDL_JoystickIsHaptic_REAL
|
||||
#define SDL_LinuxSetThreadPriority SDL_LinuxSetThreadPriority_REAL
|
||||
#define SDL_LinuxSetThreadPriorityAndPolicy SDL_LinuxSetThreadPriorityAndPolicy_REAL
|
||||
#define SDL_LoadBMP SDL_LoadBMP_REAL
|
||||
#define SDL_LoadBMP_RW SDL_LoadBMP_RW_REAL
|
||||
#define SDL_LoadBMP_IO SDL_LoadBMP_IO_REAL
|
||||
#define SDL_LoadFile SDL_LoadFile_REAL
|
||||
#define SDL_LoadFile_RW SDL_LoadFile_RW_REAL
|
||||
#define SDL_LoadFile_IO SDL_LoadFile_IO_REAL
|
||||
#define SDL_LoadFunction SDL_LoadFunction_REAL
|
||||
#define SDL_LoadObject SDL_LoadObject_REAL
|
||||
#define SDL_LoadWAV SDL_LoadWAV_REAL
|
||||
#define SDL_LoadWAV_IO SDL_LoadWAV_IO_REAL
|
||||
#define SDL_LockAudioStream SDL_LockAudioStream_REAL
|
||||
#define SDL_LockJoysticks SDL_LockJoysticks_REAL
|
||||
#define SDL_LockMutex SDL_LockMutex_REAL
|
||||
#define SDL_LockProperties SDL_LockProperties_REAL
|
||||
#define SDL_LockRWLockForReading SDL_LockRWLockForReading_REAL
|
||||
#define SDL_LockRWLockForWriting SDL_LockRWLockForWriting_REAL
|
||||
#define SDL_LockSpinlock SDL_LockSpinlock_REAL
|
||||
#define SDL_LockSurface SDL_LockSurface_REAL
|
||||
#define SDL_LockTexture SDL_LockTexture_REAL
|
||||
#define SDL_LockTextureToSurface SDL_LockTextureToSurface_REAL
|
||||
@@ -461,14 +578,12 @@
|
||||
#define SDL_LogCritical SDL_LogCritical_REAL
|
||||
#define SDL_LogDebug SDL_LogDebug_REAL
|
||||
#define SDL_LogError SDL_LogError_REAL
|
||||
#define SDL_LogGetOutputFunction SDL_LogGetOutputFunction_REAL
|
||||
#define SDL_LogGetPriority SDL_LogGetPriority_REAL
|
||||
#define SDL_LogInfo SDL_LogInfo_REAL
|
||||
#define SDL_LogMessage SDL_LogMessage_REAL
|
||||
#define SDL_LogMessageV SDL_LogMessageV_REAL
|
||||
#define SDL_LogResetPriorities SDL_LogResetPriorities_REAL
|
||||
#define SDL_LogSetAllPriority SDL_LogSetAllPriority_REAL
|
||||
#define SDL_LogSetOutputFunction SDL_LogSetOutputFunction_REAL
|
||||
#define SDL_LogSetPriority SDL_LogSetPriority_REAL
|
||||
#define SDL_LogVerbose SDL_LogVerbose_REAL
|
||||
#define SDL_LogWarn SDL_LogWarn_REAL
|
||||
@@ -481,8 +596,7 @@
|
||||
#define SDL_Metal_DestroyView SDL_Metal_DestroyView_REAL
|
||||
#define SDL_Metal_GetLayer SDL_Metal_GetLayer_REAL
|
||||
#define SDL_MinimizeWindow SDL_MinimizeWindow_REAL
|
||||
#define SDL_MouseIsHaptic SDL_MouseIsHaptic_REAL
|
||||
#define SDL_NumHaptics SDL_NumHaptics_REAL
|
||||
#define SDL_MixAudioFormat SDL_MixAudioFormat_REAL
|
||||
#define SDL_OnApplicationDidBecomeActive SDL_OnApplicationDidBecomeActive_REAL
|
||||
#define SDL_OnApplicationDidChangeStatusBarOrientation SDL_OnApplicationDidChangeStatusBarOrientation_REAL
|
||||
#define SDL_OnApplicationDidEnterBackground SDL_OnApplicationDidEnterBackground_REAL
|
||||
@@ -490,39 +604,62 @@
|
||||
#define SDL_OnApplicationWillEnterForeground SDL_OnApplicationWillEnterForeground_REAL
|
||||
#define SDL_OnApplicationWillResignActive SDL_OnApplicationWillResignActive_REAL
|
||||
#define SDL_OnApplicationWillTerminate SDL_OnApplicationWillTerminate_REAL
|
||||
#define SDL_OpenAudioDevice SDL_OpenAudioDevice_REAL
|
||||
#define SDL_OpenAudioDeviceStream SDL_OpenAudioDeviceStream_REAL
|
||||
#define SDL_OpenCameraDevice SDL_OpenCameraDevice_REAL
|
||||
#define SDL_OpenFileStorage SDL_OpenFileStorage_REAL
|
||||
#define SDL_OpenGamepad SDL_OpenGamepad_REAL
|
||||
#define SDL_OpenHaptic SDL_OpenHaptic_REAL
|
||||
#define SDL_OpenHapticFromJoystick SDL_OpenHapticFromJoystick_REAL
|
||||
#define SDL_OpenHapticFromMouse SDL_OpenHapticFromMouse_REAL
|
||||
#define SDL_OpenIO SDL_OpenIO_REAL
|
||||
#define SDL_OpenJoystick SDL_OpenJoystick_REAL
|
||||
#define SDL_OpenSensor SDL_OpenSensor_REAL
|
||||
#define SDL_OpenStorage SDL_OpenStorage_REAL
|
||||
#define SDL_OpenTitleStorage SDL_OpenTitleStorage_REAL
|
||||
#define SDL_OpenURL SDL_OpenURL_REAL
|
||||
#define SDL_OpenUserStorage SDL_OpenUserStorage_REAL
|
||||
#define SDL_PauseAudioDevice SDL_PauseAudioDevice_REAL
|
||||
#define SDL_PauseHaptic SDL_PauseHaptic_REAL
|
||||
#define SDL_PeepEvents SDL_PeepEvents_REAL
|
||||
#define SDL_PenConnected SDL_PenConnected_REAL
|
||||
#define SDL_PenConnected SDL_PenConnected_REAL
|
||||
#define SDL_PlayHapticRumble SDL_PlayHapticRumble_REAL
|
||||
#define SDL_PollEvent SDL_PollEvent_REAL
|
||||
#define SDL_PostSemaphore SDL_PostSemaphore_REAL
|
||||
#define SDL_PremultiplyAlpha SDL_PremultiplyAlpha_REAL
|
||||
#define SDL_PumpEvents SDL_PumpEvents_REAL
|
||||
#define SDL_PushEvent SDL_PushEvent_REAL
|
||||
#define SDL_PutAudioStreamData SDL_PutAudioStreamData_REAL
|
||||
#define SDL_QueryTexture SDL_QueryTexture_REAL
|
||||
#define SDL_Quit SDL_Quit_REAL
|
||||
#define SDL_QuitSubSystem SDL_QuitSubSystem_REAL
|
||||
#define SDL_RWFromConstMem SDL_RWFromConstMem_REAL
|
||||
#define SDL_RWFromFile SDL_RWFromFile_REAL
|
||||
#define SDL_RWFromMem SDL_RWFromMem_REAL
|
||||
#define SDL_RWclose SDL_RWclose_REAL
|
||||
#define SDL_RWread SDL_RWread_REAL
|
||||
#define SDL_RWseek SDL_RWseek_REAL
|
||||
#define SDL_RWsize SDL_RWsize_REAL
|
||||
#define SDL_RWtell SDL_RWtell_REAL
|
||||
#define SDL_RWwrite SDL_RWwrite_REAL
|
||||
#define SDL_RaiseWindow SDL_RaiseWindow_REAL
|
||||
#define SDL_ReadIO SDL_ReadIO_REAL
|
||||
#define SDL_ReadS16BE SDL_ReadS16BE_REAL
|
||||
#define SDL_ReadS16LE SDL_ReadS16LE_REAL
|
||||
#define SDL_ReadS32BE SDL_ReadS32BE_REAL
|
||||
#define SDL_ReadS32LE SDL_ReadS32LE_REAL
|
||||
#define SDL_ReadS64BE SDL_ReadS64BE_REAL
|
||||
#define SDL_ReadS64LE SDL_ReadS64LE_REAL
|
||||
#define SDL_ReadStorageFile SDL_ReadStorageFile_REAL
|
||||
#define SDL_ReadSurfacePixel SDL_ReadSurfacePixel_REAL
|
||||
#define SDL_ReadU16BE SDL_ReadU16BE_REAL
|
||||
#define SDL_ReadU32BE SDL_ReadU32BE_REAL
|
||||
#define SDL_ReadU64BE SDL_ReadU64BE_REAL
|
||||
#define SDL_ReadU16LE SDL_ReadU16LE_REAL
|
||||
#define SDL_ReadU32BE SDL_ReadU32BE_REAL
|
||||
#define SDL_ReadU32LE SDL_ReadU32LE_REAL
|
||||
#define SDL_ReadU64BE SDL_ReadU64BE_REAL
|
||||
#define SDL_ReadU64LE SDL_ReadU64LE_REAL
|
||||
#define SDL_ReadU8 SDL_ReadU8_REAL
|
||||
#define SDL_RegisterApp SDL_RegisterApp_REAL
|
||||
#define SDL_RegisterEvents SDL_RegisterEvents_REAL
|
||||
#define SDL_ReleaseCameraFrame SDL_ReleaseCameraFrame_REAL
|
||||
#define SDL_ReloadGamepadMappings SDL_ReloadGamepadMappings_REAL
|
||||
#define SDL_RemovePath SDL_RemovePath_REAL
|
||||
#define SDL_RemoveStoragePath SDL_RemoveStoragePath_REAL
|
||||
#define SDL_RemoveTimer SDL_RemoveTimer_REAL
|
||||
#define SDL_RenamePath SDL_RenamePath_REAL
|
||||
#define SDL_RenameStoragePath SDL_RenameStoragePath_REAL
|
||||
#define SDL_RenderClear SDL_RenderClear_REAL
|
||||
#define SDL_RenderClipEnabled SDL_RenderClipEnabled_REAL
|
||||
#define SDL_RenderCoordinatesFromWindow SDL_RenderCoordinatesFromWindow_REAL
|
||||
@@ -531,6 +668,7 @@
|
||||
#define SDL_RenderFillRects SDL_RenderFillRects_REAL
|
||||
#define SDL_RenderGeometry SDL_RenderGeometry_REAL
|
||||
#define SDL_RenderGeometryRaw SDL_RenderGeometryRaw_REAL
|
||||
#define SDL_RenderGeometryRawFloat SDL_RenderGeometryRawFloat_REAL
|
||||
#define SDL_RenderLine SDL_RenderLine_REAL
|
||||
#define SDL_RenderLines SDL_RenderLines_REAL
|
||||
#define SDL_RenderPoint SDL_RenderPoint_REAL
|
||||
@@ -541,35 +679,50 @@
|
||||
#define SDL_RenderRects SDL_RenderRects_REAL
|
||||
#define SDL_RenderTexture SDL_RenderTexture_REAL
|
||||
#define SDL_RenderTextureRotated SDL_RenderTextureRotated_REAL
|
||||
#define SDL_RenderViewportSet SDL_RenderViewportSet_REAL
|
||||
#define SDL_ReportAssertion SDL_ReportAssertion_REAL
|
||||
#define SDL_ResetAssertionReport SDL_ResetAssertionReport_REAL
|
||||
#define SDL_ResetHint SDL_ResetHint_REAL
|
||||
#define SDL_ResetHints SDL_ResetHints_REAL
|
||||
#define SDL_ResetKeyboard SDL_ResetKeyboard_REAL
|
||||
#define SDL_RestoreWindow SDL_RestoreWindow_REAL
|
||||
#define SDL_ResumeAudioDevice SDL_ResumeAudioDevice_REAL
|
||||
#define SDL_ResumeHaptic SDL_ResumeHaptic_REAL
|
||||
#define SDL_RumbleGamepad SDL_RumbleGamepad_REAL
|
||||
#define SDL_RumbleGamepadTriggers SDL_RumbleGamepadTriggers_REAL
|
||||
#define SDL_RumbleJoystick SDL_RumbleJoystick_REAL
|
||||
#define SDL_RumbleJoystickTriggers SDL_RumbleJoystickTriggers_REAL
|
||||
#define SDL_RunApp SDL_RunApp_REAL
|
||||
#define SDL_RunHapticEffect SDL_RunHapticEffect_REAL
|
||||
#define SDL_SIMDGetAlignment SDL_SIMDGetAlignment_REAL
|
||||
#define SDL_SaveBMP SDL_SaveBMP_REAL
|
||||
#define SDL_SaveBMP_RW SDL_SaveBMP_RW_REAL
|
||||
#define SDL_SaveBMP_IO SDL_SaveBMP_IO_REAL
|
||||
#define SDL_ScreenKeyboardShown SDL_ScreenKeyboardShown_REAL
|
||||
#define SDL_ScreenSaverEnabled SDL_ScreenSaverEnabled_REAL
|
||||
#define SDL_SeekIO SDL_SeekIO_REAL
|
||||
#define SDL_SendGamepadEffect SDL_SendGamepadEffect_REAL
|
||||
#define SDL_SendJoystickEffect SDL_SendJoystickEffect_REAL
|
||||
#define SDL_SetAssertionHandler SDL_SetAssertionHandler_REAL
|
||||
#define SDL_SetAudioPostmixCallback SDL_SetAudioPostmixCallback_REAL
|
||||
#define SDL_SetAudioStreamFormat SDL_SetAudioStreamFormat_REAL
|
||||
#define SDL_SetAudioStreamFrequencyRatio SDL_SetAudioStreamFrequencyRatio_REAL
|
||||
#define SDL_SetAudioStreamGetCallback SDL_SetAudioStreamGetCallback_REAL
|
||||
#define SDL_SetAudioStreamPutCallback SDL_SetAudioStreamPutCallback_REAL
|
||||
#define SDL_SetBooleanProperty SDL_SetBooleanProperty_REAL
|
||||
#define SDL_SetClipboardData SDL_SetClipboardData_REAL
|
||||
#define SDL_SetClipboardText SDL_SetClipboardText_REAL
|
||||
#define SDL_SetCursor SDL_SetCursor_REAL
|
||||
#define SDL_SetError SDL_SetError_REAL
|
||||
#define SDL_SetEventEnabled SDL_SetEventEnabled_REAL
|
||||
#define SDL_SetEventFilter SDL_SetEventFilter_REAL
|
||||
#define SDL_SetFloatProperty SDL_SetFloatProperty_REAL
|
||||
#define SDL_SetGamepadEventsEnabled SDL_SetGamepadEventsEnabled_REAL
|
||||
#define SDL_SetGamepadLED SDL_SetGamepadLED_REAL
|
||||
#define SDL_SetGamepadMapping SDL_SetGamepadMapping_REAL
|
||||
#define SDL_SetGamepadPlayerIndex SDL_SetGamepadPlayerIndex_REAL
|
||||
#define SDL_SetGamepadSensorEnabled SDL_SetGamepadSensorEnabled_REAL
|
||||
#define SDL_SetHapticAutocenter SDL_SetHapticAutocenter_REAL
|
||||
#define SDL_SetHapticGain SDL_SetHapticGain_REAL
|
||||
#define SDL_SetHint SDL_SetHint_REAL
|
||||
#define SDL_SetHintWithPriority SDL_SetHintWithPriority_REAL
|
||||
#define SDL_SetJoystickEventsEnabled SDL_SetJoystickEventsEnabled_REAL
|
||||
@@ -578,40 +731,50 @@
|
||||
#define SDL_SetJoystickVirtualAxis SDL_SetJoystickVirtualAxis_REAL
|
||||
#define SDL_SetJoystickVirtualButton SDL_SetJoystickVirtualButton_REAL
|
||||
#define SDL_SetJoystickVirtualHat SDL_SetJoystickVirtualHat_REAL
|
||||
#define SDL_SetLogOutputFunction SDL_SetLogOutputFunction_REAL
|
||||
#define SDL_SetMainReady SDL_SetMainReady_REAL
|
||||
#define SDL_SetMemoryFunctions SDL_SetMemoryFunctions_REAL
|
||||
#define SDL_SetModState SDL_SetModState_REAL
|
||||
#define SDL_SetNumberProperty SDL_SetNumberProperty_REAL
|
||||
#define SDL_SetPaletteColors SDL_SetPaletteColors_REAL
|
||||
#define SDL_SetPixelFormatPalette SDL_SetPixelFormatPalette_REAL
|
||||
#define SDL_SetPrimarySelectionText SDL_SetPrimarySelectionText_REAL
|
||||
#define SDL_SetProperty SDL_SetProperty_REAL
|
||||
#define SDL_SetPropertyWithCleanup SDL_SetPropertyWithCleanup_REAL
|
||||
#define SDL_SetRelativeMouseMode SDL_SetRelativeMouseMode_REAL
|
||||
#define SDL_SetRenderClipRect SDL_SetRenderClipRect_REAL
|
||||
#define SDL_SetRenderColorScale SDL_SetRenderColorScale_REAL
|
||||
#define SDL_SetRenderDrawBlendMode SDL_SetRenderDrawBlendMode_REAL
|
||||
#define SDL_SetRenderDrawColor SDL_SetRenderDrawColor_REAL
|
||||
#define SDL_SetRenderDrawColorFloat SDL_SetRenderDrawColorFloat_REAL
|
||||
#define SDL_SetRenderLogicalPresentation SDL_SetRenderLogicalPresentation_REAL
|
||||
#define SDL_SetRenderScale SDL_SetRenderScale_REAL
|
||||
#define SDL_SetRenderTarget SDL_SetRenderTarget_REAL
|
||||
#define SDL_SetRenderVSync SDL_SetRenderVSync_REAL
|
||||
#define SDL_SetRenderViewport SDL_SetRenderViewport_REAL
|
||||
#define SDL_SetStringProperty SDL_SetStringProperty_REAL
|
||||
#define SDL_SetSurfaceAlphaMod SDL_SetSurfaceAlphaMod_REAL
|
||||
#define SDL_SetSurfaceBlendMode SDL_SetSurfaceBlendMode_REAL
|
||||
#define SDL_SetSurfaceClipRect SDL_SetSurfaceClipRect_REAL
|
||||
#define SDL_SetSurfaceColorKey SDL_SetSurfaceColorKey_REAL
|
||||
#define SDL_SetSurfaceColorMod SDL_SetSurfaceColorMod_REAL
|
||||
#define SDL_SetSurfaceColorspace SDL_SetSurfaceColorspace_REAL
|
||||
#define SDL_SetSurfacePalette SDL_SetSurfacePalette_REAL
|
||||
#define SDL_SetSurfaceRLE SDL_SetSurfaceRLE_REAL
|
||||
#define SDL_SetTLS SDL_SetTLS_REAL
|
||||
#define SDL_SetTextInputRect SDL_SetTextInputRect_REAL
|
||||
#define SDL_SetTextureAlphaMod SDL_SetTextureAlphaMod_REAL
|
||||
#define SDL_SetTextureAlphaModFloat SDL_SetTextureAlphaModFloat_REAL
|
||||
#define SDL_SetTextureBlendMode SDL_SetTextureBlendMode_REAL
|
||||
#define SDL_SetTextureColorMod SDL_SetTextureColorMod_REAL
|
||||
#define SDL_SetTextureColorModFloat SDL_SetTextureColorModFloat_REAL
|
||||
#define SDL_SetTextureScaleMode SDL_SetTextureScaleMode_REAL
|
||||
#define SDL_SetThreadPriority SDL_SetThreadPriority_REAL
|
||||
#define SDL_SetWindowAlwaysOnTop SDL_SetWindowAlwaysOnTop_REAL
|
||||
#define SDL_SetWindowBordered SDL_SetWindowBordered_REAL
|
||||
#define SDL_SetWindowFocusable SDL_SetWindowFocusable_REAL
|
||||
#define SDL_SetWindowFullscreen SDL_SetWindowFullscreen_REAL
|
||||
#define SDL_SetWindowFullscreenMode SDL_SetWindowFullscreenMode_REAL
|
||||
#define SDL_SetWindowGrab SDL_SetWindowGrab_REAL
|
||||
#define SDL_SetWindowHitTest SDL_SetWindowHitTest_REAL
|
||||
#define SDL_SetWindowIcon SDL_SetWindowIcon_REAL
|
||||
#define SDL_SetWindowInputFocus SDL_SetWindowInputFocus_REAL
|
||||
@@ -624,35 +787,54 @@
|
||||
#define SDL_SetWindowOpacity SDL_SetWindowOpacity_REAL
|
||||
#define SDL_SetWindowPosition SDL_SetWindowPosition_REAL
|
||||
#define SDL_SetWindowResizable SDL_SetWindowResizable_REAL
|
||||
#define SDL_SetWindowShape SDL_SetWindowShape_REAL
|
||||
#define SDL_SetWindowSize SDL_SetWindowSize_REAL
|
||||
#define SDL_SetWindowTitle SDL_SetWindowTitle_REAL
|
||||
#define SDL_SetWindowsMessageHook SDL_SetWindowsMessageHook_REAL
|
||||
#define SDL_SetYUVConversionMode SDL_SetYUVConversionMode_REAL
|
||||
#define SDL_SetX11EventHook SDL_SetX11EventHook_REAL
|
||||
#define SDL_ShowCursor SDL_ShowCursor_REAL
|
||||
#define SDL_ShowMessageBox SDL_ShowMessageBox_REAL
|
||||
#define SDL_ShowOpenFileDialog SDL_ShowOpenFileDialog_REAL
|
||||
#define SDL_ShowOpenFolderDialog SDL_ShowOpenFolderDialog_REAL
|
||||
#define SDL_ShowSaveFileDialog SDL_ShowSaveFileDialog_REAL
|
||||
#define SDL_ShowSimpleMessageBox SDL_ShowSimpleMessageBox_REAL
|
||||
#define SDL_ShowWindow SDL_ShowWindow_REAL
|
||||
#define SDL_ShowWindowSystemMenu SDL_ShowWindowSystemMenu_REAL
|
||||
#define SDL_SignalCondition SDL_SignalCondition_REAL
|
||||
#define SDL_SoftStretch SDL_SoftStretch_REAL
|
||||
#define SDL_StartTextInput SDL_StartTextInput_REAL
|
||||
#define SDL_StopHapticEffect SDL_StopHapticEffect_REAL
|
||||
#define SDL_StopHapticEffects SDL_StopHapticEffects_REAL
|
||||
#define SDL_StopHapticRumble SDL_StopHapticRumble_REAL
|
||||
#define SDL_StopTextInput SDL_StopTextInput_REAL
|
||||
#define SDL_StorageReady SDL_StorageReady_REAL
|
||||
#define SDL_SurfaceHasColorKey SDL_SurfaceHasColorKey_REAL
|
||||
#define SDL_SurfaceHasRLE SDL_SurfaceHasRLE_REAL
|
||||
#define SDL_SyncWindow SDL_SyncWindow_REAL
|
||||
#define SDL_TellIO SDL_TellIO_REAL
|
||||
#define SDL_TextInputActive SDL_TextInputActive_REAL
|
||||
#define SDL_TextInputShown SDL_TextInputShown_REAL
|
||||
#define SDL_ThreadID SDL_ThreadID_REAL
|
||||
#define SDL_TimeFromWindows SDL_TimeFromWindows_REAL
|
||||
#define SDL_TimeToDateTime SDL_TimeToDateTime_REAL
|
||||
#define SDL_TimeToWindows SDL_TimeToWindows_REAL
|
||||
#define SDL_TryLockMutex SDL_TryLockMutex_REAL
|
||||
#define SDL_TryLockRWLockForReading SDL_TryLockRWLockForReading_REAL
|
||||
#define SDL_TryLockRWLockForWriting SDL_TryLockRWLockForWriting_REAL
|
||||
#define SDL_TryLockSpinlock SDL_TryLockSpinlock_REAL
|
||||
#define SDL_TryWaitSemaphore SDL_TryWaitSemaphore_REAL
|
||||
#define SDL_UnbindAudioStream SDL_UnbindAudioStream_REAL
|
||||
#define SDL_UnbindAudioStreams SDL_UnbindAudioStreams_REAL
|
||||
#define SDL_UnloadObject SDL_UnloadObject_REAL
|
||||
#define SDL_UnlockAudioStream SDL_UnlockAudioStream_REAL
|
||||
#define SDL_UnlockJoysticks SDL_UnlockJoysticks_REAL
|
||||
#define SDL_UnlockMutex SDL_UnlockMutex_REAL
|
||||
#define SDL_UnlockProperties SDL_UnlockProperties_REAL
|
||||
#define SDL_UnlockRWLock SDL_UnlockRWLock_REAL
|
||||
#define SDL_UnlockSpinlock SDL_UnlockSpinlock_REAL
|
||||
#define SDL_UnlockSurface SDL_UnlockSurface_REAL
|
||||
#define SDL_UnlockTexture SDL_UnlockTexture_REAL
|
||||
#define SDL_UnregisterApp SDL_UnregisterApp_REAL
|
||||
#define SDL_UpdateGamepads SDL_UpdateGamepads_REAL
|
||||
#define SDL_UpdateHapticEffect SDL_UpdateHapticEffect_REAL
|
||||
#define SDL_UpdateJoysticks SDL_UpdateJoysticks_REAL
|
||||
#define SDL_UpdateNVTexture SDL_UpdateNVTexture_REAL
|
||||
#define SDL_UpdateSensors SDL_UpdateSensors_REAL
|
||||
@@ -678,11 +860,19 @@
|
||||
#define SDL_WinRTGetDeviceFamily SDL_WinRTGetDeviceFamily_REAL
|
||||
#define SDL_WinRTGetFSPathUNICODE SDL_WinRTGetFSPathUNICODE_REAL
|
||||
#define SDL_WinRTGetFSPathUTF8 SDL_WinRTGetFSPathUTF8_REAL
|
||||
#define SDL_WindowHasSurface SDL_WindowHasSurface_REAL
|
||||
#define SDL_WriteIO SDL_WriteIO_REAL
|
||||
#define SDL_WriteS16BE SDL_WriteS16BE_REAL
|
||||
#define SDL_WriteS16LE SDL_WriteS16LE_REAL
|
||||
#define SDL_WriteS32BE SDL_WriteS32BE_REAL
|
||||
#define SDL_WriteS32LE SDL_WriteS32LE_REAL
|
||||
#define SDL_WriteS64BE SDL_WriteS64BE_REAL
|
||||
#define SDL_WriteS64LE SDL_WriteS64LE_REAL
|
||||
#define SDL_WriteU16BE SDL_WriteU16BE_REAL
|
||||
#define SDL_WriteU32BE SDL_WriteU32BE_REAL
|
||||
#define SDL_WriteU64BE SDL_WriteU64BE_REAL
|
||||
#define SDL_WriteU16LE SDL_WriteU16LE_REAL
|
||||
#define SDL_WriteU32BE SDL_WriteU32BE_REAL
|
||||
#define SDL_WriteU32LE SDL_WriteU32LE_REAL
|
||||
#define SDL_WriteU64BE SDL_WriteU64BE_REAL
|
||||
#define SDL_WriteU64LE SDL_WriteU64LE_REAL
|
||||
#define SDL_WriteU8 SDL_WriteU8_REAL
|
||||
#define SDL_abs SDL_abs_REAL
|
||||
@@ -700,6 +890,7 @@
|
||||
#define SDL_atof SDL_atof_REAL
|
||||
#define SDL_atoi SDL_atoi_REAL
|
||||
#define SDL_bsearch SDL_bsearch_REAL
|
||||
#define SDL_bsearch_r SDL_bsearch_r_REAL
|
||||
#define SDL_calloc SDL_calloc_REAL
|
||||
#define SDL_ceil SDL_ceil_REAL
|
||||
#define SDL_ceilf SDL_ceilf_REAL
|
||||
@@ -779,6 +970,7 @@
|
||||
#define SDL_pow SDL_pow_REAL
|
||||
#define SDL_powf SDL_powf_REAL
|
||||
#define SDL_qsort SDL_qsort_REAL
|
||||
#define SDL_qsort_r SDL_qsort_r_REAL
|
||||
#define SDL_realloc SDL_realloc_REAL
|
||||
#define SDL_round SDL_round_REAL
|
||||
#define SDL_roundf SDL_roundf_REAL
|
||||
@@ -802,6 +994,9 @@
|
||||
#define SDL_strlwr SDL_strlwr_REAL
|
||||
#define SDL_strncasecmp SDL_strncasecmp_REAL
|
||||
#define SDL_strncmp SDL_strncmp_REAL
|
||||
#define SDL_strndup SDL_strndup_REAL
|
||||
#define SDL_strnlen SDL_strnlen_REAL
|
||||
#define SDL_strnstr SDL_strnstr_REAL
|
||||
#define SDL_strrchr SDL_strrchr_REAL
|
||||
#define SDL_strrev SDL_strrev_REAL
|
||||
#define SDL_strstr SDL_strstr_REAL
|
||||
@@ -837,153 +1032,7 @@
|
||||
#define SDL_wcslen SDL_wcslen_REAL
|
||||
#define SDL_wcsncasecmp SDL_wcsncasecmp_REAL
|
||||
#define SDL_wcsncmp SDL_wcsncmp_REAL
|
||||
#define SDL_wcsnlen SDL_wcsnlen_REAL
|
||||
#define SDL_wcsnstr SDL_wcsnstr_REAL
|
||||
#define SDL_wcsstr SDL_wcsstr_REAL
|
||||
#define SDL_wcstol SDL_wcstol_REAL
|
||||
|
||||
/* New API symbols are added at the end */
|
||||
#define SDL_ClearClipboardData SDL_ClearClipboardData_REAL
|
||||
#define SDL_GetGamepadInstanceID SDL_GetGamepadInstanceID_REAL
|
||||
#define SDL_GetGamepadPowerLevel SDL_GetGamepadPowerLevel_REAL
|
||||
#define SDL_SetGamepadMapping SDL_SetGamepadMapping_REAL
|
||||
#define SDL_strndup SDL_strndup_REAL
|
||||
#define SDL_GetGamepadTypeFromString SDL_GetGamepadTypeFromString_REAL
|
||||
#define SDL_GetGamepadStringForType SDL_GetGamepadStringForType_REAL
|
||||
#define SDL_GetRealGamepadInstanceType SDL_GetRealGamepadInstanceType_REAL
|
||||
#define SDL_GetRealGamepadType SDL_GetRealGamepadType_REAL
|
||||
#define SDL_wcsnlen SDL_wcsnlen_REAL
|
||||
#define SDL_strnlen SDL_strnlen_REAL
|
||||
#define SDL_AddGamepadMappingsFromFile SDL_AddGamepadMappingsFromFile_REAL
|
||||
#define SDL_ReloadGamepadMappings SDL_ReloadGamepadMappings_REAL
|
||||
#define SDL_GetNumAudioDrivers SDL_GetNumAudioDrivers_REAL
|
||||
#define SDL_GetAudioDriver SDL_GetAudioDriver_REAL
|
||||
#define SDL_GetCurrentAudioDriver SDL_GetCurrentAudioDriver_REAL
|
||||
#define SDL_GetAudioOutputDevices SDL_GetAudioOutputDevices_REAL
|
||||
#define SDL_GetAudioCaptureDevices SDL_GetAudioCaptureDevices_REAL
|
||||
#define SDL_GetAudioDeviceName SDL_GetAudioDeviceName_REAL
|
||||
#define SDL_GetAudioDeviceFormat SDL_GetAudioDeviceFormat_REAL
|
||||
#define SDL_OpenAudioDevice SDL_OpenAudioDevice_REAL
|
||||
#define SDL_CloseAudioDevice SDL_CloseAudioDevice_REAL
|
||||
#define SDL_BindAudioStreams SDL_BindAudioStreams_REAL
|
||||
#define SDL_BindAudioStream SDL_BindAudioStream_REAL
|
||||
#define SDL_UnbindAudioStreams SDL_UnbindAudioStreams_REAL
|
||||
#define SDL_UnbindAudioStream SDL_UnbindAudioStream_REAL
|
||||
#define SDL_CreateAudioStream SDL_CreateAudioStream_REAL
|
||||
#define SDL_GetAudioStreamFormat SDL_GetAudioStreamFormat_REAL
|
||||
#define SDL_SetAudioStreamFormat SDL_SetAudioStreamFormat_REAL
|
||||
#define SDL_PutAudioStreamData SDL_PutAudioStreamData_REAL
|
||||
#define SDL_GetAudioStreamData SDL_GetAudioStreamData_REAL
|
||||
#define SDL_GetAudioStreamAvailable SDL_GetAudioStreamAvailable_REAL
|
||||
#define SDL_FlushAudioStream SDL_FlushAudioStream_REAL
|
||||
#define SDL_ClearAudioStream SDL_ClearAudioStream_REAL
|
||||
#define SDL_LockAudioStream SDL_LockAudioStream_REAL
|
||||
#define SDL_UnlockAudioStream SDL_UnlockAudioStream_REAL
|
||||
#define SDL_SetAudioStreamGetCallback SDL_SetAudioStreamGetCallback_REAL
|
||||
#define SDL_SetAudioStreamPutCallback SDL_SetAudioStreamPutCallback_REAL
|
||||
#define SDL_DestroyAudioStream SDL_DestroyAudioStream_REAL
|
||||
#define SDL_OpenAudioDeviceStream SDL_OpenAudioDeviceStream_REAL
|
||||
#define SDL_LoadWAV_RW SDL_LoadWAV_RW_REAL
|
||||
#define SDL_LoadWAV SDL_LoadWAV_REAL
|
||||
#define SDL_MixAudioFormat SDL_MixAudioFormat_REAL
|
||||
#define SDL_ConvertAudioSamples SDL_ConvertAudioSamples_REAL
|
||||
#define SDL_GetSilenceValueForFormat SDL_GetSilenceValueForFormat_REAL
|
||||
#define SDL_PauseAudioDevice SDL_PauseAudioDevice_REAL
|
||||
#define SDL_ResumeAudioDevice SDL_ResumeAudioDevice_REAL
|
||||
#define SDL_AudioDevicePaused SDL_AudioDevicePaused_REAL
|
||||
#define SDL_GetAudioStreamDevice SDL_GetAudioStreamDevice_REAL
|
||||
#define SDL_ShowWindowSystemMenu SDL_ShowWindowSystemMenu_REAL
|
||||
#define SDL_ReadS16LE SDL_ReadS16LE_REAL
|
||||
#define SDL_ReadS16BE SDL_ReadS16BE_REAL
|
||||
#define SDL_ReadS32LE SDL_ReadS32LE_REAL
|
||||
#define SDL_ReadS32BE SDL_ReadS32BE_REAL
|
||||
#define SDL_ReadS64LE SDL_ReadS64LE_REAL
|
||||
#define SDL_ReadS64BE SDL_ReadS64BE_REAL
|
||||
#define SDL_WriteS16LE SDL_WriteS16LE_REAL
|
||||
#define SDL_WriteS16BE SDL_WriteS16BE_REAL
|
||||
#define SDL_WriteS32LE SDL_WriteS32LE_REAL
|
||||
#define SDL_WriteS32BE SDL_WriteS32BE_REAL
|
||||
#define SDL_WriteS64LE SDL_WriteS64LE_REAL
|
||||
#define SDL_WriteS64BE SDL_WriteS64BE_REAL
|
||||
#define SDL_GDKGetDefaultUser SDL_GDKGetDefaultUser_REAL
|
||||
#define SDL_SetWindowFocusable SDL_SetWindowFocusable_REAL
|
||||
#define SDL_GetAudioStreamFrequencyRatio SDL_GetAudioStreamFrequencyRatio_REAL
|
||||
#define SDL_SetAudioStreamFrequencyRatio SDL_SetAudioStreamFrequencyRatio_REAL
|
||||
#define SDL_SetAudioPostmixCallback SDL_SetAudioPostmixCallback_REAL
|
||||
#define SDL_GetAudioStreamQueued SDL_GetAudioStreamQueued_REAL
|
||||
#define SDL_CreateProperties SDL_CreateProperties_REAL
|
||||
#define SDL_LockProperties SDL_LockProperties_REAL
|
||||
#define SDL_UnlockProperties SDL_UnlockProperties_REAL
|
||||
#define SDL_SetProperty SDL_SetProperty_REAL
|
||||
#define SDL_GetProperty SDL_GetProperty_REAL
|
||||
#define SDL_DestroyProperties SDL_DestroyProperties_REAL
|
||||
#define SDL_GetAudioStreamProperties SDL_GetAudioStreamProperties_REAL
|
||||
#define SDL_GetGamepadProperties SDL_GetGamepadProperties_REAL
|
||||
#define SDL_GetJoystickProperties SDL_GetJoystickProperties_REAL
|
||||
#define SDL_GetRendererProperties SDL_GetRendererProperties_REAL
|
||||
#define SDL_GetTextureProperties SDL_GetTextureProperties_REAL
|
||||
#define SDL_GetRWProperties SDL_GetRWProperties_REAL
|
||||
#define SDL_GetSensorProperties SDL_GetSensorProperties_REAL
|
||||
#define SDL_GetSurfaceProperties SDL_GetSurfaceProperties_REAL
|
||||
#define SDL_GetWindowProperties SDL_GetWindowProperties_REAL
|
||||
#define SDL_ClearProperty SDL_ClearProperty_REAL
|
||||
#define SDL_EnterAppMainCallbacks SDL_EnterAppMainCallbacks_REAL
|
||||
#define SDL_RWprintf SDL_RWprintf_REAL
|
||||
#define SDL_RWvprintf SDL_RWvprintf_REAL
|
||||
#define SDL_AllocateEventMemory SDL_AllocateEventMemory_REAL
|
||||
#define SDL_GetDisplayProperties SDL_GetDisplayProperties_REAL
|
||||
#define SDL_SetPropertyWithCleanup SDL_SetPropertyWithCleanup_REAL
|
||||
#define SDL_SetX11EventHook SDL_SetX11EventHook_REAL
|
||||
#define SDL_GetGlobalProperties SDL_GetGlobalProperties_REAL
|
||||
#define SDL_OpenVideoCapture SDL_OpenVideoCapture_REAL
|
||||
#define SDL_SetVideoCaptureSpec SDL_SetVideoCaptureSpec_REAL
|
||||
#define SDL_OpenVideoCaptureWithSpec SDL_OpenVideoCaptureWithSpec_REAL
|
||||
#define SDL_GetVideoCaptureDeviceName SDL_GetVideoCaptureDeviceName_REAL
|
||||
#define SDL_GetVideoCaptureSpec SDL_GetVideoCaptureSpec_REAL
|
||||
#define SDL_GetVideoCaptureFormat SDL_GetVideoCaptureFormat_REAL
|
||||
#define SDL_GetNumVideoCaptureFormats SDL_GetNumVideoCaptureFormats_REAL
|
||||
#define SDL_GetVideoCaptureFrameSize SDL_GetVideoCaptureFrameSize_REAL
|
||||
#define SDL_GetNumVideoCaptureFrameSizes SDL_GetNumVideoCaptureFrameSizes_REAL
|
||||
#define SDL_GetVideoCaptureStatus SDL_GetVideoCaptureStatus_REAL
|
||||
#define SDL_StartVideoCapture SDL_StartVideoCapture_REAL
|
||||
#define SDL_AcquireVideoCaptureFrame SDL_AcquireVideoCaptureFrame_REAL
|
||||
#define SDL_ReleaseVideoCaptureFrame SDL_ReleaseVideoCaptureFrame_REAL
|
||||
#define SDL_StopVideoCapture SDL_StopVideoCapture_REAL
|
||||
#define SDL_CloseVideoCapture SDL_CloseVideoCapture_REAL
|
||||
#define SDL_GetVideoCaptureDevices SDL_GetVideoCaptureDevices_REAL
|
||||
#define SDL_GetGamepadButtonLabelForType SDL_GetGamepadButtonLabelForType_REAL
|
||||
#define SDL_GetGamepadButtonLabel SDL_GetGamepadButtonLabel_REAL
|
||||
#define SDL_GetPens SDL_GetPens_REAL
|
||||
#define SDL_GetPenStatus SDL_GetPenStatus_REAL
|
||||
#define SDL_GetPenFromGUID SDL_GetPenFromGUID_REAL
|
||||
#define SDL_GetPenGUID SDL_GetPenGUID_REAL
|
||||
#define SDL_PenConnected SDL_PenConnected_REAL
|
||||
#define SDL_GetPenName SDL_GetPenName_REAL
|
||||
#define SDL_GetPenCapabilities SDL_GetPenCapabilities_REAL
|
||||
#define SDL_GetPenType SDL_GetPenType_REAL
|
||||
#define SDL_GetPens SDL_GetPens_REAL
|
||||
#define SDL_GetPenStatus SDL_GetPenStatus_REAL
|
||||
#define SDL_GetPenFromGUID SDL_GetPenFromGUID_REAL
|
||||
#define SDL_GetPenGUID SDL_GetPenGUID_REAL
|
||||
#define SDL_PenConnected SDL_PenConnected_REAL
|
||||
#define SDL_GetPenName SDL_GetPenName_REAL
|
||||
#define SDL_GetPenCapabilities SDL_GetPenCapabilities_REAL
|
||||
#define SDL_GetPenType SDL_GetPenType_REAL
|
||||
#define SDL_SetStringProperty SDL_SetStringProperty_REAL
|
||||
#define SDL_SetNumberProperty SDL_SetNumberProperty_REAL
|
||||
#define SDL_SetFloatProperty SDL_SetFloatProperty_REAL
|
||||
#define SDL_GetPropertyType SDL_GetPropertyType_REAL
|
||||
#define SDL_GetStringProperty SDL_GetStringProperty_REAL
|
||||
#define SDL_GetNumberProperty SDL_GetNumberProperty_REAL
|
||||
#define SDL_GetFloatProperty SDL_GetFloatProperty_REAL
|
||||
#define SDL_EnumerateProperties SDL_EnumerateProperties_REAL
|
||||
#define SDL_SetBooleanProperty SDL_SetBooleanProperty_REAL
|
||||
#define SDL_GetBooleanProperty SDL_GetBooleanProperty_REAL
|
||||
#define SDL_CreateTextureWithProperties SDL_CreateTextureWithProperties_REAL
|
||||
#define SDL_CreateRendererWithProperties SDL_CreateRendererWithProperties_REAL
|
||||
#define SDL_GetGamepadMappings SDL_GetGamepadMappings_REAL
|
||||
#define SDL_GetTouchDevices SDL_GetTouchDevices_REAL
|
||||
#define SDL_GetTouchDeviceName SDL_GetTouchDeviceName_REAL
|
||||
#define SDL_strnstr SDL_strnstr_REAL
|
||||
#define SDL_wcsnstr SDL_wcsnstr_REAL
|
||||
#define SDL_SyncWindow SDL_SyncWindow_REAL
|
||||
#define SDL_GetGamepadSteamHandle SDL_GetGamepadSteamHandle_REAL
|
||||
#define SDL_GetRendererFromTexture SDL_GetRendererFromTexture_REAL
|
||||
|
||||
584
external/sdl/SDL/src/dynapi/SDL_dynapi_procs.h
vendored
584
external/sdl/SDL/src/dynapi/SDL_dynapi_procs.h
vendored
File diff suppressed because it is too large
Load Diff
@@ -23,26 +23,30 @@
|
||||
#define SDL_dynapi_unsupported_h_
|
||||
|
||||
|
||||
#if !(defined(__WIN32__) || defined(__GDK__))
|
||||
#if !(defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_GDK))
|
||||
typedef struct ID3D12Device ID3D12Device;
|
||||
typedef void *SDL_WindowsMessageHook;
|
||||
#endif
|
||||
|
||||
#if !(defined(__WIN32__) || defined(__WINGDK__))
|
||||
#if !(defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_WINGDK))
|
||||
typedef struct ID3D11Device ID3D11Device;
|
||||
typedef struct IDirect3DDevice9 IDirect3DDevice9;
|
||||
#endif
|
||||
|
||||
#ifndef __GDK__
|
||||
#ifndef SDL_PLATFORM_GDK
|
||||
typedef struct XTaskQueueHandle XTaskQueueHandle;
|
||||
#endif
|
||||
|
||||
#ifndef __WINRT__
|
||||
#ifndef SDL_PLATFORM_WINRT
|
||||
typedef int SDL_WinRT_DeviceFamily;
|
||||
typedef int SDL_WinRT_Path;
|
||||
#endif
|
||||
#ifndef __GDK__
|
||||
#ifndef SDL_PLATFORM_GDK
|
||||
typedef struct XUserHandle XUserHandle;
|
||||
#endif
|
||||
|
||||
#ifndef SDL_PLATFORM_ANDROID
|
||||
typedef void *SDL_AndroidRequestPermissionCallback;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
2
external/sdl/SDL/src/dynapi/gendynapi.py
vendored
2
external/sdl/SDL/src/dynapi/gendynapi.py
vendored
@@ -25,7 +25,7 @@
|
||||
# It keeps the dynamic API jump table operating correctly.
|
||||
#
|
||||
# OS-specific API:
|
||||
# After running the script, you have to manually add #ifdef __WIN32__
|
||||
# After running the script, you have to manually add #ifdef SDL_PLATFORM_WIN32
|
||||
# or similar around the function in 'SDL_dynapi_procs.h'
|
||||
#
|
||||
|
||||
|
||||
135
external/sdl/SDL/src/events/SDL_events.c
vendored
135
external/sdl/SDL/src/events/SDL_events.c
vendored
@@ -25,6 +25,7 @@
|
||||
#include "SDL_events_c.h"
|
||||
#include "../SDL_hints_c.h"
|
||||
#include "../audio/SDL_audio_c.h"
|
||||
#include "../camera/SDL_camera_c.h"
|
||||
#include "../timer/SDL_timer_c.h"
|
||||
#ifndef SDL_JOYSTICK_DISABLED
|
||||
#include "../joystick/SDL_joystick_c.h"
|
||||
@@ -35,7 +36,7 @@
|
||||
#include "../video/SDL_sysvideo.h"
|
||||
|
||||
#undef SDL_PRIs64
|
||||
#if (defined(__WIN32__) || defined(__GDK__)) && !defined(__CYGWIN__)
|
||||
#if (defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_GDK)) && !defined(SDL_PLATFORM_CYGWIN)
|
||||
#define SDL_PRIs64 "I64d"
|
||||
#else
|
||||
#define SDL_PRIs64 "lld"
|
||||
@@ -44,8 +45,14 @@
|
||||
/* An arbitrary limit so we don't have unbounded growth */
|
||||
#define SDL_MAX_QUEUED_EVENTS 65535
|
||||
|
||||
/* Determines how often we wake to call SDL_PumpEvents() in SDL_WaitEventTimeout_Device() */
|
||||
#define PERIODIC_POLL_INTERVAL_NS (3 * SDL_NS_PER_SECOND)
|
||||
/* Determines how often we pump events if joystick or sensor subsystems are active */
|
||||
#define ENUMERATION_POLL_INTERVAL_NS (3 * SDL_NS_PER_SECOND)
|
||||
|
||||
/* Determines how often to pump events if joysticks or sensors are actively being read */
|
||||
#define EVENT_POLL_INTERVAL_NS SDL_MS_TO_NS(1)
|
||||
|
||||
/* Make sure the type in the SDL_Event aligns properly across the union */
|
||||
SDL_COMPILE_TIME_ASSERT(SDL_Event_type, sizeof(Uint32) == sizeof(SDL_EventType));
|
||||
|
||||
typedef struct SDL_EventWatcher
|
||||
{
|
||||
@@ -282,6 +289,7 @@ static void SDL_LogEvent(const SDL_Event *event)
|
||||
SDL_DISPLAYEVENT_CASE(SDL_EVENT_DISPLAY_REMOVED);
|
||||
SDL_DISPLAYEVENT_CASE(SDL_EVENT_DISPLAY_MOVED);
|
||||
SDL_DISPLAYEVENT_CASE(SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED);
|
||||
SDL_DISPLAYEVENT_CASE(SDL_EVENT_DISPLAY_HDR_STATE_CHANGED);
|
||||
#undef SDL_DISPLAYEVENT_CASE
|
||||
|
||||
#define SDL_WINDOWEVENT_CASE(x) \
|
||||
@@ -317,9 +325,18 @@ static void SDL_LogEvent(const SDL_Event *event)
|
||||
SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_DESTROYED);
|
||||
#undef SDL_WINDOWEVENT_CASE
|
||||
|
||||
#define PRINT_KEYDEV_EVENT(event) (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%u)", (uint)event->kdevice.timestamp, (uint)event->kdevice.which)
|
||||
SDL_EVENT_CASE(SDL_EVENT_KEYBOARD_ADDED)
|
||||
PRINT_KEYDEV_EVENT(event);
|
||||
break;
|
||||
SDL_EVENT_CASE(SDL_EVENT_KEYBOARD_REMOVED)
|
||||
PRINT_KEYDEV_EVENT(event);
|
||||
break;
|
||||
#undef PRINT_KEYDEV_EVENT
|
||||
|
||||
#define PRINT_KEY_EVENT(event) \
|
||||
(void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u state=%s repeat=%s scancode=%u keycode=%u mod=%u)", \
|
||||
(uint)event->key.timestamp, (uint)event->key.windowID, \
|
||||
(void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u state=%s repeat=%s scancode=%u keycode=%u mod=%u)", \
|
||||
(uint)event->key.timestamp, (uint)event->key.windowID, (uint)event->key.which, \
|
||||
event->key.state == SDL_PRESSED ? "pressed" : "released", \
|
||||
event->key.repeat ? "true" : "false", \
|
||||
(uint)event->key.keysym.scancode, \
|
||||
@@ -343,6 +360,15 @@ static void SDL_LogEvent(const SDL_Event *event)
|
||||
(void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u text='%s')", (uint)event->text.timestamp, (uint)event->text.windowID, event->text.text);
|
||||
break;
|
||||
|
||||
#define PRINT_MOUSEDEV_EVENT(event) (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%u)", (uint)event->mdevice.timestamp, (uint)event->mdevice.which)
|
||||
SDL_EVENT_CASE(SDL_EVENT_MOUSE_ADDED)
|
||||
PRINT_MOUSEDEV_EVENT(event);
|
||||
break;
|
||||
SDL_EVENT_CASE(SDL_EVENT_MOUSE_REMOVED)
|
||||
PRINT_MOUSEDEV_EVENT(event);
|
||||
break;
|
||||
#undef PRINT_MOUSEDEV_EVENT
|
||||
|
||||
SDL_EVENT_CASE(SDL_EVENT_MOUSE_MOTION)
|
||||
(void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u state=%u x=%g y=%g xrel=%g yrel=%g)",
|
||||
(uint)event->motion.timestamp, (uint)event->motion.windowID,
|
||||
@@ -378,6 +404,12 @@ static void SDL_LogEvent(const SDL_Event *event)
|
||||
(uint)event->jaxis.axis, (int)event->jaxis.value);
|
||||
break;
|
||||
|
||||
SDL_EVENT_CASE(SDL_EVENT_JOYSTICK_BALL_MOTION)
|
||||
(void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%d ball=%u xrel=%d yrel=%d)",
|
||||
(uint)event->jball.timestamp, (int)event->jball.which,
|
||||
(uint)event->jball.ball, (int)event->jball.xrel, (int)event->jball.yrel);
|
||||
break;
|
||||
|
||||
SDL_EVENT_CASE(SDL_EVENT_JOYSTICK_HAT_MOTION)
|
||||
(void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%d hat=%u value=%u)",
|
||||
(uint)event->jhat.timestamp, (int)event->jhat.which,
|
||||
@@ -461,9 +493,9 @@ static void SDL_LogEvent(const SDL_Event *event)
|
||||
break;
|
||||
|
||||
#define PRINT_FINGER_EVENT(event) \
|
||||
(void)SDL_snprintf(details, sizeof(details), " (timestamp=%u touchid=%" SDL_PRIs64 " fingerid=%" SDL_PRIs64 " x=%f y=%f dx=%f dy=%f pressure=%f)", \
|
||||
(uint)event->tfinger.timestamp, (long long)event->tfinger.touchId, \
|
||||
(long long)event->tfinger.fingerId, event->tfinger.x, event->tfinger.y, \
|
||||
(void)SDL_snprintf(details, sizeof(details), " (timestamp=%u touchid=%" SDL_PRIu64 " fingerid=%" SDL_PRIu64 " x=%f y=%f dx=%f dy=%f pressure=%f)", \
|
||||
(uint)event->tfinger.timestamp, event->tfinger.touchID, \
|
||||
event->tfinger.fingerID, event->tfinger.x, event->tfinger.y, \
|
||||
event->tfinger.dx, event->tfinger.dy, event->tfinger.pressure)
|
||||
SDL_EVENT_CASE(SDL_EVENT_FINGER_DOWN)
|
||||
PRINT_FINGER_EVENT(event);
|
||||
@@ -553,6 +585,21 @@ static void SDL_LogEvent(const SDL_Event *event)
|
||||
break;
|
||||
#undef PRINT_AUDIODEV_EVENT
|
||||
|
||||
#define PRINT_CAMERADEV_EVENT(event) (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%u)", (uint)event->cdevice.timestamp, (uint)event->cdevice.which)
|
||||
SDL_EVENT_CASE(SDL_EVENT_CAMERA_DEVICE_ADDED)
|
||||
PRINT_CAMERADEV_EVENT(event);
|
||||
break;
|
||||
SDL_EVENT_CASE(SDL_EVENT_CAMERA_DEVICE_REMOVED)
|
||||
PRINT_CAMERADEV_EVENT(event);
|
||||
break;
|
||||
SDL_EVENT_CASE(SDL_EVENT_CAMERA_DEVICE_APPROVED)
|
||||
PRINT_CAMERADEV_EVENT(event);
|
||||
break;
|
||||
SDL_EVENT_CASE(SDL_EVENT_CAMERA_DEVICE_DENIED)
|
||||
PRINT_CAMERADEV_EVENT(event);
|
||||
break;
|
||||
#undef PRINT_CAMERADEV_EVENT
|
||||
|
||||
SDL_EVENT_CASE(SDL_EVENT_SENSOR_UPDATE)
|
||||
(void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%d data[0]=%f data[1]=%f data[2]=%f data[3]=%f data[4]=%f data[5]=%f)",
|
||||
(uint)event->sensor.timestamp, (int)event->sensor.which,
|
||||
@@ -682,14 +729,6 @@ int SDL_StartEventLoop(void)
|
||||
}
|
||||
#endif /* !SDL_THREADS_DISABLED */
|
||||
|
||||
/* Process most event types */
|
||||
SDL_SetEventEnabled(SDL_EVENT_TEXT_INPUT, SDL_FALSE);
|
||||
SDL_SetEventEnabled(SDL_EVENT_TEXT_EDITING, SDL_FALSE);
|
||||
#if 0 /* Leave these events enabled so apps can respond to items being dragged onto them at startup */
|
||||
SDL_SetEventEnabled(SDL_EVENT_DROP_FILE, SDL_FALSE);
|
||||
SDL_SetEventEnabled(SDL_EVENT_DROP_TEXT, SDL_FALSE);
|
||||
#endif
|
||||
|
||||
SDL_EventQ.active = SDL_TRUE;
|
||||
SDL_UnlockMutex(SDL_EventQ.lock);
|
||||
return 0;
|
||||
@@ -941,6 +980,10 @@ static void SDL_PumpEventsInternal(SDL_bool push_sentinel)
|
||||
SDL_UpdateAudio();
|
||||
#endif
|
||||
|
||||
#ifndef SDL_CAMERA_DISABLED
|
||||
SDL_UpdateCamera();
|
||||
#endif
|
||||
|
||||
#ifndef SDL_SENSOR_DISABLED
|
||||
/* Check for sensor state change */
|
||||
if (SDL_update_sensors) {
|
||||
@@ -983,21 +1026,36 @@ SDL_bool SDL_PollEvent(SDL_Event *event)
|
||||
return SDL_WaitEventTimeoutNS(event, 0);
|
||||
}
|
||||
|
||||
static SDL_bool SDL_events_need_periodic_poll(void)
|
||||
static Sint64 SDL_events_get_polling_interval(void)
|
||||
{
|
||||
SDL_bool need_periodic_poll = SDL_FALSE;
|
||||
Sint64 poll_intervalNS = SDL_MAX_SINT64;
|
||||
|
||||
#ifndef SDL_JOYSTICK_DISABLED
|
||||
need_periodic_poll = SDL_WasInit(SDL_INIT_JOYSTICK) && SDL_update_joysticks;
|
||||
if (SDL_WasInit(SDL_INIT_JOYSTICK) && SDL_update_joysticks) {
|
||||
if (SDL_JoysticksOpened()) {
|
||||
/* If we have joysticks open, we need to poll rapidly for events */
|
||||
poll_intervalNS = SDL_min(poll_intervalNS, EVENT_POLL_INTERVAL_NS);
|
||||
} else {
|
||||
/* If not, just poll every few seconds to enumerate new joysticks */
|
||||
poll_intervalNS = SDL_min(poll_intervalNS, ENUMERATION_POLL_INTERVAL_NS);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return need_periodic_poll;
|
||||
#ifndef SDL_SENSOR_DISABLED
|
||||
if (SDL_WasInit(SDL_INIT_SENSOR) && SDL_update_sensors && SDL_SensorsOpened()) {
|
||||
/* If we have sensors open, we need to poll rapidly for events */
|
||||
poll_intervalNS = SDL_min(poll_intervalNS, EVENT_POLL_INTERVAL_NS);
|
||||
}
|
||||
#endif
|
||||
|
||||
return poll_intervalNS;
|
||||
}
|
||||
|
||||
static int SDL_WaitEventTimeout_Device(SDL_VideoDevice *_this, SDL_Window *wakeup_window, SDL_Event *event, Uint64 start, Sint64 timeoutNS)
|
||||
{
|
||||
Sint64 loop_timeoutNS = timeoutNS;
|
||||
SDL_bool need_periodic_poll = SDL_events_need_periodic_poll();
|
||||
Sint64 poll_intervalNS = SDL_events_get_polling_interval();
|
||||
|
||||
for (;;) {
|
||||
int status;
|
||||
@@ -1039,17 +1097,18 @@ static int SDL_WaitEventTimeout_Device(SDL_VideoDevice *_this, SDL_Window *wakeu
|
||||
}
|
||||
loop_timeoutNS = (timeoutNS - elapsed);
|
||||
}
|
||||
if (need_periodic_poll) {
|
||||
/* Adjust the timeout for any polling requirements we currently have. */
|
||||
if (poll_intervalNS != SDL_MAX_SINT64) {
|
||||
if (loop_timeoutNS >= 0) {
|
||||
loop_timeoutNS = SDL_min(loop_timeoutNS, PERIODIC_POLL_INTERVAL_NS);
|
||||
loop_timeoutNS = SDL_min(loop_timeoutNS, poll_intervalNS);
|
||||
} else {
|
||||
loop_timeoutNS = PERIODIC_POLL_INTERVAL_NS;
|
||||
loop_timeoutNS = poll_intervalNS;
|
||||
}
|
||||
}
|
||||
status = _this->WaitEventTimeout(_this, loop_timeoutNS);
|
||||
/* Set wakeup_window to NULL without holding the lock. */
|
||||
_this->wakeup_window = NULL;
|
||||
if (status == 0 && need_periodic_poll && loop_timeoutNS == PERIODIC_POLL_INTERVAL_NS) {
|
||||
if (status == 0 && poll_intervalNS != SDL_MAX_SINT64 && loop_timeoutNS == poll_intervalNS) {
|
||||
/* We may have woken up to poll. Try again */
|
||||
continue;
|
||||
} else if (status <= 0) {
|
||||
@@ -1062,22 +1121,6 @@ static int SDL_WaitEventTimeout_Device(SDL_VideoDevice *_this, SDL_Window *wakeu
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SDL_bool SDL_events_need_polling(void)
|
||||
{
|
||||
SDL_bool need_polling = SDL_FALSE;
|
||||
|
||||
#ifndef SDL_JOYSTICK_DISABLED
|
||||
need_polling = SDL_WasInit(SDL_INIT_JOYSTICK) && SDL_update_joysticks && SDL_JoysticksOpened();
|
||||
#endif
|
||||
|
||||
#ifndef SDL_SENSOR_DISABLED
|
||||
need_polling = need_polling ||
|
||||
(SDL_WasInit(SDL_INIT_SENSOR) && SDL_update_sensors && SDL_SensorsOpened());
|
||||
#endif
|
||||
|
||||
return need_polling;
|
||||
}
|
||||
|
||||
static SDL_Window *SDL_find_active_window(SDL_VideoDevice *_this)
|
||||
{
|
||||
SDL_Window *window;
|
||||
@@ -1162,7 +1205,7 @@ SDL_bool SDL_WaitEventTimeoutNS(SDL_Event *event, Sint64 timeoutNS)
|
||||
/* We should have completely handled timeoutNS == 0 above */
|
||||
SDL_assert(timeoutNS != 0);
|
||||
|
||||
if (_this && _this->WaitEventTimeout && _this->SendWakeupEvent && !SDL_events_need_polling()) {
|
||||
if (_this && _this->WaitEventTimeout && _this->SendWakeupEvent) {
|
||||
/* Look if a shown window is available to send the wakeup event. */
|
||||
wakeup_window = SDL_find_active_window(_this);
|
||||
if (wakeup_window) {
|
||||
@@ -1186,7 +1229,7 @@ SDL_bool SDL_WaitEventTimeoutNS(SDL_Event *event, Sint64 timeoutNS)
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
Uint64 delay = SDL_MS_TO_NS(1);
|
||||
Uint64 delay = EVENT_POLL_INTERVAL_NS;
|
||||
if (timeoutNS > 0) {
|
||||
Uint64 now = SDL_GetTicksNS();
|
||||
if (now >= expiration) {
|
||||
@@ -1287,7 +1330,7 @@ int SDL_AddEventWatch(SDL_EventFilter filter, void *userdata)
|
||||
{
|
||||
SDL_EventWatcher *event_watchers;
|
||||
|
||||
event_watchers = SDL_realloc(SDL_event_watchers, (SDL_event_watchers_count + 1) * sizeof(*event_watchers));
|
||||
event_watchers = (SDL_EventWatcher *)SDL_realloc(SDL_event_watchers, (SDL_event_watchers_count + 1) * sizeof(*event_watchers));
|
||||
if (event_watchers) {
|
||||
SDL_EventWatcher *watcher;
|
||||
|
||||
@@ -1426,13 +1469,11 @@ SDL_bool SDL_EventEnabled(Uint32 type)
|
||||
|
||||
Uint32 SDL_RegisterEvents(int numevents)
|
||||
{
|
||||
Uint32 event_base;
|
||||
Uint32 event_base = 0;
|
||||
|
||||
if ((numevents > 0) && (SDL_userevents + numevents <= SDL_EVENT_LAST)) {
|
||||
event_base = SDL_userevents;
|
||||
SDL_userevents += numevents;
|
||||
} else {
|
||||
event_base = (Uint32)-1;
|
||||
}
|
||||
return event_base;
|
||||
}
|
||||
|
||||
310
external/sdl/SDL/src/events/SDL_keyboard.c
vendored
310
external/sdl/SDL/src/events/SDL_keyboard.c
vendored
@@ -40,9 +40,13 @@ typedef enum
|
||||
|
||||
#define KEYBOARD_SOURCE_MASK (KEYBOARD_HARDWARE | KEYBOARD_AUTORELEASE)
|
||||
|
||||
typedef struct SDL_Keyboard SDL_Keyboard;
|
||||
typedef struct SDL_KeyboardInstance
|
||||
{
|
||||
SDL_KeyboardID instance_id;
|
||||
char *name;
|
||||
} SDL_KeyboardInstance;
|
||||
|
||||
struct SDL_Keyboard
|
||||
typedef struct SDL_Keyboard
|
||||
{
|
||||
/* Data common to all keyboards */
|
||||
SDL_Window *focus;
|
||||
@@ -52,15 +56,17 @@ struct SDL_Keyboard
|
||||
SDL_Keycode keymap[SDL_NUM_SCANCODES];
|
||||
SDL_bool autorelease_pending;
|
||||
Uint64 hardware_timestamp;
|
||||
};
|
||||
} SDL_Keyboard;
|
||||
|
||||
static SDL_Keyboard SDL_keyboard;
|
||||
static int SDL_keyboard_count;
|
||||
static SDL_KeyboardInstance *SDL_keyboards;
|
||||
|
||||
static const SDL_Keycode SDL_default_keymap[SDL_NUM_SCANCODES] = {
|
||||
/* 0 */ 0,
|
||||
/* 1 */ 0,
|
||||
/* 2 */ 0,
|
||||
/* 3 */ 0,
|
||||
/* 0 */ SDLK_UNKNOWN,
|
||||
/* 1 */ SDLK_UNKNOWN,
|
||||
/* 2 */ SDLK_UNKNOWN,
|
||||
/* 3 */ SDLK_UNKNOWN,
|
||||
/* 4 */ 'a',
|
||||
/* 5 */ 'b',
|
||||
/* 6 */ 'c',
|
||||
@@ -157,7 +163,7 @@ static const SDL_Keycode SDL_default_keymap[SDL_NUM_SCANCODES] = {
|
||||
/* 97 */ SDLK_KP_9,
|
||||
/* 98 */ SDLK_KP_0,
|
||||
/* 99 */ SDLK_KP_PERIOD,
|
||||
/* 100 */ 0,
|
||||
/* 100 */ SDLK_UNKNOWN,
|
||||
/* 101 */ SDLK_APPLICATION,
|
||||
/* 102 */ SDLK_POWER,
|
||||
/* 103 */ SDLK_KP_EQUALS,
|
||||
@@ -187,29 +193,29 @@ static const SDL_Keycode SDL_default_keymap[SDL_NUM_SCANCODES] = {
|
||||
/* 127 */ SDLK_MUTE,
|
||||
/* 128 */ SDLK_VOLUMEUP,
|
||||
/* 129 */ SDLK_VOLUMEDOWN,
|
||||
/* 130 */ 0,
|
||||
/* 131 */ 0,
|
||||
/* 132 */ 0,
|
||||
/* 130 */ SDLK_UNKNOWN,
|
||||
/* 131 */ SDLK_UNKNOWN,
|
||||
/* 132 */ SDLK_UNKNOWN,
|
||||
/* 133 */ SDLK_KP_COMMA,
|
||||
/* 134 */ SDLK_KP_EQUALSAS400,
|
||||
/* 135 */ 0,
|
||||
/* 136 */ 0,
|
||||
/* 137 */ 0,
|
||||
/* 138 */ 0,
|
||||
/* 139 */ 0,
|
||||
/* 140 */ 0,
|
||||
/* 141 */ 0,
|
||||
/* 142 */ 0,
|
||||
/* 143 */ 0,
|
||||
/* 144 */ 0,
|
||||
/* 145 */ 0,
|
||||
/* 146 */ 0,
|
||||
/* 147 */ 0,
|
||||
/* 148 */ 0,
|
||||
/* 149 */ 0,
|
||||
/* 150 */ 0,
|
||||
/* 151 */ 0,
|
||||
/* 152 */ 0,
|
||||
/* 135 */ SDLK_UNKNOWN,
|
||||
/* 136 */ SDLK_UNKNOWN,
|
||||
/* 137 */ SDLK_UNKNOWN,
|
||||
/* 138 */ SDLK_UNKNOWN,
|
||||
/* 139 */ SDLK_UNKNOWN,
|
||||
/* 140 */ SDLK_UNKNOWN,
|
||||
/* 141 */ SDLK_UNKNOWN,
|
||||
/* 142 */ SDLK_UNKNOWN,
|
||||
/* 143 */ SDLK_UNKNOWN,
|
||||
/* 144 */ SDLK_UNKNOWN,
|
||||
/* 145 */ SDLK_UNKNOWN,
|
||||
/* 146 */ SDLK_UNKNOWN,
|
||||
/* 147 */ SDLK_UNKNOWN,
|
||||
/* 148 */ SDLK_UNKNOWN,
|
||||
/* 149 */ SDLK_UNKNOWN,
|
||||
/* 150 */ SDLK_UNKNOWN,
|
||||
/* 151 */ SDLK_UNKNOWN,
|
||||
/* 152 */ SDLK_UNKNOWN,
|
||||
/* 153 */ SDLK_ALTERASE,
|
||||
/* 154 */ SDLK_SYSREQ,
|
||||
/* 155 */ SDLK_CANCEL,
|
||||
@@ -222,17 +228,17 @@ static const SDL_Keycode SDL_default_keymap[SDL_NUM_SCANCODES] = {
|
||||
/* 162 */ SDLK_CLEARAGAIN,
|
||||
/* 163 */ SDLK_CRSEL,
|
||||
/* 164 */ SDLK_EXSEL,
|
||||
/* 165 */ 0,
|
||||
/* 166 */ 0,
|
||||
/* 167 */ 0,
|
||||
/* 168 */ 0,
|
||||
/* 169 */ 0,
|
||||
/* 170 */ 0,
|
||||
/* 171 */ 0,
|
||||
/* 172 */ 0,
|
||||
/* 173 */ 0,
|
||||
/* 174 */ 0,
|
||||
/* 175 */ 0,
|
||||
/* 165 */ SDLK_UNKNOWN,
|
||||
/* 166 */ SDLK_UNKNOWN,
|
||||
/* 167 */ SDLK_UNKNOWN,
|
||||
/* 168 */ SDLK_UNKNOWN,
|
||||
/* 169 */ SDLK_UNKNOWN,
|
||||
/* 170 */ SDLK_UNKNOWN,
|
||||
/* 171 */ SDLK_UNKNOWN,
|
||||
/* 172 */ SDLK_UNKNOWN,
|
||||
/* 173 */ SDLK_UNKNOWN,
|
||||
/* 174 */ SDLK_UNKNOWN,
|
||||
/* 175 */ SDLK_UNKNOWN,
|
||||
/* 176 */ SDLK_KP_00,
|
||||
/* 177 */ SDLK_KP_000,
|
||||
/* 178 */ SDLK_THOUSANDSSEPARATOR,
|
||||
@@ -279,8 +285,8 @@ static const SDL_Keycode SDL_default_keymap[SDL_NUM_SCANCODES] = {
|
||||
/* 219 */ SDLK_KP_OCTAL,
|
||||
/* 220 */ SDLK_KP_DECIMAL,
|
||||
/* 221 */ SDLK_KP_HEXADECIMAL,
|
||||
/* 222 */ 0,
|
||||
/* 223 */ 0,
|
||||
/* 222 */ SDLK_UNKNOWN,
|
||||
/* 223 */ SDLK_UNKNOWN,
|
||||
/* 224 */ SDLK_LCTRL,
|
||||
/* 225 */ SDLK_LSHIFT,
|
||||
/* 226 */ SDLK_LALT,
|
||||
@@ -289,31 +295,31 @@ static const SDL_Keycode SDL_default_keymap[SDL_NUM_SCANCODES] = {
|
||||
/* 229 */ SDLK_RSHIFT,
|
||||
/* 230 */ SDLK_RALT,
|
||||
/* 231 */ SDLK_RGUI,
|
||||
/* 232 */ 0,
|
||||
/* 233 */ 0,
|
||||
/* 234 */ 0,
|
||||
/* 235 */ 0,
|
||||
/* 236 */ 0,
|
||||
/* 237 */ 0,
|
||||
/* 238 */ 0,
|
||||
/* 239 */ 0,
|
||||
/* 240 */ 0,
|
||||
/* 241 */ 0,
|
||||
/* 242 */ 0,
|
||||
/* 243 */ 0,
|
||||
/* 244 */ 0,
|
||||
/* 245 */ 0,
|
||||
/* 246 */ 0,
|
||||
/* 247 */ 0,
|
||||
/* 248 */ 0,
|
||||
/* 249 */ 0,
|
||||
/* 250 */ 0,
|
||||
/* 251 */ 0,
|
||||
/* 252 */ 0,
|
||||
/* 253 */ 0,
|
||||
/* 254 */ 0,
|
||||
/* 255 */ 0,
|
||||
/* 256 */ 0,
|
||||
/* 232 */ SDLK_UNKNOWN,
|
||||
/* 233 */ SDLK_UNKNOWN,
|
||||
/* 234 */ SDLK_UNKNOWN,
|
||||
/* 235 */ SDLK_UNKNOWN,
|
||||
/* 236 */ SDLK_UNKNOWN,
|
||||
/* 237 */ SDLK_UNKNOWN,
|
||||
/* 238 */ SDLK_UNKNOWN,
|
||||
/* 239 */ SDLK_UNKNOWN,
|
||||
/* 240 */ SDLK_UNKNOWN,
|
||||
/* 241 */ SDLK_UNKNOWN,
|
||||
/* 242 */ SDLK_UNKNOWN,
|
||||
/* 243 */ SDLK_UNKNOWN,
|
||||
/* 244 */ SDLK_UNKNOWN,
|
||||
/* 245 */ SDLK_UNKNOWN,
|
||||
/* 246 */ SDLK_UNKNOWN,
|
||||
/* 247 */ SDLK_UNKNOWN,
|
||||
/* 248 */ SDLK_UNKNOWN,
|
||||
/* 249 */ SDLK_UNKNOWN,
|
||||
/* 250 */ SDLK_UNKNOWN,
|
||||
/* 251 */ SDLK_UNKNOWN,
|
||||
/* 252 */ SDLK_UNKNOWN,
|
||||
/* 253 */ SDLK_UNKNOWN,
|
||||
/* 254 */ SDLK_UNKNOWN,
|
||||
/* 255 */ SDLK_UNKNOWN,
|
||||
/* 256 */ SDLK_UNKNOWN,
|
||||
/* 257 */ SDLK_MODE,
|
||||
/* 258 */ SDLK_AUDIONEXT,
|
||||
/* 259 */ SDLK_AUDIOPREV,
|
||||
@@ -678,6 +684,116 @@ int SDL_InitKeyboard(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
SDL_bool SDL_IsKeyboard(Uint16 vendor, Uint16 product, int num_keys)
|
||||
{
|
||||
const int REAL_KEYBOARD_KEY_COUNT = 50;
|
||||
if (num_keys > 0 && num_keys < REAL_KEYBOARD_KEY_COUNT) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
/* Eventually we'll have a blacklist of devices that enumerate as keyboards but aren't really */
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
static int SDL_GetKeyboardIndex(SDL_KeyboardID keyboardID)
|
||||
{
|
||||
for (int i = 0; i < SDL_keyboard_count; ++i) {
|
||||
if (keyboardID == SDL_keyboards[i].instance_id) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void SDL_AddKeyboard(SDL_KeyboardID keyboardID, const char *name, SDL_bool send_event)
|
||||
{
|
||||
int keyboard_index = SDL_GetKeyboardIndex(keyboardID);
|
||||
if (keyboard_index >= 0) {
|
||||
/* We already know about this keyboard */
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_assert(keyboardID != 0);
|
||||
|
||||
SDL_KeyboardInstance *keyboards = (SDL_KeyboardInstance *)SDL_realloc(SDL_keyboards, (SDL_keyboard_count + 1) * sizeof(*keyboards));
|
||||
if (!keyboards) {
|
||||
return;
|
||||
}
|
||||
SDL_KeyboardInstance *instance = &keyboards[SDL_keyboard_count];
|
||||
instance->instance_id = keyboardID;
|
||||
instance->name = SDL_strdup(name ? name : "");
|
||||
SDL_keyboards = keyboards;
|
||||
++SDL_keyboard_count;
|
||||
|
||||
if (send_event) {
|
||||
SDL_Event event;
|
||||
SDL_zero(event);
|
||||
event.type = SDL_EVENT_KEYBOARD_ADDED;
|
||||
event.kdevice.which = keyboardID;
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
}
|
||||
|
||||
void SDL_RemoveKeyboard(SDL_KeyboardID keyboardID)
|
||||
{
|
||||
int keyboard_index = SDL_GetKeyboardIndex(keyboardID);
|
||||
if (keyboard_index < 0) {
|
||||
/* We don't know about this keyboard */
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_free(SDL_keyboards[keyboard_index].name);
|
||||
|
||||
if (keyboard_index != SDL_keyboard_count - 1) {
|
||||
SDL_memcpy(&SDL_keyboards[keyboard_index], &SDL_keyboards[keyboard_index + 1], (SDL_keyboard_count - keyboard_index - 1) * sizeof(SDL_keyboards[keyboard_index]));
|
||||
}
|
||||
--SDL_keyboard_count;
|
||||
|
||||
SDL_Event event;
|
||||
SDL_zero(event);
|
||||
event.type = SDL_EVENT_KEYBOARD_REMOVED;
|
||||
event.kdevice.which = keyboardID;
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
|
||||
SDL_bool SDL_HasKeyboard(void)
|
||||
{
|
||||
return (SDL_keyboard_count > 0);
|
||||
}
|
||||
|
||||
SDL_KeyboardID *SDL_GetKeyboards(int *count)
|
||||
{
|
||||
int i;
|
||||
SDL_KeyboardID *keyboards;
|
||||
|
||||
keyboards = (SDL_JoystickID *)SDL_malloc((SDL_keyboard_count + 1) * sizeof(*keyboards));
|
||||
if (keyboards) {
|
||||
if (count) {
|
||||
*count = SDL_keyboard_count;
|
||||
}
|
||||
|
||||
for (i = 0; i < SDL_keyboard_count; ++i) {
|
||||
keyboards[i] = SDL_keyboards[i].instance_id;
|
||||
}
|
||||
keyboards[i] = 0;
|
||||
} else {
|
||||
if (count) {
|
||||
*count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return keyboards;
|
||||
}
|
||||
|
||||
const char *SDL_GetKeyboardInstanceName(SDL_KeyboardID instance_id)
|
||||
{
|
||||
int keyboard_index = SDL_GetKeyboardIndex(instance_id);
|
||||
if (keyboard_index < 0) {
|
||||
return NULL;
|
||||
}
|
||||
return SDL_keyboards[keyboard_index].name;
|
||||
}
|
||||
|
||||
void SDL_ResetKeyboard(void)
|
||||
{
|
||||
SDL_Keyboard *keyboard = &SDL_keyboard;
|
||||
@@ -688,7 +804,7 @@ void SDL_ResetKeyboard(void)
|
||||
#endif
|
||||
for (scancode = (SDL_Scancode)0; scancode < SDL_NUM_SCANCODES; ++scancode) {
|
||||
if (keyboard->keystate[scancode] == SDL_PRESSED) {
|
||||
SDL_SendKeyboardKey(0, SDL_RELEASED, scancode);
|
||||
SDL_SendKeyboardKey(0, SDL_GLOBAL_KEYBOARD_ID, SDL_RELEASED, scancode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -796,11 +912,10 @@ int SDL_SetKeyboardFocus(SDL_Window *window)
|
||||
SDL_assert(!(keyboard->focus->flags & SDL_WINDOW_MOUSE_CAPTURE));
|
||||
}
|
||||
|
||||
SDL_SendWindowEvent(keyboard->focus, SDL_EVENT_WINDOW_FOCUS_LOST,
|
||||
0, 0);
|
||||
SDL_SendWindowEvent(keyboard->focus, SDL_EVENT_WINDOW_FOCUS_LOST, 0, 0);
|
||||
|
||||
/* Ensures IME compositions are committed */
|
||||
if (SDL_EventEnabled(SDL_EVENT_TEXT_INPUT)) {
|
||||
if (SDL_TextInputActive()) {
|
||||
if (video && video->StopTextInput) {
|
||||
video->StopTextInput(video);
|
||||
}
|
||||
@@ -810,10 +925,9 @@ int SDL_SetKeyboardFocus(SDL_Window *window)
|
||||
keyboard->focus = window;
|
||||
|
||||
if (keyboard->focus) {
|
||||
SDL_SendWindowEvent(keyboard->focus, SDL_EVENT_WINDOW_FOCUS_GAINED,
|
||||
0, 0);
|
||||
SDL_SendWindowEvent(keyboard->focus, SDL_EVENT_WINDOW_FOCUS_GAINED, 0, 0);
|
||||
|
||||
if (SDL_EventEnabled(SDL_EVENT_TEXT_INPUT)) {
|
||||
if (SDL_TextInputActive()) {
|
||||
if (video && video->StartTextInput) {
|
||||
video->StartTextInput(video);
|
||||
}
|
||||
@@ -822,7 +936,7 @@ int SDL_SetKeyboardFocus(SDL_Window *window)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int SDL_SendKeyboardKeyInternal(Uint64 timestamp, SDL_KeyboardFlags flags, Uint8 state, SDL_Scancode scancode, SDL_Keycode keycode)
|
||||
static int SDL_SendKeyboardKeyInternal(Uint64 timestamp, Uint32 flags, SDL_KeyboardID keyboardID, Uint8 state, SDL_Scancode scancode, SDL_Keycode keycode)
|
||||
{
|
||||
SDL_Keyboard *keyboard = &SDL_keyboard;
|
||||
int posted;
|
||||
@@ -949,6 +1063,7 @@ static int SDL_SendKeyboardKeyInternal(Uint64 timestamp, SDL_KeyboardFlags flags
|
||||
event.key.keysym.sym = keycode;
|
||||
event.key.keysym.mod = keyboard->modstate;
|
||||
event.key.windowID = keyboard->focus ? keyboard->focus->id : 0;
|
||||
event.key.which = keyboardID;
|
||||
posted = (SDL_PushEvent(&event) > 0);
|
||||
}
|
||||
|
||||
@@ -982,43 +1097,43 @@ int SDL_SendKeyboardUnicodeKey(Uint64 timestamp, Uint32 ch)
|
||||
|
||||
if (mod & SDL_KMOD_SHIFT) {
|
||||
/* If the character uses shift, press shift down */
|
||||
SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_PRESSED, SDL_SCANCODE_LSHIFT, SDLK_UNKNOWN);
|
||||
SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_GLOBAL_KEYBOARD_ID, SDL_PRESSED, SDL_SCANCODE_LSHIFT, SDLK_UNKNOWN);
|
||||
}
|
||||
|
||||
/* Send a keydown and keyup for the character */
|
||||
SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_PRESSED, code, SDLK_UNKNOWN);
|
||||
SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_RELEASED, code, SDLK_UNKNOWN);
|
||||
SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_GLOBAL_KEYBOARD_ID, SDL_PRESSED, code, SDLK_UNKNOWN);
|
||||
SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_GLOBAL_KEYBOARD_ID, SDL_RELEASED, code, SDLK_UNKNOWN);
|
||||
|
||||
if (mod & SDL_KMOD_SHIFT) {
|
||||
/* If the character uses shift, release shift */
|
||||
SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_RELEASED, SDL_SCANCODE_LSHIFT, SDLK_UNKNOWN);
|
||||
SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_GLOBAL_KEYBOARD_ID, SDL_RELEASED, SDL_SCANCODE_LSHIFT, SDLK_UNKNOWN);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDL_SendVirtualKeyboardKey(Uint64 timestamp, Uint8 state, SDL_Scancode scancode)
|
||||
{
|
||||
return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, state, scancode, SDLK_UNKNOWN);
|
||||
return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_GLOBAL_KEYBOARD_ID, state, scancode, SDLK_UNKNOWN);
|
||||
}
|
||||
|
||||
int SDL_SendKeyboardKey(Uint64 timestamp, Uint8 state, SDL_Scancode scancode)
|
||||
int SDL_SendKeyboardKey(Uint64 timestamp, SDL_KeyboardID keyboardID, Uint8 state, SDL_Scancode scancode)
|
||||
{
|
||||
return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_HARDWARE, state, scancode, SDLK_UNKNOWN);
|
||||
return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_HARDWARE, keyboardID, state, scancode, SDLK_UNKNOWN);
|
||||
}
|
||||
|
||||
int SDL_SendKeyboardKeyAndKeycode(Uint64 timestamp, Uint8 state, SDL_Scancode scancode, SDL_Keycode keycode)
|
||||
int SDL_SendKeyboardKeyAndKeycode(Uint64 timestamp, SDL_KeyboardID keyboardID, Uint8 state, SDL_Scancode scancode, SDL_Keycode keycode)
|
||||
{
|
||||
return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_HARDWARE, state, scancode, keycode);
|
||||
return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_HARDWARE, keyboardID, state, scancode, keycode);
|
||||
}
|
||||
|
||||
int SDL_SendKeyboardKeyAutoRelease(Uint64 timestamp, SDL_Scancode scancode)
|
||||
{
|
||||
return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_AUTORELEASE, SDL_PRESSED, scancode, SDLK_UNKNOWN);
|
||||
return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_AUTORELEASE, SDL_GLOBAL_KEYBOARD_ID, SDL_PRESSED, scancode, SDLK_UNKNOWN);
|
||||
}
|
||||
|
||||
int SDL_SendKeyboardKeyIgnoreModifiers(Uint64 timestamp, Uint8 state, SDL_Scancode scancode)
|
||||
int SDL_SendKeyboardKeyIgnoreModifiers(Uint64 timestamp, SDL_KeyboardID keyboardID, Uint8 state, SDL_Scancode scancode)
|
||||
{
|
||||
return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_HARDWARE | KEYBOARD_IGNOREMODIFIERS, state, scancode, SDLK_UNKNOWN);
|
||||
return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_HARDWARE | KEYBOARD_IGNOREMODIFIERS, keyboardID, state, scancode, SDLK_UNKNOWN);
|
||||
}
|
||||
|
||||
void SDL_ReleaseAutoReleaseKeys(void)
|
||||
@@ -1029,7 +1144,7 @@ void SDL_ReleaseAutoReleaseKeys(void)
|
||||
if (keyboard->autorelease_pending) {
|
||||
for (scancode = SDL_SCANCODE_UNKNOWN; scancode < SDL_NUM_SCANCODES; ++scancode) {
|
||||
if (keyboard->keysource[scancode] == KEYBOARD_AUTORELEASE) {
|
||||
SDL_SendKeyboardKeyInternal(0, KEYBOARD_AUTORELEASE, SDL_RELEASED, scancode, SDLK_UNKNOWN);
|
||||
SDL_SendKeyboardKeyInternal(0, KEYBOARD_AUTORELEASE, SDL_GLOBAL_KEYBOARD_ID, SDL_RELEASED, scancode, SDLK_UNKNOWN);
|
||||
}
|
||||
}
|
||||
keyboard->autorelease_pending = SDL_FALSE;
|
||||
@@ -1062,6 +1177,14 @@ int SDL_SendKeyboardText(const char *text)
|
||||
SDL_Keyboard *keyboard = &SDL_keyboard;
|
||||
int posted;
|
||||
|
||||
if (!SDL_TextInputActive()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!text || !*text) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Don't post text events for unprintable characters */
|
||||
if (SDL_iscntrl((unsigned char)*text)) {
|
||||
return 0;
|
||||
@@ -1092,6 +1215,14 @@ int SDL_SendEditingText(const char *text, int start, int length)
|
||||
SDL_Keyboard *keyboard = &SDL_keyboard;
|
||||
int posted;
|
||||
|
||||
if (!SDL_TextInputActive()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!text) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Post the event, if desired */
|
||||
posted = 0;
|
||||
if (SDL_EventEnabled(SDL_EVENT_TEXT_EDITING)) {
|
||||
@@ -1117,6 +1248,9 @@ int SDL_SendEditingText(const char *text, int start, int length)
|
||||
|
||||
void SDL_QuitKeyboard(void)
|
||||
{
|
||||
SDL_keyboard_count = 0;
|
||||
SDL_free(SDL_keyboards);
|
||||
SDL_keyboards = NULL;
|
||||
}
|
||||
|
||||
const Uint8 *SDL_GetKeyboardState(int *numkeys)
|
||||
|
||||
21
external/sdl/SDL/src/events/SDL_keyboard_c.h
vendored
21
external/sdl/SDL/src/events/SDL_keyboard_c.h
vendored
@@ -23,9 +23,24 @@
|
||||
#ifndef SDL_keyboard_c_h_
|
||||
#define SDL_keyboard_c_h_
|
||||
|
||||
/* Keyboard events not associated with a specific input device */
|
||||
#define SDL_GLOBAL_KEYBOARD_ID 0
|
||||
|
||||
/* The default keyboard input device, for platforms that don't have multiple keyboards */
|
||||
#define SDL_DEFAULT_KEYBOARD_ID 1
|
||||
|
||||
/* Initialize the keyboard subsystem */
|
||||
extern int SDL_InitKeyboard(void);
|
||||
|
||||
/* Return whether a device is actually a keyboard */
|
||||
extern SDL_bool SDL_IsKeyboard(Uint16 vendor, Uint16 product, int num_keys);
|
||||
|
||||
/* A keyboard has been added to the system */
|
||||
extern void SDL_AddKeyboard(SDL_KeyboardID keyboardID, const char *name, SDL_bool send_event);
|
||||
|
||||
/* A keyboard has been removed from the system */
|
||||
extern void SDL_RemoveKeyboard(SDL_KeyboardID keyboardID);
|
||||
|
||||
/* Get the default keymap */
|
||||
extern void SDL_GetDefaultKeymap(SDL_Keycode *keymap);
|
||||
|
||||
@@ -53,13 +68,13 @@ extern int SDL_SendKeyboardUnicodeKey(Uint64 timestamp, Uint32 ch);
|
||||
extern int SDL_SendVirtualKeyboardKey(Uint64 timestamp, Uint8 state, SDL_Scancode scancode);
|
||||
|
||||
/* Send a keyboard key event */
|
||||
extern int SDL_SendKeyboardKey(Uint64 timestamp, Uint8 state, SDL_Scancode scancode);
|
||||
extern int SDL_SendKeyboardKey(Uint64 timestamp, SDL_KeyboardID keyboardID, Uint8 state, SDL_Scancode scancode);
|
||||
extern int SDL_SendKeyboardKeyAutoRelease(Uint64 timestamp, SDL_Scancode scancode);
|
||||
extern int SDL_SendKeyboardKeyIgnoreModifiers(Uint64 timestamp, Uint8 state, SDL_Scancode scancode);
|
||||
extern int SDL_SendKeyboardKeyIgnoreModifiers(Uint64 timestamp, SDL_KeyboardID keyboardID, Uint8 state, SDL_Scancode scancode);
|
||||
|
||||
/* This is for platforms that don't know the keymap but can report scancode and keycode directly.
|
||||
Most platforms should prefer to optionally call SDL_SetKeymap and then use SDL_SendKeyboardKey. */
|
||||
extern int SDL_SendKeyboardKeyAndKeycode(Uint64 timestamp, Uint8 state, SDL_Scancode scancode, SDL_Keycode keycode);
|
||||
extern int SDL_SendKeyboardKeyAndKeycode(Uint64 timestamp, SDL_KeyboardID keyboardID, Uint8 state, SDL_Scancode scancode, SDL_Keycode keycode);
|
||||
|
||||
/* Release all the autorelease keys */
|
||||
extern void SDL_ReleaseAutoReleaseKeys(void);
|
||||
|
||||
248
external/sdl/SDL/src/events/SDL_mouse.c
vendored
248
external/sdl/SDL/src/events/SDL_mouse.c
vendored
@@ -27,19 +27,27 @@
|
||||
#include "SDL_events_c.h"
|
||||
#include "SDL_mouse_c.h"
|
||||
#include "SDL_pen_c.h"
|
||||
#if defined(__WIN32__) || defined(__GDK__)
|
||||
#if defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_GDK)
|
||||
#include "../core/windows/SDL_windows.h" // For GetDoubleClickTime()
|
||||
#endif
|
||||
|
||||
/* #define DEBUG_MOUSE */
|
||||
|
||||
typedef struct SDL_MouseInstance
|
||||
{
|
||||
SDL_MouseID instance_id;
|
||||
char *name;
|
||||
} SDL_MouseInstance;
|
||||
|
||||
/* The mouse state */
|
||||
static SDL_Mouse SDL_mouse;
|
||||
static int SDL_mouse_count;
|
||||
static SDL_MouseInstance *SDL_mice;
|
||||
|
||||
/* for mapping mouse events to touch */
|
||||
static SDL_bool track_mouse_down = SDL_FALSE;
|
||||
|
||||
static int SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, int relative, float x, float y);
|
||||
static int SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, SDL_bool relative, float x, float y);
|
||||
|
||||
static void SDLCALL SDL_MouseDoubleClickTimeChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
|
||||
{
|
||||
@@ -48,7 +56,7 @@ static void SDLCALL SDL_MouseDoubleClickTimeChanged(void *userdata, const char *
|
||||
if (hint && *hint) {
|
||||
mouse->double_click_time = SDL_atoi(hint);
|
||||
} else {
|
||||
#if defined(__WIN32__) || defined(__WINGDK__)
|
||||
#if defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_WINGDK)
|
||||
mouse->double_click_time = GetDoubleClickTime();
|
||||
#else
|
||||
mouse->double_click_time = 500;
|
||||
@@ -107,7 +115,7 @@ static void SDLCALL SDL_TouchMouseEventsChanged(void *userdata, const char *name
|
||||
mouse->touch_mouse_events = SDL_GetStringBoolean(hint, SDL_TRUE);
|
||||
}
|
||||
|
||||
#ifdef __vita__
|
||||
#ifdef SDL_PLATFORM_VITA
|
||||
static void SDLCALL SDL_VitaTouchMouseDeviceChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
|
||||
{
|
||||
SDL_Mouse *mouse = (SDL_Mouse *)userdata;
|
||||
@@ -133,7 +141,7 @@ static void SDLCALL SDL_MouseTouchEventsChanged(void *userdata, const char *name
|
||||
SDL_Mouse *mouse = (SDL_Mouse *)userdata;
|
||||
SDL_bool default_value;
|
||||
|
||||
#if defined(__ANDROID__) || (defined(__IOS__) && !defined(__TVOS__))
|
||||
#if defined(SDL_PLATFORM_ANDROID) || (defined(SDL_PLATFORM_IOS) && !defined(SDL_PLATFORM_TVOS))
|
||||
default_value = SDL_TRUE;
|
||||
#else
|
||||
default_value = SDL_FALSE;
|
||||
@@ -188,7 +196,7 @@ int SDL_PreInitMouse(void)
|
||||
SDL_AddHintCallback(SDL_HINT_TOUCH_MOUSE_EVENTS,
|
||||
SDL_TouchMouseEventsChanged, mouse);
|
||||
|
||||
#ifdef __vita__
|
||||
#ifdef SDL_PLATFORM_VITA
|
||||
SDL_AddHintCallback(SDL_HINT_VITA_TOUCH_MOUSE_DEVICE,
|
||||
SDL_VitaTouchMouseDeviceChanged, mouse);
|
||||
#endif
|
||||
@@ -227,6 +235,124 @@ void SDL_PostInitMouse(void)
|
||||
SDL_PenInit();
|
||||
}
|
||||
|
||||
SDL_bool SDL_IsMouse(Uint16 vendor, Uint16 product)
|
||||
{
|
||||
/* Eventually we'll have a blacklist of devices that enumerate as mice but aren't really */
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
static int SDL_GetMouseIndex(SDL_MouseID mouseID)
|
||||
{
|
||||
for (int i = 0; i < SDL_mouse_count; ++i) {
|
||||
if (mouseID == SDL_mice[i].instance_id) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void SDL_AddMouse(SDL_MouseID mouseID, const char *name, SDL_bool send_event)
|
||||
{
|
||||
int mouse_index = SDL_GetMouseIndex(mouseID);
|
||||
if (mouse_index >= 0) {
|
||||
/* We already know about this mouse */
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_assert(mouseID != 0);
|
||||
|
||||
SDL_MouseInstance *mice = (SDL_MouseInstance *)SDL_realloc(SDL_mice, (SDL_mouse_count + 1) * sizeof(*mice));
|
||||
if (!mice) {
|
||||
return;
|
||||
}
|
||||
SDL_MouseInstance *instance = &mice[SDL_mouse_count];
|
||||
instance->instance_id = mouseID;
|
||||
instance->name = SDL_strdup(name ? name : "");
|
||||
SDL_mice = mice;
|
||||
++SDL_mouse_count;
|
||||
|
||||
if (send_event) {
|
||||
SDL_Event event;
|
||||
SDL_zero(event);
|
||||
event.type = SDL_EVENT_MOUSE_ADDED;
|
||||
event.mdevice.which = mouseID;
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
}
|
||||
|
||||
void SDL_RemoveMouse(SDL_MouseID mouseID)
|
||||
{
|
||||
int mouse_index = SDL_GetMouseIndex(mouseID);
|
||||
if (mouse_index < 0) {
|
||||
/* We don't know about this mouse */
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_free(SDL_mice[mouse_index].name);
|
||||
|
||||
if (mouse_index != SDL_mouse_count - 1) {
|
||||
SDL_memcpy(&SDL_mice[mouse_index], &SDL_mice[mouse_index + 1], (SDL_mouse_count - mouse_index - 1) * sizeof(SDL_mice[mouse_index]));
|
||||
}
|
||||
--SDL_mouse_count;
|
||||
|
||||
/* Remove any mouse input sources for this mouseID */
|
||||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
for (int i = 0; i < mouse->num_sources; ++i) {
|
||||
SDL_MouseInputSource *source = &mouse->sources[i];
|
||||
if (source->mouseID == mouseID) {
|
||||
if (i != mouse->num_sources - 1) {
|
||||
SDL_memcpy(&mouse->sources[i], &mouse->sources[i + 1], (mouse->num_sources - i - 1) * sizeof(mouse->sources[i]));
|
||||
}
|
||||
--mouse->num_sources;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_Event event;
|
||||
SDL_zero(event);
|
||||
event.type = SDL_EVENT_MOUSE_REMOVED;
|
||||
event.mdevice.which = mouseID;
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
|
||||
SDL_bool SDL_HasMouse(void)
|
||||
{
|
||||
return (SDL_mouse_count > 0);
|
||||
}
|
||||
|
||||
SDL_MouseID *SDL_GetMice(int *count)
|
||||
{
|
||||
int i;
|
||||
SDL_MouseID *mice;
|
||||
|
||||
mice = (SDL_JoystickID *)SDL_malloc((SDL_mouse_count + 1) * sizeof(*mice));
|
||||
if (mice) {
|
||||
if (count) {
|
||||
*count = SDL_mouse_count;
|
||||
}
|
||||
|
||||
for (i = 0; i < SDL_mouse_count; ++i) {
|
||||
mice[i] = SDL_mice[i].instance_id;
|
||||
}
|
||||
mice[i] = 0;
|
||||
} else {
|
||||
if (count) {
|
||||
*count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return mice;
|
||||
}
|
||||
|
||||
const char *SDL_GetMouseInstanceName(SDL_MouseID instance_id)
|
||||
{
|
||||
int mouse_index = SDL_GetMouseIndex(instance_id);
|
||||
if (mouse_index < 0) {
|
||||
return NULL;
|
||||
}
|
||||
return SDL_mice[mouse_index].name;
|
||||
}
|
||||
|
||||
void SDL_SetDefaultCursor(SDL_Cursor *cursor)
|
||||
{
|
||||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
@@ -276,14 +402,21 @@ SDL_Mouse *SDL_GetMouse(void)
|
||||
return &SDL_mouse;
|
||||
}
|
||||
|
||||
static Uint32 GetButtonState(SDL_Mouse *mouse, SDL_bool include_touch)
|
||||
Uint32 SDL_GetMouseButtonState(SDL_Mouse *mouse, SDL_MouseID mouseID, SDL_bool include_touch)
|
||||
{
|
||||
int i;
|
||||
Uint32 buttonstate = 0;
|
||||
|
||||
for (i = 0; i < mouse->num_sources; ++i) {
|
||||
if (include_touch || mouse->sources[i].mouseID != SDL_TOUCH_MOUSEID) {
|
||||
buttonstate |= mouse->sources[i].buttonstate;
|
||||
if (mouseID == SDL_GLOBAL_MOUSE_ID || mouseID == SDL_TOUCH_MOUSEID) {
|
||||
if (include_touch || mouse->sources[i].mouseID != SDL_TOUCH_MOUSEID) {
|
||||
buttonstate |= mouse->sources[i].buttonstate;
|
||||
}
|
||||
} else {
|
||||
if (mouseID == mouse->sources[i].mouseID) {
|
||||
buttonstate |= mouse->sources[i].buttonstate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return buttonstate;
|
||||
@@ -307,7 +440,7 @@ SDL_Window *SDL_GetMouseFocus(void)
|
||||
void SDL_ResetMouse(void)
|
||||
{
|
||||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
Uint32 buttonState = GetButtonState(mouse, SDL_FALSE);
|
||||
Uint32 buttonState = SDL_GetMouseButtonState(mouse, SDL_GLOBAL_MOUSE_ID, SDL_FALSE);
|
||||
int i;
|
||||
|
||||
for (i = 1; i <= sizeof(buttonState)*8; ++i) {
|
||||
@@ -315,7 +448,7 @@ void SDL_ResetMouse(void)
|
||||
SDL_SendMouseButton(0, mouse->focus, mouse->mouseID, SDL_RELEASED, i);
|
||||
}
|
||||
}
|
||||
SDL_assert(GetButtonState(mouse, SDL_FALSE) == 0);
|
||||
SDL_assert(SDL_GetMouseButtonState(mouse, SDL_GLOBAL_MOUSE_ID, SDL_FALSE) == 0);
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
@@ -355,7 +488,7 @@ void SDL_SetMouseFocus(SDL_Window *window)
|
||||
SDL_SetCursor(NULL);
|
||||
}
|
||||
|
||||
SDL_bool SDL_MousePositionInWindow(SDL_Window *window, SDL_MouseID mouseID, float x, float y)
|
||||
SDL_bool SDL_MousePositionInWindow(SDL_Window *window, float x, float y)
|
||||
{
|
||||
if (!window) {
|
||||
return SDL_FALSE;
|
||||
@@ -373,7 +506,7 @@ SDL_bool SDL_MousePositionInWindow(SDL_Window *window, SDL_MouseID mouseID, floa
|
||||
static SDL_bool SDL_UpdateMouseFocus(SDL_Window *window, float x, float y, Uint32 buttonstate, SDL_bool send_mouse_motion)
|
||||
{
|
||||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
SDL_bool inWindow = SDL_MousePositionInWindow(window, mouse->mouseID, x, y);
|
||||
SDL_bool inWindow = SDL_MousePositionInWindow(window, x, y);
|
||||
|
||||
if (!inWindow) {
|
||||
if (window == mouse->focus) {
|
||||
@@ -381,7 +514,7 @@ static SDL_bool SDL_UpdateMouseFocus(SDL_Window *window, float x, float y, Uint3
|
||||
SDL_Log("Mouse left window, synthesizing move & focus lost event\n");
|
||||
#endif
|
||||
if (send_mouse_motion) {
|
||||
SDL_PrivateSendMouseMotion(0, window, mouse->mouseID, 0, x, y);
|
||||
SDL_PrivateSendMouseMotion(0, window, SDL_GLOBAL_MOUSE_ID, SDL_FALSE, x, y);
|
||||
}
|
||||
SDL_SetMouseFocus(NULL);
|
||||
}
|
||||
@@ -394,17 +527,17 @@ static SDL_bool SDL_UpdateMouseFocus(SDL_Window *window, float x, float y, Uint3
|
||||
#endif
|
||||
SDL_SetMouseFocus(window);
|
||||
if (send_mouse_motion) {
|
||||
SDL_PrivateSendMouseMotion(0, window, mouse->mouseID, 0, x, y);
|
||||
SDL_PrivateSendMouseMotion(0, window, SDL_GLOBAL_MOUSE_ID, SDL_FALSE, x, y);
|
||||
}
|
||||
}
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
int SDL_SendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, int relative, float x, float y)
|
||||
int SDL_SendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, SDL_bool relative, float x, float y)
|
||||
{
|
||||
if (window && !relative) {
|
||||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
if (!SDL_UpdateMouseFocus(window, x, y, GetButtonState(mouse, SDL_TRUE), (mouseID != SDL_TOUCH_MOUSEID))) {
|
||||
if (!SDL_UpdateMouseFocus(window, x, y, SDL_GetMouseButtonState(mouse, mouseID, SDL_TRUE), (mouseID != SDL_TOUCH_MOUSEID))) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -438,7 +571,7 @@ static float CalculateSystemScale(SDL_Mouse *mouse, SDL_Window *window, const fl
|
||||
scale = v[i + 1] + (coef * (v[i + 3] - v[i + 1]));
|
||||
}
|
||||
}
|
||||
#ifdef __WIN32__
|
||||
#ifdef SDL_PLATFORM_WIN32
|
||||
{
|
||||
/* On Windows the mouse speed is affected by the content scale */
|
||||
SDL_VideoDisplay *display;
|
||||
@@ -558,20 +691,25 @@ static void ConstrainMousePosition(SDL_Mouse *mouse, SDL_Window *window, float *
|
||||
}
|
||||
}
|
||||
|
||||
static int SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, int relative, float x, float y)
|
||||
static int SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, SDL_bool relative, float x, float y)
|
||||
{
|
||||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
int posted;
|
||||
float xrel = 0.0f;
|
||||
float yrel = 0.0f;
|
||||
|
||||
if (!mouse->relative_mode && mouseID != SDL_TOUCH_MOUSEID && mouseID != SDL_PEN_MOUSEID) {
|
||||
/* We're not in relative mode, so all mouse events are global mouse events */
|
||||
mouseID = SDL_GLOBAL_MOUSE_ID;
|
||||
}
|
||||
|
||||
/* SDL_HINT_MOUSE_TOUCH_EVENTS: controlling whether mouse events should generate synthetic touch events */
|
||||
if (mouse->mouse_touch_events) {
|
||||
if (mouseID != SDL_TOUCH_MOUSEID && !relative && track_mouse_down) {
|
||||
if (window) {
|
||||
float normalized_x = x / (float)window->w;
|
||||
float normalized_y = y / (float)window->h;
|
||||
SDL_SendTouchMotion(timestamp, SDL_MOUSE_TOUCHID, 0, window, normalized_x, normalized_y, 1.0f);
|
||||
SDL_SendTouchMotion(timestamp, SDL_MOUSE_TOUCHID, SDL_BUTTON_LEFT, window, normalized_x, normalized_y, 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -599,7 +737,7 @@ static int SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_
|
||||
if (mouse->WarpMouse) {
|
||||
mouse->WarpMouse(window, center_x, center_y);
|
||||
} else {
|
||||
SDL_PrivateSendMouseMotion(timestamp, window, mouseID, 0, center_x, center_y);
|
||||
SDL_PrivateSendMouseMotion(timestamp, window, mouseID, SDL_FALSE, center_x, center_y);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -629,7 +767,7 @@ static int SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_
|
||||
}
|
||||
|
||||
/* Ignore relative motion positioning the first touch */
|
||||
if (mouseID == SDL_TOUCH_MOUSEID && !GetButtonState(mouse, SDL_TRUE)) {
|
||||
if (mouseID == SDL_TOUCH_MOUSEID && !SDL_GetMouseButtonState(mouse, mouseID, SDL_TRUE)) {
|
||||
xrel = 0.0f;
|
||||
yrel = 0.0f;
|
||||
}
|
||||
@@ -669,7 +807,7 @@ static int SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_
|
||||
event.motion.which = mouseID;
|
||||
/* Set us pending (or clear during a normal mouse movement event) as having triggered */
|
||||
mouse->was_touch_mouse_events = (mouseID == SDL_TOUCH_MOUSEID);
|
||||
event.motion.state = GetButtonState(mouse, SDL_TRUE);
|
||||
event.motion.state = SDL_GetMouseButtonState(mouse, mouseID, SDL_TRUE);
|
||||
event.motion.x = mouse->x;
|
||||
event.motion.y = mouse->y;
|
||||
event.motion.xrel = xrel;
|
||||
@@ -687,18 +825,35 @@ static int SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_
|
||||
return posted;
|
||||
}
|
||||
|
||||
static SDL_MouseInputSource *GetMouseInputSource(SDL_Mouse *mouse, SDL_MouseID mouseID)
|
||||
static SDL_MouseInputSource *GetMouseInputSource(SDL_Mouse *mouse, SDL_MouseID mouseID, Uint8 state, Uint8 button)
|
||||
{
|
||||
SDL_MouseInputSource *source, *sources;
|
||||
SDL_MouseInputSource *source, *match = NULL, *sources;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < mouse->num_sources; ++i) {
|
||||
source = &mouse->sources[i];
|
||||
if (source->mouseID == mouseID) {
|
||||
return source;
|
||||
match = source;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!state && (!match || !(match->buttonstate & SDL_BUTTON(button)))) {
|
||||
/* This might be a button release from a transition between mouse messages and raw input.
|
||||
* See if there's another mouse source that already has that button down and use that.
|
||||
*/
|
||||
for (i = 0; i < mouse->num_sources; ++i) {
|
||||
source = &mouse->sources[i];
|
||||
if ((source->buttonstate & SDL_BUTTON(button))) {
|
||||
match = source;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (match) {
|
||||
return match;
|
||||
}
|
||||
|
||||
sources = (SDL_MouseInputSource *)SDL_realloc(mouse->sources, (mouse->num_sources + 1) * sizeof(*mouse->sources));
|
||||
if (sources) {
|
||||
mouse->sources = sources;
|
||||
@@ -737,7 +892,12 @@ static int SDL_PrivateSendMouseButton(Uint64 timestamp, SDL_Window *window, SDL_
|
||||
Uint32 buttonstate;
|
||||
SDL_MouseInputSource *source;
|
||||
|
||||
source = GetMouseInputSource(mouse, mouseID);
|
||||
if (!mouse->relative_mode && mouseID != SDL_TOUCH_MOUSEID && mouseID != SDL_PEN_MOUSEID) {
|
||||
/* We're not in relative mode, so all mouse events are global mouse events */
|
||||
mouseID = SDL_GLOBAL_MOUSE_ID;
|
||||
}
|
||||
|
||||
source = GetMouseInputSource(mouse, mouseID, state, button);
|
||||
if (!source) {
|
||||
return 0;
|
||||
}
|
||||
@@ -754,7 +914,7 @@ static int SDL_PrivateSendMouseButton(Uint64 timestamp, SDL_Window *window, SDL_
|
||||
if (window) {
|
||||
float normalized_x = mouse->x / (float)window->w;
|
||||
float normalized_y = mouse->y / (float)window->h;
|
||||
SDL_SendTouch(timestamp, SDL_MOUSE_TOUCHID, 0, window, track_mouse_down, normalized_x, normalized_y, 1.0f);
|
||||
SDL_SendTouch(timestamp, SDL_MOUSE_TOUCHID, SDL_BUTTON_LEFT, window, track_mouse_down, normalized_x, normalized_y, 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -823,7 +983,7 @@ static int SDL_PrivateSendMouseButton(Uint64 timestamp, SDL_Window *window, SDL_
|
||||
event.type = type;
|
||||
event.common.timestamp = timestamp;
|
||||
event.button.windowID = mouse->focus ? mouse->focus->id : 0;
|
||||
event.button.which = mouseID;
|
||||
event.button.which = source->mouseID;
|
||||
event.button.state = state;
|
||||
event.button.button = button;
|
||||
event.button.clicks = (Uint8)SDL_min(clicks, 255);
|
||||
@@ -879,9 +1039,9 @@ int SDL_SendMouseWheel(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID
|
||||
event.wheel.which = mouseID;
|
||||
event.wheel.x = x;
|
||||
event.wheel.y = y;
|
||||
event.wheel.direction = (Uint32)direction;
|
||||
event.wheel.mouseX = mouse->x;
|
||||
event.wheel.mouseY = mouse->y;
|
||||
event.wheel.direction = direction;
|
||||
event.wheel.mouse_x = mouse->x;
|
||||
event.wheel.mouse_y = mouse->y;
|
||||
posted = (SDL_PushEvent(&event) > 0);
|
||||
}
|
||||
return posted;
|
||||
@@ -957,6 +1117,10 @@ void SDL_QuitMouse(void)
|
||||
|
||||
SDL_DelHintCallback(SDL_HINT_MOUSE_RELATIVE_WARP_MOTION,
|
||||
SDL_MouseRelativeWarpMotionChanged, mouse);
|
||||
|
||||
SDL_mouse_count = 0;
|
||||
SDL_free(SDL_mice);
|
||||
SDL_mice = NULL;
|
||||
}
|
||||
|
||||
Uint32 SDL_GetMouseState(float *x, float *y)
|
||||
@@ -969,7 +1133,7 @@ Uint32 SDL_GetMouseState(float *x, float *y)
|
||||
if (y) {
|
||||
*y = mouse->y;
|
||||
}
|
||||
return GetButtonState(mouse, SDL_TRUE);
|
||||
return SDL_GetMouseButtonState(mouse, SDL_GLOBAL_MOUSE_ID, SDL_TRUE);
|
||||
}
|
||||
|
||||
Uint32 SDL_GetRelativeMouseState(float *x, float *y)
|
||||
@@ -984,7 +1148,7 @@ Uint32 SDL_GetRelativeMouseState(float *x, float *y)
|
||||
}
|
||||
mouse->xdelta = 0.0f;
|
||||
mouse->ydelta = 0.0f;
|
||||
return GetButtonState(mouse, SDL_TRUE);
|
||||
return SDL_GetMouseButtonState(mouse, SDL_GLOBAL_MOUSE_ID, SDL_TRUE);
|
||||
}
|
||||
|
||||
Uint32 SDL_GetGlobalMouseState(float *x, float *y)
|
||||
@@ -1051,7 +1215,7 @@ void SDL_PerformWarpMouseInWindow(SDL_Window *window, float x, float y, SDL_bool
|
||||
(!mouse->relative_mode || mouse->relative_mode_warp)) {
|
||||
mouse->WarpMouse(window, x, y);
|
||||
} else {
|
||||
SDL_PrivateSendMouseMotion(0, window, mouse->mouseID, 0, x, y);
|
||||
SDL_PrivateSendMouseMotion(0, window, SDL_GLOBAL_MOUSE_ID, SDL_FALSE, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1161,9 +1325,9 @@ int SDL_UpdateMouseCapture(SDL_bool force_release)
|
||||
|
||||
if (!force_release) {
|
||||
if (SDL_GetMessageBoxCount() == 0 &&
|
||||
(mouse->capture_desired || (mouse->auto_capture && GetButtonState(mouse, SDL_FALSE) != 0))) {
|
||||
(mouse->capture_desired || (mouse->auto_capture && SDL_GetMouseButtonState(mouse, SDL_GLOBAL_MOUSE_ID, SDL_FALSE) != 0))) {
|
||||
if (!mouse->relative_mode) {
|
||||
capture_window = SDL_GetKeyboardFocus();
|
||||
capture_window = mouse->focus;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1209,7 +1373,7 @@ int SDL_CaptureMouse(SDL_bool enabled)
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
#if defined(__WIN32__) || defined(__WINGDK__)
|
||||
#if defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_WINGDK)
|
||||
/* Windows mouse capture is tied to the current thread, and must be called
|
||||
* from the thread that created the window being captured. Since we update
|
||||
* the mouse capture state from the event processing, any application state
|
||||
@@ -1218,7 +1382,7 @@ int SDL_CaptureMouse(SDL_bool enabled)
|
||||
if (!SDL_OnVideoThread()) {
|
||||
return SDL_SetError("SDL_CaptureMouse() must be called on the main thread");
|
||||
}
|
||||
#endif /* defined(__WIN32__) || defined(__WINGDK__) */
|
||||
#endif /* defined(SDL_PLATFORM_WIN32) || defined(SDL_PLATFORM_WINGDK) */
|
||||
|
||||
if (enabled && SDL_GetKeyboardFocus() == NULL) {
|
||||
return SDL_SetError("No window has focus");
|
||||
@@ -1238,12 +1402,12 @@ SDL_Cursor *SDL_CreateCursor(const Uint8 *data, const Uint8 *mask, int w, int h,
|
||||
const Uint32 black = 0xFF000000;
|
||||
const Uint32 white = 0xFFFFFFFF;
|
||||
const Uint32 transparent = 0x00000000;
|
||||
#if defined(__WIN32__)
|
||||
#if defined(SDL_PLATFORM_WIN32)
|
||||
/* Only Windows backend supports inverted pixels in mono cursors. */
|
||||
const Uint32 inverted = 0x00FFFFFF;
|
||||
#else
|
||||
const Uint32 inverted = 0xFF000000;
|
||||
#endif /* defined(__WIN32__) */
|
||||
#endif /* defined(SDL_PLATFORM_WIN32) */
|
||||
|
||||
/* Make sure the width is a multiple of 8 */
|
||||
w = ((w + 7) & ~7);
|
||||
@@ -1306,7 +1470,7 @@ SDL_Cursor *SDL_CreateColorCursor(SDL_Surface *surface, int hot_x, int hot_y)
|
||||
if (mouse->CreateCursor) {
|
||||
cursor = mouse->CreateCursor(surface, hot_x, hot_y);
|
||||
} else {
|
||||
cursor = SDL_calloc(1, sizeof(*cursor));
|
||||
cursor = (SDL_Cursor *)SDL_calloc(1, sizeof(*cursor));
|
||||
}
|
||||
if (cursor) {
|
||||
cursor->next = mouse->cursors;
|
||||
|
||||
27
external/sdl/SDL/src/events/SDL_mouse_c.h
vendored
27
external/sdl/SDL/src/events/SDL_mouse_c.h
vendored
@@ -23,6 +23,12 @@
|
||||
#ifndef SDL_mouse_c_h_
|
||||
#define SDL_mouse_c_h_
|
||||
|
||||
/* Mouse events not associated with a specific input device */
|
||||
#define SDL_GLOBAL_MOUSE_ID 0
|
||||
|
||||
/* The default mouse input device, for platforms that don't have multiple mice */
|
||||
#define SDL_DEFAULT_MOUSE_ID 1
|
||||
|
||||
struct SDL_Cursor
|
||||
{
|
||||
struct SDL_Cursor *next;
|
||||
@@ -75,7 +81,6 @@ typedef struct
|
||||
Uint32 (*GetGlobalMouseState)(float *x, float *y);
|
||||
|
||||
/* Data common to all mice */
|
||||
SDL_MouseID mouseID;
|
||||
SDL_Window *focus;
|
||||
float x;
|
||||
float y;
|
||||
@@ -98,7 +103,7 @@ typedef struct
|
||||
SDL_bool touch_mouse_events;
|
||||
SDL_bool mouse_touch_events;
|
||||
SDL_bool was_touch_mouse_events; /* Was a touch-mouse event pending? */
|
||||
#ifdef __vita__
|
||||
#ifdef SDL_PLATFORM_VITA
|
||||
Uint8 vita_touch_mouse_device;
|
||||
#endif
|
||||
SDL_bool auto_capture;
|
||||
@@ -128,8 +133,17 @@ extern int SDL_PreInitMouse(void);
|
||||
/* Finish initializing the mouse subsystem, called after the main video driver was initialized */
|
||||
extern void SDL_PostInitMouse(void);
|
||||
|
||||
/* Return whether a device is actually a mouse */
|
||||
extern SDL_bool SDL_IsMouse(Uint16 vendor, Uint16 product);
|
||||
|
||||
/* A mouse has been added to the system */
|
||||
extern void SDL_AddMouse(SDL_MouseID mouseID, const char *name, SDL_bool send_event);
|
||||
|
||||
/* A mouse has been removed from the system */
|
||||
extern void SDL_RemoveMouse(SDL_MouseID mouseID);
|
||||
|
||||
/* Get the mouse state structure */
|
||||
SDL_Mouse *SDL_GetMouse(void);
|
||||
extern SDL_Mouse *SDL_GetMouse(void);
|
||||
|
||||
/* Set the default mouse cursor */
|
||||
extern void SDL_SetDefaultCursor(SDL_Cursor *cursor);
|
||||
@@ -140,11 +154,14 @@ extern void SDL_SetMouseFocus(SDL_Window *window);
|
||||
/* Update the mouse capture window */
|
||||
extern int SDL_UpdateMouseCapture(SDL_bool force_release);
|
||||
|
||||
/* Get the current mouse button state for a mouse */
|
||||
Uint32 SDL_GetMouseButtonState(SDL_Mouse *mouse, SDL_MouseID mouseID, SDL_bool include_touch);
|
||||
|
||||
/* You can set either a single scale, or a set of {speed, scale} values in sorted order */
|
||||
extern int SDL_SetMouseSystemScale(int num_values, const float *values);
|
||||
|
||||
/* Send a mouse motion event */
|
||||
extern int SDL_SendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, int relative, float x, float y);
|
||||
extern int SDL_SendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, SDL_bool relative, float x, float y);
|
||||
|
||||
/* Send a mouse button event */
|
||||
extern int SDL_SendMouseButton(Uint64 timestamp, SDL_Window *window, SDL_MouseID mouseID, Uint8 state, Uint8 button);
|
||||
@@ -164,7 +181,7 @@ extern void SDL_ResetMouse(void);
|
||||
#endif /* 0 */
|
||||
|
||||
/* Check if mouse position is within window or captured by window */
|
||||
extern SDL_bool SDL_MousePositionInWindow(SDL_Window *window, SDL_MouseID mouseID, float x, float y);
|
||||
extern SDL_bool SDL_MousePositionInWindow(SDL_Window *window, float x, float y);
|
||||
|
||||
/* Shutdown the mouse subsystem */
|
||||
extern void SDL_QuitMouse(void);
|
||||
|
||||
50
external/sdl/SDL/src/events/SDL_pen.c
vendored
50
external/sdl/SDL/src/events/SDL_pen.c
vendored
@@ -97,8 +97,8 @@ static int SDLCALL pen_compare(const void *lhs, const void *rhs)
|
||||
|
||||
static int SDLCALL pen_header_compare(const void *lhs, const void *rhs)
|
||||
{
|
||||
const struct SDL_Pen_header *l = lhs;
|
||||
const struct SDL_Pen_header *r = rhs;
|
||||
const SDL_PenHeader *l = (const SDL_PenHeader *)lhs;
|
||||
const SDL_PenHeader *r = (const SDL_PenHeader *)rhs;
|
||||
int l_detached = l->flags & SDL_PEN_FLAG_DETACHED;
|
||||
int r_detached = r->flags & SDL_PEN_FLAG_DETACHED;
|
||||
|
||||
@@ -121,15 +121,13 @@ SDL_Pen *SDL_GetPenPtr(Uint32 instance_id)
|
||||
}
|
||||
|
||||
if (pen_handler.sorted) {
|
||||
struct SDL_Pen_header key;
|
||||
SDL_PenHeader key;
|
||||
SDL_Pen *pen;
|
||||
|
||||
SDL_zero(key);
|
||||
key.id = instance_id;
|
||||
|
||||
pen = SDL_bsearch(&key, pen_handler.pens,
|
||||
pen_handler.pens_known, sizeof(SDL_Pen),
|
||||
pen_header_compare);
|
||||
pen = (SDL_Pen *)SDL_bsearch(&key, pen_handler.pens, pen_handler.pens_known, sizeof(SDL_Pen), pen_header_compare);
|
||||
if (pen) {
|
||||
return pen;
|
||||
}
|
||||
@@ -149,7 +147,7 @@ SDL_PenID *SDL_GetPens(int *count)
|
||||
{
|
||||
int i;
|
||||
int pens_nr = (int)pen_handler.pens_attached;
|
||||
SDL_PenID *pens = SDL_calloc(pens_nr + 1, sizeof(SDL_PenID));
|
||||
SDL_PenID *pens = (SDL_PenID *)SDL_calloc(pens_nr + 1, sizeof(SDL_PenID));
|
||||
if (!pens) { /* OOM */
|
||||
return pens;
|
||||
}
|
||||
@@ -222,7 +220,7 @@ const char *SDL_GetPenName(SDL_PenID instance_id)
|
||||
SDL_PenSubtype SDL_GetPenType(SDL_PenID instance_id)
|
||||
{
|
||||
SDL_PenSubtype result;
|
||||
SDL_LOAD_LOCK_PEN(pen, instance_id, 0u);
|
||||
SDL_LOAD_LOCK_PEN(pen, instance_id, SDL_PEN_TYPE_UNKNOWN);
|
||||
result = pen->type;
|
||||
SDL_UNLOCK_PENS();
|
||||
return result;
|
||||
@@ -293,11 +291,11 @@ SDL_Pen *SDL_PenModifyBegin(Uint32 instance_id)
|
||||
size_t pens_to_allocate = pen_handler.pens_allocated + alloc_growth_constant;
|
||||
SDL_Pen *pens;
|
||||
if (pen_handler.pens) {
|
||||
pens = SDL_realloc(pen_handler.pens, sizeof(SDL_Pen) * pens_to_allocate);
|
||||
pens = (SDL_Pen *)SDL_realloc(pen_handler.pens, sizeof(SDL_Pen) * pens_to_allocate);
|
||||
SDL_memset(pens + pen_handler.pens_known, 0,
|
||||
sizeof(SDL_Pen) * (pens_to_allocate - pen_handler.pens_allocated));
|
||||
} else {
|
||||
pens = SDL_calloc(sizeof(SDL_Pen), pens_to_allocate);
|
||||
pens = (SDL_Pen *)SDL_calloc(sizeof(SDL_Pen), pens_to_allocate);
|
||||
}
|
||||
pen_handler.pens = pens;
|
||||
pen_handler.pens_allocated = pens_to_allocate;
|
||||
@@ -305,13 +303,13 @@ SDL_Pen *SDL_PenModifyBegin(Uint32 instance_id)
|
||||
pen = &pen_handler.pens[pen_handler.pens_known];
|
||||
pen_handler.pens_known += 1;
|
||||
|
||||
/* Default pen initialisation */
|
||||
/* Default pen initialization */
|
||||
pen->header.id = id;
|
||||
pen->header.flags = SDL_PEN_FLAG_NEW;
|
||||
pen->info.num_buttons = SDL_PEN_INFO_UNKNOWN;
|
||||
pen->info.max_tilt = SDL_PEN_INFO_UNKNOWN;
|
||||
pen->type = SDL_PEN_TYPE_PEN;
|
||||
pen->name = SDL_calloc(1, SDL_PEN_MAX_NAME); /* Never deallocated */
|
||||
pen->name = (char *)SDL_calloc(1, SDL_PEN_MAX_NAME); /* Never deallocated */
|
||||
}
|
||||
return pen;
|
||||
}
|
||||
@@ -359,6 +357,7 @@ void SDL_PenModifyEnd(SDL_Pen *pen, SDL_bool attach)
|
||||
attach = SDL_FALSE;
|
||||
} else {
|
||||
pen_handler.pens_known -= 1;
|
||||
SDL_free(pen->name);
|
||||
SDL_memset(pen, 0, sizeof(SDL_Pen));
|
||||
SDL_UNLOCK_PENS();
|
||||
return;
|
||||
@@ -498,7 +497,6 @@ int SDL_SendPenMotion(Uint64 timestamp,
|
||||
SDL_bool window_relative,
|
||||
const SDL_PenStatusInfo *status)
|
||||
{
|
||||
const SDL_Mouse *mouse = SDL_GetMouse();
|
||||
int i;
|
||||
SDL_Pen *pen = SDL_GetPenPtr(instance_id);
|
||||
SDL_Event event;
|
||||
@@ -541,7 +539,7 @@ int SDL_SendPenMotion(Uint64 timestamp,
|
||||
|
||||
send_mouse_update = (x != last_x) || (y != last_y);
|
||||
|
||||
if (!(SDL_MousePositionInWindow(window, mouse->mouseID, x, y))) {
|
||||
if (!(SDL_MousePositionInWindow(window, x, y))) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
@@ -559,7 +557,7 @@ int SDL_SendPenMotion(Uint64 timestamp,
|
||||
if (send_mouse_update) {
|
||||
switch (pen_mouse_emulation_mode) {
|
||||
case PEN_MOUSE_EMULATE:
|
||||
return (SDL_SendMouseMotion(0, window, SDL_PEN_MOUSEID, 0, x, y)) || posted;
|
||||
return (SDL_SendMouseMotion(0, window, SDL_PEN_MOUSEID, SDL_FALSE, x, y)) || posted;
|
||||
|
||||
case PEN_MOUSE_STATELESS:
|
||||
/* Report mouse event but don't update mouse state */
|
||||
@@ -575,6 +573,7 @@ int SDL_SendPenMotion(Uint64 timestamp,
|
||||
event.motion.yrel = last_y - y;
|
||||
return (SDL_PushEvent(&event) > 0) || posted;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
@@ -585,7 +584,6 @@ int SDL_SendPenMotion(Uint64 timestamp,
|
||||
|
||||
int SDL_SendPenTipEvent(Uint64 timestamp, SDL_PenID instance_id, Uint8 state)
|
||||
{
|
||||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
SDL_Pen *pen = SDL_GetPenPtr(instance_id);
|
||||
SDL_Event event;
|
||||
SDL_bool posted = SDL_FALSE;
|
||||
@@ -598,7 +596,7 @@ int SDL_SendPenTipEvent(Uint64 timestamp, SDL_PenID instance_id, Uint8 state)
|
||||
}
|
||||
window = pen->header.window;
|
||||
|
||||
if ((state == SDL_PRESSED) && !(window && SDL_MousePositionInWindow(window, mouse->mouseID, last->x, last->y))) {
|
||||
if ((state == SDL_PRESSED) && !(window && SDL_MousePositionInWindow(window, last->x, last->y))) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
@@ -664,7 +662,6 @@ int SDL_SendPenButton(Uint64 timestamp,
|
||||
SDL_PenID instance_id,
|
||||
Uint8 state, Uint8 button)
|
||||
{
|
||||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
SDL_Pen *pen = SDL_GetPenPtr(instance_id);
|
||||
SDL_Event event;
|
||||
SDL_bool posted = SDL_FALSE;
|
||||
@@ -677,7 +674,7 @@ int SDL_SendPenButton(Uint64 timestamp,
|
||||
}
|
||||
window = pen->header.window;
|
||||
|
||||
if ((state == SDL_PRESSED) && !(window && SDL_MousePositionInWindow(window, mouse->mouseID, last->x, last->y))) {
|
||||
if ((state == SDL_PRESSED) && !(window && SDL_MousePositionInWindow(window, last->x, last->y))) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
@@ -798,7 +795,7 @@ int SDL_SendPenWindowEvent(Uint64 timestamp, SDL_PenID instance_id, SDL_Window *
|
||||
|
||||
static void SDLCALL SDL_PenUpdateHint(void *userdata, const char *name, const char *oldvalue, const char *newvalue)
|
||||
{
|
||||
int *var = userdata;
|
||||
int *var = (int *)userdata;
|
||||
if (newvalue == NULL) {
|
||||
return;
|
||||
}
|
||||
@@ -832,6 +829,8 @@ void SDL_PenInit(void)
|
||||
|
||||
void SDL_PenQuit(void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
SDL_DelHintCallback(SDL_HINT_PEN_NOT_MOUSE,
|
||||
SDL_PenUpdateHint, &pen_mouse_emulation_mode);
|
||||
|
||||
@@ -841,6 +840,15 @@ void SDL_PenQuit(void)
|
||||
SDL_DestroyMutex(SDL_pen_access_lock);
|
||||
SDL_pen_access_lock = NULL;
|
||||
#endif
|
||||
|
||||
if (pen_handler.pens) {
|
||||
for (i = 0; i < pen_handler.pens_known; ++i) {
|
||||
SDL_free(pen_handler.pens[i].name);
|
||||
}
|
||||
SDL_free(pen_handler.pens);
|
||||
/* Reset static pen information */
|
||||
SDL_memset(&pen_handler, 0, sizeof(pen_handler));
|
||||
}
|
||||
}
|
||||
|
||||
SDL_bool SDL_PenPerformHitTest(void)
|
||||
@@ -1053,7 +1061,7 @@ int SDL_PenModifyForWacomID(SDL_Pen *pen, Uint32 wacom_devicetype_id, Uint32 *ax
|
||||
wacom_devicetype_id = PEN_WACOM_ID_INVALID; /* force detection to fail */
|
||||
#endif
|
||||
|
||||
#if defined(__LINUX__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
#if defined(SDL_PLATFORM_LINUX) || defined(SDL_PLATFORM_FREEBSD) || defined(SDL_PLATFORM_NETBSD) || defined(SDL_PLATFORM_OPENBSD)
|
||||
/* According to Ping Cheng, the curent Wacom for Linux maintainer, device IDs on Linux
|
||||
squeeze a "0" nibble after the 3rd (least significant) nibble.
|
||||
This may also affect the *BSDs, so they are heuristically included here.
|
||||
|
||||
14
external/sdl/SDL/src/events/SDL_pen_c.h
vendored
14
external/sdl/SDL/src/events/SDL_pen_c.h
vendored
@@ -56,6 +56,13 @@ typedef struct SDL_PenStatusInfo
|
||||
Uint16 buttons; /* SDL_BUTTON(1) | SDL_BUTTON(2) | ... | SDL_PEN_DOWN_MASK */
|
||||
} SDL_PenStatusInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SDL_PenID id; /* id determines sort order unless SDL_PEN_FLAG_DETACHED is set */
|
||||
Uint32 flags; /* SDL_PEN_FLAG_* | SDK_PEN_DOWN_MASK | SDL_PEN_INK_MASK | SDL_PEN_ERASER_MASK | SDL_PEN_AXIS_* */
|
||||
SDL_Window *window; /* Current SDL window for this pen, or NULL */
|
||||
} SDL_PenHeader;
|
||||
|
||||
/**
|
||||
* Internal (backend driver-independent) pen representation
|
||||
*
|
||||
@@ -66,12 +73,7 @@ typedef struct SDL_PenStatusInfo
|
||||
typedef struct SDL_Pen
|
||||
{
|
||||
/* Backend driver MUST NOT not write to: */
|
||||
struct SDL_Pen_header
|
||||
{
|
||||
SDL_PenID id; /* id determines sort order unless SDL_PEN_FLAG_DETACHED is set */
|
||||
Uint32 flags; /* SDL_PEN_FLAG_* | SDK_PEN_DOWN_MASK | SDL_PEN_INK_MASK | SDL_PEN_ERASER_MASK | SDL_PEN_AXIS_* */
|
||||
SDL_Window *window; /* Current SDL window for this pen, or NULL */
|
||||
} header;
|
||||
SDL_PenHeader header;
|
||||
|
||||
SDL_PenStatusInfo last; /* Last reported status, normally read-only for backend */
|
||||
|
||||
|
||||
22
external/sdl/SDL/src/events/SDL_touch.c
vendored
22
external/sdl/SDL/src/events/SDL_touch.c
vendored
@@ -158,6 +158,8 @@ int SDL_AddTouch(SDL_TouchID touchID, SDL_TouchDeviceType type, const char *name
|
||||
SDL_Touch **touchDevices;
|
||||
int index;
|
||||
|
||||
SDL_assert(touchID != 0);
|
||||
|
||||
index = SDL_GetTouchIndex(touchID);
|
||||
if (index >= 0) {
|
||||
return index;
|
||||
@@ -196,6 +198,8 @@ static int SDL_AddFinger(SDL_Touch *touch, SDL_FingerID fingerid, float x, float
|
||||
{
|
||||
SDL_Finger *finger;
|
||||
|
||||
SDL_assert(fingerid != 0);
|
||||
|
||||
if (touch->num_fingers == touch->max_fingers) {
|
||||
SDL_Finger **new_fingers;
|
||||
new_fingers = (SDL_Finger **)SDL_realloc(touch->fingers, (touch->max_fingers + 1) * sizeof(*touch->fingers));
|
||||
@@ -251,7 +255,7 @@ int SDL_SendTouch(Uint64 timestamp, SDL_TouchID id, SDL_FingerID fingerid, SDL_W
|
||||
/* SDL_HINT_TOUCH_MOUSE_EVENTS: controlling whether touch events should generate synthetic mouse events */
|
||||
/* SDL_HINT_VITA_TOUCH_MOUSE_DEVICE: controlling which touchpad should generate synthetic mouse events, PSVita-only */
|
||||
{
|
||||
#ifdef __vita__
|
||||
#ifdef SDL_PLATFORM_VITA
|
||||
if (mouse->touch_mouse_events && ((mouse->vita_touch_mouse_device == id) || (mouse->vita_touch_mouse_device == 2))) {
|
||||
#else
|
||||
if (mouse->touch_mouse_events) {
|
||||
@@ -275,7 +279,7 @@ int SDL_SendTouch(Uint64 timestamp, SDL_TouchID id, SDL_FingerID fingerid, SDL_W
|
||||
if (pos_y > (float)(window->h - 1)) {
|
||||
pos_y = (float)(window->h - 1);
|
||||
}
|
||||
SDL_SendMouseMotion(timestamp, window, SDL_TOUCH_MOUSEID, 0, pos_x, pos_y);
|
||||
SDL_SendMouseMotion(timestamp, window, SDL_TOUCH_MOUSEID, SDL_FALSE, pos_x, pos_y);
|
||||
SDL_SendMouseButton(timestamp, window, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT);
|
||||
}
|
||||
} else {
|
||||
@@ -324,8 +328,8 @@ int SDL_SendTouch(Uint64 timestamp, SDL_TouchID id, SDL_FingerID fingerid, SDL_W
|
||||
SDL_Event event;
|
||||
event.type = SDL_EVENT_FINGER_DOWN;
|
||||
event.common.timestamp = timestamp;
|
||||
event.tfinger.touchId = id;
|
||||
event.tfinger.fingerId = fingerid;
|
||||
event.tfinger.touchID = id;
|
||||
event.tfinger.fingerID = fingerid;
|
||||
event.tfinger.x = x;
|
||||
event.tfinger.y = y;
|
||||
event.tfinger.dx = 0;
|
||||
@@ -345,8 +349,8 @@ int SDL_SendTouch(Uint64 timestamp, SDL_TouchID id, SDL_FingerID fingerid, SDL_W
|
||||
SDL_Event event;
|
||||
event.type = SDL_EVENT_FINGER_UP;
|
||||
event.common.timestamp = timestamp;
|
||||
event.tfinger.touchId = id;
|
||||
event.tfinger.fingerId = fingerid;
|
||||
event.tfinger.touchID = id;
|
||||
event.tfinger.fingerID = fingerid;
|
||||
/* I don't trust the coordinates passed on fingerUp */
|
||||
event.tfinger.x = finger->x;
|
||||
event.tfinger.y = finger->y;
|
||||
@@ -399,7 +403,7 @@ int SDL_SendTouchMotion(Uint64 timestamp, SDL_TouchID id, SDL_FingerID fingerid,
|
||||
if (pos_y > (float)(window->h - 1)) {
|
||||
pos_y = (float)(window->h - 1);
|
||||
}
|
||||
SDL_SendMouseMotion(timestamp, window, SDL_TOUCH_MOUSEID, 0, pos_x, pos_y);
|
||||
SDL_SendMouseMotion(timestamp, window, SDL_TOUCH_MOUSEID, SDL_FALSE, pos_x, pos_y);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -442,8 +446,8 @@ int SDL_SendTouchMotion(Uint64 timestamp, SDL_TouchID id, SDL_FingerID fingerid,
|
||||
SDL_Event event;
|
||||
event.type = SDL_EVENT_FINGER_MOTION;
|
||||
event.common.timestamp = timestamp;
|
||||
event.tfinger.touchId = id;
|
||||
event.tfinger.fingerId = fingerid;
|
||||
event.tfinger.touchID = id;
|
||||
event.tfinger.fingerID = fingerid;
|
||||
event.tfinger.x = x;
|
||||
event.tfinger.y = y;
|
||||
event.tfinger.dx = xrel;
|
||||
|
||||
1289
external/sdl/SDL/src/file/SDL_iostream.c
vendored
Normal file
1289
external/sdl/SDL/src/file/SDL_iostream.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1052
external/sdl/SDL/src/file/SDL_rwops.c
vendored
1052
external/sdl/SDL/src/file/SDL_rwops.c
vendored
File diff suppressed because it is too large
Load Diff
@@ -19,12 +19,12 @@
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifdef __APPLE__
|
||||
#ifdef SDL_PLATFORM_APPLE
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef SDL_rwopsbundlesupport_h
|
||||
#define SDL_rwopsbundlesupport_h
|
||||
#ifndef SDL_iostreambundlesupport_h
|
||||
#define SDL_iostreambundlesupport_h
|
||||
FILE *SDL_OpenFPFromBundleOrFallback(const char *file, const char *mode);
|
||||
#endif
|
||||
#endif
|
||||
@@ -20,10 +20,10 @@
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#ifdef SDL_PLATFORM_APPLE
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#include "SDL_rwopsbundlesupport.h"
|
||||
#include "SDL_iostreambundlesupport.h"
|
||||
|
||||
/* For proper macOS applications, the resources are contained inside the application bundle.
|
||||
So the strategy is to first check the application bundle for the file, then fallback to the current working directory.
|
||||
@@ -62,4 +62,4 @@ FILE *SDL_OpenFPFromBundleOrFallback(const char *file, const char *mode)
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* __APPLE__ */
|
||||
#endif /* SDL_PLATFORM_APPLE */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user