LIBS: updated sdl2
parent
f425c549f7
commit
ef09d67d80
|
@ -71,12 +71,12 @@ include(cmake/sdlchecks.cmake)
|
|||
# set SDL_BINARY_AGE and SDL_INTERFACE_AGE to 0.
|
||||
set(SDL_MAJOR_VERSION 2)
|
||||
set(SDL_MINOR_VERSION 0)
|
||||
set(SDL_MICRO_VERSION 21)
|
||||
set(SDL_INTERFACE_AGE 3)
|
||||
set(SDL_BINARY_AGE 21)
|
||||
set(SDL_MICRO_VERSION 22)
|
||||
set(SDL_INTERFACE_AGE 0)
|
||||
set(SDL_BINARY_AGE 22)
|
||||
set(SDL_VERSION "${SDL_MAJOR_VERSION}.${SDL_MINOR_VERSION}.${SDL_MICRO_VERSION}")
|
||||
# the following should match the versions in Xcode project file:
|
||||
set(DYLIB_CURRENT_VERSION 19.3.0)
|
||||
set(DYLIB_CURRENT_VERSION 23.0.0)
|
||||
set(DYLIB_COMPATIBILITY_VERSION 1.0.0)
|
||||
|
||||
# Calculate a libtool-like version number
|
||||
|
@ -1604,6 +1604,7 @@ elseif(WINDOWS)
|
|||
|
||||
# headers needed elsewhere
|
||||
check_include_file(tpcshrd.h HAVE_TPCSHRD_H)
|
||||
check_include_file(roapi.h HAVE_ROAPI_H)
|
||||
check_include_file(mmdeviceapi.h HAVE_MMDEVICEAPI_H)
|
||||
check_include_file(audioclient.h HAVE_AUDIOCLIENT_H)
|
||||
check_include_file(sensorsapi.h HAVE_SENSORSAPI_H)
|
||||
|
@ -2283,6 +2284,11 @@ elseif(VITA)
|
|||
${SDL2_SOURCE_DIR}/src/thread/generic/SDL_systls.c)
|
||||
set(HAVE_SDL_THREADS TRUE)
|
||||
endif()
|
||||
if(SDL_LOCALE)
|
||||
file(GLOB LOCALE_SOURCES ${SDL2_SOURCE_DIR}/src/locale/vita/*.c)
|
||||
set(SOURCE_FILES ${SOURCE_FILES} ${LOCALE_SOURCES})
|
||||
set(HAVE_SDL_LOCALE TRUE)
|
||||
endif()
|
||||
if(SDL_TIMERS)
|
||||
set(SDL_TIMER_VITA 1)
|
||||
file(GLOB TIMER_SOURCES ${SDL2_SOURCE_DIR}/src/timer/vita/*.c)
|
||||
|
@ -2309,10 +2315,10 @@ elseif(VITA)
|
|||
list(APPEND EXTRA_LIBS
|
||||
pib
|
||||
)
|
||||
set(HAVE_VITA_PIB ON)
|
||||
set(HAVE_VIDEO_VITA_PIB ON)
|
||||
set(SDL_VIDEO_VITA_PIB 1)
|
||||
else()
|
||||
set(HAVE_VITA_PIB OFF)
|
||||
set(HAVE_VIDEO_VITA_PIB OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
@ -2320,6 +2326,7 @@ elseif(VITA)
|
|||
check_include_file(gpu_es4/psp2_pvr_hint.h HAVE_PVR_H)
|
||||
if(HAVE_PVR_H)
|
||||
target_compile_definitions(sdl-build-options INTERFACE "-D__psp2__")
|
||||
check_include_file(gl4esinit.h HAVE_GL4ES_H)
|
||||
set(SDL_VIDEO_OPENGL_EGL 1)
|
||||
set(HAVE_OPENGLES TRUE)
|
||||
set(SDL_VIDEO_OPENGL_ES 1)
|
||||
|
@ -2331,10 +2338,20 @@ elseif(VITA)
|
|||
libgpu_es4_ext_stub_weak
|
||||
libIMGEGL_stub_weak
|
||||
)
|
||||
set(HAVE_VITA_PVR ON)
|
||||
|
||||
set(HAVE_VIDEO_VITA_PVR ON)
|
||||
set(SDL_VIDEO_VITA_PVR 1)
|
||||
|
||||
if(HAVE_GL4ES_H)
|
||||
set(HAVE_OPENGL TRUE)
|
||||
set(SDL_VIDEO_OPENGL 1)
|
||||
set(SDL_VIDEO_RENDER_OGL 1)
|
||||
list(APPEND EXTRA_LIBS libGL_stub)
|
||||
set(SDL_VIDEO_VITA_PVR_OGL 1)
|
||||
endif()
|
||||
|
||||
else()
|
||||
set(HAVE_VITA_PVR OFF)
|
||||
set(HAVE_VIDEO_VITA_PVR OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
@ -2346,6 +2363,7 @@ elseif(VITA)
|
|||
SceCtrl_stub
|
||||
SceAppMgr_stub
|
||||
SceAudio_stub
|
||||
SceAudioIn_stub
|
||||
SceSysmodule_stub
|
||||
SceDisplay_stub
|
||||
SceCtrl_stub
|
||||
|
|
|
@ -67,9 +67,8 @@ typedef enum
|
|||
SDL_BLENDOPERATION_ADD = 0x1, /**< dst + src: supported by all renderers */
|
||||
SDL_BLENDOPERATION_SUBTRACT = 0x2, /**< dst - src : supported by D3D9, D3D11, OpenGL, OpenGLES */
|
||||
SDL_BLENDOPERATION_REV_SUBTRACT = 0x3, /**< src - dst : supported by D3D9, D3D11, OpenGL, OpenGLES */
|
||||
SDL_BLENDOPERATION_MINIMUM = 0x4, /**< min(dst, src) : supported by D3D11 */
|
||||
SDL_BLENDOPERATION_MAXIMUM = 0x5 /**< max(dst, src) : supported by D3D11 */
|
||||
|
||||
SDL_BLENDOPERATION_MINIMUM = 0x4, /**< min(dst, src) : supported by D3D9, D3D11 */
|
||||
SDL_BLENDOPERATION_MAXIMUM = 0x5 /**< max(dst, src) : supported by D3D9, D3D11 */
|
||||
} SDL_BlendOperation;
|
||||
|
||||
/**
|
||||
|
@ -87,7 +86,6 @@ typedef enum
|
|||
SDL_BLENDFACTOR_ONE_MINUS_DST_COLOR = 0x8, /**< 1-dstR, 1-dstG, 1-dstB, 1-dstA */
|
||||
SDL_BLENDFACTOR_DST_ALPHA = 0x9, /**< dstA, dstA, dstA, dstA */
|
||||
SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA = 0xA /**< 1-dstA, 1-dstA, 1-dstA, 1-dstA */
|
||||
|
||||
} SDL_BlendFactor;
|
||||
|
||||
/**
|
||||
|
@ -135,10 +133,10 @@ typedef enum
|
|||
* SDL 2.0.6. All renderers support the four blend modes listed in the
|
||||
* SDL_BlendMode enumeration.
|
||||
*
|
||||
* - **direct3d**: Supports `SDL_BLENDOPERATION_ADD` with all factors.
|
||||
* - **direct3d11**: Supports all operations with all factors. However, some
|
||||
* - **direct3d**: Supports all operations with all factors. However, some
|
||||
* factors produce unexpected results with `SDL_BLENDOPERATION_MINIMUM` and
|
||||
* `SDL_BLENDOPERATION_MAXIMUM`.
|
||||
* - **direct3d11**: Same as Direct3D 9.
|
||||
* - **opengl**: Supports the `SDL_BLENDOPERATION_ADD` operation with all
|
||||
* factors. OpenGL versions 1.1, 1.2, and 1.3 do not work correctly with SDL
|
||||
* 2.0.6.
|
||||
|
|
|
@ -253,6 +253,7 @@
|
|||
#cmakedefine HAVE_AUDIOCLIENT_H @HAVE_AUDIOCLIENT_H@
|
||||
#cmakedefine HAVE_TPCSHRD_H @HAVE_TPCSHRD_H@
|
||||
#cmakedefine HAVE_SENSORSAPI_H @HAVE_SENSORSAPI_H@
|
||||
#cmakedefine HAVE_ROAPI_H @HAVE_ROAPI_H@
|
||||
|
||||
#cmakedefine HAVE_XINPUT_GAMEPAD_EX @HAVE_XINPUT_GAMEPAD_EX@
|
||||
#cmakedefine HAVE_XINPUT_STATE_EX @HAVE_XINPUT_STATE_EX@
|
||||
|
@ -520,6 +521,7 @@
|
|||
|
||||
#cmakedefine SDL_VIDEO_VITA_PIB @SDL_VIDEO_VITA_PIB@
|
||||
#cmakedefine SDL_VIDEO_VITA_PVR @SDL_VIDEO_VITA_PVR@
|
||||
#cmakedefine SDL_VIDEO_VITA_PVR_OGL @SDL_VIDEO_VITA_PVR_OGL@
|
||||
|
||||
#if !defined(__WIN32__) && !defined(__WINRT__)
|
||||
# if !defined(_STDINT_H_) && !defined(_STDINT_H) && !defined(HAVE_STDINT_H) && !defined(_HAVE_STDINT_H)
|
||||
|
|
|
@ -242,6 +242,7 @@
|
|||
#undef HAVE_AUDIOCLIENT_H
|
||||
#undef HAVE_TPCSHRD_H
|
||||
#undef HAVE_SENSORSAPI_H
|
||||
#undef HAVE_ROAPI_H
|
||||
|
||||
/* SDL internal assertion support */
|
||||
#undef SDL_DEFAULT_ASSERT_LEVEL
|
||||
|
|
|
@ -185,6 +185,7 @@
|
|||
/* Enable various threading systems */
|
||||
#ifdef __EMSCRIPTEN_PTHREADS__
|
||||
#define SDL_THREAD_PTHREAD 1
|
||||
#define SDL_THREAD_PTHREAD_RECURSIVE_MUTEX 1
|
||||
#endif
|
||||
|
||||
/* Enable various timer systems */
|
||||
|
|
|
@ -104,6 +104,7 @@ typedef unsigned int uintptr_t;
|
|||
#endif
|
||||
#if defined(_WIN32_MAXVER) && _WIN32_MAXVER >= 0x0602 /* Windows 8 SDK */
|
||||
#define HAVE_D3D11_H 1
|
||||
#define HAVE_ROAPI_H 1
|
||||
#endif
|
||||
#define HAVE_MMDEVICEAPI_H 1
|
||||
#define HAVE_AUDIOCLIENT_H 1
|
||||
|
|
|
@ -195,6 +195,8 @@ typedef unsigned int uintptr_t;
|
|||
#define HAVE_TRUNCF 1
|
||||
#define HAVE__FSEEKI64 1
|
||||
|
||||
#define HAVE_ROAPI_H 1
|
||||
|
||||
/* Enable various audio drivers */
|
||||
#define SDL_AUDIO_DRIVER_WASAPI 1
|
||||
#define SDL_AUDIO_DRIVER_DISK 1
|
||||
|
|
|
@ -1354,6 +1354,18 @@ extern "C" {
|
|||
*/
|
||||
#define SDL_HINT_TOUCH_MOUSE_EVENTS "SDL_TOUCH_MOUSE_EVENTS"
|
||||
|
||||
/**
|
||||
* \brief A variable controlling which touchpad should generate synthetic mouse events
|
||||
*
|
||||
* This variable can be set to the following values:
|
||||
* "0" - Only front touchpad should generate mouse events. Default
|
||||
* "1" - Only back touchpad should generate mouse events.
|
||||
* "2" - Both touchpads should generate mouse events.
|
||||
*
|
||||
* By default SDL will generate mouse events for all touch devices
|
||||
*/
|
||||
#define SDL_HINT_VITA_TOUCH_MOUSE_DEVICE "SDL_HINT_VITA_TOUCH_MOUSE_DEVICE"
|
||||
|
||||
/**
|
||||
* \brief A variable controlling whether the Android / tvOS remotes
|
||||
* should be listed as joystick devices, instead of sending keyboard events.
|
||||
|
@ -1463,6 +1475,20 @@ extern "C" {
|
|||
*/
|
||||
#define SDL_HINT_VIDEO_WAYLAND_ALLOW_LIBDECOR "SDL_VIDEO_WAYLAND_ALLOW_LIBDECOR"
|
||||
|
||||
/**
|
||||
* \brief A variable controlling whether the libdecor Wayland backend is preferred over native decrations.
|
||||
*
|
||||
* When this hint is set, libdecor will be used to provide window decorations, even if xdg-decoration is
|
||||
* available. (Note that, by default, libdecor will use xdg-decoration itself if available).
|
||||
*
|
||||
* This variable can be set to the following values:
|
||||
* "0" - libdecor is enabled only if server-side decorations are unavailable.
|
||||
* "1" - libdecor is always enabled if available.
|
||||
*
|
||||
* libdecor is used over xdg-shell when xdg-decoration protocol is unavailable.
|
||||
*/
|
||||
#define SDL_HINT_VIDEO_WAYLAND_PREFER_LIBDECOR "SDL_VIDEO_WAYLAND_PREFER_LIBDECOR"
|
||||
|
||||
/**
|
||||
* \brief A variable that is the address of another SDL_Window* (as a hex string formatted with "%p").
|
||||
*
|
||||
|
@ -1938,8 +1964,7 @@ extern "C" {
|
|||
* If not set or set to "", this hint is ignored. This hint must be set
|
||||
* before the SDL_CreateWindow() call that it is intended to affect.
|
||||
*
|
||||
* This hint is available since SDL 2.0.22. Before then, virtual devices are
|
||||
* always ignored.
|
||||
* This hint is available since SDL 2.0.22.
|
||||
*/
|
||||
#define SDL_HINT_X11_WINDOW_TYPE "SDL_X11_WINDOW_TYPE"
|
||||
|
||||
|
|
|
@ -92,6 +92,7 @@ extern DECLSPEC void *SDLCALL SDL_Metal_GetLayer(SDL_MetalView view);
|
|||
*
|
||||
* \param window SDL_Window from which the drawable size should be queried
|
||||
* \param w Pointer to variable for storing the width in pixels, may be NULL
|
||||
* \param h Pointer to variable for storing the height in pixels, may be NULL
|
||||
*
|
||||
* \since This function is available since SDL 2.0.14.
|
||||
*
|
||||
|
|
|
@ -1618,6 +1618,7 @@ extern DECLSPEC int SDLCALL SDL_RenderCopyExF(SDL_Renderer * renderer,
|
|||
* vertex array Color and alpha modulation is done per vertex
|
||||
* (SDL_SetTextureColorMod and SDL_SetTextureAlphaMod are ignored).
|
||||
*
|
||||
* \param renderer The rendering context.
|
||||
* \param texture (optional) The SDL texture to use.
|
||||
* \param vertices Vertices.
|
||||
* \param num_vertices Number of vertices.
|
||||
|
@ -1642,6 +1643,7 @@ extern DECLSPEC int SDLCALL SDL_RenderGeometry(SDL_Renderer *renderer,
|
|||
* vertex arrays Color and alpha modulation is done per vertex
|
||||
* (SDL_SetTextureColorMod and SDL_SetTextureAlphaMod are ignored).
|
||||
*
|
||||
* \param renderer The rendering context.
|
||||
* \param texture (optional) The SDL texture to use.
|
||||
* \param xy Vertex positions
|
||||
* \param xy_stride Byte size to move from one element to the next element
|
||||
|
|
|
@ -355,9 +355,9 @@ typedef uint64_t Uint64;
|
|||
#endif /* SDL_DISABLE_ANALYZE_MACROS */
|
||||
|
||||
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
|
||||
#define SDL_COMPILE_TIME_ASSERT(name, x) _Static_assert(x, #x);
|
||||
#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);
|
||||
#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]
|
||||
|
|
|
@ -59,7 +59,7 @@ typedef struct SDL_version
|
|||
*/
|
||||
#define SDL_MAJOR_VERSION 2
|
||||
#define SDL_MINOR_VERSION 0
|
||||
#define SDL_PATCHLEVEL 21
|
||||
#define SDL_PATCHLEVEL 22
|
||||
|
||||
/**
|
||||
* Macro to determine SDL version program was compiled against.
|
||||
|
|
|
@ -1337,6 +1337,7 @@ extern DECLSPEC void SDLCALL SDL_SetWindowKeyboardGrab(SDL_Window * window,
|
|||
* Mouse grab confines the mouse cursor to the window.
|
||||
*
|
||||
* \param window The window for which the mouse grab mode should be set.
|
||||
* \param grabbed This is SDL_TRUE to grab mouse, and SDL_FALSE to release.
|
||||
*
|
||||
* \since This function is available since SDL 2.0.16.
|
||||
*
|
||||
|
|
|
@ -107,7 +107,7 @@
|
|||
#ifdef __BORLANDC__
|
||||
#pragma nopackwarning
|
||||
#endif
|
||||
#ifdef _M_X64
|
||||
#ifdef _WIN64
|
||||
/* Use 8-byte alignment on 64-bit architectures, so pointers are aligned */
|
||||
#pragma pack(push,8)
|
||||
#else
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
#include "./SDL_internal.h"
|
||||
|
||||
#include "SDL.h"
|
||||
#include "./SDL_list.h"
|
||||
|
||||
/* Push */
|
||||
int
|
||||
SDL_ListAdd(SDL_ListNode **head, void *ent)
|
||||
{
|
||||
SDL_ListNode *node = SDL_malloc(sizeof (*node));
|
||||
|
||||
if (node == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
node->entry = ent;
|
||||
node->next = *head;
|
||||
*head = node;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Pop from end as a FIFO (if add with SDL_ListAdd) */
|
||||
void
|
||||
SDL_ListPop(SDL_ListNode **head, void **ent)
|
||||
{
|
||||
SDL_ListNode **ptr = head;
|
||||
|
||||
/* Invalid or empty */
|
||||
if (head == NULL || *head == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
while ((*ptr)->next) {
|
||||
ptr = &(*ptr)->next;
|
||||
}
|
||||
|
||||
if (ent) {
|
||||
*ent = (*ptr)->entry;
|
||||
}
|
||||
|
||||
SDL_free(*ptr);
|
||||
*ptr = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
SDL_ListRemove(SDL_ListNode **head, void *ent)
|
||||
{
|
||||
SDL_ListNode **ptr = head;
|
||||
|
||||
while (*ptr) {
|
||||
if ((*ptr)->entry == ent) {
|
||||
SDL_ListNode *tmp = *ptr;
|
||||
*ptr = (*ptr)->next;
|
||||
SDL_free(tmp);
|
||||
return;
|
||||
}
|
||||
ptr = &(*ptr)->next;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SDL_ListClear(SDL_ListNode **head)
|
||||
{
|
||||
SDL_ListNode *l = *head;
|
||||
*head = NULL;
|
||||
while (l) {
|
||||
SDL_ListNode *tmp = l;
|
||||
l = l->next;
|
||||
SDL_free(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef SDL_list_h_
|
||||
#define SDL_list_h_
|
||||
|
||||
typedef struct SDL_ListNode
|
||||
{
|
||||
void *entry;
|
||||
struct SDL_ListNode *next;
|
||||
} SDL_ListNode;
|
||||
|
||||
|
||||
int SDL_ListAdd(SDL_ListNode **head, void *ent);
|
||||
void SDL_ListPop(SDL_ListNode **head, void **ent);
|
||||
void SDL_ListRemove(SDL_ListNode **head, void *ent);
|
||||
void SDL_ListClear(SDL_ListNode **head);
|
||||
|
||||
#endif /* SDL_list_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
@ -80,7 +80,7 @@ SDL_ConvertStereoToMono_SSE3(SDL_AudioCVT * cvt, SDL_AudioFormat format)
|
|||
Just use unaligned load/stores, if the memory at runtime is
|
||||
aligned it'll be just as fast on modern processors */
|
||||
while (i >= 4) { /* 4 * float32 */
|
||||
_mm_storeu_ps(dst, _mm_mul_ps(_mm_hadd_ps(_mm_load_ps(src), _mm_loadu_ps(src+4)), divby2));
|
||||
_mm_storeu_ps(dst, _mm_mul_ps(_mm_hadd_ps(_mm_loadu_ps(src), _mm_loadu_ps(src+4)), divby2));
|
||||
i -= 4; src += 8; dst += 4;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ static void
|
|||
FeedAudioDevice(_THIS, const void *buf, const int buflen)
|
||||
{
|
||||
const int framelen = (SDL_AUDIO_BITSIZE(this->spec.format) / 8) * this->spec.channels;
|
||||
EM_ASM_ARGS({
|
||||
MAIN_THREAD_EM_ASM({
|
||||
var SDL2 = Module['SDL2'];
|
||||
var numChannels = SDL2.audio.currentOutputBuffer['numberOfChannels'];
|
||||
for (var c = 0; c < numChannels; ++c) {
|
||||
|
@ -101,7 +101,7 @@ HandleCaptureProcess(_THIS)
|
|||
return;
|
||||
}
|
||||
|
||||
EM_ASM_ARGS({
|
||||
MAIN_THREAD_EM_ASM({
|
||||
var SDL2 = Module['SDL2'];
|
||||
var numChannels = SDL2.capture.currentCaptureBuffer.numberOfChannels;
|
||||
for (var c = 0; c < numChannels; ++c) {
|
||||
|
@ -147,7 +147,7 @@ HandleCaptureProcess(_THIS)
|
|||
static void
|
||||
EMSCRIPTENAUDIO_CloseDevice(_THIS)
|
||||
{
|
||||
EM_ASM_({
|
||||
MAIN_THREAD_EM_ASM({
|
||||
var SDL2 = Module['SDL2'];
|
||||
if ($0) {
|
||||
if (SDL2.capture.silenceTimer !== undefined) {
|
||||
|
@ -201,7 +201,7 @@ EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname)
|
|||
/* based on parts of library_sdl.js */
|
||||
|
||||
/* create context */
|
||||
result = EM_ASM_INT({
|
||||
result = MAIN_THREAD_EM_ASM_INT({
|
||||
if(typeof(Module['SDL2']) === 'undefined') {
|
||||
Module['SDL2'] = {};
|
||||
}
|
||||
|
@ -280,7 +280,7 @@ EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname)
|
|||
feels like it's a pretty inefficient tapdance in similar ways,
|
||||
to be honest. */
|
||||
|
||||
EM_ASM_({
|
||||
MAIN_THREAD_EM_ASM({
|
||||
var SDL2 = Module['SDL2'];
|
||||
var have_microphone = function(stream) {
|
||||
//console.log('SDL audio capture: we have a microphone! Replacing silence callback.');
|
||||
|
@ -323,7 +323,7 @@ EMSCRIPTENAUDIO_OpenDevice(_THIS, const char *devname)
|
|||
}, this->spec.channels, this->spec.samples, HandleCaptureProcess, this);
|
||||
} else {
|
||||
/* setup a ScriptProcessorNode */
|
||||
EM_ASM_ARGS({
|
||||
MAIN_THREAD_EM_ASM({
|
||||
var SDL2 = Module['SDL2'];
|
||||
SDL2.audio.scriptProcessorNode = SDL2.audioContext['createScriptProcessor']($1, 0, $0);
|
||||
SDL2.audio.scriptProcessorNode['onaudioprocess'] = function (e) {
|
||||
|
@ -359,7 +359,7 @@ EMSCRIPTENAUDIO_Init(SDL_AudioDriverImpl * impl)
|
|||
impl->ProvidesOwnCallbackThread = SDL_TRUE;
|
||||
|
||||
/* check availability */
|
||||
available = EM_ASM_INT_V({
|
||||
available = MAIN_THREAD_EM_ASM_INT({
|
||||
if (typeof(AudioContext) !== 'undefined') {
|
||||
return true;
|
||||
} else if (typeof(webkitAudioContext) !== 'undefined') {
|
||||
|
@ -372,7 +372,7 @@ EMSCRIPTENAUDIO_Init(SDL_AudioDriverImpl * impl)
|
|||
SDL_SetError("No audio context available");
|
||||
}
|
||||
|
||||
capture_available = available && EM_ASM_INT_V({
|
||||
capture_available = available && MAIN_THREAD_EM_ASM_INT({
|
||||
if ((typeof(navigator.mediaDevices) !== 'undefined') && (typeof(navigator.mediaDevices.getUserMedia) !== 'undefined')) {
|
||||
return true;
|
||||
} else if (typeof(navigator.webkitGetUserMedia) !== 'undefined') {
|
||||
|
|
|
@ -37,12 +37,28 @@
|
|||
|
||||
#include <psp2/kernel/threadmgr.h>
|
||||
#include <psp2/audioout.h>
|
||||
#include <psp2/audioin.h>
|
||||
|
||||
#define SCE_AUDIO_SAMPLE_ALIGN(s) (((s) + 63) & ~63)
|
||||
#define SCE_AUDIO_MAX_VOLUME 0x8000
|
||||
|
||||
/* The tag name used by VITA audio */
|
||||
#define VITAAUD_DRIVER_NAME "vita"
|
||||
static int
|
||||
VITAAUD_OpenCaptureDevice(_THIS)
|
||||
{
|
||||
this->spec.freq = 16000;
|
||||
this->spec.samples = 512;
|
||||
this->spec.channels = 1;
|
||||
|
||||
SDL_CalculateAudioSpec(&this->spec);
|
||||
|
||||
this->hidden->port = sceAudioInOpenPort(SCE_AUDIO_IN_PORT_TYPE_VOICE , 512, 16000, SCE_AUDIO_IN_PARAM_FORMAT_S16_MONO);
|
||||
|
||||
if (this->hidden->port < 0) {
|
||||
return SDL_SetError("Couldn't open audio in port: %x", this->hidden->port);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
VITAAUD_OpenDevice(_THIS, const char *devname)
|
||||
|
@ -59,8 +75,7 @@ VITAAUD_OpenDevice(_THIS, const char *devname)
|
|||
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)) {
|
||||
if (test_format == AUDIO_S16LSB) {
|
||||
this->spec.format = test_format;
|
||||
break;
|
||||
}
|
||||
|
@ -70,13 +85,8 @@ VITAAUD_OpenDevice(_THIS, const char *devname)
|
|||
return SDL_SetError("Unsupported audio format");
|
||||
}
|
||||
|
||||
switch (this->spec.format & 0xff) {
|
||||
case 8:
|
||||
case 16:
|
||||
this->spec.format = AUDIO_S16LSB;
|
||||
break;
|
||||
default:
|
||||
return SDL_SetError("Unsupported audio format");
|
||||
if (this->iscapture) {
|
||||
return VITAAUD_OpenCaptureDevice(this);
|
||||
}
|
||||
|
||||
/* The sample count must be a multiple of 64. */
|
||||
|
@ -105,14 +115,14 @@ VITAAUD_OpenDevice(_THIS, const char *devname)
|
|||
port = SCE_AUDIO_OUT_PORT_TYPE_BGM;
|
||||
}
|
||||
|
||||
this->hidden->channel = sceAudioOutOpenPort(port, this->spec.samples, this->spec.freq, format);
|
||||
if (this->hidden->channel < 0) {
|
||||
this->hidden->port = sceAudioOutOpenPort(port, this->spec.samples, this->spec.freq, format);
|
||||
if (this->hidden->port < 0) {
|
||||
free(this->hidden->rawbuf);
|
||||
this->hidden->rawbuf = NULL;
|
||||
return SDL_SetError("Couldn't reserve hardware channel");
|
||||
return SDL_SetError("Couldn't open audio out port: %x", this->hidden->port);
|
||||
}
|
||||
|
||||
sceAudioOutSetVolume(this->hidden->channel, SCE_AUDIO_VOLUME_FLAG_L_CH|SCE_AUDIO_VOLUME_FLAG_R_CH, vols);
|
||||
sceAudioOutSetVolume(this->hidden->port, SCE_AUDIO_VOLUME_FLAG_L_CH|SCE_AUDIO_VOLUME_FLAG_R_CH, vols);
|
||||
|
||||
SDL_memset(this->hidden->rawbuf, 0, mixlen);
|
||||
for (i = 0; i < NUM_BUFFERS; i++) {
|
||||
|
@ -127,7 +137,7 @@ static void VITAAUD_PlayDevice(_THIS)
|
|||
{
|
||||
Uint8 *mixbuf = this->hidden->mixbufs[this->hidden->next_buffer];
|
||||
|
||||
sceAudioOutOutput(this->hidden->channel, mixbuf);
|
||||
sceAudioOutOutput(this->hidden->port, mixbuf);
|
||||
|
||||
this->hidden->next_buffer = (this->hidden->next_buffer + 1) % NUM_BUFFERS;
|
||||
}
|
||||
|
@ -137,6 +147,7 @@ static void VITAAUD_WaitDevice(_THIS)
|
|||
{
|
||||
/* Because we block when sending audio, there's no need for this function to do anything. */
|
||||
}
|
||||
|
||||
static Uint8 *VITAAUD_GetDeviceBuf(_THIS)
|
||||
{
|
||||
return this->hidden->mixbufs[this->hidden->next_buffer];
|
||||
|
@ -144,17 +155,32 @@ static Uint8 *VITAAUD_GetDeviceBuf(_THIS)
|
|||
|
||||
static void VITAAUD_CloseDevice(_THIS)
|
||||
{
|
||||
if (this->hidden->channel >= 0) {
|
||||
sceAudioOutReleasePort(this->hidden->channel);
|
||||
this->hidden->channel = -1;
|
||||
if (this->hidden->port >= 0) {
|
||||
if (this->iscapture) {
|
||||
sceAudioInReleasePort(this->hidden->port);
|
||||
} else {
|
||||
sceAudioOutReleasePort(this->hidden->port);
|
||||
}
|
||||
this->hidden->port = -1;
|
||||
}
|
||||
|
||||
if (this->hidden->rawbuf != NULL) {
|
||||
if (!this->iscapture && this->hidden->rawbuf != NULL) {
|
||||
free(this->hidden->rawbuf); /* this uses memalign(), not SDL_malloc(). */
|
||||
this->hidden->rawbuf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int VITAAUD_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||
{
|
||||
int ret;
|
||||
SDL_assert(buflen == this->spec.size);
|
||||
ret = sceAudioInInput(this->hidden->port, buffer);
|
||||
if (ret < 0) {
|
||||
return SDL_SetError("Failed to capture from device: %x", ret);
|
||||
}
|
||||
return this->spec.size;
|
||||
}
|
||||
|
||||
static void VITAAUD_ThreadInit(_THIS)
|
||||
{
|
||||
/* Increase the priority of this audio thread by 1 to put it
|
||||
|
@ -179,12 +205,13 @@ VITAAUD_Init(SDL_AudioDriverImpl * impl)
|
|||
impl->CloseDevice = VITAAUD_CloseDevice;
|
||||
impl->ThreadInit = VITAAUD_ThreadInit;
|
||||
|
||||
/* VITA audio device */
|
||||
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
|
||||
/*
|
||||
impl->CaptureFromDevice = VITAAUD_CaptureFromDevice;
|
||||
|
||||
/* and the capabilities */
|
||||
impl->HasCaptureSupport = SDL_TRUE;
|
||||
impl->OnlyHasDefaultInputDevice = SDL_TRUE;
|
||||
*/
|
||||
impl->OnlyHasDefaultOutputDevice = SDL_TRUE;
|
||||
impl->OnlyHasDefaultCaptureDevice = SDL_TRUE;
|
||||
|
||||
return SDL_TRUE; /* this audio target is available. */
|
||||
}
|
||||
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
#define NUM_BUFFERS 2
|
||||
|
||||
struct SDL_PrivateAudioData {
|
||||
/* The hardware output channel. */
|
||||
int channel;
|
||||
/* The hardware input/output port. */
|
||||
int port;
|
||||
/* The raw allocated mixing buffer. */
|
||||
Uint8 *rawbuf;
|
||||
/* Individual mixing buffers. */
|
||||
|
|
|
@ -339,11 +339,11 @@ SDL_Fcitx_Reset(void)
|
|||
}
|
||||
|
||||
SDL_bool
|
||||
SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode)
|
||||
SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state)
|
||||
{
|
||||
Uint32 state = Fcitx_ModState();
|
||||
Uint32 mod_state = Fcitx_ModState();
|
||||
Uint32 handled = SDL_FALSE;
|
||||
Uint32 is_release = SDL_FALSE;
|
||||
Uint32 is_release = (state == SDL_RELEASED);
|
||||
Uint32 event_time = 0;
|
||||
|
||||
if (!fcitx_client.ic_path) {
|
||||
|
@ -351,7 +351,7 @@ SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode)
|
|||
}
|
||||
|
||||
if (SDL_DBus_CallMethod(FCITX_DBUS_SERVICE, fcitx_client.ic_path, FCITX_IC_DBUS_INTERFACE, "ProcessKeyEvent",
|
||||
DBUS_TYPE_UINT32, &keysym, DBUS_TYPE_UINT32, &keycode, DBUS_TYPE_UINT32, &state, DBUS_TYPE_BOOLEAN, &is_release, DBUS_TYPE_UINT32, &event_time, DBUS_TYPE_INVALID,
|
||||
DBUS_TYPE_UINT32, &keysym, DBUS_TYPE_UINT32, &keycode, DBUS_TYPE_UINT32, &mod_state, DBUS_TYPE_BOOLEAN, &is_release, DBUS_TYPE_UINT32, &event_time, DBUS_TYPE_INVALID,
|
||||
DBUS_TYPE_BOOLEAN, &handled, DBUS_TYPE_INVALID)) {
|
||||
if (handled) {
|
||||
SDL_Fcitx_UpdateTextRect(NULL);
|
||||
|
|
|
@ -31,7 +31,7 @@ extern SDL_bool SDL_Fcitx_Init(void);
|
|||
extern void SDL_Fcitx_Quit(void);
|
||||
extern void SDL_Fcitx_SetFocus(SDL_bool focused);
|
||||
extern void SDL_Fcitx_Reset(void);
|
||||
extern SDL_bool SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode);
|
||||
extern SDL_bool SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state);
|
||||
extern void SDL_Fcitx_UpdateTextRect(SDL_Rect *rect);
|
||||
extern void SDL_Fcitx_PumpEvents(void);
|
||||
|
||||
|
|
|
@ -503,15 +503,20 @@ SDL_IBus_Reset(void)
|
|||
}
|
||||
|
||||
SDL_bool
|
||||
SDL_IBus_ProcessKeyEvent(Uint32 keysym, Uint32 keycode)
|
||||
SDL_IBus_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state)
|
||||
{
|
||||
Uint32 result = 0;
|
||||
SDL_DBusContext *dbus = SDL_DBus_GetContext();
|
||||
|
||||
|
||||
|
||||
if (IBus_CheckConnection(dbus)) {
|
||||
Uint32 mods = IBus_ModState();
|
||||
Uint32 ibus_keycode = keycode - 8;
|
||||
if (state == SDL_RELEASED) {
|
||||
mods |= (1 << 30); // IBUS_RELEASE_MASK
|
||||
}
|
||||
if (!SDL_DBus_CallMethodOnConnection(ibus_conn, IBUS_SERVICE, input_ctx_path, IBUS_INPUT_INTERFACE, "ProcessKeyEvent",
|
||||
DBUS_TYPE_UINT32, &keysym, DBUS_TYPE_UINT32, &keycode, DBUS_TYPE_UINT32, &mods, DBUS_TYPE_INVALID,
|
||||
DBUS_TYPE_UINT32, &keysym, DBUS_TYPE_UINT32, &ibus_keycode, DBUS_TYPE_UINT32, &mods, DBUS_TYPE_INVALID,
|
||||
DBUS_TYPE_BOOLEAN, &result, DBUS_TYPE_INVALID)) {
|
||||
result = 0;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ extern void SDL_IBus_Reset(void);
|
|||
/* Sends a keypress event to IBus, returns SDL_TRUE if IBus used this event to
|
||||
update its candidate list or change input methods. PumpEvents should be
|
||||
called some time after this, to recieve the TextInput / TextEditing event back. */
|
||||
extern SDL_bool SDL_IBus_ProcessKeyEvent(Uint32 keysym, Uint32 keycode);
|
||||
extern SDL_bool SDL_IBus_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state);
|
||||
|
||||
/* Update the position of IBus' candidate list. If rect is NULL then this will
|
||||
just reposition it relative to the focused window's new position. */
|
||||
|
|
|
@ -27,7 +27,7 @@ typedef SDL_bool (*_SDL_IME_Init)(void);
|
|||
typedef void (*_SDL_IME_Quit)(void);
|
||||
typedef void (*_SDL_IME_SetFocus)(SDL_bool);
|
||||
typedef void (*_SDL_IME_Reset)(void);
|
||||
typedef SDL_bool (*_SDL_IME_ProcessKeyEvent)(Uint32, Uint32);
|
||||
typedef SDL_bool (*_SDL_IME_ProcessKeyEvent)(Uint32, Uint32, Uint8 state);
|
||||
typedef void (*_SDL_IME_UpdateTextRect)(SDL_Rect *);
|
||||
typedef void (*_SDL_IME_PumpEvents)(void);
|
||||
|
||||
|
@ -127,10 +127,10 @@ SDL_IME_Reset(void)
|
|||
}
|
||||
|
||||
SDL_bool
|
||||
SDL_IME_ProcessKeyEvent(Uint32 keysym, Uint32 keycode)
|
||||
SDL_IME_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state)
|
||||
{
|
||||
if (SDL_IME_ProcessKeyEvent_Real)
|
||||
return SDL_IME_ProcessKeyEvent_Real(keysym, keycode);
|
||||
return SDL_IME_ProcessKeyEvent_Real(keysym, keycode, state);
|
||||
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ extern SDL_bool SDL_IME_Init(void);
|
|||
extern void SDL_IME_Quit(void);
|
||||
extern void SDL_IME_SetFocus(SDL_bool focused);
|
||||
extern void SDL_IME_Reset(void);
|
||||
extern SDL_bool SDL_IME_ProcessKeyEvent(Uint32 keysym, Uint32 keycode);
|
||||
extern SDL_bool SDL_IME_ProcessKeyEvent(Uint32 keysym, Uint32 keycode, Uint8 state);
|
||||
extern void SDL_IME_UpdateTextRect(SDL_Rect *rect);
|
||||
extern void SDL_IME_PumpEvents(void);
|
||||
|
||||
|
|
|
@ -25,7 +25,15 @@
|
|||
#include "SDL_windows.h"
|
||||
#include "SDL_error.h"
|
||||
|
||||
#include <objbase.h> /* for CoInitialize/CoUninitialize (Win32 only) */
|
||||
#include <objbase.h> /* for CoInitialize/CoUninitialize (Win32 only) */
|
||||
#if defined(HAVE_ROAPI_H)
|
||||
#include <roapi.h> /* For RoInitialize/RoUninitialize (Win32 only) */
|
||||
#else
|
||||
typedef enum RO_INIT_TYPE {
|
||||
RO_INIT_SINGLETHREADED = 0,
|
||||
RO_INIT_MULTITHREADED = 1
|
||||
} RO_INIT_TYPE;
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32_WINNT_VISTA
|
||||
#define _WIN32_WINNT_VISTA 0x0600
|
||||
|
@ -37,6 +45,10 @@
|
|||
#define _WIN32_WINNT_WIN8 0x0602
|
||||
#endif
|
||||
|
||||
#ifndef LOAD_LIBRARY_SEARCH_SYSTEM32
|
||||
#define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800
|
||||
#endif
|
||||
|
||||
|
||||
/* Sets an error message based on an HRESULT */
|
||||
int
|
||||
|
@ -104,51 +116,54 @@ void
|
|||
WIN_CoUninitialize(void)
|
||||
{
|
||||
#ifndef __WINRT__
|
||||
/* 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:
|
||||
CoUninitialize();
|
||||
#endif
|
||||
}
|
||||
|
||||
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();*/
|
||||
#ifndef __WINRT__
|
||||
void *
|
||||
WIN_LoadComBaseFunction(const char *name)
|
||||
{
|
||||
static SDL_bool s_bLoaded;
|
||||
static HMODULE s_hComBase;
|
||||
|
||||
if (!s_bLoaded) {
|
||||
s_hComBase = LoadLibraryEx(TEXT("combase.dll"), NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
s_bLoaded = SDL_TRUE;
|
||||
}
|
||||
if (s_hComBase) {
|
||||
return GetProcAddress(s_hComBase, name);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
HRESULT
|
||||
WIN_RoInitialize(void)
|
||||
{
|
||||
#ifdef __WINRT__
|
||||
return S_OK;
|
||||
#else
|
||||
typedef HRESULT (*RoInitialize_t)(RO_INIT_TYPE initType);
|
||||
RoInitialize_t RoInitializeFunc = (RoInitialize_t)WIN_LoadComBaseFunction("RoInitialize");
|
||||
if (RoInitializeFunc) {
|
||||
return RoInitializeFunc(RO_INIT_MULTITHREADED);
|
||||
} else {
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
WIN_RoUninitialize(void)
|
||||
{
|
||||
#ifndef __WINRT__
|
||||
typedef void (*RoUninitialize_t)(void);
|
||||
RoUninitialize_t RoUninitializeFunc = (RoUninitialize_t)WIN_LoadComBaseFunction("RoUninitialize");
|
||||
if (RoUninitializeFunc) {
|
||||
RoUninitializeFunc();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -63,10 +63,19 @@ extern int WIN_SetErrorFromHRESULT(const char *prefix, HRESULT hr);
|
|||
/* Sets an error message based on GetLastError(). Always return -1. */
|
||||
extern int WIN_SetError(const char *prefix);
|
||||
|
||||
#if !defined(__WINRT__)
|
||||
/* Load a function from combase.dll */
|
||||
void *WIN_LoadComBaseFunction(const char *name);
|
||||
#endif
|
||||
|
||||
/* Wrap up the oddities of CoInitialize() into a common function. */
|
||||
extern HRESULT WIN_CoInitialize(void);
|
||||
extern void WIN_CoUninitialize(void);
|
||||
|
||||
/* Wrap up the oddities of RoInitialize() into a common function. */
|
||||
extern HRESULT WIN_RoInitialize(void);
|
||||
extern void WIN_RoUninitialize(void);
|
||||
|
||||
/* Returns SDL_TRUE if we're running on Windows Vista and newer */
|
||||
extern BOOL WIN_IsWindowsVistaOrGreater(void);
|
||||
|
||||
|
|
|
@ -638,6 +638,7 @@ SDL_SetKeyboardFocus(SDL_Window * window)
|
|||
/* old window must lose an existing mouse capture. */
|
||||
if (keyboard->focus->flags & SDL_WINDOW_MOUSE_CAPTURE) {
|
||||
SDL_CaptureMouse(SDL_FALSE); /* drop the capture. */
|
||||
SDL_UpdateMouseCapture(SDL_TRUE);
|
||||
SDL_assert(!(keyboard->focus->flags & SDL_WINDOW_MOUSE_CAPTURE));
|
||||
}
|
||||
|
||||
|
|
|
@ -109,6 +109,28 @@ SDL_TouchMouseEventsChanged(void *userdata, const char *name, const char *oldVal
|
|||
mouse->touch_mouse_events = SDL_GetStringBoolean(hint, SDL_TRUE);
|
||||
}
|
||||
|
||||
#if defined(__vita__)
|
||||
static void SDLCALL
|
||||
SDL_VitaTouchMouseDeviceChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
|
||||
{
|
||||
SDL_Mouse *mouse = (SDL_Mouse *)userdata;
|
||||
if (hint) {
|
||||
switch(*hint) {
|
||||
default:
|
||||
case '0':
|
||||
mouse->vita_touch_mouse_device = 0;
|
||||
break;
|
||||
case '1':
|
||||
mouse->vita_touch_mouse_device = 1;
|
||||
break;
|
||||
case '2':
|
||||
mouse->vita_touch_mouse_device = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void SDLCALL
|
||||
SDL_MouseTouchEventsChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
|
||||
{
|
||||
|
@ -134,12 +156,8 @@ SDL_MouseAutoCaptureChanged(void *userdata, const char *name, const char *oldVal
|
|||
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;
|
||||
SDL_UpdateMouseCapture(SDL_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -166,6 +184,11 @@ SDL_MouseInit(void)
|
|||
SDL_AddHintCallback(SDL_HINT_TOUCH_MOUSE_EVENTS,
|
||||
SDL_TouchMouseEventsChanged, mouse);
|
||||
|
||||
#if defined(__vita__)
|
||||
SDL_AddHintCallback(SDL_HINT_VITA_TOUCH_MOUSE_DEVICE,
|
||||
SDL_VitaTouchMouseDeviceChanged, mouse);
|
||||
#endif
|
||||
|
||||
SDL_AddHintCallback(SDL_HINT_MOUSE_TOUCH_EVENTS,
|
||||
SDL_MouseTouchEventsChanged, mouse);
|
||||
|
||||
|
@ -538,7 +561,6 @@ 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) {
|
||||
|
@ -641,10 +663,7 @@ SDL_PrivateSendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state
|
|||
|
||||
/* 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);
|
||||
}
|
||||
SDL_UpdateMouseCapture(SDL_FALSE);
|
||||
}
|
||||
|
||||
return posted;
|
||||
|
@ -741,6 +760,7 @@ SDL_MouseQuit(void)
|
|||
|
||||
if (mouse->CaptureMouse) {
|
||||
SDL_CaptureMouse(SDL_FALSE);
|
||||
SDL_UpdateMouseCapture(SDL_TRUE);
|
||||
}
|
||||
SDL_SetRelativeMouseMode(SDL_FALSE);
|
||||
SDL_ShowCursor(1);
|
||||
|
@ -945,6 +965,8 @@ SDL_SetRelativeMouseMode(SDL_bool enabled)
|
|||
if (!enabled) {
|
||||
SDL_WarpMouseInWindow(focusWindow, mouse->x, mouse->y);
|
||||
}
|
||||
|
||||
SDL_UpdateMouseCapture(SDL_FALSE);
|
||||
}
|
||||
|
||||
if (!enabled) {
|
||||
|
@ -966,39 +988,59 @@ SDL_GetRelativeMouseMode()
|
|||
return mouse->relative_mode;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_UpdateMouseCapture(SDL_bool force_release)
|
||||
{
|
||||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
SDL_Window *capture_window = NULL;
|
||||
|
||||
if (!mouse->CaptureMouse) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!force_release) {
|
||||
if (mouse->capture_desired || (mouse->auto_capture && SDL_GetMouseState(NULL, NULL) != 0)) {
|
||||
if (!mouse->relative_mode) {
|
||||
capture_window = SDL_GetKeyboardFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (capture_window != mouse->capture_window) {
|
||||
if (mouse->capture_window) {
|
||||
mouse->CaptureMouse(NULL);
|
||||
mouse->capture_window->flags &= ~SDL_WINDOW_MOUSE_CAPTURE;
|
||||
mouse->capture_window = NULL;
|
||||
}
|
||||
|
||||
if (capture_window) {
|
||||
if (mouse->CaptureMouse(capture_window) < 0) {
|
||||
/* CaptureMouse() will have set an error */
|
||||
return -1;
|
||||
}
|
||||
capture_window->flags |= SDL_WINDOW_MOUSE_CAPTURE;
|
||||
}
|
||||
|
||||
mouse->capture_window = capture_window;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_CaptureMouse(SDL_bool enabled)
|
||||
{
|
||||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
SDL_Window *focusWindow;
|
||||
SDL_bool isCaptured;
|
||||
|
||||
if (!mouse->CaptureMouse) {
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
focusWindow = SDL_GetKeyboardFocus();
|
||||
|
||||
isCaptured = focusWindow && (focusWindow->flags & SDL_WINDOW_MOUSE_CAPTURE);
|
||||
if (isCaptured == enabled) {
|
||||
return 0; /* already done! */
|
||||
if (enabled && SDL_GetKeyboardFocus() == NULL) {
|
||||
return SDL_SetError("No window has focus");
|
||||
}
|
||||
mouse->capture_desired = enabled;
|
||||
|
||||
if (enabled) {
|
||||
if (!focusWindow) {
|
||||
return SDL_SetError("No window has focus");
|
||||
} else if (mouse->CaptureMouse(focusWindow) == -1) {
|
||||
return -1; /* CaptureMouse() should call SetError */
|
||||
}
|
||||
focusWindow->flags |= SDL_WINDOW_MOUSE_CAPTURE;
|
||||
} else {
|
||||
if (mouse->CaptureMouse(NULL) == -1) {
|
||||
return -1; /* CaptureMouse() should call SetError */
|
||||
}
|
||||
focusWindow->flags &= ~SDL_WINDOW_MOUSE_CAPTURE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return SDL_UpdateMouseCapture(SDL_FALSE);
|
||||
}
|
||||
|
||||
SDL_Cursor *
|
||||
|
|
|
@ -100,7 +100,12 @@ typedef struct
|
|||
SDL_bool touch_mouse_events;
|
||||
SDL_bool mouse_touch_events;
|
||||
SDL_bool was_touch_mouse_events; /* Was a touch-mouse event pending? */
|
||||
#if defined(__vita__)
|
||||
Uint8 vita_touch_mouse_device;
|
||||
#endif
|
||||
SDL_bool auto_capture;
|
||||
SDL_bool capture_desired;
|
||||
SDL_Window *capture_window;
|
||||
|
||||
/* Data for input source state */
|
||||
int num_sources;
|
||||
|
@ -132,6 +137,9 @@ extern void SDL_SetDefaultCursor(SDL_Cursor * cursor);
|
|||
/* Set the mouse focus window */
|
||||
extern void SDL_SetMouseFocus(SDL_Window * window);
|
||||
|
||||
/* Update the mouse capture window */
|
||||
extern int SDL_UpdateMouseCapture(SDL_bool force_release);
|
||||
|
||||
/* Send a mouse motion event */
|
||||
extern int SDL_SendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relative, int x, int y);
|
||||
|
||||
|
|
|
@ -265,8 +265,13 @@ SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window * window,
|
|||
|
||||
#if SYNTHESIZE_TOUCH_TO_MOUSE
|
||||
/* SDL_HINT_TOUCH_MOUSE_EVENTS: controlling whether touch events should generate synthetic mouse events */
|
||||
/* SDL_HINT_VITA_TOUCH_MOUSE_DEVICE: controlling which touchpad should generate synthetic mouse events, PSVita-only */
|
||||
{
|
||||
#if defined(__vita__)
|
||||
if (mouse->touch_mouse_events && ((mouse->vita_touch_mouse_device == id) || (mouse->vita_touch_mouse_device == 2)) ) {
|
||||
#else
|
||||
if (mouse->touch_mouse_events) {
|
||||
#endif
|
||||
/* FIXME: maybe we should only restrict to a few SDL_TouchDeviceType */
|
||||
if (id != SDL_MOUSE_TOUCHID) {
|
||||
if (window) {
|
||||
|
|
|
@ -1185,9 +1185,9 @@ struct SDL_hid_device_info *SDL_hid_enumerate(unsigned short vendor_id, unsigned
|
|||
#ifdef SDL_LIBUSB_DYNAMIC
|
||||
if (libusb_ctx.libhandle) {
|
||||
usb_devs = LIBUSB_hid_enumerate(vendor_id, product_id);
|
||||
#ifdef DEBUG_HIDAPI
|
||||
#ifdef DEBUG_HIDAPI
|
||||
SDL_Log("libusb devices found:");
|
||||
#endif
|
||||
#endif
|
||||
for (usb_dev = usb_devs; usb_dev; usb_dev = usb_dev->next) {
|
||||
new_dev = (struct SDL_hid_device_info*) SDL_malloc(sizeof(struct SDL_hid_device_info));
|
||||
if (!new_dev) {
|
||||
|
@ -1197,11 +1197,11 @@ struct SDL_hid_device_info *SDL_hid_enumerate(unsigned short vendor_id, unsigned
|
|||
return NULL;
|
||||
}
|
||||
CopyHIDDeviceInfo(usb_dev, new_dev);
|
||||
#ifdef DEBUG_HIDAPI
|
||||
#ifdef DEBUG_HIDAPI
|
||||
SDL_Log(" - %ls %ls 0x%.4hx 0x%.4hx",
|
||||
usb_dev->manufacturer_string, usb_dev->product_string,
|
||||
usb_dev->vendor_id, usb_dev->product_id);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (last != NULL) {
|
||||
last->next = new_dev;
|
||||
|
|
|
@ -747,7 +747,11 @@ HIDAPI_DriverPS5_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joy
|
|||
}
|
||||
}
|
||||
|
||||
return SDL_HIDAPI_SendRumbleAndUnlock(device, data, report_size);
|
||||
if (SDL_HIDAPI_SendRumbleAndUnlock(device, data, report_size) != report_size) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -109,6 +109,7 @@ typedef struct SDL_joylist_item
|
|||
/* Steam Controller support */
|
||||
SDL_bool m_bSteamController;
|
||||
|
||||
SDL_bool checked_mapping;
|
||||
SDL_GamepadMapping *mapping;
|
||||
} SDL_joylist_item;
|
||||
|
||||
|
@ -605,6 +606,26 @@ LINUX_InotifyJoystickDetect(void)
|
|||
}
|
||||
#endif /* HAVE_INOTIFY */
|
||||
|
||||
static int get_event_joystick_index(int event)
|
||||
{
|
||||
int joystick_index = -1;
|
||||
int i, count;
|
||||
struct dirent **entries = NULL;
|
||||
char path[PATH_MAX];
|
||||
|
||||
SDL_snprintf(path, SDL_arraysize(path), "/sys/class/input/event%d/device", event);
|
||||
count = scandir(path, &entries, NULL, alphasort);
|
||||
for (i = 0; i < count; ++i) {
|
||||
if (SDL_strncmp(entries[i]->d_name, "js", 2) == 0) {
|
||||
joystick_index = SDL_atoi(entries[i]->d_name+2);
|
||||
}
|
||||
free(entries[i]); /* This should NOT be SDL_free() */
|
||||
}
|
||||
free(entries); /* This should NOT be SDL_free() */
|
||||
|
||||
return joystick_index;
|
||||
}
|
||||
|
||||
/* Detect devices by reading /dev/input. In the inotify code path we
|
||||
* have to do this the first time, to detect devices that already existed
|
||||
* before we started; in the non-inotify code path we do this repeatedly
|
||||
|
@ -617,10 +638,35 @@ filter_entries(const struct dirent *entry)
|
|||
static int
|
||||
sort_entries(const struct dirent **a, const struct dirent **b)
|
||||
{
|
||||
int numA = SDL_atoi((*a)->d_name+5);
|
||||
int numB = SDL_atoi((*b)->d_name+5);
|
||||
int numA, numB;
|
||||
int offset;
|
||||
|
||||
if (SDL_classic_joysticks) {
|
||||
offset = 2; /* strlen("js") */
|
||||
numA = SDL_atoi((*a)->d_name+offset);
|
||||
numB = SDL_atoi((*b)->d_name+offset);
|
||||
} else {
|
||||
offset = 5; /* strlen("event") */
|
||||
numA = SDL_atoi((*a)->d_name+offset);
|
||||
numB = SDL_atoi((*b)->d_name+offset);
|
||||
|
||||
/* See if we can get the joystick ordering */
|
||||
{
|
||||
int jsA = get_event_joystick_index(numA);
|
||||
int jsB = get_event_joystick_index(numB);
|
||||
if (jsA >= 0 && jsB >= 0) {
|
||||
numA = jsA;
|
||||
numB = jsB;
|
||||
} else if (jsA >= 0) {
|
||||
return -1;
|
||||
} else if (jsB >= 0) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (numA - numB);
|
||||
}
|
||||
|
||||
static void
|
||||
LINUX_FallbackJoystickDetect(void)
|
||||
{
|
||||
|
@ -633,7 +679,7 @@ LINUX_FallbackJoystickDetect(void)
|
|||
/* Opening input devices can generate synchronous device I/O, so avoid it if we can */
|
||||
if (stat("/dev/input", &sb) == 0 && sb.st_mtime != last_input_dir_mtime) {
|
||||
int i, count;
|
||||
struct dirent **entries;
|
||||
struct dirent **entries = NULL;
|
||||
char path[PATH_MAX];
|
||||
|
||||
count = scandir("/dev/input", &entries, filter_entries, sort_entries);
|
||||
|
@ -683,29 +729,7 @@ LINUX_JoystickInit(void)
|
|||
|
||||
SDL_classic_joysticks = SDL_GetHintBoolean(SDL_HINT_LINUX_JOYSTICK_CLASSIC, SDL_FALSE);
|
||||
|
||||
#if SDL_USE_LIBUDEV
|
||||
if (enumeration_method == ENUMERATION_UNSET) {
|
||||
if (SDL_GetHintBoolean("SDL_JOYSTICK_DISABLE_UDEV", SDL_FALSE)) {
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
|
||||
"udev disabled by SDL_JOYSTICK_DISABLE_UDEV");
|
||||
enumeration_method = ENUMERATION_FALLBACK;
|
||||
|
||||
} else if (access("/.flatpak-info", F_OK) == 0
|
||||
|| access("/run/host/container-manager", F_OK) == 0) {
|
||||
/* Explicitly check `/.flatpak-info` because, for old versions of
|
||||
* Flatpak, this was the only available way to tell if we were in
|
||||
* a Flatpak container. */
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
|
||||
"Container detected, disabling udev integration");
|
||||
enumeration_method = ENUMERATION_FALLBACK;
|
||||
|
||||
} else {
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
|
||||
"Using udev for joystick device discovery");
|
||||
enumeration_method = ENUMERATION_LIBUDEV;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
enumeration_method = ENUMERATION_UNSET;
|
||||
|
||||
/* First see if the user specified one or more joysticks to use */
|
||||
if (devices != NULL) {
|
||||
|
@ -734,6 +758,28 @@ LINUX_JoystickInit(void)
|
|||
LINUX_JoystickDetect();
|
||||
|
||||
#if SDL_USE_LIBUDEV
|
||||
if (enumeration_method == ENUMERATION_UNSET) {
|
||||
if (SDL_GetHintBoolean("SDL_JOYSTICK_DISABLE_UDEV", SDL_FALSE)) {
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
|
||||
"udev disabled by SDL_JOYSTICK_DISABLE_UDEV");
|
||||
enumeration_method = ENUMERATION_FALLBACK;
|
||||
|
||||
} else if (access("/.flatpak-info", F_OK) == 0
|
||||
|| access("/run/host/container-manager", F_OK) == 0) {
|
||||
/* Explicitly check `/.flatpak-info` because, for old versions of
|
||||
* Flatpak, this was the only available way to tell if we were in
|
||||
* a Flatpak container. */
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
|
||||
"Container detected, disabling udev integration");
|
||||
enumeration_method = ENUMERATION_FALLBACK;
|
||||
|
||||
} else {
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
|
||||
"Using udev for joystick device discovery");
|
||||
enumeration_method = ENUMERATION_LIBUDEV;
|
||||
}
|
||||
}
|
||||
|
||||
if (enumeration_method == ENUMERATION_LIBUDEV) {
|
||||
if (SDL_UDEV_Init() < 0) {
|
||||
return SDL_SetError("Could not initialize UDEV");
|
||||
|
@ -1573,9 +1619,13 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
|
|||
SDL_Joystick *joystick;
|
||||
SDL_joylist_item *item = JoystickByDevIndex(device_index);
|
||||
|
||||
if (item->mapping) {
|
||||
SDL_memcpy(out, item->mapping, sizeof(*out));
|
||||
return SDL_TRUE;
|
||||
if (item->checked_mapping) {
|
||||
if (item->mapping) {
|
||||
SDL_memcpy(out, item->mapping, sizeof(*out));
|
||||
return SDL_TRUE;
|
||||
} else {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* We temporarily open the device to check how it's configured. Make
|
||||
|
@ -1595,6 +1645,8 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
|
|||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
item->checked_mapping = SDL_TRUE;
|
||||
|
||||
if (PrepareJoystickHwdata(joystick, item) == -1) {
|
||||
SDL_free(joystick->hwdata);
|
||||
SDL_free(joystick);
|
||||
|
|
|
@ -62,6 +62,7 @@ typedef struct WindowsGamingInputGamepadState WindowsGamingInputGamepadState;
|
|||
#define GamepadButtons_GUIDE 0x40000000
|
||||
#define COBJMACROS
|
||||
#include "windows.gaming.input.h"
|
||||
#include <roapi.h>
|
||||
#endif
|
||||
|
||||
#if defined(SDL_JOYSTICK_RAWINPUT_XINPUT) || defined(SDL_JOYSTICK_RAWINPUT_WGI)
|
||||
|
@ -565,22 +566,24 @@ RAWINPUT_InitWindowsGamingInput(RAWINPUT_DeviceContext *ctx)
|
|||
if (!wgi_state.initialized) {
|
||||
static const IID SDL_IID_IGamepadStatics = { 0x8BBCE529, 0xD49C, 0x39E9, { 0x95, 0x60, 0xE4, 0x7D, 0xDE, 0x96, 0xB7, 0xC8 } };
|
||||
HRESULT hr;
|
||||
HMODULE hModule;
|
||||
|
||||
/* I think this takes care of RoInitialize() in a way that is compatible with the rest of SDL */
|
||||
if (FAILED(WIN_CoInitialize())) {
|
||||
if (FAILED(WIN_RoInitialize())) {
|
||||
return;
|
||||
}
|
||||
wgi_state.initialized = SDL_TRUE;
|
||||
wgi_state.dirty = SDL_TRUE;
|
||||
|
||||
hModule = LoadLibraryA("combase.dll");
|
||||
if (hModule != NULL) {
|
||||
{
|
||||
typedef HRESULT (WINAPI *WindowsCreateStringReference_t)(PCWSTR sourceString, UINT32 length, HSTRING_HEADER *hstringHeader, HSTRING* string);
|
||||
typedef HRESULT (WINAPI *RoGetActivationFactory_t)(HSTRING activatableClassId, REFIID iid, void** factory);
|
||||
|
||||
WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)GetProcAddress(hModule, "WindowsCreateStringReference");
|
||||
RoGetActivationFactory_t RoGetActivationFactoryFunc = (RoGetActivationFactory_t)GetProcAddress(hModule, "RoGetActivationFactory");
|
||||
#ifdef __WINRT__
|
||||
WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = WindowsCreateStringReference;
|
||||
RoGetActivationFactory_t RoGetActivationFactoryFunc = RoGetActivationFactory;
|
||||
#else
|
||||
WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)WIN_LoadComBaseFunction("WindowsCreateStringReference");
|
||||
RoGetActivationFactory_t RoGetActivationFactoryFunc = (RoGetActivationFactory_t)WIN_LoadComBaseFunction("RoGetActivationFactory");
|
||||
#endif
|
||||
if (WindowsCreateStringReferenceFunc && RoGetActivationFactoryFunc) {
|
||||
PCWSTR pNamespace = L"Windows.Gaming.Input.Gamepad";
|
||||
HSTRING_HEADER hNamespaceStringHeader;
|
||||
|
@ -591,7 +594,6 @@ RAWINPUT_InitWindowsGamingInput(RAWINPUT_DeviceContext *ctx)
|
|||
RoGetActivationFactoryFunc(hNamespaceString, &SDL_IID_IGamepadStatics, (void **)&wgi_state.gamepad_statics);
|
||||
}
|
||||
}
|
||||
FreeLibrary(hModule);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -657,7 +659,7 @@ RAWINPUT_QuitWindowsGamingInput(RAWINPUT_DeviceContext *ctx)
|
|||
__x_ABI_CWindows_CGaming_CInput_CIGamepadStatics_Release(wgi_state.gamepad_statics);
|
||||
wgi_state.gamepad_statics = NULL;
|
||||
}
|
||||
WIN_CoUninitialize();
|
||||
WIN_RoUninitialize();
|
||||
wgi_state.initialized = SDL_FALSE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -260,10 +260,9 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeAdde
|
|||
WindowsGetStringRawBufferFunc = WindowsGetStringRawBuffer;
|
||||
WindowsDeleteStringFunc = WindowsDeleteString;
|
||||
#else
|
||||
HMODULE hModule = LoadLibraryA("combase.dll");
|
||||
if (hModule != NULL) {
|
||||
WindowsGetStringRawBufferFunc = (WindowsGetStringRawBuffer_t)GetProcAddress(hModule, "WindowsGetStringRawBuffer");
|
||||
WindowsDeleteStringFunc = (WindowsDeleteString_t)GetProcAddress(hModule, "WindowsDeleteString");
|
||||
{
|
||||
WindowsGetStringRawBufferFunc = (WindowsGetStringRawBuffer_t)WIN_LoadComBaseFunction("WindowsGetStringRawBuffer");
|
||||
WindowsDeleteStringFunc = (WindowsDeleteString_t)WIN_LoadComBaseFunction("WindowsDeleteString");
|
||||
}
|
||||
#endif /* __WINRT__ */
|
||||
if (WindowsGetStringRawBufferFunc && WindowsDeleteStringFunc) {
|
||||
|
@ -277,11 +276,6 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeAdde
|
|||
WindowsDeleteStringFunc(hString);
|
||||
}
|
||||
}
|
||||
#ifndef __WINRT__
|
||||
if (hModule != NULL) {
|
||||
FreeLibrary(hModule);
|
||||
}
|
||||
#endif
|
||||
__x_ABI_CWindows_CGaming_CInput_CIRawGameController2_Release(controller2);
|
||||
}
|
||||
if (!name) {
|
||||
|
@ -444,23 +438,19 @@ WGI_JoystickInit(void)
|
|||
|
||||
WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = NULL;
|
||||
RoGetActivationFactory_t RoGetActivationFactoryFunc = NULL;
|
||||
#ifndef __WINRT__
|
||||
HMODULE hModule;
|
||||
#endif
|
||||
HRESULT hr;
|
||||
|
||||
if (FAILED(WIN_CoInitialize())) {
|
||||
return SDL_SetError("CoInitialize() failed");
|
||||
if (FAILED(WIN_RoInitialize())) {
|
||||
return SDL_SetError("RoInitialize() failed");
|
||||
}
|
||||
|
||||
#ifdef __WINRT__
|
||||
WindowsCreateStringReferenceFunc = WindowsCreateStringReference;
|
||||
RoGetActivationFactoryFunc = RoGetActivationFactory;
|
||||
#else
|
||||
hModule = LoadLibraryA("combase.dll");
|
||||
if (hModule != NULL) {
|
||||
WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)GetProcAddress(hModule, "WindowsCreateStringReference");
|
||||
RoGetActivationFactoryFunc = (RoGetActivationFactory_t)GetProcAddress(hModule, "RoGetActivationFactory");
|
||||
{
|
||||
WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)WIN_LoadComBaseFunction("WindowsCreateStringReference");
|
||||
RoGetActivationFactoryFunc = (RoGetActivationFactory_t)WIN_LoadComBaseFunction("RoGetActivationFactory");
|
||||
}
|
||||
#endif /* __WINRT__ */
|
||||
if (WindowsCreateStringReferenceFunc && RoGetActivationFactoryFunc) {
|
||||
|
@ -519,11 +509,6 @@ WGI_JoystickInit(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
#ifndef __WINRT__
|
||||
if (hModule != NULL) {
|
||||
FreeLibrary(hModule);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (wgi.statics) {
|
||||
__FIVectorView_1_Windows__CGaming__CInput__CRawGameController *controllers;
|
||||
|
@ -865,7 +850,7 @@ WGI_JoystickQuit(void)
|
|||
}
|
||||
SDL_zero(wgi);
|
||||
|
||||
WIN_CoUninitialize();
|
||||
WIN_RoUninitialize();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "../../SDL_internal.h"
|
||||
#include "../SDL_syslocale.h"
|
||||
|
||||
#include <psp2/apputil.h>
|
||||
#include <psp2/system_param.h>
|
||||
|
||||
void
|
||||
SDL_SYS_GetPreferredLocales(char *buf, size_t buflen)
|
||||
{
|
||||
const char *vita_locales[] = {
|
||||
"ja_JP",
|
||||
"en_US",
|
||||
"fr_FR",
|
||||
"es_ES",
|
||||
"de_DE",
|
||||
"it_IT",
|
||||
"nl_NL",
|
||||
"pt_PT",
|
||||
"ru_RU",
|
||||
"ko_KR",
|
||||
"zh_TW",
|
||||
"zh_CN",
|
||||
"fi_FI",
|
||||
"sv_SE",
|
||||
"da_DK",
|
||||
"no_NO",
|
||||
"pl_PL",
|
||||
"pt_BR",
|
||||
"en_GB",
|
||||
"tr_TR",
|
||||
};
|
||||
|
||||
Sint32 language = SCE_SYSTEM_PARAM_LANG_ENGLISH_US;
|
||||
SceAppUtilInitParam initParam;
|
||||
SceAppUtilBootParam bootParam;
|
||||
SDL_zero(initParam);
|
||||
SDL_zero(bootParam);
|
||||
sceAppUtilInit(&initParam, &bootParam);
|
||||
sceAppUtilSystemParamGetInt(SCE_SYSTEM_PARAM_ID_LANG, &language);
|
||||
|
||||
if (language < 0 || language > SCE_SYSTEM_PARAM_LANG_TURKISH)
|
||||
language = SCE_SYSTEM_PARAM_LANG_ENGLISH_US; // default to english
|
||||
|
||||
SDL_strlcpy(buf, vita_locales[language], buflen);
|
||||
|
||||
sceAppUtilShutdown();
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
@ -9,8 +9,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 2,0,21,0
|
||||
PRODUCTVERSION 2,0,21,0
|
||||
FILEVERSION 2,0,22,0
|
||||
PRODUCTVERSION 2,0,22,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
FILEFLAGS 0x0L
|
||||
FILEOS 0x40004L
|
||||
|
@ -23,12 +23,12 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "\0"
|
||||
VALUE "FileDescription", "SDL\0"
|
||||
VALUE "FileVersion", "2, 0, 21, 0\0"
|
||||
VALUE "FileVersion", "2, 0, 22, 0\0"
|
||||
VALUE "InternalName", "SDL\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2022 Sam Lantinga\0"
|
||||
VALUE "OriginalFilename", "SDL2.dll\0"
|
||||
VALUE "ProductName", "Simple DirectMedia Layer\0"
|
||||
VALUE "ProductVersion", "2, 0, 21, 0\0"
|
||||
VALUE "ProductVersion", "2, 0, 22, 0\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
|
@ -580,10 +580,10 @@ QueueCmdFillRects(SDL_Renderer *renderer, const SDL_FRect * rects, const int cou
|
|||
if (retval < 0) {
|
||||
cmd->command = SDL_RENDERCMD_NO_OP;
|
||||
}
|
||||
|
||||
SDL_small_free(xy, isstack1);
|
||||
SDL_small_free(indices, isstack2);
|
||||
}
|
||||
SDL_small_free(xy, isstack1);
|
||||
SDL_small_free(indices, isstack2);
|
||||
|
||||
} else {
|
||||
retval = renderer->QueueFillRects(renderer, cmd, rects, count);
|
||||
if (retval < 0) {
|
||||
|
@ -698,7 +698,17 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event)
|
|||
renderer->WindowEvent(renderer, &event->window);
|
||||
}
|
||||
|
||||
if (event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
|
||||
/* In addition to size changes, we also want to do this block for
|
||||
* moves as well, for two reasons:
|
||||
*
|
||||
* 1. The window could be moved to a new display, which has a new
|
||||
* DPI and therefore a new window/drawable ratio
|
||||
* 2. For whatever reason, the viewport can get messed up during
|
||||
* window movement (this has been observed on macOS), so this is
|
||||
* also a good opportunity to force viewport updates
|
||||
*/
|
||||
if (event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED ||
|
||||
event->window.event == SDL_WINDOWEVENT_MOVED) {
|
||||
/* Make sure we're operating on the default render target */
|
||||
SDL_Texture *saved_target = SDL_GetRenderTarget(renderer);
|
||||
if (saved_target) {
|
||||
|
@ -1592,10 +1602,11 @@ SDL_SetTextureScaleMode(SDL_Texture * texture, SDL_ScaleMode scaleMode)
|
|||
CHECK_TEXTURE_MAGIC(texture, -1);
|
||||
|
||||
renderer = texture->renderer;
|
||||
renderer->SetTextureScaleMode(renderer, texture, scaleMode);
|
||||
texture->scaleMode = scaleMode;
|
||||
if (texture->native) {
|
||||
return SDL_SetTextureScaleMode(texture->native, scaleMode);
|
||||
} else {
|
||||
renderer->SetTextureScaleMode(renderer, texture, scaleMode);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -347,7 +347,8 @@ D3D_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
|
|||
}
|
||||
}
|
||||
|
||||
static D3DBLEND GetBlendFunc(SDL_BlendFactor factor)
|
||||
static D3DBLEND
|
||||
GetBlendFunc(SDL_BlendFactor factor)
|
||||
{
|
||||
switch (factor) {
|
||||
case SDL_BLENDFACTOR_ZERO:
|
||||
|
@ -370,9 +371,28 @@ static D3DBLEND GetBlendFunc(SDL_BlendFactor factor)
|
|||
return D3DBLEND_DESTALPHA;
|
||||
case SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA:
|
||||
return D3DBLEND_INVDESTALPHA;
|
||||
default:
|
||||
return (D3DBLEND)0;
|
||||
default: break;
|
||||
}
|
||||
return (D3DBLEND) 0;
|
||||
}
|
||||
|
||||
static D3DBLENDOP
|
||||
GetBlendEquation(SDL_BlendOperation operation)
|
||||
{
|
||||
switch (operation) {
|
||||
case SDL_BLENDOPERATION_ADD:
|
||||
return D3DBLENDOP_ADD;
|
||||
case SDL_BLENDOPERATION_SUBTRACT:
|
||||
return D3DBLENDOP_SUBTRACT;
|
||||
case SDL_BLENDOPERATION_REV_SUBTRACT:
|
||||
return D3DBLENDOP_REVSUBTRACT;
|
||||
case SDL_BLENDOPERATION_MINIMUM:
|
||||
return D3DBLENDOP_MIN;
|
||||
case SDL_BLENDOPERATION_MAXIMUM:
|
||||
return D3DBLENDOP_MAX;
|
||||
default: break;
|
||||
}
|
||||
return (D3DBLENDOP) 0;
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
|
@ -387,14 +407,16 @@ D3D_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode)
|
|||
SDL_BlendOperation alphaOperation = SDL_GetBlendModeAlphaOperation(blendMode);
|
||||
|
||||
if (!GetBlendFunc(srcColorFactor) || !GetBlendFunc(srcAlphaFactor) ||
|
||||
!GetBlendFunc(dstColorFactor) || !GetBlendFunc(dstAlphaFactor)) {
|
||||
!GetBlendEquation(colorOperation) ||
|
||||
!GetBlendFunc(dstColorFactor) || !GetBlendFunc(dstAlphaFactor) ||
|
||||
!GetBlendEquation(alphaOperation)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
if ((srcColorFactor != srcAlphaFactor || dstColorFactor != dstAlphaFactor) && !data->enableSeparateAlphaBlend) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
if (colorOperation != SDL_BLENDOPERATION_ADD || alphaOperation != SDL_BLENDOPERATION_ADD) {
|
||||
return SDL_FALSE;
|
||||
|
||||
if (!data->enableSeparateAlphaBlend) {
|
||||
if ((srcColorFactor != srcAlphaFactor) || (dstColorFactor != dstAlphaFactor) || (colorOperation != alphaOperation)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
}
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
@ -1040,11 +1062,15 @@ SetDrawState(D3D_RenderData *data, const SDL_RenderCommand *cmd)
|
|||
GetBlendFunc(SDL_GetBlendModeSrcColorFactor(blend)));
|
||||
IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND,
|
||||
GetBlendFunc(SDL_GetBlendModeDstColorFactor(blend)));
|
||||
IDirect3DDevice9_SetRenderState(data->device, D3DRS_BLENDOP,
|
||||
GetBlendEquation(SDL_GetBlendModeColorOperation(blend)));
|
||||
if (data->enableSeparateAlphaBlend) {
|
||||
IDirect3DDevice9_SetRenderState(data->device, D3DRS_SRCBLENDALPHA,
|
||||
GetBlendFunc(SDL_GetBlendModeSrcAlphaFactor(blend)));
|
||||
IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLENDALPHA,
|
||||
GetBlendFunc(SDL_GetBlendModeDstAlphaFactor(blend)));
|
||||
IDirect3DDevice9_SetRenderState(data->device, D3DRS_BLENDOPALPHA,
|
||||
GetBlendEquation(SDL_GetBlendModeAlphaOperation(blend)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -998,6 +998,16 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer)
|
|||
goto done;
|
||||
}
|
||||
|
||||
/* Set the swap chain target immediately, so that a target is always set
|
||||
* even before we get to SetDrawState. Without this it's possible to hit
|
||||
* null references in places like ReadPixels!
|
||||
*/
|
||||
ID3D11DeviceContext_OMSetRenderTargets(data->d3dContext,
|
||||
1,
|
||||
&data->mainRenderTargetView,
|
||||
NULL
|
||||
);
|
||||
|
||||
data->viewportDirty = SDL_TRUE;
|
||||
|
||||
done:
|
||||
|
|
|
@ -30,6 +30,11 @@
|
|||
#include <OpenGL/OpenGL.h>
|
||||
#endif
|
||||
|
||||
#ifdef SDL_VIDEO_VITA_PVR_OGL
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glext.h>
|
||||
#endif
|
||||
|
||||
/* To prevent unnecessary window recreation,
|
||||
* these should match the defaults selected in SDL_GL_ResetAttributes
|
||||
*/
|
||||
|
@ -319,6 +324,20 @@ GL_GetFBO(GL_RenderData *data, Uint32 w, Uint32 h)
|
|||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
GL_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
|
||||
{
|
||||
/* If the window x/y/w/h changed at all, assume the viewport has been
|
||||
* changed behind our backs. x/y changes might seem weird but viewport
|
||||
* resets have been observed on macOS at minimum!
|
||||
*/
|
||||
if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED ||
|
||||
event->event == SDL_WINDOWEVENT_MOVED) {
|
||||
GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
|
||||
data->drawstate.viewport_dirty = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
GL_GetOutputSize(SDL_Renderer * renderer, int *w, int *h)
|
||||
{
|
||||
|
@ -1211,13 +1230,6 @@ GL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef __MACOSX__
|
||||
// On macOS, moving the window seems to invalidate the OpenGL viewport state,
|
||||
// so don't bother trying to persist it across frames; always reset it.
|
||||
// Workaround for: https://github.com/libsdl-org/SDL/issues/1504
|
||||
data->drawstate.viewport_dirty = SDL_TRUE;
|
||||
#endif
|
||||
|
||||
while (cmd) {
|
||||
switch (cmd->command) {
|
||||
case SDL_RENDERCMD_SETDRAWCOLOR: {
|
||||
|
@ -1733,6 +1745,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
|||
SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &major);
|
||||
SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &minor);
|
||||
|
||||
#ifndef SDL_VIDEO_VITA_PVR_OGL
|
||||
window_flags = SDL_GetWindowFlags(window);
|
||||
if (!(window_flags & SDL_WINDOW_OPENGL) ||
|
||||
profile_mask == SDL_GL_CONTEXT_PROFILE_ES || major != RENDERER_CONTEXT_MAJOR || minor != RENDERER_CONTEXT_MINOR) {
|
||||
|
@ -1746,6 +1759,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
|||
goto error;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
|
||||
if (!renderer) {
|
||||
|
@ -1760,6 +1774,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
|||
goto error;
|
||||
}
|
||||
|
||||
renderer->WindowEvent = GL_WindowEvent;
|
||||
renderer->GetOutputSize = GL_GetOutputSize;
|
||||
renderer->SupportsBlendMode = GL_SupportsBlendMode;
|
||||
renderer->CreateTexture = GL_CreateTexture;
|
||||
|
|
|
@ -1246,7 +1246,7 @@ VITA_GXM_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture)
|
|||
|
||||
sceGxmFinish(data->gxm_context);
|
||||
|
||||
free_gxm_texture(vita_texture->tex);
|
||||
free_gxm_texture(data, vita_texture->tex);
|
||||
|
||||
SDL_free(vita_texture);
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include "SDL_render_vita_gxm_memory.h"
|
||||
|
||||
void *
|
||||
mem_gpu_alloc(SceKernelMemBlockType type, unsigned int size, unsigned int alignment, unsigned int attribs, SceUID *uid)
|
||||
vita_mem_alloc(SceKernelMemBlockType type, unsigned int size, unsigned int alignment, unsigned int attribs, SceUID *uid)
|
||||
{
|
||||
void *mem;
|
||||
|
||||
|
@ -51,7 +51,7 @@ mem_gpu_alloc(SceKernelMemBlockType type, unsigned int size, unsigned int alignm
|
|||
}
|
||||
|
||||
void
|
||||
mem_gpu_free(SceUID uid)
|
||||
vita_mem_free(SceUID uid)
|
||||
{
|
||||
void *mem = NULL;
|
||||
if (sceKernelGetMemBlockBase(uid, &mem) < 0)
|
||||
|
@ -61,7 +61,71 @@ mem_gpu_free(SceUID uid)
|
|||
}
|
||||
|
||||
void *
|
||||
mem_vertex_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset)
|
||||
vita_gpu_mem_alloc(VITA_GXM_RenderData *data, unsigned int size)
|
||||
{
|
||||
void *mem;
|
||||
|
||||
if (data->texturePool == NULL) {
|
||||
int poolsize;
|
||||
int ret;
|
||||
SceKernelFreeMemorySizeInfo info;
|
||||
info.size = sizeof(SceKernelFreeMemorySizeInfo);
|
||||
sceKernelGetFreeMemorySize(&info);
|
||||
|
||||
poolsize = ALIGN(info.size_cdram, 256*1024);
|
||||
if (poolsize > info.size_cdram) {
|
||||
poolsize = ALIGN(info.size_cdram - 256*1024, 256*1024);
|
||||
}
|
||||
data->texturePoolUID = sceKernelAllocMemBlock("gpu_texture_pool", SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, poolsize, NULL);
|
||||
if (data->texturePoolUID < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = sceKernelGetMemBlockBase(data->texturePoolUID, &mem);
|
||||
if ( ret < 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
data->texturePool = sceClibMspaceCreate(mem, poolsize);
|
||||
|
||||
if (data->texturePool == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
ret = sceGxmMapMemory(mem, poolsize, SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE);
|
||||
if (ret < 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return sceClibMspaceMemalign(data->texturePool, SCE_GXM_TEXTURE_ALIGNMENT, size);
|
||||
}
|
||||
|
||||
void
|
||||
vita_gpu_mem_free(VITA_GXM_RenderData *data, void* ptr)
|
||||
{
|
||||
if (data->texturePool != NULL)
|
||||
{
|
||||
sceClibMspaceFree(data->texturePool, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
vita_gpu_mem_destroy(VITA_GXM_RenderData *data)
|
||||
{
|
||||
void *mem = NULL;
|
||||
if (data->texturePool != NULL)
|
||||
{
|
||||
sceClibMspaceDestroy(data->texturePool);
|
||||
data->texturePool = NULL;
|
||||
if (sceKernelGetMemBlockBase(data->texturePoolUID, &mem) < 0)
|
||||
return;
|
||||
sceGxmUnmapMemory(mem);
|
||||
sceKernelFreeMemBlock(data->texturePoolUID);
|
||||
}
|
||||
}
|
||||
|
||||
void *
|
||||
vita_mem_vertex_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset)
|
||||
{
|
||||
void *mem = NULL;
|
||||
|
||||
|
@ -77,7 +141,7 @@ mem_vertex_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset)
|
|||
}
|
||||
|
||||
void
|
||||
mem_vertex_usse_free(SceUID uid)
|
||||
vita_mem_vertex_usse_free(SceUID uid)
|
||||
{
|
||||
void *mem = NULL;
|
||||
if (sceKernelGetMemBlockBase(uid, &mem) < 0)
|
||||
|
@ -87,7 +151,7 @@ mem_vertex_usse_free(SceUID uid)
|
|||
}
|
||||
|
||||
void *
|
||||
mem_fragment_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset)
|
||||
vita_mem_fragment_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset)
|
||||
{
|
||||
void *mem = NULL;
|
||||
|
||||
|
@ -103,7 +167,7 @@ mem_fragment_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offse
|
|||
}
|
||||
|
||||
void
|
||||
mem_fragment_usse_free(SceUID uid)
|
||||
vita_mem_fragment_usse_free(SceUID uid)
|
||||
{
|
||||
void *mem = NULL;
|
||||
if (sceKernelGetMemBlockBase(uid, &mem) < 0)
|
||||
|
|
|
@ -25,15 +25,19 @@
|
|||
#include <psp2/gxm.h>
|
||||
#include <psp2/types.h>
|
||||
#include <psp2/kernel/sysmem.h>
|
||||
#include "SDL_render_vita_gxm_types.h"
|
||||
|
||||
#define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1))
|
||||
|
||||
void *mem_gpu_alloc(SceKernelMemBlockType type, unsigned int size, unsigned int alignment, unsigned int attribs, SceUID *uid);
|
||||
void mem_gpu_free(SceUID uid);
|
||||
void *mem_vertex_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset);
|
||||
void mem_vertex_usse_free(SceUID uid);
|
||||
void *mem_fragment_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset);
|
||||
void mem_fragment_usse_free(SceUID uid);
|
||||
void *vita_mem_alloc(SceKernelMemBlockType type, unsigned int size, unsigned int alignment, unsigned int attribs, SceUID *uid);
|
||||
void vita_mem_free(SceUID uid);
|
||||
void *vita_gpu_mem_alloc(VITA_GXM_RenderData *data, unsigned int size);
|
||||
void vita_gpu_mem_free(VITA_GXM_RenderData *data, void* ptr);
|
||||
void vita_gpu_mem_destroy(VITA_GXM_RenderData *data);
|
||||
void *vita_mem_vertex_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset);
|
||||
void vita_mem_vertex_usse_free(SceUID uid);
|
||||
void *vita_mem_fragment_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset);
|
||||
void vita_mem_fragment_usse_free(SceUID uid);
|
||||
|
||||
#endif /* SDL_RENDER_VITA_GXM_MEMORY_H */
|
||||
|
||||
|
|
|
@ -416,28 +416,28 @@ gxm_init(SDL_Renderer *renderer)
|
|||
}
|
||||
|
||||
// allocate ring buffer memory using default sizes
|
||||
vdmRingBuffer = mem_gpu_alloc(
|
||||
vdmRingBuffer = vita_mem_alloc(
|
||||
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
|
||||
SCE_GXM_DEFAULT_VDM_RING_BUFFER_SIZE,
|
||||
4,
|
||||
SCE_GXM_MEMORY_ATTRIB_READ,
|
||||
&data->vdmRingBufferUid);
|
||||
|
||||
vertexRingBuffer = mem_gpu_alloc(
|
||||
vertexRingBuffer = vita_mem_alloc(
|
||||
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
|
||||
SCE_GXM_DEFAULT_VERTEX_RING_BUFFER_SIZE,
|
||||
4,
|
||||
SCE_GXM_MEMORY_ATTRIB_READ,
|
||||
&data->vertexRingBufferUid);
|
||||
|
||||
fragmentRingBuffer = mem_gpu_alloc(
|
||||
fragmentRingBuffer = vita_mem_alloc(
|
||||
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
|
||||
SCE_GXM_DEFAULT_FRAGMENT_RING_BUFFER_SIZE,
|
||||
4,
|
||||
SCE_GXM_MEMORY_ATTRIB_READ,
|
||||
&data->fragmentRingBufferUid);
|
||||
|
||||
fragmentUsseRingBuffer = mem_fragment_usse_alloc(
|
||||
fragmentUsseRingBuffer = vita_mem_fragment_usse_alloc(
|
||||
SCE_GXM_DEFAULT_FRAGMENT_USSE_RING_BUFFER_SIZE,
|
||||
&data->fragmentUsseRingBufferUid,
|
||||
&fragmentUsseRingBufferOffset);
|
||||
|
@ -482,7 +482,7 @@ gxm_init(SDL_Renderer *renderer)
|
|||
for (i = 0; i < VITA_GXM_BUFFERS; i++) {
|
||||
|
||||
// allocate memory for display
|
||||
data->displayBufferData[i] = mem_gpu_alloc(
|
||||
data->displayBufferData[i] = vita_mem_alloc(
|
||||
SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW,
|
||||
4 * VITA_GXM_SCREEN_STRIDE * VITA_GXM_SCREEN_HEIGHT,
|
||||
SCE_GXM_COLOR_SURFACE_ALIGNMENT,
|
||||
|
@ -527,7 +527,7 @@ gxm_init(SDL_Renderer *renderer)
|
|||
|
||||
|
||||
// allocate the depth buffer
|
||||
data->depthBufferData = mem_gpu_alloc(
|
||||
data->depthBufferData = vita_mem_alloc(
|
||||
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
|
||||
4 * sampleCount,
|
||||
SCE_GXM_DEPTHSTENCIL_SURFACE_ALIGNMENT,
|
||||
|
@ -535,7 +535,7 @@ gxm_init(SDL_Renderer *renderer)
|
|||
&data->depthBufferUid);
|
||||
|
||||
// allocate the stencil buffer
|
||||
data->stencilBufferData = mem_gpu_alloc(
|
||||
data->stencilBufferData = vita_mem_alloc(
|
||||
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
|
||||
4 * sampleCount,
|
||||
SCE_GXM_DEPTHSTENCIL_SURFACE_ALIGNMENT,
|
||||
|
@ -567,19 +567,19 @@ gxm_init(SDL_Renderer *renderer)
|
|||
|
||||
|
||||
// allocate memory for buffers and USSE code
|
||||
patcherBuffer = mem_gpu_alloc(
|
||||
patcherBuffer = vita_mem_alloc(
|
||||
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
|
||||
patcherBufferSize,
|
||||
4,
|
||||
SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE,
|
||||
&data->patcherBufferUid);
|
||||
|
||||
patcherVertexUsse = mem_vertex_usse_alloc(
|
||||
patcherVertexUsse = vita_mem_vertex_usse_alloc(
|
||||
patcherVertexUsseSize,
|
||||
&data->patcherVertexUsseUid,
|
||||
&patcherVertexUsseOffset);
|
||||
|
||||
patcherFragmentUsse = mem_fragment_usse_alloc(
|
||||
patcherFragmentUsse = vita_mem_fragment_usse_alloc(
|
||||
patcherFragmentUsseSize,
|
||||
&data->patcherFragmentUsseUid,
|
||||
&patcherFragmentUsseOffset);
|
||||
|
@ -730,7 +730,7 @@ gxm_init(SDL_Renderer *renderer)
|
|||
}
|
||||
|
||||
// create the clear triangle vertex/index data
|
||||
data->clearVertices = (clear_vertex *)mem_gpu_alloc(
|
||||
data->clearVertices = (clear_vertex *)vita_mem_alloc(
|
||||
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
|
||||
3*sizeof(clear_vertex),
|
||||
4,
|
||||
|
@ -742,7 +742,7 @@ gxm_init(SDL_Renderer *renderer)
|
|||
// Allocate a 64k * 2 bytes = 128 KiB buffer and store all possible
|
||||
// 16-bit indices in linear ascending order, so we can use this for
|
||||
// all drawing operations where we don't want to use indexing.
|
||||
data->linearIndices = (uint16_t *)mem_gpu_alloc(
|
||||
data->linearIndices = (uint16_t *)vita_mem_alloc(
|
||||
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
|
||||
UINT16_MAX*sizeof(uint16_t),
|
||||
sizeof(uint16_t),
|
||||
|
@ -873,7 +873,7 @@ gxm_init(SDL_Renderer *renderer)
|
|||
data->textureWvpParam = (SceGxmProgramParameter *)sceGxmProgramFindParameterByName(textureVertexProgramGxp, "wvp");
|
||||
|
||||
// Allocate memory for the memory pool
|
||||
data->pool_addr[0] = mem_gpu_alloc(
|
||||
data->pool_addr[0] = vita_mem_alloc(
|
||||
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW,
|
||||
VITA_GXM_POOL_SIZE,
|
||||
sizeof(void *),
|
||||
|
@ -881,7 +881,7 @@ gxm_init(SDL_Renderer *renderer)
|
|||
&data->poolUid[0]
|
||||
);
|
||||
|
||||
data->pool_addr[1] = mem_gpu_alloc(
|
||||
data->pool_addr[1] = vita_mem_alloc(
|
||||
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW,
|
||||
VITA_GXM_POOL_SIZE,
|
||||
sizeof(void *),
|
||||
|
@ -920,28 +920,28 @@ void gxm_finish(SDL_Renderer *renderer)
|
|||
free_fragment_programs(data, &data->blendFragmentPrograms.blend_mode_mod);
|
||||
free_fragment_programs(data, &data->blendFragmentPrograms.blend_mode_mul);
|
||||
|
||||
mem_gpu_free(data->linearIndicesUid);
|
||||
mem_gpu_free(data->clearVerticesUid);
|
||||
vita_mem_free(data->linearIndicesUid);
|
||||
vita_mem_free(data->clearVerticesUid);
|
||||
|
||||
// wait until display queue is finished before deallocating display buffers
|
||||
sceGxmDisplayQueueFinish();
|
||||
|
||||
// clean up display queue
|
||||
mem_gpu_free(data->depthBufferUid);
|
||||
vita_mem_free(data->depthBufferUid);
|
||||
|
||||
for (size_t i = 0; i < VITA_GXM_BUFFERS; i++)
|
||||
{
|
||||
// clear the buffer then deallocate
|
||||
SDL_memset(data->displayBufferData[i], 0, VITA_GXM_SCREEN_HEIGHT * VITA_GXM_SCREEN_STRIDE * 4);
|
||||
mem_gpu_free(data->displayBufferUid[i]);
|
||||
vita_mem_free(data->displayBufferUid[i]);
|
||||
|
||||
// destroy the sync object
|
||||
sceGxmSyncObjectDestroy(data->displayBufferSync[i]);
|
||||
}
|
||||
|
||||
// Free the depth and stencil buffer
|
||||
mem_gpu_free(data->depthBufferUid);
|
||||
mem_gpu_free(data->stencilBufferUid);
|
||||
vita_mem_free(data->depthBufferUid);
|
||||
vita_mem_free(data->stencilBufferUid);
|
||||
|
||||
// unregister programs and destroy shader patcher
|
||||
sceGxmShaderPatcherUnregisterProgram(data->shaderPatcher, data->clearFragmentProgramId);
|
||||
|
@ -952,23 +952,24 @@ void gxm_finish(SDL_Renderer *renderer)
|
|||
sceGxmShaderPatcherUnregisterProgram(data->shaderPatcher, data->textureVertexProgramId);
|
||||
|
||||
sceGxmShaderPatcherDestroy(data->shaderPatcher);
|
||||
mem_fragment_usse_free(data->patcherFragmentUsseUid);
|
||||
mem_vertex_usse_free(data->patcherVertexUsseUid);
|
||||
mem_gpu_free(data->patcherBufferUid);
|
||||
vita_mem_fragment_usse_free(data->patcherFragmentUsseUid);
|
||||
vita_mem_vertex_usse_free(data->patcherVertexUsseUid);
|
||||
vita_mem_free(data->patcherBufferUid);
|
||||
|
||||
// destroy the render target
|
||||
sceGxmDestroyRenderTarget(data->renderTarget);
|
||||
|
||||
// destroy the gxm context
|
||||
sceGxmDestroyContext(data->gxm_context);
|
||||
mem_fragment_usse_free(data->fragmentUsseRingBufferUid);
|
||||
mem_gpu_free(data->fragmentRingBufferUid);
|
||||
mem_gpu_free(data->vertexRingBufferUid);
|
||||
mem_gpu_free(data->vdmRingBufferUid);
|
||||
vita_mem_fragment_usse_free(data->fragmentUsseRingBufferUid);
|
||||
vita_mem_free(data->fragmentRingBufferUid);
|
||||
vita_mem_free(data->vertexRingBufferUid);
|
||||
vita_mem_free(data->vdmRingBufferUid);
|
||||
SDL_free(data->contextParams.hostMem);
|
||||
|
||||
mem_gpu_free(data->poolUid[0]);
|
||||
mem_gpu_free(data->poolUid[1]);
|
||||
vita_mem_free(data->poolUid[0]);
|
||||
vita_mem_free(data->poolUid[1]);
|
||||
vita_gpu_mem_destroy(data);
|
||||
|
||||
// terminate libgxm
|
||||
sceGxmTerminate();
|
||||
|
@ -977,16 +978,20 @@ void gxm_finish(SDL_Renderer *renderer)
|
|||
// textures
|
||||
|
||||
void
|
||||
free_gxm_texture(gxm_texture *texture)
|
||||
free_gxm_texture(VITA_GXM_RenderData *data, gxm_texture *texture)
|
||||
{
|
||||
if (texture) {
|
||||
if (texture->gxm_rendertarget) {
|
||||
sceGxmDestroyRenderTarget(texture->gxm_rendertarget);
|
||||
}
|
||||
if (texture->depth_UID) {
|
||||
mem_gpu_free(texture->depth_UID);
|
||||
vita_mem_free(texture->depth_UID);
|
||||
}
|
||||
if (texture->cdram) {
|
||||
vita_gpu_mem_free(data, sceGxmTextureGetData(&texture->gxm_tex));
|
||||
} else {
|
||||
vita_mem_free(texture->data_UID);
|
||||
}
|
||||
mem_gpu_free(texture->data_UID);
|
||||
SDL_free(texture);
|
||||
}
|
||||
}
|
||||
|
@ -1033,24 +1038,24 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
|
|||
*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,
|
||||
tex_size,
|
||||
SCE_GXM_TEXTURE_ALIGNMENT,
|
||||
SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE,
|
||||
&texture->data_UID
|
||||
texture_data = vita_gpu_mem_alloc(
|
||||
data,
|
||||
tex_size
|
||||
);
|
||||
|
||||
/* Try SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE in case we're out of VRAM */
|
||||
if (!texture_data) {
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_RENDER, "CDRAM texture allocation failed\n");
|
||||
texture_data = mem_gpu_alloc(
|
||||
texture_data = vita_mem_alloc(
|
||||
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
|
||||
tex_size,
|
||||
SCE_GXM_TEXTURE_ALIGNMENT,
|
||||
SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE,
|
||||
&texture->data_UID
|
||||
);
|
||||
texture->cdram = 0;
|
||||
} else {
|
||||
texture->cdram = 1;
|
||||
}
|
||||
|
||||
if (!texture_data) {
|
||||
|
@ -1064,7 +1069,7 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
|
|||
/* Create the gxm texture */
|
||||
ret = sceGxmTextureInitLinear( &texture->gxm_tex, texture_data, format, texture_w, h, 0);
|
||||
if (ret < 0) {
|
||||
free_gxm_texture(texture);
|
||||
free_gxm_texture(data, texture);
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "texture init failed: %x\n", ret);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1090,13 +1095,13 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
|
|||
);
|
||||
|
||||
if (err < 0) {
|
||||
free_gxm_texture(texture);
|
||||
free_gxm_texture(data, texture);
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "color surface init failed: %x\n", err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// allocate it
|
||||
depthBufferData = mem_gpu_alloc(
|
||||
depthBufferData = vita_mem_alloc(
|
||||
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
|
||||
4*sampleCount,
|
||||
SCE_GXM_DEPTHSTENCIL_SURFACE_ALIGNMENT,
|
||||
|
@ -1113,7 +1118,7 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
|
|||
NULL);
|
||||
|
||||
if (err < 0) {
|
||||
free_gxm_texture(texture);
|
||||
free_gxm_texture(data, texture);
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "depth stencil init failed: %x\n", err);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1138,7 +1143,7 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
|
|||
texture->gxm_rendertarget = tgt;
|
||||
|
||||
if (err < 0) {
|
||||
free_gxm_texture(texture);
|
||||
free_gxm_texture(data, texture);
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "create render target failed: %x\n", err);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1188,7 +1193,7 @@ void gxm_init_for_common_dialog(void)
|
|||
for (int i = 0; i < VITA_GXM_BUFFERS; i += 1)
|
||||
{
|
||||
buffer_for_common_dialog[i].displayData.wait_vblank = SDL_TRUE;
|
||||
buffer_for_common_dialog[i].displayData.address = mem_gpu_alloc(
|
||||
buffer_for_common_dialog[i].displayData.address = vita_mem_alloc(
|
||||
SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW,
|
||||
4 * VITA_GXM_SCREEN_STRIDE * VITA_GXM_SCREEN_HEIGHT,
|
||||
SCE_GXM_COLOR_SURFACE_ALIGNMENT,
|
||||
|
@ -1236,7 +1241,7 @@ void gxm_term_for_common_dialog(void)
|
|||
sceGxmDisplayQueueFinish();
|
||||
for (int i = 0; i < VITA_GXM_BUFFERS; i += 1)
|
||||
{
|
||||
mem_gpu_free(buffer_for_common_dialog[i].uid);
|
||||
vita_mem_free(buffer_for_common_dialog[i].uid);
|
||||
sceGxmSyncObjectDestroy(buffer_for_common_dialog[i].sync);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ 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, unsigned int *return_w, unsigned int *return_h, unsigned int *return_pitch, float *return_wscale);
|
||||
void free_gxm_texture(gxm_texture *texture);
|
||||
void free_gxm_texture(VITA_GXM_RenderData *data, 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);
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <psp2/gxm.h>
|
||||
#include <psp2/types.h>
|
||||
#include <psp2/kernel/sysmem.h>
|
||||
#include <psp2/kernel/clib.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
@ -79,6 +80,7 @@ typedef struct gxm_texture {
|
|||
SceGxmColorSurface gxm_colorsurface;
|
||||
SceGxmDepthStencilSurface gxm_depthstencil;
|
||||
SceUID depth_UID;
|
||||
SDL_bool cdram;
|
||||
} gxm_texture;
|
||||
|
||||
typedef struct fragment_programs {
|
||||
|
@ -186,6 +188,8 @@ typedef struct
|
|||
blend_fragment_programs blendFragmentPrograms;
|
||||
|
||||
gxm_drawstate_cache drawstate;
|
||||
SceClibMspace texturePool;
|
||||
SceUID texturePoolUID;
|
||||
} VITA_GXM_RenderData;
|
||||
|
||||
typedef struct
|
||||
|
|
|
@ -1464,10 +1464,12 @@ default: return "???";
|
|||
static void
|
||||
SDLTest_PrintEvent(SDL_Event * event)
|
||||
{
|
||||
#ifndef VERBOSE_MOTION_EVENTS
|
||||
if ((event->type == SDL_MOUSEMOTION) || (event->type == SDL_FINGERMOTION)) {
|
||||
/* Mouse and finger motion are really spammy */
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (event->type) {
|
||||
case SDL_DISPLAYEVENT:
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
|
||||
typedef unsigned long long ULLONG;
|
||||
|
||||
static SDL_bool ticks_started = SDL_FALSE;
|
||||
static ULONG ulTmrFreq = 0;
|
||||
static ULLONG ullTmrStart = 0;
|
||||
|
||||
|
@ -46,7 +47,14 @@ void
|
|||
SDL_TicksInit(void)
|
||||
{
|
||||
ULONG ulTmrStart; /* for 32-bit fallback. */
|
||||
ULONG ulRC = DosTmrQueryFreq(&ulTmrFreq);
|
||||
ULONG ulRC;
|
||||
|
||||
if (ticks_started) {
|
||||
return;
|
||||
}
|
||||
ticks_started = SDL_TRUE;
|
||||
|
||||
ulRC = DosTmrQueryFreq(&ulTmrFreq);
|
||||
if (ulRC != NO_ERROR) {
|
||||
debug_os2("DosTmrQueryFreq() failed, rc = %u", ulRC);
|
||||
} else {
|
||||
|
@ -65,6 +73,7 @@ SDL_TicksInit(void)
|
|||
void
|
||||
SDL_TicksQuit(void)
|
||||
{
|
||||
ticks_started = SDL_FALSE;
|
||||
}
|
||||
|
||||
Uint64
|
||||
|
@ -73,7 +82,7 @@ SDL_GetTicks64(void)
|
|||
Uint64 ui64Result;
|
||||
ULLONG ullTmrNow;
|
||||
|
||||
if (ulTmrFreq == 0) { /* Was not initialized. */
|
||||
if (!ticks_started) {
|
||||
SDL_TicksInit();
|
||||
}
|
||||
|
||||
|
|
|
@ -394,12 +394,6 @@ 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,
|
||||
|
@ -418,6 +412,12 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc)
|
|||
goto done;
|
||||
}
|
||||
|
||||
if (biBitCount >= 32) { /* we shift biClrUsed by this value later. */
|
||||
SDL_SetError("Unsupported or incorrect biBitCount field");
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (biClrUsed == 0) {
|
||||
biClrUsed = 1 << biBitCount;
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#endif
|
||||
#if SDL_VIDEO_DRIVER_ANDROID
|
||||
#include <android/native_window.h>
|
||||
#include "../core/android/SDL_android.h"
|
||||
#include "../video/android/SDL_androidvideo.h"
|
||||
#endif
|
||||
#if SDL_VIDEO_DRIVER_RPI
|
||||
|
@ -99,7 +98,7 @@
|
|||
#define DEFAULT_OGL_ES "libGLESv1_CM.so.1"
|
||||
#endif /* SDL_VIDEO_DRIVER_RPI */
|
||||
|
||||
#if SDL_VIDEO_OPENGL
|
||||
#if SDL_VIDEO_OPENGL && !SDL_VIDEO_VITA_PVR_OGL
|
||||
#include "SDL_opengl.h"
|
||||
#endif
|
||||
|
||||
|
@ -1062,7 +1061,7 @@ SDL_EGL_CreateContext(_THIS, EGLSurface egl_surface)
|
|||
if (SDL_GL_ExtensionSupported("GL_OES_surfaceless_context")) {
|
||||
_this->gl_allow_no_surface = SDL_TRUE;
|
||||
}
|
||||
#if SDL_VIDEO_OPENGL
|
||||
#if SDL_VIDEO_OPENGL && !defined(SDL_VIDEO_DRIVER_VITA)
|
||||
} else {
|
||||
/* Desktop OpenGL supports it by default from version 3.0 on. */
|
||||
void (APIENTRY * glGetIntegervFunc) (GLenum pname, GLint * params);
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "SDL_blit.h"
|
||||
#include "SDL_pixels_c.h"
|
||||
#include "SDL_RLEaccel_c.h"
|
||||
#include "../SDL_list.h"
|
||||
|
||||
|
||||
/* Lookup tables to expand partial bytes to the full 0..255 range */
|
||||
|
@ -1024,12 +1025,6 @@ SDL_AllocBlitMap(void)
|
|||
}
|
||||
|
||||
|
||||
typedef struct SDL_ListNode
|
||||
{
|
||||
void *entry;
|
||||
struct SDL_ListNode *next;
|
||||
} SDL_ListNode;
|
||||
|
||||
void
|
||||
SDL_InvalidateAllBlitMap(SDL_Surface *surface)
|
||||
{
|
||||
|
@ -1045,40 +1040,6 @@ SDL_InvalidateAllBlitMap(SDL_Surface *surface)
|
|||
}
|
||||
}
|
||||
|
||||
static void SDL_ListAdd(SDL_ListNode **head, void *ent);
|
||||
static void SDL_ListRemove(SDL_ListNode **head, void *ent);
|
||||
|
||||
void
|
||||
SDL_ListAdd(SDL_ListNode **head, void *ent)
|
||||
{
|
||||
SDL_ListNode *node = SDL_malloc(sizeof (*node));
|
||||
|
||||
if (node == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
return;
|
||||
}
|
||||
|
||||
node->entry = ent;
|
||||
node->next = *head;
|
||||
*head = node;
|
||||
}
|
||||
|
||||
void
|
||||
SDL_ListRemove(SDL_ListNode **head, void *ent)
|
||||
{
|
||||
SDL_ListNode **ptr = head;
|
||||
|
||||
while (*ptr) {
|
||||
if ((*ptr)->entry == ent) {
|
||||
SDL_ListNode *tmp = *ptr;
|
||||
*ptr = (*ptr)->next;
|
||||
SDL_free(tmp);
|
||||
return;
|
||||
}
|
||||
ptr = &(*ptr)->next;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SDL_InvalidateMap(SDL_BlitMap * map)
|
||||
{
|
||||
|
|
|
@ -345,6 +345,7 @@ struct SDL_VideoDevice
|
|||
Uint32 next_object_id;
|
||||
char *clipboard_text;
|
||||
SDL_bool setting_display_mode;
|
||||
SDL_bool disable_display_mode_switching;
|
||||
|
||||
/* * * */
|
||||
/* Data used by the GL drivers */
|
||||
|
|
|
@ -1339,14 +1339,17 @@ SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool fullscreen)
|
|||
resized = SDL_FALSE;
|
||||
}
|
||||
|
||||
/* only do the mode change if we want exclusive fullscreen */
|
||||
if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) {
|
||||
if (SDL_SetDisplayModeForDisplay(display, &fullscreen_mode) < 0) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (SDL_SetDisplayModeForDisplay(display, NULL) < 0) {
|
||||
return -1;
|
||||
/* Don't try to change the display mode if the driver doesn't want it. */
|
||||
if (_this->disable_display_mode_switching == SDL_FALSE) {
|
||||
/* only do the mode change if we want exclusive fullscreen */
|
||||
if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) {
|
||||
if (SDL_SetDisplayModeForDisplay(display, &fullscreen_mode) < 0) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (SDL_SetDisplayModeForDisplay(display, NULL) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#include "SDL_emscriptenframebuffer.h"
|
||||
#include "SDL_hints.h"
|
||||
|
||||
#include <emscripten/threading.h>
|
||||
|
||||
|
||||
int Emscripten_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch)
|
||||
{
|
||||
|
@ -57,18 +59,9 @@ int Emscripten_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * form
|
|||
return 0;
|
||||
}
|
||||
|
||||
int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects)
|
||||
static void
|
||||
Emscripten_UpdateWindowFramebufferWorker(SDL_Surface* surface)
|
||||
{
|
||||
SDL_Surface *surface;
|
||||
|
||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
surface = data->surface;
|
||||
if (!surface) {
|
||||
return SDL_SetError("Couldn't find framebuffer surface for window");
|
||||
}
|
||||
|
||||
/* Send the data to the display */
|
||||
|
||||
EM_ASM_INT({
|
||||
var w = $0;
|
||||
var h = $1;
|
||||
|
@ -156,6 +149,29 @@ int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rec
|
|||
SDL2.ctx.putImageData(SDL2.image, 0, 0);
|
||||
return 0;
|
||||
}, surface->w, surface->h, surface->pixels);
|
||||
}
|
||||
|
||||
int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects)
|
||||
{
|
||||
SDL_Surface *surface;
|
||||
|
||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
surface = data->surface;
|
||||
if (!surface) {
|
||||
return SDL_SetError("Couldn't find framebuffer surface for window");
|
||||
}
|
||||
|
||||
/* Send the data to the display */
|
||||
|
||||
if (emscripten_is_main_runtime_thread()) {
|
||||
Emscripten_UpdateWindowFramebufferWorker(surface);
|
||||
} else {
|
||||
emscripten_sync_run_in_main_runtime_thread(
|
||||
EM_FUNC_SIG_VI,
|
||||
Emscripten_UpdateWindowFramebufferWorker,
|
||||
(uint32_t)surface
|
||||
);
|
||||
}
|
||||
|
||||
if (emscripten_has_asyncify() && SDL_GetHintBoolean(SDL_HINT_EMSCRIPTEN_ASYNCIFY, SDL_TRUE)) {
|
||||
/* give back control to browser for screen refresh */
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include <emscripten/emscripten.h>
|
||||
#include <emscripten/html5.h>
|
||||
#include <emscripten/threading.h>
|
||||
|
||||
#include "SDL_emscriptenmouse.h"
|
||||
#include "SDL_emscriptenvideo.h"
|
||||
|
@ -62,19 +63,10 @@ Emscripten_CreateDefaultCursor()
|
|||
return Emscripten_CreateCursorFromString("default", SDL_FALSE);
|
||||
}
|
||||
|
||||
static SDL_Cursor*
|
||||
Emscripten_CreateCursor(SDL_Surface* surface, int hot_x, int hot_y)
|
||||
static const char*
|
||||
Emscripten_GetCursorUrl(int w, int h, int hot_x, int hot_y, void* pixels)
|
||||
{
|
||||
const char *cursor_url = NULL;
|
||||
SDL_Surface *conv_surf;
|
||||
|
||||
conv_surf = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_ABGR8888, 0);
|
||||
|
||||
if (!conv_surf) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cursor_url = (const char *)EM_ASM_INT({
|
||||
return (const char *)EM_ASM_INT({
|
||||
var w = $0;
|
||||
var h = $1;
|
||||
var hot_x = $2;
|
||||
|
@ -122,7 +114,40 @@ Emscripten_CreateCursor(SDL_Surface* surface, int hot_x, int hot_y)
|
|||
stringToUTF8(url, urlBuf, url.length + 1);
|
||||
|
||||
return urlBuf;
|
||||
}, surface->w, surface->h, hot_x, hot_y, conv_surf->pixels);
|
||||
}, w, h, hot_x, hot_y, pixels);
|
||||
}
|
||||
|
||||
static SDL_Cursor*
|
||||
Emscripten_CreateCursor(SDL_Surface* surface, int hot_x, int hot_y)
|
||||
{
|
||||
const char *cursor_url = NULL;
|
||||
SDL_Surface *conv_surf;
|
||||
|
||||
conv_surf = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_ABGR8888, 0);
|
||||
|
||||
if (!conv_surf) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (emscripten_is_main_runtime_thread()) {
|
||||
cursor_url = Emscripten_GetCursorUrl(
|
||||
surface->w,
|
||||
surface->h,
|
||||
hot_x,
|
||||
hot_y,
|
||||
conv_surf->pixels
|
||||
);
|
||||
} else {
|
||||
cursor_url = (const char *)emscripten_sync_run_in_main_runtime_thread(
|
||||
EM_FUNC_SIG_IIIIIII,
|
||||
Emscripten_GetCursorUrl,
|
||||
surface->w,
|
||||
surface->h,
|
||||
hot_x,
|
||||
hot_y,
|
||||
conv_surf->pixels
|
||||
);
|
||||
}
|
||||
|
||||
SDL_FreeSurface(conv_surf);
|
||||
|
||||
|
@ -206,16 +231,15 @@ Emscripten_ShowCursor(SDL_Cursor* cursor)
|
|||
curdata = (Emscripten_CursorData *) cursor->driverdata;
|
||||
|
||||
if(curdata->system_cursor) {
|
||||
EM_ASM_INT({
|
||||
MAIN_THREAD_EM_ASM({
|
||||
if (Module['canvas']) {
|
||||
Module['canvas'].style['cursor'] = UTF8ToString($0);
|
||||
}
|
||||
return 0;
|
||||
}, curdata->system_cursor);
|
||||
}
|
||||
}
|
||||
else {
|
||||
EM_ASM(
|
||||
MAIN_THREAD_EM_ASM(
|
||||
if (Module['canvas']) {
|
||||
Module['canvas'].style['cursor'] = 'none';
|
||||
}
|
||||
|
|
|
@ -174,10 +174,10 @@ Emscripten_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect *
|
|||
if (rect) {
|
||||
rect->x = 0;
|
||||
rect->y = 0;
|
||||
rect->w = EM_ASM_INT_V({
|
||||
rect->w = MAIN_THREAD_EM_ASM_INT({
|
||||
return window.innerWidth;
|
||||
});
|
||||
rect->h = EM_ASM_INT_V({
|
||||
rect->h = MAIN_THREAD_EM_ASM_INT({
|
||||
return window.innerHeight;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -186,8 +186,8 @@ UIKit_ShowMessageBoxAlertView(const SDL_MessageBoxData *messageboxdata, int *but
|
|||
#endif /* __IPHONE_OS_VERSION_MIN_REQUIRED < 80000 */
|
||||
}
|
||||
|
||||
int
|
||||
UIKit_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
|
||||
static void
|
||||
UIKit_ShowMessageBoxImpl(const SDL_MessageBoxData *messageboxdata, int *buttonid, int *returnValue)
|
||||
{
|
||||
BOOL success = NO;
|
||||
|
||||
|
@ -199,12 +199,26 @@ UIKit_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
|
|||
}
|
||||
|
||||
if (!success) {
|
||||
return SDL_SetError("Could not show message box.");
|
||||
*returnValue = SDL_SetError("Could not show message box.");
|
||||
} else {
|
||||
*returnValue = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
UIKit_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
|
||||
{ @autoreleasepool
|
||||
{
|
||||
__block int returnValue = 0;
|
||||
|
||||
if ([NSThread isMainThread]) {
|
||||
UIKit_ShowMessageBoxImpl(messageboxdata, buttonid, &returnValue);
|
||||
} else {
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{ UIKit_ShowMessageBoxImpl(messageboxdata, buttonid, &returnValue); });
|
||||
}
|
||||
return returnValue;
|
||||
}}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_UIKIT */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
@ -20,11 +20,12 @@
|
|||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_VIDEO_DRIVER_VITA && SDL_VIDEO_VITA_PVR
|
||||
#if SDL_VIDEO_DRIVER_VITA && SDL_VIDEO_VITA_PVR && SDL_VIDEO_VITA_PVR_OGL
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <psp2/kernel/modulemgr.h>
|
||||
#include <gpu_es4/psp2_pvr_hint.h>
|
||||
#include <gl4esinit.h>
|
||||
|
||||
#include "SDL_error.h"
|
||||
#include "SDL_log.h"
|
||||
|
@ -34,6 +35,16 @@
|
|||
|
||||
#define MAX_PATH 256 // vita limits are somehow wrong
|
||||
|
||||
/* Defaults */
|
||||
int FB_WIDTH = 960;
|
||||
int FB_HEIGHT = 544;
|
||||
|
||||
void getFBSize(int *width, int *height)
|
||||
{
|
||||
*width = FB_WIDTH;
|
||||
*height = FB_HEIGHT;
|
||||
}
|
||||
|
||||
int
|
||||
VITA_GL_LoadLibrary(_THIS, const char *path)
|
||||
{
|
||||
|
@ -53,6 +64,9 @@ VITA_GL_LoadLibrary(_THIS, const char *path)
|
|||
sceKernelLoadStartModule("vs0:sys/external/libfios2.suprx", 0, NULL, 0, NULL, NULL);
|
||||
sceKernelLoadStartModule("vs0:sys/external/libc.suprx", 0, NULL, 0, NULL, NULL);
|
||||
|
||||
SDL_snprintf(target_path, MAX_PATH, "%s/%s", default_path, "libGL.suprx");
|
||||
sceKernelLoadStartModule(target_path, 0, NULL, 0, NULL, NULL);
|
||||
|
||||
SDL_snprintf(target_path, MAX_PATH, "%s/%s", default_path, "libgpu_es4_ext.suprx");
|
||||
sceKernelLoadStartModule(target_path, 0, NULL, 0, NULL, NULL);
|
||||
|
||||
|
@ -74,30 +88,45 @@ VITA_GL_LoadLibrary(_THIS, const char *path)
|
|||
SDL_GLContext
|
||||
VITA_GL_CreateContext(_THIS, SDL_Window * window)
|
||||
{
|
||||
return SDL_EGL_CreateContext(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);
|
||||
}
|
||||
char gl_version[3];
|
||||
SDL_GLContext context = NULL;
|
||||
int temp_major = _this->gl_config.major_version;
|
||||
int temp_minor = _this->gl_config.minor_version;
|
||||
int temp_profile = _this->gl_config.profile_mask;
|
||||
|
||||
int
|
||||
VITA_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
|
||||
{
|
||||
if (window && context) {
|
||||
return SDL_EGL_MakeCurrent(_this, ((SDL_WindowData *) window->driverdata)->egl_surface, context);
|
||||
} else {
|
||||
return SDL_EGL_MakeCurrent(_this, NULL, NULL);
|
||||
/* Set version to 2.0 and PROFILE to ES */
|
||||
_this->gl_config.major_version = 2;
|
||||
_this->gl_config.minor_version = 0;
|
||||
_this->gl_config.profile_mask = SDL_GL_CONTEXT_PROFILE_ES;
|
||||
|
||||
context = SDL_EGL_CreateContext(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);
|
||||
|
||||
if (context != NULL)
|
||||
{
|
||||
FB_WIDTH = window->w;
|
||||
FB_HEIGHT = window->h;
|
||||
set_getprocaddress((void *(*)(const char *))eglGetProcAddress);
|
||||
set_getmainfbsize(getFBSize);
|
||||
SDL_snprintf(gl_version, 3, "%d%d", temp_major, temp_minor);
|
||||
gl4es_setenv("LIBGL_NOTEXRECT", "1", 1); /* Currently broken in driver */
|
||||
gl4es_setenv("LIBGL_GL", gl_version, 1);
|
||||
initialize_gl4es();
|
||||
}
|
||||
|
||||
/* Restore gl_config */
|
||||
_this->gl_config.major_version = temp_major;
|
||||
_this->gl_config.minor_version = temp_minor;
|
||||
_this->gl_config.profile_mask = temp_profile;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
int
|
||||
VITA_GL_SwapWindow(_THIS, SDL_Window * window)
|
||||
void *
|
||||
VITA_GL_GetProcAddress(_THIS, const char *proc)
|
||||
{
|
||||
SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
|
||||
if (videodata->ime_active) {
|
||||
sceImeUpdate();
|
||||
}
|
||||
return SDL_EGL_SwapBuffers(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);
|
||||
return gl4es_GetProcAddress(proc);
|
||||
}
|
||||
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_VITA && SDL_VIDEO_VITA_PVR */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
@ -19,17 +19,16 @@
|
|||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_vitagl_c_h_
|
||||
#define SDL_vitagl_c_h_
|
||||
#ifndef SDL_vitagl_pvr_c_h_
|
||||
#define SDL_vitagl_pvr_c_h_
|
||||
|
||||
#include "SDL_vitavideo.h"
|
||||
|
||||
extern int VITA_GL_MakeCurrent(_THIS,SDL_Window * window, SDL_GLContext context);
|
||||
extern int VITA_GL_SwapWindow(_THIS, SDL_Window * window);
|
||||
extern SDL_GLContext VITA_GL_CreateContext(_THIS, SDL_Window * window);
|
||||
extern int VITA_GL_LoadLibrary(_THIS, const char *path);
|
||||
extern void *VITA_GL_GetProcAddress(_THIS, const char *proc);
|
||||
|
||||
|
||||
#endif /* SDL_vitagl_c_h_ */
|
||||
#endif /* SDL_vitagl_pvr_c_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "SDL_error.h"
|
||||
#include "SDL_log.h"
|
||||
#include "SDL_vitavideo.h"
|
||||
#include "SDL_vitagl_c.h"
|
||||
#include "SDL_vitagles_c.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
/* SDL OpenGL/OpenGL ES functions */
|
||||
|
@ -45,7 +45,7 @@
|
|||
} while (0)
|
||||
|
||||
void
|
||||
VITA_GL_KeyboardCallback(ScePigletPreSwapData *data)
|
||||
VITA_GLES_KeyboardCallback(ScePigletPreSwapData *data)
|
||||
{
|
||||
SceCommonDialogUpdateParam commonDialogParam;
|
||||
SDL_zero(commonDialogParam);
|
||||
|
@ -62,20 +62,20 @@ VITA_GL_KeyboardCallback(ScePigletPreSwapData *data)
|
|||
}
|
||||
|
||||
int
|
||||
VITA_GL_LoadLibrary(_THIS, const char *path)
|
||||
VITA_GLES_LoadLibrary(_THIS, const char *path)
|
||||
{
|
||||
pibInit(PIB_SHACCCG | PIB_GET_PROC_ADDR_CORE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *
|
||||
VITA_GL_GetProcAddress(_THIS, const char *proc)
|
||||
VITA_GLES_GetProcAddress(_THIS, const char *proc)
|
||||
{
|
||||
return eglGetProcAddress(proc);
|
||||
}
|
||||
|
||||
void
|
||||
VITA_GL_UnloadLibrary(_THIS)
|
||||
VITA_GLES_UnloadLibrary(_THIS)
|
||||
{
|
||||
eglTerminate(_this->gl_data->display);
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ static EGLint width = 960;
|
|||
static EGLint height = 544;
|
||||
|
||||
SDL_GLContext
|
||||
VITA_GL_CreateContext(_THIS, SDL_Window * window)
|
||||
VITA_GLES_CreateContext(_THIS, SDL_Window * window)
|
||||
{
|
||||
|
||||
SDL_WindowData *wdata = (SDL_WindowData *) window->driverdata;
|
||||
|
@ -159,13 +159,13 @@ VITA_GL_CreateContext(_THIS, SDL_Window * window)
|
|||
_this->gl_data->surface = surface;
|
||||
|
||||
preSwapCallback = (PFNEGLPIGLETVITASETPRESWAPCALLBACKSCEPROC) eglGetProcAddress("eglPigletVitaSetPreSwapCallbackSCE");
|
||||
preSwapCallback(VITA_GL_KeyboardCallback);
|
||||
preSwapCallback(VITA_GLES_KeyboardCallback);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
int
|
||||
VITA_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
|
||||
VITA_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
|
||||
{
|
||||
if (!eglMakeCurrent(_this->gl_data->display, _this->gl_data->surface,
|
||||
_this->gl_data->surface, _this->gl_data->context))
|
||||
|
@ -176,7 +176,7 @@ VITA_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
|
|||
}
|
||||
|
||||
int
|
||||
VITA_GL_SetSwapInterval(_THIS, int interval)
|
||||
VITA_GLES_SetSwapInterval(_THIS, int interval)
|
||||
{
|
||||
EGLBoolean status;
|
||||
status = eglSwapInterval(_this->gl_data->display, interval);
|
||||
|
@ -190,13 +190,13 @@ VITA_GL_SetSwapInterval(_THIS, int interval)
|
|||
}
|
||||
|
||||
int
|
||||
VITA_GL_GetSwapInterval(_THIS)
|
||||
VITA_GLES_GetSwapInterval(_THIS)
|
||||
{
|
||||
return _this->gl_data->swapinterval;
|
||||
}
|
||||
|
||||
int
|
||||
VITA_GL_SwapWindow(_THIS, SDL_Window * window)
|
||||
VITA_GLES_SwapWindow(_THIS, SDL_Window * window)
|
||||
{
|
||||
if (!eglSwapBuffers(_this->gl_data->display, _this->gl_data->surface)) {
|
||||
return SDL_SetError("eglSwapBuffers() failed");
|
||||
|
@ -205,7 +205,7 @@ VITA_GL_SwapWindow(_THIS, SDL_Window * window)
|
|||
}
|
||||
|
||||
void
|
||||
VITA_GL_DeleteContext(_THIS, SDL_GLContext context)
|
||||
VITA_GLES_DeleteContext(_THIS, SDL_GLContext context)
|
||||
{
|
||||
SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
|
||||
EGLBoolean status;
|
|
@ -19,8 +19,8 @@
|
|||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SDL_vitagl_c_h_
|
||||
#define SDL_vitagl_c_h_
|
||||
#ifndef SDL_vitagles_c_h_
|
||||
#define SDL_vitagles_c_h_
|
||||
|
||||
|
||||
#include <pib.h>
|
||||
|
@ -39,19 +39,19 @@ typedef struct SDL_GLDriverData {
|
|||
uint32_t swapinterval;
|
||||
}SDL_GLDriverData;
|
||||
|
||||
extern void * VITA_GL_GetProcAddress(_THIS, const char *proc);
|
||||
extern int VITA_GL_MakeCurrent(_THIS,SDL_Window * window, SDL_GLContext context);
|
||||
extern void VITA_GL_SwapBuffers(_THIS);
|
||||
extern void * VITA_GLES_GetProcAddress(_THIS, const char *proc);
|
||||
extern int VITA_GLES_MakeCurrent(_THIS,SDL_Window * window, SDL_GLContext context);
|
||||
extern void VITA_GLES_SwapBuffers(_THIS);
|
||||
|
||||
extern int VITA_GL_SwapWindow(_THIS, SDL_Window * window);
|
||||
extern SDL_GLContext VITA_GL_CreateContext(_THIS, SDL_Window * window);
|
||||
extern int VITA_GLES_SwapWindow(_THIS, SDL_Window * window);
|
||||
extern SDL_GLContext VITA_GLES_CreateContext(_THIS, SDL_Window * window);
|
||||
|
||||
extern int VITA_GL_LoadLibrary(_THIS, const char *path);
|
||||
extern void VITA_GL_UnloadLibrary(_THIS);
|
||||
extern int VITA_GL_SetSwapInterval(_THIS, int interval);
|
||||
extern int VITA_GL_GetSwapInterval(_THIS);
|
||||
extern int VITA_GLES_LoadLibrary(_THIS, const char *path);
|
||||
extern void VITA_GLES_UnloadLibrary(_THIS);
|
||||
extern int VITA_GLES_SetSwapInterval(_THIS, int interval);
|
||||
extern int VITA_GLES_GetSwapInterval(_THIS);
|
||||
|
||||
|
||||
#endif /* SDL_vitagl_c_h_ */
|
||||
#endif /* SDL_vitagles_c_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_VIDEO_DRIVER_VITA && SDL_VIDEO_VITA_PVR
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <psp2/kernel/modulemgr.h>
|
||||
#include <gpu_es4/psp2_pvr_hint.h>
|
||||
|
||||
#include "SDL_error.h"
|
||||
#include "SDL_log.h"
|
||||
#include "SDL_vitavideo.h"
|
||||
#include "../SDL_egl_c.h"
|
||||
#include "SDL_vitagles_pvr_c.h"
|
||||
|
||||
#define MAX_PATH 256 // vita limits are somehow wrong
|
||||
|
||||
int
|
||||
VITA_GLES_LoadLibrary(_THIS, const char *path)
|
||||
{
|
||||
PVRSRV_PSP2_APPHINT hint;
|
||||
char* override = SDL_getenv("VITA_MODULE_PATH");
|
||||
char* skip_init = SDL_getenv("VITA_PVR_SKIP_INIT");
|
||||
char* default_path = "app0:module";
|
||||
char target_path[MAX_PATH];
|
||||
|
||||
if (skip_init == NULL) // we don't care about actual value
|
||||
{
|
||||
if (override != NULL)
|
||||
{
|
||||
default_path = override;
|
||||
}
|
||||
|
||||
sceKernelLoadStartModule("vs0:sys/external/libfios2.suprx", 0, NULL, 0, NULL, NULL);
|
||||
sceKernelLoadStartModule("vs0:sys/external/libc.suprx", 0, NULL, 0, NULL, NULL);
|
||||
|
||||
SDL_snprintf(target_path, MAX_PATH, "%s/%s", default_path, "libgpu_es4_ext.suprx");
|
||||
sceKernelLoadStartModule(target_path, 0, NULL, 0, NULL, NULL);
|
||||
|
||||
SDL_snprintf(target_path, MAX_PATH, "%s/%s", default_path, "libIMGEGL.suprx");
|
||||
sceKernelLoadStartModule(target_path, 0, NULL, 0, NULL, NULL);
|
||||
|
||||
PVRSRVInitializeAppHint(&hint);
|
||||
|
||||
SDL_snprintf(hint.szGLES1, MAX_PATH, "%s/%s", default_path, "libGLESv1_CM.suprx");
|
||||
SDL_snprintf(hint.szGLES2, MAX_PATH, "%s/%s", default_path, "libGLESv2.suprx");
|
||||
SDL_snprintf(hint.szWindowSystem, MAX_PATH, "%s/%s", default_path, "libpvrPSP2_WSEGL.suprx");
|
||||
|
||||
PVRSRVCreateVirtualAppHint(&hint);
|
||||
}
|
||||
|
||||
return SDL_EGL_LoadLibrary(_this, path, (NativeDisplayType) 0, 0);
|
||||
}
|
||||
|
||||
SDL_GLContext
|
||||
VITA_GLES_CreateContext(_THIS, SDL_Window * window)
|
||||
{
|
||||
return SDL_EGL_CreateContext(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);
|
||||
}
|
||||
|
||||
int
|
||||
VITA_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
|
||||
{
|
||||
if (window && context) {
|
||||
return SDL_EGL_MakeCurrent(_this, ((SDL_WindowData *) window->driverdata)->egl_surface, context);
|
||||
} else {
|
||||
return SDL_EGL_MakeCurrent(_this, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
VITA_GLES_SwapWindow(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
|
||||
if (videodata->ime_active) {
|
||||
sceImeUpdate();
|
||||
}
|
||||
return SDL_EGL_SwapBuffers(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);
|
||||
}
|
||||
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_VITA && SDL_VIDEO_VITA_PVR */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef SDL_vitagles_pvr_c_h_
|
||||
#define SDL_vitagles_pvr_c_h_
|
||||
|
||||
#include "SDL_vitavideo.h"
|
||||
|
||||
extern int VITA_GLES_MakeCurrent(_THIS,SDL_Window * window, SDL_GLContext context);
|
||||
extern int VITA_GLES_SwapWindow(_THIS, SDL_Window * window);
|
||||
extern SDL_GLContext VITA_GLES_CreateContext(_THIS, SDL_Window * window);
|
||||
extern int VITA_GLES_LoadLibrary(_THIS, const char *path);
|
||||
|
||||
|
||||
#endif /* SDL_vitagles_pvr_c_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
|
@ -41,15 +41,17 @@
|
|||
#include "SDL_vitaframebuffer.h"
|
||||
|
||||
#if defined(SDL_VIDEO_VITA_PIB)
|
||||
#include "SDL_vitagl_c.h"
|
||||
#include "SDL_vitagles_c.h"
|
||||
#elif defined(SDL_VIDEO_VITA_PVR)
|
||||
#include "SDL_vitagles_pvr_c.h"
|
||||
#if defined(SDL_VIDEO_VITA_PVR_OGL)
|
||||
#include "SDL_vitagl_pvr_c.h"
|
||||
#include "../SDL_egl_c.h"
|
||||
#define VITA_GL_GetProcAddress SDL_EGL_GetProcAddress
|
||||
#define VITA_GL_UnloadLibrary SDL_EGL_UnloadLibrary
|
||||
#define VITA_GL_SetSwapInterval SDL_EGL_SetSwapInterval
|
||||
#define VITA_GL_GetSwapInterval SDL_EGL_GetSwapInterval
|
||||
#define VITA_GL_DeleteContext SDL_EGL_DeleteContext
|
||||
#endif
|
||||
#define VITA_GLES_GetProcAddress SDL_EGL_GetProcAddress
|
||||
#define VITA_GLES_UnloadLibrary SDL_EGL_UnloadLibrary
|
||||
#define VITA_GLES_SetSwapInterval SDL_EGL_SetSwapInterval
|
||||
#define VITA_GLES_GetSwapInterval SDL_EGL_GetSwapInterval
|
||||
#define VITA_GLES_DeleteContext SDL_EGL_DeleteContext
|
||||
#endif
|
||||
|
||||
SDL_Window *Vita_Window;
|
||||
|
@ -140,15 +142,26 @@ VITA_Create()
|
|||
*/
|
||||
|
||||
#if defined(SDL_VIDEO_VITA_PIB) || defined(SDL_VIDEO_VITA_PVR)
|
||||
#if defined(SDL_VIDEO_VITA_PVR_OGL)
|
||||
if(SDL_getenv("VITA_PVR_OGL") != NULL) {
|
||||
device->GL_LoadLibrary = VITA_GL_LoadLibrary;
|
||||
device->GL_GetProcAddress = VITA_GL_GetProcAddress;
|
||||
device->GL_UnloadLibrary = VITA_GL_UnloadLibrary;
|
||||
device->GL_CreateContext = VITA_GL_CreateContext;
|
||||
device->GL_MakeCurrent = VITA_GL_MakeCurrent;
|
||||
device->GL_SetSwapInterval = VITA_GL_SetSwapInterval;
|
||||
device->GL_GetSwapInterval = VITA_GL_GetSwapInterval;
|
||||
device->GL_SwapWindow = VITA_GL_SwapWindow;
|
||||
device->GL_DeleteContext = VITA_GL_DeleteContext;
|
||||
device->GL_GetProcAddress = VITA_GL_GetProcAddress;
|
||||
} else {
|
||||
#endif
|
||||
device->GL_LoadLibrary = VITA_GLES_LoadLibrary;
|
||||
device->GL_CreateContext = VITA_GLES_CreateContext;
|
||||
device->GL_GetProcAddress = VITA_GLES_GetProcAddress;
|
||||
#if defined(SDL_VIDEO_VITA_PVR_OGL)
|
||||
}
|
||||
#endif
|
||||
|
||||
device->GL_UnloadLibrary = VITA_GLES_UnloadLibrary;
|
||||
device->GL_MakeCurrent = VITA_GLES_MakeCurrent;
|
||||
device->GL_SetSwapInterval = VITA_GLES_SetSwapInterval;
|
||||
device->GL_GetSwapInterval = VITA_GLES_GetSwapInterval;
|
||||
device->GL_SwapWindow = VITA_GLES_SwapWindow;
|
||||
device->GL_DeleteContext = VITA_GLES_DeleteContext;
|
||||
#endif
|
||||
|
||||
device->HasScreenKeyboardSupport = VITA_HasScreenKeyboardSupport;
|
||||
|
@ -245,6 +258,9 @@ VITA_CreateWindow(_THIS, SDL_Window * window)
|
|||
SDL_WindowData *wdata;
|
||||
#if defined(SDL_VIDEO_VITA_PVR)
|
||||
Psp2NativeWindow win;
|
||||
int temp_major = 2;
|
||||
int temp_minor = 1;
|
||||
int temp_profile = 0;
|
||||
#endif
|
||||
|
||||
/* Allocate window internal data */
|
||||
|
@ -282,11 +298,26 @@ VITA_CreateWindow(_THIS, SDL_Window * window)
|
|||
win.windowSize = PSP2_WINDOW_960X544;
|
||||
}
|
||||
if ((window->flags & SDL_WINDOW_OPENGL) != 0) {
|
||||
wdata->egl_surface = SDL_EGL_CreateSurface(_this, &win);
|
||||
if(SDL_getenv("VITA_PVR_OGL") != NULL) {
|
||||
/* Set version to 2.1 and PROFILE to ES */
|
||||
temp_major = _this->gl_config.major_version;
|
||||
temp_minor = _this->gl_config.minor_version;
|
||||
temp_profile = _this->gl_config.profile_mask;
|
||||
|
||||
_this->gl_config.major_version = 2;
|
||||
_this->gl_config.minor_version = 1;
|
||||
_this->gl_config.profile_mask = SDL_GL_CONTEXT_PROFILE_ES;
|
||||
}
|
||||
wdata->egl_surface = SDL_EGL_CreateSurface(_this, &win);
|
||||
if (wdata->egl_surface == EGL_NO_SURFACE) {
|
||||
return SDL_SetError("Could not create GLES window surface");
|
||||
}
|
||||
if(SDL_getenv("VITA_PVR_OGL") != NULL) {
|
||||
/* Revert */
|
||||
_this->gl_config.major_version = temp_major;
|
||||
_this->gl_config.minor_version = temp_minor;
|
||||
_this->gl_config.profile_mask = temp_profile;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -90,16 +90,23 @@ SDL_bool VITA_GetWindowWMInfo(_THIS, SDL_Window * window,
|
|||
struct SDL_SysWMinfo *info);
|
||||
|
||||
#if SDL_VIDEO_DRIVER_VITA
|
||||
#if defined(SDL_VIDEO_VITA_PVR_OGL)
|
||||
/* OpenGL functions */
|
||||
int VITA_GL_LoadLibrary(_THIS, const char *path);
|
||||
void *VITA_GL_GetProcAddress(_THIS, const char *proc);
|
||||
void VITA_GL_UnloadLibrary(_THIS);
|
||||
SDL_GLContext VITA_GL_CreateContext(_THIS, SDL_Window * window);
|
||||
int VITA_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context);
|
||||
int VITA_GL_SetSwapInterval(_THIS, int interval);
|
||||
int VITA_GL_GetSwapInterval(_THIS);
|
||||
int VITA_GL_SwapWindow(_THIS, SDL_Window * window);
|
||||
void VITA_GL_DeleteContext(_THIS, SDL_GLContext context);
|
||||
void *VITA_GL_GetProcAddress(_THIS, const char *proc);
|
||||
#endif
|
||||
|
||||
/* OpenGLES functions */
|
||||
int VITA_GLES_LoadLibrary(_THIS, const char *path);
|
||||
void *VITA_GLES_GetProcAddress(_THIS, const char *proc);
|
||||
void VITA_GLES_UnloadLibrary(_THIS);
|
||||
SDL_GLContext VITA_GLES_CreateContext(_THIS, SDL_Window * window);
|
||||
int VITA_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context);
|
||||
int VITA_GLES_SetSwapInterval(_THIS, int interval);
|
||||
int VITA_GLES_GetSwapInterval(_THIS);
|
||||
int VITA_GLES_SwapWindow(_THIS, SDL_Window * window);
|
||||
void VITA_GLES_DeleteContext(_THIS, SDL_GLContext context);
|
||||
#endif
|
||||
|
||||
/* VITA on screen keyboard */
|
||||
|
|
|
@ -389,8 +389,10 @@ pointer_handle_motion(void *data, struct wl_pointer *pointer,
|
|||
input->sx_w = sx_w;
|
||||
input->sy_w = sy_w;
|
||||
if (input->pointer_focus) {
|
||||
const int sx = wl_fixed_to_int(sx_w);
|
||||
const int sy = wl_fixed_to_int(sy_w);
|
||||
const float sx_f = (float)wl_fixed_to_double(sx_w);
|
||||
const float sy_f = (float)wl_fixed_to_double(sy_w);
|
||||
const int sx = (int)SDL_lroundf(sx_f * window->pointer_scale_x);
|
||||
const int sy = (int)SDL_lroundf(sy_f * window->pointer_scale_y);
|
||||
SDL_SendMouseMotion(window->sdlwindow, 0, 0, sx, sy);
|
||||
}
|
||||
}
|
||||
|
@ -717,8 +719,8 @@ touch_handler_down(void *data, struct wl_touch *touch, unsigned int serial,
|
|||
int id, wl_fixed_t fx, wl_fixed_t fy)
|
||||
{
|
||||
SDL_WindowData *window_data = (SDL_WindowData *)wl_surface_get_user_data(surface);
|
||||
const double dblx = wl_fixed_to_double(fx);
|
||||
const double dbly = wl_fixed_to_double(fy);
|
||||
const double dblx = wl_fixed_to_double(fx) * window_data->pointer_scale_x;
|
||||
const double dbly = wl_fixed_to_double(fy) * window_data->pointer_scale_y;
|
||||
const float x = dblx / window_data->sdlwindow->w;
|
||||
const float y = dbly / window_data->sdlwindow->h;
|
||||
|
||||
|
@ -750,8 +752,8 @@ touch_handler_motion(void *data, struct wl_touch *touch, unsigned int timestamp,
|
|||
int id, wl_fixed_t fx, wl_fixed_t fy)
|
||||
{
|
||||
SDL_WindowData *window_data = (SDL_WindowData *)wl_surface_get_user_data(touch_surface(id));
|
||||
const double dblx = wl_fixed_to_double(fx);
|
||||
const double dbly = wl_fixed_to_double(fy);
|
||||
const double dblx = wl_fixed_to_double(fx) * window_data->pointer_scale_x;
|
||||
const double dbly = wl_fixed_to_double(fy) * window_data->pointer_scale_y;
|
||||
const float x = dblx / window_data->sdlwindow->w;
|
||||
const float y = dbly / window_data->sdlwindow->h;
|
||||
|
||||
|
@ -919,7 +921,7 @@ keyboard_handle_leave(void *data, struct wl_keyboard *keyboard,
|
|||
}
|
||||
|
||||
static SDL_bool
|
||||
keyboard_input_get_text(char text[8], const struct SDL_WaylandInput *input, uint32_t key, SDL_bool *handled_by_ime)
|
||||
keyboard_input_get_text(char text[8], const struct SDL_WaylandInput *input, uint32_t key, Uint8 state, SDL_bool *handled_by_ime)
|
||||
{
|
||||
SDL_WindowData *window = input->keyboard_focus;
|
||||
const xkb_keysym_t *syms;
|
||||
|
@ -936,12 +938,16 @@ keyboard_input_get_text(char text[8], const struct SDL_WaylandInput *input, uint
|
|||
sym = syms[0];
|
||||
|
||||
#ifdef SDL_USE_IME
|
||||
if (SDL_IME_ProcessKeyEvent(sym, key + 8)) {
|
||||
if (SDL_IME_ProcessKeyEvent(sym, key + 8, state)) {
|
||||
*handled_by_ime = SDL_TRUE;
|
||||
return SDL_TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (state == SDL_RELEASED) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (input->xkb.compose_state && WAYLAND_xkb_compose_state_feed(input->xkb.compose_state, sym) == XKB_COMPOSE_FEED_ACCEPTED) {
|
||||
switch(WAYLAND_xkb_compose_state_get_status(input->xkb.compose_state)) {
|
||||
case XKB_COMPOSE_COMPOSING:
|
||||
|
@ -975,7 +981,7 @@ keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
|
|||
SDL_bool handled_by_ime = SDL_FALSE;
|
||||
|
||||
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
||||
has_text = keyboard_input_get_text(text, input, key, &handled_by_ime);
|
||||
has_text = keyboard_input_get_text(text, input, key, SDL_PRESSED, &handled_by_ime);
|
||||
} else {
|
||||
if (keyboard_repeat_is_set(&input->keyboard_repeat)) {
|
||||
// Send any due key repeat events before stopping the repeat and generating the key up event
|
||||
|
@ -985,6 +991,7 @@ keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
|
|||
keyboard_repeat_handle(&input->keyboard_repeat, time - input->keyboard_repeat.wl_press_time);
|
||||
keyboard_repeat_clear(&input->keyboard_repeat);
|
||||
}
|
||||
keyboard_input_get_text(text, input, key, SDL_RELEASED, &handled_by_ime);
|
||||
}
|
||||
|
||||
if (!handled_by_ime && key < SDL_arraysize(xfree86_scancode_table2)) {
|
||||
|
@ -1817,8 +1824,10 @@ tablet_tool_handle_motion(void* data, struct zwp_tablet_tool_v2* tool, wl_fixed_
|
|||
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);
|
||||
const float sx_f = (float)wl_fixed_to_double(sx_w);
|
||||
const float sy_f = (float)wl_fixed_to_double(sy_w);
|
||||
const int sx = (int)SDL_lroundf(sx_f * window->pointer_scale_x);
|
||||
const int sy = (int)SDL_lroundf(sy_f * window->pointer_scale_y);
|
||||
SDL_SendMouseMotion(window->sdlwindow, 0, 0, sx, sy);
|
||||
}
|
||||
}
|
||||
|
@ -2345,12 +2354,19 @@ int Wayland_input_confine_pointer(struct SDL_WaylandInput *input, SDL_Window *wi
|
|||
if (SDL_RectEmpty(&window->mouse_rect)) {
|
||||
confine_rect = NULL;
|
||||
} else {
|
||||
SDL_Rect scaled_mouse_rect;
|
||||
|
||||
scaled_mouse_rect.x = (int)SDL_floorf((float)window->mouse_rect.x / w->pointer_scale_x);
|
||||
scaled_mouse_rect.y = (int)SDL_floorf((float)window->mouse_rect.y / w->pointer_scale_y);
|
||||
scaled_mouse_rect.w = (int)SDL_ceilf((float)window->mouse_rect.w / w->pointer_scale_x);
|
||||
scaled_mouse_rect.h = (int)SDL_ceilf((float)window->mouse_rect.h / w->pointer_scale_y);
|
||||
|
||||
confine_rect = wl_compositor_create_region(d->compositor);
|
||||
wl_region_add(confine_rect,
|
||||
window->mouse_rect.x,
|
||||
window->mouse_rect.y,
|
||||
window->mouse_rect.w,
|
||||
window->mouse_rect.h);
|
||||
scaled_mouse_rect.x,
|
||||
scaled_mouse_rect.y,
|
||||
scaled_mouse_rect.w,
|
||||
scaled_mouse_rect.h);
|
||||
}
|
||||
|
||||
confined_pointer =
|
||||
|
|
|
@ -205,11 +205,11 @@ Wayland_GLES_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h)
|
|||
data = (SDL_WindowData *) window->driverdata;
|
||||
|
||||
if (w) {
|
||||
*w = window->w * data->scale_factor;
|
||||
*w = data->drawable_width;
|
||||
}
|
||||
|
||||
if (h) {
|
||||
*h = window->h * data->scale_factor;
|
||||
*h = data->drawable_height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "text-input-unstable-v3-client-protocol.h"
|
||||
#include "tablet-unstable-v2-client-protocol.h"
|
||||
#include "xdg-output-unstable-v1-client-protocol.h"
|
||||
#include "viewporter-client-protocol.h"
|
||||
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
#include <libdecor.h>
|
||||
|
@ -278,6 +279,8 @@ Wayland_CreateDevice(int devindex)
|
|||
|
||||
device->free = Wayland_DeleteDevice;
|
||||
|
||||
device->disable_display_mode_switching = SDL_TRUE;
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
|
@ -294,6 +297,7 @@ xdg_output_handle_logical_position(void *data, struct zxdg_output_v1 *xdg_output
|
|||
|
||||
driverdata->x = x;
|
||||
driverdata->y = y;
|
||||
driverdata->has_logical_position = SDL_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -302,8 +306,28 @@ xdg_output_handle_logical_size(void *data, struct zxdg_output_v1 *xdg_output,
|
|||
{
|
||||
SDL_WaylandOutputData* driverdata = data;
|
||||
|
||||
if (driverdata->width != 0 && driverdata->height != 0) {
|
||||
/* FIXME: GNOME has a bug where the logical size does not account for
|
||||
* scale, resulting in bogus viewport sizes.
|
||||
*
|
||||
* Until this is fixed, validate that _some_ kind of scaling is being
|
||||
* done (we can't match exactly because fractional scaling can't be
|
||||
* detected otherwise), then override if necessary.
|
||||
* -flibit
|
||||
*/
|
||||
const float scale = (float) driverdata->width / (float) width;
|
||||
if ((scale == 1.0f) && (driverdata->scale_factor != 1.0f)) {
|
||||
SDL_LogWarn(
|
||||
SDL_LOG_CATEGORY_VIDEO,
|
||||
"xdg_output scale did not match, overriding with wl_output scale"
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
driverdata->width = width;
|
||||
driverdata->height = height;
|
||||
driverdata->has_logical_size = SDL_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -340,6 +364,80 @@ static const struct zxdg_output_v1_listener xdg_output_listener = {
|
|||
xdg_output_handle_description,
|
||||
};
|
||||
|
||||
static void
|
||||
AddEmulatedModes(SDL_VideoDisplay *dpy, SDL_bool rot_90)
|
||||
{
|
||||
struct EmulatedMode
|
||||
{
|
||||
int w;
|
||||
int h;
|
||||
};
|
||||
|
||||
/* Resolution lists courtesy of XWayland */
|
||||
const struct EmulatedMode mode_list[] = {
|
||||
/* 16:9 (1.77) */
|
||||
{ 7680, 4320 },
|
||||
{ 6144, 3160 },
|
||||
{ 5120, 2880 },
|
||||
{ 4096, 2304 },
|
||||
{ 3840, 2160 },
|
||||
{ 3200, 1800 },
|
||||
{ 2880, 1620 },
|
||||
{ 2560, 1440 },
|
||||
{ 2048, 1152 },
|
||||
{ 1920, 1080 },
|
||||
{ 1600, 900 },
|
||||
{ 1368, 768 },
|
||||
{ 1280, 720 },
|
||||
{ 864, 486 },
|
||||
|
||||
/* 16:10 (1.6) */
|
||||
{ 2560, 1600 },
|
||||
{ 1920, 1200 },
|
||||
{ 1680, 1050 },
|
||||
{ 1440, 900 },
|
||||
{ 1280, 800 },
|
||||
|
||||
/* 3:2 (1.5) */
|
||||
{ 720, 480 },
|
||||
|
||||
/* 4:3 (1.33) */
|
||||
{ 2048, 1536 },
|
||||
{ 1920, 1440 },
|
||||
{ 1600, 1200 },
|
||||
{ 1440, 1080 },
|
||||
{ 1400, 1050 },
|
||||
{ 1280, 1024 },
|
||||
{ 1280, 960 },
|
||||
{ 1152, 864 },
|
||||
{ 1024, 768 },
|
||||
{ 800, 600 },
|
||||
{ 640, 480 }
|
||||
};
|
||||
|
||||
int i;
|
||||
const int native_width = dpy->display_modes->w;
|
||||
const int native_height = dpy->display_modes->h;
|
||||
|
||||
for (i = 0; i < SDL_arraysize(mode_list); ++i) {
|
||||
/* Only add modes that are smaller than the native mode */
|
||||
if ((mode_list[i].w < native_width && mode_list[i].h < native_height) ||
|
||||
(mode_list[i].w < native_width && mode_list[i].h == native_height)) {
|
||||
SDL_DisplayMode mode = *dpy->display_modes;
|
||||
|
||||
if (rot_90) {
|
||||
mode.w = mode_list[i].h;
|
||||
mode.h = mode_list[i].w;
|
||||
} else {
|
||||
mode.w = mode_list[i].w;
|
||||
mode.h = mode_list[i].h;
|
||||
}
|
||||
|
||||
SDL_AddDisplayMode(dpy, &mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
display_handle_geometry(void *data,
|
||||
struct wl_output *output,
|
||||
|
@ -371,7 +469,7 @@ display_handle_geometry(void *data,
|
|||
}
|
||||
|
||||
/* Apply the change from wl-output only if xdg-output is not supported */
|
||||
if (driverdata->xdg_output) {
|
||||
if (!driverdata->has_logical_position) {
|
||||
driverdata->x = x;
|
||||
driverdata->y = y;
|
||||
}
|
||||
|
@ -421,43 +519,22 @@ display_handle_mode(void *data,
|
|||
int refresh)
|
||||
{
|
||||
SDL_WaylandOutputData* driverdata = data;
|
||||
SDL_DisplayMode mode;
|
||||
|
||||
if (flags & WL_OUTPUT_MODE_CURRENT) {
|
||||
driverdata->native_width = width;
|
||||
driverdata->native_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) {
|
||||
if (!driverdata->has_logical_size) {
|
||||
driverdata->width = width;
|
||||
driverdata->height = height;
|
||||
}
|
||||
|
||||
driverdata->refresh = refresh;
|
||||
}
|
||||
|
||||
/* Note that the width/height are NOT multiplied by scale_factor!
|
||||
* This is intentional and is designed to get the unscaled modes, which is
|
||||
* important for high-DPI games intending to use the display mode as the
|
||||
* target drawable size. The scaled desktop mode will be added at the end
|
||||
* when display_handle_done is called (see below).
|
||||
*/
|
||||
SDL_zero(mode);
|
||||
mode.format = SDL_PIXELFORMAT_RGB888;
|
||||
if (driverdata->transform & WL_OUTPUT_TRANSFORM_90) {
|
||||
mode.w = height;
|
||||
mode.h = width;
|
||||
} else {
|
||||
mode.w = width;
|
||||
mode.h = height;
|
||||
}
|
||||
mode.refresh_rate = (int)SDL_round(refresh / 1000.0); /* mHz to Hz */
|
||||
mode.driverdata = driverdata->output;
|
||||
if (driverdata->index > -1) {
|
||||
SDL_AddDisplayMode(SDL_GetDisplay(driverdata->index), &mode);
|
||||
} else {
|
||||
SDL_AddDisplayMode(&driverdata->placeholder, &mode);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -465,7 +542,8 @@ display_handle_done(void *data,
|
|||
struct wl_output *output)
|
||||
{
|
||||
SDL_WaylandOutputData* driverdata = data;
|
||||
SDL_DisplayMode mode;
|
||||
SDL_VideoData* video = driverdata->videodata;
|
||||
SDL_DisplayMode native_mode, desktop_mode;
|
||||
SDL_VideoDisplay *dpy;
|
||||
|
||||
/*
|
||||
|
@ -482,19 +560,51 @@ display_handle_done(void *data,
|
|||
return;
|
||||
}
|
||||
|
||||
SDL_zero(mode);
|
||||
mode.format = SDL_PIXELFORMAT_RGB888;
|
||||
/* The native display resolution */
|
||||
SDL_zero(native_mode);
|
||||
native_mode.format = SDL_PIXELFORMAT_RGB888;
|
||||
|
||||
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;
|
||||
if (driverdata->transform & WL_OUTPUT_TRANSFORM_90) {
|
||||
native_mode.w = driverdata->native_height;
|
||||
native_mode.h = driverdata->native_width;
|
||||
} else {
|
||||
mode.w = driverdata->width / driverdata->scale_factor;
|
||||
mode.h = driverdata->height / driverdata->scale_factor;
|
||||
native_mode.w = driverdata->native_width;
|
||||
native_mode.h = driverdata->native_height;
|
||||
}
|
||||
native_mode.refresh_rate = (int)SDL_round(driverdata->refresh / 1000.0); /* mHz to Hz */
|
||||
native_mode.driverdata = driverdata->output;
|
||||
|
||||
/* The scaled desktop mode */
|
||||
SDL_zero(desktop_mode);
|
||||
desktop_mode.format = SDL_PIXELFORMAT_RGB888;
|
||||
|
||||
/* Scale the desktop coordinates, if xdg-output isn't present */
|
||||
if (!driverdata->has_logical_size) {
|
||||
driverdata->width /= driverdata->scale_factor;
|
||||
driverdata->height /= driverdata->scale_factor;
|
||||
}
|
||||
|
||||
/* xdg-output dimensions are already transformed, so no need to rotate. */
|
||||
if (driverdata->has_logical_size || !(driverdata->transform & WL_OUTPUT_TRANSFORM_90)) {
|
||||
desktop_mode.w = driverdata->width;
|
||||
desktop_mode.h = driverdata->height;
|
||||
} else {
|
||||
desktop_mode.w = driverdata->height;
|
||||
desktop_mode.h = driverdata->width;
|
||||
}
|
||||
desktop_mode.refresh_rate = (int)SDL_round(driverdata->refresh / 1000.0); /* mHz to Hz */
|
||||
desktop_mode.driverdata = driverdata->output;
|
||||
|
||||
/*
|
||||
* The native display mode is only exposed separately from the desktop size if:
|
||||
* the desktop is scaled and the wp_viewporter protocol is supported.
|
||||
*/
|
||||
if (driverdata->scale_factor > 1.0f && video->viewporter != NULL) {
|
||||
if (driverdata->index > -1) {
|
||||
SDL_AddDisplayMode(SDL_GetDisplay(driverdata->index), &native_mode);
|
||||
} else {
|
||||
SDL_AddDisplayMode(&driverdata->placeholder, &native_mode);
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate the display DPI */
|
||||
|
@ -522,18 +632,20 @@ display_handle_done(void *data,
|
|||
((float) driverdata->physical_height) / 25.4f);
|
||||
}
|
||||
|
||||
mode.refresh_rate = (int)SDL_round(driverdata->refresh / 1000.0); /* mHz to Hz */
|
||||
mode.driverdata = driverdata->output;
|
||||
|
||||
if (driverdata->index > -1) {
|
||||
dpy = SDL_GetDisplay(driverdata->index);
|
||||
} else {
|
||||
dpy = &driverdata->placeholder;
|
||||
}
|
||||
|
||||
SDL_AddDisplayMode(dpy, &mode);
|
||||
SDL_SetCurrentDisplayMode(dpy, &mode);
|
||||
SDL_SetDesktopDisplayMode(dpy, &mode);
|
||||
SDL_AddDisplayMode(dpy, &desktop_mode);
|
||||
SDL_SetCurrentDisplayMode(dpy, &desktop_mode);
|
||||
SDL_SetDesktopDisplayMode(dpy, &desktop_mode);
|
||||
|
||||
/* Add emulated modes if wp_viewporter is supported. */
|
||||
if (video->viewporter) {
|
||||
AddEmulatedModes(dpy, (driverdata->transform & WL_OUTPUT_TRANSFORM_90) != 0);
|
||||
}
|
||||
|
||||
if (driverdata->index == -1) {
|
||||
/* First time getting display info, create the VideoDisplay */
|
||||
|
@ -580,7 +692,7 @@ Wayland_add_display(SDL_VideoData *d, uint32_t id)
|
|||
data->videodata = d;
|
||||
data->output = output;
|
||||
data->registry_id = id;
|
||||
data->scale_factor = 1.0;
|
||||
data->scale_factor = 1.0f;
|
||||
data->index = -1;
|
||||
|
||||
wl_output_add_listener(output, &output_listener, data);
|
||||
|
@ -736,6 +848,8 @@ display_handle_global(void *data, struct wl_registry *registry, uint32_t id,
|
|||
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);
|
||||
} else if (SDL_strcmp(interface, "wp_viewporter") == 0) {
|
||||
d->viewporter = wl_registry_bind(d->registry, id, &wp_viewporter_interface, 1);
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
|
||||
} else if (SDL_strcmp(interface, "qt_touch_extension") == 0) {
|
||||
|
@ -762,6 +876,29 @@ static const struct wl_registry_listener registry_listener = {
|
|||
display_handle_global,
|
||||
display_remove_global
|
||||
};
|
||||
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
static SDL_bool should_use_libdecor(SDL_VideoData *data)
|
||||
{
|
||||
if (!SDL_WAYLAND_HAVE_WAYLAND_LIBDECOR) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (!SDL_GetHintBoolean(SDL_HINT_VIDEO_WAYLAND_ALLOW_LIBDECOR, SDL_TRUE)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (SDL_GetHintBoolean(SDL_HINT_VIDEO_WAYLAND_PREFER_LIBDECOR, SDL_FALSE)) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
if (data->decoration_manager) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
Wayland_VideoInit(_THIS)
|
||||
|
@ -785,7 +922,7 @@ Wayland_VideoInit(_THIS)
|
|||
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
/* Don't have server-side decorations? Try client-side instead. */
|
||||
if (!data->decoration_manager && SDL_WAYLAND_HAVE_WAYLAND_LIBDECOR && SDL_GetHintBoolean(SDL_HINT_VIDEO_WAYLAND_ALLOW_LIBDECOR, SDL_TRUE)) {
|
||||
if (should_use_libdecor(data)) {
|
||||
data->shell.libdecor = libdecor_new(data->display, &libdecor_interface);
|
||||
|
||||
/* If libdecor works, we don't need xdg-shell anymore. */
|
||||
|
@ -925,6 +1062,10 @@ Wayland_VideoQuit(_THIS)
|
|||
zxdg_output_manager_v1_destroy(data->xdg_output_manager);
|
||||
}
|
||||
|
||||
if (data->viewporter) {
|
||||
wp_viewporter_destroy(data->viewporter);
|
||||
}
|
||||
|
||||
if (data->compositor)
|
||||
wl_compositor_destroy(data->compositor);
|
||||
|
||||
|
|
|
@ -74,6 +74,7 @@ typedef struct {
|
|||
struct xdg_activation_v1 *activation_manager;
|
||||
struct zwp_text_input_manager_v3 *text_input_manager;
|
||||
struct zxdg_output_manager_v1 *xdg_output_manager;
|
||||
struct wp_viewporter *viewporter;
|
||||
|
||||
EGLDisplay edpy;
|
||||
EGLContext context;
|
||||
|
@ -101,10 +102,12 @@ struct SDL_WaylandOutputData {
|
|||
struct zxdg_output_v1 *xdg_output;
|
||||
uint32_t registry_id;
|
||||
float scale_factor;
|
||||
int native_width, native_height;
|
||||
int x, y, width, height, refresh, transform;
|
||||
SDL_DisplayOrientation orientation;
|
||||
int physical_width, physical_height;
|
||||
float ddpi, hdpi, vdpi;
|
||||
SDL_bool has_logical_position, has_logical_size;
|
||||
int index;
|
||||
SDL_VideoDisplay placeholder;
|
||||
int wl_output_done_count;
|
||||
|
|
|
@ -139,11 +139,11 @@ void Wayland_Vulkan_GetDrawableSize(_THIS, SDL_Window *window, int *w, int *h)
|
|||
data = (SDL_WindowData *) window->driverdata;
|
||||
|
||||
if (w) {
|
||||
*w = window->w * data->scale_factor;
|
||||
*w = data->drawable_width;
|
||||
}
|
||||
|
||||
if (h) {
|
||||
*h = window->h * data->scale_factor;
|
||||
*h = data->drawable_height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,11 +36,268 @@
|
|||
#include "xdg-decoration-unstable-v1-client-protocol.h"
|
||||
#include "idle-inhibit-unstable-v1-client-protocol.h"
|
||||
#include "xdg-activation-v1-client-protocol.h"
|
||||
#include "viewporter-client-protocol.h"
|
||||
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
#include <libdecor.h>
|
||||
#endif
|
||||
|
||||
static void
|
||||
GetFullScreenDimensions(SDL_Window *window, int *width, int *height, int *drawable_width, int *drawable_height)
|
||||
{
|
||||
SDL_WaylandOutputData *output = (SDL_WaylandOutputData *)SDL_GetDisplayForWindow(window)->driverdata;
|
||||
|
||||
int fs_width, fs_height;
|
||||
int buf_width, buf_height;
|
||||
|
||||
/*
|
||||
* Fullscreen desktop mandates a desktop sized window, so that's what applications will get.
|
||||
* If the application is DPI aware, it will need to handle the transformations between the
|
||||
* differently sized window and backbuffer spaces on its own.
|
||||
*/
|
||||
if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP) {
|
||||
fs_width = output->width;
|
||||
fs_height = output->height;
|
||||
|
||||
/* If the application is DPI aware, we can expose the true backbuffer size */
|
||||
if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
|
||||
buf_width = output->native_width;
|
||||
buf_height = output->native_height;
|
||||
} else {
|
||||
buf_width = fs_width;
|
||||
buf_height = fs_height;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* If a mode was set, use it, otherwise use the native resolution
|
||||
* for DPI aware apps and the desktop size for legacy apps.
|
||||
*/
|
||||
if (window->fullscreen_mode.w != 0 && window->fullscreen_mode.h != 0) {
|
||||
fs_width = window->fullscreen_mode.w;
|
||||
fs_height = window->fullscreen_mode.h;
|
||||
} else if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
|
||||
fs_width = output->native_width;
|
||||
fs_height = output->native_height;
|
||||
} else {
|
||||
fs_width = output->width;
|
||||
fs_height = output->height;
|
||||
}
|
||||
|
||||
buf_width = fs_width;
|
||||
buf_height = fs_height;
|
||||
}
|
||||
|
||||
if (width) {
|
||||
*width = fs_width;
|
||||
}
|
||||
if (height) {
|
||||
*height = fs_height;
|
||||
}
|
||||
if (drawable_width) {
|
||||
*drawable_width = buf_width;
|
||||
}
|
||||
if (drawable_height) {
|
||||
*drawable_height = buf_height;
|
||||
}
|
||||
}
|
||||
|
||||
static inline SDL_bool
|
||||
DesktopIsScaled(SDL_Window *window)
|
||||
{
|
||||
SDL_WindowData *data = window->driverdata;
|
||||
|
||||
return data->scale_factor != 1.0f;
|
||||
}
|
||||
|
||||
static inline SDL_bool
|
||||
DesktopIsFractionalScaled(SDL_Window *window)
|
||||
{
|
||||
SDL_WindowData *data = window->driverdata;
|
||||
SDL_WaylandOutputData *output = (SDL_WaylandOutputData *)SDL_GetDisplayForWindow(window)->driverdata;
|
||||
|
||||
if ((output->native_width != (int)(output->width * data->scale_factor) ||
|
||||
output->native_height != (int)(output->height * data->scale_factor))) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
NeedFullscreenViewport(SDL_Window *window)
|
||||
{
|
||||
SDL_WindowData *data = window->driverdata;
|
||||
SDL_VideoData *video = data->waylandData;
|
||||
SDL_WaylandOutputData *output = (SDL_WaylandOutputData *)SDL_GetDisplayForWindow(window)->driverdata;
|
||||
|
||||
int fs_width, fs_height;
|
||||
|
||||
GetFullScreenDimensions(window, &fs_width, &fs_height, NULL, NULL);
|
||||
|
||||
/*
|
||||
* Fullscreen needs a viewport:
|
||||
* - If the desktop uses fractional scaling
|
||||
* - Fullscreen desktop was not requested OR the window is DPI aware
|
||||
*
|
||||
* - The desktop uses non-fractional scaling
|
||||
* - Fullscreen desktop was NOT requested
|
||||
*
|
||||
* - The desktop is not scaled
|
||||
* - A non-native fullscreen mode was explicitly set by the client
|
||||
*/
|
||||
if (video->viewporter != NULL && (window->flags & SDL_WINDOW_FULLSCREEN)) {
|
||||
if (DesktopIsFractionalScaled(window)) {
|
||||
if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP ||
|
||||
(window->flags & SDL_WINDOW_ALLOW_HIGHDPI)) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
} else if (DesktopIsScaled(window)) {
|
||||
if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
} else if (fs_width != output->native_width && fs_height != output->native_height) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
static inline SDL_bool
|
||||
NeedWindowedViewport(SDL_Window *window)
|
||||
{
|
||||
SDL_WindowData *data = window->driverdata;
|
||||
SDL_VideoData *video = data->waylandData;
|
||||
|
||||
return !(window->flags & SDL_WINDOW_FULLSCREEN) && (video->viewporter != NULL) &&
|
||||
DesktopIsFractionalScaled(window) && (window->flags & SDL_WINDOW_ALLOW_HIGHDPI);
|
||||
}
|
||||
|
||||
static void
|
||||
GetWindowBufferSize(SDL_Window *window, int *width, int *height)
|
||||
{
|
||||
SDL_WindowData *data = window->driverdata;
|
||||
SDL_WaylandOutputData *output = (SDL_WaylandOutputData *)SDL_GetDisplayForWindow(window)->driverdata;
|
||||
int buf_width;
|
||||
int buf_height;
|
||||
|
||||
if (NeedWindowedViewport(window)) {
|
||||
const float frac_scale_x = (float)output->native_width / (float)output->width;
|
||||
const float frac_scale_y = (float)output->native_height / (float)output->height;
|
||||
|
||||
buf_width = (int)SDL_lroundf(window->w * frac_scale_x);
|
||||
buf_height = (int)SDL_lroundf(window->h * frac_scale_y);
|
||||
} else { /* Windowed or fullscreen with no viewport */
|
||||
buf_width = window->w * data->scale_factor;
|
||||
buf_height = window->h * data->scale_factor;
|
||||
}
|
||||
|
||||
if (width) {
|
||||
*width = buf_width;
|
||||
}
|
||||
if (height) {
|
||||
*height = buf_height;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
SetViewport(SDL_Window *window, int src_width, int src_height, int dst_width, int dst_height)
|
||||
{
|
||||
SDL_WindowData *wind = window->driverdata;
|
||||
SDL_VideoData *video = wind->waylandData;
|
||||
|
||||
if (video->viewporter) {
|
||||
if (wind->viewport == NULL) {
|
||||
wind->viewport = wp_viewporter_get_viewport(video->viewporter, wind->surface);
|
||||
}
|
||||
|
||||
wp_viewport_set_source(wind->viewport, wl_fixed_from_int(0), wl_fixed_from_int(0), wl_fixed_from_int(src_width), wl_fixed_from_int(src_height));
|
||||
wp_viewport_set_destination(wind->viewport, dst_width, dst_height);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
UnsetViewport(SDL_Window *window)
|
||||
{
|
||||
SDL_WindowData *wind = window->driverdata;
|
||||
|
||||
if (wind->viewport) {
|
||||
wp_viewport_destroy(wind->viewport);
|
||||
wind->viewport = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ConfigureViewport(SDL_Window *window)
|
||||
{
|
||||
SDL_WindowData *data = window->driverdata;
|
||||
SDL_VideoData *viddata = data->waylandData;
|
||||
SDL_WaylandOutputData *output = (SDL_WaylandOutputData *)SDL_GetDisplayForWindow(window)->driverdata;
|
||||
|
||||
if (NeedFullscreenViewport(window)) {
|
||||
int fs_width, fs_height;
|
||||
int src_width, src_height;
|
||||
|
||||
GetFullScreenDimensions(window, &fs_width, &fs_height, &src_width, &src_height);
|
||||
SetViewport(window, src_width, src_height, output->width, output->height);
|
||||
|
||||
data->damage_region.x = 0;
|
||||
data->damage_region.y = 0;
|
||||
data->damage_region.w = output->width;
|
||||
data->damage_region.h = output->height;
|
||||
|
||||
data->pointer_scale_x = (float)fs_width / (float)output->width;
|
||||
data->pointer_scale_y = (float)fs_height / (float)output->height;
|
||||
} else {
|
||||
if (NeedWindowedViewport(window)) {
|
||||
int src_width, src_height;
|
||||
|
||||
GetWindowBufferSize(window, &src_width, &src_height);
|
||||
SetViewport(window, src_width, src_height, window->w, window->h);
|
||||
} else {
|
||||
UnsetViewport(window);
|
||||
}
|
||||
|
||||
SDL_zero(data->damage_region);
|
||||
|
||||
data->pointer_scale_x = 1.0f;
|
||||
data->pointer_scale_y = 1.0f;
|
||||
}
|
||||
|
||||
/*
|
||||
* If mouse_rect is not empty, re-create the confinement region with the new scale value.
|
||||
* If the pointer is locked to the general surface with unspecified coordinates, it will
|
||||
* be confined to the viewport region, so no update is required.
|
||||
*/
|
||||
if (!SDL_RectEmpty(&window->mouse_rect)) {
|
||||
Wayland_input_confine_pointer(viddata->input, window);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
SetDrawScale(SDL_Window *window)
|
||||
{
|
||||
SDL_WindowData *data = window->driverdata;
|
||||
|
||||
if (NeedFullscreenViewport(window)) {
|
||||
int fs_width, fs_height;
|
||||
|
||||
GetFullScreenDimensions(window, &fs_width, &fs_height, &data->drawable_width, &data->drawable_height);
|
||||
|
||||
/* Set the buffer scale to 1 since a viewport will be used. */
|
||||
wl_surface_set_buffer_scale(data->surface, 1);
|
||||
} else {
|
||||
GetWindowBufferSize(window, &data->drawable_width, &data->drawable_height);
|
||||
|
||||
if (NeedWindowedViewport(window)) {
|
||||
/* Set the buffer scale to 1 since a viewport will be used. */
|
||||
wl_surface_set_buffer_scale(data->surface, 1);
|
||||
} else {
|
||||
wl_surface_set_buffer_scale(data->surface, (int32_t)data->scale_factor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
SetMinMaxDimensions(SDL_Window *window, SDL_bool commit)
|
||||
{
|
||||
|
@ -150,6 +407,11 @@ handle_surface_frame_done(void *data, struct wl_callback *cb, uint32_t time)
|
|||
SDL_WindowData *wind = (SDL_WindowData *) data;
|
||||
SDL_AtomicSet(&wind->swap_interval_ready, 1); /* mark window as ready to present again. */
|
||||
|
||||
if (!SDL_RectEmpty(&wind->damage_region)) {
|
||||
wl_surface_damage(wind->surface, wind->damage_region.x, wind->damage_region.y,
|
||||
wind->damage_region.w, wind->damage_region.h);
|
||||
}
|
||||
|
||||
/* reset this callback to fire again once a new frame was presented and compositor wants the next one. */
|
||||
wind->frame_callback = wl_surface_frame(wind->frame_surface_wrapper);
|
||||
wl_callback_destroy(cb);
|
||||
|
@ -303,9 +565,14 @@ handle_configure_xdg_toplevel(void *data,
|
|||
* UPDATE: Nope, sure enough a compositor sends 0,0. This is a known bug:
|
||||
* https://bugs.kde.org/show_bug.cgi?id=444962
|
||||
*/
|
||||
if (width != 0 && height != 0 && (window->w != width || window->h != height)) {
|
||||
window->w = width;
|
||||
window->h = height;
|
||||
if (!NeedFullscreenViewport(window)) {
|
||||
if (width != 0 && height != 0 && (window->w != width || window->h != height)) {
|
||||
window->w = width;
|
||||
window->h = height;
|
||||
wind->needs_resize_event = SDL_TRUE;
|
||||
}
|
||||
} else {
|
||||
GetFullScreenDimensions(window, &window->w, &window->h, NULL, NULL);
|
||||
wind->needs_resize_event = SDL_TRUE;
|
||||
}
|
||||
|
||||
|
@ -399,17 +666,23 @@ decoration_frame_configure(struct libdecor_frame *frame,
|
|||
* Always assume the configure is wrong.
|
||||
*/
|
||||
if (fullscreen) {
|
||||
/* FIXME: We have been explicitly told to respect the fullscreen size
|
||||
* parameters here, even though they are known to be wrong on GNOME at
|
||||
* bare minimum. If this is wrong, don't blame us, we were explicitly
|
||||
* told to do this.
|
||||
*/
|
||||
if (!libdecor_configuration_get_content_size(configuration, frame,
|
||||
&width, &height)) {
|
||||
width = window->w;
|
||||
height = window->h;
|
||||
if (!NeedFullscreenViewport(window)) {
|
||||
/* FIXME: We have been explicitly told to respect the fullscreen size
|
||||
* parameters here, even though they are known to be wrong on GNOME at
|
||||
* bare minimum. If this is wrong, don't blame us, we were explicitly
|
||||
* told to do this.
|
||||
*/
|
||||
if (!libdecor_configuration_get_content_size(configuration, frame,
|
||||
&width, &height)) {
|
||||
width = window->w;
|
||||
height = window->h;
|
||||
}
|
||||
} else {
|
||||
GetFullScreenDimensions(window, &width, &height, NULL, NULL);
|
||||
}
|
||||
|
||||
wind->needs_resize_event = SDL_TRUE;
|
||||
|
||||
/* This part is good though. */
|
||||
if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
|
||||
scale_factor = driverdata->scale_factor;
|
||||
|
@ -554,9 +827,28 @@ Wayland_move_window(SDL_Window *window,
|
|||
int i, numdisplays = SDL_GetNumVideoDisplays();
|
||||
for (i = 0; i < numdisplays; i += 1) {
|
||||
if (SDL_GetDisplay(i)->driverdata == driverdata) {
|
||||
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED,
|
||||
SDL_WINDOWPOS_CENTERED_DISPLAY(i),
|
||||
SDL_WINDOWPOS_CENTERED_DISPLAY(i));
|
||||
/* We want to send a very very specific combination here:
|
||||
*
|
||||
* 1. A coordinate that tells the application what display we're on
|
||||
* 2. Exactly (0, 0)
|
||||
*
|
||||
* Part 1 is useful information but is also really important for
|
||||
* ensuring we end up on the right display for fullscreen, while
|
||||
* part 2 is important because numerous applications use a specific
|
||||
* combination of GetWindowPosition and GetGlobalMouseState, and of
|
||||
* course neither are supported by Wayland. Since global mouse will
|
||||
* fall back to just GetMouseState, we need the window position to
|
||||
* be zero so the cursor math works without it going off in some
|
||||
* random direction. See UE5 Editor for a notable example of this!
|
||||
*
|
||||
* This may be an issue some day if we're ever able to implement
|
||||
* SDL_GetDisplayUsableBounds!
|
||||
*
|
||||
* -flibit
|
||||
*/
|
||||
SDL_Rect bounds;
|
||||
SDL_GetDisplayBounds(i, &bounds);
|
||||
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, bounds.x, bounds.y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -731,6 +1023,23 @@ void Wayland_ShowWindow(_THIS, SDL_Window *window)
|
|||
SDL_VideoData *c = _this->driverdata;
|
||||
SDL_WindowData *data = window->driverdata;
|
||||
|
||||
/* Detach any previous buffers before resetting everything, otherwise when
|
||||
* calling this a second time you'll get an annoying protocol error!
|
||||
*
|
||||
* FIXME: This was originally moved to HideWindow, which _should_ make
|
||||
* sense, but for whatever reason UE5's popups require that this actually
|
||||
* be in both places at once? Possibly from renderers making commits? I can't
|
||||
* fully remember if this location caused crashes or if I was fixing a pair
|
||||
* of Hide/Show calls. In any case, UE gives us a pretty good test and having
|
||||
* both detach calls passes. This bug may be relevant if I'm wrong:
|
||||
*
|
||||
* https://bugs.kde.org/show_bug.cgi?id=448856
|
||||
*
|
||||
* -flibit
|
||||
*/
|
||||
wl_surface_attach(data->surface, NULL, 0, 0);
|
||||
wl_surface_commit(data->surface);
|
||||
|
||||
/* Create the shell surface and map the toplevel */
|
||||
#ifdef HAVE_LIBDECOR_H
|
||||
if (c->shell.libdecor) {
|
||||
|
@ -1269,7 +1578,9 @@ int Wayland_CreateWindow(_THIS, SDL_Window *window)
|
|||
data->waylandData = c;
|
||||
data->sdlwindow = window;
|
||||
|
||||
data->scale_factor = 1.0;
|
||||
data->scale_factor = 1.0f;
|
||||
data->pointer_scale_x = 1.0f;
|
||||
data->pointer_scale_y = 1.0f;
|
||||
|
||||
if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
|
||||
int i;
|
||||
|
@ -1316,9 +1627,11 @@ int Wayland_CreateWindow(_THIS, SDL_Window *window)
|
|||
}
|
||||
#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
|
||||
|
||||
data->drawable_width = window->w * data->scale_factor;
|
||||
data->drawable_height = window->h * data->scale_factor;
|
||||
|
||||
if (window->flags & SDL_WINDOW_OPENGL) {
|
||||
data->egl_window = WAYLAND_wl_egl_window_create(data->surface,
|
||||
window->w * data->scale_factor, window->h * data->scale_factor);
|
||||
data->egl_window = WAYLAND_wl_egl_window_create(data->surface, data->drawable_width, data->drawable_height);
|
||||
|
||||
#if SDL_VIDEO_OPENGL_EGL
|
||||
/* Create the GLES window surface */
|
||||
|
@ -1375,12 +1688,13 @@ Wayland_HandleResize(SDL_Window *window, int width, int height, float scale)
|
|||
data->needs_resize_event = SDL_FALSE;
|
||||
}
|
||||
|
||||
wl_surface_set_buffer_scale(data->surface, data->scale_factor);
|
||||
/* Configure the backbuffer size and scale factors */
|
||||
SetDrawScale(window);
|
||||
|
||||
if (data->egl_window) {
|
||||
WAYLAND_wl_egl_window_resize(data->egl_window,
|
||||
window->w * data->scale_factor,
|
||||
window->h * data->scale_factor,
|
||||
data->drawable_width,
|
||||
data->drawable_height,
|
||||
0, 0);
|
||||
}
|
||||
|
||||
|
@ -1397,6 +1711,9 @@ Wayland_HandleResize(SDL_Window *window, int width, int height, float scale)
|
|||
if (viddata->shell.xdg && data->shell_surface.xdg.surface) {
|
||||
xdg_surface_set_window_geometry(data->shell_surface.xdg.surface, 0, 0, window->w, window->h);
|
||||
}
|
||||
|
||||
/* Update the viewport */
|
||||
ConfigureViewport(window);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1431,12 +1748,12 @@ void Wayland_SetWindowSize(_THIS, SDL_Window * window)
|
|||
}
|
||||
#endif
|
||||
|
||||
wl_surface_set_buffer_scale(wind->surface, wind->scale_factor);
|
||||
SetDrawScale(window);
|
||||
|
||||
if (wind->egl_window) {
|
||||
WAYLAND_wl_egl_window_resize(wind->egl_window,
|
||||
window->w * wind->scale_factor,
|
||||
window->h * wind->scale_factor,
|
||||
wind->drawable_width,
|
||||
wind->drawable_height,
|
||||
0, 0);
|
||||
}
|
||||
|
||||
|
@ -1549,6 +1866,10 @@ void Wayland_DestroyWindow(_THIS, SDL_Window *window)
|
|||
xdg_activation_token_v1_destroy(wind->activation_token);
|
||||
}
|
||||
|
||||
if (wind->viewport) {
|
||||
wp_viewport_destroy(wind->viewport);
|
||||
}
|
||||
|
||||
SDL_free(wind->outputs);
|
||||
|
||||
if (wind->frame_callback) {
|
||||
|
|
|
@ -72,6 +72,7 @@ typedef struct {
|
|||
struct zwp_keyboard_shortcuts_inhibitor_v1 *key_inhibitor;
|
||||
struct zwp_idle_inhibitor_v1 *idle_inhibitor;
|
||||
struct xdg_activation_token_v1 *activation_token;
|
||||
struct wp_viewport *viewport;
|
||||
|
||||
/* floating dimensions for restoring from maximized and fullscreen */
|
||||
int floating_width, floating_height;
|
||||
|
@ -86,6 +87,10 @@ typedef struct {
|
|||
int num_outputs;
|
||||
|
||||
float scale_factor;
|
||||
float pointer_scale_x;
|
||||
float pointer_scale_y;
|
||||
int drawable_width, drawable_height;
|
||||
SDL_Rect damage_region;
|
||||
SDL_bool needs_resize_event;
|
||||
SDL_bool floating_resize_pending;
|
||||
} SDL_WindowData;
|
||||
|
@ -112,6 +117,7 @@ extern int Wayland_SetWindowModalFor(_THIS, SDL_Window * modal_window, SDL_Windo
|
|||
extern void Wayland_SetWindowTitle(_THIS, SDL_Window * window);
|
||||
extern void Wayland_DestroyWindow(_THIS, SDL_Window *window);
|
||||
extern void Wayland_SuspendScreenSaver(_THIS);
|
||||
extern int Wayland_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
|
||||
|
||||
extern SDL_bool
|
||||
Wayland_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info);
|
||||
|
|
|
@ -378,14 +378,14 @@ WIN_CheckAsyncMouseRelease(SDL_WindowData *data)
|
|||
}
|
||||
|
||||
static void
|
||||
WIN_UpdateFocus(SDL_Window *window)
|
||||
WIN_UpdateFocus(SDL_Window *window, SDL_bool expect_focus)
|
||||
{
|
||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
HWND hwnd = data->hwnd;
|
||||
SDL_bool had_focus = (SDL_GetKeyboardFocus() == window) ? SDL_TRUE : SDL_FALSE;
|
||||
SDL_bool has_focus = (GetForegroundWindow() == hwnd) ? SDL_TRUE : SDL_FALSE;
|
||||
|
||||
if (had_focus == has_focus) {
|
||||
if (had_focus == has_focus || has_focus != expect_focus) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -686,7 +686,7 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
/* Update the focus here, since it's possible to get WM_ACTIVATE and WM_SETFOCUS without
|
||||
actually being the foreground window, but this appears to get called in all cases where
|
||||
the global foreground window changes to and from this window. */
|
||||
WIN_UpdateFocus(data->window);
|
||||
WIN_UpdateFocus(data->window, !!wParam);
|
||||
WIN_CheckICMProfileChanged(data->window);
|
||||
}
|
||||
break;
|
||||
|
@ -694,16 +694,22 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
case WM_ACTIVATE:
|
||||
{
|
||||
/* Update the focus in case we changed focus to a child window and then away from the application */
|
||||
WIN_UpdateFocus(data->window);
|
||||
WIN_UpdateFocus(data->window, !!LOWORD(wParam));
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_SETFOCUS:
|
||||
{
|
||||
/* Update the focus in case it's changing between top-level windows in the same application */
|
||||
WIN_UpdateFocus(data->window, SDL_TRUE);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_KILLFOCUS:
|
||||
case WM_ENTERIDLE:
|
||||
{
|
||||
/* Update the focus in case it's changing between top-level windows in the same application */
|
||||
WIN_UpdateFocus(data->window);
|
||||
WIN_UpdateFocus(data->window, SDL_FALSE);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -734,6 +734,13 @@ WIN_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display,
|
|||
int x, y;
|
||||
int w, h;
|
||||
|
||||
if (!fullscreen && (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_FULLSCREEN_DESKTOP)) != 0) {
|
||||
/* Resizing the window on hide causes problems restoring it in Wine, and it's unnecessary.
|
||||
* Also, Windows would preview the minimized window with the wrong size.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
if (SDL_ShouldAllowTopmost() && ((window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS)) == (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_INPUT_FOCUS) || window->flags & SDL_WINDOW_ALWAYS_ON_TOP)) {
|
||||
top = HWND_TOPMOST;
|
||||
} else {
|
||||
|
|
|
@ -408,7 +408,22 @@ X11_ReconcileKeyboardState(_THIS)
|
|||
SDL_bool sdlKeyPressed = keyboardState[scancode] == SDL_PRESSED;
|
||||
|
||||
if (x11KeyPressed && !sdlKeyPressed) {
|
||||
SDL_SendKeyboardKey(SDL_PRESSED, scancode);
|
||||
/* Only update modifier state for keys that are pressed in another application */
|
||||
switch (SDL_GetKeyFromScancode(scancode)) {
|
||||
case SDLK_LCTRL:
|
||||
case SDLK_RCTRL:
|
||||
case SDLK_LSHIFT:
|
||||
case SDLK_RSHIFT:
|
||||
case SDLK_LALT:
|
||||
case SDLK_RALT:
|
||||
case SDLK_LGUI:
|
||||
case SDLK_RGUI:
|
||||
case SDLK_MODE:
|
||||
SDL_SendKeyboardKey(SDL_PRESSED, scancode);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (!x11KeyPressed && sdlKeyPressed) {
|
||||
SDL_SendKeyboardKey(SDL_RELEASED, scancode);
|
||||
}
|
||||
|
@ -996,8 +1011,9 @@ X11_DispatchEvent(_THIS, XEvent *xevent)
|
|||
}
|
||||
break;
|
||||
|
||||
/* Key press? */
|
||||
case KeyPress:{
|
||||
/* Key press/release? */
|
||||
case KeyPress:
|
||||
case KeyRelease: {
|
||||
KeyCode keycode = xevent->xkey.keycode;
|
||||
KeySym keysym = NoSymbol;
|
||||
char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];
|
||||
|
@ -1005,7 +1021,7 @@ X11_DispatchEvent(_THIS, XEvent *xevent)
|
|||
SDL_bool handled_by_ime = SDL_FALSE;
|
||||
|
||||
#ifdef DEBUG_XEVENTS
|
||||
printf("window %p: KeyPress (X11 keycode = 0x%X)\n", data, xevent->xkey.keycode);
|
||||
printf("window %p: %s (X11 keycode = 0x%X)\n" data, (xevent->type == KeyPress ? "KeyPress" : "KeyRelease"), xevent->xkey.keycode);
|
||||
#endif
|
||||
#if 1
|
||||
if (videodata->key_layout[keycode] == SDL_SCANCODE_UNKNOWN && keycode) {
|
||||
|
@ -1021,7 +1037,7 @@ X11_DispatchEvent(_THIS, XEvent *xevent)
|
|||
/* */
|
||||
SDL_zeroa(text);
|
||||
#ifdef X_HAVE_UTF8_STRING
|
||||
if (data->ic) {
|
||||
if (data->ic && xevent->type == KeyPress) {
|
||||
X11_Xutf8LookupString(data->ic, &xevent->xkey, text, sizeof(text),
|
||||
&keysym, &status);
|
||||
} else {
|
||||
|
@ -1033,35 +1049,30 @@ X11_DispatchEvent(_THIS, XEvent *xevent)
|
|||
|
||||
#ifdef SDL_USE_IME
|
||||
if(SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE){
|
||||
handled_by_ime = SDL_IME_ProcessKeyEvent(keysym, keycode);
|
||||
handled_by_ime = SDL_IME_ProcessKeyEvent(keysym, keycode, (xevent->type == KeyPress ? SDL_PRESSED : SDL_RELEASED));
|
||||
}
|
||||
#endif
|
||||
if (!handled_by_ime) {
|
||||
/* Don't send the key if it looks like a duplicate of a filtered key sent by an IME */
|
||||
if (xevent->xkey.keycode != videodata->filter_code || xevent->xkey.time != videodata->filter_time) {
|
||||
SDL_SendKeyboardKey(SDL_PRESSED, videodata->key_layout[keycode]);
|
||||
}
|
||||
if(*text) {
|
||||
SDL_SendKeyboardText(text);
|
||||
if (xevent->type == KeyPress) {
|
||||
/* Don't send the key if it looks like a duplicate of a filtered key sent by an IME */
|
||||
if (xevent->xkey.keycode != videodata->filter_code || xevent->xkey.time != videodata->filter_time) {
|
||||
SDL_SendKeyboardKey(SDL_PRESSED, videodata->key_layout[keycode]);
|
||||
}
|
||||
if(*text) {
|
||||
SDL_SendKeyboardText(text);
|
||||
}
|
||||
} else {
|
||||
if (X11_KeyRepeat(display, xevent)) {
|
||||
/* We're about to get a repeated key down, ignore the key up */
|
||||
break;
|
||||
}
|
||||
SDL_SendKeyboardKey(SDL_RELEASED, videodata->key_layout[keycode]);
|
||||
}
|
||||
}
|
||||
|
||||
X11_UpdateUserTime(data, xevent->xkey.time);
|
||||
}
|
||||
break;
|
||||
|
||||
/* Key release? */
|
||||
case KeyRelease:{
|
||||
KeyCode keycode = xevent->xkey.keycode;
|
||||
|
||||
#ifdef DEBUG_XEVENTS
|
||||
printf("window %p: KeyRelease (X11 keycode = 0x%X)\n", data, xevent->xkey.keycode);
|
||||
#endif
|
||||
if (X11_KeyRepeat(display, xevent)) {
|
||||
/* We're about to get a repeated key down, ignore the key up */
|
||||
break;
|
||||
if (xevent->type == KeyPress) {
|
||||
X11_UpdateUserTime(data, xevent->xkey.time);
|
||||
}
|
||||
SDL_SendKeyboardKey(SDL_RELEASED, videodata->key_layout[keycode]);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1438,6 +1449,13 @@ X11_DispatchEvent(_THIS, XEvent *xevent)
|
|||
}
|
||||
}
|
||||
|
||||
if (changed & SDL_WINDOW_FULLSCREEN_DESKTOP) {
|
||||
/* FULLSCREEN_DESKTOP encompasses two bits: SDL_WINDOW_FULLSCREEN, plus a bit to note it's FULLSCREEN_DESKTOP */
|
||||
const Uint32 fsmasked = flags & SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
data->window->flags &= ~SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
data->window->flags |= fsmasked;
|
||||
}
|
||||
|
||||
if (changed & SDL_WINDOW_MAXIMIZED) {
|
||||
if (flags & SDL_WINDOW_MAXIMIZED) {
|
||||
SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_MAXIMIZED, 0, 0);
|
||||
|
|
|
@ -1011,7 +1011,13 @@ static int (*PreXRRSetScreenSizeErrorHandler)(Display *, XErrorEvent *) = NULL;
|
|||
static int
|
||||
SDL_XRRSetScreenSizeErrHandler(Display *d, XErrorEvent *e)
|
||||
{
|
||||
return (e->error_code == BadMatch) ? 0 : PreXRRSetScreenSizeErrorHandler(d, e);
|
||||
/* BadMatch: https://github.com/libsdl-org/SDL/issues/4561 */
|
||||
/* BadValue: https://github.com/libsdl-org/SDL/issues/4840 */
|
||||
if ((e->error_code == BadMatch) || (e->error_code == BadValue)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return PreXRRSetScreenSizeErrorHandler(d, e);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -247,11 +247,6 @@ X11_GL_LoadLibrary(_THIS, const char *path)
|
|||
X11_GL_UseEGL(_this) ) {
|
||||
#if SDL_VIDEO_OPENGL_EGL
|
||||
X11_GL_UnloadLibrary(_this);
|
||||
/* Better avoid conflicts! */
|
||||
if (_this->gl_config.dll_handle != NULL ) {
|
||||
GL_UnloadObject(_this->gl_config.dll_handle);
|
||||
_this->gl_config.dll_handle = NULL;
|
||||
}
|
||||
_this->GL_LoadLibrary = X11_GLES_LoadLibrary;
|
||||
_this->GL_GetProcAddress = X11_GLES_GetProcAddress;
|
||||
_this->GL_UnloadLibrary = X11_GLES_UnloadLibrary;
|
||||
|
|
|
@ -222,7 +222,7 @@ X11_GetNetWMState(_THIS, Window xwindow)
|
|||
}
|
||||
|
||||
if (fullscreen == 1) {
|
||||
flags |= SDL_WINDOW_FULLSCREEN;
|
||||
flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
}
|
||||
|
||||
/* If the window is unmapped, numItems will be zero and _NET_WM_STATE_HIDDEN
|
||||
|
@ -782,11 +782,22 @@ X11_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
|
|||
X11_XFlush(display);
|
||||
}
|
||||
|
||||
static SDL_bool caught_x11_error = SDL_FALSE;
|
||||
static int
|
||||
X11_CatchAnyError(Display * d, XErrorEvent * e)
|
||||
{
|
||||
/* this may happen during tumultuous times when we are polling anyhow,
|
||||
so just note we had an error and return control. */
|
||||
caught_x11_error = SDL_TRUE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
X11_SetWindowPosition(_THIS, SDL_Window * window)
|
||||
{
|
||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
Display *display = data->videodata->display;
|
||||
int (*prev_handler) (Display *, XErrorEvent *) = NULL;
|
||||
unsigned int childCount;
|
||||
Window childReturn, root, parent;
|
||||
Window* children;
|
||||
|
@ -805,20 +816,27 @@ X11_SetWindowPosition(_THIS, SDL_Window * window)
|
|||
|
||||
/* Wait a brief time to see if the window manager decided to let this move happen.
|
||||
If the window changes at all, even to an unexpected value, we break out. */
|
||||
X11_XSync(display, False);
|
||||
prev_handler = X11_XSetErrorHandler(X11_CatchAnyError);
|
||||
|
||||
timeout = SDL_GetTicks() + 100;
|
||||
while (SDL_TRUE) {
|
||||
int x, y;
|
||||
|
||||
caught_x11_error = SDL_FALSE;
|
||||
X11_XSync(display, False);
|
||||
X11_XGetWindowAttributes(display, data->xwindow, &attrs);
|
||||
X11_XTranslateCoordinates(display, parent, DefaultRootWindow(display),
|
||||
attrs.x, attrs.y, &x, &y, &childReturn);
|
||||
|
||||
if ((x != orig_x) || (y != orig_y)) {
|
||||
window->x = x;
|
||||
window->y = y;
|
||||
break; /* window moved, time to go. */
|
||||
} else if ((x == window->x) && (y == window->y)) {
|
||||
break; /* we're at the place we wanted to be anyhow, drop out. */
|
||||
if (!caught_x11_error) {
|
||||
if ((x != orig_x) || (y != orig_y)) {
|
||||
window->x = x;
|
||||
window->y = y;
|
||||
break; /* window moved, time to go. */
|
||||
} else if ((x == window->x) && (y == window->y)) {
|
||||
break; /* we're at the place we wanted to be anyhow, drop out. */
|
||||
}
|
||||
}
|
||||
|
||||
if (SDL_TICKS_PASSED(SDL_GetTicks(), timeout)) {
|
||||
|
@ -827,6 +845,9 @@ X11_SetWindowPosition(_THIS, SDL_Window * window)
|
|||
|
||||
SDL_Delay(10);
|
||||
}
|
||||
|
||||
X11_XSetErrorHandler(prev_handler);
|
||||
caught_x11_error = SDL_FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -892,6 +913,7 @@ X11_SetWindowSize(_THIS, SDL_Window * window)
|
|||
{
|
||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
Display *display = data->videodata->display;
|
||||
int (*prev_handler) (Display *, XErrorEvent *) = NULL;
|
||||
XWindowAttributes attrs;
|
||||
int orig_w, orig_h;
|
||||
Uint32 timeout;
|
||||
|
@ -943,19 +965,25 @@ X11_SetWindowSize(_THIS, SDL_Window * window)
|
|||
X11_XResizeWindow(display, data->xwindow, window->w, window->h);
|
||||
}
|
||||
|
||||
X11_XSync(display, False);
|
||||
prev_handler = X11_XSetErrorHandler(X11_CatchAnyError);
|
||||
|
||||
/* Wait a brief time to see if the window manager decided to let this resize happen.
|
||||
If the window changes at all, even to an unexpected value, we break out. */
|
||||
timeout = SDL_GetTicks() + 100;
|
||||
while (SDL_TRUE) {
|
||||
caught_x11_error = SDL_FALSE;
|
||||
X11_XSync(display, False);
|
||||
X11_XGetWindowAttributes(display, data->xwindow, &attrs);
|
||||
|
||||
if ((attrs.width != orig_w) || (attrs.height != orig_h)) {
|
||||
window->w = attrs.width;
|
||||
window->h = attrs.height;
|
||||
break; /* window changed, time to go. */
|
||||
} else if ((attrs.width == window->w) && (attrs.height == window->h)) {
|
||||
break; /* we're at the place we wanted to be anyhow, drop out. */
|
||||
if (!caught_x11_error) {
|
||||
if ((attrs.width != orig_w) || (attrs.height != orig_h)) {
|
||||
window->w = attrs.width;
|
||||
window->h = attrs.height;
|
||||
break; /* window changed, time to go. */
|
||||
} else if ((attrs.width == window->w) && (attrs.height == window->h)) {
|
||||
break; /* we're at the place we wanted to be anyhow, drop out. */
|
||||
}
|
||||
}
|
||||
|
||||
if (SDL_TICKS_PASSED(SDL_GetTicks(), timeout)) {
|
||||
|
@ -964,6 +992,9 @@ X11_SetWindowSize(_THIS, SDL_Window * window)
|
|||
|
||||
SDL_Delay(10);
|
||||
}
|
||||
|
||||
X11_XSetErrorHandler(prev_handler);
|
||||
caught_x11_error = SDL_FALSE;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -1281,6 +1312,22 @@ X11_SetWindowFullscreenViaWM(_THIS, SDL_Window * window, SDL_VideoDisplay * _dis
|
|||
|
||||
if (X11_IsWindowMapped(_this, window)) {
|
||||
XEvent e;
|
||||
/* !!! FIXME: most of this waiting code is copy/pasted from elsewhere. */
|
||||
int (*prev_handler) (Display *, XErrorEvent *) = NULL;
|
||||
unsigned int childCount;
|
||||
Window childReturn, root, parent;
|
||||
Window* children;
|
||||
XWindowAttributes attrs;
|
||||
int orig_w, orig_h, orig_x, orig_y;
|
||||
Uint64 timeout;
|
||||
|
||||
X11_XSync(display, False);
|
||||
X11_XQueryTree(display, data->xwindow, &root, &parent, &children, &childCount);
|
||||
X11_XGetWindowAttributes(display, data->xwindow, &attrs);
|
||||
X11_XTranslateCoordinates(display, parent, DefaultRootWindow(display),
|
||||
attrs.x, attrs.y, &orig_x, &orig_y, &childReturn);
|
||||
orig_w = attrs.width;
|
||||
orig_h = attrs.height;
|
||||
|
||||
if (!(window->flags & SDL_WINDOW_RESIZABLE)) {
|
||||
/* Compiz refuses fullscreen toggle if we're not resizable, so update the hints so we
|
||||
|
@ -1330,6 +1377,41 @@ X11_SetWindowFullscreenViaWM(_THIS, SDL_Window * window, SDL_VideoDisplay * _dis
|
|||
X11_XSendEvent(display, RootWindow(display, displaydata->screen), 0,
|
||||
SubstructureNotifyMask | SubstructureRedirectMask, &e);
|
||||
}
|
||||
|
||||
/* Wait a brief time to see if the window manager decided to let this happen.
|
||||
If the window changes at all, even to an unexpected value, we break out. */
|
||||
X11_XSync(display, False);
|
||||
prev_handler = X11_XSetErrorHandler(X11_CatchAnyError);
|
||||
|
||||
timeout = SDL_GetTicks64() + 100;
|
||||
while (SDL_TRUE) {
|
||||
int x, y;
|
||||
|
||||
caught_x11_error = SDL_FALSE;
|
||||
X11_XSync(display, False);
|
||||
X11_XGetWindowAttributes(display, data->xwindow, &attrs);
|
||||
X11_XTranslateCoordinates(display, parent, DefaultRootWindow(display),
|
||||
attrs.x, attrs.y, &x, &y, &childReturn);
|
||||
|
||||
if (!caught_x11_error) {
|
||||
if ((x != orig_x) || (y != orig_y) || (attrs.width != orig_w) || (attrs.height != orig_h)) {
|
||||
window->x = x;
|
||||
window->y = y;
|
||||
window->w = attrs.width;
|
||||
window->h = attrs.height;
|
||||
break; /* window moved, time to go. */
|
||||
}
|
||||
}
|
||||
|
||||
if (SDL_GetTicks64() >= timeout) {
|
||||
break;
|
||||
}
|
||||
|
||||
SDL_Delay(10);
|
||||
}
|
||||
|
||||
X11_XSetErrorHandler(prev_handler);
|
||||
caught_x11_error = SDL_FALSE;
|
||||
} else {
|
||||
Uint32 flags;
|
||||
|
||||
|
|
|
@ -0,0 +1,186 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="viewporter">
|
||||
|
||||
<copyright>
|
||||
Copyright © 2013-2016 Collabora, Ltd.
|
||||
|
||||
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>
|
||||
|
||||
<interface name="wp_viewporter" version="1">
|
||||
<description summary="surface cropping and scaling">
|
||||
The global interface exposing surface cropping and scaling
|
||||
capabilities is used to instantiate an interface extension for a
|
||||
wl_surface object. This extended interface will then allow
|
||||
cropping and scaling the surface contents, effectively
|
||||
disconnecting the direct relationship between the buffer and the
|
||||
surface size.
|
||||
</description>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="unbind from the cropping and scaling interface">
|
||||
Informs the server that the client will not be using this
|
||||
protocol object anymore. This does not affect any other objects,
|
||||
wp_viewport objects included.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="viewport_exists" value="0"
|
||||
summary="the surface already has a viewport object associated"/>
|
||||
</enum>
|
||||
|
||||
<request name="get_viewport">
|
||||
<description summary="extend surface interface for crop and scale">
|
||||
Instantiate an interface extension for the given wl_surface to
|
||||
crop and scale its content. If the given wl_surface already has
|
||||
a wp_viewport object associated, the viewport_exists
|
||||
protocol error is raised.
|
||||
</description>
|
||||
<arg name="id" type="new_id" interface="wp_viewport"
|
||||
summary="the new viewport interface id"/>
|
||||
<arg name="surface" type="object" interface="wl_surface"
|
||||
summary="the surface"/>
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="wp_viewport" version="1">
|
||||
<description summary="crop and scale interface to a wl_surface">
|
||||
An additional interface to a wl_surface object, which allows the
|
||||
client to specify the cropping and scaling of the surface
|
||||
contents.
|
||||
|
||||
This interface works with two concepts: the source rectangle (src_x,
|
||||
src_y, src_width, src_height), and the destination size (dst_width,
|
||||
dst_height). The contents of the source rectangle are scaled to the
|
||||
destination size, and content outside the source rectangle is ignored.
|
||||
This state is double-buffered, and is applied on the next
|
||||
wl_surface.commit.
|
||||
|
||||
The two parts of crop and scale state are independent: the source
|
||||
rectangle, and the destination size. Initially both are unset, that
|
||||
is, no scaling is applied. The whole of the current wl_buffer is
|
||||
used as the source, and the surface size is as defined in
|
||||
wl_surface.attach.
|
||||
|
||||
If the destination size is set, it causes the surface size to become
|
||||
dst_width, dst_height. The source (rectangle) is scaled to exactly
|
||||
this size. This overrides whatever the attached wl_buffer size is,
|
||||
unless the wl_buffer is NULL. If the wl_buffer is NULL, the surface
|
||||
has no content and therefore no size. Otherwise, the size is always
|
||||
at least 1x1 in surface local coordinates.
|
||||
|
||||
If the source rectangle is set, it defines what area of the wl_buffer is
|
||||
taken as the source. If the source rectangle is set and the destination
|
||||
size is not set, then src_width and src_height must be integers, and the
|
||||
surface size becomes the source rectangle size. This results in cropping
|
||||
without scaling. If src_width or src_height are not integers and
|
||||
destination size is not set, the bad_size protocol error is raised when
|
||||
the surface state is applied.
|
||||
|
||||
The coordinate transformations from buffer pixel coordinates up to
|
||||
the surface-local coordinates happen in the following order:
|
||||
1. buffer_transform (wl_surface.set_buffer_transform)
|
||||
2. buffer_scale (wl_surface.set_buffer_scale)
|
||||
3. crop and scale (wp_viewport.set*)
|
||||
This means, that the source rectangle coordinates of crop and scale
|
||||
are given in the coordinates after the buffer transform and scale,
|
||||
i.e. in the coordinates that would be the surface-local coordinates
|
||||
if the crop and scale was not applied.
|
||||
|
||||
If src_x or src_y are negative, the bad_value protocol error is raised.
|
||||
Otherwise, if the source rectangle is partially or completely outside of
|
||||
the non-NULL wl_buffer, then the out_of_buffer protocol error is raised
|
||||
when the surface state is applied. A NULL wl_buffer does not raise the
|
||||
out_of_buffer error.
|
||||
|
||||
The x, y arguments of wl_surface.attach are applied as normal to
|
||||
the surface. They indicate how many pixels to remove from the
|
||||
surface size from the left and the top. In other words, they are
|
||||
still in the surface-local coordinate system, just like dst_width
|
||||
and dst_height are.
|
||||
|
||||
If the wl_surface associated with the wp_viewport is destroyed,
|
||||
all wp_viewport requests except 'destroy' raise the protocol error
|
||||
no_surface.
|
||||
|
||||
If the wp_viewport object is destroyed, the crop and scale
|
||||
state is removed from the wl_surface. The change will be applied
|
||||
on the next wl_surface.commit.
|
||||
</description>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="remove scaling and cropping from the surface">
|
||||
The associated wl_surface's crop and scale state is removed.
|
||||
The change is applied on the next wl_surface.commit.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="bad_value" value="0"
|
||||
summary="negative or zero values in width or height"/>
|
||||
<entry name="bad_size" value="1"
|
||||
summary="destination size is not integer"/>
|
||||
<entry name="out_of_buffer" value="2"
|
||||
summary="source rectangle extends outside of the content area"/>
|
||||
<entry name="no_surface" value="3"
|
||||
summary="the wl_surface was destroyed"/>
|
||||
</enum>
|
||||
|
||||
<request name="set_source">
|
||||
<description summary="set the source rectangle for cropping">
|
||||
Set the source rectangle of the associated wl_surface. See
|
||||
wp_viewport for the description, and relation to the wl_buffer
|
||||
size.
|
||||
|
||||
If all of x, y, width and height are -1.0, the source rectangle is
|
||||
unset instead. Any other set of values where width or height are zero
|
||||
or negative, or x or y are negative, raise the bad_value protocol
|
||||
error.
|
||||
|
||||
The crop and scale state is double-buffered state, and will be
|
||||
applied on the next wl_surface.commit.
|
||||
</description>
|
||||
<arg name="x" type="fixed" summary="source rectangle x"/>
|
||||
<arg name="y" type="fixed" summary="source rectangle y"/>
|
||||
<arg name="width" type="fixed" summary="source rectangle width"/>
|
||||
<arg name="height" type="fixed" summary="source rectangle height"/>
|
||||
</request>
|
||||
|
||||
<request name="set_destination">
|
||||
<description summary="set the surface size for scaling">
|
||||
Set the destination size of the associated wl_surface. See
|
||||
wp_viewport for the description, and relation to the wl_buffer
|
||||
size.
|
||||
|
||||
If width is -1 and height is -1, the destination size is unset
|
||||
instead. Any other pair of values for width and height that
|
||||
contains zero or negative values raises the bad_value protocol
|
||||
error.
|
||||
|
||||
The crop and scale state is double-buffered state, and will be
|
||||
applied on the next wl_surface.commit.
|
||||
</description>
|
||||
<arg name="width" type="int" summary="surface width"/>
|
||||
<arg name="height" type="int" summary="surface height"/>
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
</protocol>
|
Loading…
Reference in New Issue