LIBS: updated sdl2
parent
1cf6d667c8
commit
e00739e233
|
@ -297,7 +297,7 @@ if(CYGWIN)
|
|||
# We build SDL on cygwin without the UNIX emulation layer
|
||||
target_include_directories(sdl-build-options INTERFACE "/usr/include/mingw")
|
||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -mno-cygwin")
|
||||
check_c_source_compiles("int main(int argc, char **argv) {}"
|
||||
check_c_source_compiles("int main(int argc, char **argv) { return 0; }"
|
||||
HAVE_GCC_NO_CYGWIN)
|
||||
set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
|
||||
if(HAVE_GCC_NO_CYGWIN)
|
||||
|
@ -462,8 +462,8 @@ dep_option(SDL_STATIC_PIC "Static version of the library should be built wi
|
|||
set_option(SDL_TEST "Build the test directory" OFF)
|
||||
|
||||
if(VITA)
|
||||
set_option(VIDEO_VITA_PIB "Build with PSVita piglet gles2 support" OFF)
|
||||
set_option(VIDEO_VITA_PVR "Build with PSVita PVR gles/gles2 support" OFF)
|
||||
set_option(VIDEO_VITA_PIB "Build with PSVita piglet gles2 support" OFF)
|
||||
set_option(VIDEO_VITA_PVR "Build with PSVita PVR gles/gles2 support" OFF)
|
||||
endif()
|
||||
|
||||
# General source files
|
||||
|
@ -475,6 +475,7 @@ file(GLOB SOURCE_FILES
|
|||
${SDL2_SOURCE_DIR}/src/dynapi/*.c
|
||||
${SDL2_SOURCE_DIR}/src/events/*.c
|
||||
${SDL2_SOURCE_DIR}/src/file/*.c
|
||||
${SDL2_SOURCE_DIR}/src/joystick/*.c
|
||||
${SDL2_SOURCE_DIR}/src/haptic/*.c
|
||||
${SDL2_SOURCE_DIR}/src/hidapi/*.c
|
||||
${SDL2_SOURCE_DIR}/src/libm/*.c
|
||||
|
@ -548,7 +549,7 @@ if(USE_GCC OR USE_CLANG)
|
|||
#if !defined(__GNUC__) || __GNUC__ < 3
|
||||
#error Dependency tracking requires GCC 3.0 or newer
|
||||
#endif
|
||||
int main(int argc, char **argv) { }" HAVE_DEPENDENCY_TRACKING)
|
||||
int main(int argc, char **argv) { return 0; }" HAVE_DEPENDENCY_TRACKING)
|
||||
endif()
|
||||
|
||||
if(SDL_GCC_ATOMICS)
|
||||
|
@ -559,17 +560,19 @@ if(USE_GCC OR USE_CLANG)
|
|||
__sync_lock_test_and_set(&x, y);
|
||||
__sync_fetch_and_add(&a, 1);
|
||||
__sync_bool_compare_and_swap(&a, 5, 10);
|
||||
__sync_bool_compare_and_swap(&x, y, z); }" HAVE_GCC_ATOMICS)
|
||||
__sync_bool_compare_and_swap(&x, y, z);
|
||||
return 0; }" HAVE_GCC_ATOMICS)
|
||||
if(NOT HAVE_GCC_ATOMICS)
|
||||
check_c_source_compiles("int main(int argc, char **argv) {
|
||||
int a;
|
||||
__sync_lock_test_and_set(&a, 1);
|
||||
__sync_lock_release(&a); }" HAVE_GCC_SYNC_LOCK_TEST_AND_SET)
|
||||
__sync_lock_release(&a);
|
||||
return 0; }" HAVE_GCC_SYNC_LOCK_TEST_AND_SET)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(CMAKE_REQUIRED_FLAGS "-mpreferred-stack-boundary=2")
|
||||
check_c_source_compiles("int x = 0; int main(int argc, char **argv) {}"
|
||||
check_c_source_compiles("int x = 0; int main(int argc, char **argv) { return 0; }"
|
||||
HAVE_GCC_PREFERRED_STACK_BOUNDARY)
|
||||
set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
|
||||
|
||||
|
@ -578,7 +581,7 @@ if(USE_GCC OR USE_CLANG)
|
|||
#if !defined(__GNUC__) || __GNUC__ < 4
|
||||
#error SDL only uses visibility attributes in GCC 4 or newer
|
||||
#endif
|
||||
int main(int argc, char **argv) {}" HAVE_GCC_FVISIBILITY)
|
||||
int main(int argc, char **argv) { return 0; }" HAVE_GCC_FVISIBILITY)
|
||||
if(HAVE_GCC_FVISIBILITY)
|
||||
list(APPEND EXTRA_CFLAGS "-fvisibility=hidden")
|
||||
endif()
|
||||
|
@ -634,7 +637,7 @@ if(SDL_ASSEMBLY)
|
|||
#ifndef __MMX__
|
||||
#error Assembler CPP flag not enabled
|
||||
#endif
|
||||
int main(int argc, char **argv) { }" HAVE_MMX)
|
||||
int main(int argc, char **argv) { return 0; }" HAVE_MMX)
|
||||
if(HAVE_MMX)
|
||||
list(APPEND EXTRA_CFLAGS "-mmmx")
|
||||
endif()
|
||||
|
@ -651,6 +654,7 @@ if(SDL_ASSEMBLY)
|
|||
int main(int argc, char **argv) {
|
||||
void *p = 0;
|
||||
_m_prefetch(p);
|
||||
return 0;
|
||||
}" HAVE_3DNOW)
|
||||
if(HAVE_3DNOW)
|
||||
list(APPEND EXTRA_CFLAGS "-m3dnow")
|
||||
|
@ -674,7 +678,7 @@ if(SDL_ASSEMBLY)
|
|||
#ifndef __SSE__
|
||||
#error Assembler CPP flag not enabled
|
||||
#endif
|
||||
int main(int argc, char **argv) { }" HAVE_SSE)
|
||||
int main(int argc, char **argv) { return 0; }" HAVE_SSE)
|
||||
if(HAVE_SSE)
|
||||
list(APPEND EXTRA_CFLAGS "-msse")
|
||||
endif()
|
||||
|
@ -697,7 +701,7 @@ if(SDL_ASSEMBLY)
|
|||
#ifndef __SSE2__
|
||||
#error Assembler CPP flag not enabled
|
||||
#endif
|
||||
int main(int argc, char **argv) { }" HAVE_SSE2)
|
||||
int main(int argc, char **argv) { return 0; }" HAVE_SSE2)
|
||||
if(HAVE_SSE2)
|
||||
list(APPEND EXTRA_CFLAGS "-msse2")
|
||||
endif()
|
||||
|
@ -720,7 +724,7 @@ if(SDL_ASSEMBLY)
|
|||
#ifndef __SSE3__
|
||||
#error Assembler CPP flag not enabled
|
||||
#endif
|
||||
int main(int argc, char **argv) { }" HAVE_SSE3)
|
||||
int main(int argc, char **argv) { return 0; }" HAVE_SSE3)
|
||||
if(HAVE_SSE3)
|
||||
list(APPEND EXTRA_CFLAGS "-msse3")
|
||||
endif()
|
||||
|
@ -749,12 +753,12 @@ if(SDL_ASSEMBLY)
|
|||
vector unsigned int vzero() {
|
||||
return vec_splat_u32(0);
|
||||
}
|
||||
int main(int argc, char **argv) { }" HAVE_ALTIVEC_H_HDR)
|
||||
int main(int argc, char **argv) { return 0; }" HAVE_ALTIVEC_H_HDR)
|
||||
check_c_source_compiles("
|
||||
vector unsigned int vzero() {
|
||||
return vec_splat_u32(0);
|
||||
}
|
||||
int main(int argc, char **argv) { }" HAVE_ALTIVEC)
|
||||
int main(int argc, char **argv) { return 0; }" HAVE_ALTIVEC)
|
||||
set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
|
||||
if(HAVE_ALTIVEC OR HAVE_ALTIVEC_H_HDR)
|
||||
set(HAVE_ALTIVEC TRUE) # if only HAVE_ALTIVEC_H_HDR is set
|
||||
|
@ -881,7 +885,7 @@ if(SDL_LIBC)
|
|||
# TODO: refine the mprotect check
|
||||
check_c_source_compiles("#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
int main() { }" HAVE_MPROTECT)
|
||||
int main(void) { return 0; }" HAVE_MPROTECT)
|
||||
foreach(_FN
|
||||
strtod malloc calloc realloc free getenv setenv putenv unsetenv
|
||||
qsort abs bcopy memset memcpy memmove memcmp strlen strlcpy strlcat
|
||||
|
@ -965,10 +969,6 @@ foreach(_SUB ${SDL_SUBSYSTEMS})
|
|||
set(SDL_${_OPT}_DISABLED 1)
|
||||
endif()
|
||||
endforeach()
|
||||
if(SDL_JOYSTICK)
|
||||
file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/*.c)
|
||||
set(SOURCE_FILES ${SOURCE_FILES} ${JOYSTICK_SOURCES})
|
||||
endif()
|
||||
if(SDL_HAPTIC)
|
||||
if(NOT SDL_JOYSTICK)
|
||||
# Haptic requires some private functions from the joystick subsystem.
|
||||
|
@ -1163,9 +1163,7 @@ if(ANDROID)
|
|||
#if defined(__ARM_ARCH) && __ARM_ARCH < 7
|
||||
#error Vulkan doesn't work on this configuration
|
||||
#endif
|
||||
int main(void) {
|
||||
return 0;
|
||||
}
|
||||
int main(int argc, char **argv) { return 0; }
|
||||
" VULKAN_PASSED_ANDROID_CHECKS)
|
||||
if(VULKAN_PASSED_ANDROID_CHECKS)
|
||||
set(SDL_VIDEO_VULKAN 1)
|
||||
|
@ -1181,10 +1179,11 @@ elseif(EMSCRIPTEN)
|
|||
# project. Uncomment at will for verbose cross-compiling -I/../ path info.
|
||||
target_compile_options(sdl-build-options INTERFACE "-Wno-warn-absolute-paths")
|
||||
|
||||
file(GLOB EMSRIPTEN_MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/emscripten/*.c)
|
||||
set(SOURCE_FILES ${SOURCE_FILES} ${EMSRIPTEN_MISC_SOURCES})
|
||||
set(HAVE_SDL_MISC TRUE)
|
||||
|
||||
if(SDL_MISC)
|
||||
file(GLOB EMSRIPTEN_MISC_SOURCES ${SDL2_SOURCE_DIR}/src/misc/emscripten/*.c)
|
||||
set(SOURCE_FILES ${SOURCE_FILES} ${EMSRIPTEN_MISC_SOURCES})
|
||||
set(HAVE_SDL_MISC TRUE)
|
||||
endif()
|
||||
if(SDL_AUDIO)
|
||||
set(SDL_AUDIO_DRIVER_EMSCRIPTEN 1)
|
||||
file(GLOB EM_AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/emscripten/*.c)
|
||||
|
@ -1301,28 +1300,26 @@ elseif(UNIX AND NOT APPLE AND NOT ANDROID AND NOT RISCOS AND NOT HAIKU)
|
|||
#ifndef EVIOCGNAME
|
||||
#error EVIOCGNAME() ioctl not available
|
||||
#endif
|
||||
int main(int argc, char** argv) {}" HAVE_INPUT_EVENTS)
|
||||
int main(int argc, char** argv) { return 0; }" HAVE_INPUT_EVENTS)
|
||||
|
||||
if(LINUX)
|
||||
check_c_source_compiles("
|
||||
#include <linux/kd.h>
|
||||
#include <linux/keyboard.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int main(int argc, char **argv) {
|
||||
struct kbentry kbe;
|
||||
kbe.kb_table = KG_CTRL;
|
||||
ioctl(0, KDGKBENT, &kbe);
|
||||
return 0;
|
||||
}" HAVE_INPUT_KD)
|
||||
elseif(FREEBSD)
|
||||
check_c_source_compiles("
|
||||
#include <sys/kbio.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int main(int argc, char **argv) {
|
||||
accentmap_t accTable;
|
||||
ioctl(0, KDENABIO, 1);
|
||||
return 0;
|
||||
}" HAVE_INPUT_KBIO)
|
||||
endif()
|
||||
|
||||
|
@ -1522,7 +1519,7 @@ elseif(WINDOWS)
|
|||
|
||||
check_c_source_compiles("
|
||||
#include <windows.h>
|
||||
int main(int argc, char **argv) { }" HAVE_WIN32_CC)
|
||||
int main(int argc, char **argv) { return 0; }" HAVE_WIN32_CC)
|
||||
|
||||
file(GLOB CORE_SOURCES ${SDL2_SOURCE_DIR}/src/core/windows/*.c)
|
||||
set(SOURCE_FILES ${SOURCE_FILES} ${CORE_SOURCES})
|
||||
|
@ -1587,22 +1584,22 @@ elseif(WINDOWS)
|
|||
check_c_source_compiles("
|
||||
#include <windows.h>
|
||||
#include <xinput.h>
|
||||
int main(int argc, char **argv) { }" HAVE_XINPUT_H)
|
||||
int main(int argc, char **argv) { return 0; }" HAVE_XINPUT_H)
|
||||
check_c_source_compiles("
|
||||
#include <windows.h>
|
||||
#include <xinput.h>
|
||||
XINPUT_GAMEPAD_EX x1;
|
||||
int main(int argc, char **argv) { }" HAVE_XINPUT_GAMEPAD_EX)
|
||||
int main(int argc, char **argv) { return 0; }" HAVE_XINPUT_GAMEPAD_EX)
|
||||
check_c_source_compiles("
|
||||
#include <windows.h>
|
||||
#include <xinput.h>
|
||||
XINPUT_STATE_EX s1;
|
||||
int main(int argc, char **argv) { }" HAVE_XINPUT_STATE_EX)
|
||||
int main(int argc, char **argv) { return 0; }" HAVE_XINPUT_STATE_EX)
|
||||
check_c_source_compiles("
|
||||
#define COBJMACROS
|
||||
#include <windows.gaming.input.h>
|
||||
__x_ABI_CWindows_CGaming_CInput_CIGamepadStatics2 *s2;
|
||||
int main(int argc, char **argv) { }" HAVE_WINDOWS_GAMING_INPUT_H)
|
||||
int main(int argc, char **argv) { return 0; }" HAVE_WINDOWS_GAMING_INPUT_H)
|
||||
endif()
|
||||
|
||||
# headers needed elsewhere
|
||||
|
@ -1845,8 +1842,6 @@ elseif(APPLE)
|
|||
if(SDL_FILE)
|
||||
file(GLOB EXTRA_SOURCES ${SDL2_SOURCE_DIR}/src/file/cocoa/*.m)
|
||||
set(SOURCE_FILES ${EXTRA_SOURCES} ${SOURCE_FILES})
|
||||
# !!! FIXME: modern CMake doesn't need "LANGUAGE C" for Objective-C.
|
||||
set_source_files_properties(${EXTRA_SOURCES} PROPERTIES LANGUAGE C)
|
||||
set(HAVE_SDL_FILE TRUE)
|
||||
endif()
|
||||
|
||||
|
@ -1867,8 +1862,6 @@ elseif(APPLE)
|
|||
if(SDL_AUDIO)
|
||||
set(SDL_AUDIO_DRIVER_COREAUDIO 1)
|
||||
file(GLOB AUDIO_SOURCES ${SDL2_SOURCE_DIR}/src/audio/coreaudio/*.m)
|
||||
# !!! FIXME: modern CMake doesn't need "LANGUAGE C" for Objective-C.
|
||||
set_source_files_properties(${AUDIO_SOURCES} PROPERTIES LANGUAGE C)
|
||||
set(SOURCE_FILES ${SOURCE_FILES} ${AUDIO_SOURCES})
|
||||
set(HAVE_SDL_AUDIO TRUE)
|
||||
set(SDL_FRAMEWORK_COREAUDIO 1)
|
||||
|
@ -1904,13 +1897,13 @@ elseif(APPLE)
|
|||
#if TARGET_CPU_X86
|
||||
#error GameController framework doesn't work on this configuration
|
||||
#endif
|
||||
int main() {}" HAVE_FRAMEWORK_GAMECONTROLLER)
|
||||
int main() { return 0; }" HAVE_FRAMEWORK_GAMECONTROLLER)
|
||||
check_objc_source_compiles("
|
||||
#include <AvailabilityMacros.h>
|
||||
#include <TargetConditionals.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <CoreHaptics/CoreHaptics.h>
|
||||
int main() {}" HAVE_FRAMEWORK_COREHAPTICS)
|
||||
int main() { return 0; }" HAVE_FRAMEWORK_COREHAPTICS)
|
||||
if(HAVE_FRAMEWORK_GAMECONTROLLER AND HAVE_FRAMEWORK_COREHAPTICS)
|
||||
# Only enable MFI if we also have CoreHaptics to ensure rumble works
|
||||
set(SDL_JOYSTICK_MFI 1)
|
||||
|
@ -1968,8 +1961,6 @@ elseif(APPLE)
|
|||
if(SDL_FILESYSTEM)
|
||||
set(SDL_FILESYSTEM_COCOA 1)
|
||||
file(GLOB FILESYSTEM_SOURCES ${SDL2_SOURCE_DIR}/src/filesystem/cocoa/*.m)
|
||||
# !!! FIXME: modern CMake doesn't need "LANGUAGE C" for Objective-C.
|
||||
set_source_files_properties(${FILESYSTEM_SOURCES} PROPERTIES LANGUAGE C)
|
||||
set(SOURCE_FILES ${SOURCE_FILES} ${FILESYSTEM_SOURCES})
|
||||
set(HAVE_SDL_FILESYSTEM TRUE)
|
||||
endif()
|
||||
|
@ -2027,7 +2018,7 @@ elseif(APPLE)
|
|||
#if (!TARGET_CPU_X86_64 && !TARGET_CPU_ARM64)
|
||||
#error Metal doesn't work on this configuration
|
||||
#endif
|
||||
int main(void) {}" HAVE_FRAMEWORK_METAL)
|
||||
int main(int argc, char **argv) { return 0; }" HAVE_FRAMEWORK_METAL)
|
||||
if(HAVE_FRAMEWORK_METAL)
|
||||
set(SDL_FRAMEWORK_METAL 1)
|
||||
set(SDL_FRAMEWORK_QUARTZCORE 1)
|
||||
|
@ -2562,10 +2553,8 @@ if(NOT HAVE_SDL_VIDEO)
|
|||
endif()
|
||||
if(NOT HAVE_SDL_JOYSTICK)
|
||||
set(SDL_JOYSTICK_DUMMY 1)
|
||||
if(SDL_JOYSTICK AND NOT APPLE) # results in unresolved symbols on OSX
|
||||
file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/dummy/*.c)
|
||||
set(SOURCE_FILES ${SOURCE_FILES} ${JOYSTICK_SOURCES})
|
||||
endif()
|
||||
file(GLOB JOYSTICK_SOURCES ${SDL2_SOURCE_DIR}/src/joystick/dummy/*.c)
|
||||
set(SOURCE_FILES ${SOURCE_FILES} ${JOYSTICK_SOURCES})
|
||||
endif()
|
||||
if(NOT HAVE_SDL_HAPTIC)
|
||||
set(SDL_HAPTIC_DUMMY 1)
|
||||
|
|
|
@ -530,8 +530,7 @@ macro(CheckX11)
|
|||
#include <X11/extensions/XInput2.h>
|
||||
int event_type = XI_TouchBegin;
|
||||
XITouchClassInfo *t;
|
||||
Status XIAllowTouchEvents(Display *a,int b,unsigned int c,Window d,int f)
|
||||
{
|
||||
Status XIAllowTouchEvents(Display *a,int b,unsigned int c,Window d,int f) {
|
||||
return (Status)0;
|
||||
}
|
||||
int main(int argc, char **argv) { return 0; }" HAVE_XINPUT2_MULTITOUCH)
|
||||
|
@ -633,7 +632,7 @@ endmacro()
|
|||
# - HAVE_SDL_LOADSO opt
|
||||
macro(CheckWayland)
|
||||
if(SDL_WAYLAND)
|
||||
pkg_check_modules(WAYLAND wayland-client wayland-egl wayland-cursor egl "xkbcommon>=0.5.0")
|
||||
pkg_check_modules(WAYLAND "wayland-client>=1.18" wayland-egl wayland-cursor egl "xkbcommon>=0.5.0")
|
||||
|
||||
if(WAYLAND_FOUND)
|
||||
find_program(WAYLAND_SCANNER NAMES wayland-scanner REQUIRED)
|
||||
|
@ -793,7 +792,9 @@ macro(CheckVivante)
|
|||
set(SDL_VIDEO_DRIVER_VIVANTE 1)
|
||||
if(HAVE_VIVANTE_VDK)
|
||||
set(SDL_VIDEO_DRIVER_VIVANTE_VDK 1)
|
||||
list(APPEND EXTRA_LIBS VDK VIVANTE)
|
||||
find_library(VIVANTE_LIBRARY REQUIRED NAMES VIVANTE vivante drm_vivante)
|
||||
find_library(VIVANTE_VDK_LIBRARY VDK REQUIRED)
|
||||
list(APPEND EXTRA_LIBS ${VIVANTE_LIBRARY} ${VIVANTE_VDK_LIBRARY})
|
||||
else()
|
||||
set(SDL_CFLAGS "${SDL_CFLAGS} -DLINUX -DEGL_API_FB")
|
||||
list(APPEND EXTRA_LIBS EGL)
|
||||
|
|
|
@ -65,6 +65,15 @@ _m_prefetch(void *__P)
|
|||
#elif defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
#include <sys/endian.h>
|
||||
#define SDL_BYTEORDER BYTE_ORDER
|
||||
/* predefs from newer gcc and clang versions: */
|
||||
#elif defined(__ORDER_LITTLE_ENDIAN__) && defined(__ORDER_BIG_ENDIAN__) && defined(__BYTE_ORDER__)
|
||||
#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
|
||||
#define SDL_BYTEORDER SDL_LIL_ENDIAN
|
||||
#elif (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
|
||||
#define SDL_BYTEORDER SDL_BIG_ENDIAN
|
||||
#else
|
||||
#error Unsupported endianness
|
||||
#endif /**/
|
||||
#else
|
||||
#if defined(__hppa__) || \
|
||||
defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \
|
||||
|
|
|
@ -933,6 +933,22 @@ extern "C" {
|
|||
*/
|
||||
#define SDL_HINT_MOUSE_NORMAL_SPEED_SCALE "SDL_MOUSE_NORMAL_SPEED_SCALE"
|
||||
|
||||
/**
|
||||
* \brief A variable controlling whether relative mouse mode constrains the mouse to the center of the window
|
||||
*
|
||||
* This variable can be set to the following values:
|
||||
* "0" - Relative mouse mode constrains the mouse to the window
|
||||
* "1" - Relative mouse mode constrains the mouse to the center of the window
|
||||
*
|
||||
* Constraining to the center of the window works better for FPS games and when the
|
||||
* application is running over RDP. Constraining to the whole window works better
|
||||
* for 2D games and increases the chance that the mouse will be in the correct
|
||||
* position when using high DPI mice.
|
||||
*
|
||||
* By default SDL will constrain the mouse to the center of the window
|
||||
*/
|
||||
#define SDL_HINT_MOUSE_RELATIVE_MODE_CENTER "SDL_MOUSE_RELATIVE_MODE_CENTER"
|
||||
|
||||
/**
|
||||
* \brief A variable controlling whether relative mouse mode is implemented using mouse warping
|
||||
*
|
||||
|
@ -969,6 +985,19 @@ extern "C" {
|
|||
*/
|
||||
#define SDL_HINT_MOUSE_TOUCH_EVENTS "SDL_MOUSE_TOUCH_EVENTS"
|
||||
|
||||
/**
|
||||
* \brief A variable controlling whether the mouse is captured while mouse buttons are pressed
|
||||
*
|
||||
* This variable can be set to the following values:
|
||||
* "0" - The mouse is not captured while mouse buttons are pressed
|
||||
* "1" - The mouse is captured while mouse buttons are pressed
|
||||
*
|
||||
* By default the mouse is captured while mouse buttons are pressed so if the mouse is dragged
|
||||
* outside the window, the application continues to receive mouse events until the button is
|
||||
* released.
|
||||
*/
|
||||
#define SDL_HINT_MOUSE_AUTO_CAPTURE "SDL_MOUSE_AUTO_CAPTURE"
|
||||
|
||||
/**
|
||||
* \brief Tell SDL not to catch the SIGINT or SIGTERM signals.
|
||||
*
|
||||
|
@ -1453,6 +1482,28 @@ extern "C" {
|
|||
*/
|
||||
#define SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT "SDL_VIDEO_WINDOW_SHARE_PIXEL_FORMAT"
|
||||
|
||||
/**
|
||||
* \brief When calling SDL_CreateWindowFrom(), make the window compatible with OpenGL.
|
||||
*
|
||||
* This variable can be set to the following values:
|
||||
* "0" - Don't add any graphics flags to the SDL_WindowFlags
|
||||
* "1" - Add SDL_WINDOW_OPENGL to the SDL_WindowFlags
|
||||
*
|
||||
* By default SDL will not make the foreign window compatible with OpenGL.
|
||||
*/
|
||||
#define SDL_HINT_VIDEO_FOREIGN_WINDOW_OPENGL "SDL_VIDEO_FOREIGN_WINDOW_OPENGL"
|
||||
|
||||
/**
|
||||
* \brief When calling SDL_CreateWindowFrom(), make the window compatible with Vulkan.
|
||||
*
|
||||
* This variable can be set to the following values:
|
||||
* "0" - Don't add any graphics flags to the SDL_WindowFlags
|
||||
* "1" - Add SDL_WINDOW_VULKAN to the SDL_WindowFlags
|
||||
*
|
||||
* By default SDL will not make the foreign window compatible with Vulkan.
|
||||
*/
|
||||
#define SDL_HINT_VIDEO_FOREIGN_WINDOW_VULKAN "SDL_VIDEO_FOREIGN_WINDOW_VULKAN"
|
||||
|
||||
/**
|
||||
* \brief A variable specifying which shader compiler to preload when using the Chrome ANGLE binaries
|
||||
*
|
||||
|
@ -1892,6 +1943,30 @@ extern "C" {
|
|||
*/
|
||||
#define SDL_HINT_X11_WINDOW_TYPE "SDL_X11_WINDOW_TYPE"
|
||||
|
||||
/**
|
||||
* \brief A variable that decides whether to send SDL_QUIT when closing the final window.
|
||||
*
|
||||
* By default, SDL sends an SDL_QUIT event when there is only one window
|
||||
* and it receives an SDL_WINDOWEVENT_CLOSE event, under the assumption most
|
||||
* apps would also take the loss of this window as a signal to terminate the
|
||||
* program.
|
||||
*
|
||||
* However, it's not unreasonable in some cases to have the program continue
|
||||
* to live on, perhaps to create new windows later.
|
||||
*
|
||||
* Changing this hint to "0" will cause SDL to not send an SDL_QUIT event
|
||||
* when the final window is requesting to close. Note that in this case,
|
||||
* there are still other legitimate reasons one might get an SDL_QUIT
|
||||
* event: choosing "Quit" from the macOS menu bar, sending a SIGINT (ctrl-c)
|
||||
* on Unix, etc.
|
||||
*
|
||||
* The default value is "1". This hint can be changed at any time.
|
||||
*
|
||||
* This hint is available since SDL 2.0.22. Before then, you always get
|
||||
* an SDL_QUIT event when closing the final window.
|
||||
*/
|
||||
#define SDL_HINT_QUIT_ON_LAST_WINDOW_CLOSE "SDL_QUIT_ON_LAST_WINDOW_CLOSE"
|
||||
|
||||
|
||||
/**
|
||||
* \brief An enumeration of hint priorities
|
||||
|
|
|
@ -54,8 +54,13 @@ typedef struct SDL_Point
|
|||
/**
|
||||
* The structure that defines a point (floating point)
|
||||
*
|
||||
* \sa SDL_EnclosePoints
|
||||
* \sa SDL_PointInRect
|
||||
* \sa SDL_FRectEmpty
|
||||
* \sa SDL_FRectEquals
|
||||
* \sa SDL_HasIntersectionF
|
||||
* \sa SDL_IntersectFRect
|
||||
* \sa SDL_UnionFRect
|
||||
* \sa SDL_EncloseFPoints
|
||||
* \sa SDL_PointInFRect
|
||||
*/
|
||||
typedef struct SDL_FPoint
|
||||
{
|
||||
|
@ -213,6 +218,131 @@ extern DECLSPEC SDL_bool SDLCALL SDL_IntersectRectAndLine(const SDL_Rect *
|
|||
int *Y1, int *X2,
|
||||
int *Y2);
|
||||
|
||||
|
||||
/* SDL_FRect versions... */
|
||||
|
||||
/**
|
||||
* Returns true if point resides inside a rectangle.
|
||||
*/
|
||||
SDL_FORCE_INLINE SDL_bool SDL_PointInFRect(const SDL_FPoint *p, const SDL_FRect *r)
|
||||
{
|
||||
return ( (p->x >= r->x) && (p->x < (r->x + r->w)) &&
|
||||
(p->y >= r->y) && (p->y < (r->y + r->h)) ) ? SDL_TRUE : SDL_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the rectangle has no area.
|
||||
*/
|
||||
SDL_FORCE_INLINE SDL_bool SDL_FRectEmpty(const SDL_FRect *r)
|
||||
{
|
||||
return ((!r) || (r->w <= 0.0f) || (r->h <= 0.0f)) ? SDL_TRUE : SDL_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the two rectangles are equal.
|
||||
*/
|
||||
SDL_FORCE_INLINE SDL_bool SDL_FRectEquals(const SDL_FRect *a, const SDL_FRect *b)
|
||||
{
|
||||
return (a && b && (a->x == b->x) && (a->y == b->y) &&
|
||||
(a->w == b->w) && (a->h == b->h)) ? SDL_TRUE : SDL_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether two rectangles intersect with float precision.
|
||||
*
|
||||
* If either pointer is NULL the function will return SDL_FALSE.
|
||||
*
|
||||
* \param A an SDL_FRect structure representing the first rectangle
|
||||
* \param B an SDL_FRect structure representing the second rectangle
|
||||
* \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.22.
|
||||
*
|
||||
* \sa SDL_IntersectRect
|
||||
*/
|
||||
extern DECLSPEC SDL_bool SDLCALL SDL_HasIntersectionF(const SDL_FRect * A,
|
||||
const SDL_FRect * B);
|
||||
|
||||
/**
|
||||
* Calculate the intersection of two rectangles with float precision.
|
||||
*
|
||||
* If `result` is NULL then this function will return SDL_FALSE.
|
||||
*
|
||||
* \param A an SDL_FRect structure representing the first rectangle
|
||||
* \param B an SDL_FRect structure representing the second rectangle
|
||||
* \param result an SDL_FRect structure filled in with the intersection of
|
||||
* rectangles `A` and `B`
|
||||
* \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.22.
|
||||
*
|
||||
* \sa SDL_HasIntersectionF
|
||||
*/
|
||||
extern DECLSPEC SDL_bool SDLCALL SDL_IntersectFRect(const SDL_FRect * A,
|
||||
const SDL_FRect * B,
|
||||
SDL_FRect * result);
|
||||
|
||||
/**
|
||||
* Calculate the union of two rectangles with float precision.
|
||||
*
|
||||
* \param A an SDL_FRect structure representing the first rectangle
|
||||
* \param B an SDL_FRect structure representing the second rectangle
|
||||
* \param result an SDL_FRect structure filled in with the union of rectangles
|
||||
* `A` and `B`
|
||||
*
|
||||
* \since This function is available since SDL 2.0.22.
|
||||
*/
|
||||
extern DECLSPEC void SDLCALL SDL_UnionFRect(const SDL_FRect * A,
|
||||
const SDL_FRect * B,
|
||||
SDL_FRect * result);
|
||||
|
||||
/**
|
||||
* Calculate a minimal rectangle enclosing a set of points with float
|
||||
* precision.
|
||||
*
|
||||
* If `clip` is not NULL then only points inside of the clipping rectangle are
|
||||
* considered.
|
||||
*
|
||||
* \param points an array of SDL_FPoint structures representing points to be
|
||||
* enclosed
|
||||
* \param count the number of structures in the `points` array
|
||||
* \param clip an SDL_FRect used for clipping or NULL to enclose all points
|
||||
* \param result an SDL_FRect structure filled in with the minimal enclosing
|
||||
* rectangle
|
||||
* \returns SDL_TRUE if any points were enclosed or SDL_FALSE if all the
|
||||
* points were outside of the clipping rectangle.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.22.
|
||||
*/
|
||||
extern DECLSPEC SDL_bool SDLCALL SDL_EncloseFPoints(const SDL_FPoint * points,
|
||||
int count,
|
||||
const SDL_FRect * clip,
|
||||
SDL_FRect * result);
|
||||
|
||||
/**
|
||||
* Calculate the intersection of a rectangle and line segment with float
|
||||
* precision.
|
||||
*
|
||||
* This function is used to clip a line segment to a rectangle. A line segment
|
||||
* contained entirely within the rectangle or that does not intersect will
|
||||
* remain unchanged. A line segment that crosses the rectangle at either or
|
||||
* both ends will be clipped to the boundary of the rectangle and the new
|
||||
* coordinates saved in `X1`, `Y1`, `X2`, and/or `Y2` as necessary.
|
||||
*
|
||||
* \param rect an SDL_FRect structure representing the rectangle to intersect
|
||||
* \param X1 a pointer to the starting X-coordinate of the line
|
||||
* \param Y1 a pointer to the starting Y-coordinate of the line
|
||||
* \param X2 a pointer to the ending X-coordinate of the line
|
||||
* \param Y2 a pointer to the ending Y-coordinate of the line
|
||||
* \returns SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.22.
|
||||
*/
|
||||
extern DECLSPEC SDL_bool SDLCALL SDL_IntersectFRectAndLine(const SDL_FRect *
|
||||
rect, float *X1,
|
||||
float *Y1, float *X2,
|
||||
float *Y2);
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -261,6 +261,17 @@ extern DECLSPEC SDL_Renderer * SDLCALL SDL_CreateSoftwareRenderer(SDL_Surface *
|
|||
*/
|
||||
extern DECLSPEC SDL_Renderer * SDLCALL SDL_GetRenderer(SDL_Window * window);
|
||||
|
||||
/**
|
||||
* Get the window associated with a renderer.
|
||||
*
|
||||
* \param renderer the renderer to query
|
||||
* \returns the window on success or NULL on failure; call SDL_GetError() for
|
||||
* more information.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.22.
|
||||
*/
|
||||
extern DECLSPEC SDL_Window * SDLCALL SDL_RenderGetWindow(SDL_Renderer *renderer);
|
||||
|
||||
/**
|
||||
* Get information about a rendering context.
|
||||
*
|
||||
|
@ -1662,7 +1673,8 @@ extern DECLSPEC int SDLCALL SDL_RenderGeometryRaw(SDL_Renderer *renderer,
|
|||
* Read pixels from the current rendering target to an array of pixels.
|
||||
*
|
||||
* **WARNING**: This is a very slow operation, and should not be used
|
||||
* frequently.
|
||||
* frequently. If you're using this on the main rendering target, it should be
|
||||
* called after rendering and before SDL_RenderPresent().
|
||||
*
|
||||
* `pitch` specifies the number of bytes between rows in the destination
|
||||
* `pixels` data. This allows you to write to a subrectangle or have padded
|
||||
|
|
|
@ -354,8 +354,14 @@ typedef uint64_t Uint64;
|
|||
#endif
|
||||
#endif /* SDL_DISABLE_ANALYZE_MACROS */
|
||||
|
||||
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
|
||||
#define SDL_COMPILE_TIME_ASSERT(name, x) _Static_assert(x, #x);
|
||||
#elif defined(__cplusplus) && (__cplusplus >= 201103L)
|
||||
#define SDL_COMPILE_TIME_ASSERT(name, x) static_assert(x, #x);
|
||||
#else /* universal, but may trigger -Wunused-local-typedefs */
|
||||
#define SDL_COMPILE_TIME_ASSERT(name, x) \
|
||||
typedef int SDL_compile_time_assert_ ## name[(x) * 2 - 1]
|
||||
#endif
|
||||
/** \cond */
|
||||
#ifndef DOXYGEN_SHOULD_IGNORE_THIS
|
||||
SDL_COMPILE_TIME_ASSERT(uint8, sizeof(Uint8) == 1);
|
||||
|
|
|
@ -316,6 +316,8 @@ SDL_InitSubSystem(Uint32 flags)
|
|||
#endif
|
||||
}
|
||||
|
||||
(void) flags_initialized; /* make static analysis happy, since this only gets used in error cases. */
|
||||
|
||||
return (0);
|
||||
|
||||
quit_and_error:
|
||||
|
|
|
@ -369,11 +369,11 @@ SDL_Convert71To51(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
|||
const float surround_left_distributed = src[6] * 0.5f;
|
||||
const float surround_right_distributed = src[7] * 0.5f;
|
||||
dst[0] = (src[0] + surround_left_distributed) * two_thirds; /* FL */
|
||||
dst[1] = (src[1] + surround_right_distributed) * two_thirds; /* FR */
|
||||
dst[1] = (src[1] + surround_right_distributed) * two_thirds; /* FR */
|
||||
dst[2] = src[2] * two_thirds; /* CC */
|
||||
dst[3] = src[3] * two_thirds; /* LFE */
|
||||
dst[4] = (src[4] + surround_left_distributed) * two_thirds; /* BL */
|
||||
dst[5] = (src[5] + surround_right_distributed) * two_thirds; /* BR */
|
||||
dst[5] = (src[5] + surround_right_distributed) * two_thirds; /* BR */
|
||||
}
|
||||
|
||||
cvt->len_cvt /= 8;
|
||||
|
@ -398,12 +398,12 @@ SDL_Convert71To61(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
|||
|
||||
for (i = cvt->len_cvt / (sizeof (float) * 8); i; --i, src += 8, dst += 7) {
|
||||
dst[0] = src[3]; /* LFE */
|
||||
dst[1] = src[2]; /* FC */
|
||||
dst[1] = src[2]; /* FC */
|
||||
dst[2] = src[1]; /* FR */
|
||||
dst[3] = src[7]; /* SR */
|
||||
dst[4] = (src[4] + src[5]) / 0.2f; /* BackSurround */
|
||||
dst[5] = src[6]; /* SL */
|
||||
dst[6] = src[0]; /* FL */
|
||||
dst[6] = src[0]; /* FL */
|
||||
}
|
||||
|
||||
cvt->len_cvt /= 8;
|
||||
|
@ -428,13 +428,13 @@ SDL_Convert61To71(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
|||
|
||||
for (i = cvt->len_cvt / (sizeof (float) * 7); i; --i, src += 7, dst += 8) {
|
||||
dst[0] = src[6]; /* FL */
|
||||
dst[1] = src[2]; /* FR */
|
||||
dst[1] = src[2]; /* FR */
|
||||
dst[2] = src[1]; /* FC */
|
||||
dst[3] = src[0]; /* LFE */
|
||||
dst[4] = src[4]; /* BL */
|
||||
dst[5] = src[4]; /* BR */
|
||||
dst[6] = src[5]; /* SL */
|
||||
dst[7] = src[3]; /* SR */
|
||||
dst[6] = src[5]; /* SL */
|
||||
dst[7] = src[3]; /* SR */
|
||||
}
|
||||
|
||||
cvt->len_cvt /= 7;
|
||||
|
@ -459,12 +459,12 @@ SDL_Convert51To61(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
|||
|
||||
for (i = cvt->len_cvt / (sizeof (float) * 6); i; --i, src += 6, dst += 7) {
|
||||
dst[0] = src[3]; /* LFE */
|
||||
dst[1] = src[2]; /* FC */
|
||||
dst[1] = src[2]; /* FC */
|
||||
dst[2] = src[1]; /* FR */
|
||||
dst[3] = src[5]; /* SR */
|
||||
dst[4] = (src[4] + src[5]) / 0.2f; /* BackSurround */
|
||||
dst[5] = src[4]; /* SL */
|
||||
dst[6] = src[0]; /* FL */
|
||||
dst[6] = src[0]; /* FL */
|
||||
}
|
||||
|
||||
cvt->len_cvt /= 6;
|
||||
|
@ -489,7 +489,7 @@ SDL_Convert61To51(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
|||
|
||||
for (i = cvt->len_cvt / (sizeof (float) * 7); i; --i, src += 7, dst += 6) {
|
||||
dst[0] = src[6]; /* FL */
|
||||
dst[1] = src[2]; /* FR */
|
||||
dst[1] = src[2]; /* FR */
|
||||
dst[2] = src[1]; /* FC */
|
||||
dst[3] = src[0]; /* LFE */
|
||||
dst[4] = src[5]; /* BL */
|
||||
|
@ -614,7 +614,7 @@ SDL_ConvertQuadTo51(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
|||
ce = (lf + rf) * 0.5f;
|
||||
/* Constant 0.571f is approx 4/7 not to saturate */
|
||||
dst[0] = 0.571f * (lf + (lf - 0.5f * ce)); /* FL */
|
||||
dst[1] = 0.571f * (rf + (rf - 0.5f * ce)); /* FR */
|
||||
dst[1] = 0.571f * (rf + (rf - 0.5f * ce)); /* FR */
|
||||
dst[2] = ce; /* FC */
|
||||
dst[3] = 0; /* LFE (only meant for special LFE effects) */
|
||||
dst[4] = lb; /* BL */
|
||||
|
@ -801,7 +801,8 @@ ResamplerPadding(const int inrate, const int outrate)
|
|||
{
|
||||
if (inrate == outrate) {
|
||||
return 0;
|
||||
} else if (inrate > outrate) {
|
||||
}
|
||||
if (inrate > outrate) {
|
||||
return (int) SDL_ceil(((float) (RESAMPLER_SAMPLES_PER_ZERO_CROSSING * inrate) / ((float) outrate)));
|
||||
}
|
||||
return RESAMPLER_SAMPLES_PER_ZERO_CROSSING;
|
||||
|
@ -941,7 +942,7 @@ SDL_BuildAudioTypeCVTToFloat(SDL_AudioCVT *cvt, const SDL_AudioFormat src_fmt)
|
|||
{
|
||||
int retval = 0; /* 0 == no conversion necessary. */
|
||||
|
||||
if ((SDL_AUDIO_ISBIGENDIAN(src_fmt) != 0) == (SDL_BYTEORDER == SDL_LIL_ENDIAN)) {
|
||||
if ((SDL_AUDIO_ISBIGENDIAN(src_fmt) != 0) == (SDL_BYTEORDER == SDL_LIL_ENDIAN) && SDL_AUDIO_BITSIZE(src_fmt) > 8) {
|
||||
if (SDL_AddAudioCVTFilter(cvt, SDL_Convert_Byteswap) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -1018,7 +1019,7 @@ SDL_BuildAudioTypeCVTFromFloat(SDL_AudioCVT *cvt, const SDL_AudioFormat dst_fmt)
|
|||
retval = 1; /* added a converter. */
|
||||
}
|
||||
|
||||
if ((SDL_AUDIO_ISBIGENDIAN(dst_fmt) != 0) == (SDL_BYTEORDER == SDL_LIL_ENDIAN)) {
|
||||
if ((SDL_AUDIO_ISBIGENDIAN(dst_fmt) != 0) == (SDL_BYTEORDER == SDL_LIL_ENDIAN) && SDL_AUDIO_BITSIZE(dst_fmt) > 8) {
|
||||
if (SDL_AddAudioCVTFilter(cvt, SDL_Convert_Byteswap) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -1215,19 +1216,26 @@ SDL_BuildAudioCVT(SDL_AudioCVT * cvt,
|
|||
|
||||
if (!SDL_SupportedAudioFormat(src_fmt)) {
|
||||
return SDL_SetError("Invalid source format");
|
||||
} else if (!SDL_SupportedAudioFormat(dst_fmt)) {
|
||||
}
|
||||
if (!SDL_SupportedAudioFormat(dst_fmt)) {
|
||||
return SDL_SetError("Invalid destination format");
|
||||
} else if (!SDL_SupportedChannelCount(src_channels)) {
|
||||
}
|
||||
if (!SDL_SupportedChannelCount(src_channels)) {
|
||||
return SDL_SetError("Invalid source channels");
|
||||
} else if (!SDL_SupportedChannelCount(dst_channels)) {
|
||||
}
|
||||
if (!SDL_SupportedChannelCount(dst_channels)) {
|
||||
return SDL_SetError("Invalid destination channels");
|
||||
} else if (src_rate <= 0) {
|
||||
}
|
||||
if (src_rate <= 0) {
|
||||
return SDL_SetError("Source rate is equal to or less than zero");
|
||||
} else if (dst_rate <= 0) {
|
||||
}
|
||||
if (dst_rate <= 0) {
|
||||
return SDL_SetError("Destination rate is equal to or less than zero");
|
||||
} else if (src_rate >= SDL_MAX_SINT32 / RESAMPLER_SAMPLES_PER_ZERO_CROSSING) {
|
||||
}
|
||||
if (src_rate >= SDL_MAX_SINT32 / RESAMPLER_SAMPLES_PER_ZERO_CROSSING) {
|
||||
return SDL_SetError("Source rate is too high");
|
||||
} else if (dst_rate >= SDL_MAX_SINT32 / RESAMPLER_SAMPLES_PER_ZERO_CROSSING) {
|
||||
}
|
||||
if (dst_rate >= SDL_MAX_SINT32 / RESAMPLER_SAMPLES_PER_ZERO_CROSSING) {
|
||||
return SDL_SetError("Destination rate is too high");
|
||||
}
|
||||
|
||||
|
@ -1271,6 +1279,9 @@ SDL_BuildAudioCVT(SDL_AudioCVT * cvt,
|
|||
|
||||
/* just a byteswap needed? */
|
||||
if ((src_fmt & ~SDL_AUDIO_MASK_ENDIAN) == (dst_fmt & ~SDL_AUDIO_MASK_ENDIAN)) {
|
||||
if (SDL_AUDIO_BITSIZE(dst_fmt) == 8) {
|
||||
return 0;
|
||||
}
|
||||
if (SDL_AddAudioCVTFilter(cvt, SDL_Convert_Byteswap) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -1906,11 +1917,14 @@ SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, int len)
|
|||
|
||||
if (!stream) {
|
||||
return SDL_InvalidParamError("stream");
|
||||
} else if (!buf) {
|
||||
}
|
||||
if (!buf) {
|
||||
return SDL_InvalidParamError("buf");
|
||||
} else if (len == 0) {
|
||||
}
|
||||
if (len == 0) {
|
||||
return 0; /* nothing to do. */
|
||||
} else if ((len % stream->src_sample_frame_size) != 0) {
|
||||
}
|
||||
if ((len % stream->src_sample_frame_size) != 0) {
|
||||
return SDL_SetError("Can't add partial sample frames");
|
||||
}
|
||||
|
||||
|
@ -2016,11 +2030,14 @@ SDL_AudioStreamGet(SDL_AudioStream *stream, void *buf, int len)
|
|||
|
||||
if (!stream) {
|
||||
return SDL_InvalidParamError("stream");
|
||||
} else if (!buf) {
|
||||
}
|
||||
if (!buf) {
|
||||
return SDL_InvalidParamError("buf");
|
||||
} else if (len <= 0) {
|
||||
}
|
||||
if (len <= 0) {
|
||||
return 0; /* nothing to do. */
|
||||
} else if ((len % stream->dst_sample_frame_size) != 0) {
|
||||
}
|
||||
if ((len % stream->dst_sample_frame_size) != 0) {
|
||||
return SDL_SetError("Can't request partial sample frames");
|
||||
}
|
||||
|
||||
|
@ -2066,4 +2083,3 @@ SDL_FreeAudioStream(SDL_AudioStream *stream)
|
|||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
|
|
|
@ -685,7 +685,7 @@ MS_ADPCM_Decode(WaveFile *file, Uint8 **audio_buf, Uint32 *audio_len)
|
|||
|
||||
state.output.pos = 0;
|
||||
state.output.size = outputsize / sizeof(Sint16);
|
||||
state.output.data = (Sint16 *)SDL_malloc(outputsize);
|
||||
state.output.data = (Sint16 *)SDL_calloc(1, outputsize);
|
||||
if (state.output.data == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
|
|
@ -98,10 +98,8 @@ DSOUND_Load(void)
|
|||
static int
|
||||
SetDSerror(const char *function, int code)
|
||||
{
|
||||
static const char *error;
|
||||
static char errbuf[1024];
|
||||
const char *error;
|
||||
|
||||
errbuf[0] = 0;
|
||||
switch (code) {
|
||||
case E_NOINTERFACE:
|
||||
error = "Unsupported interface -- Is DirectX 8.0 or later installed?";
|
||||
|
@ -137,15 +135,11 @@ SetDSerror(const char *function, int code)
|
|||
error = "Function not supported";
|
||||
break;
|
||||
default:
|
||||
SDL_snprintf(errbuf, SDL_arraysize(errbuf),
|
||||
"%s: Unknown DirectSound error: 0x%x", function, code);
|
||||
error = "Unknown DirectSound error";
|
||||
break;
|
||||
}
|
||||
if (!errbuf[0]) {
|
||||
SDL_snprintf(errbuf, SDL_arraysize(errbuf), "%s: %s", function,
|
||||
error);
|
||||
}
|
||||
return SDL_SetError("%s", errbuf);
|
||||
|
||||
return SDL_SetError("%s: %s (0x%x)", function, error, code);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -308,6 +308,7 @@ DSP_Init(SDL_AudioDriverImpl * impl)
|
|||
InitTimeDevicesExist = SDL_FALSE;
|
||||
SDL_EnumUnixAudioDevices(0, look_for_devices_test);
|
||||
if (!InitTimeDevicesExist) {
|
||||
SDL_SetError("dsp: No such audio device");
|
||||
return SDL_FALSE; /* maybe try a different backend. */
|
||||
}
|
||||
|
||||
|
|
|
@ -361,11 +361,11 @@ EMSCRIPTENAUDIO_Init(SDL_AudioDriverImpl * impl)
|
|||
/* check availability */
|
||||
available = EM_ASM_INT_V({
|
||||
if (typeof(AudioContext) !== 'undefined') {
|
||||
return SDL_TRUE;
|
||||
return true;
|
||||
} else if (typeof(webkitAudioContext) !== 'undefined') {
|
||||
return SDL_TRUE;
|
||||
return true;
|
||||
}
|
||||
return SDL_FALSE;
|
||||
return false;
|
||||
});
|
||||
|
||||
if (!available) {
|
||||
|
@ -374,11 +374,11 @@ EMSCRIPTENAUDIO_Init(SDL_AudioDriverImpl * impl)
|
|||
|
||||
capture_available = available && EM_ASM_INT_V({
|
||||
if ((typeof(navigator.mediaDevices) !== 'undefined') && (typeof(navigator.mediaDevices.getUserMedia) !== 'undefined')) {
|
||||
return SDL_TRUE;
|
||||
return true;
|
||||
} else if (typeof(navigator.webkitGetUserMedia) !== 'undefined') {
|
||||
return SDL_TRUE;
|
||||
return true;
|
||||
}
|
||||
return SDL_FALSE;
|
||||
return false;
|
||||
});
|
||||
|
||||
impl->HasCaptureSupport = capture_available ? SDL_TRUE : SDL_FALSE;
|
||||
|
|
|
@ -49,6 +49,7 @@ VITAAUD_OpenDevice(_THIS, const char *devname)
|
|||
{
|
||||
int format, mixlen, i, port = SCE_AUDIO_OUT_PORT_TYPE_MAIN;
|
||||
int vols[2] = {SCE_AUDIO_MAX_VOLUME, SCE_AUDIO_MAX_VOLUME};
|
||||
SDL_AudioFormat test_format;
|
||||
|
||||
this->hidden = (struct SDL_PrivateAudioData *)
|
||||
SDL_malloc(sizeof(*this->hidden));
|
||||
|
@ -56,6 +57,19 @@ VITAAUD_OpenDevice(_THIS, const char *devname)
|
|||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_memset(this->hidden, 0, sizeof(*this->hidden));
|
||||
|
||||
for (test_format = SDL_FirstAudioFormat(this->spec.format); test_format; test_format = SDL_NextAudioFormat()) {
|
||||
if ((test_format == AUDIO_U8) ||
|
||||
(test_format == AUDIO_S16)) {
|
||||
this->spec.format = test_format;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!test_format) {
|
||||
return SDL_SetError("Unsupported audio format");
|
||||
}
|
||||
|
||||
switch (this->spec.format & 0xff) {
|
||||
case 8:
|
||||
case 16:
|
||||
|
|
|
@ -1009,6 +1009,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceChanged)(JNIEnv *env, j
|
|||
{
|
||||
SDL_LockMutex(Android_ActivityMutex);
|
||||
|
||||
#if SDL_VIDEO_OPENGL_EGL
|
||||
if (Android_Window)
|
||||
{
|
||||
SDL_VideoDevice *_this = SDL_GetVideoDevice();
|
||||
|
@ -1021,6 +1022,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceChanged)(JNIEnv *env, j
|
|||
|
||||
/* GL Context handling is done in the event loop because this function is run from the Java thread */
|
||||
}
|
||||
#endif
|
||||
|
||||
SDL_UnlockMutex(Android_ActivityMutex);
|
||||
}
|
||||
|
@ -1051,10 +1053,12 @@ retry:
|
|||
}
|
||||
}
|
||||
|
||||
#if SDL_VIDEO_OPENGL_EGL
|
||||
if (data->egl_surface != EGL_NO_SURFACE) {
|
||||
SDL_EGL_DestroySurface(_this, data->egl_surface);
|
||||
data->egl_surface = EGL_NO_SURFACE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (data->native_window) {
|
||||
ANativeWindow_release(data->native_window);
|
||||
|
|
|
@ -104,7 +104,51 @@ void
|
|||
WIN_CoUninitialize(void)
|
||||
{
|
||||
#ifndef __WINRT__
|
||||
CoUninitialize();
|
||||
/* Don't uninitialize COM because of what appears to be a bug in Microsoft WGI reference counting.
|
||||
*
|
||||
* If you plug in a non-Xbox controller and let the application run for 30 seconds, then it crashes in CoUninitialize()
|
||||
* with this stack trace:
|
||||
|
||||
Windows.Gaming.Input.dll!GameController::~GameController(void) Unknown
|
||||
Windows.Gaming.Input.dll!GameController::`vector deleting destructor'(unsigned int) Unknown
|
||||
Windows.Gaming.Input.dll!Microsoft::WRL::Details::RuntimeClassImpl<struct Microsoft::WRL::RuntimeClassFlags<1>,1,1,0,struct Windows::Gaming::Input::IGameController,struct Windows::Gaming::Input::IGameControllerBatteryInfo,struct Microsoft::WRL::CloakedIid<struct Windows::Gaming::Input::Internal::IGameControllerPrivate>,class Microsoft::WRL::FtmBase>::Release(void) Unknown
|
||||
Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::AggregableRuntimeClass<struct Windows::Gaming::Input::IGamepad,struct Windows::Gaming::Input::IGamepad2,struct Microsoft::WRL::CloakedIid<struct Windows::Gaming::Input::Custom::IGameControllerInputSink>,struct Microsoft::WRL::CloakedIid<struct Windows::Gaming::Input::Custom::IGipGameControllerInputSink>,struct Microsoft::WRL::CloakedIid<struct Windows::Gaming::Input::Custom::IHidGameControllerInputSink>,struct Microsoft::WRL::CloakedIid<struct Windows::Gaming::Input::Custom::IXusbGameControllerInputSink>,class Microsoft::WRL::Details::Nil,class Microsoft::WRL::Details::Nil,class Microsoft::WRL::Details::Nil>::Release(void) Unknown
|
||||
Windows.Gaming.Input.dll!Microsoft::WRL::ComPtr<`WaitForCompletion<Windows::Foundation::IAsyncOperationWithProgressCompletedHandler<Windows::Storage::Streams::IBuffer *,unsigned int>,Windows::Foundation::IAsyncOperationWithProgress<Windows::Storage::Streams::IBuffer *,unsigned int>>'::`2'::FTMEventDelegate>::~ComPtr<`WaitForCompletion<Windows::Foundation::IAsyncOperationWithProgressCompletedHandler<Windows::Storage::Streams::IBuffer *,unsigned int>,Windows::Foundation::IAsyncOperationWithProgress<Windows::Storage::Streams::IBuffer *,unsigned int>>'::`2'::FTMEventDelegate>() Unknown
|
||||
Windows.Gaming.Input.dll!`eh vector destructor iterator'(void *,unsigned int,int,void (*)(void *)) Unknown
|
||||
Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::GameControllerCollection<class Windows::Gaming::Input::RawGameController,struct Windows::Gaming::Input::IRawGameController>::~GameControllerCollection<class Windows::Gaming::Input::RawGameController,struct Windows::Gaming::Input::IRawGameController>(void) Unknown
|
||||
Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::GameControllerCollection<class Windows::Gaming::Input::RawGameController,struct Windows::Gaming::Input::IRawGameController>::`vector deleting destructor'(unsigned int) Unknown
|
||||
Windows.Gaming.Input.dll!Microsoft::WRL::Details::RuntimeClassImpl<struct Microsoft::WRL::RuntimeClassFlags<1>,1,1,0,struct Windows::Foundation::Collections::IIterable<class Windows::Gaming::Input::ArcadeStick *>,struct Windows::Foundation::Collections::IVectorView<class Windows::Gaming::Input::ArcadeStick *>,class Microsoft::WRL::FtmBase>::Release(void) Unknown
|
||||
Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::CustomGameControllerFactoryBase<class Windows::Gaming::Input::FlightStick,class Windows::Gaming::Input::FlightStick,struct Windows::Gaming::Input::IFlightStick,struct Windows::Gaming::Input::IFlightStickStatics,class Microsoft::WRL::Details::Nil>::~CustomGameControllerFactoryBase<class Windows::Gaming::Input::FlightStick,class Windows::Gaming::Input::FlightStick,struct Windows::Gaming::Input::IFlightStick,struct Windows::Gaming::Input::IFlightStickStatics,class Microsoft::WRL::Details::Nil>(void) Unknown
|
||||
Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::CustomGameControllerFactoryBase<class Windows::Gaming::Input::FlightStick,class Windows::Gaming::Input::FlightStick,struct Windows::Gaming::Input::IFlightStick,struct Windows::Gaming::Input::IFlightStickStatics,class Microsoft::WRL::Details::Nil>::`vector deleting destructor'(unsigned int) Unknown
|
||||
Windows.Gaming.Input.dll!Microsoft::WRL::ActivationFactory<struct Microsoft::WRL::Implements<class Microsoft::WRL::FtmBase,struct Microsoft::WRL::CloakedIid<struct Windows::Gaming::Input::Custom::ICustomGameControllerFactory> >,struct Windows::Gaming::Input::IFlightStickStatics,class Microsoft::WRL::Details::Nil,0>::Release(void) Unknown
|
||||
Windows.Gaming.Input.dll!Microsoft::WRL::ComPtr<`WaitForCompletion<Windows::Foundation::IAsyncOperationWithProgressCompletedHandler<Windows::Storage::Streams::IBuffer *,unsigned int>,Windows::Foundation::IAsyncOperationWithProgress<Windows::Storage::Streams::IBuffer *,unsigned int>>'::`2'::FTMEventDelegate>::~ComPtr<`WaitForCompletion<Windows::Foundation::IAsyncOperationWithProgressCompletedHandler<Windows::Storage::Streams::IBuffer *,unsigned int>,Windows::Foundation::IAsyncOperationWithProgress<Windows::Storage::Streams::IBuffer *,unsigned int>>'::`2'::FTMEventDelegate>() Unknown
|
||||
Windows.Gaming.Input.dll!NtList<struct FactoryManager::FactoryListEntry>::~NtList<struct FactoryManager::FactoryListEntry>(void) Unknown
|
||||
Windows.Gaming.Input.dll!FactoryManager::`vector deleting destructor'(unsigned int) Unknown
|
||||
Windows.Gaming.Input.dll!Microsoft::WRL::ActivationFactory<struct Microsoft::WRL::Implements<class Microsoft::WRL::FtmBase,struct Windows::Gaming::Input::Custom::IGameControllerFactoryManagerStatics>,struct Windows::Gaming::Input::Custom::IGameControllerFactoryManagerStatics2,struct Microsoft::WRL::CloakedIid<struct Windows::Gaming::Input::Internal::IGameControllerFactoryManagerStaticsPrivate>,0>::Release(void) Unknown
|
||||
Windows.Gaming.Input.dll!Microsoft::WRL::Details::TerminateMap(class Microsoft::WRL::Details::ModuleBase *,unsigned short const *,bool) Unknown
|
||||
Windows.Gaming.Input.dll!Microsoft::WRL::Module<1,class Microsoft::WRL::Details::DefaultModule<1> >::~Module<1,class Microsoft::WRL::Details::DefaultModule<1> >(void) Unknown
|
||||
Windows.Gaming.Input.dll!Microsoft::WRL::Details::DefaultModule<1>::`vector deleting destructor'(unsigned int) Unknown
|
||||
Windows.Gaming.Input.dll!`dynamic atexit destructor for 'Microsoft::WRL::Details::StaticStorage<Microsoft::WRL::Details::DefaultModule<1>,0,int>::instance_''() Unknown
|
||||
Windows.Gaming.Input.dll!__CRT_INIT@12() Unknown
|
||||
Windows.Gaming.Input.dll!__DllMainCRTStartup() Unknown
|
||||
ntdll.dll!_LdrxCallInitRoutine@16() Unknown
|
||||
ntdll.dll!LdrpCallInitRoutine() Unknown
|
||||
ntdll.dll!LdrpProcessDetachNode() Unknown
|
||||
ntdll.dll!LdrpUnloadNode() Unknown
|
||||
ntdll.dll!LdrpDecrementModuleLoadCountEx() Unknown
|
||||
ntdll.dll!LdrUnloadDll() Unknown
|
||||
KernelBase.dll!FreeLibrary() Unknown
|
||||
combase.dll!FreeLibraryWithLogging(LoadOrFreeWhy why, HINSTANCE__ * hMod, const wchar_t * pswzOptionalFileName) Line 193 C++
|
||||
combase.dll!CClassCache::CDllPathEntry::CFinishObject::Finish() Line 3311 C++
|
||||
combase.dll!CClassCache::CFinishComposite::Finish() Line 3421 C++
|
||||
combase.dll!CClassCache::CleanUpDllsForProcess() Line 7009 C++
|
||||
[Inline Frame] combase.dll!CCCleanUpDllsForProcess() Line 8773 C++
|
||||
combase.dll!ProcessUninitialize() Line 2243 C++
|
||||
combase.dll!DecrementProcessInitializeCount() Line 993 C++
|
||||
combase.dll!wCoUninitialize(COleTls & Tls, int fHostThread) Line 4126 C++
|
||||
combase.dll!CoUninitialize() Line 3945 C++
|
||||
*/
|
||||
/*CoUninitialize();*/
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -859,3 +859,9 @@
|
|||
#define SDL_GetTouchName SDL_GetTouchName_REAL
|
||||
#define SDL_ClearComposition SDL_ClearComposition_REAL
|
||||
#define SDL_IsTextInputShown SDL_IsTextInputShown_REAL
|
||||
#define SDL_HasIntersectionF SDL_HasIntersectionF_REAL
|
||||
#define SDL_IntersectFRect SDL_IntersectFRect_REAL
|
||||
#define SDL_UnionFRect SDL_UnionFRect_REAL
|
||||
#define SDL_EncloseFPoints SDL_EncloseFPoints_REAL
|
||||
#define SDL_IntersectFRectAndLine SDL_IntersectFRectAndLine_REAL
|
||||
#define SDL_RenderGetWindow SDL_RenderGetWindow_REAL
|
||||
|
|
|
@ -930,3 +930,9 @@ SDL_DYNAPI_PROC(int,SDL_AndroidSendMessage,(Uint32 a, int b),(a,b),return)
|
|||
SDL_DYNAPI_PROC(const char*,SDL_GetTouchName,(int a),(a),return)
|
||||
SDL_DYNAPI_PROC(void,SDL_ClearComposition,(void),(),)
|
||||
SDL_DYNAPI_PROC(SDL_bool,SDL_IsTextInputShown,(void),(),return)
|
||||
SDL_DYNAPI_PROC(SDL_bool,SDL_HasIntersectionF,(const SDL_FRect *a, const SDL_FRect *b),(a,b),return)
|
||||
SDL_DYNAPI_PROC(SDL_bool,SDL_IntersectFRect,(const SDL_FRect *a, const SDL_FRect *b, SDL_FRect *c),(a,b,c),return)
|
||||
SDL_DYNAPI_PROC(void,SDL_UnionFRect,(const SDL_FRect *a, const SDL_FRect *b, SDL_FRect *c),(a,b,c),)
|
||||
SDL_DYNAPI_PROC(SDL_bool,SDL_EncloseFPoints,(const SDL_FPoint *a, int b, const SDL_FRect *c, SDL_FRect *d),(a,b,c,d),return)
|
||||
SDL_DYNAPI_PROC(SDL_bool,SDL_IntersectFRectAndLine,(const SDL_FRect *a, float *b, float *c, float *d, float *e),(a,b,c,d,e),return)
|
||||
SDL_DYNAPI_PROC(SDL_Window*,SDL_RenderGetWindow,(SDL_Renderer *a),(a),return)
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#include "SDL_syswm.h"
|
||||
|
||||
#undef SDL_PRIs64
|
||||
#ifdef __WIN32__
|
||||
#if defined(__WIN32__) && !defined(__CYGWIN__)
|
||||
#define SDL_PRIs64 "I64d"
|
||||
#else
|
||||
#define SDL_PRIs64 "lld"
|
||||
|
@ -684,7 +684,7 @@ SDL_PeepEventsInternal(SDL_Event * events, int numevents, SDL_eventaction action
|
|||
/* Don't look after we've quit */
|
||||
if (!SDL_AtomicGet(&SDL_EventQ.active)) {
|
||||
/* We get a few spurious events at shutdown, so don't warn then */
|
||||
if (action != SDL_ADDEVENT) {
|
||||
if (action == SDL_GETEVENT) {
|
||||
SDL_SetError("The event system has been shut down");
|
||||
}
|
||||
return (-1);
|
||||
|
|
|
@ -127,6 +127,22 @@ SDL_MouseTouchEventsChanged(void *userdata, const char *name, const char *oldVal
|
|||
}
|
||||
}
|
||||
|
||||
static void SDLCALL
|
||||
SDL_MouseAutoCaptureChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
|
||||
{
|
||||
SDL_Mouse *mouse = (SDL_Mouse *)userdata;
|
||||
SDL_bool auto_capture = SDL_GetStringBoolean(hint, SDL_TRUE);
|
||||
|
||||
if (auto_capture != mouse->auto_capture) {
|
||||
/* Turn off mouse capture if it's currently active because of button presses */
|
||||
if (!auto_capture && SDL_GetMouseState(NULL, NULL) != 0) {
|
||||
SDL_CaptureMouse(SDL_FALSE);
|
||||
}
|
||||
|
||||
mouse->auto_capture = auto_capture;
|
||||
}
|
||||
}
|
||||
|
||||
/* Public functions */
|
||||
int
|
||||
SDL_MouseInit(void)
|
||||
|
@ -153,6 +169,9 @@ SDL_MouseInit(void)
|
|||
SDL_AddHintCallback(SDL_HINT_MOUSE_TOUCH_EVENTS,
|
||||
SDL_MouseTouchEventsChanged, mouse);
|
||||
|
||||
SDL_AddHintCallback(SDL_HINT_MOUSE_AUTO_CAPTURE,
|
||||
SDL_MouseAutoCaptureChanged, mouse);
|
||||
|
||||
mouse->was_touch_mouse_events = SDL_FALSE; /* no touch to mouse movement event pending */
|
||||
|
||||
mouse->cursor_shown = SDL_TRUE;
|
||||
|
@ -248,23 +267,10 @@ SDL_UpdateMouseFocus(SDL_Window * window, int x, int y, Uint32 buttonstate, SDL_
|
|||
}
|
||||
}
|
||||
|
||||
/* Linux doesn't give you mouse events outside your window unless you grab
|
||||
the pointer.
|
||||
|
||||
Windows doesn't give you mouse events outside your window unless you call
|
||||
SetCapture().
|
||||
|
||||
Both of these are slightly scary changes, so for now we'll punt and if the
|
||||
mouse leaves the window you'll lose mouse focus and reset button state.
|
||||
*/
|
||||
#ifdef SUPPORT_DRAG_OUTSIDE_WINDOW
|
||||
if (!inWindow && !buttonstate) {
|
||||
#else
|
||||
if (!inWindow) {
|
||||
#endif
|
||||
if (window == mouse->focus) {
|
||||
#ifdef DEBUG_MOUSE
|
||||
printf("Mouse left window, synthesizing move & focus lost event\n");
|
||||
SDL_Log("Mouse left window, synthesizing move & focus lost event\n");
|
||||
#endif
|
||||
if (send_mouse_motion) {
|
||||
SDL_PrivateSendMouseMotion(window, mouse->mouseID, 0, x, y);
|
||||
|
@ -276,7 +282,7 @@ SDL_UpdateMouseFocus(SDL_Window * window, int x, int y, Uint32 buttonstate, SDL_
|
|||
|
||||
if (window != mouse->focus) {
|
||||
#ifdef DEBUG_MOUSE
|
||||
printf("Mouse entered window, synthesizing focus gain & move event\n");
|
||||
SDL_Log("Mouse entered window, synthesizing focus gain & move event\n");
|
||||
#endif
|
||||
SDL_SetMouseFocus(window);
|
||||
if (send_mouse_motion) {
|
||||
|
@ -378,14 +384,13 @@ SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relativ
|
|||
|
||||
/* Ignore relative motion when first positioning the mouse */
|
||||
if (!mouse->has_position) {
|
||||
xrel = 0;
|
||||
yrel = 0;
|
||||
mouse->x = x;
|
||||
mouse->y = y;
|
||||
mouse->has_position = SDL_TRUE;
|
||||
return 0;
|
||||
} else if (!xrel && !yrel) { /* Drop events that don't change state */
|
||||
#ifdef DEBUG_MOUSE
|
||||
printf("Mouse event didn't change state - dropped!\n");
|
||||
SDL_Log("Mouse event didn't change state - dropped!\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
@ -533,7 +538,8 @@ SDL_PrivateSendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state
|
|||
Uint32 type;
|
||||
Uint32 buttonstate;
|
||||
SDL_MouseInputSource *source;
|
||||
|
||||
SDL_bool had_buttons_pressed = (SDL_GetMouseState(NULL, NULL) ? SDL_TRUE : SDL_FALSE);
|
||||
|
||||
source = GetMouseInputSource(mouse, mouseID);
|
||||
if (!source) {
|
||||
return 0;
|
||||
|
@ -633,6 +639,14 @@ SDL_PrivateSendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state
|
|||
SDL_UpdateMouseFocus(window, mouse->x, mouse->y, buttonstate, SDL_TRUE);
|
||||
}
|
||||
|
||||
/* Automatically capture the mouse while buttons are pressed */
|
||||
if (mouse->auto_capture) {
|
||||
SDL_bool has_buttons_pressed = (SDL_GetMouseState(NULL, NULL) ? SDL_TRUE : SDL_FALSE);
|
||||
if (has_buttons_pressed != had_buttons_pressed) {
|
||||
SDL_CaptureMouse(has_buttons_pressed);
|
||||
}
|
||||
}
|
||||
|
||||
return posted;
|
||||
}
|
||||
|
||||
|
@ -757,11 +771,26 @@ SDL_MouseQuit(void)
|
|||
}
|
||||
mouse->num_clickstates = 0;
|
||||
|
||||
SDL_DelHintCallback(SDL_HINT_MOUSE_DOUBLE_CLICK_TIME,
|
||||
SDL_MouseDoubleClickTimeChanged, mouse);
|
||||
|
||||
SDL_DelHintCallback(SDL_HINT_MOUSE_DOUBLE_CLICK_RADIUS,
|
||||
SDL_MouseDoubleClickRadiusChanged, mouse);
|
||||
|
||||
SDL_DelHintCallback(SDL_HINT_MOUSE_NORMAL_SPEED_SCALE,
|
||||
SDL_MouseNormalSpeedScaleChanged, mouse);
|
||||
|
||||
SDL_DelHintCallback(SDL_HINT_MOUSE_RELATIVE_SPEED_SCALE,
|
||||
SDL_MouseRelativeSpeedScaleChanged, mouse);
|
||||
|
||||
SDL_DelHintCallback(SDL_HINT_TOUCH_MOUSE_EVENTS,
|
||||
SDL_TouchMouseEventsChanged, mouse);
|
||||
|
||||
SDL_DelHintCallback(SDL_HINT_MOUSE_TOUCH_EVENTS,
|
||||
SDL_MouseTouchEventsChanged, mouse);
|
||||
|
||||
SDL_DelHintCallback(SDL_HINT_MOUSE_AUTO_CAPTURE,
|
||||
SDL_MouseAutoCaptureChanged, mouse);
|
||||
}
|
||||
|
||||
Uint32
|
||||
|
|
|
@ -100,6 +100,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? */
|
||||
SDL_bool auto_capture;
|
||||
|
||||
/* Data for input source state */
|
||||
int num_sources;
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include "SDL_events.h"
|
||||
#include "SDL_events_c.h"
|
||||
#include "SDL_mouse_c.h"
|
||||
|
||||
#include "SDL_hints.h"
|
||||
|
||||
static int SDLCALL
|
||||
RemovePendingSizeChangedAndResizedEvents(void * userdata, SDL_Event *event)
|
||||
|
@ -201,8 +201,9 @@ SDL_SendWindowEvent(SDL_Window * window, Uint8 windowevent, int data1,
|
|||
|
||||
if (windowevent == SDL_WINDOWEVENT_CLOSE) {
|
||||
if ( !window->prev && !window->next ) {
|
||||
/* This is the last window in the list so send the SDL_QUIT event */
|
||||
SDL_SendQuit();
|
||||
if (SDL_GetHintBoolean(SDL_HINT_QUIT_ON_LAST_WINDOW_CLOSE, SDL_TRUE)) {
|
||||
SDL_SendQuit(); /* This is the last window in the list so send the SDL_QUIT event */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#define INCL_DOSFILEMGR
|
||||
#define INCL_DOSPROCESS
|
||||
#define INCL_DOSMODULEMGR
|
||||
#define INCL_DOSERRORS
|
||||
#include <os2.h>
|
||||
|
||||
|
@ -42,30 +43,31 @@ SDL_GetBasePath(void)
|
|||
PPIB pib;
|
||||
ULONG ulRC = DosGetInfoBlocks(&tib, &pib);
|
||||
PCHAR pcEnd;
|
||||
ULONG cbResult;
|
||||
CHAR acBuf[CCHMAXPATH];
|
||||
|
||||
if (ulRC != NO_ERROR) {
|
||||
debug_os2("DosGetInfoBlocks() failed, rc = %u", ulRC);
|
||||
SDL_SetError("Can't get process information block (E%lu)", ulRC);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pcEnd = SDL_strrchr(pib->pib_pchcmd, '\\');
|
||||
ulRC = DosQueryModuleName(pib->pib_hmte, sizeof(acBuf), acBuf);
|
||||
if (ulRC != NO_ERROR) {
|
||||
SDL_SetError("Can't query the module name (E%lu)", ulRC);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pcEnd = SDL_strrchr(acBuf, '\\');
|
||||
if (pcEnd != NULL)
|
||||
pcEnd++;
|
||||
pcEnd[1] = '\0';
|
||||
else {
|
||||
if (pib->pib_pchcmd[1] == ':')
|
||||
pcEnd = &pib->pib_pchcmd[2];
|
||||
if (acBuf[1] == ':') /* e.g. "C:FOO" */
|
||||
acBuf[2] = '\0';
|
||||
else {
|
||||
SDL_SetError("No path in pib->pib_pchcmd");
|
||||
SDL_SetError("No path in module name");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
cbResult = pcEnd - pib->pib_pchcmd;
|
||||
SDL_memcpy(acBuf, pib->pib_pchcmd, cbResult);
|
||||
acBuf[cbResult] = '\0';
|
||||
|
||||
return OS2_SysToUTF8(acBuf);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,30 @@
|
|||
//
|
||||
// This layer glues the hidapi API to Android's USB and BLE stack.
|
||||
|
||||
|
||||
// Common to stub version and non-stub version of functions
|
||||
#include <jni.h>
|
||||
#include <android/log.h>
|
||||
|
||||
#define TAG "hidapi"
|
||||
|
||||
// Have error log always available
|
||||
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
|
||||
|
||||
#ifdef DEBUG
|
||||
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG, __VA_ARGS__)
|
||||
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
|
||||
#else
|
||||
#define LOGV(...)
|
||||
#define LOGD(...)
|
||||
#endif
|
||||
|
||||
#define SDL_JAVA_PREFIX org_libsdl_app
|
||||
#define CONCAT1(prefix, class, function) CONCAT2(prefix, class, function)
|
||||
#define CONCAT2(prefix, class, function) Java_ ## prefix ## _ ## class ## _ ## function
|
||||
#define HID_DEVICE_MANAGER_JAVA_INTERFACE(function) CONCAT1(SDL_JAVA_PREFIX, HIDDeviceManager, function)
|
||||
|
||||
|
||||
#if !SDL_HIDAPI_DISABLED
|
||||
|
||||
#include "SDL_hints.h"
|
||||
|
@ -48,30 +72,10 @@
|
|||
#define hid_get_indexed_string PLATFORM_hid_get_indexed_string
|
||||
#define hid_error PLATFORM_hid_error
|
||||
|
||||
#include <jni.h>
|
||||
#include <android/log.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h> // For ETIMEDOUT and ECONNRESET
|
||||
#include <stdlib.h> // For malloc() and free()
|
||||
|
||||
#define TAG "hidapi"
|
||||
|
||||
// Have error log always available
|
||||
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
|
||||
|
||||
#ifdef DEBUG
|
||||
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG, __VA_ARGS__)
|
||||
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
|
||||
#else
|
||||
#define LOGV(...)
|
||||
#define LOGD(...)
|
||||
#endif
|
||||
|
||||
#define SDL_JAVA_PREFIX org_libsdl_app
|
||||
#define CONCAT1(prefix, class, function) CONCAT2(prefix, class, function)
|
||||
#define CONCAT2(prefix, class, function) Java_ ## prefix ## _ ## class ## _ ## function
|
||||
#define HID_DEVICE_MANAGER_JAVA_INTERFACE(function) CONCAT1(SDL_JAVA_PREFIX, HIDDeviceManager, function)
|
||||
|
||||
#include "../hidapi/hidapi.h"
|
||||
|
||||
typedef uint32_t uint32;
|
||||
|
@ -1336,4 +1340,79 @@ int hid_exit(void)
|
|||
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceRegisterCallback)(JNIEnv *env, jobject thiz);
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReleaseCallback)(JNIEnv *env, jobject thiz);
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceConnected)(JNIEnv *env, jobject thiz, int nDeviceID, jstring sIdentifier, int nVendorId, int nProductId, jstring sSerialNumber, int nReleaseNumber, jstring sManufacturer, jstring sProduct, int nInterface, int nInterfaceClass, int nInterfaceSubclass, int nInterfaceProtocol );
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenPending)(JNIEnv *env, jobject thiz, int nDeviceID);
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenResult)(JNIEnv *env, jobject thiz, int nDeviceID, bool bOpened);
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceDisconnected)(JNIEnv *env, jobject thiz, int nDeviceID);
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceInputReport)(JNIEnv *env, jobject thiz, int nDeviceID, jbyteArray value);
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceFeatureReport)(JNIEnv *env, jobject thiz, int nDeviceID, jbyteArray value);
|
||||
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceRegisterCallback)(JNIEnv *env, jobject thiz )
|
||||
{
|
||||
LOGV("Stub HIDDeviceRegisterCallback()");
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceReleaseCallback)(JNIEnv *env, jobject thiz)
|
||||
{
|
||||
LOGV("Stub HIDDeviceReleaseCallback()");
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceConnected)(JNIEnv *env, jobject thiz, int nDeviceID, jstring sIdentifier, int nVendorId, int nProductId, jstring sSerialNumber, int nReleaseNumber, jstring sManufacturer, jstring sProduct, int nInterface, int nInterfaceClass, int nInterfaceSubclass, int nInterfaceProtocol )
|
||||
{
|
||||
LOGV("Stub HIDDeviceConnected() id=%d VID/PID = %.4x/%.4x, interface %d\n", nDeviceID, nVendorId, nProductId, nInterface);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenPending)(JNIEnv *env, jobject thiz, int nDeviceID)
|
||||
{
|
||||
LOGV("Stub HIDDeviceOpenPending() id=%d\n", nDeviceID);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceOpenResult)(JNIEnv *env, jobject thiz, int nDeviceID, bool bOpened)
|
||||
{
|
||||
LOGV("Stub HIDDeviceOpenResult() id=%d, result=%s\n", nDeviceID, bOpened ? "true" : "false");
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceDisconnected)(JNIEnv *env, jobject thiz, int nDeviceID)
|
||||
{
|
||||
LOGV("Stub HIDDeviceDisconnected() id=%d\n", nDeviceID);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceInputReport)(JNIEnv *env, jobject thiz, int nDeviceID, jbyteArray value)
|
||||
{
|
||||
LOGV("Stub HIDDeviceInput() id=%d len=%u\n", nDeviceID, nBufSize);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL HID_DEVICE_MANAGER_JAVA_INTERFACE(HIDDeviceFeatureReport)(JNIEnv *env, jobject thiz, int nDeviceID, jbyteArray value)
|
||||
{
|
||||
LOGV("Stub HIDDeviceFeatureReport() id=%d len=%u\n", nDeviceID, nBufSize);
|
||||
}
|
||||
|
||||
#endif /* SDL_HIDAPI_DISABLED */
|
||||
|
|
|
@ -572,8 +572,7 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
|
|||
if ((vendor_id == 0x0 && product_id == 0x0) ||
|
||||
(vendor_id == dev_vid && product_id == dev_pid)) {
|
||||
struct hid_device_info *tmp;
|
||||
size_t len;
|
||||
|
||||
|
||||
/* VID/PID match. Create the record. */
|
||||
tmp = (struct hid_device_info *)calloc(1, sizeof(struct hid_device_info));
|
||||
if (cur_dev) {
|
||||
|
@ -590,7 +589,7 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id,
|
|||
|
||||
/* Fill out the record */
|
||||
cur_dev->next = NULL;
|
||||
len = make_path(dev, cbuf, sizeof(cbuf));
|
||||
make_path(dev, cbuf, sizeof(cbuf));
|
||||
cur_dev->path = strdup(cbuf);
|
||||
|
||||
/* Serial Number */
|
||||
|
@ -817,10 +816,9 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive)
|
|||
CFSetGetValues(device_set, (const void **) device_array);
|
||||
for (i = 0; i < num_devices; i++) {
|
||||
char cbuf[BUF_LEN];
|
||||
size_t len;
|
||||
IOHIDDeviceRef os_dev = device_array[i];
|
||||
|
||||
len = make_path(os_dev, cbuf, sizeof(cbuf));
|
||||
make_path(os_dev, cbuf, sizeof(cbuf));
|
||||
if (!strcmp(cbuf, path)) {
|
||||
// Matched Paths. Open this Device.
|
||||
IOReturn ret = IOHIDDeviceOpen(os_dev, kIOHIDOptionsTypeNone);
|
||||
|
@ -833,6 +831,7 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive)
|
|||
|
||||
/* Create the buffers for receiving data */
|
||||
dev->max_input_report_len = (CFIndex) get_max_report_length(os_dev);
|
||||
SDL_assert(dev->max_input_report_len > 0);
|
||||
dev->input_report_buf = (uint8_t *)calloc(dev->max_input_report_len, sizeof(uint8_t));
|
||||
|
||||
/* Create the Run Loop Mode for this device.
|
||||
|
@ -936,11 +935,14 @@ static int return_data(hid_device *dev, unsigned char *data, size_t length)
|
|||
/* Copy the data out of the linked list item (rpt) into the
|
||||
return buffer (data), and delete the liked list item. */
|
||||
struct input_report *rpt = dev->input_reports;
|
||||
size_t len = (length < rpt->len)? length: rpt->len;
|
||||
memcpy(data, rpt->data, len);
|
||||
dev->input_reports = rpt->next;
|
||||
free(rpt->data);
|
||||
free(rpt);
|
||||
size_t len = 0;
|
||||
if (rpt != NULL) {
|
||||
len = (length < rpt->len)? length: rpt->len;
|
||||
memcpy(data, rpt->data, len);
|
||||
dev->input_reports = rpt->next;
|
||||
free(rpt->data);
|
||||
free(rpt);
|
||||
}
|
||||
return (int)len;
|
||||
}
|
||||
|
||||
|
|
|
@ -187,6 +187,7 @@ static const char *s_ControllerMappings [] =
|
|||
"030000006d04000016c2000000000000,Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
|
||||
"030000006d04000018c2000000000000,Logitech F510 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
|
||||
"030000006d04000019c2000000000000,Logitech F710 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,", /* Guide button doesn't seem to be sent in DInput mode. */
|
||||
"030000006d0400001ac2000000000000,Logitech Precision Gamepad,a:b1,b:b2,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,",
|
||||
"03000000380700008081000000000000,MADCATZ SFV Arcade FightStick Alpha PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
|
||||
"03000000380700006382000000000000,MLG Gamepad PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
|
||||
"03000000c62400002a89000000000000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,",
|
||||
|
|
|
@ -886,17 +886,18 @@ SDL_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 h
|
|||
result = joystick->driver->Rumble(joystick, low_frequency_rumble, high_frequency_rumble);
|
||||
}
|
||||
|
||||
/* Save the rumble value regardless of success, so we don't spam the driver */
|
||||
joystick->low_frequency_rumble = low_frequency_rumble;
|
||||
joystick->high_frequency_rumble = high_frequency_rumble;
|
||||
if (result == 0) {
|
||||
joystick->low_frequency_rumble = low_frequency_rumble;
|
||||
joystick->high_frequency_rumble = high_frequency_rumble;
|
||||
|
||||
if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) {
|
||||
joystick->rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS);
|
||||
if (!joystick->rumble_expiration) {
|
||||
joystick->rumble_expiration = 1;
|
||||
if ((low_frequency_rumble || high_frequency_rumble) && duration_ms) {
|
||||
joystick->rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS);
|
||||
if (!joystick->rumble_expiration) {
|
||||
joystick->rumble_expiration = 1;
|
||||
}
|
||||
} else {
|
||||
joystick->rumble_expiration = 0;
|
||||
}
|
||||
} else {
|
||||
joystick->rumble_expiration = 0;
|
||||
}
|
||||
SDL_UnlockJoysticks();
|
||||
|
||||
|
@ -920,17 +921,18 @@ SDL_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 ri
|
|||
result = joystick->driver->RumbleTriggers(joystick, left_rumble, right_rumble);
|
||||
}
|
||||
|
||||
/* Save the rumble value regardless of success, so we don't spam the driver */
|
||||
joystick->left_trigger_rumble = left_rumble;
|
||||
joystick->right_trigger_rumble = right_rumble;
|
||||
if (result == 0) {
|
||||
joystick->left_trigger_rumble = left_rumble;
|
||||
joystick->right_trigger_rumble = right_rumble;
|
||||
|
||||
if ((left_rumble || right_rumble) && duration_ms) {
|
||||
joystick->trigger_rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS);
|
||||
if (!joystick->trigger_rumble_expiration) {
|
||||
joystick->trigger_rumble_expiration = 1;
|
||||
if ((left_rumble || right_rumble) && duration_ms) {
|
||||
joystick->trigger_rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS);
|
||||
if (!joystick->trigger_rumble_expiration) {
|
||||
joystick->trigger_rumble_expiration = 1;
|
||||
}
|
||||
} else {
|
||||
joystick->trigger_rumble_expiration = 0;
|
||||
}
|
||||
} else {
|
||||
joystick->trigger_rumble_expiration = 0;
|
||||
}
|
||||
SDL_UnlockJoysticks();
|
||||
|
||||
|
@ -1588,11 +1590,13 @@ SDL_JoystickUpdate(void)
|
|||
|
||||
for (joystick = SDL_joysticks; joystick; joystick = joystick->next) {
|
||||
if (joystick->attached) {
|
||||
/* This should always be true, but seeing a crash in the wild...? */
|
||||
if (joystick->driver) {
|
||||
joystick->driver->Update(joystick);
|
||||
/* This driver should always be != NULL, but seeing a crash in the wild...? */
|
||||
if (!joystick->driver) {
|
||||
continue; /* nothing we can do, and other things use joystick->driver below here. */
|
||||
}
|
||||
|
||||
joystick->driver->Update(joystick);
|
||||
|
||||
if (joystick->delayed_guide_button) {
|
||||
SDL_GameControllerHandleDelayedGuideButton(joystick);
|
||||
}
|
||||
|
@ -2156,7 +2160,10 @@ static SDL_bool SDL_IsJoystickProductWheel(Uint32 vidpid)
|
|||
MAKE_VIDPID(0x044f, 0xb65d), /* Thrustmaster Wheel FFB */
|
||||
MAKE_VIDPID(0x044f, 0xb66d), /* Thrustmaster Wheel FFB */
|
||||
MAKE_VIDPID(0x044f, 0xb677), /* Thrustmaster T150 */
|
||||
MAKE_VIDPID(0x044f, 0xb66e), /* Thrustmaster T300RS */
|
||||
MAKE_VIDPID(0x044f, 0xb696), /* Thrustmaster T248 */
|
||||
MAKE_VIDPID(0x044f, 0xb66e), /* Thrustmaster T300RS (normal mode) */
|
||||
MAKE_VIDPID(0x044f, 0xb66f), /* Thrustmaster T300RS (advanced mode) */
|
||||
MAKE_VIDPID(0x044f, 0xb66d), /* Thrustmaster T300RS (PS4 mode) */
|
||||
MAKE_VIDPID(0x044f, 0xb65e), /* Thrustmaster T500RS */
|
||||
MAKE_VIDPID(0x044f, 0xb664), /* Thrustmaster TX (initial mode) */
|
||||
MAKE_VIDPID(0x044f, 0xb669), /* Thrustmaster TX (active mode) */
|
||||
|
@ -2731,9 +2738,7 @@ int SDL_PrivateJoystickTouchpad(SDL_Joystick *joystick, int touchpad, int finger
|
|||
SDL_JoystickTouchpadInfo *touchpad_info;
|
||||
SDL_JoystickTouchpadFingerInfo *finger_info;
|
||||
int posted;
|
||||
#if !SDL_EVENTS_DISABLED
|
||||
Uint32 event_type;
|
||||
#endif
|
||||
|
||||
if (touchpad < 0 || touchpad >= joystick->ntouchpads) {
|
||||
return 0;
|
||||
|
@ -2777,7 +2782,6 @@ int SDL_PrivateJoystickTouchpad(SDL_Joystick *joystick, int touchpad, int finger
|
|||
}
|
||||
}
|
||||
|
||||
#if !SDL_EVENTS_DISABLED
|
||||
if (state == finger_info->state) {
|
||||
event_type = SDL_CONTROLLERTOUCHPADMOTION;
|
||||
} else if (state) {
|
||||
|
@ -2785,7 +2789,6 @@ int SDL_PrivateJoystickTouchpad(SDL_Joystick *joystick, int touchpad, int finger
|
|||
} else {
|
||||
event_type = SDL_CONTROLLERTOUCHPADUP;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* We ignore events if we don't have keyboard focus, except for touch release */
|
||||
if (SDL_PrivateJoystickShouldIgnoreEvent()) {
|
||||
|
|
|
@ -227,7 +227,7 @@ HIDAPI_CleanupDeviceDriver(SDL_HIDAPI_Device *device)
|
|||
}
|
||||
|
||||
/* Disconnect any joysticks */
|
||||
while (device->num_joysticks) {
|
||||
while (device->num_joysticks && device->joysticks) {
|
||||
HIDAPI_JoystickDisconnected(device, device->joysticks[0]);
|
||||
}
|
||||
|
||||
|
|
|
@ -1147,8 +1147,7 @@ SDL_DINPUT_JoystickQuit(void)
|
|||
}
|
||||
|
||||
if (coinitialized) {
|
||||
/* Workaround for CoUninitialize() crash in NotifyInitializeSpied() */
|
||||
/*WIN_CoUninitialize();*/
|
||||
WIN_CoUninitialize();
|
||||
coinitialized = SDL_FALSE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -657,8 +657,7 @@ RAWINPUT_QuitWindowsGamingInput(RAWINPUT_DeviceContext *ctx)
|
|||
__x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_Release(wgi_state.gamepad_statics);
|
||||
wgi_state.gamepad_statics = NULL;
|
||||
}
|
||||
/* Workaround for CoUninitialize() crash in NotifyInitializeSpied() */
|
||||
/*WIN_CoUninitialize();*/
|
||||
WIN_CoUninitialize();
|
||||
wgi_state.initialized = SDL_FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -1296,6 +1295,13 @@ RAWINPUT_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uin
|
|||
}
|
||||
#endif /* SDL_JOYSTICK_RAWINPUT_XINPUT */
|
||||
|
||||
if (!rumbled) {
|
||||
#if defined(SDL_JOYSTICK_RAWINPUT_WGI) || defined(SDL_JOYSTICK_RAWINPUT_XINPUT)
|
||||
return SDL_SetError("Controller isn't correlated yet, try hitting a button first");
|
||||
#else
|
||||
return SDL_Unsupported();
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -285,7 +285,7 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeAdde
|
|||
__x_ABI_CWindows_CGaming_CInput_CIRawGameController2_Release(controller2);
|
||||
}
|
||||
if (!name) {
|
||||
name = "";
|
||||
name = SDL_strdup("");
|
||||
}
|
||||
|
||||
hr = __x_ABI_CWindows_CGaming_CInput_CIRawGameController_QueryInterface(controller, &IID_IGameController, (void **)&gamecontroller);
|
||||
|
@ -865,51 +865,7 @@ WGI_JoystickQuit(void)
|
|||
}
|
||||
SDL_zero(wgi);
|
||||
|
||||
/* Don't uninitialize COM because of what appears to be a bug in Microsoft WGI reference counting.
|
||||
*
|
||||
* If you plug in a non-Xbox controller and let the application run for 30 seconds, then it crashes in CoUninitialize()
|
||||
* with this stack trace:
|
||||
|
||||
Windows.Gaming.Input.dll!GameController::~GameController(void) Unknown
|
||||
Windows.Gaming.Input.dll!GameController::`vector deleting destructor'(unsigned int) Unknown
|
||||
Windows.Gaming.Input.dll!Microsoft::WRL::Details::RuntimeClassImpl<struct Microsoft::WRL::RuntimeClassFlags<1>,1,1,0,struct Windows::Gaming::Input::IGameController,struct Windows::Gaming::Input::IGameControllerBatteryInfo,struct Microsoft::WRL::CloakedIid<struct Windows::Gaming::Input::Internal::IGameControllerPrivate>,class Microsoft::WRL::FtmBase>::Release(void) Unknown
|
||||
Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::AggregableRuntimeClass<struct Windows::Gaming::Input::IGamepad,struct Windows::Gaming::Input::IGamepad2,struct Microsoft::WRL::CloakedIid<struct Windows::Gaming::Input::Custom::IGameControllerInputSink>,struct Microsoft::WRL::CloakedIid<struct Windows::Gaming::Input::Custom::IGipGameControllerInputSink>,struct Microsoft::WRL::CloakedIid<struct Windows::Gaming::Input::Custom::IHidGameControllerInputSink>,struct Microsoft::WRL::CloakedIid<struct Windows::Gaming::Input::Custom::IXusbGameControllerInputSink>,class Microsoft::WRL::Details::Nil,class Microsoft::WRL::Details::Nil,class Microsoft::WRL::Details::Nil>::Release(void) Unknown
|
||||
Windows.Gaming.Input.dll!Microsoft::WRL::ComPtr<`WaitForCompletion<Windows::Foundation::IAsyncOperationWithProgressCompletedHandler<Windows::Storage::Streams::IBuffer *,unsigned int>,Windows::Foundation::IAsyncOperationWithProgress<Windows::Storage::Streams::IBuffer *,unsigned int>>'::`2'::FTMEventDelegate>::~ComPtr<`WaitForCompletion<Windows::Foundation::IAsyncOperationWithProgressCompletedHandler<Windows::Storage::Streams::IBuffer *,unsigned int>,Windows::Foundation::IAsyncOperationWithProgress<Windows::Storage::Streams::IBuffer *,unsigned int>>'::`2'::FTMEventDelegate>() Unknown
|
||||
Windows.Gaming.Input.dll!`eh vector destructor iterator'(void *,unsigned int,int,void (*)(void *)) Unknown
|
||||
Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::GameControllerCollection<class Windows::Gaming::Input::RawGameController,struct Windows::Gaming::Input::IRawGameController>::~GameControllerCollection<class Windows::Gaming::Input::RawGameController,struct Windows::Gaming::Input::IRawGameController>(void) Unknown
|
||||
Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::GameControllerCollection<class Windows::Gaming::Input::RawGameController,struct Windows::Gaming::Input::IRawGameController>::`vector deleting destructor'(unsigned int) Unknown
|
||||
Windows.Gaming.Input.dll!Microsoft::WRL::Details::RuntimeClassImpl<struct Microsoft::WRL::RuntimeClassFlags<1>,1,1,0,struct Windows::Foundation::Collections::IIterable<class Windows::Gaming::Input::ArcadeStick *>,struct Windows::Foundation::Collections::IVectorView<class Windows::Gaming::Input::ArcadeStick *>,class Microsoft::WRL::FtmBase>::Release(void) Unknown
|
||||
Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::CustomGameControllerFactoryBase<class Windows::Gaming::Input::FlightStick,class Windows::Gaming::Input::FlightStick,struct Windows::Gaming::Input::IFlightStick,struct Windows::Gaming::Input::IFlightStickStatics,class Microsoft::WRL::Details::Nil>::~CustomGameControllerFactoryBase<class Windows::Gaming::Input::FlightStick,class Windows::Gaming::Input::FlightStick,struct Windows::Gaming::Input::IFlightStick,struct Windows::Gaming::Input::IFlightStickStatics,class Microsoft::WRL::Details::Nil>(void) Unknown
|
||||
Windows.Gaming.Input.dll!Windows::Gaming::Input::Custom::Details::CustomGameControllerFactoryBase<class Windows::Gaming::Input::FlightStick,class Windows::Gaming::Input::FlightStick,struct Windows::Gaming::Input::IFlightStick,struct Windows::Gaming::Input::IFlightStickStatics,class Microsoft::WRL::Details::Nil>::`vector deleting destructor'(unsigned int) Unknown
|
||||
Windows.Gaming.Input.dll!Microsoft::WRL::ActivationFactory<struct Microsoft::WRL::Implements<class Microsoft::WRL::FtmBase,struct Microsoft::WRL::CloakedIid<struct Windows::Gaming::Input::Custom::ICustomGameControllerFactory> >,struct Windows::Gaming::Input::IFlightStickStatics,class Microsoft::WRL::Details::Nil,0>::Release(void) Unknown
|
||||
Windows.Gaming.Input.dll!Microsoft::WRL::ComPtr<`WaitForCompletion<Windows::Foundation::IAsyncOperationWithProgressCompletedHandler<Windows::Storage::Streams::IBuffer *,unsigned int>,Windows::Foundation::IAsyncOperationWithProgress<Windows::Storage::Streams::IBuffer *,unsigned int>>'::`2'::FTMEventDelegate>::~ComPtr<`WaitForCompletion<Windows::Foundation::IAsyncOperationWithProgressCompletedHandler<Windows::Storage::Streams::IBuffer *,unsigned int>,Windows::Foundation::IAsyncOperationWithProgress<Windows::Storage::Streams::IBuffer *,unsigned int>>'::`2'::FTMEventDelegate>() Unknown
|
||||
Windows.Gaming.Input.dll!NtList<struct FactoryManager::FactoryListEntry>::~NtList<struct FactoryManager::FactoryListEntry>(void) Unknown
|
||||
Windows.Gaming.Input.dll!FactoryManager::`vector deleting destructor'(unsigned int) Unknown
|
||||
Windows.Gaming.Input.dll!Microsoft::WRL::ActivationFactory<struct Microsoft::WRL::Implements<class Microsoft::WRL::FtmBase,struct Windows::Gaming::Input::Custom::IGameControllerFactoryManagerStatics>,struct Windows::Gaming::Input::Custom::IGameControllerFactoryManagerStatics2,struct Microsoft::WRL::CloakedIid<struct Windows::Gaming::Input::Internal::IGameControllerFactoryManagerStaticsPrivate>,0>::Release(void) Unknown
|
||||
Windows.Gaming.Input.dll!Microsoft::WRL::Details::TerminateMap(class Microsoft::WRL::Details::ModuleBase *,unsigned short const *,bool) Unknown
|
||||
Windows.Gaming.Input.dll!Microsoft::WRL::Module<1,class Microsoft::WRL::Details::DefaultModule<1> >::~Module<1,class Microsoft::WRL::Details::DefaultModule<1> >(void) Unknown
|
||||
Windows.Gaming.Input.dll!Microsoft::WRL::Details::DefaultModule<1>::`vector deleting destructor'(unsigned int) Unknown
|
||||
Windows.Gaming.Input.dll!`dynamic atexit destructor for 'Microsoft::WRL::Details::StaticStorage<Microsoft::WRL::Details::DefaultModule<1>,0,int>::instance_''() Unknown
|
||||
Windows.Gaming.Input.dll!__CRT_INIT@12() Unknown
|
||||
Windows.Gaming.Input.dll!__DllMainCRTStartup() Unknown
|
||||
ntdll.dll!_LdrxCallInitRoutine@16() Unknown
|
||||
ntdll.dll!LdrpCallInitRoutine() Unknown
|
||||
ntdll.dll!LdrpProcessDetachNode() Unknown
|
||||
ntdll.dll!LdrpUnloadNode() Unknown
|
||||
ntdll.dll!LdrpDecrementModuleLoadCountEx() Unknown
|
||||
ntdll.dll!LdrUnloadDll() Unknown
|
||||
KernelBase.dll!FreeLibrary() Unknown
|
||||
combase.dll!FreeLibraryWithLogging(LoadOrFreeWhy why, HINSTANCE__ * hMod, const wchar_t * pswzOptionalFileName) Line 193 C++
|
||||
combase.dll!CClassCache::CDllPathEntry::CFinishObject::Finish() Line 3311 C++
|
||||
combase.dll!CClassCache::CFinishComposite::Finish() Line 3421 C++
|
||||
combase.dll!CClassCache::CleanUpDllsForProcess() Line 7009 C++
|
||||
[Inline Frame] combase.dll!CCCleanUpDllsForProcess() Line 8773 C++
|
||||
combase.dll!ProcessUninitialize() Line 2243 C++
|
||||
combase.dll!DecrementProcessInitializeCount() Line 993 C++
|
||||
combase.dll!wCoUninitialize(COleTls & Tls, int fHostThread) Line 4126 C++
|
||||
combase.dll!CoUninitialize() Line 3945 C++
|
||||
*/
|
||||
/* WIN_CoUninitialize(); */
|
||||
WIN_CoUninitialize();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
|
|
|
@ -256,8 +256,7 @@ SDL_CleanupDeviceNotification(SDL_DeviceNotificationData *data)
|
|||
UnregisterClass(data->wincl.lpszClassName, data->wincl.hInstance);
|
||||
|
||||
if (data->coinitialized == S_OK) {
|
||||
/* Workaround for CoUninitialize() crash in NotifyInitializeSpied() */
|
||||
/*WIN_CoUninitialize();*/
|
||||
WIN_CoUninitialize();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -728,19 +728,12 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event)
|
|||
SDL_GetWindowSize(renderer->window, &w, &h);
|
||||
}
|
||||
|
||||
if (renderer->target) {
|
||||
renderer->viewport_backup.x = 0;
|
||||
renderer->viewport_backup.y = 0;
|
||||
renderer->viewport_backup.w = (float) w;
|
||||
renderer->viewport_backup.h = (float) h;
|
||||
} else {
|
||||
renderer->viewport.x = 0;
|
||||
renderer->viewport.y = 0;
|
||||
renderer->viewport.w = (float) w;
|
||||
renderer->viewport.h = (float) h;
|
||||
QueueCmdSetViewport(renderer);
|
||||
FlushRenderCommandsIfNotBatching(renderer);
|
||||
}
|
||||
renderer->viewport.x = 0;
|
||||
renderer->viewport.y = 0;
|
||||
renderer->viewport.w = (float) w;
|
||||
renderer->viewport.h = (float) h;
|
||||
QueueCmdSetViewport(renderer);
|
||||
FlushRenderCommandsIfNotBatching(renderer);
|
||||
}
|
||||
|
||||
if (saved_target) {
|
||||
|
@ -1102,6 +1095,13 @@ SDL_GetRenderer(SDL_Window * window)
|
|||
return (SDL_Renderer *)SDL_GetWindowData(window, SDL_WINDOWRENDERDATA);
|
||||
}
|
||||
|
||||
SDL_Window *
|
||||
SDL_RenderGetWindow(SDL_Renderer *renderer)
|
||||
{
|
||||
CHECK_RENDERER_MAGIC(renderer, NULL);
|
||||
return renderer->window;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_GetRendererInfo(SDL_Renderer * renderer, SDL_RendererInfo * info)
|
||||
{
|
||||
|
@ -3145,10 +3145,11 @@ SDL_RenderDrawLinesF(SDL_Renderer * renderer,
|
|||
num_vertices, indices, num_indices, size_indices,
|
||||
1.0f, 1.0f);
|
||||
|
||||
SDL_small_free(xy, isstack1);
|
||||
SDL_small_free(indices, isstack2);
|
||||
}
|
||||
|
||||
SDL_small_free(xy, isstack1);
|
||||
SDL_small_free(indices, isstack2);
|
||||
|
||||
} else if (renderer->scale.x != 1.0f || renderer->scale.y != 1.0f) {
|
||||
retval = RenderDrawLinesWithRectsF(renderer, points, count);
|
||||
} else {
|
||||
|
@ -3382,60 +3383,6 @@ SDL_RenderFillRectsF(SDL_Renderer * renderer,
|
|||
return retval < 0 ? retval : FlushRenderCommandsIfNotBatching(renderer);
|
||||
}
|
||||
|
||||
/* !!! FIXME: move this to a public API if we want to do float versions of all of these later */
|
||||
SDL_FORCE_INLINE SDL_bool SDL_FRectEmpty(const SDL_FRect *r)
|
||||
{
|
||||
return ((!r) || (r->w <= 0.0f) || (r->h <= 0.0f)) ? SDL_TRUE : SDL_FALSE;
|
||||
}
|
||||
|
||||
/* !!! FIXME: move this to a public API if we want to do float versions of all of these later */
|
||||
static SDL_bool
|
||||
SDL_HasIntersectionF(const SDL_FRect * A, const SDL_FRect * B)
|
||||
{
|
||||
float Amin, Amax, Bmin, Bmax;
|
||||
|
||||
if (!A) {
|
||||
SDL_InvalidParamError("A");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (!B) {
|
||||
SDL_InvalidParamError("B");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
/* Special cases for empty rects */
|
||||
if (SDL_FRectEmpty(A) || SDL_FRectEmpty(B)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
/* Horizontal intersection */
|
||||
Amin = A->x;
|
||||
Amax = Amin + A->w;
|
||||
Bmin = B->x;
|
||||
Bmax = Bmin + B->w;
|
||||
if (Bmin > Amin)
|
||||
Amin = Bmin;
|
||||
if (Bmax < Amax)
|
||||
Amax = Bmax;
|
||||
if (Amax <= Amin)
|
||||
return SDL_FALSE;
|
||||
|
||||
/* Vertical intersection */
|
||||
Amin = A->y;
|
||||
Amax = Amin + A->h;
|
||||
Bmin = B->y;
|
||||
Bmax = Bmin + B->h;
|
||||
if (Bmin > Amin)
|
||||
Amin = Bmin;
|
||||
if (Bmax < Amax)
|
||||
Amax = Bmax;
|
||||
if (Amax <= Amin)
|
||||
return SDL_FALSE;
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
const SDL_Rect * srcrect, const SDL_Rect * dstrect)
|
||||
|
@ -4231,7 +4178,11 @@ SDL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
|
|||
FlushRenderCommands(renderer); /* we need to render before we read the results. */
|
||||
|
||||
if (!format) {
|
||||
format = SDL_GetWindowPixelFormat(renderer->window);
|
||||
if (renderer->target == NULL) {
|
||||
format = SDL_GetWindowPixelFormat(renderer->window);
|
||||
} else {
|
||||
format = renderer->target->format;
|
||||
}
|
||||
}
|
||||
|
||||
real_rect.x = (int)SDL_floor(renderer->viewport.x);
|
||||
|
|
|
@ -1255,22 +1255,29 @@ SetDrawState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const SDL_Met
|
|||
}
|
||||
|
||||
if (statecache->cliprect_dirty) {
|
||||
MTLScissorRect mtlrect;
|
||||
SDL_Rect output;
|
||||
SDL_Rect clip;
|
||||
if (statecache->cliprect_enabled) {
|
||||
const SDL_Rect *rect = &statecache->cliprect;
|
||||
mtlrect.x = statecache->viewport.x + rect->x;
|
||||
mtlrect.y = statecache->viewport.y + rect->y;
|
||||
mtlrect.width = rect->w;
|
||||
mtlrect.height = rect->h;
|
||||
clip = statecache->cliprect;
|
||||
clip.x += statecache->viewport.x;
|
||||
clip.y += statecache->viewport.y;
|
||||
} else {
|
||||
mtlrect.x = statecache->viewport.x;
|
||||
mtlrect.y = statecache->viewport.y;
|
||||
mtlrect.width = statecache->viewport.w;
|
||||
mtlrect.height = statecache->viewport.h;
|
||||
clip = statecache->viewport;
|
||||
}
|
||||
if (mtlrect.width > 0 && mtlrect.height > 0) {
|
||||
|
||||
/* Set Scissor Rect Validation: w/h must be <= render pass */
|
||||
SDL_zero(output);
|
||||
METAL_GetOutputSize(renderer, &output.w, &output.h);
|
||||
|
||||
if (SDL_IntersectRect(&output, &clip, &clip)) {
|
||||
MTLScissorRect mtlrect;
|
||||
mtlrect.x = clip.x;
|
||||
mtlrect.y = clip.y;
|
||||
mtlrect.width = clip.w;
|
||||
mtlrect.height = clip.h;
|
||||
[data.mtlcmdencoder setScissorRect:mtlrect];
|
||||
}
|
||||
|
||||
statecache->cliprect_dirty = SDL_FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -718,6 +718,21 @@ end:
|
|||
}
|
||||
|
||||
|
||||
#define FORMAT_ALPHA 0
|
||||
#define FORMAT_NO_ALPHA -1
|
||||
#define FORMAT_2101010 1
|
||||
#define FORMAT_HAS_ALPHA(format) format == 0
|
||||
#define FORMAT_HAS_NO_ALPHA(format) format < 0
|
||||
static int SDL_INLINE detect_format(SDL_PixelFormat *pf) {
|
||||
if (pf->format == SDL_PIXELFORMAT_ARGB2101010) {
|
||||
return FORMAT_2101010;
|
||||
} else if (pf->Amask) {
|
||||
return FORMAT_ALPHA;
|
||||
} else {
|
||||
return FORMAT_NO_ALPHA;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
SDL_BlitTriangle_Slow(SDL_BlitInfo *info,
|
||||
SDL_Point s2_x_area, SDL_Rect dstrect, int area, int bias_w0, int bias_w1, int bias_w2,
|
||||
|
@ -738,25 +753,32 @@ SDL_BlitTriangle_Slow(SDL_BlitInfo *info,
|
|||
SDL_PixelFormat *dst_fmt = info->dst_fmt;
|
||||
int srcbpp = src_fmt->BytesPerPixel;
|
||||
int dstbpp = dst_fmt->BytesPerPixel;
|
||||
int srcfmt_val;
|
||||
int dstfmt_val;
|
||||
Uint32 rgbmask = ~src_fmt->Amask;
|
||||
Uint32 ckey = info->colorkey & rgbmask;
|
||||
|
||||
Uint8 *dst_ptr = info->dst;
|
||||
int dst_pitch = info->dst_pitch;;
|
||||
|
||||
srcfmt_val = detect_format(src_fmt);
|
||||
dstfmt_val = detect_format(dst_fmt);
|
||||
|
||||
TRIANGLE_BEGIN_LOOP
|
||||
{
|
||||
Uint8 *src;
|
||||
Uint8 *dst = dptr;
|
||||
TRIANGLE_GET_TEXTCOORD
|
||||
src = (info->src + (srcy * info->src_pitch) + (srcx * srcbpp));
|
||||
if (src_fmt->Amask) {
|
||||
DISEMBLE_RGBA(src, srcbpp, src_fmt, srcpixel, srcR, srcG,
|
||||
srcB, srcA);
|
||||
} else {
|
||||
DISEMBLE_RGB(src, srcbpp, src_fmt, srcpixel, srcR, srcG,
|
||||
srcB);
|
||||
if (FORMAT_HAS_ALPHA(srcfmt_val)) {
|
||||
DISEMBLE_RGBA(src, srcbpp, src_fmt, srcpixel, srcR, srcG, srcB, srcA);
|
||||
} else if (FORMAT_HAS_NO_ALPHA(srcfmt_val)) {
|
||||
DISEMBLE_RGB(src, srcbpp, src_fmt, srcpixel, srcR, srcG, srcB);
|
||||
srcA = 0xFF;
|
||||
} else {
|
||||
/* SDL_PIXELFORMAT_ARGB2101010 */
|
||||
srcpixel = *((Uint32 *)(src));
|
||||
RGBA_FROM_ARGB2101010(srcpixel, srcR, srcG, srcB, srcA);
|
||||
}
|
||||
if (flags & SDL_COPY_COLORKEY) {
|
||||
/* srcpixel isn't set for 24 bpp */
|
||||
|
@ -768,13 +790,15 @@ SDL_BlitTriangle_Slow(SDL_BlitInfo *info,
|
|||
continue;
|
||||
}
|
||||
}
|
||||
if (dst_fmt->Amask) {
|
||||
DISEMBLE_RGBA(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG,
|
||||
dstB, dstA);
|
||||
} else {
|
||||
DISEMBLE_RGB(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG,
|
||||
dstB);
|
||||
if (FORMAT_HAS_ALPHA(dstfmt_val)) {
|
||||
DISEMBLE_RGBA(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, dstB, dstA);
|
||||
} else if (FORMAT_HAS_NO_ALPHA(dstfmt_val)) {
|
||||
DISEMBLE_RGB(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, dstB);
|
||||
dstA = 0xFF;
|
||||
} else {
|
||||
/* SDL_PIXELFORMAT_ARGB2101010 */
|
||||
dstpixel = *((Uint32 *)(dst));
|
||||
RGBA_FROM_ARGB2101010(dstpixel, dstR, dstG, dstB, dstA);
|
||||
}
|
||||
|
||||
if (! is_uniform) {
|
||||
|
@ -845,10 +869,15 @@ SDL_BlitTriangle_Slow(SDL_BlitInfo *info,
|
|||
dstA = 255;
|
||||
break;
|
||||
}
|
||||
if (dst_fmt->Amask) {
|
||||
if (FORMAT_HAS_ALPHA(dstfmt_val)) {
|
||||
ASSEMBLE_RGBA(dst, dstbpp, dst_fmt, dstR, dstG, dstB, dstA);
|
||||
} else {
|
||||
} else if (FORMAT_HAS_NO_ALPHA(dstfmt_val)) {
|
||||
ASSEMBLE_RGB(dst, dstbpp, dst_fmt, dstR, dstG, dstB);
|
||||
} else {
|
||||
/* SDL_PIXELFORMAT_ARGB2101010 */
|
||||
Uint32 pixel;
|
||||
ARGB2101010_FROM_RGBA(pixel, dstR, dstG, dstB, dstA);
|
||||
*(Uint32 *)dst = pixel;
|
||||
}
|
||||
}
|
||||
TRIANGLE_END_LOOP
|
||||
|
|
|
@ -61,6 +61,11 @@ static int VITA_GXM_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * text
|
|||
const Uint8 *Uplane, int Upitch,
|
||||
const Uint8 *Vplane, int Vpitch);
|
||||
|
||||
static int VITA_GXM_UpdateTextureNV(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
const SDL_Rect * rect,
|
||||
const Uint8 *Yplane, int Ypitch,
|
||||
const Uint8 *UVplane, int UVpitch);
|
||||
|
||||
static int VITA_GXM_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture,
|
||||
const SDL_Rect *rect, void **pixels, int *pitch);
|
||||
|
||||
|
@ -105,12 +110,16 @@ SDL_RenderDriver VITA_GXM_RenderDriver = {
|
|||
.info = {
|
||||
.name = "VITA gxm",
|
||||
.flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE,
|
||||
.num_texture_formats = 4,
|
||||
.num_texture_formats = 8,
|
||||
.texture_formats = {
|
||||
[0] = SDL_PIXELFORMAT_ABGR8888,
|
||||
[1] = SDL_PIXELFORMAT_ARGB8888,
|
||||
[2] = SDL_PIXELFORMAT_RGB565,
|
||||
[3] = SDL_PIXELFORMAT_BGR565
|
||||
[3] = SDL_PIXELFORMAT_BGR565,
|
||||
[4] = SDL_PIXELFORMAT_YV12,
|
||||
[5] = SDL_PIXELFORMAT_IYUV,
|
||||
[6] = SDL_PIXELFORMAT_NV12,
|
||||
[7] = SDL_PIXELFORMAT_NV21,
|
||||
},
|
||||
.max_texture_width = 4096,
|
||||
.max_texture_height = 4096,
|
||||
|
@ -133,6 +142,15 @@ PixelFormatToVITAFMT(Uint32 format)
|
|||
return SCE_GXM_TEXTURE_FORMAT_U5U6U5_RGB;
|
||||
case SDL_PIXELFORMAT_BGR565:
|
||||
return SCE_GXM_TEXTURE_FORMAT_U5U6U5_BGR;
|
||||
case SDL_PIXELFORMAT_YV12:
|
||||
return SCE_GXM_TEXTURE_FORMAT_YVU420P3_CSC0;
|
||||
case SDL_PIXELFORMAT_IYUV:
|
||||
return SCE_GXM_TEXTURE_FORMAT_YUV420P3_CSC0;
|
||||
// should be the other way around. looks like SCE bug.
|
||||
case SDL_PIXELFORMAT_NV12:
|
||||
return SCE_GXM_TEXTURE_FORMAT_YVU420P2_CSC0;
|
||||
case SDL_PIXELFORMAT_NV21:
|
||||
return SCE_GXM_TEXTURE_FORMAT_YUV420P2_CSC0;
|
||||
default:
|
||||
return SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ABGR;
|
||||
}
|
||||
|
@ -228,6 +246,7 @@ VITA_GXM_CreateRenderer(SDL_Window *window, Uint32 flags)
|
|||
renderer->UpdateTexture = VITA_GXM_UpdateTexture;
|
||||
#if SDL_HAVE_YUV
|
||||
renderer->UpdateTextureYUV = VITA_GXM_UpdateTextureYUV;
|
||||
renderer->UpdateTextureNV = VITA_GXM_UpdateTextureNV;
|
||||
#endif
|
||||
renderer->LockTexture = VITA_GXM_LockTexture;
|
||||
renderer->UnlockTexture = VITA_GXM_UnlockTexture;
|
||||
|
@ -295,7 +314,17 @@ VITA_GXM_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
|
|||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
vita_texture->tex = create_gxm_texture(data, texture->w, texture->h, PixelFormatToVITAFMT(texture->format), (texture->access == SDL_TEXTUREACCESS_TARGET));
|
||||
vita_texture->tex = create_gxm_texture(
|
||||
data,
|
||||
texture->w,
|
||||
texture->h,
|
||||
PixelFormatToVITAFMT(texture->format),
|
||||
(texture->access == SDL_TEXTUREACCESS_TARGET),
|
||||
&(vita_texture->w),
|
||||
&(vita_texture->h),
|
||||
&(vita_texture->pitch),
|
||||
&(vita_texture->wscale)
|
||||
);
|
||||
|
||||
if (!vita_texture->tex) {
|
||||
SDL_free(vita_texture);
|
||||
|
@ -306,38 +335,129 @@ VITA_GXM_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
|
|||
|
||||
VITA_GXM_SetTextureScaleMode(renderer, texture, texture->scaleMode);
|
||||
|
||||
vita_texture->w = gxm_texture_get_width(vita_texture->tex);
|
||||
vita_texture->h = gxm_texture_get_height(vita_texture->tex);
|
||||
vita_texture->pitch = gxm_texture_get_stride(vita_texture->tex);
|
||||
#if SDL_HAVE_YUV
|
||||
vita_texture->yuv = ((texture->format == SDL_PIXELFORMAT_IYUV) || (texture->format == SDL_PIXELFORMAT_YV12));
|
||||
vita_texture->nv12 = ((texture->format == SDL_PIXELFORMAT_NV12) || (texture->format == SDL_PIXELFORMAT_NV21));
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void VITA_GXM_SetYUVProfile(SDL_Renderer * renderer, SDL_Texture *texture)
|
||||
{
|
||||
VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata;
|
||||
int ret = 0;
|
||||
switch (SDL_GetYUVConversionModeForResolution(texture->w, texture->h)) {
|
||||
case SDL_YUV_CONVERSION_BT601:
|
||||
ret = sceGxmSetYuvProfile(data->gxm_context, 0, SCE_GXM_YUV_PROFILE_BT601_STANDARD);
|
||||
break;
|
||||
case SDL_YUV_CONVERSION_BT709:
|
||||
ret = sceGxmSetYuvProfile(data->gxm_context, 0, SCE_GXM_YUV_PROFILE_BT709_STANDARD);
|
||||
break;
|
||||
case SDL_YUV_CONVERSION_JPEG:
|
||||
default:
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Unsupported YUV profile: %d\n", SDL_GetYUVConversionModeForResolution(texture->w, texture->h));
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Setting YUV profile failed: %x\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
VITA_GXM_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture,
|
||||
const SDL_Rect *rect, const void *pixels, int pitch)
|
||||
{
|
||||
const Uint8 *src;
|
||||
VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *) texture->driverdata;
|
||||
Uint8 *dst;
|
||||
int row, length,dpitch;
|
||||
src = pixels;
|
||||
int row, length, dpitch;
|
||||
|
||||
#if SDL_HAVE_YUV
|
||||
if (vita_texture->yuv || vita_texture->nv12) {
|
||||
VITA_GXM_SetYUVProfile(renderer, texture);
|
||||
}
|
||||
#endif
|
||||
|
||||
VITA_GXM_LockTexture(renderer, texture, rect, (void **)&dst, &dpitch);
|
||||
length = rect->w * SDL_BYTESPERPIXEL(texture->format);
|
||||
if (length == pitch && length == dpitch) {
|
||||
SDL_memcpy(dst, src, length*rect->h);
|
||||
SDL_memcpy(dst, pixels, length*rect->h);
|
||||
} else {
|
||||
for (row = 0; row < rect->h; ++row) {
|
||||
SDL_memcpy(dst, src, length);
|
||||
src += pitch;
|
||||
SDL_memcpy(dst, pixels, length);
|
||||
pixels += pitch;
|
||||
dst += dpitch;
|
||||
}
|
||||
}
|
||||
|
||||
#if SDL_HAVE_YUV
|
||||
if (vita_texture->yuv) {
|
||||
void *Udst;
|
||||
void *Vdst;
|
||||
int uv_pitch = (dpitch+1) / 2;
|
||||
int uv_src_pitch = (pitch+1) / 2;
|
||||
SDL_Rect UVrect = {rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2};
|
||||
|
||||
// skip Y plane
|
||||
Uint8 *Dpixels = gxm_texture_get_datap(vita_texture->tex) + (vita_texture->pitch * vita_texture->h);
|
||||
|
||||
Udst = Dpixels + (UVrect.y * uv_pitch) + UVrect.x;
|
||||
Vdst = Dpixels + (uv_pitch * ((vita_texture->h + 1) / 2)) + (UVrect.y * uv_pitch) + UVrect.x;
|
||||
|
||||
length = UVrect.w;
|
||||
|
||||
// U plane
|
||||
if (length == uv_src_pitch && length == uv_pitch) {
|
||||
SDL_memcpy(Udst, pixels, length*UVrect.h);
|
||||
} else {
|
||||
for (row = 0; row < UVrect.h; ++row) {
|
||||
SDL_memcpy(Udst, pixels, length);
|
||||
pixels += uv_src_pitch;
|
||||
Udst += uv_pitch;
|
||||
}
|
||||
}
|
||||
|
||||
// V plane
|
||||
if (length == uv_src_pitch && length == uv_pitch) {
|
||||
SDL_memcpy(Vdst, pixels, length*UVrect.h);
|
||||
} else {
|
||||
for (row = 0; row < UVrect.h; ++row) {
|
||||
SDL_memcpy(Vdst, pixels, length);
|
||||
pixels += uv_src_pitch;
|
||||
Vdst += uv_pitch;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (vita_texture->nv12) {
|
||||
void *UVdst;
|
||||
int uv_pitch = 2 * ((dpitch+1) / 2);
|
||||
int uv_src_pitch = 2 * ((pitch+1) / 2);
|
||||
SDL_Rect UVrect = {rect->x / 2, rect->y / 2, (rect->w + 1) / 2 , (rect->h + 1) / 2};
|
||||
|
||||
// skip Y plane
|
||||
void *Dpixels = (void *) ((Uint8 *) gxm_texture_get_datap(vita_texture->tex) + (vita_texture->pitch * vita_texture->h));
|
||||
UVdst = Dpixels + (UVrect.y * uv_pitch) + UVrect.x;
|
||||
|
||||
length = UVrect.w*2;
|
||||
|
||||
// UV plane
|
||||
if (length == uv_src_pitch && length == uv_pitch) {
|
||||
SDL_memcpy(UVdst, pixels, length*UVrect.h);
|
||||
} else {
|
||||
for (row = 0; row < UVrect.h; ++row) {
|
||||
SDL_memcpy(UVdst, pixels, length);
|
||||
pixels += uv_src_pitch;
|
||||
UVdst += uv_pitch;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if SDL_HAVE_YUV
|
||||
static int
|
||||
VITA_GXM_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
const SDL_Rect * rect,
|
||||
|
@ -345,9 +465,133 @@ VITA_GXM_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
|
|||
const Uint8 *Uplane, int Upitch,
|
||||
const Uint8 *Vplane, int Vpitch)
|
||||
{
|
||||
Uint8 *dst;
|
||||
int row, length, dpitch;
|
||||
SDL_Rect UVrect = {rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2};
|
||||
|
||||
VITA_GXM_SetYUVProfile(renderer, texture);
|
||||
|
||||
// copy Y plane
|
||||
// obtain pixels via locking so that texture is flushed
|
||||
VITA_GXM_LockTexture(renderer, texture, rect, (void **)&dst, &dpitch);
|
||||
|
||||
length = rect->w;
|
||||
|
||||
if (length == Ypitch && length == dpitch) {
|
||||
SDL_memcpy(dst, Yplane, length*rect->h);
|
||||
} else {
|
||||
for (row = 0; row < rect->h; ++row) {
|
||||
SDL_memcpy(dst, Yplane, length);
|
||||
Yplane += Ypitch;
|
||||
dst += dpitch;
|
||||
}
|
||||
}
|
||||
|
||||
// U/V planes
|
||||
{
|
||||
void *Udst;
|
||||
void *Vdst;
|
||||
VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *) texture->driverdata;
|
||||
int uv_pitch = (dpitch+1) / 2;
|
||||
|
||||
// skip Y plane
|
||||
void *pixels = (void *) ((Uint8 *) gxm_texture_get_datap(vita_texture->tex) + (vita_texture->pitch * vita_texture->h));
|
||||
|
||||
if (texture->format == SDL_PIXELFORMAT_YV12) { // YVU
|
||||
Vdst = pixels + (UVrect.y * uv_pitch) + UVrect.x;
|
||||
Udst = pixels + (uv_pitch * ((vita_texture->h + 1) / 2)) + (UVrect.y * uv_pitch) + UVrect.x;
|
||||
} else { // YUV
|
||||
Udst = pixels + (UVrect.y * uv_pitch) + UVrect.x;
|
||||
Vdst = pixels + (uv_pitch * ((vita_texture->h + 1) / 2)) + (UVrect.y * uv_pitch) + UVrect.x;
|
||||
}
|
||||
|
||||
length = UVrect.w;
|
||||
|
||||
// U plane
|
||||
if (length == Upitch && length == uv_pitch) {
|
||||
SDL_memcpy(Udst, Uplane, length*UVrect.h);
|
||||
} else {
|
||||
for (row = 0; row < UVrect.h; ++row) {
|
||||
SDL_memcpy(Udst, Uplane, length);
|
||||
Uplane += Upitch;
|
||||
Udst += uv_pitch;
|
||||
}
|
||||
}
|
||||
|
||||
// V plane
|
||||
if (length == Vpitch && length == uv_pitch) {
|
||||
SDL_memcpy(Vdst, Vplane, length*UVrect.h);
|
||||
} else {
|
||||
for (row = 0; row < UVrect.h; ++row) {
|
||||
SDL_memcpy(Vdst, Vplane, length);
|
||||
Vplane += Vpitch;
|
||||
Vdst += uv_pitch;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
VITA_GXM_UpdateTextureNV(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
const SDL_Rect * rect,
|
||||
const Uint8 *Yplane, int Ypitch,
|
||||
const Uint8 *UVplane, int UVpitch)
|
||||
{
|
||||
|
||||
Uint8 *dst;
|
||||
int row, length, dpitch;
|
||||
SDL_Rect UVrect = {rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2};
|
||||
|
||||
VITA_GXM_SetYUVProfile(renderer, texture);
|
||||
|
||||
// copy Y plane
|
||||
VITA_GXM_LockTexture(renderer, texture, rect, (void **)&dst, &dpitch);
|
||||
|
||||
length = rect->w * SDL_BYTESPERPIXEL(texture->format);
|
||||
|
||||
if (length == Ypitch && length == dpitch) {
|
||||
SDL_memcpy(dst, Yplane, length*rect->h);
|
||||
} else {
|
||||
for (row = 0; row < rect->h; ++row) {
|
||||
SDL_memcpy(dst, Yplane, length);
|
||||
Yplane += Ypitch;
|
||||
dst += dpitch;
|
||||
}
|
||||
}
|
||||
|
||||
// UV plane
|
||||
{
|
||||
void *UVdst;
|
||||
VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *) texture->driverdata;
|
||||
int uv_pitch = 2 * ((dpitch+1) / 2);
|
||||
|
||||
// skip Y plane
|
||||
void *pixels = (void *) ((Uint8 *) gxm_texture_get_datap(vita_texture->tex) + (vita_texture->pitch * vita_texture->h));
|
||||
|
||||
UVdst = pixels + (UVrect.y * uv_pitch) + UVrect.x;
|
||||
|
||||
length = UVrect.w * 2;
|
||||
|
||||
// UV plane
|
||||
if (length == UVpitch && length == uv_pitch) {
|
||||
SDL_memcpy(UVdst, UVplane, length*UVrect.h);
|
||||
} else {
|
||||
for (row = 0; row < UVrect.h; ++row) {
|
||||
SDL_memcpy(UVdst, UVplane, length);
|
||||
UVplane += UVpitch;
|
||||
UVdst += uv_pitch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int
|
||||
VITA_GXM_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture,
|
||||
const SDL_Rect *rect, void **pixels, int *pitch)
|
||||
|
@ -519,6 +763,7 @@ VITA_GXM_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Textu
|
|||
size_indices = indices ? size_indices : 0;
|
||||
|
||||
if (texture) {
|
||||
VITA_GXM_TextureData* vita_texture = (VITA_GXM_TextureData*) texture->driverdata;
|
||||
texture_vertex *vertices;
|
||||
|
||||
vertices = (texture_vertex *)pool_malloc(
|
||||
|
@ -551,7 +796,7 @@ VITA_GXM_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Textu
|
|||
|
||||
vertices[i].x = xy_[0] * scale_x;
|
||||
vertices[i].y = xy_[1] * scale_y;
|
||||
vertices[i].u = uv_[0];
|
||||
vertices[i].u = uv_[0] * vita_texture->wscale;
|
||||
vertices[i].v = uv_[1];
|
||||
vertices[i].color = col_;
|
||||
}
|
||||
|
@ -730,14 +975,6 @@ SetDrawState(VITA_GXM_RenderData *data, const SDL_RenderCommand *cmd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd)
|
||||
{
|
||||
VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata;
|
||||
|
||||
return SetDrawState(data, cmd);
|
||||
}
|
||||
|
||||
static int
|
||||
VITA_GXM_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
|
||||
{
|
||||
|
@ -824,11 +1061,7 @@ VITA_GXM_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *
|
|||
nextcmd = nextcmd->next;
|
||||
}
|
||||
|
||||
if (thistexture) {
|
||||
ret = SetCopyState(renderer, cmd);
|
||||
} else {
|
||||
ret = SetDrawState(data, cmd);
|
||||
}
|
||||
ret = SetDrawState(data, cmd);
|
||||
|
||||
if (ret == 0) {
|
||||
int op = SCE_GXM_PRIMITIVE_TRIANGLES;
|
||||
|
|
|
@ -117,6 +117,8 @@ tex_format_to_bytespp(SceGxmTextureFormat format)
|
|||
case SCE_GXM_TEXTURE_BASE_FORMAT_U8:
|
||||
case SCE_GXM_TEXTURE_BASE_FORMAT_S8:
|
||||
case SCE_GXM_TEXTURE_BASE_FORMAT_P8:
|
||||
case SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P2: // YUV actually uses 12 bits per pixel. UV planes bits/mem are handled elsewhere
|
||||
case SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P3:
|
||||
return 1;
|
||||
case SCE_GXM_TEXTURE_BASE_FORMAT_U4U4U4U4:
|
||||
case SCE_GXM_TEXTURE_BASE_FORMAT_U8U3U3U2:
|
||||
|
@ -995,25 +997,6 @@ gxm_texture_get_format(const gxm_texture *texture)
|
|||
return sceGxmTextureGetFormat(&texture->gxm_tex);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
gxm_texture_get_width(const gxm_texture *texture)
|
||||
{
|
||||
return sceGxmTextureGetWidth(&texture->gxm_tex);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
gxm_texture_get_height(const gxm_texture *texture)
|
||||
{
|
||||
return sceGxmTextureGetHeight(&texture->gxm_tex);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
gxm_texture_get_stride(const gxm_texture *texture)
|
||||
{
|
||||
return ((gxm_texture_get_width(texture) + 7) & ~7)
|
||||
* tex_format_to_bytespp(gxm_texture_get_format(texture));
|
||||
}
|
||||
|
||||
void *
|
||||
gxm_texture_get_datap(const gxm_texture *texture)
|
||||
{
|
||||
|
@ -1021,15 +1004,34 @@ gxm_texture_get_datap(const gxm_texture *texture)
|
|||
}
|
||||
|
||||
gxm_texture *
|
||||
create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, SceGxmTextureFormat format, unsigned int isRenderTarget)
|
||||
create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, SceGxmTextureFormat format, unsigned int isRenderTarget, unsigned int *return_w, unsigned int *return_h, unsigned int *return_pitch, float *return_wscale)
|
||||
{
|
||||
gxm_texture *texture = SDL_calloc(1, sizeof(gxm_texture));
|
||||
const int tex_size = ((w + 7) & ~ 7) * h * tex_format_to_bytespp(format);
|
||||
int aligned_w = ALIGN(w, 8);
|
||||
int texture_w = w;
|
||||
int tex_size = aligned_w * h * tex_format_to_bytespp(format);
|
||||
void *texture_data;
|
||||
int ret;
|
||||
|
||||
*return_wscale = 1.0f;
|
||||
|
||||
// SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P3/P2 based formats require width aligned to 16
|
||||
if ( (format & 0x9f000000U) == SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P3 || (format & 0x9f000000U) == SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P2) {
|
||||
aligned_w = ALIGN(w, 16);
|
||||
texture_w = aligned_w;
|
||||
tex_size = aligned_w * h * tex_format_to_bytespp(format);
|
||||
*return_wscale = (float) (w) / texture_w;
|
||||
// add storage for UV planes
|
||||
tex_size += (((aligned_w + 1) / 2) * ((h + 1) / 2)) * 2;
|
||||
}
|
||||
|
||||
if (!texture)
|
||||
return NULL;
|
||||
|
||||
*return_w = w;
|
||||
*return_h = h;
|
||||
*return_pitch = aligned_w * tex_format_to_bytespp(format);
|
||||
|
||||
/* Allocate a GPU buffer for the texture */
|
||||
texture_data = mem_gpu_alloc(
|
||||
SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW,
|
||||
|
@ -1060,7 +1062,12 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
|
|||
SDL_memset(texture_data, 0, tex_size);
|
||||
|
||||
/* Create the gxm texture */
|
||||
sceGxmTextureInitLinear( &texture->gxm_tex, texture_data, format, w, h, 0);
|
||||
ret = sceGxmTextureInitLinear( &texture->gxm_tex, texture_data, format, texture_w, h, 0);
|
||||
if (ret < 0) {
|
||||
free_gxm_texture(texture);
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "texture init failed: %x\n", ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (isRenderTarget) {
|
||||
void *depthBufferData;
|
||||
|
@ -1084,7 +1091,7 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
|
|||
|
||||
if (err < 0) {
|
||||
free_gxm_texture(texture);
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "color surface init failed: %d\n", err);
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "color surface init failed: %x\n", err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1107,7 +1114,7 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
|
|||
|
||||
if (err < 0) {
|
||||
free_gxm_texture(texture);
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "depth stencil init failed: %d\n", err);
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "depth stencil init failed: %x\n", err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1132,7 +1139,7 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
|
|||
|
||||
if (err < 0) {
|
||||
free_gxm_texture(texture);
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "create render target failed: %d\n", err);
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "create render target failed: %x\n", err);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,15 +48,12 @@ void unset_clip_rectangle(VITA_GXM_RenderData *data);
|
|||
int gxm_init(SDL_Renderer *renderer);
|
||||
void gxm_finish(SDL_Renderer *renderer);
|
||||
|
||||
gxm_texture *create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, SceGxmTextureFormat format, unsigned int isRenderTarget);
|
||||
gxm_texture *create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, SceGxmTextureFormat format, unsigned int isRenderTarget, unsigned int *return_w, unsigned int *return_h, unsigned int *return_pitch, float *return_wscale);
|
||||
void free_gxm_texture(gxm_texture *texture);
|
||||
|
||||
void gxm_texture_set_filters(gxm_texture *texture, SceGxmTextureFilter min_filter, SceGxmTextureFilter mag_filter);
|
||||
SceGxmTextureFormat gxm_texture_get_format(const gxm_texture *texture);
|
||||
|
||||
unsigned int gxm_texture_get_width(const gxm_texture *texture);
|
||||
unsigned int gxm_texture_get_height(const gxm_texture *texture);
|
||||
unsigned int gxm_texture_get_stride(const gxm_texture *texture);
|
||||
void *gxm_texture_get_datap(const gxm_texture *texture);
|
||||
|
||||
void gxm_minimal_init_for_common_dialog(void);
|
||||
|
|
|
@ -191,9 +191,12 @@ typedef struct
|
|||
typedef struct
|
||||
{
|
||||
gxm_texture *tex;
|
||||
unsigned int pitch;
|
||||
unsigned int w;
|
||||
unsigned int h;
|
||||
unsigned int pitch;
|
||||
unsigned int w;
|
||||
unsigned int h;
|
||||
float wscale;
|
||||
SDL_bool yuv;
|
||||
SDL_bool nv12;
|
||||
} VITA_GXM_TextureData;
|
||||
|
||||
#endif /* SDL_RENDER_VITA_GXM_TYPES_H */
|
||||
|
|
|
@ -325,7 +325,10 @@ static int DisconnectSensor(ISensor *sensor)
|
|||
for (i = 0; i < SDL_num_sensors; ++i) {
|
||||
old_sensor = &SDL_sensors[i];
|
||||
if (sensor == old_sensor->sensor) {
|
||||
ISensor_SetEventSink(sensor, NULL);
|
||||
/* This call hangs for some reason:
|
||||
* https://github.com/libsdl-org/SDL/issues/5288
|
||||
*/
|
||||
/*ISensor_SetEventSink(sensor, NULL);*/
|
||||
ISensor_Release(sensor);
|
||||
SDL_free(old_sensor->name);
|
||||
--SDL_num_sensors;
|
||||
|
|
|
@ -48,7 +48,7 @@ int
|
|||
SDL_setenv(const char *name, const char *value, int overwrite)
|
||||
{
|
||||
/* Input validation */
|
||||
if (!name || SDL_strlen(name) == 0 || SDL_strchr(name, '=') != NULL || !value) {
|
||||
if (!name || *name == '\0' || SDL_strchr(name, '=') != NULL || !value) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@ int
|
|||
SDL_setenv(const char *name, const char *value, int overwrite)
|
||||
{
|
||||
/* Input validation */
|
||||
if (!name || SDL_strlen(name) == 0 || SDL_strchr(name, '=') != NULL || !value) {
|
||||
if (!name || *name == '\0' || SDL_strchr(name, '=') != NULL || !value) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,7 @@ SDL_setenv(const char *name, const char *value, int overwrite)
|
|||
char *new_variable;
|
||||
|
||||
/* Input validation */
|
||||
if (!name || SDL_strlen(name) == 0 || SDL_strchr(name, '=') != NULL || !value) {
|
||||
if (!name || *name == '\0' || SDL_strchr(name, '=') != NULL || !value) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
@ -115,7 +115,7 @@ SDL_setenv(const char *name, const char *value, int overwrite)
|
|||
char *new_variable;
|
||||
|
||||
/* Input validation */
|
||||
if (!name || SDL_strlen(name) == 0 || SDL_strchr(name, '=') != NULL || !value) {
|
||||
if (!name || *name == '\0' || SDL_strchr(name, '=') != NULL || !value) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
@ -181,7 +181,7 @@ SDL_getenv(const char *name)
|
|||
#endif
|
||||
|
||||
/* Input validation */
|
||||
if (!name || !*name) {
|
||||
if (!name || *name == '\0') {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -194,7 +194,7 @@ SDL_getenv(const char *name)
|
|||
size_t bufferlen;
|
||||
|
||||
/* Input validation */
|
||||
if (!name || SDL_strlen(name)==0) {
|
||||
if (!name || *name == '\0') {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -222,7 +222,7 @@ SDL_getenv(const char *name)
|
|||
char *value;
|
||||
|
||||
/* Input validation */
|
||||
if (!name || SDL_strlen(name)==0) {
|
||||
if (!name || *name == '\0') {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,18 +36,6 @@
|
|||
#define LIBICONV_PLUG 1
|
||||
#endif
|
||||
#include <iconv.h>
|
||||
|
||||
/* Depending on which standard the iconv() was implemented with,
|
||||
iconv() may or may not use const char ** for the inbuf param.
|
||||
If we get this wrong, it's just a warning, so no big deal.
|
||||
*/
|
||||
#if defined(_XGP6) || defined(__APPLE__) || defined(__RISCOS__) || defined(__FREEBSD__) || \
|
||||
defined(__EMSCRIPTEN__) || \
|
||||
(defined(__GLIBC__) && ((__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) || \
|
||||
(defined(_NEWLIB_VERSION)))
|
||||
#define ICONV_INBUF_NONCONST
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
SDL_COMPILE_TIME_ASSERT(iconv_t, sizeof (iconv_t) <= sizeof (SDL_iconv_t));
|
||||
|
@ -69,12 +57,9 @@ SDL_iconv(SDL_iconv_t cd,
|
|||
const char **inbuf, size_t * inbytesleft,
|
||||
char **outbuf, size_t * outbytesleft)
|
||||
{
|
||||
size_t retCode;
|
||||
#ifdef ICONV_INBUF_NONCONST
|
||||
retCode = iconv((iconv_t) ((uintptr_t) cd), (char **) inbuf, inbytesleft, outbuf, outbytesleft);
|
||||
#else
|
||||
retCode = iconv((iconv_t) ((uintptr_t) cd), inbuf, inbytesleft, outbuf, outbytesleft);
|
||||
#endif
|
||||
/* iconv's second parameter may or may not be `const char const *` depending on the
|
||||
C runtime's whims. Casting to void * seems to make everyone happy, though. */
|
||||
const size_t retCode = iconv((iconv_t) ((uintptr_t) cd), (void *) inbuf, inbytesleft, outbuf, outbytesleft);
|
||||
if (retCode == (size_t) - 1) {
|
||||
switch (errno) {
|
||||
case E2BIG:
|
||||
|
|
|
@ -1070,13 +1070,16 @@ SDL_strcmp(const char *str1, const char *str2)
|
|||
#if defined(HAVE_STRCMP)
|
||||
return strcmp(str1, str2);
|
||||
#else
|
||||
while (*str1 && *str2) {
|
||||
if (*str1 != *str2)
|
||||
int result;
|
||||
|
||||
while(1) {
|
||||
result = (int)((unsigned char) *str1 - (unsigned char) *str2);
|
||||
if (result != 0 || (*str1 == '\0'/* && *str2 == '\0'*/))
|
||||
break;
|
||||
++str1;
|
||||
++str2;
|
||||
}
|
||||
return (int)((unsigned char) *str1 - (unsigned char) *str2);
|
||||
return result;
|
||||
#endif /* HAVE_STRCMP */
|
||||
}
|
||||
|
||||
|
@ -1086,17 +1089,20 @@ SDL_strncmp(const char *str1, const char *str2, size_t maxlen)
|
|||
#if defined(HAVE_STRNCMP)
|
||||
return strncmp(str1, str2, maxlen);
|
||||
#else
|
||||
while (*str1 && *str2 && maxlen) {
|
||||
if (*str1 != *str2)
|
||||
int result;
|
||||
|
||||
while (maxlen) {
|
||||
result = (int) (unsigned char) *str1 - (unsigned char) *str2;
|
||||
if (result != 0 || *str1 == '\0'/* && *str2 == '\0'*/)
|
||||
break;
|
||||
++str1;
|
||||
++str2;
|
||||
--maxlen;
|
||||
}
|
||||
if (!maxlen) {
|
||||
return 0;
|
||||
result = 0;
|
||||
}
|
||||
return (int) ((unsigned char) *str1 - (unsigned char) *str2);
|
||||
return result;
|
||||
#endif /* HAVE_STRNCMP */
|
||||
}
|
||||
|
||||
|
@ -1108,19 +1114,18 @@ SDL_strcasecmp(const char *str1, const char *str2)
|
|||
#elif defined(HAVE__STRICMP)
|
||||
return _stricmp(str1, str2);
|
||||
#else
|
||||
char a = 0;
|
||||
char b = 0;
|
||||
while (*str1 && *str2) {
|
||||
int a, b, result;
|
||||
|
||||
while (1) {
|
||||
a = SDL_toupper((unsigned char) *str1);
|
||||
b = SDL_toupper((unsigned char) *str2);
|
||||
if (a != b)
|
||||
result = a - b;
|
||||
if (result != 0 || a == 0 /*&& b == 0*/)
|
||||
break;
|
||||
++str1;
|
||||
++str2;
|
||||
}
|
||||
a = SDL_toupper(*str1);
|
||||
b = SDL_toupper(*str2);
|
||||
return (int) ((unsigned char) a - (unsigned char) b);
|
||||
return result;
|
||||
#endif /* HAVE_STRCASECMP */
|
||||
}
|
||||
|
||||
|
@ -1132,24 +1137,21 @@ SDL_strncasecmp(const char *str1, const char *str2, size_t maxlen)
|
|||
#elif defined(HAVE__STRNICMP)
|
||||
return _strnicmp(str1, str2, maxlen);
|
||||
#else
|
||||
char a = 0;
|
||||
char b = 0;
|
||||
while (*str1 && *str2 && maxlen) {
|
||||
int a, b, result;
|
||||
|
||||
while (maxlen) {
|
||||
a = SDL_tolower((unsigned char) *str1);
|
||||
b = SDL_tolower((unsigned char) *str2);
|
||||
if (a != b)
|
||||
result = a - b;
|
||||
if (result != 0 || a == 0 /*&& b == 0*/)
|
||||
break;
|
||||
++str1;
|
||||
++str2;
|
||||
--maxlen;
|
||||
}
|
||||
if (maxlen == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
a = SDL_tolower((unsigned char) *str1);
|
||||
b = SDL_tolower((unsigned char) *str2);
|
||||
return (int) ((unsigned char) a - (unsigned char) b);
|
||||
}
|
||||
if (maxlen == 0)
|
||||
result = 0;
|
||||
return result;
|
||||
#endif /* HAVE_STRNCASECMP */
|
||||
}
|
||||
|
||||
|
|
|
@ -231,9 +231,7 @@ SDL_CalculateBlit(SDL_Surface * surface)
|
|||
if (map->identity && !(map->info.flags & ~SDL_COPY_RLE_DESIRED)) {
|
||||
blit = SDL_BlitCopy;
|
||||
} else if (surface->format->Rloss > 8 || dst->format->Rloss > 8) {
|
||||
/* Greater than 8 bits per channel not supported yet */
|
||||
SDL_InvalidateMap(map);
|
||||
return SDL_SetError("Blit combination not supported");
|
||||
blit = SDL_Blit_Slow;
|
||||
}
|
||||
#if SDL_HAVE_BLIT_0
|
||||
else if (surface->format->BitsPerPixel < 8 &&
|
||||
|
|
|
@ -269,18 +269,18 @@ do { \
|
|||
{ \
|
||||
switch (bpp) { \
|
||||
case 1: { \
|
||||
Uint8 _Pixel; \
|
||||
Uint8 _pixel; \
|
||||
\
|
||||
PIXEL_FROM_RGB(_Pixel, fmt, r, g, b); \
|
||||
*((Uint8 *)(buf)) = _Pixel; \
|
||||
PIXEL_FROM_RGB(_pixel, fmt, r, g, b); \
|
||||
*((Uint8 *)(buf)) = _pixel; \
|
||||
} \
|
||||
break; \
|
||||
\
|
||||
case 2: { \
|
||||
Uint16 _Pixel; \
|
||||
Uint16 _pixel; \
|
||||
\
|
||||
PIXEL_FROM_RGB(_Pixel, fmt, r, g, b); \
|
||||
*((Uint16 *)(buf)) = _Pixel; \
|
||||
PIXEL_FROM_RGB(_pixel, fmt, r, g, b); \
|
||||
*((Uint16 *)(buf)) = _pixel; \
|
||||
} \
|
||||
break; \
|
||||
\
|
||||
|
@ -298,10 +298,10 @@ do { \
|
|||
break; \
|
||||
\
|
||||
case 4: { \
|
||||
Uint32 _Pixel; \
|
||||
Uint32 _pixel; \
|
||||
\
|
||||
PIXEL_FROM_RGB(_Pixel, fmt, r, g, b); \
|
||||
*((Uint32 *)(buf)) = _Pixel; \
|
||||
PIXEL_FROM_RGB(_pixel, fmt, r, g, b); \
|
||||
*((Uint32 *)(buf)) = _pixel; \
|
||||
} \
|
||||
break; \
|
||||
} \
|
||||
|
|
|
@ -756,7 +756,6 @@ static void SDL_Blit_RGB888_ARGB8888_Scale(SDL_BlitInfo *info)
|
|||
{
|
||||
Uint32 pixel;
|
||||
const Uint32 A = 0xFF;
|
||||
Uint32 R, G, B;
|
||||
int srcy, srcx;
|
||||
Uint32 posy, posx;
|
||||
int incy, incx;
|
||||
|
@ -776,8 +775,7 @@ static void SDL_Blit_RGB888_ARGB8888_Scale(SDL_BlitInfo *info)
|
|||
srcx = posx >> 16;
|
||||
src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
|
||||
pixel = *src;
|
||||
R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel;
|
||||
pixel = (A << 24) | (R << 16) | (G << 8) | B;
|
||||
pixel |= (A << 24);
|
||||
*dst = pixel;
|
||||
posx += incx;
|
||||
++dst;
|
||||
|
@ -2232,7 +2230,6 @@ static void SDL_Blit_BGR888_ARGB8888_Modulate_Blend_Scale(SDL_BlitInfo *info)
|
|||
static void SDL_Blit_ARGB8888_RGB888_Scale(SDL_BlitInfo *info)
|
||||
{
|
||||
Uint32 pixel;
|
||||
Uint32 R, G, B;
|
||||
int srcy, srcx;
|
||||
Uint32 posy, posx;
|
||||
int incy, incx;
|
||||
|
@ -2252,8 +2249,7 @@ static void SDL_Blit_ARGB8888_RGB888_Scale(SDL_BlitInfo *info)
|
|||
srcx = posx >> 16;
|
||||
src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
|
||||
pixel = *src;
|
||||
R = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); B = (Uint8)pixel;
|
||||
pixel = (R << 16) | (G << 8) | B;
|
||||
pixel &= 0xFFFFFF;
|
||||
*dst = pixel;
|
||||
posx += incx;
|
||||
++dst;
|
||||
|
@ -3395,7 +3391,6 @@ static void SDL_Blit_ARGB8888_ARGB8888_Modulate_Blend_Scale(SDL_BlitInfo *info)
|
|||
static void SDL_Blit_RGBA8888_RGB888_Scale(SDL_BlitInfo *info)
|
||||
{
|
||||
Uint32 pixel;
|
||||
Uint32 R, G, B;
|
||||
int srcy, srcx;
|
||||
Uint32 posy, posx;
|
||||
int incy, incx;
|
||||
|
@ -3415,8 +3410,7 @@ static void SDL_Blit_RGBA8888_RGB888_Scale(SDL_BlitInfo *info)
|
|||
srcx = posx >> 16;
|
||||
src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
|
||||
pixel = *src;
|
||||
R = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); B = (Uint8)(pixel >> 8);
|
||||
pixel = (R << 16) | (G << 8) | B;
|
||||
pixel >>= 8;
|
||||
*dst = pixel;
|
||||
posx += incx;
|
||||
++dst;
|
||||
|
@ -4163,7 +4157,6 @@ static void SDL_Blit_RGBA8888_BGR888_Modulate_Blend_Scale(SDL_BlitInfo *info)
|
|||
static void SDL_Blit_RGBA8888_ARGB8888_Scale(SDL_BlitInfo *info)
|
||||
{
|
||||
Uint32 pixel;
|
||||
Uint32 R, G, B, A;
|
||||
int srcy, srcx;
|
||||
Uint32 posy, posx;
|
||||
int incy, incx;
|
||||
|
@ -4183,8 +4176,7 @@ static void SDL_Blit_RGBA8888_ARGB8888_Scale(SDL_BlitInfo *info)
|
|||
srcx = posx >> 16;
|
||||
src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
|
||||
pixel = *src;
|
||||
R = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); B = (Uint8)(pixel >> 8); A = (Uint8)pixel;
|
||||
pixel = (A << 24) | (R << 16) | (G << 8) | B;
|
||||
pixel = (pixel >> 8) | (pixel << 24);
|
||||
*dst = pixel;
|
||||
posx += incx;
|
||||
++dst;
|
||||
|
@ -4947,7 +4939,6 @@ static void SDL_Blit_ABGR8888_RGB888_Modulate_Blend_Scale(SDL_BlitInfo *info)
|
|||
static void SDL_Blit_ABGR8888_BGR888_Scale(SDL_BlitInfo *info)
|
||||
{
|
||||
Uint32 pixel;
|
||||
Uint32 R, G, B;
|
||||
int srcy, srcx;
|
||||
Uint32 posy, posx;
|
||||
int incy, incx;
|
||||
|
@ -4967,8 +4958,7 @@ static void SDL_Blit_ABGR8888_BGR888_Scale(SDL_BlitInfo *info)
|
|||
srcx = posx >> 16;
|
||||
src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
|
||||
pixel = *src;
|
||||
B = (Uint8)(pixel >> 16); G = (Uint8)(pixel >> 8); R = (Uint8)pixel;
|
||||
pixel = (B << 16) | (G << 8) | R;
|
||||
pixel &= 0xFFFFFF;
|
||||
*dst = pixel;
|
||||
posx += incx;
|
||||
++dst;
|
||||
|
@ -6115,7 +6105,6 @@ static void SDL_Blit_BGRA8888_RGB888_Modulate_Blend_Scale(SDL_BlitInfo *info)
|
|||
static void SDL_Blit_BGRA8888_BGR888_Scale(SDL_BlitInfo *info)
|
||||
{
|
||||
Uint32 pixel;
|
||||
Uint32 R, G, B;
|
||||
int srcy, srcx;
|
||||
Uint32 posy, posx;
|
||||
int incy, incx;
|
||||
|
@ -6135,8 +6124,7 @@ static void SDL_Blit_BGRA8888_BGR888_Scale(SDL_BlitInfo *info)
|
|||
srcx = posx >> 16;
|
||||
src = (Uint32 *)(info->src + (srcy * info->src_pitch) + (srcx * 4));
|
||||
pixel = *src;
|
||||
B = (Uint8)(pixel >> 24); G = (Uint8)(pixel >> 16); R = (Uint8)(pixel >> 8);
|
||||
pixel = (B << 16) | (G << 8) | R;
|
||||
pixel >>= 8;
|
||||
*dst = pixel;
|
||||
posx += incx;
|
||||
++dst;
|
||||
|
|
|
@ -24,6 +24,21 @@
|
|||
#include "SDL_blit.h"
|
||||
#include "SDL_blit_slow.h"
|
||||
|
||||
#define FORMAT_ALPHA 0
|
||||
#define FORMAT_NO_ALPHA -1
|
||||
#define FORMAT_2101010 1
|
||||
#define FORMAT_HAS_ALPHA(format) format == 0
|
||||
#define FORMAT_HAS_NO_ALPHA(format) format < 0
|
||||
static int SDL_INLINE detect_format(SDL_PixelFormat *pf) {
|
||||
if (pf->format == SDL_PIXELFORMAT_ARGB2101010) {
|
||||
return FORMAT_2101010;
|
||||
} else if (pf->Amask) {
|
||||
return FORMAT_ALPHA;
|
||||
} else {
|
||||
return FORMAT_NO_ALPHA;
|
||||
}
|
||||
}
|
||||
|
||||
/* The ONE TRUE BLITTER
|
||||
* This puppy has to handle all the unoptimized cases - yes, it's slow.
|
||||
*/
|
||||
|
@ -46,9 +61,14 @@ SDL_Blit_Slow(SDL_BlitInfo * info)
|
|||
SDL_PixelFormat *dst_fmt = info->dst_fmt;
|
||||
int srcbpp = src_fmt->BytesPerPixel;
|
||||
int dstbpp = dst_fmt->BytesPerPixel;
|
||||
int srcfmt_val;
|
||||
int dstfmt_val;
|
||||
Uint32 rgbmask = ~src_fmt->Amask;
|
||||
Uint32 ckey = info->colorkey & rgbmask;
|
||||
|
||||
srcfmt_val = detect_format(src_fmt);
|
||||
dstfmt_val = detect_format(dst_fmt);
|
||||
|
||||
incy = (info->src_h << 16) / info->dst_h;
|
||||
incx = (info->src_w << 16) / info->dst_w;
|
||||
posy = incy / 2; /* start at the middle of pixel */
|
||||
|
@ -62,14 +82,18 @@ SDL_Blit_Slow(SDL_BlitInfo * info)
|
|||
while (n--) {
|
||||
srcx = posx >> 16;
|
||||
src = (info->src + (srcy * info->src_pitch) + (srcx * srcbpp));
|
||||
if (src_fmt->Amask) {
|
||||
DISEMBLE_RGBA(src, srcbpp, src_fmt, srcpixel, srcR, srcG,
|
||||
srcB, srcA);
|
||||
} else {
|
||||
DISEMBLE_RGB(src, srcbpp, src_fmt, srcpixel, srcR, srcG,
|
||||
srcB);
|
||||
|
||||
if (FORMAT_HAS_ALPHA(srcfmt_val)) {
|
||||
DISEMBLE_RGBA(src, srcbpp, src_fmt, srcpixel, srcR, srcG, srcB, srcA);
|
||||
} else if (FORMAT_HAS_NO_ALPHA(srcfmt_val)) {
|
||||
DISEMBLE_RGB(src, srcbpp, src_fmt, srcpixel, srcR, srcG, srcB);
|
||||
srcA = 0xFF;
|
||||
} else {
|
||||
/* SDL_PIXELFORMAT_ARGB2101010 */
|
||||
srcpixel = *((Uint32 *)(src));
|
||||
RGBA_FROM_ARGB2101010(srcpixel, srcR, srcG, srcB, srcA);
|
||||
}
|
||||
|
||||
if (flags & SDL_COPY_COLORKEY) {
|
||||
/* srcpixel isn't set for 24 bpp */
|
||||
if (srcbpp == 3) {
|
||||
|
@ -82,13 +106,15 @@ SDL_Blit_Slow(SDL_BlitInfo * info)
|
|||
continue;
|
||||
}
|
||||
}
|
||||
if (dst_fmt->Amask) {
|
||||
DISEMBLE_RGBA(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG,
|
||||
dstB, dstA);
|
||||
} else {
|
||||
DISEMBLE_RGB(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG,
|
||||
dstB);
|
||||
if (FORMAT_HAS_ALPHA(dstfmt_val)) {
|
||||
DISEMBLE_RGBA(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, dstB, dstA);
|
||||
} else if (FORMAT_HAS_NO_ALPHA(dstfmt_val)) {
|
||||
DISEMBLE_RGB(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, dstB);
|
||||
dstA = 0xFF;
|
||||
} else {
|
||||
/* SDL_PIXELFORMAT_ARGB2101010 */
|
||||
dstpixel = *((Uint32 *)(dst));
|
||||
RGBA_FROM_ARGB2101010(dstpixel, dstR, dstG, dstB, dstA);
|
||||
}
|
||||
|
||||
if (flags & SDL_COPY_MODULATE_COLOR) {
|
||||
|
@ -151,10 +177,15 @@ SDL_Blit_Slow(SDL_BlitInfo * info)
|
|||
dstA = 255;
|
||||
break;
|
||||
}
|
||||
if (dst_fmt->Amask) {
|
||||
if (FORMAT_HAS_ALPHA(dstfmt_val)) {
|
||||
ASSEMBLE_RGBA(dst, dstbpp, dst_fmt, dstR, dstG, dstB, dstA);
|
||||
} else {
|
||||
} else if (FORMAT_HAS_NO_ALPHA(dstfmt_val)) {
|
||||
ASSEMBLE_RGB(dst, dstbpp, dst_fmt, dstR, dstG, dstB);
|
||||
} else {
|
||||
/* SDL_PIXELFORMAT_ARGB2101010 */
|
||||
Uint32 pixel;
|
||||
ARGB2101010_FROM_RGBA(pixel, dstR, dstG, dstB, dstA);
|
||||
*(Uint32 *)dst = pixel;
|
||||
}
|
||||
posx += incx;
|
||||
dst += dstbpp;
|
||||
|
|
|
@ -394,6 +394,12 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc)
|
|||
break;
|
||||
}
|
||||
|
||||
if (biBitCount >= 32) { /* we shift biClrUsed by this value later. */
|
||||
SDL_SetError("Unsupported or incorrect biBitCount field");
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Create a compatible surface, note that the colors are RGB ordered */
|
||||
surface =
|
||||
SDL_CreateRGBSurface(0, biWidth, biHeight, biBitCount, Rmask, Gmask,
|
||||
|
|
|
@ -530,7 +530,7 @@ SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_displa
|
|||
}
|
||||
#endif
|
||||
/* Try the implementation-specific eglGetDisplay even if eglGetPlatformDisplay fails */
|
||||
if (_this->egl_data->egl_display == EGL_NO_DISPLAY) {
|
||||
if ((_this->egl_data->egl_display == EGL_NO_DISPLAY) && (_this->egl_data->eglGetDisplay != NULL)) {
|
||||
_this->egl_data->egl_display = _this->egl_data->eglGetDisplay(native_display);
|
||||
}
|
||||
if (_this->egl_data->egl_display == EGL_NO_DISPLAY) {
|
||||
|
|
|
@ -23,447 +23,8 @@
|
|||
#include "SDL_rect.h"
|
||||
#include "SDL_rect_c.h"
|
||||
|
||||
SDL_bool
|
||||
SDL_HasIntersection(const SDL_Rect * A, const SDL_Rect * B)
|
||||
{
|
||||
int Amin, Amax, Bmin, Bmax;
|
||||
|
||||
if (!A) {
|
||||
SDL_InvalidParamError("A");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (!B) {
|
||||
SDL_InvalidParamError("B");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
/* Special cases for empty rects */
|
||||
if (SDL_RectEmpty(A) || SDL_RectEmpty(B)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
/* Horizontal intersection */
|
||||
Amin = A->x;
|
||||
Amax = Amin + A->w;
|
||||
Bmin = B->x;
|
||||
Bmax = Bmin + B->w;
|
||||
if (Bmin > Amin)
|
||||
Amin = Bmin;
|
||||
if (Bmax < Amax)
|
||||
Amax = Bmax;
|
||||
if (Amax <= Amin)
|
||||
return SDL_FALSE;
|
||||
|
||||
/* Vertical intersection */
|
||||
Amin = A->y;
|
||||
Amax = Amin + A->h;
|
||||
Bmin = B->y;
|
||||
Bmax = Bmin + B->h;
|
||||
if (Bmin > Amin)
|
||||
Amin = Bmin;
|
||||
if (Bmax < Amax)
|
||||
Amax = Bmax;
|
||||
if (Amax <= Amin)
|
||||
return SDL_FALSE;
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
SDL_bool
|
||||
SDL_IntersectRect(const SDL_Rect * A, const SDL_Rect * B, SDL_Rect * result)
|
||||
{
|
||||
int Amin, Amax, Bmin, Bmax;
|
||||
|
||||
if (!A) {
|
||||
SDL_InvalidParamError("A");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (!B) {
|
||||
SDL_InvalidParamError("B");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
SDL_InvalidParamError("result");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
/* Special cases for empty rects */
|
||||
if (SDL_RectEmpty(A) || SDL_RectEmpty(B)) {
|
||||
result->w = 0;
|
||||
result->h = 0;
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
/* Horizontal intersection */
|
||||
Amin = A->x;
|
||||
Amax = Amin + A->w;
|
||||
Bmin = B->x;
|
||||
Bmax = Bmin + B->w;
|
||||
if (Bmin > Amin)
|
||||
Amin = Bmin;
|
||||
result->x = Amin;
|
||||
if (Bmax < Amax)
|
||||
Amax = Bmax;
|
||||
result->w = Amax - Amin;
|
||||
|
||||
/* Vertical intersection */
|
||||
Amin = A->y;
|
||||
Amax = Amin + A->h;
|
||||
Bmin = B->y;
|
||||
Bmax = Bmin + B->h;
|
||||
if (Bmin > Amin)
|
||||
Amin = Bmin;
|
||||
result->y = Amin;
|
||||
if (Bmax < Amax)
|
||||
Amax = Bmax;
|
||||
result->h = Amax - Amin;
|
||||
|
||||
return !SDL_RectEmpty(result);
|
||||
}
|
||||
|
||||
void
|
||||
SDL_UnionRect(const SDL_Rect * A, const SDL_Rect * B, SDL_Rect * result)
|
||||
{
|
||||
int Amin, Amax, Bmin, Bmax;
|
||||
|
||||
if (!A) {
|
||||
SDL_InvalidParamError("A");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!B) {
|
||||
SDL_InvalidParamError("B");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
SDL_InvalidParamError("result");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Special cases for empty Rects */
|
||||
if (SDL_RectEmpty(A)) {
|
||||
if (SDL_RectEmpty(B)) {
|
||||
/* A and B empty */
|
||||
return;
|
||||
} else {
|
||||
/* A empty, B not empty */
|
||||
*result = *B;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (SDL_RectEmpty(B)) {
|
||||
/* A not empty, B empty */
|
||||
*result = *A;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Horizontal union */
|
||||
Amin = A->x;
|
||||
Amax = Amin + A->w;
|
||||
Bmin = B->x;
|
||||
Bmax = Bmin + B->w;
|
||||
if (Bmin < Amin)
|
||||
Amin = Bmin;
|
||||
result->x = Amin;
|
||||
if (Bmax > Amax)
|
||||
Amax = Bmax;
|
||||
result->w = Amax - Amin;
|
||||
|
||||
/* Vertical union */
|
||||
Amin = A->y;
|
||||
Amax = Amin + A->h;
|
||||
Bmin = B->y;
|
||||
Bmax = Bmin + B->h;
|
||||
if (Bmin < Amin)
|
||||
Amin = Bmin;
|
||||
result->y = Amin;
|
||||
if (Bmax > Amax)
|
||||
Amax = Bmax;
|
||||
result->h = Amax - Amin;
|
||||
}
|
||||
|
||||
SDL_bool
|
||||
SDL_EnclosePoints(const SDL_Point * points, int count, const SDL_Rect * clip,
|
||||
SDL_Rect * result)
|
||||
{
|
||||
int minx = 0;
|
||||
int miny = 0;
|
||||
int maxx = 0;
|
||||
int maxy = 0;
|
||||
int x, y, i;
|
||||
|
||||
if (!points) {
|
||||
SDL_InvalidParamError("points");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (count < 1) {
|
||||
SDL_InvalidParamError("count");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (clip) {
|
||||
SDL_bool added = SDL_FALSE;
|
||||
const int clip_minx = clip->x;
|
||||
const int clip_miny = clip->y;
|
||||
const int clip_maxx = clip->x+clip->w-1;
|
||||
const int clip_maxy = clip->y+clip->h-1;
|
||||
|
||||
/* Special case for empty rectangle */
|
||||
if (SDL_RectEmpty(clip)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; ++i) {
|
||||
x = points[i].x;
|
||||
y = points[i].y;
|
||||
|
||||
if (x < clip_minx || x > clip_maxx ||
|
||||
y < clip_miny || y > clip_maxy) {
|
||||
continue;
|
||||
}
|
||||
if (!added) {
|
||||
/* Special case: if no result was requested, we are done */
|
||||
if (result == NULL) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
/* First point added */
|
||||
minx = maxx = x;
|
||||
miny = maxy = y;
|
||||
added = SDL_TRUE;
|
||||
continue;
|
||||
}
|
||||
if (x < minx) {
|
||||
minx = x;
|
||||
} else if (x > maxx) {
|
||||
maxx = x;
|
||||
}
|
||||
if (y < miny) {
|
||||
miny = y;
|
||||
} else if (y > maxy) {
|
||||
maxy = y;
|
||||
}
|
||||
}
|
||||
if (!added) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
} else {
|
||||
/* Special case: if no result was requested, we are done */
|
||||
if (result == NULL) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
/* No clipping, always add the first point */
|
||||
minx = maxx = points[0].x;
|
||||
miny = maxy = points[0].y;
|
||||
|
||||
for (i = 1; i < count; ++i) {
|
||||
x = points[i].x;
|
||||
y = points[i].y;
|
||||
|
||||
if (x < minx) {
|
||||
minx = x;
|
||||
} else if (x > maxx) {
|
||||
maxx = x;
|
||||
}
|
||||
if (y < miny) {
|
||||
miny = y;
|
||||
} else if (y > maxy) {
|
||||
maxy = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result) {
|
||||
result->x = minx;
|
||||
result->y = miny;
|
||||
result->w = (maxx-minx)+1;
|
||||
result->h = (maxy-miny)+1;
|
||||
}
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
/* Use the Cohen-Sutherland algorithm for line clipping */
|
||||
#define CODE_BOTTOM 1
|
||||
#define CODE_TOP 2
|
||||
#define CODE_LEFT 4
|
||||
#define CODE_RIGHT 8
|
||||
|
||||
static int
|
||||
ComputeOutCode(const SDL_Rect * rect, int x, int y)
|
||||
{
|
||||
int code = 0;
|
||||
if (y < rect->y) {
|
||||
code |= CODE_TOP;
|
||||
} else if (y >= rect->y + rect->h) {
|
||||
code |= CODE_BOTTOM;
|
||||
}
|
||||
if (x < rect->x) {
|
||||
code |= CODE_LEFT;
|
||||
} else if (x >= rect->x + rect->w) {
|
||||
code |= CODE_RIGHT;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
SDL_bool
|
||||
SDL_IntersectRectAndLine(const SDL_Rect * rect, int *X1, int *Y1, int *X2,
|
||||
int *Y2)
|
||||
{
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int x1, y1;
|
||||
int x2, y2;
|
||||
int rectx1;
|
||||
int recty1;
|
||||
int rectx2;
|
||||
int recty2;
|
||||
int outcode1, outcode2;
|
||||
|
||||
if (!rect) {
|
||||
SDL_InvalidParamError("rect");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (!X1) {
|
||||
SDL_InvalidParamError("X1");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (!Y1) {
|
||||
SDL_InvalidParamError("Y1");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (!X2) {
|
||||
SDL_InvalidParamError("X2");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (!Y2) {
|
||||
SDL_InvalidParamError("Y2");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
/* Special case for empty rect */
|
||||
if (SDL_RectEmpty(rect)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
x1 = *X1;
|
||||
y1 = *Y1;
|
||||
x2 = *X2;
|
||||
y2 = *Y2;
|
||||
rectx1 = rect->x;
|
||||
recty1 = rect->y;
|
||||
rectx2 = rect->x + rect->w - 1;
|
||||
recty2 = rect->y + rect->h - 1;
|
||||
|
||||
/* Check to see if entire line is inside rect */
|
||||
if (x1 >= rectx1 && x1 <= rectx2 && x2 >= rectx1 && x2 <= rectx2 &&
|
||||
y1 >= recty1 && y1 <= recty2 && y2 >= recty1 && y2 <= recty2) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
/* Check to see if entire line is to one side of rect */
|
||||
if ((x1 < rectx1 && x2 < rectx1) || (x1 > rectx2 && x2 > rectx2) ||
|
||||
(y1 < recty1 && y2 < recty1) || (y1 > recty2 && y2 > recty2)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (y1 == y2) {
|
||||
/* Horizontal line, easy to clip */
|
||||
if (x1 < rectx1) {
|
||||
*X1 = rectx1;
|
||||
} else if (x1 > rectx2) {
|
||||
*X1 = rectx2;
|
||||
}
|
||||
if (x2 < rectx1) {
|
||||
*X2 = rectx1;
|
||||
} else if (x2 > rectx2) {
|
||||
*X2 = rectx2;
|
||||
}
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
if (x1 == x2) {
|
||||
/* Vertical line, easy to clip */
|
||||
if (y1 < recty1) {
|
||||
*Y1 = recty1;
|
||||
} else if (y1 > recty2) {
|
||||
*Y1 = recty2;
|
||||
}
|
||||
if (y2 < recty1) {
|
||||
*Y2 = recty1;
|
||||
} else if (y2 > recty2) {
|
||||
*Y2 = recty2;
|
||||
}
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
/* More complicated Cohen-Sutherland algorithm */
|
||||
outcode1 = ComputeOutCode(rect, x1, y1);
|
||||
outcode2 = ComputeOutCode(rect, x2, y2);
|
||||
while (outcode1 || outcode2) {
|
||||
if (outcode1 & outcode2) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (outcode1) {
|
||||
if (outcode1 & CODE_TOP) {
|
||||
y = recty1;
|
||||
x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
|
||||
} else if (outcode1 & CODE_BOTTOM) {
|
||||
y = recty2;
|
||||
x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
|
||||
} else if (outcode1 & CODE_LEFT) {
|
||||
x = rectx1;
|
||||
y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
|
||||
} else if (outcode1 & CODE_RIGHT) {
|
||||
x = rectx2;
|
||||
y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
|
||||
}
|
||||
x1 = x;
|
||||
y1 = y;
|
||||
outcode1 = ComputeOutCode(rect, x, y);
|
||||
} else {
|
||||
if (outcode2 & CODE_TOP) {
|
||||
y = recty1;
|
||||
x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
|
||||
} else if (outcode2 & CODE_BOTTOM) {
|
||||
y = recty2;
|
||||
x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
|
||||
} else if (outcode2 & CODE_LEFT) {
|
||||
/* If this assertion ever fires, here's the static analysis that warned about it:
|
||||
http://buildbot.libsdl.org/sdl-static-analysis/sdl-macosx-static-analysis/sdl-macosx-static-analysis-1101/report-b0d01a.html#EndPath */
|
||||
SDL_assert(x2 != x1); /* if equal: division by zero. */
|
||||
x = rectx1;
|
||||
y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
|
||||
} else if (outcode2 & CODE_RIGHT) {
|
||||
/* If this assertion ever fires, here's the static analysis that warned about it:
|
||||
http://buildbot.libsdl.org/sdl-static-analysis/sdl-macosx-static-analysis/sdl-macosx-static-analysis-1101/report-39b114.html#EndPath */
|
||||
SDL_assert(x2 != x1); /* if equal: division by zero. */
|
||||
x = rectx2;
|
||||
y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
|
||||
}
|
||||
x2 = x;
|
||||
y2 = y;
|
||||
outcode2 = ComputeOutCode(rect, x, y);
|
||||
}
|
||||
}
|
||||
*X1 = x1;
|
||||
*Y1 = y1;
|
||||
*X2 = x2;
|
||||
*Y2 = y2;
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
/* There's no float version of this at the moment, because it's not a public API
|
||||
and internally we only need the int version. */
|
||||
SDL_bool
|
||||
SDL_GetSpanEnclosingRect(int width, int height,
|
||||
int numrects, const SDL_Rect * rects, SDL_Rect *span)
|
||||
|
@ -475,24 +36,16 @@ SDL_GetSpanEnclosingRect(int width, int height,
|
|||
if (width < 1) {
|
||||
SDL_InvalidParamError("width");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (height < 1) {
|
||||
} else if (height < 1) {
|
||||
SDL_InvalidParamError("height");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (!rects) {
|
||||
} else if (!rects) {
|
||||
SDL_InvalidParamError("rects");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (!span) {
|
||||
} else if (!span) {
|
||||
SDL_InvalidParamError("span");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (numrects < 1) {
|
||||
} else if (numrects < 1) {
|
||||
SDL_InvalidParamError("numrects");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
@ -527,4 +80,36 @@ SDL_GetSpanEnclosingRect(int width, int height,
|
|||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* For use with the Cohen-Sutherland algorithm for line clipping, in SDL_rect_impl.h */
|
||||
#define CODE_BOTTOM 1
|
||||
#define CODE_TOP 2
|
||||
#define CODE_LEFT 4
|
||||
#define CODE_RIGHT 8
|
||||
|
||||
/* Same code twice, for float and int versions... */
|
||||
#define RECTTYPE SDL_Rect
|
||||
#define POINTTYPE SDL_Point
|
||||
#define SCALARTYPE int
|
||||
#define COMPUTEOUTCODE ComputeOutCode
|
||||
#define SDL_HASINTERSECTION SDL_HasIntersection
|
||||
#define SDL_INTERSECTRECT SDL_IntersectRect
|
||||
#define SDL_RECTEMPTY SDL_RectEmpty
|
||||
#define SDL_UNIONRECT SDL_UnionRect
|
||||
#define SDL_ENCLOSEPOINTS SDL_EnclosePoints
|
||||
#define SDL_INTERSECTRECTANDLINE SDL_IntersectRectAndLine
|
||||
#include "SDL_rect_impl.h"
|
||||
|
||||
#define RECTTYPE SDL_FRect
|
||||
#define POINTTYPE SDL_FPoint
|
||||
#define SCALARTYPE float
|
||||
#define COMPUTEOUTCODE ComputeOutCodeF
|
||||
#define SDL_HASINTERSECTION SDL_HasIntersectionF
|
||||
#define SDL_INTERSECTRECT SDL_IntersectFRect
|
||||
#define SDL_RECTEMPTY SDL_FRectEmpty
|
||||
#define SDL_UNIONRECT SDL_UnionFRect
|
||||
#define SDL_ENCLOSEPOINTS SDL_EncloseFPoints
|
||||
#define SDL_INTERSECTRECTANDLINE SDL_IntersectFRectAndLine
|
||||
#include "SDL_rect_impl.h"
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
@ -0,0 +1,444 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 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.
|
||||
*/
|
||||
|
||||
/* This file is #included twice to support int and float versions with the same code. */
|
||||
|
||||
SDL_bool
|
||||
SDL_HASINTERSECTION(const RECTTYPE * A, const RECTTYPE * B)
|
||||
{
|
||||
SCALARTYPE Amin, Amax, Bmin, Bmax;
|
||||
|
||||
if (!A) {
|
||||
SDL_InvalidParamError("A");
|
||||
return SDL_FALSE;
|
||||
} else if (!B) {
|
||||
SDL_InvalidParamError("B");
|
||||
return SDL_FALSE;
|
||||
} else if (SDL_RECTEMPTY(A) || SDL_RECTEMPTY(B)) {
|
||||
return SDL_FALSE; /* Special cases for empty rects */
|
||||
}
|
||||
|
||||
/* Horizontal intersection */
|
||||
Amin = A->x;
|
||||
Amax = Amin + A->w;
|
||||
Bmin = B->x;
|
||||
Bmax = Bmin + B->w;
|
||||
if (Bmin > Amin) {
|
||||
Amin = Bmin;
|
||||
}
|
||||
if (Bmax < Amax) {
|
||||
Amax = Bmax;
|
||||
}
|
||||
if (Amax <= Amin) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
/* Vertical intersection */
|
||||
Amin = A->y;
|
||||
Amax = Amin + A->h;
|
||||
Bmin = B->y;
|
||||
Bmax = Bmin + B->h;
|
||||
if (Bmin > Amin) {
|
||||
Amin = Bmin;
|
||||
}
|
||||
if (Bmax < Amax) {
|
||||
Amax = Bmax;
|
||||
}
|
||||
if (Amax <= Amin) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
SDL_bool
|
||||
SDL_INTERSECTRECT(const RECTTYPE * A, const RECTTYPE * B, RECTTYPE * result)
|
||||
{
|
||||
SCALARTYPE Amin, Amax, Bmin, Bmax;
|
||||
|
||||
if (!A) {
|
||||
SDL_InvalidParamError("A");
|
||||
return SDL_FALSE;
|
||||
} else if (!B) {
|
||||
SDL_InvalidParamError("B");
|
||||
return SDL_FALSE;
|
||||
} else if (!result) {
|
||||
SDL_InvalidParamError("result");
|
||||
return SDL_FALSE;
|
||||
} else if (SDL_RECTEMPTY(A) || SDL_RECTEMPTY(B)) { /* Special cases for empty rects */
|
||||
result->w = 0;
|
||||
result->h = 0;
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
/* Horizontal intersection */
|
||||
Amin = A->x;
|
||||
Amax = Amin + A->w;
|
||||
Bmin = B->x;
|
||||
Bmax = Bmin + B->w;
|
||||
if (Bmin > Amin) {
|
||||
Amin = Bmin;
|
||||
}
|
||||
result->x = Amin;
|
||||
if (Bmax < Amax) {
|
||||
Amax = Bmax;
|
||||
}
|
||||
result->w = Amax - Amin;
|
||||
|
||||
/* Vertical intersection */
|
||||
Amin = A->y;
|
||||
Amax = Amin + A->h;
|
||||
Bmin = B->y;
|
||||
Bmax = Bmin + B->h;
|
||||
if (Bmin > Amin) {
|
||||
Amin = Bmin;
|
||||
}
|
||||
result->y = Amin;
|
||||
if (Bmax < Amax) {
|
||||
Amax = Bmax;
|
||||
}
|
||||
result->h = Amax - Amin;
|
||||
|
||||
return !SDL_RECTEMPTY(result);
|
||||
}
|
||||
|
||||
void
|
||||
SDL_UNIONRECT(const RECTTYPE * A, const RECTTYPE * B, RECTTYPE * result)
|
||||
{
|
||||
SCALARTYPE Amin, Amax, Bmin, Bmax;
|
||||
|
||||
if (!A) {
|
||||
SDL_InvalidParamError("A");
|
||||
return;
|
||||
} else if (!B) {
|
||||
SDL_InvalidParamError("B");
|
||||
return;
|
||||
} else if (!result) {
|
||||
SDL_InvalidParamError("result");
|
||||
return;
|
||||
} else if (SDL_RECTEMPTY(A)) { /* Special cases for empty Rects */
|
||||
if (SDL_RECTEMPTY(B)) { /* A and B empty */
|
||||
SDL_zerop(result);
|
||||
} else { /* A empty, B not empty */
|
||||
*result = *B;
|
||||
}
|
||||
return;
|
||||
} else if (SDL_RECTEMPTY(B)) { /* A not empty, B empty */
|
||||
*result = *A;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Horizontal union */
|
||||
Amin = A->x;
|
||||
Amax = Amin + A->w;
|
||||
Bmin = B->x;
|
||||
Bmax = Bmin + B->w;
|
||||
if (Bmin < Amin) {
|
||||
Amin = Bmin;
|
||||
}
|
||||
result->x = Amin;
|
||||
if (Bmax > Amax) {
|
||||
Amax = Bmax;
|
||||
}
|
||||
result->w = Amax - Amin;
|
||||
|
||||
/* Vertical union */
|
||||
Amin = A->y;
|
||||
Amax = Amin + A->h;
|
||||
Bmin = B->y;
|
||||
Bmax = Bmin + B->h;
|
||||
if (Bmin < Amin) {
|
||||
Amin = Bmin;
|
||||
}
|
||||
result->y = Amin;
|
||||
if (Bmax > Amax) {
|
||||
Amax = Bmax;
|
||||
}
|
||||
result->h = Amax - Amin;
|
||||
}
|
||||
|
||||
SDL_bool SDL_ENCLOSEPOINTS(const POINTTYPE * points, int count, const RECTTYPE * clip,
|
||||
RECTTYPE * result)
|
||||
{
|
||||
SCALARTYPE minx = 0;
|
||||
SCALARTYPE miny = 0;
|
||||
SCALARTYPE maxx = 0;
|
||||
SCALARTYPE maxy = 0;
|
||||
SCALARTYPE x, y;
|
||||
int i;
|
||||
|
||||
if (!points) {
|
||||
SDL_InvalidParamError("points");
|
||||
return SDL_FALSE;
|
||||
} else if (count < 1) {
|
||||
SDL_InvalidParamError("count");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (clip) {
|
||||
SDL_bool added = SDL_FALSE;
|
||||
const SCALARTYPE clip_minx = clip->x;
|
||||
const SCALARTYPE clip_miny = clip->y;
|
||||
const SCALARTYPE clip_maxx = clip->x+clip->w-1;
|
||||
const SCALARTYPE clip_maxy = clip->y+clip->h-1;
|
||||
|
||||
/* Special case for empty rectangle */
|
||||
if (SDL_RECTEMPTY(clip)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; ++i) {
|
||||
x = points[i].x;
|
||||
y = points[i].y;
|
||||
|
||||
if (x < clip_minx || x > clip_maxx ||
|
||||
y < clip_miny || y > clip_maxy) {
|
||||
continue;
|
||||
}
|
||||
if (!added) {
|
||||
/* Special case: if no result was requested, we are done */
|
||||
if (result == NULL) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
/* First point added */
|
||||
minx = maxx = x;
|
||||
miny = maxy = y;
|
||||
added = SDL_TRUE;
|
||||
continue;
|
||||
}
|
||||
if (x < minx) {
|
||||
minx = x;
|
||||
} else if (x > maxx) {
|
||||
maxx = x;
|
||||
}
|
||||
if (y < miny) {
|
||||
miny = y;
|
||||
} else if (y > maxy) {
|
||||
maxy = y;
|
||||
}
|
||||
}
|
||||
if (!added) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
} else {
|
||||
/* Special case: if no result was requested, we are done */
|
||||
if (result == NULL) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
/* No clipping, always add the first point */
|
||||
minx = maxx = points[0].x;
|
||||
miny = maxy = points[0].y;
|
||||
|
||||
for (i = 1; i < count; ++i) {
|
||||
x = points[i].x;
|
||||
y = points[i].y;
|
||||
|
||||
if (x < minx) {
|
||||
minx = x;
|
||||
} else if (x > maxx) {
|
||||
maxx = x;
|
||||
}
|
||||
if (y < miny) {
|
||||
miny = y;
|
||||
} else if (y > maxy) {
|
||||
maxy = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result) {
|
||||
result->x = minx;
|
||||
result->y = miny;
|
||||
result->w = (maxx-minx)+1;
|
||||
result->h = (maxy-miny)+1;
|
||||
}
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
/* Use the Cohen-Sutherland algorithm for line clipping */
|
||||
static int
|
||||
COMPUTEOUTCODE(const RECTTYPE * rect, SCALARTYPE x, SCALARTYPE y)
|
||||
{
|
||||
int code = 0;
|
||||
if (y < rect->y) {
|
||||
code |= CODE_TOP;
|
||||
} else if (y >= rect->y + rect->h) {
|
||||
code |= CODE_BOTTOM;
|
||||
}
|
||||
if (x < rect->x) {
|
||||
code |= CODE_LEFT;
|
||||
} else if (x >= rect->x + rect->w) {
|
||||
code |= CODE_RIGHT;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
SDL_bool
|
||||
SDL_INTERSECTRECTANDLINE(const RECTTYPE * rect, SCALARTYPE *X1, SCALARTYPE *Y1, SCALARTYPE *X2,
|
||||
SCALARTYPE *Y2)
|
||||
{
|
||||
SCALARTYPE x = 0;
|
||||
SCALARTYPE y = 0;
|
||||
SCALARTYPE x1, y1;
|
||||
SCALARTYPE x2, y2;
|
||||
SCALARTYPE rectx1;
|
||||
SCALARTYPE recty1;
|
||||
SCALARTYPE rectx2;
|
||||
SCALARTYPE recty2;
|
||||
int outcode1, outcode2;
|
||||
|
||||
if (!rect) {
|
||||
SDL_InvalidParamError("rect");
|
||||
return SDL_FALSE;
|
||||
} else if (!X1) {
|
||||
SDL_InvalidParamError("X1");
|
||||
return SDL_FALSE;
|
||||
} else if (!Y1) {
|
||||
SDL_InvalidParamError("Y1");
|
||||
return SDL_FALSE;
|
||||
} else if (!X2) {
|
||||
SDL_InvalidParamError("X2");
|
||||
return SDL_FALSE;
|
||||
} else if (!Y2) {
|
||||
SDL_InvalidParamError("Y2");
|
||||
return SDL_FALSE;
|
||||
} else if (SDL_RECTEMPTY(rect)) {
|
||||
return SDL_FALSE; /* Special case for empty rect */
|
||||
}
|
||||
|
||||
x1 = *X1;
|
||||
y1 = *Y1;
|
||||
x2 = *X2;
|
||||
y2 = *Y2;
|
||||
rectx1 = rect->x;
|
||||
recty1 = rect->y;
|
||||
rectx2 = rect->x + rect->w - 1;
|
||||
recty2 = rect->y + rect->h - 1;
|
||||
|
||||
/* Check to see if entire line is inside rect */
|
||||
if (x1 >= rectx1 && x1 <= rectx2 && x2 >= rectx1 && x2 <= rectx2 &&
|
||||
y1 >= recty1 && y1 <= recty2 && y2 >= recty1 && y2 <= recty2) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
/* Check to see if entire line is to one side of rect */
|
||||
if ((x1 < rectx1 && x2 < rectx1) || (x1 > rectx2 && x2 > rectx2) ||
|
||||
(y1 < recty1 && y2 < recty1) || (y1 > recty2 && y2 > recty2)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (y1 == y2) { /* Horizontal line, easy to clip */
|
||||
if (x1 < rectx1) {
|
||||
*X1 = rectx1;
|
||||
} else if (x1 > rectx2) {
|
||||
*X1 = rectx2;
|
||||
}
|
||||
if (x2 < rectx1) {
|
||||
*X2 = rectx1;
|
||||
} else if (x2 > rectx2) {
|
||||
*X2 = rectx2;
|
||||
}
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
if (x1 == x2) { /* Vertical line, easy to clip */
|
||||
if (y1 < recty1) {
|
||||
*Y1 = recty1;
|
||||
} else if (y1 > recty2) {
|
||||
*Y1 = recty2;
|
||||
}
|
||||
if (y2 < recty1) {
|
||||
*Y2 = recty1;
|
||||
} else if (y2 > recty2) {
|
||||
*Y2 = recty2;
|
||||
}
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
/* More complicated Cohen-Sutherland algorithm */
|
||||
outcode1 = COMPUTEOUTCODE(rect, x1, y1);
|
||||
outcode2 = COMPUTEOUTCODE(rect, x2, y2);
|
||||
while (outcode1 || outcode2) {
|
||||
if (outcode1 & outcode2) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (outcode1) {
|
||||
if (outcode1 & CODE_TOP) {
|
||||
y = recty1;
|
||||
x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
|
||||
} else if (outcode1 & CODE_BOTTOM) {
|
||||
y = recty2;
|
||||
x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
|
||||
} else if (outcode1 & CODE_LEFT) {
|
||||
x = rectx1;
|
||||
y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
|
||||
} else if (outcode1 & CODE_RIGHT) {
|
||||
x = rectx2;
|
||||
y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
|
||||
}
|
||||
x1 = x;
|
||||
y1 = y;
|
||||
outcode1 = COMPUTEOUTCODE(rect, x, y);
|
||||
} else {
|
||||
if (outcode2 & CODE_TOP) {
|
||||
y = recty1;
|
||||
x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
|
||||
} else if (outcode2 & CODE_BOTTOM) {
|
||||
y = recty2;
|
||||
x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
|
||||
} else if (outcode2 & CODE_LEFT) {
|
||||
/* If this assertion ever fires, here's the static analysis that warned about it:
|
||||
http://buildbot.libsdl.org/sdl-static-analysis/sdl-macosx-static-analysis/sdl-macosx-static-analysis-1101/report-b0d01a.html#EndPath */
|
||||
SDL_assert(x2 != x1); /* if equal: division by zero. */
|
||||
x = rectx1;
|
||||
y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
|
||||
} else if (outcode2 & CODE_RIGHT) {
|
||||
/* If this assertion ever fires, here's the static analysis that warned about it:
|
||||
http://buildbot.libsdl.org/sdl-static-analysis/sdl-macosx-static-analysis/sdl-macosx-static-analysis-1101/report-39b114.html#EndPath */
|
||||
SDL_assert(x2 != x1); /* if equal: division by zero. */
|
||||
x = rectx2;
|
||||
y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
|
||||
}
|
||||
x2 = x;
|
||||
y2 = y;
|
||||
outcode2 = COMPUTEOUTCODE(rect, x, y);
|
||||
}
|
||||
}
|
||||
*X1 = x1;
|
||||
*Y1 = y1;
|
||||
*X2 = x2;
|
||||
*Y2 = y2;
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
#undef RECTTYPE
|
||||
#undef POINTTYPE
|
||||
#undef SCALARTYPE
|
||||
#undef COMPUTEOUTCODE
|
||||
#undef SDL_HASINTERSECTION
|
||||
#undef SDL_INTERSECTRECT
|
||||
#undef SDL_RECTEMPTY
|
||||
#undef SDL_UNIONRECT
|
||||
#undef SDL_ENCLOSEPOINTS
|
||||
#undef SDL_INTERSECTRECTANDLINE
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
@ -261,6 +261,7 @@ SDL_CreateWindowTexture(SDL_VideoDevice *_this, SDL_Window * window, Uint32 * fo
|
|||
SDL_TEXTUREACCESS_STREAMING,
|
||||
window->w, window->h);
|
||||
if (!data->texture) {
|
||||
/* codechecker_false_positive [Malloc] Static analyzer doesn't realize allocated `data` is saved to SDL_WINDOWTEXTUREDATA and not leaked here. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1184,6 +1185,7 @@ SDL_GetWindowDisplayMode(SDL_Window * window, SDL_DisplayMode * mode)
|
|||
} else if (!SDL_GetClosestDisplayModeForDisplay(SDL_GetDisplayForWindow(window),
|
||||
&fullscreen_mode,
|
||||
&fullscreen_mode)) {
|
||||
SDL_zerop(mode);
|
||||
return SDL_SetError("Couldn't find display mode match");
|
||||
}
|
||||
|
||||
|
@ -1676,6 +1678,7 @@ SDL_Window *
|
|||
SDL_CreateWindowFrom(const void *data)
|
||||
{
|
||||
SDL_Window *window;
|
||||
Uint32 flags = SDL_WINDOW_FOREIGN;
|
||||
|
||||
if (!_this) {
|
||||
SDL_UninitializedVideo();
|
||||
|
@ -1685,6 +1688,37 @@ SDL_CreateWindowFrom(const void *data)
|
|||
SDL_Unsupported();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (SDL_GetHintBoolean(SDL_HINT_VIDEO_FOREIGN_WINDOW_OPENGL, SDL_FALSE)) {
|
||||
if (!_this->GL_CreateContext) {
|
||||
SDL_SetError("OpenGL support is either not configured in SDL "
|
||||
"or not available in current SDL video driver "
|
||||
"(%s) or platform", _this->name);
|
||||
return NULL;
|
||||
}
|
||||
if (SDL_GL_LoadLibrary(NULL) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
flags |= SDL_WINDOW_OPENGL;
|
||||
}
|
||||
|
||||
if (SDL_GetHintBoolean(SDL_HINT_VIDEO_FOREIGN_WINDOW_VULKAN, SDL_FALSE)) {
|
||||
if (!_this->Vulkan_CreateSurface) {
|
||||
SDL_SetError("Vulkan support is either not configured in SDL "
|
||||
"or not available in current SDL video driver "
|
||||
"(%s) or platform", _this->name);
|
||||
return NULL;
|
||||
}
|
||||
if (flags & SDL_WINDOW_OPENGL) {
|
||||
SDL_SetError("Vulkan and OpenGL not supported on same window");
|
||||
return NULL;
|
||||
}
|
||||
if (SDL_Vulkan_LoadLibrary(NULL) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
flags |= SDL_WINDOW_VULKAN;
|
||||
}
|
||||
|
||||
window = (SDL_Window *)SDL_calloc(1, sizeof(*window));
|
||||
if (!window) {
|
||||
SDL_OutOfMemory();
|
||||
|
@ -1692,7 +1726,7 @@ SDL_CreateWindowFrom(const void *data)
|
|||
}
|
||||
window->magic = &_this->window_magic;
|
||||
window->id = _this->next_object_id++;
|
||||
window->flags = SDL_WINDOW_FOREIGN;
|
||||
window->flags = flags;
|
||||
window->last_fullscreen_flags = window->flags;
|
||||
window->is_destroying = SDL_FALSE;
|
||||
window->opacity = 1.0f;
|
||||
|
@ -1738,7 +1772,9 @@ SDL_RecreateWindow(SDL_Window * window, Uint32 flags)
|
|||
}
|
||||
|
||||
/* Restore video mode, etc. */
|
||||
SDL_HideWindow(window);
|
||||
if (!(window->flags & SDL_WINDOW_FOREIGN)) {
|
||||
SDL_HideWindow(window);
|
||||
}
|
||||
|
||||
/* Tear down the old native window */
|
||||
if (window->surface) {
|
||||
|
@ -2473,6 +2509,11 @@ SDL_CreateWindowFramebuffer(SDL_Window * window)
|
|||
attempt_texture_framebuffer = SDL_FALSE;
|
||||
}
|
||||
#endif
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
else {
|
||||
attempt_texture_framebuffer = SDL_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (attempt_texture_framebuffer) {
|
||||
if (SDL_CreateWindowTexture(_this, window, &format, &pixels, &pitch) == -1) {
|
||||
|
@ -3067,7 +3108,9 @@ SDL_DestroyWindow(SDL_Window * window)
|
|||
window->is_destroying = SDL_TRUE;
|
||||
|
||||
/* Restore video mode, etc. */
|
||||
SDL_HideWindow(window);
|
||||
if (!(window->flags & SDL_WINDOW_FOREIGN)) {
|
||||
SDL_HideWindow(window);
|
||||
}
|
||||
|
||||
/* Make sure this window no longer has focus */
|
||||
if (SDL_GetKeyboardFocus() == window) {
|
||||
|
|
|
@ -67,6 +67,7 @@ SDL_NumberOfEvents(Uint32 type)
|
|||
return SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, type, type);
|
||||
}
|
||||
|
||||
#if SDL_VIDEO_OPENGL_EGL
|
||||
static void
|
||||
android_egl_context_restore(SDL_Window *window)
|
||||
{
|
||||
|
@ -96,7 +97,7 @@ android_egl_context_backup(SDL_Window *window)
|
|||
data->backup_done = 1;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Android_ResumeSem and Android_PauseSem are signaled from Java_org_libsdl_app_SDLActivity_nativePause and Java_org_libsdl_app_SDLActivity_nativeResume
|
||||
|
@ -113,12 +114,14 @@ Android_PumpEvents_Blocking(_THIS)
|
|||
if (videodata->isPaused) {
|
||||
SDL_bool isContextExternal = SDL_IsVideoContextExternal();
|
||||
|
||||
#if SDL_VIDEO_OPENGL_EGL
|
||||
/* Make sure this is the last thing we do before pausing */
|
||||
if (!isContextExternal) {
|
||||
SDL_LockMutex(Android_ActivityMutex);
|
||||
android_egl_context_backup(Android_Window);
|
||||
SDL_UnlockMutex(Android_ActivityMutex);
|
||||
}
|
||||
#endif
|
||||
|
||||
ANDROIDAUDIO_PauseDevices();
|
||||
openslES_PauseDevices();
|
||||
|
@ -138,11 +141,13 @@ Android_PumpEvents_Blocking(_THIS)
|
|||
aaudio_ResumeDevices();
|
||||
|
||||
/* Restore the GL Context from here, as this operation is thread dependent */
|
||||
#if SDL_VIDEO_OPENGL_EGL
|
||||
if (!isContextExternal && !SDL_HasEvent(SDL_QUIT)) {
|
||||
SDL_LockMutex(Android_ActivityMutex);
|
||||
android_egl_context_restore(Android_Window);
|
||||
SDL_UnlockMutex(Android_ActivityMutex);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Make sure SW Keyboard is restored when an app becomes foreground */
|
||||
if (SDL_IsTextInputActive()) {
|
||||
|
@ -188,11 +193,13 @@ Android_PumpEvents_NonBlocking(_THIS)
|
|||
SDL_bool isContextExternal = SDL_IsVideoContextExternal();
|
||||
if (backup_context) {
|
||||
|
||||
#if SDL_VIDEO_OPENGL_EGL
|
||||
if (!isContextExternal) {
|
||||
SDL_LockMutex(Android_ActivityMutex);
|
||||
android_egl_context_backup(Android_Window);
|
||||
SDL_UnlockMutex(Android_ActivityMutex);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (videodata->pauseAudio) {
|
||||
ANDROIDAUDIO_PauseDevices();
|
||||
|
@ -219,12 +226,14 @@ Android_PumpEvents_NonBlocking(_THIS)
|
|||
aaudio_ResumeDevices();
|
||||
}
|
||||
|
||||
#if SDL_VIDEO_OPENGL_EGL
|
||||
/* Restore the GL Context from here, as this operation is thread dependent */
|
||||
if (!isContextExternal && !SDL_HasEvent(SDL_QUIT)) {
|
||||
SDL_LockMutex(Android_ActivityMutex);
|
||||
android_egl_context_restore(Android_Window);
|
||||
SDL_UnlockMutex(Android_ActivityMutex);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Make sure SW Keyboard is restored when an app becomes foreground */
|
||||
if (SDL_IsTextInputActive()) {
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_VIDEO_DRIVER_ANDROID
|
||||
#if SDL_VIDEO_DRIVER_ANDROID && SDL_VIDEO_OPENGL_EGL
|
||||
|
||||
/* Android SDL video driver implementation */
|
||||
|
||||
|
|
|
@ -122,12 +122,14 @@ Android_CreateDevice(int devindex)
|
|||
device->SetWindowTitle = Android_SetWindowTitle;
|
||||
device->SetWindowFullscreen = Android_SetWindowFullscreen;
|
||||
device->MinimizeWindow = Android_MinimizeWindow;
|
||||
device->SetWindowResizable = Android_SetWindowResizable;
|
||||
device->DestroyWindow = Android_DestroyWindow;
|
||||
device->GetWindowWMInfo = Android_GetWindowWMInfo;
|
||||
|
||||
device->free = Android_DeleteDevice;
|
||||
|
||||
/* GL pointers */
|
||||
#if SDL_VIDEO_OPENGL_EGL
|
||||
device->GL_LoadLibrary = Android_GLES_LoadLibrary;
|
||||
device->GL_GetProcAddress = Android_GLES_GetProcAddress;
|
||||
device->GL_UnloadLibrary = Android_GLES_UnloadLibrary;
|
||||
|
@ -137,6 +139,7 @@ Android_CreateDevice(int devindex)
|
|||
device->GL_GetSwapInterval = Android_GLES_GetSwapInterval;
|
||||
device->GL_SwapWindow = Android_GLES_SwapWindow;
|
||||
device->GL_DeleteContext = Android_GLES_DeleteContext;
|
||||
#endif
|
||||
|
||||
#if SDL_VIDEO_VULKAN
|
||||
device->Vulkan_LoadLibrary = Android_Vulkan_LoadLibrary;
|
||||
|
|
|
@ -81,6 +81,7 @@ Android_CreateWindow(_THIS, SDL_Window * window)
|
|||
|
||||
/* Do not create EGLSurface for Vulkan window since it will then make the window
|
||||
incompatible with vkCreateAndroidSurfaceKHR */
|
||||
#if SDL_VIDEO_OPENGL_EGL
|
||||
if ((window->flags & SDL_WINDOW_OPENGL) != 0) {
|
||||
data->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) data->native_window);
|
||||
|
||||
|
@ -91,6 +92,7 @@ Android_CreateWindow(_THIS, SDL_Window * window)
|
|||
goto endfunction;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
window->driverdata = data;
|
||||
Android_Window = window;
|
||||
|
@ -165,6 +167,12 @@ Android_MinimizeWindow(_THIS, SDL_Window *window)
|
|||
Android_JNI_MinizeWindow();
|
||||
}
|
||||
|
||||
void Android_SetWindowResizable(_THIS, SDL_Window *window, SDL_bool resizable)
|
||||
{
|
||||
/* Set orientation */
|
||||
Android_JNI_SetOrientation(window->w, window->h, window->flags & SDL_WINDOW_RESIZABLE, SDL_GetHint(SDL_HINT_ORIENTATIONS));
|
||||
}
|
||||
|
||||
void
|
||||
Android_DestroyWindow(_THIS, SDL_Window *window)
|
||||
{
|
||||
|
@ -175,9 +183,13 @@ Android_DestroyWindow(_THIS, SDL_Window *window)
|
|||
|
||||
if (window->driverdata) {
|
||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
|
||||
#if SDL_VIDEO_OPENGL_EGL
|
||||
if (data->egl_surface != EGL_NO_SURFACE) {
|
||||
SDL_EGL_DestroySurface(_this, data->egl_surface);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (data->native_window) {
|
||||
ANativeWindow_release(data->native_window);
|
||||
}
|
||||
|
@ -198,7 +210,11 @@ Android_GetWindowWMInfo(_THIS, SDL_Window *window, SDL_SysWMinfo *info)
|
|||
info->version.minor == SDL_MINOR_VERSION) {
|
||||
info->subsystem = SDL_SYSWM_ANDROID;
|
||||
info->info.android.window = data->native_window;
|
||||
|
||||
#if SDL_VIDEO_OPENGL_EGL
|
||||
info->info.android.surface = data->egl_surface;
|
||||
#endif
|
||||
|
||||
return SDL_TRUE;
|
||||
} else {
|
||||
SDL_SetError("Application not compiled with SDL %d.%d",
|
||||
|
|
|
@ -30,6 +30,7 @@ extern int Android_CreateWindow(_THIS, SDL_Window *window);
|
|||
extern void Android_SetWindowTitle(_THIS, SDL_Window *window);
|
||||
extern void Android_SetWindowFullscreen(_THIS, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen);
|
||||
extern void Android_MinimizeWindow(_THIS, SDL_Window *window);
|
||||
extern void Android_SetWindowResizable(_THIS, SDL_Window *window, SDL_bool resizable);
|
||||
|
||||
extern void Android_DestroyWindow(_THIS, SDL_Window *window);
|
||||
extern SDL_bool Android_GetWindowWMInfo(_THIS, SDL_Window *window, struct SDL_SysWMinfo *info);
|
||||
|
@ -37,8 +38,10 @@ extern SDL_Window *Android_Window;
|
|||
|
||||
typedef struct
|
||||
{
|
||||
#if SDL_VIDEO_OPENGL_EGL
|
||||
EGLSurface egl_surface;
|
||||
EGLContext egl_context; /* We use this to preserve the context when losing focus */
|
||||
#endif
|
||||
SDL_bool backup_done;
|
||||
ANativeWindow *native_window;
|
||||
|
||||
|
|
|
@ -253,7 +253,7 @@ Cocoa_WarpMouseGlobal(int x, int y)
|
|||
static void
|
||||
Cocoa_WarpMouse(SDL_Window * window, int x, int y)
|
||||
{
|
||||
Cocoa_WarpMouseGlobal(x + window->x, y + window->y);
|
||||
Cocoa_WarpMouseGlobal(window->x + x, window->y + y);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -262,9 +262,9 @@ Cocoa_SetRelativeMouseMode(SDL_bool enabled)
|
|||
/* We will re-apply the relative mode when the window gets focus, if it
|
||||
* doesn't have focus right now.
|
||||
*/
|
||||
SDL_Window *window = SDL_GetMouseFocus();
|
||||
SDL_Window *window = SDL_GetKeyboardFocus();
|
||||
if (!window) {
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We will re-apply the relative mode when the window finishes being moved,
|
||||
|
|
|
@ -2020,9 +2020,19 @@ Cocoa_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable)
|
|||
*/
|
||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
Cocoa_WindowListener *listener = data->listener;
|
||||
NSWindow *nswindow = data->nswindow;
|
||||
SDL_VideoData *videodata = ((SDL_WindowData *) window->driverdata)->videodata;
|
||||
if (![listener isInFullscreenSpace]) {
|
||||
SetWindowStyle(window, GetWindowStyle(window));
|
||||
}
|
||||
if (videodata->allow_spaces) {
|
||||
if (resizable) {
|
||||
/* resizable windows are Spaces-friendly: they get the "go fullscreen" toggle button on their titlebar. */
|
||||
[nswindow setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
|
||||
} else {
|
||||
[nswindow setCollectionBehavior:NSWindowCollectionBehaviorManaged];
|
||||
}
|
||||
}
|
||||
}}
|
||||
|
||||
void
|
||||
|
|
|
@ -220,16 +220,82 @@ sub output_copycore
|
|||
my $A_is_const_FF = shift;
|
||||
my $s = "";
|
||||
my $d = "";
|
||||
my $dst_has_alpha = ($dst =~ /A/) ? 1 : 0;
|
||||
my $src_has_alpha = ($src =~ /A/) ? 1 : 0;
|
||||
my $sa = "";
|
||||
my $da = "";
|
||||
|
||||
# Nice and easy...
|
||||
if ( $src eq $dst && !$modulate && !$blend ) {
|
||||
print FILE <<__EOF__;
|
||||
if (!$modulate && !$blend) {
|
||||
# Nice and easy...
|
||||
if ( $src eq $dst ) {
|
||||
print FILE <<__EOF__;
|
||||
*dst = *src;
|
||||
__EOF__
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
# Matching color-order
|
||||
$sa = $src;
|
||||
$sa =~ s/[A8]//g;
|
||||
$da = $dst;
|
||||
$da =~ s/[A8]//g;
|
||||
if ($sa eq $da) {
|
||||
if ($dst_has_alpha && $src_has_alpha) {
|
||||
$da = substr $dst, 0, 1;
|
||||
if ($da eq "A") {
|
||||
# RGBA -> ARGB
|
||||
print FILE <<__EOF__;
|
||||
pixel = *src;
|
||||
pixel = (pixel >> 8) | (pixel << 24);
|
||||
*dst = pixel;
|
||||
__EOF__
|
||||
} else {
|
||||
# ARGB -> RGBA -- unused
|
||||
print FILE <<__EOF__;
|
||||
pixel = *src;
|
||||
pixel = (pixel << 8) | A;
|
||||
*dst = pixel;
|
||||
__EOF__
|
||||
}
|
||||
} elsif ($dst_has_alpha) {
|
||||
$da = substr $dst, 0, 1;
|
||||
if ($da eq "A") {
|
||||
# RGB -> ARGB
|
||||
print FILE <<__EOF__;
|
||||
pixel = *src;
|
||||
pixel |= (A << 24);
|
||||
*dst = pixel;
|
||||
__EOF__
|
||||
} else {
|
||||
# RGB -> RGBA -- unused
|
||||
print FILE <<__EOF__;
|
||||
pixel = *src;
|
||||
pixel = (pixel << 8) | A;
|
||||
*dst = pixel;
|
||||
__EOF__
|
||||
}
|
||||
} else {
|
||||
$sa = substr $src, 0, 1;
|
||||
if ($sa eq "A") {
|
||||
# ARGB -> RGB
|
||||
print FILE <<__EOF__;
|
||||
pixel = *src;
|
||||
pixel &= 0xFFFFFF;
|
||||
*dst = pixel;
|
||||
__EOF__
|
||||
} else {
|
||||
# RGBA -> RGB
|
||||
print FILE <<__EOF__;
|
||||
pixel = *src;
|
||||
pixel >>= 8;
|
||||
*dst = pixel;
|
||||
__EOF__
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
my $dst_has_alpha = ($dst =~ /A/) ? 1 : 0;
|
||||
my $ignore_dst_alpha = !$dst_has_alpha && !$blend;
|
||||
|
||||
if ( $blend ) {
|
||||
|
@ -366,6 +432,14 @@ sub output_copyfunc
|
|||
my $is_modulateA_done = 0;
|
||||
my $A_is_const_FF = 0;
|
||||
|
||||
my $sa = $src;
|
||||
my $da = $dst;
|
||||
my $matching_colors = 0;
|
||||
|
||||
$sa =~ s/[A8]//g;
|
||||
$da =~ s/[A8]//g;
|
||||
$matching_colors = (!$modulate && !$blend && ($sa eq $da)) ? 1 : 0;
|
||||
|
||||
output_copyfuncname("static void", $src, $dst, $modulate, $blend, $scale, 1, "\n");
|
||||
print FILE <<__EOF__;
|
||||
{
|
||||
|
@ -424,8 +498,8 @@ __EOF__
|
|||
print FILE <<__EOF__;
|
||||
Uint32 pixel;
|
||||
__EOF__
|
||||
if (!$ignore_dst_alpha && !$src_has_alpha) {
|
||||
if ($modulate){
|
||||
if ( !$ignore_dst_alpha && !$src_has_alpha ) {
|
||||
if ( $modulate ) {
|
||||
$is_modulateA_done = 1;
|
||||
print FILE <<__EOF__;
|
||||
const Uint32 A = (flags & SDL_COPY_MODULATE_ALPHA) ? modulateA : 0xFF;
|
||||
|
@ -436,14 +510,18 @@ __EOF__
|
|||
const Uint32 A = 0xFF;
|
||||
__EOF__
|
||||
}
|
||||
print FILE <<__EOF__;
|
||||
if ( !$matching_colors ) {
|
||||
print FILE <<__EOF__;
|
||||
Uint32 R, G, B;
|
||||
__EOF__
|
||||
} elsif (!$ignore_dst_alpha) {
|
||||
print FILE <<__EOF__;
|
||||
}
|
||||
} elsif ( !$ignore_dst_alpha ) {
|
||||
if ( !$matching_colors ) {
|
||||
print FILE <<__EOF__;
|
||||
Uint32 R, G, B, A;
|
||||
__EOF__
|
||||
} else {
|
||||
}
|
||||
} elsif ( !$matching_colors ) {
|
||||
print FILE <<__EOF__;
|
||||
Uint32 R, G, B;
|
||||
__EOF__
|
||||
|
|
|
@ -52,6 +52,14 @@ enum libdecor_window_state;
|
|||
#include "xkbcommon/xkbcommon.h"
|
||||
#include "xkbcommon/xkbcommon-compose.h"
|
||||
|
||||
/* Must be included before our #defines, see Bugzilla #4957 */
|
||||
#include "wayland-client-core.h"
|
||||
|
||||
#define SDL_WAYLAND_CHECK_VERSION(x, y, z) \
|
||||
(WAYLAND_VERSION_MAJOR > x || \
|
||||
(WAYLAND_VERSION_MAJOR == x && WAYLAND_VERSION_MINOR > y) || \
|
||||
(WAYLAND_VERSION_MAJOR == x && WAYLAND_VERSION_MINOR == y && WAYLAND_VERSION_MICRO >= z))
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
|
@ -71,9 +79,6 @@ void SDL_WAYLAND_UnloadSymbols(void);
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Must be included before our #defines, see Bugzilla #4957 */
|
||||
#include "wayland-client-core.h"
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC
|
||||
|
||||
#if defined(_WAYLAND_CLIENT_H) || defined(WAYLAND_CLIENT_H)
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "xdg-shell-client-protocol.h"
|
||||
#include "keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h"
|
||||
#include "text-input-unstable-v3-client-protocol.h"
|
||||
#include "tablet-unstable-v2-client-protocol.h"
|
||||
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
#include <libdecor.h>
|
||||
|
@ -83,6 +84,7 @@ static const struct {
|
|||
{ XKB_KEY_Super_R, SDLK_RGUI },
|
||||
{ XKB_KEY_Hyper_L, SDLK_LGUI },
|
||||
{ XKB_KEY_Hyper_R, SDLK_RGUI },
|
||||
{ XKB_KEY_BackSpace, SDLK_BACKSPACE },
|
||||
};
|
||||
|
||||
struct SDL_WaylandTouchPoint {
|
||||
|
@ -815,6 +817,16 @@ keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
|
|||
return;
|
||||
}
|
||||
|
||||
#define GET_MOD_INDEX(mod) \
|
||||
WAYLAND_xkb_keymap_mod_get_index(input->xkb.keymap, XKB_MOD_NAME_##mod)
|
||||
input->xkb.idx_shift = 1 << GET_MOD_INDEX(SHIFT);
|
||||
input->xkb.idx_ctrl = 1 << GET_MOD_INDEX(CTRL);
|
||||
input->xkb.idx_alt = 1 << GET_MOD_INDEX(ALT);
|
||||
input->xkb.idx_gui = 1 << GET_MOD_INDEX(LOGO);
|
||||
input->xkb.idx_num = 1 << GET_MOD_INDEX(NUM);
|
||||
input->xkb.idx_caps = 1 << GET_MOD_INDEX(CAPS);
|
||||
#undef GET_MOD_INDEX
|
||||
|
||||
input->xkb.state = WAYLAND_xkb_state_new(input->xkb.keymap);
|
||||
if (!input->xkb.state) {
|
||||
fprintf(stderr, "failed to create XKB state\n");
|
||||
|
@ -829,10 +841,14 @@ keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
|
|||
*/
|
||||
|
||||
/* Look up the preferred locale, falling back to "C" as default */
|
||||
if (!(locale = SDL_getenv("LC_ALL")))
|
||||
if (!(locale = SDL_getenv("LC_CTYPE")))
|
||||
if (!(locale = SDL_getenv("LANG")))
|
||||
if (!(locale = SDL_getenv("LC_ALL"))) {
|
||||
if (!(locale = SDL_getenv("LC_CTYPE"))) {
|
||||
if (!(locale = SDL_getenv("LANG"))) {
|
||||
locale = "C";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Set up XKB compose table */
|
||||
input->xkb.compose_table = WAYLAND_xkb_compose_table_new_from_locale(input->display->xkb_context,
|
||||
locale, XKB_COMPOSE_COMPILE_NO_FLAGS);
|
||||
|
@ -1054,10 +1070,24 @@ keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
|
|||
{
|
||||
struct SDL_WaylandInput *input = data;
|
||||
Wayland_Keymap keymap;
|
||||
uint32_t modstate = (mods_depressed | mods_latched | mods_locked);
|
||||
|
||||
WAYLAND_xkb_state_update_mask(input->xkb.state, mods_depressed, mods_latched,
|
||||
mods_locked, 0, 0, group);
|
||||
|
||||
SDL_ToggleModState(KMOD_SHIFT, modstate & input->xkb.idx_shift);
|
||||
SDL_ToggleModState(KMOD_CTRL, modstate & input->xkb.idx_ctrl);
|
||||
SDL_ToggleModState(KMOD_ALT, modstate & input->xkb.idx_alt);
|
||||
SDL_ToggleModState(KMOD_GUI, modstate & input->xkb.idx_gui);
|
||||
SDL_ToggleModState(KMOD_NUM, modstate & input->xkb.idx_num);
|
||||
SDL_ToggleModState(KMOD_CAPS, modstate & input->xkb.idx_caps);
|
||||
|
||||
if (group == input->xkb.current_group) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* The layout changed, remap and fire an event */
|
||||
input->xkb.current_group = group;
|
||||
keymap.layout = group;
|
||||
SDL_GetDefaultKeymap(keymap.keymap);
|
||||
WAYLAND_xkb_keymap_key_for_each(input->xkb.keymap,
|
||||
|
@ -1646,6 +1676,361 @@ Wayland_add_text_input_manager(SDL_VideoData *d, uint32_t id, uint32_t version)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tablet_tool_handle_type(void* data, struct zwp_tablet_tool_v2* tool, uint32_t type)
|
||||
{
|
||||
/* unimplemented */
|
||||
}
|
||||
|
||||
static void
|
||||
tablet_tool_handle_hardware_serial(void* data, struct zwp_tablet_tool_v2* tool, uint32_t serial_hi, uint32_t serial_lo)
|
||||
{
|
||||
/* unimplemented */
|
||||
}
|
||||
|
||||
static void
|
||||
tablet_tool_handle_hardware_id_wacom(void* data, struct zwp_tablet_tool_v2* tool, uint32_t id_hi, uint32_t id_lo)
|
||||
{
|
||||
/* unimplemented */
|
||||
}
|
||||
|
||||
static void
|
||||
tablet_tool_handle_capability(void* data, struct zwp_tablet_tool_v2* tool, uint32_t capability)
|
||||
{
|
||||
/* unimplemented */
|
||||
}
|
||||
|
||||
static void
|
||||
tablet_tool_handle_done(void* data, struct zwp_tablet_tool_v2* tool)
|
||||
{
|
||||
/* unimplemented */
|
||||
}
|
||||
|
||||
static void
|
||||
tablet_tool_handle_removed(void* data, struct zwp_tablet_tool_v2* tool)
|
||||
{
|
||||
/* unimplemented */
|
||||
}
|
||||
|
||||
static void
|
||||
tablet_tool_handle_proximity_in(void* data, struct zwp_tablet_tool_v2* tool, uint32_t serial, struct zwp_tablet_v2* tablet, struct wl_surface* surface)
|
||||
{
|
||||
struct SDL_WaylandTabletInput* input = data;
|
||||
SDL_WindowData* window;
|
||||
|
||||
if (!surface) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!SDL_WAYLAND_own_surface(surface)) {
|
||||
return;
|
||||
}
|
||||
|
||||
window = (SDL_WindowData*)wl_surface_get_user_data(surface);
|
||||
|
||||
if (window) {
|
||||
input->tool_focus = window;
|
||||
input->tool_prox_serial = serial;
|
||||
|
||||
input->is_down = SDL_FALSE;
|
||||
|
||||
input->btn_stylus = SDL_FALSE;
|
||||
input->btn_stylus2 = SDL_FALSE;
|
||||
input->btn_stylus3 = SDL_FALSE;
|
||||
|
||||
SDL_SetMouseFocus(window->sdlwindow);
|
||||
SDL_SetCursor(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tablet_tool_handle_proximity_out(void* data, struct zwp_tablet_tool_v2* tool)
|
||||
{
|
||||
struct SDL_WaylandTabletInput* input = data;
|
||||
|
||||
if (input->tool_focus) {
|
||||
SDL_SetMouseFocus(NULL);
|
||||
input->tool_focus = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
tablet_tool_btn_to_sdl_button(struct SDL_WaylandTabletInput* input)
|
||||
{
|
||||
unsigned int tool_btn = input->btn_stylus3 << 2 | input->btn_stylus2 << 1 | input->btn_stylus << 0;
|
||||
switch (tool_btn) {
|
||||
case 0b000:
|
||||
return SDL_BUTTON_LEFT;
|
||||
case 0b001:
|
||||
return SDL_BUTTON_RIGHT;
|
||||
case 0b010:
|
||||
return SDL_BUTTON_MIDDLE;
|
||||
case 0b100:
|
||||
return SDL_BUTTON_X1;
|
||||
default:
|
||||
return SDL_BUTTON_LEFT;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tablet_tool_handle_down(void* data, struct zwp_tablet_tool_v2* tool, uint32_t serial)
|
||||
{
|
||||
struct SDL_WaylandTabletInput* input = data;
|
||||
SDL_WindowData* window = input->tool_focus;
|
||||
input->is_down = SDL_TRUE;
|
||||
if (!window) {
|
||||
/* tablet_tool_handle_proximity_out gets called when moving over the libdecoration csd.
|
||||
* that sets input->tool_focus (window) to NULL, but handle_{down,up} events are still
|
||||
* received. To prevent SIGSEGV this returns when this is the case.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_SendMouseButton(window->sdlwindow, 0, SDL_PRESSED, tablet_tool_btn_to_sdl_button(input));
|
||||
}
|
||||
|
||||
static void
|
||||
tablet_tool_handle_up(void* data, struct zwp_tablet_tool_v2* tool)
|
||||
{
|
||||
struct SDL_WaylandTabletInput* input = data;
|
||||
SDL_WindowData* window = input->tool_focus;
|
||||
|
||||
input->is_down = SDL_FALSE;
|
||||
|
||||
if (!window) {
|
||||
/* tablet_tool_handle_proximity_out gets called when moving over the libdecoration csd.
|
||||
* that sets input->tool_focus (window) to NULL, but handle_{down,up} events are still
|
||||
* received. To prevent SIGSEGV this returns when this is the case.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_SendMouseButton(window->sdlwindow, 0, SDL_RELEASED, tablet_tool_btn_to_sdl_button(input));
|
||||
}
|
||||
|
||||
static void
|
||||
tablet_tool_handle_motion(void* data, struct zwp_tablet_tool_v2* tool, wl_fixed_t sx_w, wl_fixed_t sy_w)
|
||||
{
|
||||
struct SDL_WaylandTabletInput* input = data;
|
||||
SDL_WindowData* window = input->tool_focus;
|
||||
|
||||
input->sx_w = sx_w;
|
||||
input->sy_w = sy_w;
|
||||
if (input->tool_focus) {
|
||||
const int sx = wl_fixed_to_int(sx_w);
|
||||
const int sy = wl_fixed_to_int(sy_w);
|
||||
SDL_SendMouseMotion(window->sdlwindow, 0, 0, sx, sy);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tablet_tool_handle_pressure(void* data, struct zwp_tablet_tool_v2* tool, uint32_t pressure)
|
||||
{
|
||||
/* unimplemented */
|
||||
}
|
||||
|
||||
static void
|
||||
tablet_tool_handle_distance(void* data, struct zwp_tablet_tool_v2* tool, uint32_t distance)
|
||||
{
|
||||
/* unimplemented */
|
||||
}
|
||||
|
||||
static void
|
||||
tablet_tool_handle_tilt(void* data, struct zwp_tablet_tool_v2* tool, wl_fixed_t xtilt, wl_fixed_t ytilt)
|
||||
{
|
||||
/* unimplemented */
|
||||
}
|
||||
|
||||
static void
|
||||
tablet_tool_handle_button(void* data, struct zwp_tablet_tool_v2* tool, uint32_t serial, uint32_t button, uint32_t state)
|
||||
{
|
||||
struct SDL_WaylandTabletInput* input = data;
|
||||
|
||||
if (input->is_down) {
|
||||
tablet_tool_handle_up(data, tool);
|
||||
input->is_down = SDL_TRUE;
|
||||
}
|
||||
|
||||
switch (button) {
|
||||
/* see %{_includedir}/linux/input-event-codes.h */
|
||||
case 0x14b: /* BTN_STYLUS */
|
||||
input->btn_stylus = state == ZWP_TABLET_PAD_V2_BUTTON_STATE_PRESSED ? SDL_TRUE : SDL_FALSE;
|
||||
break;
|
||||
case 0x14c: /* BTN_STYLUS2 */
|
||||
input->btn_stylus2 = state == ZWP_TABLET_PAD_V2_BUTTON_STATE_PRESSED ? SDL_TRUE : SDL_FALSE;
|
||||
break;
|
||||
case 0x149: /* BTN_STYLUS3 */
|
||||
input->btn_stylus3 = state == ZWP_TABLET_PAD_V2_BUTTON_STATE_PRESSED ? SDL_TRUE : SDL_FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (input->is_down) {
|
||||
tablet_tool_handle_down(data, tool, serial);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tablet_tool_handle_rotation(void* data, struct zwp_tablet_tool_v2* tool, wl_fixed_t degrees)
|
||||
{
|
||||
/* unimplemented */
|
||||
}
|
||||
|
||||
static void
|
||||
tablet_tool_handle_slider(void* data, struct zwp_tablet_tool_v2* tool, int32_t position)
|
||||
{
|
||||
/* unimplemented */
|
||||
}
|
||||
|
||||
static void
|
||||
tablet_tool_handle_wheel(void* data, struct zwp_tablet_tool_v2* tool, int32_t degrees, int32_t clicks)
|
||||
{
|
||||
/* unimplemented */
|
||||
}
|
||||
|
||||
static void
|
||||
tablet_tool_handle_frame(void* data, struct zwp_tablet_tool_v2* tool, uint32_t time)
|
||||
{
|
||||
/* unimplemented */
|
||||
}
|
||||
|
||||
|
||||
static const struct zwp_tablet_tool_v2_listener tablet_tool_listener = {
|
||||
tablet_tool_handle_type,
|
||||
tablet_tool_handle_hardware_serial,
|
||||
tablet_tool_handle_hardware_id_wacom,
|
||||
tablet_tool_handle_capability,
|
||||
tablet_tool_handle_done,
|
||||
tablet_tool_handle_removed,
|
||||
tablet_tool_handle_proximity_in,
|
||||
tablet_tool_handle_proximity_out,
|
||||
tablet_tool_handle_down,
|
||||
tablet_tool_handle_up,
|
||||
tablet_tool_handle_motion,
|
||||
tablet_tool_handle_pressure,
|
||||
tablet_tool_handle_distance,
|
||||
tablet_tool_handle_tilt,
|
||||
tablet_tool_handle_rotation,
|
||||
tablet_tool_handle_slider,
|
||||
tablet_tool_handle_wheel,
|
||||
tablet_tool_handle_button,
|
||||
tablet_tool_handle_frame
|
||||
};
|
||||
|
||||
struct SDL_WaylandTabletObjectListNode*
|
||||
tablet_object_list_new_node(void* object)
|
||||
{
|
||||
struct SDL_WaylandTabletObjectListNode* node;
|
||||
|
||||
node = SDL_calloc(1, sizeof *node);
|
||||
if (node == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
node->next = NULL;
|
||||
node->object = object;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
void tablet_object_list_append(struct SDL_WaylandTabletObjectListNode* head, void* object)
|
||||
{
|
||||
if (head->object == NULL) {
|
||||
head->object = object;
|
||||
return;
|
||||
}
|
||||
|
||||
while (head->next) {
|
||||
head = head->next;
|
||||
}
|
||||
|
||||
head->next = tablet_object_list_new_node(object);
|
||||
}
|
||||
|
||||
void tablet_object_list_destroy(struct SDL_WaylandTabletObjectListNode* head, void (*deleter)(void* object))
|
||||
{
|
||||
while (head) {
|
||||
struct SDL_WaylandTabletObjectListNode* next = head->next;
|
||||
if (head->object) {
|
||||
(*deleter)(head->object);
|
||||
}
|
||||
SDL_free(head);
|
||||
head = next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
tablet_seat_handle_tablet_added(void* data, struct zwp_tablet_seat_v2* seat, struct zwp_tablet_v2* tablet)
|
||||
{
|
||||
struct SDL_WaylandTabletInput* input = data;
|
||||
|
||||
tablet_object_list_append(input->tablets, tablet);
|
||||
}
|
||||
|
||||
static void
|
||||
tablet_seat_handle_tool_added(void* data, struct zwp_tablet_seat_v2* seat, struct zwp_tablet_tool_v2* tool)
|
||||
{
|
||||
struct SDL_WaylandTabletInput* input = data;
|
||||
|
||||
zwp_tablet_tool_v2_add_listener(tool, &tablet_tool_listener, data);
|
||||
zwp_tablet_tool_v2_set_user_data(tool, data);
|
||||
|
||||
tablet_object_list_append(input->tools, tool);
|
||||
}
|
||||
|
||||
static void
|
||||
tablet_seat_handle_pad_added(void* data, struct zwp_tablet_seat_v2* seat, struct zwp_tablet_pad_v2* pad)
|
||||
{
|
||||
struct SDL_WaylandTabletInput* input = data;
|
||||
|
||||
tablet_object_list_append(input->pads, pad);
|
||||
}
|
||||
|
||||
static const struct zwp_tablet_seat_v2_listener tablet_seat_listener = {
|
||||
tablet_seat_handle_tablet_added,
|
||||
tablet_seat_handle_tool_added,
|
||||
tablet_seat_handle_pad_added
|
||||
};
|
||||
|
||||
void
|
||||
Wayland_input_add_tablet(struct SDL_WaylandInput *input, struct SDL_WaylandTabletManager* tablet_manager)
|
||||
{
|
||||
struct SDL_WaylandTabletInput* tablet_input;
|
||||
|
||||
if (!tablet_manager || !input || !input->seat) {
|
||||
return;
|
||||
}
|
||||
|
||||
tablet_input = SDL_calloc(1, sizeof *tablet_input);
|
||||
if (tablet_input == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
input->tablet = tablet_input;
|
||||
|
||||
tablet_input->seat = (struct SDL_WaylandTabletSeat*)zwp_tablet_manager_v2_get_tablet_seat((struct zwp_tablet_manager_v2*)tablet_manager, input->seat);
|
||||
|
||||
tablet_input->tablets = tablet_object_list_new_node(NULL);
|
||||
tablet_input->tools = tablet_object_list_new_node(NULL);
|
||||
tablet_input->pads = tablet_object_list_new_node(NULL);
|
||||
|
||||
zwp_tablet_seat_v2_add_listener((struct zwp_tablet_seat_v2*)tablet_input->seat, &tablet_seat_listener, tablet_input);
|
||||
}
|
||||
|
||||
#define TABLET_OBJECT_LIST_DELETER(fun) (void (*)(void*))fun
|
||||
void
|
||||
Wayland_input_destroy_tablet(struct SDL_WaylandInput* input)
|
||||
{
|
||||
tablet_object_list_destroy(input->tablet->pads, TABLET_OBJECT_LIST_DELETER(zwp_tablet_pad_v2_destroy));
|
||||
tablet_object_list_destroy(input->tablet->tools, TABLET_OBJECT_LIST_DELETER(zwp_tablet_tool_v2_destroy));
|
||||
tablet_object_list_destroy(input->tablet->tablets, TABLET_OBJECT_LIST_DELETER(zwp_tablet_v2_destroy));
|
||||
|
||||
zwp_tablet_seat_v2_destroy((struct zwp_tablet_seat_v2*)input->tablet->seat);
|
||||
|
||||
SDL_free(input->tablet);
|
||||
input->tablet = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
Wayland_display_add_input(SDL_VideoData *d, uint32_t id, uint32_t version)
|
||||
{
|
||||
|
@ -1659,6 +2044,7 @@ Wayland_display_add_input(SDL_VideoData *d, uint32_t id, uint32_t version)
|
|||
input->seat = wl_registry_bind(d->registry, id, &wl_seat_interface, SDL_min(5, version));
|
||||
input->sx_w = wl_fixed_from_int(0);
|
||||
input->sy_w = wl_fixed_from_int(0);
|
||||
input->xkb.current_group = ~0;
|
||||
d->input = input;
|
||||
|
||||
if (d->data_device_manager != NULL) {
|
||||
|
@ -1671,6 +2057,10 @@ Wayland_display_add_input(SDL_VideoData *d, uint32_t id, uint32_t version)
|
|||
wl_seat_add_listener(input->seat, &seat_listener, input);
|
||||
wl_seat_set_user_data(input->seat, input);
|
||||
|
||||
if (d->tablet_manager) {
|
||||
Wayland_input_add_tablet(input, d->tablet_manager);
|
||||
}
|
||||
|
||||
WAYLAND_wl_display_flush(d->display);
|
||||
}
|
||||
|
||||
|
@ -1711,6 +2101,10 @@ void Wayland_display_destroy_input(SDL_VideoData *d)
|
|||
wl_touch_destroy(input->touch);
|
||||
}
|
||||
|
||||
if (input->tablet) {
|
||||
Wayland_input_destroy_tablet(input);
|
||||
}
|
||||
|
||||
if (input->seat)
|
||||
wl_seat_destroy(input->seat);
|
||||
|
||||
|
|
|
@ -29,6 +29,34 @@
|
|||
#include "SDL_waylanddatamanager.h"
|
||||
#include "SDL_waylandkeyboard.h"
|
||||
|
||||
struct SDL_WaylandTabletSeat;
|
||||
|
||||
struct SDL_WaylandTabletObjectListNode {
|
||||
void* object;
|
||||
struct SDL_WaylandTabletObjectListNode* next;
|
||||
};
|
||||
|
||||
struct SDL_WaylandTabletInput {
|
||||
struct SDL_WaylandTabletSeat* seat;
|
||||
|
||||
struct SDL_WaylandTabletObjectListNode* tablets;
|
||||
struct SDL_WaylandTabletObjectListNode* tools;
|
||||
struct SDL_WaylandTabletObjectListNode* pads;
|
||||
|
||||
SDL_WindowData *tool_focus;
|
||||
uint32_t tool_prox_serial;
|
||||
|
||||
/* Last motion location */
|
||||
wl_fixed_t sx_w;
|
||||
wl_fixed_t sy_w;
|
||||
|
||||
SDL_bool is_down;
|
||||
|
||||
SDL_bool btn_stylus;
|
||||
SDL_bool btn_stylus2;
|
||||
SDL_bool btn_stylus3;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
// repeat_rate in range of [1, 1000]
|
||||
int32_t repeat_rate;
|
||||
|
@ -68,6 +96,17 @@ struct SDL_WaylandInput {
|
|||
struct xkb_state *state;
|
||||
struct xkb_compose_table *compose_table;
|
||||
struct xkb_compose_state *compose_state;
|
||||
|
||||
/* Keyboard layout "group" */
|
||||
uint32_t current_group;
|
||||
|
||||
/* Modifier bitshift values */
|
||||
uint32_t idx_shift;
|
||||
uint32_t idx_ctrl;
|
||||
uint32_t idx_alt;
|
||||
uint32_t idx_gui;
|
||||
uint32_t idx_num;
|
||||
uint32_t idx_caps;
|
||||
} xkb;
|
||||
|
||||
/* information about axis events on current frame */
|
||||
|
@ -80,6 +119,8 @@ struct SDL_WaylandInput {
|
|||
} pointer_curr_axis_info;
|
||||
|
||||
SDL_WaylandKeyboardRepeat keyboard_repeat;
|
||||
|
||||
struct SDL_WaylandTabletInput* tablet;
|
||||
};
|
||||
|
||||
extern void Wayland_PumpEvents(_THIS);
|
||||
|
@ -107,6 +148,9 @@ extern void Wayland_display_destroy_relative_pointer_manager(SDL_VideoData *d);
|
|||
extern int Wayland_input_grab_keyboard(SDL_Window *window, struct SDL_WaylandInput *input);
|
||||
extern int Wayland_input_ungrab_keyboard(SDL_Window *window);
|
||||
|
||||
extern void Wayland_input_add_tablet(struct SDL_WaylandInput *input, struct SDL_WaylandTabletManager* tablet_manager);
|
||||
extern void Wayland_input_destroy_tablet(struct SDL_WaylandInput *input);
|
||||
|
||||
#endif /* SDL_waylandevents_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
@ -72,21 +72,19 @@ SDL_WAYLAND_SYM(void, wl_list_remove, (struct wl_list *))
|
|||
SDL_WAYLAND_SYM(int, wl_list_length, (const struct wl_list *))
|
||||
SDL_WAYLAND_SYM(int, wl_list_empty, (const struct wl_list *))
|
||||
SDL_WAYLAND_SYM(void, wl_list_insert_list, (struct wl_list *, struct wl_list *))
|
||||
|
||||
/* These functions are available in Wayland >= 1.4 */
|
||||
SDL_WAYLAND_MODULE(WAYLAND_CLIENT_1_4)
|
||||
SDL_WAYLAND_SYM(struct wl_proxy *, wl_proxy_marshal_constructor, (struct wl_proxy *, uint32_t opcode, const struct wl_interface *interface, ...))
|
||||
|
||||
SDL_WAYLAND_MODULE(WAYLAND_CLIENT_1_10)
|
||||
SDL_WAYLAND_SYM(struct wl_proxy *, wl_proxy_marshal_constructor_versioned, (struct wl_proxy *proxy, uint32_t opcode, const struct wl_interface *interface, uint32_t version, ...))
|
||||
|
||||
SDL_WAYLAND_MODULE(WAYLAND_CLIENT_1_18)
|
||||
SDL_WAYLAND_SYM(void, wl_proxy_set_tag, (struct wl_proxy *, const char * const *))
|
||||
SDL_WAYLAND_SYM(const char * const *, wl_proxy_get_tag, (struct wl_proxy *))
|
||||
|
||||
SDL_WAYLAND_MODULE(WAYLAND_CLIENT_1_20)
|
||||
#if SDL_WAYLAND_CHECK_VERSION(1, 20, 0)
|
||||
/* wayland-scanner 1.20 generates code that will call these, so these are
|
||||
* non-optional when we are compiling against Wayland 1.20. We don't
|
||||
* explicitly call them ourselves, though, so if we are only compiling
|
||||
* against Wayland 1.18, they're unnecessary. */
|
||||
SDL_WAYLAND_SYM(struct wl_proxy*, wl_proxy_marshal_flags, (struct wl_proxy *proxy, uint32_t opcode, const struct wl_interface *interfac, uint32_t version, uint32_t flags, ...))
|
||||
SDL_WAYLAND_SYM(struct wl_proxy*, wl_proxy_marshal_array_flags, (struct wl_proxy *proxy, uint32_t opcode, const struct wl_interface *interface, uint32_t version, uint32_t flags, union wl_argument *args))
|
||||
#endif
|
||||
|
||||
SDL_WAYLAND_INTERFACE(wl_seat_interface)
|
||||
SDL_WAYLAND_INTERFACE(wl_surface_interface)
|
||||
|
@ -149,6 +147,8 @@ SDL_WAYLAND_SYM(int, xkb_keymap_key_get_syms_by_level, (struct xkb_keymap *,
|
|||
xkb_layout_index_t,
|
||||
const xkb_keysym_t **) )
|
||||
SDL_WAYLAND_SYM(uint32_t, xkb_keysym_to_utf32, (xkb_keysym_t) )
|
||||
SDL_WAYLAND_SYM(uint32_t, xkb_keymap_mod_get_index, (struct xkb_keymap *,
|
||||
const char *) )
|
||||
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
SDL_WAYLAND_MODULE(WAYLAND_LIBDECOR)
|
||||
|
|
|
@ -52,6 +52,8 @@
|
|||
#include "idle-inhibit-unstable-v1-client-protocol.h"
|
||||
#include "xdg-activation-v1-client-protocol.h"
|
||||
#include "text-input-unstable-v3-client-protocol.h"
|
||||
#include "tablet-unstable-v2-client-protocol.h"
|
||||
#include "xdg-output-unstable-v1-client-protocol.h"
|
||||
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
#include <libdecor.h>
|
||||
|
@ -59,6 +61,9 @@
|
|||
|
||||
#define WAYLANDVID_DRIVER_NAME "wayland"
|
||||
|
||||
static void
|
||||
display_handle_done(void *data, struct wl_output *output);
|
||||
|
||||
/* Initialization/Query functions */
|
||||
static int
|
||||
Wayland_VideoInit(_THIS);
|
||||
|
@ -133,32 +138,22 @@ static const char *SDL_WAYLAND_output_tag = "sdl-output";
|
|||
|
||||
void SDL_WAYLAND_register_surface(struct wl_surface *surface)
|
||||
{
|
||||
if (SDL_WAYLAND_HAVE_WAYLAND_CLIENT_1_18) {
|
||||
wl_proxy_set_tag((struct wl_proxy *)surface, &SDL_WAYLAND_surface_tag);
|
||||
}
|
||||
wl_proxy_set_tag((struct wl_proxy *)surface, &SDL_WAYLAND_surface_tag);
|
||||
}
|
||||
|
||||
void SDL_WAYLAND_register_output(struct wl_output *output)
|
||||
{
|
||||
if (SDL_WAYLAND_HAVE_WAYLAND_CLIENT_1_18) {
|
||||
wl_proxy_set_tag((struct wl_proxy *)output, &SDL_WAYLAND_output_tag);
|
||||
}
|
||||
wl_proxy_set_tag((struct wl_proxy *)output, &SDL_WAYLAND_output_tag);
|
||||
}
|
||||
|
||||
SDL_bool SDL_WAYLAND_own_surface(struct wl_surface *surface)
|
||||
{
|
||||
if (SDL_WAYLAND_HAVE_WAYLAND_CLIENT_1_18) {
|
||||
return wl_proxy_get_tag((struct wl_proxy *) surface) == &SDL_WAYLAND_surface_tag;
|
||||
}
|
||||
return SDL_TRUE; /* For older clients we have to assume this is us... */
|
||||
return wl_proxy_get_tag((struct wl_proxy *) surface) == &SDL_WAYLAND_surface_tag;
|
||||
}
|
||||
|
||||
SDL_bool SDL_WAYLAND_own_output(struct wl_output *output)
|
||||
{
|
||||
if (SDL_WAYLAND_HAVE_WAYLAND_CLIENT_1_18) {
|
||||
return wl_proxy_get_tag((struct wl_proxy *) output) == &SDL_WAYLAND_output_tag;
|
||||
}
|
||||
return SDL_TRUE; /* For older clients we have to assume this is us... */
|
||||
return wl_proxy_get_tag((struct wl_proxy *) output) == &SDL_WAYLAND_output_tag;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -291,6 +286,60 @@ VideoBootStrap Wayland_bootstrap = {
|
|||
Wayland_CreateDevice
|
||||
};
|
||||
|
||||
static void
|
||||
xdg_output_handle_logical_position(void *data, struct zxdg_output_v1 *xdg_output,
|
||||
int32_t x, int32_t y)
|
||||
{
|
||||
SDL_WaylandOutputData* driverdata = data;
|
||||
|
||||
driverdata->x = x;
|
||||
driverdata->y = y;
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_output_handle_logical_size(void *data, struct zxdg_output_v1 *xdg_output,
|
||||
int32_t width, int32_t height)
|
||||
{
|
||||
SDL_WaylandOutputData* driverdata = data;
|
||||
|
||||
driverdata->width = width;
|
||||
driverdata->height = height;
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_output_handle_done(void *data, struct zxdg_output_v1 *xdg_output)
|
||||
{
|
||||
SDL_WaylandOutputData* driverdata = data;
|
||||
|
||||
/*
|
||||
* xdg-output.done events are deprecated and only apply below version 3 of the protocol.
|
||||
* A wl-output.done event will be emitted in version 3 or higher.
|
||||
*/
|
||||
if (zxdg_output_v1_get_version(driverdata->xdg_output) < 3) {
|
||||
display_handle_done(data, driverdata->output);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_output_handle_name(void *data, struct zxdg_output_v1 *xdg_output,
|
||||
const char *name)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_output_handle_description(void *data, struct zxdg_output_v1 *xdg_output,
|
||||
const char *description)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct zxdg_output_v1_listener xdg_output_listener = {
|
||||
xdg_output_handle_logical_position,
|
||||
xdg_output_handle_logical_size,
|
||||
xdg_output_handle_done,
|
||||
xdg_output_handle_name,
|
||||
xdg_output_handle_description,
|
||||
};
|
||||
|
||||
static void
|
||||
display_handle_geometry(void *data,
|
||||
struct wl_output *output,
|
||||
|
@ -307,7 +356,7 @@ display_handle_geometry(void *data,
|
|||
SDL_VideoDisplay *display;
|
||||
int i;
|
||||
|
||||
if (driverdata->done) {
|
||||
if (driverdata->wl_output_done_count) {
|
||||
/* Clear the wl_output ref so Reset doesn't free it */
|
||||
display = SDL_GetDisplay(driverdata->index);
|
||||
for (i = 0; i < display->num_display_modes; i += 1) {
|
||||
|
@ -318,11 +367,14 @@ display_handle_geometry(void *data,
|
|||
SDL_ResetDisplayModes(driverdata->index);
|
||||
|
||||
/* The display has officially started over. */
|
||||
driverdata->done = SDL_FALSE;
|
||||
driverdata->wl_output_done_count = 0;
|
||||
}
|
||||
|
||||
driverdata->x = x;
|
||||
driverdata->y = y;
|
||||
/* Apply the change from wl-output only if xdg-output is not supported */
|
||||
if (driverdata->xdg_output) {
|
||||
driverdata->x = x;
|
||||
driverdata->y = y;
|
||||
}
|
||||
driverdata->physical_width = physical_width;
|
||||
driverdata->physical_height = physical_height;
|
||||
if (driverdata->index == -1) {
|
||||
|
@ -372,9 +424,15 @@ display_handle_mode(void *data,
|
|||
SDL_DisplayMode mode;
|
||||
|
||||
if (flags & WL_OUTPUT_MODE_CURRENT) {
|
||||
/* Don't rotate this yet, handle_done will do it later */
|
||||
driverdata->width = width;
|
||||
driverdata->height = height;
|
||||
/*
|
||||
* Don't rotate this yet, wl-output coordinates are transformed in
|
||||
* handle_done and xdg-output coordinates are pre-transformed.
|
||||
*/
|
||||
if (!driverdata->xdg_output) {
|
||||
driverdata->width = width;
|
||||
driverdata->height = height;
|
||||
}
|
||||
|
||||
driverdata->refresh = refresh;
|
||||
}
|
||||
|
||||
|
@ -410,17 +468,37 @@ display_handle_done(void *data,
|
|||
SDL_DisplayMode mode;
|
||||
SDL_VideoDisplay *dpy;
|
||||
|
||||
if (driverdata->done)
|
||||
return;
|
||||
/*
|
||||
* When using xdg-output, two wl-output.done events will be emitted:
|
||||
* one at the completion of wl-display and one at the completion of xdg-output.
|
||||
*
|
||||
* All required events must be received before proceeding.
|
||||
*/
|
||||
const int event_await_count = 1 + (driverdata->xdg_output != NULL);
|
||||
|
||||
driverdata->done = SDL_TRUE;
|
||||
driverdata->wl_output_done_count = SDL_min(driverdata->wl_output_done_count + 1, event_await_count + 1);
|
||||
|
||||
if (driverdata->wl_output_done_count != event_await_count) {
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_zero(mode);
|
||||
mode.format = SDL_PIXELFORMAT_RGB888;
|
||||
if (driverdata->transform & WL_OUTPUT_TRANSFORM_90) {
|
||||
|
||||
if (driverdata->xdg_output) {
|
||||
/* xdg-output dimensions are already transformed, so no need to rotate. */
|
||||
mode.w = driverdata->width;
|
||||
mode.h = driverdata->height;
|
||||
} else if (driverdata->transform & WL_OUTPUT_TRANSFORM_90) {
|
||||
mode.w = driverdata->height / driverdata->scale_factor;
|
||||
mode.h = driverdata->width / driverdata->scale_factor;
|
||||
} else {
|
||||
mode.w = driverdata->width / driverdata->scale_factor;
|
||||
mode.h = driverdata->height / driverdata->scale_factor;
|
||||
}
|
||||
|
||||
/* Calculate the display DPI */
|
||||
if (driverdata->transform & WL_OUTPUT_TRANSFORM_90) {
|
||||
driverdata->hdpi = driverdata->physical_height ?
|
||||
(((float) driverdata->height) * 25.4f / driverdata->physical_height) :
|
||||
0.0f;
|
||||
|
@ -432,9 +510,6 @@ display_handle_done(void *data,
|
|||
((float) driverdata->physical_height) / 25.4f,
|
||||
((float) driverdata->physical_width) / 25.4f);
|
||||
} else {
|
||||
mode.w = driverdata->width / driverdata->scale_factor;
|
||||
mode.h = driverdata->height / driverdata->scale_factor;
|
||||
|
||||
driverdata->hdpi = driverdata->physical_width ?
|
||||
(((float) driverdata->width) * 25.4f / driverdata->physical_width) :
|
||||
0.0f;
|
||||
|
@ -446,6 +521,7 @@ display_handle_done(void *data,
|
|||
((float) driverdata->physical_width) / 25.4f,
|
||||
((float) driverdata->physical_height) / 25.4f);
|
||||
}
|
||||
|
||||
mode.refresh_rate = (int)SDL_round(driverdata->refresh / 1000.0); /* mHz to Hz */
|
||||
mode.driverdata = driverdata->output;
|
||||
|
||||
|
@ -509,6 +585,24 @@ Wayland_add_display(SDL_VideoData *d, uint32_t id)
|
|||
|
||||
wl_output_add_listener(output, &output_listener, data);
|
||||
SDL_WAYLAND_register_output(output);
|
||||
|
||||
/* Keep a list of outputs for deferred xdg-output initialization. */
|
||||
if (d->output_list != NULL) {
|
||||
SDL_WaylandOutputData *node = (SDL_WaylandOutputData*)d->output_list;
|
||||
|
||||
while (node->next != NULL) {
|
||||
node = (SDL_WaylandOutputData*)node->next;
|
||||
}
|
||||
|
||||
node->next = (struct SDL_WaylandOutputData*)data;
|
||||
} else {
|
||||
d->output_list = (struct SDL_WaylandOutputData*)data;
|
||||
}
|
||||
|
||||
if (data->videodata->xdg_output_manager) {
|
||||
data->xdg_output = zxdg_output_manager_v1_get_xdg_output(data->videodata->xdg_output_manager, output);
|
||||
zxdg_output_v1_add_listener(data->xdg_output, &xdg_output_listener, data);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -524,6 +618,9 @@ Wayland_free_display(uint32_t id)
|
|||
data = (SDL_WaylandOutputData *) display->driverdata;
|
||||
if (data->registry_id == id) {
|
||||
SDL_DelVideoDisplay(i);
|
||||
if (data->xdg_output) {
|
||||
zxdg_output_v1_destroy(data->xdg_output);
|
||||
}
|
||||
wl_output_destroy(data->output);
|
||||
SDL_free(data);
|
||||
|
||||
|
@ -540,6 +637,16 @@ Wayland_free_display(uint32_t id)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
Wayland_init_xdg_output(SDL_VideoData *d)
|
||||
{
|
||||
SDL_WaylandOutputData *node;
|
||||
for (node = d->output_list; node != NULL; node = node->next) {
|
||||
node->xdg_output = zxdg_output_manager_v1_get_xdg_output(node->videodata->xdg_output_manager, node->output);
|
||||
zxdg_output_v1_add_listener(node->xdg_output, &xdg_output_listener, node);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
|
||||
static void
|
||||
windowmanager_hints(void *data, struct qt_windowmanager *qt_windowmanager,
|
||||
|
@ -620,6 +727,15 @@ display_handle_global(void *data, struct wl_registry *registry, uint32_t id,
|
|||
Wayland_add_data_device_manager(d, id, version);
|
||||
} else if (SDL_strcmp(interface, "zxdg_decoration_manager_v1") == 0) {
|
||||
d->decoration_manager = wl_registry_bind(d->registry, id, &zxdg_decoration_manager_v1_interface, 1);
|
||||
} else if (SDL_strcmp(interface, "zwp_tablet_manager_v2") == 0) {
|
||||
d->tablet_manager = wl_registry_bind(d->registry, id, &zwp_tablet_manager_v2_interface, 1);
|
||||
if (d->input) {
|
||||
Wayland_input_add_tablet(d->input, d->tablet_manager);
|
||||
}
|
||||
} else if (SDL_strcmp(interface, "zxdg_output_manager_v1") == 0) {
|
||||
version = SDL_min(version, 3); /* Versions 1 through 3 are supported. */
|
||||
d->xdg_output_manager = wl_registry_bind(d->registry, id, &zxdg_output_manager_v1_interface, version);
|
||||
Wayland_init_xdg_output(d);
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
|
||||
} else if (SDL_strcmp(interface, "qt_touch_extension") == 0) {
|
||||
|
@ -737,6 +853,10 @@ Wayland_VideoQuit(_THIS)
|
|||
for (i = 0; i < _this->num_displays; ++i) {
|
||||
SDL_VideoDisplay *display = &_this->displays[i];
|
||||
|
||||
if (((SDL_WaylandOutputData*)display->driverdata)->xdg_output) {
|
||||
zxdg_output_v1_destroy(((SDL_WaylandOutputData*)display->driverdata)->xdg_output);
|
||||
}
|
||||
|
||||
wl_output_destroy(((SDL_WaylandOutputData*)display->driverdata)->output);
|
||||
SDL_free(display->driverdata);
|
||||
display->driverdata = NULL;
|
||||
|
@ -779,6 +899,9 @@ Wayland_VideoQuit(_THIS)
|
|||
Wayland_touch_destroy(data);
|
||||
#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
|
||||
|
||||
if (data->tablet_manager)
|
||||
zwp_tablet_manager_v2_destroy((struct zwp_tablet_manager_v2*)data->tablet_manager);
|
||||
|
||||
if (data->data_device_manager)
|
||||
wl_data_device_manager_destroy(data->data_device_manager);
|
||||
|
||||
|
@ -798,6 +921,10 @@ Wayland_VideoQuit(_THIS)
|
|||
}
|
||||
#endif
|
||||
|
||||
if (data->xdg_output_manager) {
|
||||
zxdg_output_manager_v1_destroy(data->xdg_output_manager);
|
||||
}
|
||||
|
||||
if (data->compositor)
|
||||
wl_compositor_destroy(data->compositor);
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
struct xkb_context;
|
||||
struct SDL_WaylandInput;
|
||||
struct SDL_WaylandTabletManager;
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
|
||||
struct SDL_WaylandTouch;
|
||||
|
@ -46,6 +47,8 @@ typedef struct {
|
|||
int size;
|
||||
} SDL_WaylandCursorTheme;
|
||||
|
||||
typedef struct SDL_WaylandOutputData SDL_WaylandOutputData;
|
||||
|
||||
typedef struct {
|
||||
SDL_bool initializing;
|
||||
struct wl_display *display;
|
||||
|
@ -70,6 +73,7 @@ typedef struct {
|
|||
struct zwp_idle_inhibit_manager_v1 *idle_inhibit_manager;
|
||||
struct xdg_activation_v1 *activation_manager;
|
||||
struct zwp_text_input_manager_v3 *text_input_manager;
|
||||
struct zxdg_output_manager_v1 *xdg_output_manager;
|
||||
|
||||
EGLDisplay edpy;
|
||||
EGLContext context;
|
||||
|
@ -77,6 +81,8 @@ typedef struct {
|
|||
|
||||
struct xkb_context *xkb_context;
|
||||
struct SDL_WaylandInput *input;
|
||||
struct SDL_WaylandTabletManager *tablet_manager;
|
||||
SDL_WaylandOutputData *output_list;
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
|
||||
struct SDL_WaylandTouch *touch;
|
||||
|
@ -89,9 +95,10 @@ typedef struct {
|
|||
int relative_mouse_mode;
|
||||
} SDL_VideoData;
|
||||
|
||||
typedef struct {
|
||||
struct SDL_WaylandOutputData {
|
||||
SDL_VideoData *videodata;
|
||||
struct wl_output *output;
|
||||
struct zxdg_output_v1 *xdg_output;
|
||||
uint32_t registry_id;
|
||||
float scale_factor;
|
||||
int x, y, width, height, refresh, transform;
|
||||
|
@ -100,8 +107,9 @@ typedef struct {
|
|||
float ddpi, hdpi, vdpi;
|
||||
int index;
|
||||
SDL_VideoDisplay placeholder;
|
||||
SDL_bool done;
|
||||
} SDL_WaylandOutputData;
|
||||
int wl_output_done_count;
|
||||
SDL_WaylandOutputData *next;
|
||||
};
|
||||
|
||||
/* Needed here to get wl_surface declaration, fixes GitHub#4594 */
|
||||
#include "SDL_waylanddyn.h"
|
||||
|
|
|
@ -1325,7 +1325,7 @@ int Wayland_CreateWindow(_THIS, SDL_Window *window)
|
|||
data->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) data->egl_window);
|
||||
|
||||
if (data->egl_surface == EGL_NO_SURFACE) {
|
||||
return SDL_SetError("failed to create an EGL window surface");
|
||||
return -1; /* SDL_EGL_CreateSurface should have set error */
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -374,7 +374,7 @@ WIN_CheckAsyncMouseRelease(SDL_WindowData *data)
|
|||
if (!(keyState & 0x8000)) {
|
||||
WIN_CheckWParamMouseButton(SDL_FALSE, mouseFlags, swapButtons, data, SDL_BUTTON_X2, 0);
|
||||
}
|
||||
data->mouse_button_flags = 0;
|
||||
data->mouse_button_flags = (WPARAM)-1;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1167,10 +1167,12 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
SDL_SendWindowEvent(data->window,
|
||||
SDL_WINDOWEVENT_MINIMIZED, 0, 0);
|
||||
break;
|
||||
default:
|
||||
case SIZE_RESTORED:
|
||||
SDL_SendWindowEvent(data->window,
|
||||
SDL_WINDOWEVENT_RESTORED, 0, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -276,27 +276,18 @@ WIN_SetTextInputRect(_THIS, SDL_Rect *rect)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef SDL_DISABLE_WINDOWS_IME
|
||||
|
||||
void WIN_ClearComposition(_THIS)
|
||||
{
|
||||
SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
|
||||
IME_ClearComposition(videodata);
|
||||
}
|
||||
|
||||
SDL_bool WIN_IsTextInputShown(_THIS)
|
||||
{
|
||||
SDL_VideoData* videodata = (SDL_VideoData*)_this->driverdata;
|
||||
return IME_IsTextInputShown(videodata);
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
WIN_ShouldShowNativeUI()
|
||||
{
|
||||
return SDL_GetHintBoolean(SDL_HINT_IME_SHOW_UI, SDL_FALSE);
|
||||
}
|
||||
|
||||
#ifdef SDL_DISABLE_WINDOWS_IME
|
||||
|
||||
|
||||
SDL_bool
|
||||
IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, SDL_VideoData *videodata)
|
||||
{
|
||||
|
@ -378,6 +369,12 @@ static void UILess_ReleaseSinks(SDL_VideoData *videodata);
|
|||
static void UILess_EnableUIUpdates(SDL_VideoData *videodata);
|
||||
static void UILess_DisableUIUpdates(SDL_VideoData *videodata);
|
||||
|
||||
static SDL_bool
|
||||
WIN_ShouldShowNativeUI()
|
||||
{
|
||||
return SDL_GetHintBoolean(SDL_HINT_IME_SHOW_UI, SDL_FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
IME_Init(SDL_VideoData *videodata, HWND hwnd)
|
||||
{
|
||||
|
@ -796,10 +793,10 @@ IME_GetCompositionString(SDL_VideoData *videodata, HIMC himc, DWORD string)
|
|||
videodata->ime_cursor = LOWORD(ImmGetCompositionStringW(himc, GCS_CURSORPOS, 0, 0));
|
||||
if ((dwLang == LANG_CHT || dwLang == LANG_CHS) &&
|
||||
videodata->ime_cursor > 0 &&
|
||||
videodata->ime_cursor < videodata->ime_composition_length / sizeof(WCHAR) &&
|
||||
videodata->ime_cursor < (int)(videodata->ime_composition_length / sizeof(WCHAR)) &&
|
||||
(videodata->ime_composition[0] == 0x3000 || videodata->ime_composition[0] == 0x0020)) {
|
||||
// Traditional Chinese IMEs add a placeholder U+3000
|
||||
// Simplified Chinese IMEs seem to add a placholder U+0020 sometimes
|
||||
// Simplified Chinese IMEs seem to add a placeholder U+0020 sometimes
|
||||
int i;
|
||||
for (i = videodata->ime_cursor + 1; i < length; ++i)
|
||||
videodata->ime_composition[i - 1] = videodata->ime_composition[i];
|
||||
|
@ -1714,6 +1711,18 @@ void IME_Present(SDL_VideoData *videodata)
|
|||
/* FIXME: Need to show the IME bitmap */
|
||||
}
|
||||
|
||||
SDL_bool WIN_IsTextInputShown(_THIS)
|
||||
{
|
||||
SDL_VideoData* videodata = (SDL_VideoData*)_this->driverdata;
|
||||
return IME_IsTextInputShown(videodata);
|
||||
}
|
||||
|
||||
void WIN_ClearComposition(_THIS)
|
||||
{
|
||||
SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
|
||||
IME_ClearComposition(videodata);
|
||||
}
|
||||
|
||||
#endif /* SDL_DISABLE_WINDOWS_IME */
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_WINDOWS */
|
||||
|
|
|
@ -175,11 +175,13 @@ WIN_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
|
|||
static SDL_Cursor *
|
||||
WIN_CreateBlankCursor()
|
||||
{
|
||||
SDL_Cursor *cursor = NULL;
|
||||
SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormat(0, 32, 32, 32, SDL_PIXELFORMAT_ARGB8888);
|
||||
if (surface) {
|
||||
return WIN_CreateCursor(surface, 0, 0);
|
||||
cursor = WIN_CreateCursor(surface, 0, 0);
|
||||
SDL_FreeSurface(surface);
|
||||
}
|
||||
return NULL;
|
||||
return cursor;
|
||||
}
|
||||
|
||||
static SDL_Cursor *
|
||||
|
@ -370,7 +372,8 @@ WIN_QuitMouse(_THIS)
|
|||
}
|
||||
|
||||
if (SDL_blank_cursor) {
|
||||
SDL_FreeCursor(SDL_blank_cursor);
|
||||
WIN_FreeCursor(SDL_blank_cursor);
|
||||
SDL_blank_cursor = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "../SDL_pixels_c.h"
|
||||
#include "../../events/SDL_keyboard_c.h"
|
||||
#include "../../events/SDL_mouse_c.h"
|
||||
#include "../../SDL_hints_c.h"
|
||||
|
||||
#include "SDL_windowsvideo.h"
|
||||
#include "SDL_windowswindow.h"
|
||||
|
@ -170,6 +171,13 @@ WIN_SetWindowPositionInternal(_THIS, SDL_Window * window, UINT flags)
|
|||
data->expected_resize = SDL_FALSE;
|
||||
}
|
||||
|
||||
static void SDLCALL
|
||||
WIN_MouseRelativeModeCenterChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
|
||||
{
|
||||
SDL_WindowData *data = (SDL_WindowData *)userdata;
|
||||
data->mouse_relative_mode_center = SDL_GetStringBoolean(hint, SDL_TRUE);
|
||||
}
|
||||
|
||||
static int
|
||||
SetupWindowData(_THIS, SDL_Window * window, HWND hwnd, HWND parent, SDL_bool created)
|
||||
{
|
||||
|
@ -188,11 +196,13 @@ SetupWindowData(_THIS, SDL_Window * window, HWND hwnd, HWND parent, SDL_bool cre
|
|||
data->hinstance = (HINSTANCE) GetWindowLongPtr(hwnd, GWLP_HINSTANCE);
|
||||
data->created = created;
|
||||
data->high_surrogate = 0;
|
||||
data->mouse_button_flags = 0;
|
||||
data->mouse_button_flags = (WPARAM)-1;
|
||||
data->last_pointer_update = (LPARAM)-1;
|
||||
data->videodata = videodata;
|
||||
data->initializing = SDL_TRUE;
|
||||
|
||||
SDL_AddHintCallback(SDL_HINT_MOUSE_RELATIVE_MODE_CENTER, WIN_MouseRelativeModeCenterChanged, data);
|
||||
|
||||
window->driverdata = data;
|
||||
|
||||
/* Associate the data with the window */
|
||||
|
@ -297,7 +307,39 @@ SetupWindowData(_THIS, SDL_Window * window, HWND hwnd, HWND parent, SDL_bool cre
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void CleanupWindowData(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
|
||||
if (data) {
|
||||
SDL_DelHintCallback(SDL_HINT_MOUSE_RELATIVE_MODE_CENTER, WIN_MouseRelativeModeCenterChanged, data);
|
||||
|
||||
if (data->keyboard_hook) {
|
||||
UnhookWindowsHookEx(data->keyboard_hook);
|
||||
}
|
||||
ReleaseDC(data->hwnd, data->hdc);
|
||||
RemoveProp(data->hwnd, TEXT("SDL_WindowData"));
|
||||
if (data->created) {
|
||||
DestroyWindow(data->hwnd);
|
||||
if (data->parent) {
|
||||
DestroyWindow(data->parent);
|
||||
}
|
||||
} else {
|
||||
/* Restore any original event handler... */
|
||||
if (data->wndproc != NULL) {
|
||||
#ifdef GWLP_WNDPROC
|
||||
SetWindowLongPtr(data->hwnd, GWLP_WNDPROC,
|
||||
(LONG_PTR) data->wndproc);
|
||||
#else
|
||||
SetWindowLong(data->hwnd, GWL_WNDPROC,
|
||||
(LONG_PTR) data->wndproc);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
SDL_free(data);
|
||||
}
|
||||
window->driverdata = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
WIN_CreateWindow(_THIS, SDL_Window * window)
|
||||
|
@ -422,6 +464,9 @@ WIN_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
|
|||
}
|
||||
}
|
||||
}
|
||||
} else if (window->flags & SDL_WINDOW_OPENGL) {
|
||||
/* Try to set up the pixel format, if it hasn't been set by the application */
|
||||
WIN_GL_SetupWindow(_this, window);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -855,15 +900,6 @@ void
|
|||
WIN_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
|
||||
{
|
||||
WIN_UpdateClipCursor(window);
|
||||
|
||||
if (window->flags & SDL_WINDOW_FULLSCREEN) {
|
||||
UINT flags = SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOSIZE;
|
||||
|
||||
if (!(window->flags & SDL_WINDOW_SHOWN)) {
|
||||
flags |= SWP_NOACTIVATE;
|
||||
}
|
||||
WIN_SetWindowPositionInternal(_this, window, flags);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -879,34 +915,7 @@ WIN_SetWindowKeyboardGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
|
|||
void
|
||||
WIN_DestroyWindow(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
|
||||
if (data) {
|
||||
if (data->keyboard_hook) {
|
||||
UnhookWindowsHookEx(data->keyboard_hook);
|
||||
}
|
||||
ReleaseDC(data->hwnd, data->hdc);
|
||||
RemoveProp(data->hwnd, TEXT("SDL_WindowData"));
|
||||
if (data->created) {
|
||||
DestroyWindow(data->hwnd);
|
||||
if (data->parent) {
|
||||
DestroyWindow(data->parent);
|
||||
}
|
||||
} else {
|
||||
/* Restore any original event handler... */
|
||||
if (data->wndproc != NULL) {
|
||||
#ifdef GWLP_WNDPROC
|
||||
SetWindowLongPtr(data->hwnd, GWLP_WNDPROC,
|
||||
(LONG_PTR) data->wndproc);
|
||||
#else
|
||||
SetWindowLong(data->hwnd, GWL_WNDPROC,
|
||||
(LONG_PTR) data->wndproc);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
SDL_free(data);
|
||||
}
|
||||
window->driverdata = NULL;
|
||||
CleanupWindowData(_this, window);
|
||||
}
|
||||
|
||||
SDL_bool
|
||||
|
@ -1038,7 +1047,7 @@ WIN_UpdateClipCursor(SDL_Window *window)
|
|||
if ((mouse->relative_mode || (window->flags & SDL_WINDOW_MOUSE_GRABBED) ||
|
||||
(window->mouse_rect.w > 0 && window->mouse_rect.h > 0)) &&
|
||||
(window->flags & SDL_WINDOW_INPUT_FOCUS)) {
|
||||
if (mouse->relative_mode && !mouse->relative_mode_warp) {
|
||||
if (mouse->relative_mode && !mouse->relative_mode_warp && data->mouse_relative_mode_center) {
|
||||
if (GetWindowRect(data->hwnd, &rect)) {
|
||||
LONG cx, cy;
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@ typedef struct
|
|||
Uint8 focus_click_pending;
|
||||
SDL_bool skip_update_clipcursor;
|
||||
Uint32 last_updated_clipcursor;
|
||||
SDL_bool mouse_relative_mode_center;
|
||||
SDL_bool windowed_mode_was_maximized;
|
||||
SDL_bool in_window_deactivation;
|
||||
RECT cursor_clipped_rect;
|
||||
|
|
|
@ -380,7 +380,7 @@ X11_GetScrollLockModifierMask(_THIS)
|
|||
return num_mask;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
X11_ReconcileKeyboardState(_THIS)
|
||||
{
|
||||
SDL_VideoData *viddata = (SDL_VideoData *) _this->driverdata;
|
||||
|
|
|
@ -27,6 +27,7 @@ extern void X11_PumpEvents(_THIS);
|
|||
extern int X11_WaitEventTimeout(_THIS, int timeout);
|
||||
extern void X11_SendWakeupEvent(_THIS, SDL_Window *window);
|
||||
extern void X11_SuspendScreenSaver(_THIS);
|
||||
extern void X11_ReconcileKeyboardState(_THIS);
|
||||
|
||||
#endif /* SDL_x11events_h_ */
|
||||
|
||||
|
|
|
@ -409,6 +409,8 @@ X11_InitKeyboard(_THIS)
|
|||
SDL_IME_Init();
|
||||
#endif
|
||||
|
||||
X11_ReconcileKeyboardState(_this);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -830,10 +830,11 @@ X11_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
|
|||
int exitcode = 0;
|
||||
close(fds[0]);
|
||||
status = X11_ShowMessageBoxImpl(messageboxdata, buttonid);
|
||||
if (write(fds[1], &status, sizeof (int)) != sizeof (int))
|
||||
if (write(fds[1], &status, sizeof (int)) != sizeof (int)) {
|
||||
exitcode = 1;
|
||||
else if (write(fds[1], buttonid, sizeof (int)) != sizeof (int))
|
||||
} else if (write(fds[1], buttonid, sizeof (int)) != sizeof (int)) {
|
||||
exitcode = 1;
|
||||
}
|
||||
close(fds[1]);
|
||||
_exit(exitcode); /* don't run atexit() stuff, static destructors, etc. */
|
||||
} else { /* we're the parent */
|
||||
|
@ -846,13 +847,12 @@ X11_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
|
|||
SDL_assert(rc == pid); /* not sure what to do if this fails. */
|
||||
|
||||
if ((rc == -1) || (!WIFEXITED(status)) || (WEXITSTATUS(status) != 0)) {
|
||||
return SDL_SetError("msgbox child process failed");
|
||||
status = SDL_SetError("msgbox child process failed");
|
||||
} else if ( (read(fds[0], &status, sizeof (int)) != sizeof (int)) ||
|
||||
(read(fds[0], buttonid, sizeof (int)) != sizeof (int)) ) {
|
||||
status = SDL_SetError("read from msgbox child process failed");
|
||||
*buttonid = 0;
|
||||
}
|
||||
|
||||
if (read(fds[0], &status, sizeof (int)) != sizeof (int))
|
||||
status = -1;
|
||||
else if (read(fds[0], buttonid, sizeof (int)) != sizeof (int))
|
||||
status = -1;
|
||||
close(fds[0]);
|
||||
|
||||
return status;
|
||||
|
|
|
@ -426,9 +426,17 @@ void SSE_FUNCTION_NAME(uint32_t width, uint32_t height,
|
|||
const int fix_read_nv12 = 0;
|
||||
#endif
|
||||
|
||||
#if YUV_FORMAT == YUV_FORMAT_422
|
||||
/* Avoid invalid read on last line */
|
||||
const int fix_read_422 = 1;
|
||||
#else
|
||||
const int fix_read_422 = 0;
|
||||
#endif
|
||||
|
||||
|
||||
if (width >= 32) {
|
||||
uint32_t xpos, ypos;
|
||||
for(ypos=0; ypos<(height-(uv_y_sample_interval-1)); ypos+=uv_y_sample_interval)
|
||||
for(ypos=0; ypos<(height-(uv_y_sample_interval-1)) - fix_read_422; ypos+=uv_y_sample_interval)
|
||||
{
|
||||
const uint8_t *y_ptr1=Y+ypos*Y_stride,
|
||||
*y_ptr2=Y+(ypos+1)*Y_stride,
|
||||
|
@ -459,6 +467,15 @@ void SSE_FUNCTION_NAME(uint32_t width, uint32_t height,
|
|||
}
|
||||
}
|
||||
|
||||
if (fix_read_422) {
|
||||
const uint8_t *y_ptr=Y+ypos*Y_stride,
|
||||
*u_ptr=U+(ypos/uv_y_sample_interval)*UV_stride,
|
||||
*v_ptr=V+(ypos/uv_y_sample_interval)*UV_stride;
|
||||
uint8_t *rgb_ptr=RGB+ypos*RGB_stride;
|
||||
STD_FUNCTION_NAME(width, 1, y_ptr, u_ptr, v_ptr, Y_stride, UV_stride, rgb_ptr, RGB_stride, yuv_type);
|
||||
ypos += uv_y_sample_interval;
|
||||
}
|
||||
|
||||
/* Catch the last line, if needed */
|
||||
if (uv_y_sample_interval == 2 && ypos == (height-1))
|
||||
{
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,220 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="xdg_output_unstable_v1">
|
||||
|
||||
<copyright>
|
||||
Copyright © 2017 Red Hat Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice (including the next
|
||||
paragraph) shall be included in all copies or substantial portions of the
|
||||
Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
</copyright>
|
||||
|
||||
<description summary="Protocol to describe output regions">
|
||||
This protocol aims at describing outputs in a way which is more in line
|
||||
with the concept of an output on desktop oriented systems.
|
||||
|
||||
Some information are more specific to the concept of an output for
|
||||
a desktop oriented system and may not make sense in other applications,
|
||||
such as IVI systems for example.
|
||||
|
||||
Typically, the global compositor space on a desktop system is made of
|
||||
a contiguous or overlapping set of rectangular regions.
|
||||
|
||||
Some of the information provided in this protocol might be identical
|
||||
to their counterparts already available from wl_output, in which case
|
||||
the information provided by this protocol should be preferred to their
|
||||
equivalent in wl_output. The goal is to move the desktop specific
|
||||
concepts (such as output location within the global compositor space,
|
||||
the connector name and types, etc.) out of the core wl_output protocol.
|
||||
|
||||
Warning! The protocol described in this file is experimental and
|
||||
backward incompatible changes may be made. Backward compatible
|
||||
changes may be added together with the corresponding interface
|
||||
version bump.
|
||||
Backward incompatible changes are done by bumping the version
|
||||
number in the protocol and interface names and resetting the
|
||||
interface version. Once the protocol is to be declared stable,
|
||||
the 'z' prefix and the version number in the protocol and
|
||||
interface names are removed and the interface version number is
|
||||
reset.
|
||||
</description>
|
||||
|
||||
<interface name="zxdg_output_manager_v1" version="3">
|
||||
<description summary="manage xdg_output objects">
|
||||
A global factory interface for xdg_output objects.
|
||||
</description>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy the xdg_output_manager object">
|
||||
Using this request a client can tell the server that it is not
|
||||
going to use the xdg_output_manager object anymore.
|
||||
|
||||
Any objects already created through this instance are not affected.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<request name="get_xdg_output">
|
||||
<description summary="create an xdg output from a wl_output">
|
||||
This creates a new xdg_output object for the given wl_output.
|
||||
</description>
|
||||
<arg name="id" type="new_id" interface="zxdg_output_v1"/>
|
||||
<arg name="output" type="object" interface="wl_output"/>
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="zxdg_output_v1" version="3">
|
||||
<description summary="compositor logical output region">
|
||||
An xdg_output describes part of the compositor geometry.
|
||||
|
||||
This typically corresponds to a monitor that displays part of the
|
||||
compositor space.
|
||||
|
||||
For objects version 3 onwards, after all xdg_output properties have been
|
||||
sent (when the object is created and when properties are updated), a
|
||||
wl_output.done event is sent. This allows changes to the output
|
||||
properties to be seen as atomic, even if they happen via multiple events.
|
||||
</description>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy the xdg_output object">
|
||||
Using this request a client can tell the server that it is not
|
||||
going to use the xdg_output object anymore.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<event name="logical_position">
|
||||
<description summary="position of the output within the global compositor space">
|
||||
The position event describes the location of the wl_output within
|
||||
the global compositor space.
|
||||
|
||||
The logical_position event is sent after creating an xdg_output
|
||||
(see xdg_output_manager.get_xdg_output) and whenever the location
|
||||
of the output changes within the global compositor space.
|
||||
</description>
|
||||
<arg name="x" type="int"
|
||||
summary="x position within the global compositor space"/>
|
||||
<arg name="y" type="int"
|
||||
summary="y position within the global compositor space"/>
|
||||
</event>
|
||||
|
||||
<event name="logical_size">
|
||||
<description summary="size of the output in the global compositor space">
|
||||
The logical_size event describes the size of the output in the
|
||||
global compositor space.
|
||||
|
||||
For example, a surface without any buffer scale, transformation
|
||||
nor rotation set, with the size matching the logical_size will
|
||||
have the same size as the corresponding output when displayed.
|
||||
|
||||
Most regular Wayland clients should not pay attention to the
|
||||
logical size and would rather rely on xdg_shell interfaces.
|
||||
|
||||
Some clients such as Xwayland, however, need this to configure
|
||||
their surfaces in the global compositor space as the compositor
|
||||
may apply a different scale from what is advertised by the output
|
||||
scaling property (to achieve fractional scaling, for example).
|
||||
|
||||
For example, for a wl_output mode 3840×2160 and a scale factor 2:
|
||||
|
||||
- A compositor not scaling the surface buffers will advertise a
|
||||
logical size of 3840×2160,
|
||||
|
||||
- A compositor automatically scaling the surface buffers will
|
||||
advertise a logical size of 1920×1080,
|
||||
|
||||
- A compositor using a fractional scale of 1.5 will advertise a
|
||||
logical size of 2560×1440.
|
||||
|
||||
For example, for a wl_output mode 1920×1080 and a 90 degree rotation,
|
||||
the compositor will advertise a logical size of 1080x1920.
|
||||
|
||||
The logical_size event is sent after creating an xdg_output
|
||||
(see xdg_output_manager.get_xdg_output) and whenever the logical
|
||||
size of the output changes, either as a result of a change in the
|
||||
applied scale or because of a change in the corresponding output
|
||||
mode(see wl_output.mode) or transform (see wl_output.transform).
|
||||
</description>
|
||||
<arg name="width" type="int"
|
||||
summary="width in global compositor space"/>
|
||||
<arg name="height" type="int"
|
||||
summary="height in global compositor space"/>
|
||||
</event>
|
||||
|
||||
<event name="done">
|
||||
<description summary="all information about the output have been sent">
|
||||
This event is sent after all other properties of an xdg_output
|
||||
have been sent.
|
||||
|
||||
This allows changes to the xdg_output properties to be seen as
|
||||
atomic, even if they happen via multiple events.
|
||||
|
||||
For objects version 3 onwards, this event is deprecated. Compositors
|
||||
are not required to send it anymore and must send wl_output.done
|
||||
instead.
|
||||
</description>
|
||||
</event>
|
||||
|
||||
<!-- Version 2 additions -->
|
||||
|
||||
<event name="name" since="2">
|
||||
<description summary="name of this output">
|
||||
Many compositors will assign names to their outputs, show them to the
|
||||
user, allow them to be configured by name, etc. The client may wish to
|
||||
know this name as well to offer the user similar behaviors.
|
||||
|
||||
The naming convention is compositor defined, but limited to
|
||||
alphanumeric characters and dashes (-). Each name is unique among all
|
||||
wl_output globals, but if a wl_output global is destroyed the same name
|
||||
may be reused later. The names will also remain consistent across
|
||||
sessions with the same hardware and software configuration.
|
||||
|
||||
Examples of names include 'HDMI-A-1', 'WL-1', 'X11-1', etc. However, do
|
||||
not assume that the name is a reflection of an underlying DRM
|
||||
connector, X11 connection, etc.
|
||||
|
||||
The name event is sent after creating an xdg_output (see
|
||||
xdg_output_manager.get_xdg_output). This event is only sent once per
|
||||
xdg_output, and the name does not change over the lifetime of the
|
||||
wl_output global.
|
||||
</description>
|
||||
<arg name="name" type="string" summary="output name"/>
|
||||
</event>
|
||||
|
||||
<event name="description" since="2">
|
||||
<description summary="human-readable description of this output">
|
||||
Many compositors can produce human-readable descriptions of their
|
||||
outputs. The client may wish to know this description as well, to
|
||||
communicate the user for various purposes.
|
||||
|
||||
The description is a UTF-8 string with no convention defined for its
|
||||
contents. Examples might include 'Foocorp 11" Display' or 'Virtual X11
|
||||
output via :1'.
|
||||
|
||||
The description event is sent after creating an xdg_output (see
|
||||
xdg_output_manager.get_xdg_output) and whenever the description
|
||||
changes. The description is optional, and may not be sent at all.
|
||||
|
||||
For objects of version 2 and lower, this event is only sent once per
|
||||
xdg_output, and the description does not change over the lifetime of
|
||||
the wl_output global.
|
||||
</description>
|
||||
<arg name="description" type="string" summary="output description"/>
|
||||
</event>
|
||||
|
||||
</interface>
|
||||
</protocol>
|
Loading…
Reference in New Issue