early-access version 2281

This commit is contained in:
pineappleEA
2021-12-07 02:20:09 +01:00
parent c2ae6d480a
commit c4fa174d53
591 changed files with 36978 additions and 18653 deletions

View File

@@ -1227,7 +1227,7 @@ RLEAlphaSurface(SDL_Surface * surface)
surface->flags &= ~SDL_SIMD_ALIGNED;
}
/* realloc the buffer to release unused memory */
/* reallocate the buffer to release unused memory */
{
Uint8 *p = SDL_realloc(rlebuf, dst - rlebuf);
if (!p)
@@ -1391,9 +1391,9 @@ RLEColorkeySurface(SDL_Surface * surface)
surface->flags &= ~SDL_SIMD_ALIGNED;
}
/* realloc the buffer to release unused memory */
/* reallocate the buffer to release unused memory */
{
/* If realloc returns NULL, the original block is left intact */
/* If SDL_realloc returns NULL, the original block is left intact */
Uint8 *p = SDL_realloc(rlebuf, dst - rlebuf);
if (!p)
p = rlebuf;

View File

@@ -479,14 +479,14 @@ do { \
#define DUFFS_LOOP8(pixel_copy_increment, width) \
{ int n = (width+7)/8; \
switch (width & 7) { \
case 0: do { pixel_copy_increment; /* fallthrough */ \
case 7: pixel_copy_increment; /* fallthrough */ \
case 6: pixel_copy_increment; /* fallthrough */ \
case 5: pixel_copy_increment; /* fallthrough */ \
case 4: pixel_copy_increment; /* fallthrough */ \
case 3: pixel_copy_increment; /* fallthrough */ \
case 2: pixel_copy_increment; /* fallthrough */ \
case 1: pixel_copy_increment; /* fallthrough */ \
case 0: do { pixel_copy_increment; SDL_FALLTHROUGH; \
case 7: pixel_copy_increment; SDL_FALLTHROUGH; \
case 6: pixel_copy_increment; SDL_FALLTHROUGH; \
case 5: pixel_copy_increment; SDL_FALLTHROUGH; \
case 4: pixel_copy_increment; SDL_FALLTHROUGH; \
case 3: pixel_copy_increment; SDL_FALLTHROUGH; \
case 2: pixel_copy_increment; SDL_FALLTHROUGH; \
case 1: pixel_copy_increment; \
} while ( --n > 0 ); \
} \
}
@@ -495,10 +495,10 @@ do { \
#define DUFFS_LOOP4(pixel_copy_increment, width) \
{ int n = (width+3)/4; \
switch (width & 3) { \
case 0: do { pixel_copy_increment; /* fallthrough */ \
case 3: pixel_copy_increment; /* fallthrough */ \
case 2: pixel_copy_increment; /* fallthrough */ \
case 1: pixel_copy_increment; /* fallthrough */ \
case 0: do { pixel_copy_increment; SDL_FALLTHROUGH; \
case 3: pixel_copy_increment; SDL_FALLTHROUGH; \
case 2: pixel_copy_increment; SDL_FALLTHROUGH; \
case 1: pixel_copy_increment; \
} while (--n > 0); \
} \
}

View File

@@ -397,14 +397,14 @@ void BlitARGBto565PixelAlphaARMSIMDAsm(int32_t w, int32_t h, uint16_t *dst, int3
static void
BlitARGBto565PixelAlphaARMSIMD(SDL_BlitInfo * info)
{
int32_t width = info->dst_w;
int32_t height = info->dst_h;
uint16_t *dstp = (uint16_t *)info->dst;
int32_t dststride = width + (info->dst_skip >> 1);
uint32_t *srcp = (uint32_t *)info->src;
int32_t srcstride = width + (info->src_skip >> 2);
int32_t width = info->dst_w;
int32_t height = info->dst_h;
uint16_t *dstp = (uint16_t *)info->dst;
int32_t dststride = width + (info->dst_skip >> 1);
uint32_t *srcp = (uint32_t *)info->src;
int32_t srcstride = width + (info->src_skip >> 2);
BlitARGBto565PixelAlphaARMSIMDAsm(width, height, dstp, dststride, srcp, srcstride);
BlitARGBto565PixelAlphaARMSIMDAsm(width, height, dstp, dststride, srcp, srcstride);
}
void BlitRGBtoRGBPixelAlphaARMSIMDAsm(int32_t w, int32_t h, uint32_t *dst, int32_t dst_stride, uint32_t *src, int32_t src_stride);
@@ -444,14 +444,14 @@ void BlitRGBtoRGBPixelAlphaARMNEONAsm(int32_t w, int32_t h, uint32_t *dst, int32
static void
BlitRGBtoRGBPixelAlphaARMNEON(SDL_BlitInfo * info)
{
int32_t width = info->dst_w;
int32_t height = info->dst_h;
uint32_t *dstp = (uint32_t *)info->dst;
int32_t dststride = width + (info->dst_skip >> 2);
uint32_t *srcp = (uint32_t *)info->src;
int32_t srcstride = width + (info->src_skip >> 2);
int32_t width = info->dst_w;
int32_t height = info->dst_h;
uint32_t *dstp = (uint32_t *)info->dst;
int32_t dststride = width + (info->dst_skip >> 2);
uint32_t *srcp = (uint32_t *)info->src;
int32_t srcstride = width + (info->src_skip >> 2);
BlitRGBtoRGBPixelAlphaARMNEONAsm(width, height, dstp, dststride, srcp, srcstride);
BlitRGBtoRGBPixelAlphaARMNEONAsm(width, height, dstp, dststride, srcp, srcstride);
}
#endif
@@ -575,6 +575,61 @@ BlitRGBtoRGBPixelAlpha(SDL_BlitInfo * info)
}
}
/* fast ARGB888->(A)BGR888 blending with pixel alpha */
static void
BlitRGBtoBGRPixelAlpha(SDL_BlitInfo * info)
{
int width = info->dst_w;
int height = info->dst_h;
Uint32 *srcp = (Uint32 *) info->src;
int srcskip = info->src_skip >> 2;
Uint32 *dstp = (Uint32 *) info->dst;
int dstskip = info->dst_skip >> 2;
while (height--) {
/* *INDENT-OFF* */
DUFFS_LOOP4({
Uint32 dalpha;
Uint32 d;
Uint32 s1;
Uint32 d1;
Uint32 s = *srcp;
Uint32 alpha = s >> 24;
/* FIXME: Here we special-case opaque alpha since the
compositioning used (>>8 instead of /255) doesn't handle
it correctly. Also special-case alpha=0 for speed?
Benchmark this! */
if (alpha) {
/*
* take out the middle component (green), and process
* the other two in parallel. One multiply less.
*/
s1 = s & 0xff00ff;
s1 = (s1 >> 16) | (s1 << 16);
s &= 0xff00;
if (alpha == SDL_ALPHA_OPAQUE) {
*dstp = 0xff000000 | s | s1;
} else {
d = *dstp;
dalpha = d >> 24;
d1 = d & 0xff00ff;
d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff;
d &= 0xff00;
d = (d + ((s - d) * alpha >> 8)) & 0xff00;
dalpha = alpha + (dalpha * (alpha ^ 0xFF) >> 8);
*dstp = d1 | d | (dalpha << 24);
}
}
++srcp;
++dstp;
}, width);
/* *INDENT-ON* */
srcp += srcskip;
dstp += dstskip;
}
}
#ifdef __3dNOW__
/* fast (as in MMX with prefetch) ARGB888->(A)RGB888 blending with pixel alpha */
static void
@@ -1407,6 +1462,12 @@ SDL_CalculateBlitA(SDL_Surface * surface)
#endif
return BlitRGBtoRGBPixelAlpha;
}
} else if (sf->Rmask == df->Bmask
&& sf->Gmask == df->Gmask
&& sf->Bmask == df->Rmask && sf->BytesPerPixel == 4) {
if (sf->Amask == 0xff000000) {
return BlitRGBtoBGRPixelAlpha;
}
}
return BlitNtoNPixelAlpha;

View File

@@ -40,11 +40,11 @@
/* Functions to blit from N-bit surfaces to other surfaces */
enum blit_features {
BLIT_FEATURE_NONE = 0,
BLIT_FEATURE_HAS_MMX = 1,
BLIT_FEATURE_HAS_ALTIVEC = 2,
BLIT_FEATURE_ALTIVEC_DONT_USE_PREFETCH = 4,
BLIT_FEATURE_HAS_ARM_SIMD = 8
BLIT_FEATURE_NONE = 0,
BLIT_FEATURE_HAS_MMX = 1,
BLIT_FEATURE_HAS_ALTIVEC = 2,
BLIT_FEATURE_ALTIVEC_DONT_USE_PREFETCH = 4,
BLIT_FEATURE_HAS_ARM_SIMD = 8
};
#if SDL_ALTIVEC_BLITTERS
@@ -943,14 +943,14 @@ void Blit_BGR888_RGB888ARMSIMDAsm(int32_t w, int32_t h, uint32_t *dst, int32_t d
static void
Blit_BGR888_RGB888ARMSIMD(SDL_BlitInfo * info)
{
int32_t width = info->dst_w;
int32_t height = info->dst_h;
uint32_t *dstp = (uint32_t *)info->dst;
int32_t dststride = width + (info->dst_skip >> 2);
uint32_t *srcp = (uint32_t *)info->src;
int32_t srcstride = width + (info->src_skip >> 2);
int32_t width = info->dst_w;
int32_t height = info->dst_h;
uint32_t *dstp = (uint32_t *)info->dst;
int32_t dststride = width + (info->dst_skip >> 2);
uint32_t *srcp = (uint32_t *)info->src;
int32_t srcstride = width + (info->src_skip >> 2);
Blit_BGR888_RGB888ARMSIMDAsm(width, height, dstp, dststride, srcp, srcstride);
Blit_BGR888_RGB888ARMSIMDAsm(width, height, dstp, dststride, srcp, srcstride);
}
void Blit_RGB444_RGB888ARMSIMDAsm(int32_t w, int32_t h, uint32_t *dst, int32_t dst_stride, uint16_t *src, int32_t src_stride);
@@ -958,14 +958,14 @@ void Blit_RGB444_RGB888ARMSIMDAsm(int32_t w, int32_t h, uint32_t *dst, int32_t d
static void
Blit_RGB444_RGB888ARMSIMD(SDL_BlitInfo * info)
{
int32_t width = info->dst_w;
int32_t height = info->dst_h;
uint32_t *dstp = (uint32_t *)info->dst;
int32_t dststride = width + (info->dst_skip >> 2);
uint16_t *srcp = (uint16_t *)info->src;
int32_t srcstride = width + (info->src_skip >> 1);
int32_t width = info->dst_w;
int32_t height = info->dst_h;
uint32_t *dstp = (uint32_t *)info->dst;
int32_t dststride = width + (info->dst_skip >> 2);
uint16_t *srcp = (uint16_t *)info->src;
int32_t srcstride = width + (info->src_skip >> 1);
Blit_RGB444_RGB888ARMSIMDAsm(width, height, dstp, dststride, srcp, srcstride);
Blit_RGB444_RGB888ARMSIMDAsm(width, height, dstp, dststride, srcp, srcstride);
}
#endif

View File

@@ -30,6 +30,9 @@
#include "../core/android/SDL_android.h"
#include "../video/android/SDL_androidvideo.h"
#endif
#if SDL_VIDEO_DRIVER_RPI
#include <unistd.h>
#endif
#include "SDL_sysvideo.h"
#include "SDL_egl_c.h"
@@ -43,6 +46,11 @@
#endif
#endif /* EGL_KHR_create_context */
#ifndef EGL_EXT_present_opaque
#define EGL_EXT_present_opaque 1
#define EGL_PRESENT_OPAQUE_EXT 0x31DF
#endif /* EGL_EXT_present_opaque */
#if SDL_VIDEO_DRIVER_RPI
/* Raspbian places the OpenGL ES/EGL binaries in a non standard path */
#define DEFAULT_EGL ( vc4 ? "libEGL.so.1" : "libbrcmEGL.so" )
@@ -102,7 +110,7 @@
#define EGL_PLATFORM_DEVICE_EXT 0x0
#endif
#ifdef SDL_VIDEO_STATIC_ANGLE
#if defined(SDL_VIDEO_STATIC_ANGLE) || defined(SDL_VIDEO_DRIVER_VITA)
#define LOAD_FUNC(NAME) \
_this->egl_data->NAME = (void *)NAME;
#else
@@ -118,7 +126,6 @@ if (!_this->egl_data->NAME) \
#define LOAD_FUNC_EGLEXT(NAME) \
_this->egl_data->NAME = _this->egl_data->eglGetProcAddress(#NAME);
static const char * SDL_EGL_GetErrorName(EGLint eglErrorCode)
{
#define SDL_EGL_ERROR_TRANSLATE(e) case e: return #e;
@@ -240,7 +247,7 @@ SDL_EGL_GetProcAddress(_THIS, const char *proc)
retval = _this->egl_data->eglGetProcAddress(proc);
}
#ifndef __EMSCRIPTEN__ /* LoadFunction isn't needed on Emscripten and will call dlsym(), causing other problems. */
#if !defined(__EMSCRIPTEN__) && !defined(SDL_VIDEO_DRIVER_VITA) /* LoadFunction isn't needed on Emscripten and will call dlsym(), causing other problems. */
/* Try SDL_LoadFunction() first for EGL <= 1.4, or as a fallback for >= 1.5. */
if (!retval) {
static char procname[64];
@@ -339,7 +346,7 @@ SDL_EGL_LoadLibraryOnly(_THIS, const char *egl_path)
}
#endif
#ifndef SDL_VIDEO_STATIC_ANGLE
#if !defined(SDL_VIDEO_STATIC_ANGLE) && !defined(SDL_VIDEO_DRIVER_VITA)
/* A funny thing, loading EGL.so first does not work on the Raspberry, so we load libGL* first */
path = SDL_getenv("SDL_VIDEO_GL_DRIVER");
if (path != NULL) {
@@ -425,6 +432,9 @@ SDL_EGL_LoadLibraryOnly(_THIS, const char *egl_path)
#endif
_this->egl_data->dll_handle = dll_handle;
#if SDL_VIDEO_DRIVER_VITA
_this->egl_data->egl_dll_handle = egl_dll_handle;
#endif
/* Load new function pointers */
LOAD_FUNC(eglGetDisplay);
@@ -493,6 +503,7 @@ SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_displa
_this->egl_data->egl_display = EGL_NO_DISPLAY;
#if !defined(__WINRT__)
#if !defined(SDL_VIDEO_DRIVER_VITA)
if (platform) {
/* EGL 1.5 allows querying for client version with EGL_NO_DISPLAY
* --
@@ -517,6 +528,7 @@ SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_displa
}
}
}
#endif
/* Try the implementation-specific eglGetDisplay even if eglGetPlatformDisplay fails */
if (_this->egl_data->egl_display == EGL_NO_DISPLAY) {
_this->egl_data->egl_display = _this->egl_data->eglGetDisplay(native_display);
@@ -537,7 +549,7 @@ SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_displa
/* Get the EGL version with a valid egl_display, for EGL <= 1.4 */
SDL_EGL_GetVersion(_this);
_this->egl_data->is_offscreen = 0;
_this->egl_data->is_offscreen = SDL_FALSE;
return 0;
}
@@ -557,7 +569,7 @@ SDL_EGL_InitializeOffscreen(_THIS, int device)
EGLint num_egl_devices = 0;
const char *egl_device_hint;
if (_this->gl_config.driver_loaded != 1) {
if (_this->gl_config.driver_loaded <= 0) {
return SDL_SetError("SDL_EGL_LoadLibraryOnly() has not been called or has failed.");
}
@@ -625,7 +637,7 @@ SDL_EGL_InitializeOffscreen(_THIS, int device)
/* Get the EGL version with a valid egl_display, for EGL <= 1.4 */
SDL_EGL_GetVersion(_this);
_this->egl_data->is_offscreen = 1;
_this->egl_data->is_offscreen = SDL_TRUE;
return 0;
}
@@ -1001,27 +1013,24 @@ SDL_EGL_CreateContext(_THIS, EGLSurface egl_surface)
}
}
if (_this->gl_config.no_error) {
#ifdef EGL_KHR_create_context_no_error
if (_this->gl_config.no_error) {
if (SDL_EGL_HasExtension(_this, SDL_EGL_DISPLAY_EXTENSION, "EGL_KHR_create_context_no_error")) {
attribs[attr++] = EGL_CONTEXT_OPENGL_NO_ERROR_KHR;
attribs[attr++] = _this->gl_config.no_error;
} else
#endif
{
SDL_SetError("EGL implementation does not support no_error contexts");
return NULL;
}
}
#endif
attribs[attr++] = EGL_NONE;
/* Bind the API */
if (profile_es) {
_this->egl_data->eglBindAPI(EGL_OPENGL_ES_API);
_this->egl_data->apitype = EGL_OPENGL_ES_API;
} else {
_this->egl_data->eglBindAPI(EGL_OPENGL_API);
_this->egl_data->apitype = EGL_OPENGL_API;
}
_this->egl_data->eglBindAPI(_this->egl_data->apitype);
egl_context = _this->egl_data->eglCreateContext(_this->egl_data->egl_display,
_this->egl_data->egl_config,
@@ -1099,6 +1108,11 @@ SDL_EGL_MakeCurrent(_THIS, EGLSurface egl_surface, SDL_GLContext context)
}
}
/* Make sure current thread has a valid API bound to it. */
if (_this->egl_data->eglBindAPI) {
_this->egl_data->eglBindAPI(_this->egl_data->apitype);
}
/* The android emulator crashes badly if you try to eglMakeCurrent
* with a valid context and invalid surface, so we have to check for both here.
*/
@@ -1182,8 +1196,8 @@ SDL_EGL_CreateSurface(_THIS, NativeWindowType nw)
EGLint format_wanted;
EGLint format_got;
#endif
/* max 2 values plus terminator. */
EGLint attribs[3];
/* max 2 key+value pairs, plus terminator. */
EGLint attribs[5];
int attr = 0;
EGLSurface * surface;
@@ -1216,6 +1230,14 @@ SDL_EGL_CreateSurface(_THIS, NativeWindowType nw)
}
}
#ifdef EGL_EXT_present_opaque
if (SDL_EGL_HasExtension(_this, SDL_EGL_DISPLAY_EXTENSION, "EGL_EXT_present_opaque")) {
const SDL_bool allow_transparent = SDL_GetHintBoolean(SDL_HINT_VIDEO_EGL_ALLOW_TRANSPARENCY, SDL_FALSE);
attribs[attr++] = EGL_PRESENT_OPAQUE_EXT;
attribs[attr++] = allow_transparent ? EGL_FALSE : EGL_TRUE;
}
#endif
attribs[attr++] = EGL_NONE;
surface = _this->egl_data->eglCreateWindowSurface(

View File

@@ -40,6 +40,8 @@ typedef struct SDL_EGL_VideoData
int egl_surfacetype;
int egl_version_major, egl_version_minor;
EGLint egl_required_visual_id;
SDL_bool is_offscreen; /* whether EGL display was offscreen */
EGLenum apitype; /* EGL_OPENGL_ES_API, EGL_OPENGL_API, etc */
EGLDisplay(EGLAPIENTRY *eglGetDisplay) (NativeDisplayType display);
EGLDisplay(EGLAPIENTRY *eglGetPlatformDisplay) (EGLenum platform,
@@ -114,11 +116,6 @@ typedef struct SDL_EGL_VideoData
EGLint(EGLAPIENTRY *eglClientWaitSyncKHR)(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
/* Atomic functions end */
/* whether EGL display was offscreen */
int is_offscreen;
} SDL_EGL_VideoData;
/* OpenGLES functions */

View File

@@ -145,13 +145,13 @@ SDL_FillRect1(Uint8 * pixels, int pitch, Uint32 color, int w, int h)
switch ((uintptr_t) p & 3) {
case 1:
*p++ = (Uint8) color;
--n; /* fallthrough */
--n; SDL_FALLTHROUGH;
case 2:
*p++ = (Uint8) color;
--n; /* fallthrough */
--n; SDL_FALLTHROUGH;
case 3:
*p++ = (Uint8) color;
--n; /* fallthrough */
--n;
}
SDL_memset4(p, color, (n >> 2));
}
@@ -159,11 +159,11 @@ SDL_FillRect1(Uint8 * pixels, int pitch, Uint32 color, int w, int h)
p += (n & ~3);
switch (n & 3) {
case 3:
*p++ = (Uint8) color; /* fallthrough */
*p++ = (Uint8) color; SDL_FALLTHROUGH;
case 2:
*p++ = (Uint8) color; /* fallthrough */
*p++ = (Uint8) color; SDL_FALLTHROUGH;
case 1:
*p++ = (Uint8) color; /* fallthrough */
*p++ = (Uint8) color;
}
}
pixels += pitch;

View File

@@ -333,7 +333,7 @@ SDL_MasksToPixelFormatEnum(int bpp, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask,
if (Rmask == 0) {
return SDL_PIXELFORMAT_RGB555;
}
/* fallthrough */
SDL_FALLTHROUGH;
case 16:
if (Rmask == 0) {
return SDL_PIXELFORMAT_RGB565;
@@ -871,7 +871,7 @@ SDL_MapRGBA(const SDL_PixelFormat * format, Uint8 r, Uint8 g, Uint8 b,
return (r >> format->Rloss) << format->Rshift
| (g >> format->Gloss) << format->Gshift
| (b >> format->Bloss) << format->Bshift
| ((a >> format->Aloss) << format->Ashift & format->Amask);
| ((Uint32)(a >> format->Aloss) << format->Ashift & format->Amask);
} else {
return SDL_FindColor(format->palette, r, g, b, a);
}
@@ -983,7 +983,7 @@ Map1toN(SDL_PixelFormat * src, Uint8 Rmod, Uint8 Gmod, Uint8 Bmod, Uint8 Amod,
Uint8 G = (Uint8) ((pal->colors[i].g * Gmod) / 255);
Uint8 B = (Uint8) ((pal->colors[i].b * Bmod) / 255);
Uint8 A = (Uint8) ((pal->colors[i].a * Amod) / 255);
ASSEMBLE_RGBA(&map[i * bpp], dst->BytesPerPixel, dst, R, G, B, A);
ASSEMBLE_RGBA(&map[i * bpp], dst->BytesPerPixel, dst, (Uint32)R, (Uint32)G, (Uint32)B, (Uint32)A);
}
return (map);
}

View File

@@ -1092,6 +1092,7 @@ SDL_ConvertSurface(SDL_Surface * surface, const SDL_PixelFormat * format,
int palette_ck_value = 0;
SDL_bool palette_has_alpha = SDL_FALSE;
Uint8 *palette_saved_alpha = NULL;
int palette_saved_alpha_ncolors = 0;
if (!surface) {
SDL_InvalidParamError("surface");
@@ -1173,8 +1174,9 @@ SDL_ConvertSurface(SDL_Surface * surface, const SDL_PixelFormat * format,
/* Set opaque and backup palette alpha values */
if (set_opaque) {
int i;
palette_saved_alpha = SDL_stack_alloc(Uint8, surface->format->palette->ncolors);
for (i = 0; i < surface->format->palette->ncolors; i++) {
palette_saved_alpha_ncolors = surface->format->palette->ncolors;
palette_saved_alpha = SDL_stack_alloc(Uint8, palette_saved_alpha_ncolors);
for (i = 0; i < palette_saved_alpha_ncolors; i++) {
palette_saved_alpha[i] = surface->format->palette->colors[i].a;
surface->format->palette->colors[i].a = SDL_ALPHA_OPAQUE;
}
@@ -1201,7 +1203,7 @@ SDL_ConvertSurface(SDL_Surface * surface, const SDL_PixelFormat * format,
/* Restore palette alpha values */
if (palette_saved_alpha) {
int i;
for (i = 0; i < surface->format->palette->ncolors; i++) {
for (i = 0; i < palette_saved_alpha_ncolors; i++) {
surface->format->palette->colors[i].a = palette_saved_alpha[i];
}
SDL_stack_free(palette_saved_alpha);
@@ -1379,7 +1381,12 @@ int SDL_ConvertPixels(int width, int height,
void *nonconst_src = (void *) src;
int ret;
/* Check to make sure we are blitting somewhere, so we don't crash */
if (!src) {
return SDL_InvalidParamError("src");
}
if (!src_pitch) {
return SDL_InvalidParamError("src_pitch");
}
if (!dst) {
return SDL_InvalidParamError("dst");
}
@@ -1438,6 +1445,68 @@ int SDL_ConvertPixels(int width, int height,
return ret;
}
/*
* Premultiply the alpha on a block of pixels
*
* This is currently only implemented for SDL_PIXELFORMAT_ARGB8888
*
* Here are some ideas for optimization:
* https://github.com/Wizermil/premultiply_alpha/tree/master/premultiply_alpha
* https://developer.arm.com/documentation/101964/0201/Pre-multiplied-alpha-channel-data
*/
int SDL_PremultiplyAlpha(int width, int height,
Uint32 src_format, const void * src, int src_pitch,
Uint32 dst_format, void * dst, int dst_pitch)
{
int c;
Uint32 srcpixel;
Uint32 srcR, srcG, srcB, srcA;
Uint32 dstpixel;
Uint32 dstR, dstG, dstB, dstA;
if (!src) {
return SDL_InvalidParamError("src");
}
if (!src_pitch) {
return SDL_InvalidParamError("src_pitch");
}
if (!dst) {
return SDL_InvalidParamError("dst");
}
if (!dst_pitch) {
return SDL_InvalidParamError("dst_pitch");
}
if (src_format != SDL_PIXELFORMAT_ARGB8888) {
return SDL_InvalidParamError("src_format");
}
if (dst_format != SDL_PIXELFORMAT_ARGB8888) {
return SDL_InvalidParamError("dst_format");
}
while (height--) {
const Uint32 *src_px = (const Uint32 *)src;
Uint32 *dst_px = (Uint32 *)dst;
for (c = width; c; --c) {
/* Component bytes extraction. */
srcpixel = *src_px++;
RGBA_FROM_ARGB8888(srcpixel, srcR, srcG, srcB, srcA);
/* Alpha pre-multiplication of each component. */
dstA = srcA;
dstR = (srcA * srcR) / 255;
dstG = (srcA * srcG) / 255;
dstB = (srcA * srcB) / 255;
/* ARGB8888 pixel recomposition. */
ARGB8888_FROM_RGBA(dstpixel, dstR, dstG, dstB, dstA);
*dst_px++ = dstpixel;
}
src = (const Uint8 *)src + src_pitch;
dst = (Uint8 *)dst + dst_pitch;
}
return 0;
}
/*
* Free a surface created by the above function.
*/

View File

@@ -83,6 +83,7 @@ struct SDL_Window
int max_w, max_h;
Uint32 flags;
Uint32 last_fullscreen_flags;
Uint32 display_index;
/* Stored position and size for windowed mode */
SDL_Rect windowed;
@@ -102,6 +103,8 @@ struct SDL_Window
SDL_bool is_destroying;
SDL_bool is_dropping; /* drag/drop in progress, expecting SDL_SendDropComplete(). */
SDL_Rect mouse_rect;
SDL_WindowShaper *shaper;
SDL_HitTest hit_test;
@@ -233,6 +236,8 @@ struct SDL_VideoDevice
void (*SetWindowFullscreen) (_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
int (*SetWindowGammaRamp) (_THIS, SDL_Window * window, const Uint16 * ramp);
int (*GetWindowGammaRamp) (_THIS, SDL_Window * window, Uint16 * ramp);
void* (*GetWindowICCProfile) (_THIS, SDL_Window * window, size_t* size);
void (*SetWindowMouseRect)(_THIS, SDL_Window * window);
void (*SetWindowMouseGrab) (_THIS, SDL_Window * window, SDL_bool grabbed);
void (*SetWindowKeyboardGrab) (_THIS, SDL_Window * window, SDL_bool grabbed);
void (*DestroyWindow) (_THIS, SDL_Window * window);
@@ -336,6 +341,7 @@ struct SDL_VideoDevice
Uint8 window_magic;
Uint32 next_object_id;
char *clipboard_text;
SDL_bool setting_display_mode;
/* * * */
/* Data used by the GL drivers */
@@ -435,6 +441,7 @@ extern VideoBootStrap UIKIT_bootstrap;
extern VideoBootStrap Android_bootstrap;
extern VideoBootStrap PSP_bootstrap;
extern VideoBootStrap VITA_bootstrap;
extern VideoBootStrap RISCOS_bootstrap;
extern VideoBootStrap RPI_bootstrap;
extern VideoBootStrap KMSDRM_bootstrap;
extern VideoBootStrap KMSDRM_LEGACY_bootstrap;
@@ -453,6 +460,9 @@ extern int SDL_AddBasicVideoDisplay(const SDL_DisplayMode * desktop_mode);
extern int SDL_AddVideoDisplay(const SDL_VideoDisplay * display, SDL_bool send_event);
extern void SDL_DelVideoDisplay(int index);
extern SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode * mode);
extern void SDL_SetCurrentDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode * mode);
extern void SDL_SetDesktopDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode * mode);
extern void SDL_ResetDisplayModes(int displayIndex);
extern int SDL_GetIndexOfDisplay(SDL_VideoDisplay *display);
extern SDL_VideoDisplay *SDL_GetDisplay(int displayIndex);
extern SDL_VideoDisplay *SDL_GetDisplayForWindow(SDL_Window *window);
@@ -466,6 +476,7 @@ extern SDL_bool SDL_HasWindows(void);
extern void SDL_OnWindowShown(SDL_Window * window);
extern void SDL_OnWindowHidden(SDL_Window * window);
extern void SDL_OnWindowMoved(SDL_Window * window);
extern void SDL_OnWindowResized(SDL_Window * window);
extern void SDL_OnWindowMinimized(SDL_Window * window);
extern void SDL_OnWindowRestored(SDL_Window * window);

View File

@@ -100,6 +100,9 @@ static VideoBootStrap *bootstrap[] = {
#if SDL_VIDEO_DRIVER_KMSDRM
&KMSDRM_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_RISCOS
&RISCOS_bootstrap,
#endif
#if SDL_VIDEO_DRIVER_RPI
&RPI_bootstrap,
#endif
@@ -132,7 +135,6 @@ static SDL_VideoDevice *_this = NULL;
SDL_UninitializedVideo(); \
return retval; \
} \
SDL_assert(window && window->magic == &_this->window_magic); \
if (!window || window->magic != &_this->window_magic) { \
SDL_SetError("Invalid window"); \
return retval; \
@@ -143,8 +145,6 @@ static SDL_VideoDevice *_this = NULL;
SDL_UninitializedVideo(); \
return retval; \
} \
SDL_assert(_this->displays != NULL); \
SDL_assert(displayIndex >= 0 && displayIndex < _this->num_displays); \
if (displayIndex < 0 || displayIndex >= _this->num_displays) { \
SDL_SetError("displayIndex must be in the range 0 - %d", \
_this->num_displays - 1); \
@@ -187,14 +187,6 @@ ShouldUseTextureFramebuffer()
return SDL_FALSE;
}
/* If the user has specified a software renderer we can't use a
texture framebuffer, or renderer creation will go recursive.
*/
hint = SDL_GetHint(SDL_HINT_RENDER_DRIVER);
if (hint && SDL_strcasecmp(hint, "software") == 0) {
return SDL_FALSE;
}
/* See if the user or application wants a specific behavior */
hint = SDL_GetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION);
if (hint) {
@@ -355,7 +347,7 @@ SDL_CreateWindowTexture(SDL_VideoDevice *unused, SDL_Window * window, Uint32 * f
data->pitch = (((window->w * data->bytes_per_pixel) + 3) & ~3);
{
/* Make static analysis happy about potential malloc(0) calls. */
/* Make static analysis happy about potential SDL_malloc(0) calls. */
const size_t allocsize = window->h * data->pitch;
data->pixels = SDL_malloc((allocsize > 0) ? allocsize : 1);
if (!data->pixels) {
@@ -497,7 +489,7 @@ SDL_VideoInit(const char *driver_name)
if (driver_name == NULL) {
driver_name = SDL_getenv("SDL_VIDEODRIVER");
}
if (driver_name != NULL) {
if (driver_name != NULL && *driver_name != 0) {
const char *driver_attempt = driver_name;
while(driver_attempt != NULL && *driver_attempt != 0 && video == NULL) {
const char* driver_attempt_end = SDL_strchr(driver_attempt, ',');
@@ -801,7 +793,7 @@ SDL_GetDisplayOrientation(int displayIndex)
}
SDL_bool
SDL_AddDisplayMode(SDL_VideoDisplay * display, const SDL_DisplayMode * mode)
SDL_AddDisplayMode(SDL_VideoDisplay * display, const SDL_DisplayMode * mode)
{
SDL_DisplayMode *modes;
int i, nmodes;
@@ -836,6 +828,18 @@ SDL_AddDisplayMode(SDL_VideoDisplay * display, const SDL_DisplayMode * mode)
return SDL_TRUE;
}
void
SDL_SetCurrentDisplayMode(SDL_VideoDisplay * display, const SDL_DisplayMode * mode)
{
SDL_memcpy(&display->current_mode, mode, sizeof(*mode));
}
void
SDL_SetDesktopDisplayMode(SDL_VideoDisplay * display, const SDL_DisplayMode * mode)
{
SDL_memcpy(&display->desktop_mode, mode, sizeof(*mode));
}
static int
SDL_GetNumDisplayModesForDisplay(SDL_VideoDisplay * display)
{
@@ -855,6 +859,25 @@ SDL_GetNumDisplayModes(int displayIndex)
return SDL_GetNumDisplayModesForDisplay(&_this->displays[displayIndex]);
}
void
SDL_ResetDisplayModes(int displayIndex)
{
SDL_VideoDisplay *display;
int i;
CHECK_DISPLAY_INDEX(displayIndex,);
display = &_this->displays[displayIndex];
for (i = display->num_display_modes; i--;) {
SDL_free(display->display_modes[i].driverdata);
display->display_modes[i].driverdata = NULL;
}
SDL_free(display->display_modes);
display->display_modes = NULL;
display->num_display_modes = 0;
display->max_display_modes = 0;
}
int
SDL_GetDisplayMode(int displayIndex, int index, SDL_DisplayMode * mode)
{
@@ -1026,6 +1049,7 @@ SDL_SetDisplayModeForDisplay(SDL_VideoDisplay * display, const SDL_DisplayMode *
{
SDL_DisplayMode display_mode;
SDL_DisplayMode current_mode;
int result;
if (mode) {
display_mode = *mode;
@@ -1063,10 +1087,13 @@ SDL_SetDisplayModeForDisplay(SDL_VideoDisplay * display, const SDL_DisplayMode *
if (!_this->SetDisplayMode) {
return SDL_SetError("SDL video driver doesn't support changing display mode");
}
if (_this->SetDisplayMode(_this, display, &display_mode) < 0) {
_this->setting_display_mode = SDL_TRUE;
result = _this->SetDisplayMode(_this, display, &display_mode);
_this->setting_display_mode = SDL_FALSE;
if (result < 0) {
return -1;
}
display->current_mode = display_mode;
SDL_SetCurrentDisplayMode(display, &display_mode);
return 0;
}
@@ -1215,6 +1242,16 @@ SDL_GetWindowDisplayMode(SDL_Window * window, SDL_DisplayMode * mode)
return 0;
}
void*
SDL_GetWindowICCProfile(SDL_Window * window, size_t* size)
{
if (!_this->GetWindowICCProfile) {
SDL_Unsupported();
return NULL;
}
return _this->GetWindowICCProfile(_this, window, size);
}
Uint32
SDL_GetWindowPixelFormat(SDL_Window * window)
{
@@ -1636,6 +1673,7 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
window->brightness = 1.0f;
window->next = _this->windows;
window->is_destroying = SDL_FALSE;
window->display_index = SDL_GetWindowDisplayIndex(window);
if (_this->windows) {
_this->windows->prev = window;
@@ -1715,6 +1753,7 @@ SDL_CreateWindowFrom(const void *data)
return NULL;
}
window->display_index = SDL_GetWindowDisplayIndex(window);
PrepareDragAndDropSupport(window);
return window;
@@ -2038,10 +2077,10 @@ SDL_SetWindowPosition(SDL_Window * window, int x, int y)
SDL_GetDisplayBounds(displayIndex, &bounds);
if (SDL_WINDOWPOS_ISCENTERED(x)) {
x = bounds.x + (bounds.w - window->w) / 2;
x = bounds.x + (bounds.w - window->windowed.w) / 2;
}
if (SDL_WINDOWPOS_ISCENTERED(y)) {
y = bounds.y + (bounds.h - window->h) / 2;
y = bounds.y + (bounds.h - window->windowed.h) / 2;
}
}
@@ -2795,11 +2834,7 @@ SDL_SetWindowMouseGrab(SDL_Window * window, SDL_bool grabbed)
SDL_bool
SDL_GetWindowGrab(SDL_Window * window)
{
CHECK_WINDOW_MAGIC(window, SDL_FALSE);
SDL_assert(!_this->grabbed_window ||
((_this->grabbed_window->flags & SDL_WINDOW_MOUSE_GRABBED) != 0) ||
((_this->grabbed_window->flags & SDL_WINDOW_KEYBOARD_GRABBED) != 0));
return window == _this->grabbed_window;
return (SDL_GetWindowKeyboardGrab(window) || SDL_GetWindowMouseGrab(window));
}
SDL_bool
@@ -2821,10 +2856,41 @@ SDL_GetWindowMouseGrab(SDL_Window * window)
SDL_Window *
SDL_GetGrabbedWindow(void)
{
SDL_assert(!_this->grabbed_window ||
((_this->grabbed_window->flags & SDL_WINDOW_MOUSE_GRABBED) != 0) ||
((_this->grabbed_window->flags & SDL_WINDOW_KEYBOARD_GRABBED) != 0));
return _this->grabbed_window;
if (_this->grabbed_window &&
(_this->grabbed_window->flags & (SDL_WINDOW_MOUSE_GRABBED|SDL_WINDOW_KEYBOARD_GRABBED)) != 0) {
return _this->grabbed_window;
} else {
return NULL;
}
}
int
SDL_SetWindowMouseRect(SDL_Window * window, const SDL_Rect * rect)
{
CHECK_WINDOW_MAGIC(window, -1);
if (rect) {
SDL_memcpy(&window->mouse_rect, rect, sizeof(*rect));
} else {
SDL_zero(window->mouse_rect);
}
if (_this->SetWindowMouseRect) {
_this->SetWindowMouseRect(_this, window);
}
return 0;
}
const SDL_Rect *
SDL_GetWindowMouseRect(SDL_Window * window)
{
CHECK_WINDOW_MAGIC(window, NULL);
if (SDL_RectEmpty(&window->mouse_rect)) {
return NULL;
} else {
return &window->mouse_rect;
}
}
int
@@ -2854,10 +2920,27 @@ SDL_OnWindowHidden(SDL_Window * window)
void
SDL_OnWindowResized(SDL_Window * window)
{
int display_index = SDL_GetWindowDisplayIndex(window);
window->surface_valid = SDL_FALSE;
if (!window->is_destroying) {
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SIZE_CHANGED, window->w, window->h);
if (display_index != window->display_index && display_index != -1) {
window->display_index = display_index;
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_DISPLAY_CHANGED, window->display_index, 0);
}
}
}
void
SDL_OnWindowMoved(SDL_Window * window)
{
int display_index = SDL_GetWindowDisplayIndex(window);
if (!window->is_destroying && display_index != window->display_index && display_index != -1) {
window->display_index = display_index;
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_DISPLAY_CHANGED, window->display_index, 0);
}
}
@@ -2907,7 +2990,9 @@ SDL_OnWindowFocusGained(SDL_Window * window)
if (mouse && mouse->relative_mode) {
SDL_SetMouseFocus(window);
SDL_WarpMouseInWindow(window, window->w/2, window->h/2);
if (mouse->relative_mode_warp) {
SDL_WarpMouseInWindow(window, window->w/2, window->h/2);
}
}
SDL_UpdateWindowGrab(window);
@@ -3104,7 +3189,7 @@ SDL_DisableScreenSaver()
void
SDL_VideoQuit(void)
{
int i, j;
int i;
if (!_this) {
return;
@@ -3126,12 +3211,7 @@ SDL_VideoQuit(void)
for (i = 0; i < _this->num_displays; ++i) {
SDL_VideoDisplay *display = &_this->displays[i];
for (j = display->num_display_modes; j--;) {
SDL_free(display->display_modes[j].driverdata);
display->display_modes[j].driverdata = NULL;
}
SDL_free(display->display_modes);
display->display_modes = NULL;
SDL_ResetDisplayModes(i);
SDL_free(display->desktop_mode.driverdata);
display->desktop_mode.driverdata = NULL;
SDL_free(display->driverdata);
@@ -4131,11 +4211,14 @@ SDL_IsScreenKeyboardShown(SDL_Window *window)
#if SDL_VIDEO_DRIVER_OS2
#include "os2/SDL_os2messagebox.h"
#endif
#if SDL_VIDEO_DRIVER_RISCOS
#include "riscos/SDL_riscosmessagebox.h"
#endif
#if SDL_VIDEO_DRIVER_VITA
#include "vita/SDL_vitamessagebox.h"
#endif
#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT || SDL_VIDEO_DRIVER_COCOA || SDL_VIDEO_DRIVER_UIKIT || SDL_VIDEO_DRIVER_X11 || SDL_VIDEO_DRIVER_WAYLAND || SDL_VIDEO_DRIVER_HAIKU || SDL_VIDEO_DRIVER_OS2
#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT || SDL_VIDEO_DRIVER_COCOA || SDL_VIDEO_DRIVER_UIKIT || SDL_VIDEO_DRIVER_X11 || SDL_VIDEO_DRIVER_WAYLAND || SDL_VIDEO_DRIVER_HAIKU || SDL_VIDEO_DRIVER_OS2 || SDL_VIDEO_DRIVER_RISCOS
static SDL_bool SDL_MessageboxValidForDriver(const SDL_MessageBoxData *messageboxdata, SDL_SYSWM_TYPE drivertype)
{
SDL_SysWMinfo info;
@@ -4188,6 +4271,8 @@ SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
if (!mbdata.message) mbdata.message = "";
messageboxdata = &mbdata;
SDL_ClearError();
if (_this && _this->ShowMessageBox) {
retval = _this->ShowMessageBox(_this, messageboxdata, buttonid);
}
@@ -4255,6 +4340,13 @@ SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
retval = 0;
}
#endif
#if SDL_VIDEO_DRIVER_RISCOS
if (retval == -1 &&
SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_RISCOS) &&
RISCOS_ShowMessageBox(messageboxdata, buttonid) == 0) {
retval = 0;
}
#endif
#if SDL_VIDEO_DRIVER_VITA
if (retval == -1 &&
VITA_ShowMessageBox(messageboxdata, buttonid) == 0) {
@@ -4262,7 +4354,11 @@ SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
}
#endif
if (retval == -1) {
SDL_SetError("No message system available");
const char *error = SDL_GetError();
if (!*error) {
SDL_SetError("No message system available");
}
}
if (current_window) {

View File

@@ -1839,7 +1839,7 @@ SDL_ConvertPixels_YUV_to_YUV(int width, int height,
return SDL_SetError("SDL_ConvertPixels_YUV_to_YUV: Unsupported YUV conversion: %s -> %s", SDL_GetPixelFormatName(src_format), SDL_GetPixelFormatName(dst_format));
}
#else
return SDL_SetError("SDL not built with YUV support");
return SDL_SetError("SDL not built with YUV support");
#endif
}

View File

@@ -51,9 +51,11 @@ static void openslES_PauseDevices(void) {}
#if !SDL_AUDIO_DISABLED && SDL_AUDIO_DRIVER_AAUDIO
extern void aaudio_ResumeDevices(void);
extern void aaudio_PauseDevices(void);
SDL_bool aaudio_DetectBrokenPlayState( void );
#else
static void aaudio_ResumeDevices(void) {}
static void aaudio_PauseDevices(void) {}
static SDL_bool aaudio_DetectBrokenPlayState( void ) { return SDL_FALSE; }
#endif
@@ -168,6 +170,11 @@ Android_PumpEvents_Blocking(_THIS)
}
}
}
if ( aaudio_DetectBrokenPlayState() ) {
aaudio_PauseDevices();
aaudio_ResumeDevices();
}
}
void
@@ -246,6 +253,11 @@ Android_PumpEvents_NonBlocking(_THIS)
}
}
}
if ( aaudio_DetectBrokenPlayState() ) {
aaudio_PauseDevices();
aaudio_ResumeDevices();
}
}
#endif /* SDL_VIDEO_DRIVER_ANDROID */

View File

@@ -162,7 +162,7 @@ GetDisplayModePixelFormat(CGDisplayModeRef vidmode)
}
static SDL_bool
GetDisplayMode(_THIS, CGDisplayModeRef vidmode, CFArrayRef modelist, CVDisplayLinkRef link, SDL_DisplayMode *mode)
GetDisplayMode(_THIS, CGDisplayModeRef vidmode, SDL_bool vidmodeCurrent, CFArrayRef modelist, CVDisplayLinkRef link, SDL_DisplayMode *mode)
{
SDL_DisplayModeData *data;
bool usableForGUI = CGDisplayModeIsUsableForDesktopGUI(vidmode);
@@ -178,7 +178,9 @@ GetDisplayMode(_THIS, CGDisplayModeRef vidmode, CFArrayRef modelist, CVDisplayLi
return SDL_FALSE;
}
if (!HasValidDisplayModeFlags(vidmode)) {
/* Don't fail the current mode based on flags because this could prevent Cocoa_InitModes from
* succeeding if the current mode lacks certain flags (esp kDisplayModeSafeFlag). */
if (!vidmodeCurrent && !HasValidDisplayModeFlags(vidmode)) {
return SDL_FALSE;
}
@@ -375,7 +377,7 @@ Cocoa_InitModes(_THIS)
SDL_zero(display);
/* this returns a stddup'ed string */
display.name = (char *)Cocoa_GetDisplayName(displays[i]);
if (!GetDisplayMode(_this, moderef, NULL, link, &mode)) {
if (!GetDisplayMode(_this, moderef, SDL_TRUE, NULL, link, &mode)) {
CVDisplayLinkRelease(link);
CGDisplayModeRelease(moderef);
SDL_free(display.name);
@@ -499,7 +501,7 @@ Cocoa_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
* sure there are no duplicates so it's safe to always add the desktop mode
* even in cases where it is in the CopyAllDisplayModes list.
*/
if (desktopmoderef && GetDisplayMode(_this, desktopmoderef, NULL, link, &desktopmode)) {
if (desktopmoderef && GetDisplayMode(_this, desktopmoderef, SDL_TRUE, NULL, link, &desktopmode)) {
if (!SDL_AddDisplayMode(display, &desktopmode)) {
CFRelease(((SDL_DisplayModeData*)desktopmode.driverdata)->modes);
SDL_free(desktopmode.driverdata);
@@ -546,7 +548,7 @@ Cocoa_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
CGDisplayModeRef moderef = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
SDL_DisplayMode mode;
if (GetDisplayMode(_this, moderef, modes, link, &mode)) {
if (GetDisplayMode(_this, moderef, SDL_FALSE, modes, link, &mode)) {
if (!SDL_AddDisplayMode(display, &mode)) {
CFRelease(((SDL_DisplayModeData*)mode.driverdata)->modes);
SDL_free(mode.driverdata);

View File

@@ -102,6 +102,8 @@ Cocoa_CreateDevice(int devindex)
device->SetWindowFullscreen = Cocoa_SetWindowFullscreen;
device->SetWindowGammaRamp = Cocoa_SetWindowGammaRamp;
device->GetWindowGammaRamp = Cocoa_GetWindowGammaRamp;
device->GetWindowICCProfile = Cocoa_GetWindowICCProfile;
device->SetWindowMouseRect = Cocoa_SetWindowMouseRect;
device->SetWindowMouseGrab = Cocoa_SetWindowMouseGrab;
device->SetWindowKeyboardGrab = Cocoa_SetWindowKeyboardGrab;
device->DestroyWindow = Cocoa_DestroyWindow;

View File

@@ -48,7 +48,7 @@ typedef enum
BOOL inFullscreenTransition;
PendingWindowOperation pendingWindowOperation;
BOOL isMoving;
int focusClickPending;
NSInteger focusClickPending;
int pendingWindowWarpX, pendingWindowWarpY;
BOOL isDragAreaRunning;
}
@@ -64,8 +64,8 @@ typedef enum
-(BOOL) isMoving;
-(BOOL) isMovingOrFocusClickPending;
-(void) setFocusClickPending:(int) button;
-(void) clearFocusClickPending:(int) button;
-(void) setFocusClickPending:(NSInteger) button;
-(void) clearFocusClickPending:(NSInteger) button;
-(void) setPendingMoveX:(int)x Y:(int)y;
-(void) windowDidFinishMoving;
-(void) onMovingOrFocusClickPendingStateCleared;
@@ -80,6 +80,7 @@ typedef enum
-(void) windowDidBecomeKey:(NSNotification *) aNotification;
-(void) windowDidResignKey:(NSNotification *) aNotification;
-(void) windowDidChangeBackingProperties:(NSNotification *) aNotification;
-(void) windowDidChangeScreenProfile:(NSNotification *) aNotification;
-(void) windowWillEnterFullScreen:(NSNotification *) aNotification;
-(void) windowDidEnterFullScreen:(NSNotification *) aNotification;
-(void) windowWillExitFullScreen:(NSNotification *) aNotification;
@@ -151,7 +152,9 @@ extern void Cocoa_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resiza
extern void Cocoa_SetWindowAlwaysOnTop(_THIS, SDL_Window * window, SDL_bool on_top);
extern void Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
extern int Cocoa_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp);
extern void* Cocoa_GetWindowICCProfile(_THIS, SDL_Window * window, size_t * size);
extern int Cocoa_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp);
extern void Cocoa_SetWindowMouseRect(_THIS, SDL_Window * window);
extern void Cocoa_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
extern void Cocoa_DestroyWindow(_THIS, SDL_Window * window);
extern SDL_bool Cocoa_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info);

View File

@@ -55,9 +55,21 @@
#ifndef MAC_OS_X_VERSION_10_12
#define NSEventModifierFlagCapsLock NSAlphaShiftKeyMask
#endif
#ifndef NSAppKitVersionNumber10_14
#define NSAppKitVersionNumber10_14 1671
#ifndef NSAppKitVersionNumber10_13_2
#define NSAppKitVersionNumber10_13_2 1561.2
#endif
#ifndef NSAppKitVersionNumber10_14
#define NSAppKitVersionNumber10_14 1671
#endif
@interface NSWindow (SDL)
#if MAC_OS_X_VERSION_MAX_ALLOWED < 101000 /* Added in the 10.10 SDK */
@property (readonly) NSRect contentLayoutRect;
#endif
/* This is available as of 10.13.2, but isn't in public headers */
@property (nonatomic) NSRect mouseConfinementRect;
@end
@interface SDLWindow : NSWindow <NSDraggingDestination>
/* These are needed for borderless/fullscreen windows */
@@ -322,6 +334,119 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
return SDL_TRUE;
}
static SDL_bool
ShouldAdjustCoordinatesForGrab(SDL_Window * window)
{
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
if (!data || [data->listener isMovingOrFocusClickPending]) {
return SDL_FALSE;
}
if (!(window->flags & SDL_WINDOW_INPUT_FOCUS)) {
return SDL_FALSE;
}
if ((window->flags & SDL_WINDOW_MOUSE_GRABBED) || (window->mouse_rect.w > 0 && window->mouse_rect.h > 0)) {
return SDL_TRUE;
}
return SDL_FALSE;
}
static SDL_bool
AdjustCoordinatesForGrab(SDL_Window * window, int x, int y, CGPoint *adjusted)
{
if (window->mouse_rect.w > 0 && window->mouse_rect.h > 0) {
SDL_Rect window_rect;
SDL_Rect mouse_rect;
window_rect.x = 0;
window_rect.y = 0;
window_rect.w = window->w;
window_rect.h = window->h;
if (SDL_IntersectRect(&window->mouse_rect, &window_rect, &mouse_rect)) {
int left = window->x + mouse_rect.x;
int right = left + mouse_rect.w - 1;
int top = window->y + mouse_rect.y;
int bottom = top + mouse_rect.h - 1;
if (x < left || x > right || y < top || y > bottom) {
adjusted->x = SDL_clamp(x, left, right);
adjusted->y = SDL_clamp(y, top, bottom);
return SDL_TRUE;
}
return SDL_FALSE;
}
}
if ((window->flags & SDL_WINDOW_MOUSE_GRABBED) != 0) {
int left = window->x;
int right = left + window->w - 1;
int top = window->y;
int bottom = top + window->h - 1;
if (x < left || x > right || y < top || y > bottom) {
adjusted->x = SDL_clamp(x, left, right);
adjusted->y = SDL_clamp(y, top, bottom);
return SDL_TRUE;
}
}
return SDL_FALSE;
}
static void
Cocoa_UpdateClipCursor(SDL_Window * window)
{
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_13_2) {
NSWindow *nswindow = data->nswindow;
SDL_Rect mouse_rect;
SDL_zero(mouse_rect);
if (ShouldAdjustCoordinatesForGrab(window)) {
SDL_Rect window_rect;
window_rect.x = 0;
window_rect.y = 0;
window_rect.w = window->w;
window_rect.h = window->h;
if (window->mouse_rect.w > 0 && window->mouse_rect.h > 0) {
SDL_IntersectRect(&window->mouse_rect, &window_rect, &mouse_rect);
}
if ((window->flags & SDL_WINDOW_MOUSE_GRABBED) != 0 &&
SDL_RectEmpty(&mouse_rect)) {
SDL_memcpy(&mouse_rect, &window_rect, sizeof(mouse_rect));
}
}
if (SDL_RectEmpty(&mouse_rect)) {
nswindow.mouseConfinementRect = NSZeroRect;
} else {
NSRect rect;
rect.origin.x = mouse_rect.x;
rect.origin.y = [nswindow contentLayoutRect].size.height - mouse_rect.y - mouse_rect.h;
rect.size.width = mouse_rect.w;
rect.size.height = mouse_rect.h;
nswindow.mouseConfinementRect = rect;
}
} else {
/* Move the cursor to the nearest point in the window */
if (ShouldAdjustCoordinatesForGrab(window)) {
int x, y;
CGPoint cgpoint;
SDL_GetGlobalMouseState(&x, &y);
if (AdjustCoordinatesForGrab(window, x, y, &cgpoint)) {
Cocoa_HandleMouseWarp(cgpoint.x, cgpoint.y);
CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cgpoint);
}
}
}
}
@implementation Cocoa_WindowListener
@@ -352,6 +477,7 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
[center addObserver:self selector:@selector(windowDidBecomeKey:) name:NSWindowDidBecomeKeyNotification object:window];
[center addObserver:self selector:@selector(windowDidResignKey:) name:NSWindowDidResignKeyNotification object:window];
[center addObserver:self selector:@selector(windowDidChangeBackingProperties:) name:NSWindowDidChangeBackingPropertiesNotification object:window];
[center addObserver:self selector:@selector(windowDidChangeScreenProfile:) name:NSWindowDidChangeScreenProfileNotification object:window];
[center addObserver:self selector:@selector(windowWillEnterFullScreen:) name:NSWindowWillEnterFullScreenNotification object:window];
[center addObserver:self selector:@selector(windowDidEnterFullScreen:) name:NSWindowDidEnterFullScreenNotification object:window];
[center addObserver:self selector:@selector(windowWillExitFullScreen:) name:NSWindowWillExitFullScreenNotification object:window];
@@ -483,6 +609,7 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
[center removeObserver:self name:NSWindowDidBecomeKeyNotification object:window];
[center removeObserver:self name:NSWindowDidResignKeyNotification object:window];
[center removeObserver:self name:NSWindowDidChangeBackingPropertiesNotification object:window];
[center removeObserver:self name:NSWindowDidChangeScreenProfileNotification object:window];
[center removeObserver:self name:NSWindowWillEnterFullScreenNotification object:window];
[center removeObserver:self name:NSWindowDidEnterFullScreenNotification object:window];
[center removeObserver:self name:NSWindowWillExitFullScreenNotification object:window];
@@ -513,12 +640,12 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
return isMoving || (focusClickPending != 0);
}
-(void) setFocusClickPending:(int) button
-(void) setFocusClickPending:(NSInteger) button
{
focusClickPending |= (1 << button);
}
-(void) clearFocusClickPending:(int) button
-(void) clearFocusClickPending:(NSInteger) button
{
if ((focusClickPending & (1 << button)) != 0) {
focusClickPending &= ~(1 << button);
@@ -567,6 +694,8 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
}
mouse->SetRelativeMouseMode(SDL_TRUE);
} else {
Cocoa_UpdateClipCursor(_data->window);
}
}
}
@@ -665,6 +794,10 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
- (void)windowDidMiniaturize:(NSNotification *)aNotification
{
if (focusClickPending) {
focusClickPending = 0;
[self onMovingOrFocusClickPendingStateCleared];
}
SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
}
@@ -750,6 +883,11 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
}
}
- (void)windowDidChangeScreenProfile:(NSNotification *)aNotification
{
SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_ICCPROF_CHANGED, 0, 0);
}
- (void)windowWillEnterFullScreen:(NSNotification *)aNotification
{
SDL_Window *window = _data->window;
@@ -1012,16 +1150,43 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
return NO; /* not a special area, carry on. */
}
static int
Cocoa_SendMouseButtonClicks(SDL_Mouse * mouse, NSEvent *theEvent, SDL_Window * window, const Uint8 state, const Uint8 button)
{
const SDL_MouseID mouseID = mouse->mouseID;
const int clicks = (int) [theEvent clickCount];
SDL_Window *focus = SDL_GetKeyboardFocus();
int rc;
// macOS will send non-left clicks to background windows without raising them, so we need to
// temporarily adjust the mouse position when this happens, as `mouse` will be tracking
// the position in the currently-focused window. We don't (currently) send a mousemove
// event for the background window, this just makes sure the button is reported at the
// correct position in its own event.
if ( focus && ([theEvent window] == ((SDL_WindowData *) focus->driverdata)->nswindow) ) {
rc = SDL_SendMouseButtonClicks(window, mouseID, state, button, clicks);
} else {
const int orig_x = mouse->x;
const int orig_y = mouse->y;
const NSPoint point = [theEvent locationInWindow];
mouse->x = (int) point.x;
mouse->y = (int) (window->h - point.y);
rc = SDL_SendMouseButtonClicks(window, mouseID, state, button, clicks);
mouse->x = orig_x;
mouse->y = orig_y;
}
return rc;
}
- (void)mouseDown:(NSEvent *)theEvent
{
const SDL_Mouse *mouse = SDL_GetMouse();
SDL_Mouse *mouse = SDL_GetMouse();
if (!mouse) {
return;
}
const SDL_MouseID mouseID = mouse->mouseID;
int button;
int clicks;
/* Ignore events that aren't inside the client area (i.e. title bar.) */
if ([theEvent window]) {
@@ -1058,9 +1223,7 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
break;
}
clicks = (int) [theEvent clickCount];
SDL_SendMouseButtonClicks(_data->window, mouseID, SDL_PRESSED, button, clicks);
Cocoa_SendMouseButtonClicks(mouse, theEvent, _data->window, SDL_PRESSED, button);
}
- (void)rightMouseDown:(NSEvent *)theEvent
@@ -1075,14 +1238,12 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
- (void)mouseUp:(NSEvent *)theEvent
{
const SDL_Mouse *mouse = SDL_GetMouse();
SDL_Mouse *mouse = SDL_GetMouse();
if (!mouse) {
return;
}
const SDL_MouseID mouseID = mouse->mouseID;
int button;
int clicks;
if ([self processHitTest:theEvent]) {
SDL_SendWindowEvent(_data->window, SDL_WINDOWEVENT_HIT_TEST, 0, 0);
@@ -1109,9 +1270,7 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
break;
}
clicks = (int) [theEvent clickCount];
SDL_SendMouseButtonClicks(_data->window, mouseID, SDL_RELEASED, button, clicks);
Cocoa_SendMouseButtonClicks(mouse, theEvent, _data->window, SDL_RELEASED, button);
}
- (void)rightMouseUp:(NSEvent *)theEvent
@@ -1149,27 +1308,15 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
x = (int)point.x;
y = (int)(window->h - point.y);
if (window->flags & SDL_WINDOW_MOUSE_GRABBED) {
if (x < 0 || x >= window->w || y < 0 || y >= window->h) {
if (x < 0) {
x = 0;
} else if (x >= window->w) {
x = window->w - 1;
}
if (y < 0) {
y = 0;
} else if (y >= window->h) {
y = window->h - 1;
}
CGPoint cgpoint;
cgpoint.x = window->x + x;
cgpoint.y = window->y + y;
if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_13_2) {
/* Mouse grab is taken care of by the confinement rect */
} else {
CGPoint cgpoint;
if (ShouldAdjustCoordinatesForGrab(window) &&
AdjustCoordinatesForGrab(window, window->x + x, window->y + y, &cgpoint)) {
Cocoa_HandleMouseWarp(cgpoint.x, cgpoint.y);
CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cgpoint);
CGAssociateMouseAndMouseCursorPosition(YES);
Cocoa_HandleMouseWarp(cgpoint.x, cgpoint.y);
}
}
@@ -1200,7 +1347,18 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
{
/* probably a MacBook trackpad; make this look like a synthesized event.
This is backwards from reality, but better matches user expectations. */
const BOOL istrackpad = ([theEvent subtype] == NSEventSubtypeMouseEvent);
BOOL istrackpad = NO;
@try {
istrackpad = ([theEvent subtype] == NSEventSubtypeMouseEvent);
}
@catch (NSException *e) {
/* if NSEvent type doesn't have subtype, such as NSEventTypeBeginGesture on
* macOS 10.5 to 10.10, then NSInternalInconsistencyException is thrown.
* This still prints a message to terminal so catching it's not an ideal solution.
*
* *** Assertion failure in -[NSEvent subtype]
*/
}
NSSet *touches = [theEvent touchesMatchingPhase:NSTouchPhaseAny inView:nil];
const SDL_TouchID touchID = istrackpad ? SDL_MOUSE_TOUCHID : (SDL_TouchID)(intptr_t)[[touches anyObject] device];
@@ -1251,7 +1409,18 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
/* probably a MacBook trackpad; make this look like a synthesized event.
This is backwards from reality, but better matches user expectations. */
const BOOL istrackpad = ([theEvent subtype] == NSEventSubtypeMouseEvent);
BOOL istrackpad = NO;
@try {
istrackpad = ([theEvent subtype] == NSEventSubtypeMouseEvent);
}
@catch (NSException *e) {
/* if NSEvent type doesn't have subtype, such as NSEventTypeBeginGesture on
* macOS 10.5 to 10.10, then NSInternalInconsistencyException is thrown.
* This still prints a message to terminal so catching it's not an ideal solution.
*
* *** Assertion failure in -[NSEvent subtype]
*/
}
for (NSTouch *touch in touches) {
const SDL_TouchID touchId = istrackpad ? SDL_MOUSE_TOUCHID : (SDL_TouchID)(intptr_t)[touch device];
@@ -1981,6 +2150,42 @@ Cocoa_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp)
return 0;
}
void*
Cocoa_GetWindowICCProfile(_THIS, SDL_Window * window, size_t * size)
{
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
NSWindow *nswindow = data->nswindow;
NSScreen *screen = [nswindow screen];
NSData* iccProfileData = nil;
void* retIccProfileData = NULL;
if (screen == nil) {
SDL_SetError("Could not get screen of window.");
return NULL;
}
if ([screen colorSpace] == nil) {
SDL_SetError("Could not get colorspace information of screen.");
return NULL;
}
iccProfileData = [[screen colorSpace] ICCProfileData];
if (iccProfileData == nil) {
SDL_SetError("Could not get ICC profile data.");
return NULL;
}
retIccProfileData = SDL_malloc([iccProfileData length]);
if (!retIccProfileData) {
SDL_OutOfMemory();
return NULL;
}
[iccProfileData getBytes:retIccProfileData length:[iccProfileData length]];
*size = [iccProfileData length];
return retIccProfileData;
}
int
Cocoa_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp)
{
@@ -2005,27 +2210,20 @@ Cocoa_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp)
return 0;
}
void
Cocoa_SetWindowMouseRect(_THIS, SDL_Window * window)
{
Cocoa_UpdateClipCursor(window);
}
void
Cocoa_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
{
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
/* Move the cursor to the nearest point in the window */
if (grabbed && data && ![data->listener isMovingOrFocusClickPending]) {
int x, y;
CGPoint cgpoint;
Cocoa_UpdateClipCursor(window);
SDL_GetMouseState(&x, &y);
cgpoint.x = window->x + x;
cgpoint.y = window->y + y;
Cocoa_HandleMouseWarp(cgpoint.x, cgpoint.y);
DLog("Returning cursor to (%g, %g)", cgpoint.x, cgpoint.y);
CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cgpoint);
}
if ( data && (window->flags & SDL_WINDOW_FULLSCREEN) ) {
if (data && (window->flags & SDL_WINDOW_FULLSCREEN)) {
if (SDL_ShouldAllowTopmost() && (window->flags & SDL_WINDOW_INPUT_FOCUS)
&& ![data->listener isInFullscreenSpace]) {
/* OpenGL is rendering to the window, so make it visible! */

View File

@@ -323,7 +323,7 @@ DirectFB_WM_ProcessEvent(_THIS, SDL_Window * window, DFBWindowEvent * evt)
}
if (window->flags & SDL_WINDOW_MAXIMIZED)
return 1;
/* fall through */
SDL_FALLTHROUGH;
default:
windata->wm_grab = pos;
if (grabbed_window != NULL)

View File

@@ -261,7 +261,7 @@ ProcessWindowEvent(_THIS, SDL_Window *sdlwin, DFBWindowEvent * evt)
SDL_SendWindowEvent(sdlwin, SDL_WINDOWEVENT_MOVED,
evt->x, evt->y);
}
/* fall throught */
SDL_FALLTHROUGH;
case DWET_SIZE:
/* FIXME: what about < 0 */
evt->w -= (windata->theme.right_size + windata->theme.left_size);
@@ -683,7 +683,7 @@ EnumKeyboards(DFBInputDeviceID device_id,
#endif
devdata->keyboard[devdata->num_keyboard].id = device_id;
devdata->keyboard[devdata->num_keyboard].is_generic = 0;
if (!strncmp("X11", desc.name, 3))
if (!SDL_strncmp("X11", desc.name, 3))
{
devdata->keyboard[devdata->num_keyboard].map = xfree86_scancode_table2;
devdata->keyboard[devdata->num_keyboard].map_size = SDL_arraysize(xfree86_scancode_table2);

View File

@@ -164,7 +164,7 @@ DirectFB_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
p = surface->pixels;
for (i = 0; i < surface->h; i++)
memcpy((char *) dest + i * pitch,
SDL_memcpy((char *) dest + i * pitch,
(char *) p + i * surface->pitch, 4 * surface->w);
curdata->surf->Unlock(curdata->surf);

View File

@@ -47,7 +47,7 @@ struct SDL_GLDriverData
};
#define OPENGL_REQUIRS_DLOPEN
#if defined(OPENGL_REQUIRS_DLOPEN) && defined(SDL_LOADSO_DLOPEN)
#if defined(OPENGL_REQUIRS_DLOPEN) && defined(HAVE_DLOPEN)
#include <dlfcn.h>
#define GL_LoadObject(X) dlopen(X, (RTLD_NOW|RTLD_GLOBAL))
#define GL_LoadFunction dlsym

View File

@@ -324,6 +324,22 @@ DirectFB_AcquireVidLayer(SDL_Renderer * renderer, SDL_Texture * texture)
return 1;
}
/* Copy the SDL_Surface palette to the DirectFB texture palette */
void DirectFB_SetTexturePalette(SDL_Renderer *renderer, SDL_Texture *texture, SDL_Palette *pal)
{
int i;
DFBColor dfbpal[256];
DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
for (i = 0; i < pal->ncolors; i++) {
dfbpal[i].a = pal->colors[i].a;
dfbpal[i].r = pal->colors[i].r;
dfbpal[i].g = pal->colors[i].g;
dfbpal[i].b = pal->colors[i].b;
}
data->palette->SetEntries(data->palette, dfbpal, pal->ncolors, 0);
}
static int
DirectFB_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{
@@ -615,6 +631,59 @@ DirectFB_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const
return 0;
}
static int
DirectFB_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
const float *xy, int xy_stride, const int *color, int color_stride, const float *uv, int uv_stride,
int num_vertices, const void *indices, int num_indices, int size_indices,
float scale_x, float scale_y)
{
int i;
int count = indices ? num_indices : num_vertices;
float *verts;
int sz = 2 + 4 + (texture ? 2 : 0);
verts = (float *) SDL_AllocateRenderVertices(renderer, count * sz * sizeof (float), 0, &cmd->data.draw.first);
if (!verts) {
return -1;
}
cmd->data.draw.count = count;
size_indices = indices ? size_indices : 0;
for (i = 0; i < count; i++) {
int j;
float *xy_;
SDL_Color col_;
if (size_indices == 4) {
j = ((const Uint32 *)indices)[i];
} else if (size_indices == 2) {
j = ((const Uint16 *)indices)[i];
} else if (size_indices == 1) {
j = ((const Uint8 *)indices)[i];
} else {
j = i;
}
xy_ = (float *)((char*)xy + j * xy_stride);
col_ = *(SDL_Color *)((char*)color + j * color_stride);
*(verts++) = xy_[0] * scale_x;
*(verts++) = xy_[1] * scale_y;
*(verts++) = col_.r;
*(verts++) = col_.g;
*(verts++) = col_.b;
*(verts++) = col_.a;
if (texture) {
float *uv_ = (float *)((char*)uv + j * uv_stride);
*(verts++) = uv_[0];
*(verts++) = uv_[1];
}
}
return 0;
}
static int
DirectFB_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count)
{
@@ -648,15 +717,6 @@ DirectFB_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture
return 0;
}
static int
DirectFB_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
const SDL_Rect * srcrect, const SDL_FRect * dstrect,
const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
{
return SDL_Unsupported();
}
static int
DirectFB_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
{
@@ -814,8 +874,145 @@ DirectFB_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *
break;
}
case SDL_RENDERCMD_COPY_EX:
break; /* unsupported */
case SDL_RENDERCMD_GEOMETRY: {
const float *verts = (float *) (((Uint8 *) vertices) + cmd->data.draw.first);
SDL_Texture *texture = cmd->data.draw.texture;
const size_t count = cmd->data.draw.count;
Uint8 save_r = cmd->data.draw.r;
Uint8 save_g = cmd->data.draw.g;
Uint8 save_b = cmd->data.draw.b;
Uint8 save_a = cmd->data.draw.a;
int j;
for (j = 0; j < count; j += 3)
{
float x1, y1, r1, g1, b1, a1, u1, v1;
float x2, y2, r2, g2, b2, a2, u2, v2;
float x3, y3, r3, g3, b3, a3, u3, v3;
x1 = *(verts++);
y1 = *(verts++);
r1 = *(verts++);
g1 = *(verts++);
b1 = *(verts++);
a1 = *(verts++);
if (texture) {
u1 = *(verts++);
v1 = *(verts++);
}
x2 = *(verts++);
y2 = *(verts++);
r2 = *(verts++);
g2 = *(verts++);
b2 = *(verts++);
a2 = *(verts++);
if (texture) {
u2 = *(verts++);
v2 = *(verts++);
}
x3 = *(verts++);
y3 = *(verts++);
r3 = *(verts++);
g3 = *(verts++);
b3 = *(verts++);
a3 = *(verts++);
if (texture) {
u3 = *(verts++);
v3 = *(verts++);
}
if (texture) {
DFBVertex vertices[3];
DirectFB_TextureData *texturedata = (DirectFB_TextureData *) texture->driverdata;
DFBSurfaceBlittingFlags flags = 0;
int r = (r1 + r2 + r3) / 3;
int g = (g1 + g2 + g3) / 3;
int b = (b1 + b2 + b3) / 3;
int a = (a1 + a2 + a3) / 3;
if (texturedata->isDirty) {
const SDL_Rect rect = { 0, 0, texture->w, texture->h };
DirectFB_UpdateTexture(renderer, texture, &rect, texturedata->pixels, texturedata->pitch);
}
if (a != 0xFF) {
flags |= DSBLIT_BLEND_COLORALPHA;
}
if ((r & g & b) != 0xFF) {
flags |= DSBLIT_COLORIZE;
}
destsurf->SetColor(destsurf, r, g, b, a);
/* ???? flags |= DSBLIT_SRC_PREMULTCOLOR; */
SetBlendMode(data, texture->blendMode, texturedata);
destsurf->SetBlittingFlags(destsurf, data->blitFlags | flags);
#if (DFB_VERSION_ATLEAST(1,2,0))
destsurf->SetRenderOptions(destsurf, texturedata->render_options);
#endif
vertices[0].x = x1;
vertices[0].y = y1;
vertices[0].z = 0;
vertices[0].w = 0;
vertices[0].s = u1;
vertices[0].t = v1;
vertices[1].x = x2;
vertices[1].y = y2;
vertices[1].z = 0;
vertices[1].w = 0;
vertices[1].s = u2;
vertices[1].t = v2;
vertices[2].x = x3;
vertices[2].y = y3;
vertices[2].z = 0;
vertices[2].w = 0;
vertices[2].s = u3;
vertices[2].t = v3;
destsurf->TextureTriangles(destsurf, texturedata->surface, vertices, NULL, 3, DTTF_LIST);
} else {
DFBTriangle tris;
tris.x1 = x1;
tris.y1 = y1;
tris.x2 = x2;
tris.y2 = y2;
tris.x3 = x3;
tris.y3 = y3;
cmd->data.draw.r = (r1 + r2 + r3) / 3;
cmd->data.draw.g = (g1 + g2 + g3) / 3;
cmd->data.draw.b = (b1 + b2 + b3) / 3;
cmd->data.draw.a = (a1 + a2 + a3) / 3;
PrepareDraw(renderer, cmd);
destsurf->FillTriangles(destsurf, &tris, 1);
}
}
cmd->data.draw.r = save_r;
cmd->data.draw.g = save_g;
cmd->data.draw.b = save_b;
cmd->data.draw.a = save_a;
break;
}
case SDL_RENDERCMD_COPY_EX: /* unused */
break;
case SDL_RENDERCMD_NO_OP:
break;
@@ -984,9 +1181,9 @@ DirectFB_CreateRenderer(SDL_Window * window, Uint32 flags)
renderer->QueueSetDrawColor = DirectFB_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */
renderer->QueueDrawPoints = DirectFB_QueueDrawPoints;
renderer->QueueDrawLines = DirectFB_QueueDrawPoints; /* lines and points queue vertices the same way. */
renderer->QueueGeometry = DirectFB_QueueGeometry;
renderer->QueueFillRects = DirectFB_QueueFillRects;
renderer->QueueCopy = DirectFB_QueueCopy;
renderer->QueueCopyEx = DirectFB_QueueCopyEx;
renderer->RunCommandQueue = DirectFB_RunCommandQueue;
renderer->RenderPresent = DirectFB_RenderPresent;

View File

@@ -34,7 +34,7 @@ DirectFB_CreateShaper(SDL_Window* window) {
SDL_ShapeData* data;
int resized_properly;
result = malloc(sizeof(SDL_WindowShaper));
result = SDL_malloc(sizeof(SDL_WindowShaper));
result->window = window;
result->mode.mode = ShapeModeDefault;
result->mode.parameters.binarizationCutoff = 1;

View File

@@ -201,7 +201,7 @@ static int readBoolEnv(const char *env_name, int def_val)
stemp = SDL_getenv(env_name);
if (stemp)
return atoi(stemp);
return SDL_atoi(stemp);
else
return def_val;
}

View File

@@ -227,7 +227,7 @@ DirectFB_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
p = surface->pixels;
for (i = 0; i < surface->h; i++)
memcpy((char *) dest + i * pitch,
SDL_memcpy((char *) dest + i * pitch,
(char *) p + i * surface->pitch, 4 * surface->w);
SDL_DFB_CHECK(windata->icon->Unlock(windata->icon));

View File

@@ -409,7 +409,22 @@ static EM_BOOL
Emscripten_HandleWheel(int eventType, const EmscriptenWheelEvent *wheelEvent, void *userData)
{
SDL_WindowData *window_data = userData;
SDL_SendMouseWheel(window_data->window, 0, (float)wheelEvent->deltaX, (float)-wheelEvent->deltaY, SDL_MOUSEWHEEL_NORMAL);
float deltaY = wheelEvent->deltaY;
switch (wheelEvent->deltaMode) {
case DOM_DELTA_PIXEL:
deltaY /= 100; /* 100 pixels make up a step */
break;
case DOM_DELTA_LINE:
deltaY /= 3; /* 3 lines make up a step */
break;
case DOM_DELTA_PAGE:
deltaY *= 80; /* A page makes up 80 steps */
break;
}
SDL_SendMouseWheel(window_data->window, 0, (float)wheelEvent->deltaX, -deltaY, SDL_MOUSEWHEEL_NORMAL);
return SDL_GetEventState(SDL_MOUSEWHEEL) == SDL_ENABLE;
}
@@ -607,9 +622,6 @@ Emscripten_HandleFullscreenChange(int eventType, const EmscriptenFullscreenChang
window_data->window->flags |= window_data->requested_fullscreen_mode;
window_data->requested_fullscreen_mode = 0;
if(!window_data->requested_fullscreen_mode)
window_data->window->flags |= SDL_WINDOW_FULLSCREEN; /*we didn't request fullscreen*/
}
else
{

View File

@@ -109,6 +109,7 @@ int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rec
if (SDL2.data32Data !== data) {
SDL2.data32 = new Int32Array(data.buffer);
SDL2.data8 = new Uint8Array(data.buffer);
SDL2.data32Data = data;
}
var data32 = SDL2.data32;
num = data32.length;
@@ -118,7 +119,7 @@ int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rec
// }
// the following code is faster though, because
// .set() is almost free - easily 10x faster due to
// native memcpy efficiencies, and the remaining loop
// native SDL_memcpy efficiencies, and the remaining loop
// just stores, not load + store, so it is faster
data32.set(HEAP32.subarray(src, src + num));
var data8 = SDL2.data8;
@@ -156,14 +157,6 @@ int Emscripten_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rec
return 0;
}, surface->w, surface->h, surface->pixels);
/*if (SDL_getenv("SDL_VIDEO_Emscripten_SAVE_FRAMES")) {
static int frame_number = 0;
char file[128];
SDL_snprintf(file, sizeof(file), "SDL_window%d-%8.8d.bmp",
SDL_GetWindowID(window), ++frame_number);
SDL_SaveBMP(surface, file);
}*/
if (emscripten_has_asyncify() && SDL_GetHintBoolean(SDL_HINT_EMSCRIPTEN_ASYNCIFY, SDL_TRUE)) {
/* give back control to browser for screen refresh */
emscripten_sleep(0);

View File

@@ -137,14 +137,7 @@ Emscripten_VideoInit(_THIS)
/* Use a fake 32-bpp desktop mode */
mode.format = SDL_PIXELFORMAT_RGB888;
mode.w = EM_ASM_INT_V({
return screen.width;
});
mode.h = EM_ASM_INT_V({
return screen.height;
});
emscripten_get_screen_size(&mode.w, &mode.h);
mode.refresh_rate = 0;
mode.driverdata = NULL;
@@ -359,12 +352,7 @@ Emscripten_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * di
static void
Emscripten_SetWindowTitle(_THIS, SDL_Window * window) {
EM_ASM_INT({
if (typeof setWindowTitle !== 'undefined') {
setWindowTitle(UTF8ToString($0));
}
return 0;
}, window->title);
emscripten_set_window_title(window->title);
}
#endif /* SDL_VIDEO_DRIVER_EMSCRIPTEN */

View File

@@ -124,7 +124,7 @@ class SDL_BWin:public BDirectWindow
#ifdef DRAWTHREAD
wait_for_thread(_draw_thread_id, &result);
#endif
free(_clips);
SDL_free(_clips);
delete _buffer_locker;
}
@@ -184,16 +184,16 @@ class SDL_BWin:public BDirectWindow
if (info->clip_list_count > _num_clips)
{
if(_clips) {
free(_clips);
SDL_free(_clips);
_clips = NULL;
}
}
_num_clips = info->clip_list_count;
if (_clips == NULL)
_clips = (clipping_rect *)malloc(_num_clips*sizeof(clipping_rect));
_clips = (clipping_rect *)SDL_malloc(_num_clips*sizeof(clipping_rect));
if(_clips) {
memcpy(_clips, info->clip_list,
SDL_memcpy(_clips, info->clip_list,
_num_clips*sizeof(clipping_rect));
_bits = (uint8*) info->bits;

View File

@@ -281,7 +281,7 @@ void HAIKU_GetDisplayModes(_THIS, SDL_VideoDisplay *display) {
SDL_AddDisplayMode(display, &mode);
}
}
free(bmodes);
free(bmodes); /* This should not be SDL_free() */
}
@@ -313,7 +313,7 @@ int HAIKU_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode
return SDL_SetError("Bad video mode");
}
free(bmode_list);
free(bmode_list); /* This should not be SDL_free() */
#if SDL_VIDEO_OPENGL
/* FIXME: Is there some way to reboot the OpenGL context? This doesn't

View File

@@ -6,39 +6,24 @@ extern "C" {
#endif
/*
** Copyright (c) 2013-2017 The Khronos Group Inc.
** Copyright 2013-2020 The Khronos Group Inc.
** SPDX-License-Identifier: Apache-2.0
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE 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
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
/*
** This header is generated from the Khronos OpenGL / OpenGL ES XML
** API Registry. The current version of the Registry, generator scripts
** This header is generated from the Khronos EGL XML API Registry.
** The current version of the Registry, generator scripts
** used to make the header, and the header can be found at
** http://www.khronos.org/registry/egl
**
** Khronos $Git commit SHA1: a732b061e7 $ on $Git commit date: 2017-06-17 23:27:53 +0100 $
** Khronos $Git commit SHA1: 9581d004ff $ on $Git commit date: 2021-04-06 15:53:59 +0200 $
*/
#include <EGL/eglplatform.h>
/* Generated on date 20170627 */
#ifndef EGL_EGL_PROTOTYPES
#define EGL_EGL_PROTOTYPES 1
#endif
/* Generated on date 20210802 */
/* Generated C header for:
* API: egl
@@ -118,6 +103,31 @@ typedef void (*__eglMustCastToProperFunctionPointerType)(void);
#define EGL_VERSION 0x3054
#define EGL_WIDTH 0x3057
#define EGL_WINDOW_BIT 0x0004
typedef EGLBoolean (EGLAPIENTRYP PFNEGLCHOOSECONFIGPROC) (EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOPYBUFFERSPROC) (EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target);
typedef EGLContext (EGLAPIENTRYP PFNEGLCREATECONTEXTPROC) (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPBUFFERSURFACEPROC) (EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPIXMAPSURFACEPROC) (EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list);
typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEWINDOWSURFACEPROC) (EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYCONTEXTPROC) (EGLDisplay dpy, EGLContext ctx);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSURFACEPROC) (EGLDisplay dpy, EGLSurface surface);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETCONFIGATTRIBPROC) (EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETCONFIGSPROC) (EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETCURRENTDISPLAYPROC) (void);
typedef EGLSurface (EGLAPIENTRYP PFNEGLGETCURRENTSURFACEPROC) (EGLint readdraw);
typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETDISPLAYPROC) (EGLNativeDisplayType display_id);
typedef EGLint (EGLAPIENTRYP PFNEGLGETERRORPROC) (void);
typedef __eglMustCastToProperFunctionPointerType (EGLAPIENTRYP PFNEGLGETPROCADDRESSPROC) (const char *procname);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLINITIALIZEPROC) (EGLDisplay dpy, EGLint *major, EGLint *minor);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLMAKECURRENTPROC) (EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYCONTEXTPROC) (EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value);
typedef const char *(EGLAPIENTRYP PFNEGLQUERYSTRINGPROC) (EGLDisplay dpy, EGLint name);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSPROC) (EGLDisplay dpy, EGLSurface surface);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLTERMINATEPROC) (EGLDisplay dpy);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITGLPROC) (void);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITNATIVEPROC) (EGLint engine);
#if EGL_EGL_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig (EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers (EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target);
EGLAPI EGLContext EGLAPIENTRY eglCreateContext (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
@@ -142,6 +152,7 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers (EGLDisplay dpy, EGLSurface surface
EGLAPI EGLBoolean EGLAPIENTRY eglTerminate (EGLDisplay dpy);
EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL (void);
EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative (EGLint engine);
#endif
#endif /* EGL_VERSION_1_0 */
#ifndef EGL_VERSION_1_1
@@ -160,10 +171,16 @@ EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative (EGLint engine);
#define EGL_TEXTURE_RGB 0x305D
#define EGL_TEXTURE_RGBA 0x305E
#define EGL_TEXTURE_TARGET 0x3081
typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDTEXIMAGEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint buffer);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLRELEASETEXIMAGEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint buffer);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSURFACEATTRIBPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPINTERVALPROC) (EGLDisplay dpy, EGLint interval);
#if EGL_EGL_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer);
EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer);
EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval (EGLDisplay dpy, EGLint interval);
#endif
#endif /* EGL_VERSION_1_1 */
#ifndef EGL_VERSION_1_2
@@ -199,11 +216,18 @@ typedef void *EGLClientBuffer;
#define EGL_SWAP_BEHAVIOR 0x3093
#define EGL_UNKNOWN EGL_CAST(EGLint,-1)
#define EGL_VERTICAL_RESOLUTION 0x3091
typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDAPIPROC) (EGLenum api);
typedef EGLenum (EGLAPIENTRYP PFNEGLQUERYAPIPROC) (void);
typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC) (EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLRELEASETHREADPROC) (void);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITCLIENTPROC) (void);
#if EGL_EGL_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI (EGLenum api);
EGLAPI EGLenum EGLAPIENTRY eglQueryAPI (void);
EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer (EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread (void);
EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient (void);
#endif
#endif /* EGL_VERSION_1_2 */
#ifndef EGL_VERSION_1_3
@@ -232,7 +256,10 @@ EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient (void);
#define EGL_OPENGL_API 0x30A2
#define EGL_OPENGL_BIT 0x0008
#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400
typedef EGLContext (EGLAPIENTRYP PFNEGLGETCURRENTCONTEXTPROC) (void);
#if EGL_EGL_PROTOTYPES
EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext (void);
#endif
#endif /* EGL_VERSION_1_4 */
#ifndef EGL_VERSION_1_5
@@ -284,6 +311,17 @@ typedef void *EGLImage;
#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x30B8
#define EGL_IMAGE_PRESERVED 0x30D2
#define EGL_NO_IMAGE EGL_CAST(EGLImage,0)
typedef EGLSync (EGLAPIENTRYP PFNEGLCREATESYNCPROC) (EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCPROC) (EGLDisplay dpy, EGLSync sync);
typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCPROC) (EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBPROC) (EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value);
typedef EGLImage (EGLAPIENTRYP PFNEGLCREATEIMAGEPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEPROC) (EGLDisplay dpy, EGLImage image);
typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYPROC) (EGLenum platform, void *native_display, const EGLAttrib *attrib_list);
typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMWINDOWSURFACEPROC) (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list);
typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC) (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLWAITSYNCPROC) (EGLDisplay dpy, EGLSync sync, EGLint flags);
#if EGL_EGL_PROTOTYPES
EGLAPI EGLSync EGLAPIENTRY eglCreateSync (EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglDestroySync (EGLDisplay dpy, EGLSync sync);
EGLAPI EGLint EGLAPIENTRY eglClientWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout);
@@ -294,6 +332,7 @@ EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplay (EGLenum platform, void *nat
EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurface (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list);
EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurface (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags);
#endif
#endif /* EGL_VERSION_1_5 */
#ifdef __cplusplus

View File

@@ -6,39 +6,20 @@ extern "C" {
#endif
/*
** Copyright (c) 2013-2017 The Khronos Group Inc.
** Copyright 2013-2020 The Khronos Group Inc.
** SPDX-License-Identifier: Apache-2.0
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE 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
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
/*
** This header is generated from the Khronos OpenGL / OpenGL ES XML
** API Registry. The current version of the Registry, generator scripts
** This header is generated from the Khronos EGL XML API Registry.
** The current version of the Registry, generator scripts
** used to make the header, and the header can be found at
** http://www.khronos.org/registry/egl
**
** Khronos $Git commit SHA1: a732b061e7 $ on $Git commit date: 2017-06-17 23:27:53 +0100 $
** Khronos $Git commit SHA1: dc0b58dca5 $ on $Git commit date: 2021-06-25 01:58:50 +0200 $
*/
#include <EGL/eglplatform.h>
#define EGL_EGLEXT_VERSION 20170627
#define EGL_EGLEXT_VERSION 20210629
/* Generated C header for:
* API: egl
@@ -443,9 +424,9 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreateStreamProducerSurfaceKHR (EGLDisplay dpy,
#ifndef EGL_KHR_swap_buffers_with_damage
#define EGL_KHR_swap_buffers_with_damage 1
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC) (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageKHR (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageKHR (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects);
#endif
#endif /* EGL_KHR_swap_buffers_with_damage */
@@ -462,6 +443,10 @@ EGLAPI EGLint EGLAPIENTRY eglWaitSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLin
#endif
#endif /* EGL_KHR_wait_sync */
#ifndef EGL_ANDROID_GLES_layers
#define EGL_ANDROID_GLES_layers 1
#endif /* EGL_ANDROID_GLES_layers */
#ifndef EGL_ANDROID_blob_cache
#define EGL_ANDROID_blob_cache 1
typedef khronos_ssize_t EGLsizeiANDROID;
@@ -495,6 +480,47 @@ EGLAPI EGLClientBuffer EGLAPIENTRY eglCreateNativeClientBufferANDROID (const EGL
#define EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID 0x314C
#endif /* EGL_ANDROID_front_buffer_auto_refresh */
#ifndef EGL_ANDROID_get_frame_timestamps
#define EGL_ANDROID_get_frame_timestamps 1
typedef khronos_stime_nanoseconds_t EGLnsecsANDROID;
#define EGL_TIMESTAMP_PENDING_ANDROID EGL_CAST(EGLnsecsANDROID,-2)
#define EGL_TIMESTAMP_INVALID_ANDROID EGL_CAST(EGLnsecsANDROID,-1)
#define EGL_TIMESTAMPS_ANDROID 0x3430
#define EGL_COMPOSITE_DEADLINE_ANDROID 0x3431
#define EGL_COMPOSITE_INTERVAL_ANDROID 0x3432
#define EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID 0x3433
#define EGL_REQUESTED_PRESENT_TIME_ANDROID 0x3434
#define EGL_RENDERING_COMPLETE_TIME_ANDROID 0x3435
#define EGL_COMPOSITION_LATCH_TIME_ANDROID 0x3436
#define EGL_FIRST_COMPOSITION_START_TIME_ANDROID 0x3437
#define EGL_LAST_COMPOSITION_START_TIME_ANDROID 0x3438
#define EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID 0x3439
#define EGL_DISPLAY_PRESENT_TIME_ANDROID 0x343A
#define EGL_DEQUEUE_READY_TIME_ANDROID 0x343B
#define EGL_READS_DONE_TIME_ANDROID 0x343C
typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETCOMPOSITORTIMINGSUPPORTEDANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLint name);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETCOMPOSITORTIMINGANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numTimestamps, const EGLint *names, EGLnsecsANDROID *values);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETNEXTFRAMEIDANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR *frameId);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETFRAMETIMESTAMPSUPPORTEDANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLint timestamp);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETFRAMETIMESTAMPSANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR frameId, EGLint numTimestamps, const EGLint *timestamps, EGLnsecsANDROID *values);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglGetCompositorTimingSupportedANDROID (EGLDisplay dpy, EGLSurface surface, EGLint name);
EGLAPI EGLBoolean EGLAPIENTRY eglGetCompositorTimingANDROID (EGLDisplay dpy, EGLSurface surface, EGLint numTimestamps, const EGLint *names, EGLnsecsANDROID *values);
EGLAPI EGLBoolean EGLAPIENTRY eglGetNextFrameIdANDROID (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR *frameId);
EGLAPI EGLBoolean EGLAPIENTRY eglGetFrameTimestampSupportedANDROID (EGLDisplay dpy, EGLSurface surface, EGLint timestamp);
EGLAPI EGLBoolean EGLAPIENTRY eglGetFrameTimestampsANDROID (EGLDisplay dpy, EGLSurface surface, EGLuint64KHR frameId, EGLint numTimestamps, const EGLint *timestamps, EGLnsecsANDROID *values);
#endif
#endif /* EGL_ANDROID_get_frame_timestamps */
#ifndef EGL_ANDROID_get_native_client_buffer
#define EGL_ANDROID_get_native_client_buffer 1
struct AHardwareBuffer;
typedef EGLClientBuffer (EGLAPIENTRYP PFNEGLGETNATIVECLIENTBUFFERANDROIDPROC) (const struct AHardwareBuffer *buffer);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLClientBuffer EGLAPIENTRY eglGetNativeClientBufferANDROID (const struct AHardwareBuffer *buffer);
#endif
#endif /* EGL_ANDROID_get_native_client_buffer */
#ifndef EGL_ANDROID_image_native_buffer
#define EGL_ANDROID_image_native_buffer 1
#define EGL_NATIVE_BUFFER_ANDROID 0x3140
@@ -514,7 +540,6 @@ EGLAPI EGLint EGLAPIENTRY eglDupNativeFenceFDANDROID (EGLDisplay dpy, EGLSyncKHR
#ifndef EGL_ANDROID_presentation_time
#define EGL_ANDROID_presentation_time 1
typedef khronos_stime_nanoseconds_t EGLnsecsANDROID;
typedef EGLBoolean (EGLAPIENTRYP PFNEGLPRESENTATIONTIMEANDROIDPROC) (EGLDisplay dpy, EGLSurface surface, EGLnsecsANDROID time);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglPresentationTimeANDROID (EGLDisplay dpy, EGLSurface surface, EGLnsecsANDROID time);
@@ -549,11 +574,25 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu
#define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1
#endif /* EGL_ANGLE_surface_d3d_texture_2d_share_handle */
#ifndef EGL_ANGLE_sync_control_rate
#define EGL_ANGLE_sync_control_rate 1
typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETMSCRATEANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *numerator, EGLint *denominator);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglGetMscRateANGLE (EGLDisplay dpy, EGLSurface surface, EGLint *numerator, EGLint *denominator);
#endif
#endif /* EGL_ANGLE_sync_control_rate */
#ifndef EGL_ANGLE_window_fixed_size
#define EGL_ANGLE_window_fixed_size 1
#define EGL_FIXED_SIZE_ANGLE 0x3201
#endif /* EGL_ANGLE_window_fixed_size */
#ifndef EGL_ARM_image_format
#define EGL_ARM_image_format 1
#define EGL_COLOR_COMPONENT_TYPE_UNSIGNED_INTEGER_ARM 0x3287
#define EGL_COLOR_COMPONENT_TYPE_INTEGER_ARM 0x3288
#endif /* EGL_ARM_image_format */
#ifndef EGL_ARM_implicit_external_sync
#define EGL_ARM_implicit_external_sync 1
#define EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM 0x328A
@@ -578,6 +617,16 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu
#define EGL_EXT_client_extensions 1
#endif /* EGL_EXT_client_extensions */
#ifndef EGL_EXT_client_sync
#define EGL_EXT_client_sync 1
#define EGL_SYNC_CLIENT_EXT 0x3364
#define EGL_SYNC_CLIENT_SIGNAL_EXT 0x3365
typedef EGLBoolean (EGLAPIENTRYP PFNEGLCLIENTSIGNALSYNCEXTPROC) (EGLDisplay dpy, EGLSync sync, const EGLAttrib *attrib_list);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglClientSignalSyncEXT (EGLDisplay dpy, EGLSync sync, const EGLAttrib *attrib_list);
#endif
#endif /* EGL_EXT_client_sync */
#ifndef EGL_EXT_compositor
#define EGL_EXT_compositor 1
#define EGL_PRIMARY_COMPOSITOR_CONTEXT_EXT 0x3460
@@ -602,6 +651,11 @@ EGLAPI EGLBoolean EGLAPIENTRY eglCompositorSwapPolicyEXT (EGLint external_win_id
#endif
#endif /* EGL_EXT_compositor */
#ifndef EGL_EXT_config_select_group
#define EGL_EXT_config_select_group 1
#define EGL_CONFIG_SELECT_GROUP_EXT 0x34C0
#endif /* EGL_EXT_config_select_group */
#ifndef EGL_EXT_create_context_robustness
#define EGL_EXT_create_context_robustness 1
#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT 0x30BF
@@ -631,8 +685,14 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribEXT (EGLDisplay dpy, EGLint a
#ifndef EGL_EXT_device_drm
#define EGL_EXT_device_drm 1
#define EGL_DRM_DEVICE_FILE_EXT 0x3233
#define EGL_DRM_MASTER_FD_EXT 0x333C
#endif /* EGL_EXT_device_drm */
#ifndef EGL_EXT_device_drm_render_node
#define EGL_EXT_device_drm_render_node 1
#define EGL_DRM_RENDER_NODE_FILE_EXT 0x3377
#endif /* EGL_EXT_device_drm_render_node */
#ifndef EGL_EXT_device_enumeration
#define EGL_EXT_device_enumeration 1
#endif /* EGL_EXT_device_enumeration */
@@ -642,10 +702,26 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribEXT (EGLDisplay dpy, EGLint a
#define EGL_OPENWF_DEVICE_ID_EXT 0x3237
#endif /* EGL_EXT_device_openwf */
#ifndef EGL_EXT_device_persistent_id
#define EGL_EXT_device_persistent_id 1
#define EGL_DEVICE_UUID_EXT 0x335C
#define EGL_DRIVER_UUID_EXT 0x335D
#define EGL_DRIVER_NAME_EXT 0x335E
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICEBINARYEXTPROC) (EGLDeviceEXT device, EGLint name, EGLint max_size, void *value, EGLint *size);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglQueryDeviceBinaryEXT (EGLDeviceEXT device, EGLint name, EGLint max_size, void *value, EGLint *size);
#endif
#endif /* EGL_EXT_device_persistent_id */
#ifndef EGL_EXT_device_query
#define EGL_EXT_device_query 1
#endif /* EGL_EXT_device_query */
#ifndef EGL_EXT_device_query_name
#define EGL_EXT_device_query_name 1
#define EGL_RENDERER_EXT 0x335F
#endif /* EGL_EXT_device_query_name */
#ifndef EGL_EXT_gl_colorspace_bt2020_linear
#define EGL_EXT_gl_colorspace_bt2020_linear 1
#define EGL_GL_COLORSPACE_BT2020_LINEAR_EXT 0x333F
@@ -666,6 +742,11 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribEXT (EGLDisplay dpy, EGLint a
#define EGL_GL_COLORSPACE_DISPLAY_P3_LINEAR_EXT 0x3362
#endif /* EGL_EXT_gl_colorspace_display_p3_linear */
#ifndef EGL_EXT_gl_colorspace_display_p3_passthrough
#define EGL_EXT_gl_colorspace_display_p3_passthrough 1
#define EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT 0x3490
#endif /* EGL_EXT_gl_colorspace_display_p3_passthrough */
#ifndef EGL_EXT_gl_colorspace_scrgb
#define EGL_EXT_gl_colorspace_scrgb 1
#define EGL_GL_COLORSPACE_SCRGB_EXT 0x3351
@@ -723,6 +804,11 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQueryDmaBufModifiersEXT (EGLDisplay dpy, EGLint
#endif
#endif /* EGL_EXT_image_dma_buf_import_modifiers */
#ifndef EGL_EXT_image_gl_colorspace
#define EGL_EXT_image_gl_colorspace 1
#define EGL_GL_COLORSPACE_DEFAULT_EXT 0x314D
#endif /* EGL_EXT_image_gl_colorspace */
#ifndef EGL_EXT_image_implicit_sync_control
#define EGL_EXT_image_implicit_sync_control 1
#define EGL_IMPORT_SYNC_TYPE_EXT 0x3470
@@ -812,6 +898,17 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurfaceEXT (EGLDisplay dpy,
#define EGL_PLATFORM_X11_SCREEN_EXT 0x31D6
#endif /* EGL_EXT_platform_x11 */
#ifndef EGL_EXT_platform_xcb
#define EGL_EXT_platform_xcb 1
#define EGL_PLATFORM_XCB_EXT 0x31DC
#define EGL_PLATFORM_XCB_SCREEN_EXT 0x31DE
#endif /* EGL_EXT_platform_xcb */
#ifndef EGL_EXT_present_opaque
#define EGL_EXT_present_opaque 1
#define EGL_PRESENT_OPAQUE_EXT 0x31DF
#endif /* EGL_EXT_present_opaque */
#ifndef EGL_EXT_protected_content
#define EGL_EXT_protected_content 1
#define EGL_PROTECTED_CONTENT_EXT 0x32C0
@@ -852,12 +949,20 @@ EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerOutputEXT (EGLDisplay dpy, EGLStr
#ifndef EGL_EXT_swap_buffers_with_damage
#define EGL_EXT_swap_buffers_with_damage 1
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC) (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageEXT (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageEXT (EGLDisplay dpy, EGLSurface surface, const EGLint *rects, EGLint n_rects);
#endif
#endif /* EGL_EXT_swap_buffers_with_damage */
#ifndef EGL_EXT_sync_reuse
#define EGL_EXT_sync_reuse 1
typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNSIGNALSYNCEXTPROC) (EGLDisplay dpy, EGLSync sync, const EGLAttrib *attrib_list);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglUnsignalSyncEXT (EGLDisplay dpy, EGLSync sync, const EGLAttrib *attrib_list);
#endif
#endif /* EGL_EXT_sync_reuse */
#ifndef EGL_EXT_yuv_surface
#define EGL_EXT_yuv_surface 1
#define EGL_YUV_ORDER_EXT 0x3301
@@ -933,6 +1038,7 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurfaceHI (EGLDisplay dpy, EGLConfi
#define EGL_DRM_BUFFER_STRIDE_MESA 0x31D4
#define EGL_DRM_BUFFER_USE_SCANOUT_MESA 0x00000001
#define EGL_DRM_BUFFER_USE_SHARE_MESA 0x00000002
#define EGL_DRM_BUFFER_USE_CURSOR_MESA 0x00000004
typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEDRMIMAGEMESAPROC) (EGLDisplay dpy, const EGLint *attrib_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDRMIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride);
#ifdef EGL_EGLEXT_PROTOTYPES
@@ -961,6 +1067,16 @@ EGLAPI EGLBoolean EGLAPIENTRY eglExportDMABUFImageMESA (EGLDisplay dpy, EGLImage
#define EGL_PLATFORM_SURFACELESS_MESA 0x31DD
#endif /* EGL_MESA_platform_surfaceless */
#ifndef EGL_MESA_query_driver
#define EGL_MESA_query_driver 1
typedef char *(EGLAPIENTRYP PFNEGLGETDISPLAYDRIVERCONFIGPROC) (EGLDisplay dpy);
typedef const char *(EGLAPIENTRYP PFNEGLGETDISPLAYDRIVERNAMEPROC) (EGLDisplay dpy);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI char *EGLAPIENTRY eglGetDisplayDriverConfig (EGLDisplay dpy);
EGLAPI const char *EGLAPIENTRY eglGetDisplayDriverName (EGLDisplay dpy);
#endif
#endif /* EGL_MESA_query_driver */
#ifndef EGL_NOK_swap_region
#define EGL_NOK_swap_region 1
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGIONNOKPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects);
@@ -987,6 +1103,11 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegion2NOK (EGLDisplay dpy, EGLSurfa
#define EGL_AUTO_STEREO_NV 0x3136
#endif /* EGL_NV_3dvision_surface */
#ifndef EGL_NV_context_priority_realtime
#define EGL_NV_context_priority_realtime 1
#define EGL_CONTEXT_PRIORITY_REALTIME_NV 0x3357
#endif /* EGL_NV_context_priority_realtime */
#ifndef EGL_NV_coverage_sample
#define EGL_NV_coverage_sample 1
#define EGL_COVERAGE_BUFFERS_NV 0x30E0
@@ -1044,19 +1165,42 @@ EGLAPI EGLBoolean EGLAPIENTRY eglPostSubBufferNV (EGLDisplay dpy, EGLSurface sur
#endif
#endif /* EGL_NV_post_sub_buffer */
#ifndef EGL_NV_quadruple_buffer
#define EGL_NV_quadruple_buffer 1
#define EGL_QUADRUPLE_BUFFER_NV 0x3231
#endif /* EGL_NV_quadruple_buffer */
#ifndef EGL_NV_robustness_video_memory_purge
#define EGL_NV_robustness_video_memory_purge 1
#define EGL_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x334C
#endif /* EGL_NV_robustness_video_memory_purge */
#ifndef EGL_NV_stream_consumer_eglimage
#define EGL_NV_stream_consumer_eglimage 1
#define EGL_STREAM_CONSUMER_IMAGE_NV 0x3373
#define EGL_STREAM_IMAGE_ADD_NV 0x3374
#define EGL_STREAM_IMAGE_REMOVE_NV 0x3375
#define EGL_STREAM_IMAGE_AVAILABLE_NV 0x3376
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMIMAGECONSUMERCONNECTNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLint num_modifiers, EGLuint64KHR *modifiers, EGLAttrib *attrib_list);
typedef EGLint (EGLAPIENTRYP PFNEGLQUERYSTREAMCONSUMEREVENTNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLTime timeout, EGLenum *event, EGLAttrib *aux);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMACQUIREIMAGENVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLImage *pImage, EGLSync sync);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMRELEASEIMAGENVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLImage image, EGLSync sync);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglStreamImageConsumerConnectNV (EGLDisplay dpy, EGLStreamKHR stream, EGLint num_modifiers, EGLuint64KHR *modifiers, EGLAttrib *attrib_list);
EGLAPI EGLint EGLAPIENTRY eglQueryStreamConsumerEventNV (EGLDisplay dpy, EGLStreamKHR stream, EGLTime timeout, EGLenum *event, EGLAttrib *aux);
EGLAPI EGLBoolean EGLAPIENTRY eglStreamAcquireImageNV (EGLDisplay dpy, EGLStreamKHR stream, EGLImage *pImage, EGLSync sync);
EGLAPI EGLBoolean EGLAPIENTRY eglStreamReleaseImageNV (EGLDisplay dpy, EGLStreamKHR stream, EGLImage image, EGLSync sync);
#endif
#endif /* EGL_NV_stream_consumer_eglimage */
#ifndef EGL_NV_stream_consumer_gltexture_yuv
#define EGL_NV_stream_consumer_gltexture_yuv 1
#define EGL_YUV_PLANE0_TEXTURE_UNIT_NV 0x332C
#define EGL_YUV_PLANE1_TEXTURE_UNIT_NV 0x332D
#define EGL_YUV_PLANE2_TEXTURE_UNIT_NV 0x332E
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLAttrib *attrib_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALATTRIBSNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalAttribsNV (EGLDisplay dpy, EGLStreamKHR stream, EGLAttrib *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalAttribsNV (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
#endif
#endif /* EGL_NV_stream_consumer_gltexture_yuv */
@@ -1085,6 +1229,12 @@ EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalAttribsNV (EGLDi
#define EGL_STREAM_CROSS_SYSTEM_NV 0x334F
#endif /* EGL_NV_stream_cross_system */
#ifndef EGL_NV_stream_dma
#define EGL_NV_stream_dma 1
#define EGL_STREAM_DMA_NV 0x3371
#define EGL_STREAM_DMA_SERVER_NV 0x3372
#endif /* EGL_NV_stream_dma */
#ifndef EGL_NV_stream_fifo_next
#define EGL_NV_stream_fifo_next 1
#define EGL_PENDING_FRAME_NV 0x3329
@@ -1096,6 +1246,14 @@ EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalAttribsNV (EGLDi
#define EGL_STREAM_FIFO_SYNCHRONOUS_NV 0x3336
#endif /* EGL_NV_stream_fifo_synchronous */
#ifndef EGL_NV_stream_flush
#define EGL_NV_stream_flush 1
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMFLUSHNVPROC) (EGLDisplay dpy, EGLStreamKHR stream);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglStreamFlushNV (EGLDisplay dpy, EGLStreamKHR stream);
#endif
#endif /* EGL_NV_stream_flush */
#ifndef EGL_NV_stream_frame_limits
#define EGL_NV_stream_frame_limits 1
#define EGL_PRODUCER_MAX_FRAME_HINT_NV 0x3337
@@ -1128,6 +1286,21 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamMetadataNV (EGLDisplay dpy, EGLStrea
#endif
#endif /* EGL_NV_stream_metadata */
#ifndef EGL_NV_stream_origin
#define EGL_NV_stream_origin 1
#define EGL_STREAM_FRAME_ORIGIN_X_NV 0x3366
#define EGL_STREAM_FRAME_ORIGIN_Y_NV 0x3367
#define EGL_STREAM_FRAME_MAJOR_AXIS_NV 0x3368
#define EGL_CONSUMER_AUTO_ORIENTATION_NV 0x3369
#define EGL_PRODUCER_AUTO_ORIENTATION_NV 0x336A
#define EGL_LEFT_NV 0x336B
#define EGL_RIGHT_NV 0x336C
#define EGL_TOP_NV 0x336D
#define EGL_BOTTOM_NV 0x336E
#define EGL_X_AXIS_NV 0x336F
#define EGL_Y_AXIS_NV 0x3370
#endif /* EGL_NV_stream_origin */
#ifndef EGL_NV_stream_remote
#define EGL_NV_stream_remote 1
#define EGL_STREAM_STATE_INITIALIZING_NV 0x3240
@@ -1224,6 +1397,11 @@ EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV (void);
#endif /* KHRONOS_SUPPORT_INT64 */
#endif /* EGL_NV_system_time */
#ifndef EGL_NV_triple_buffer
#define EGL_NV_triple_buffer 1
#define EGL_TRIPLE_BUFFER_NV 0x3230
#endif /* EGL_NV_triple_buffer */
#ifndef EGL_TIZEN_image_native_buffer
#define EGL_TIZEN_image_native_buffer 1
#define EGL_NATIVE_BUFFER_TIZEN 0x32A0
@@ -1234,6 +1412,40 @@ EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV (void);
#define EGL_NATIVE_SURFACE_TIZEN 0x32A1
#endif /* EGL_TIZEN_image_native_surface */
#ifndef EGL_WL_bind_wayland_display
#define EGL_WL_bind_wayland_display 1
#define PFNEGLBINDWAYLANDDISPLAYWL PFNEGLBINDWAYLANDDISPLAYWLPROC
#define PFNEGLUNBINDWAYLANDDISPLAYWL PFNEGLUNBINDWAYLANDDISPLAYWLPROC
#define PFNEGLQUERYWAYLANDBUFFERWL PFNEGLQUERYWAYLANDBUFFERWLPROC
struct wl_display;
struct wl_resource;
#define EGL_WAYLAND_BUFFER_WL 0x31D5
#define EGL_WAYLAND_PLANE_WL 0x31D6
#define EGL_TEXTURE_Y_U_V_WL 0x31D7
#define EGL_TEXTURE_Y_UV_WL 0x31D8
#define EGL_TEXTURE_Y_XUXV_WL 0x31D9
#define EGL_TEXTURE_EXTERNAL_WL 0x31DA
#define EGL_WAYLAND_Y_INVERTED_WL 0x31DB
typedef EGLBoolean (EGLAPIENTRYP PFNEGLBINDWAYLANDDISPLAYWLPROC) (EGLDisplay dpy, struct wl_display *display);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNBINDWAYLANDDISPLAYWLPROC) (EGLDisplay dpy, struct wl_display *display);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYWAYLANDBUFFERWLPROC) (EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglBindWaylandDisplayWL (EGLDisplay dpy, struct wl_display *display);
EGLAPI EGLBoolean EGLAPIENTRY eglUnbindWaylandDisplayWL (EGLDisplay dpy, struct wl_display *display);
EGLAPI EGLBoolean EGLAPIENTRY eglQueryWaylandBufferWL (EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value);
#endif
#endif /* EGL_WL_bind_wayland_display */
#ifndef EGL_WL_create_wayland_buffer_from_image
#define EGL_WL_create_wayland_buffer_from_image 1
#define PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWL PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWLPROC
struct wl_buffer;
typedef struct wl_buffer *(EGLAPIENTRYP PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWLPROC) (EGLDisplay dpy, EGLImageKHR image);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI struct wl_buffer *EGLAPIENTRY eglCreateWaylandBufferFromImageWL (EGLDisplay dpy, EGLImageKHR image);
#endif
#endif /* EGL_WL_create_wayland_buffer_from_image */
#ifdef __cplusplus
}
#endif

View File

@@ -2,36 +2,17 @@
#define __eglplatform_h_
/*
** Copyright (c) 2007-2016 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE 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
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
** Copyright 2007-2020 The Khronos Group Inc.
** SPDX-License-Identifier: Apache-2.0
*/
/* Platform-specific types and definitions for egl.h
* $Revision: 30994 $ on $Date: 2015-04-30 13:36:48 -0700 (Thu, 30 Apr 2015) $
*
* Adopters may modify khrplatform.h and this file to suit their platform.
* You are encouraged to submit all modifications to the Khronos group so that
* they can be included in future versions of this file. Please submit changes
* by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla)
* by filing a bug against product "EGL" component "Registry".
* by filing an issue or pull request on the public Khronos EGL Registry, at
* https://www.github.com/KhronosGroup/EGL-Registry/
*/
#include <KHR/khrplatform.h>
@@ -67,7 +48,13 @@
* implementations.
*/
#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
#if defined(EGL_NO_PLATFORM_SPECIFIC_TYPES)
typedef void *EGLNativeDisplayType;
typedef void *EGLNativePixmapType;
typedef void *EGLNativeWindowType;
#elif defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif
@@ -77,22 +64,46 @@ typedef HDC EGLNativeDisplayType;
typedef HBITMAP EGLNativePixmapType;
typedef HWND EGLNativeWindowType;
#elif defined(__APPLE__) || defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */
#elif defined(__EMSCRIPTEN__)
typedef int EGLNativeDisplayType;
typedef int EGLNativePixmapType;
typedef int EGLNativeWindowType;
#elif defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */
typedef int EGLNativeDisplayType;
typedef void *EGLNativeWindowType;
typedef void *EGLNativePixmapType;
typedef void *EGLNativeWindowType;
#elif defined(WL_EGL_PLATFORM)
typedef struct wl_display *EGLNativeDisplayType;
typedef struct wl_egl_pixmap *EGLNativePixmapType;
typedef struct wl_egl_window *EGLNativeWindowType;
#elif defined(__GBM__)
typedef struct gbm_device *EGLNativeDisplayType;
typedef struct gbm_bo *EGLNativePixmapType;
typedef void *EGLNativeWindowType;
#elif defined(__ANDROID__) || defined(ANDROID)
struct ANativeWindow;
struct egl_native_pixmap_t;
typedef struct ANativeWindow* EGLNativeWindowType;
typedef struct egl_native_pixmap_t* EGLNativePixmapType;
typedef void* EGLNativeDisplayType;
typedef struct egl_native_pixmap_t* EGLNativePixmapType;
typedef struct ANativeWindow* EGLNativeWindowType;
#elif defined(__unix__)
#elif defined(USE_OZONE)
typedef intptr_t EGLNativeDisplayType;
typedef intptr_t EGLNativePixmapType;
typedef intptr_t EGLNativeWindowType;
#elif defined(USE_X11)
/* X11 (tentative) */
#include <X11/Xlib.h>
@@ -102,6 +113,32 @@ typedef Display *EGLNativeDisplayType;
typedef Pixmap EGLNativePixmapType;
typedef Window EGLNativeWindowType;
#elif defined(__unix__)
typedef void *EGLNativeDisplayType;
typedef khronos_uintptr_t EGLNativePixmapType;
typedef khronos_uintptr_t EGLNativeWindowType;
#elif defined(__APPLE__)
typedef int EGLNativeDisplayType;
typedef void *EGLNativePixmapType;
typedef void *EGLNativeWindowType;
#elif defined(__HAIKU__)
#include <kernel/image.h>
typedef void *EGLNativeDisplayType;
typedef khronos_uintptr_t EGLNativePixmapType;
typedef khronos_uintptr_t EGLNativeWindowType;
#elif defined(__Fuchsia__)
typedef void *EGLNativeDisplayType;
typedef khronos_uintptr_t EGLNativePixmapType;
typedef khronos_uintptr_t EGLNativeWindowType;
#else
#error "Platform not recognized"
#endif

View File

@@ -2,7 +2,7 @@
#define __khrplatform_h_
/*
** Copyright (c) 2008-2009 The Khronos Group Inc.
** Copyright (c) 2008-2018 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
@@ -26,18 +26,16 @@
/* Khronos platform-specific types and definitions.
*
* $Revision: 32517 $ on $Date: 2016-03-11 02:41:19 -0800 (Fri, 11 Mar 2016) $
* The master copy of khrplatform.h is maintained in the Khronos EGL
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
* The last semantic modification to khrplatform.h was at commit ID:
* 67a3e0864c2d75ea5287b9f3d2eb74a745936692
*
* Adopters may modify this file to suit their platform. Adopters are
* encouraged to submit platform specific modifications to the Khronos
* group so that they can be included in future versions of this file.
* Please submit changes by sending them to the public Khronos Bugzilla
* (http://khronos.org/bugzilla) by filing a bug against product
* "Khronos (general)" component "Registry".
*
* A predefined template which fills in some of the bug fields can be
* reached using http://tinyurl.com/khrplatform-h-bugreport, but you
* must create a Bugzilla login first.
* Please submit changes by filing pull requests or issues on
* the EGL Registry repository linked above.
*
*
* See the Implementer's Guidelines for information about where this file
@@ -92,12 +90,20 @@
* int arg2) KHRONOS_APIATTRIBUTES;
*/
#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC)
# define KHRONOS_STATIC 1
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APICALL
*-------------------------------------------------------------------------
* This precedes the return type of the function in the function prototype.
*/
#if defined(_WIN32) && !defined(__SCITECH_SNAP__)
#if defined(KHRONOS_STATIC)
/* If the preprocessor constant KHRONOS_STATIC is defined, make the
* header compatible with static linking. */
# define KHRONOS_APICALL
#elif defined(_WIN32)
# define KHRONOS_APICALL __declspec(dllimport)
#elif defined (__SYMBIAN32__)
# define KHRONOS_APICALL IMPORT_C

View File

@@ -30,6 +30,8 @@
#include "../../events/SDL_mouse_c.h"
#include "../../events/default_cursor.h"
#include "../SDL_pixels_c.h"
static SDL_Cursor *KMSDRM_CreateDefaultCursor(void);
static SDL_Cursor *KMSDRM_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y);
static int KMSDRM_ShowCursor(SDL_Cursor * cursor);
@@ -59,30 +61,6 @@ KMSDRM_CreateDefaultCursor(void)
return SDL_CreateCursor(default_cdata, default_cmask, DEFAULT_CWIDTH, DEFAULT_CHEIGHT, DEFAULT_CHOTX, DEFAULT_CHOTY);
}
/* Converts a pixel from straight-alpha [AA, RR, GG, BB], which the SDL cursor surface has,
to premultiplied-alpha [AA. AA*RR, AA*GG, AA*BB].
These multiplications have to be done with floats instead of uint32_t's,
and the resulting values have to be converted to be relative to the 0-255 interval,
where 255 is 1.00 and anything between 0 and 255 is 0.xx. */
void legacy_alpha_premultiply_ARGB8888 (uint32_t *pixel) {
uint32_t A, R, G, B;
/* Component bytes extraction. */
A = (*pixel >> (3 << 3)) & 0xFF;
R = (*pixel >> (2 << 3)) & 0xFF;
G = (*pixel >> (1 << 3)) & 0xFF;
B = (*pixel >> (0 << 3)) & 0xFF;
/* Alpha pre-multiplication of each component. */
R = (float)A * ((float)R /255);
G = (float)A * ((float)G /255);
B = (float)A * ((float)B /255);
/* ARGB8888 pixel recomposition. */
(*pixel) = (((uint32_t)A << 24) | ((uint32_t)R << 16) | ((uint32_t)G << 8)) | ((uint32_t)B << 0);
}
/* Given a display's driverdata, destroy the cursor BO for it.
To be called from KMSDRM_DestroyWindow(), as that's where we
destroy the driverdata for the window's display. */
@@ -141,7 +119,7 @@ KMSDRM_CreateCursorBO (SDL_VideoDisplay *display) {
}
/* Remove a cursor buffer from a display's DRM cursor BO. */
int
static int
KMSDRM_RemoveCursorFromBO(SDL_VideoDisplay *display)
{
int ret = 0;
@@ -160,7 +138,7 @@ KMSDRM_RemoveCursorFromBO(SDL_VideoDisplay *display)
}
/* Dump a cursor buffer to a display's DRM cursor BO. */
int
static int
KMSDRM_DumpCursorToBO(SDL_VideoDisplay *display, SDL_Cursor *cursor)
{
SDL_DisplayData *dispdata = (SDL_DisplayData *) display->driverdata;
@@ -171,10 +149,10 @@ KMSDRM_DumpCursorToBO(SDL_VideoDisplay *display, SDL_Cursor *cursor)
uint32_t bo_handle;
size_t bo_stride;
size_t bufsize;
uint32_t *ready_buffer = NULL;
uint32_t pixel;
uint8_t *ready_buffer = NULL;
uint8_t *src_row;
int i,j;
int i;
int ret;
if (!curdata || !dispdata->cursor_bo) {
@@ -186,21 +164,17 @@ KMSDRM_DumpCursorToBO(SDL_VideoDisplay *display, SDL_Cursor *cursor)
bo_stride = KMSDRM_gbm_bo_get_stride(dispdata->cursor_bo);
bufsize = bo_stride * dispdata->cursor_h;
ready_buffer = (uint32_t*)SDL_calloc(1, bufsize);
ready_buffer = (uint8_t*)SDL_calloc(1, bufsize);
if (!ready_buffer) {
ret = SDL_OutOfMemory();
goto cleanup;
}
/* Copy from the cursor buffer to a buffer that we can dump to the GBM BO,
pre-multiplying by alpha each pixel as we go. */
/* Copy from the cursor buffer to a buffer that we can dump to the GBM BO. */
for (i = 0; i < curdata->h; i++) {
for (j = 0; j < curdata->w; j++) {
pixel = ((uint32_t*)curdata->buffer)[i * curdata->w + j];
legacy_alpha_premultiply_ARGB8888 (&pixel);
SDL_memcpy(ready_buffer + (i * dispdata->cursor_w) + j, &pixel, 4);
}
src_row = &((uint8_t*)curdata->buffer)[i * curdata->w * 4];
SDL_memcpy(ready_buffer + (i * bo_stride), src_row, 4 * curdata->w);
}
/* Dump the cursor buffer to our GBM BO. */
@@ -271,13 +245,6 @@ KMSDRM_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
curdata = NULL;
ret = NULL;
/* All code below assumes ARGB8888 format for the cursor surface,
like other backends do. Also, the GBM BO pixels have to be
alpha-premultiplied, but the SDL surface we receive has
straight-alpha pixels, so we always have to convert. */
SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888);
SDL_assert(surface->pitch == surface->w * 4);
cursor = (SDL_Cursor *) SDL_calloc(1, sizeof(*cursor));
if (!cursor) {
SDL_OutOfMemory();
@@ -298,8 +265,8 @@ KMSDRM_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
/* Configure the cursor buffer info.
This buffer has the original size of the cursor surface we are given. */
curdata->buffer_pitch = surface->pitch;
curdata->buffer_size = surface->pitch * surface->h;
curdata->buffer_pitch = surface->w;
curdata->buffer_size = surface->w * surface->h * 4;
curdata->buffer = (uint32_t*)SDL_malloc(curdata->buffer_size);
if (!curdata->buffer) {
@@ -307,19 +274,13 @@ KMSDRM_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
goto cleanup;
}
if (SDL_MUSTLOCK(surface)) {
if (SDL_LockSurface(surface) < 0) {
/* Could not lock surface */
goto cleanup;
}
}
/* Copy the surface pixels to the cursor buffer, for future use in ShowCursor() */
SDL_memcpy(curdata->buffer, surface->pixels, curdata->buffer_size);
if (SDL_MUSTLOCK(surface)) {
SDL_UnlockSurface(surface);
}
/* All code below assumes ARGB8888 format for the cursor surface,
like other backends do. Also, the GBM BO pixels have to be
alpha-premultiplied, but the SDL surface we receive has
straight-alpha pixels, so we always have to convert. */
SDL_PremultiplyAlpha(surface->w, surface->h,
surface->format->format, surface->pixels, surface->pitch,
SDL_PIXELFORMAT_ARGB8888, curdata->buffer, surface->w * 4);
cursor->driverdata = curdata;
@@ -442,8 +403,6 @@ KMSDRM_WarpMouseGlobal(int x, int y)
} else {
return SDL_SetError("No mouse or current cursor.");
}
return 0;
}
void

View File

@@ -48,7 +48,7 @@ extern void KMSDRM_QuitMouse(_THIS);
extern void KMSDRM_CreateCursorBO(SDL_VideoDisplay *display);
extern void KMSDRM_DestroyCursorBO(_THIS, SDL_VideoDisplay *display);
extern void KMSDRM_InitCursor();
extern void KMSDRM_InitCursor(void);
#endif /* SDL_KMSDRM_mouse_h_ */

View File

@@ -60,9 +60,9 @@ SDL_KMSDRM_SYM(int,drmModeSetCrtc,(int fd, uint32_t crtcId, uint32_t bufferId,
uint32_t x, uint32_t y, uint32_t *connectors, int count,
drmModeModeInfoPtr mode))
SDL_KMSDRM_SYM(int,drmModeCrtcGetGamma,(int fd, uint32_t crtc_id, uint32_t size,
uint16_t *red, uint16_t *green, uint16_t *blue))
uint16_t *red, uint16_t *green, uint16_t *blue))
SDL_KMSDRM_SYM(int,drmModeCrtcSetGamma,(int fd, uint32_t crtc_id, uint32_t size,
uint16_t *red, uint16_t *green, uint16_t *blue))
uint16_t *red, uint16_t *green, uint16_t *blue))
SDL_KMSDRM_SYM(int,drmModeSetCursor,(int fd, uint32_t crtcId, uint32_t bo_handle,
uint32_t width, uint32_t height))
SDL_KMSDRM_SYM(int,drmModeSetCursor2,(int fd, uint32_t crtcId, uint32_t bo_handle,

View File

@@ -141,14 +141,12 @@ static int get_dricount(void)
if (!(stat(KMSDRM_DRI_PATH, &sb) == 0
&& S_ISDIR(sb.st_mode))) {
printf("The path %s cannot be opened or is not available\n",
KMSDRM_DRI_PATH);
/*printf("The path %s cannot be opened or is not available\n", KMSDRM_DRI_PATH);*/
return 0;
}
if (access(KMSDRM_DRI_PATH, F_OK) == -1) {
printf("The path %s cannot be opened\n",
KMSDRM_DRI_PATH);
/*printf("The path %s cannot be opened\n", KMSDRM_DRI_PATH);*/
return 0;
}
@@ -473,7 +471,7 @@ KMSDRM_WaitPageflip(_THIS, SDL_WindowData *windata) {
available on the DRM connector of the display.
We use the SDL mode list (which we filled in KMSDRM_GetDisplayModes)
because it's ordered, while the list on the connector is mostly random.*/
drmModeModeInfo*
static drmModeModeInfo*
KMSDRM_GetClosestDisplayMode(SDL_VideoDisplay * display,
uint32_t width, uint32_t height, uint32_t refresh_rate){
@@ -504,7 +502,8 @@ uint32_t width, uint32_t height, uint32_t refresh_rate){
/*****************************************************************************/
/* Deinitializes the driverdata of the SDL Displays in the SDL display list. */
void KMSDRM_DeinitDisplays (_THIS) {
static void
KMSDRM_DeinitDisplays (_THIS) {
SDL_DisplayData *dispdata;
int num_displays, i;
@@ -533,7 +532,8 @@ void KMSDRM_DeinitDisplays (_THIS) {
/* Gets a DRM connector, builds an SDL_Display with it, and adds it to the
list of SDL Displays in _this->displays[] */
void KMSDRM_AddDisplay (_THIS, drmModeConnector *connector, drmModeRes *resources) {
static void
KMSDRM_AddDisplay (_THIS, drmModeConnector *connector, drmModeRes *resources) {
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
SDL_DisplayData *dispdata = NULL;
@@ -721,7 +721,8 @@ cleanup:
closed when we get to the end of this function.
This is to be called early, in VideoInit(), because it gets us
the videomode information, which SDL needs immediately after VideoInit(). */
int KMSDRM_InitDisplays (_THIS) {
static int
KMSDRM_InitDisplays (_THIS) {
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
drmModeRes *resources = NULL;
@@ -815,7 +816,7 @@ cleanup:
These things are incompatible with Vulkan, which accesses the same resources
internally so they must be free when trying to build a Vulkan surface.
*/
int
static int
KMSDRM_GBMInit (_THIS, SDL_DisplayData *dispdata)
{
SDL_VideoData *viddata = (SDL_VideoData *)_this->driverdata;
@@ -839,7 +840,7 @@ KMSDRM_GBMInit (_THIS, SDL_DisplayData *dispdata)
}
/* Deinit the Vulkan-incompatible KMSDRM stuff. */
void
static void
KMSDRM_GBMDeinit (_THIS, SDL_DisplayData *dispdata)
{
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
@@ -860,7 +861,7 @@ KMSDRM_GBMDeinit (_THIS, SDL_DisplayData *dispdata)
viddata->gbm_init = SDL_FALSE;
}
void
static void
KMSDRM_DestroySurfaces(_THIS, SDL_Window *window)
{
SDL_VideoData *viddata = ((SDL_VideoData *)_this->driverdata);
@@ -871,7 +872,7 @@ KMSDRM_DestroySurfaces(_THIS, SDL_Window *window)
/**********************************************/
/* Wait for last issued pageflip to complete. */
/**********************************************/
KMSDRM_WaitPageflip(_this, windata);
/*KMSDRM_WaitPageflip(_this, windata);*/
/***********************************************************************/
/* Restore the original CRTC configuration: configue the crtc with the */

View File

@@ -182,34 +182,40 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
VkInstance instance,
VkSurfaceKHR *surface)
{
VkPhysicalDevice gpu;
VkPhysicalDevice gpu = NULL;
uint32_t gpu_count;
uint32_t display_count;
uint32_t mode_count;
uint32_t plane_count;
uint32_t plane = UINT32_MAX;
VkPhysicalDevice *physical_devices = NULL;
VkPhysicalDeviceProperties *device_props = NULL;
VkDisplayPropertiesKHR *displays_props = NULL;
VkDisplayModePropertiesKHR *modes_props = NULL;
VkDisplayPlanePropertiesKHR *planes_props = NULL;
VkDisplayPropertiesKHR *display_props = NULL;
VkDisplayModePropertiesKHR *mode_props = NULL;
VkDisplayPlanePropertiesKHR *plane_props = NULL;
VkDisplayPlaneCapabilitiesKHR plane_caps;
VkDisplayModeCreateInfoKHR display_mode_create_info;
VkDisplaySurfaceCreateInfoKHR display_plane_surface_create_info;
VkExtent2D image_size;
VkDisplayKHR display;
VkDisplayModeKHR display_mode = (VkDisplayModeKHR)0;
VkDisplayModePropertiesKHR display_mode_props = {0};
VkDisplayModeParametersKHR new_mode_parameters = { {0, 0}, 0};
/* Prefer a plane that supports per-pixel alpha. */
VkDisplayPlaneAlphaFlagBitsKHR alpha_mode = VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR;
VkResult result;
SDL_bool ret = SDL_FALSE;
SDL_bool valid_gpu = SDL_FALSE;
SDL_bool mode_found = SDL_FALSE;
SDL_bool plane_supports_display = SDL_FALSE;
/* Get the display index from the display being used by the window. */
int display_index = SDL_atoi(SDL_GetDisplayForWindow(window)->name);
int i;
int i, j;
/* Get the function pointers for the functions we will use. */
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
@@ -239,14 +245,13 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
(PFN_vkGetPhysicalDeviceDisplayPlanePropertiesKHR)vkGetInstanceProcAddr(
instance, "vkGetPhysicalDeviceDisplayPlanePropertiesKHR");
/*PFN_vkGetDisplayPlaneSupportedDisplaysKHR vkGetDisplayPlaneSupportedDisplaysKHR =
PFN_vkGetDisplayPlaneSupportedDisplaysKHR vkGetDisplayPlaneSupportedDisplaysKHR =
(PFN_vkGetDisplayPlaneSupportedDisplaysKHR)vkGetInstanceProcAddr(
instance, "vkGetDisplayPlaneSupportedDisplaysKHR");
PFN_vkGetDisplayPlaneCapabilitiesKHR vkGetDisplayPlaneCapabilitiesKHR =
(PFN_vkGetDisplayPlaneCapabilitiesKHR)vkGetInstanceProcAddr(
instance, "vkGetDisplayPlaneCapabilitiesKHR");
*/
PFN_vkCreateDisplayModeKHR vkCreateDisplayModeKHR =
(PFN_vkCreateDisplayModeKHR)vkGetInstanceProcAddr(
@@ -329,38 +334,29 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
}
/* Get the props of the displays of the physical device. */
displays_props = (VkDisplayPropertiesKHR *) SDL_malloc(display_count * sizeof(*displays_props));
display_props = (VkDisplayPropertiesKHR *) SDL_malloc(display_count * sizeof(*display_props));
vkGetPhysicalDeviceDisplayPropertiesKHR(gpu,
&display_count,
displays_props);
display_props);
/* Get the videomode count for the first display. */
/* Get the chosen display based on the display index. */
display = display_props[display_index].display;
/* Get the list of the display videomodes. */
vkGetDisplayModePropertiesKHR(gpu,
displays_props[display_index].display,
display,
&mode_count, NULL);
if (mode_count == 0) {
SDL_SetError("Vulkan can't find any video modes for display %i (%s)\n", 0,
displays_props[display_index].displayName);
display_props[display_index].displayName);
goto clean;
}
/* Get the props of the videomodes for the display. */
modes_props = (VkDisplayModePropertiesKHR *) SDL_malloc(mode_count * sizeof(*modes_props));
mode_props = (VkDisplayModePropertiesKHR *) SDL_malloc(mode_count * sizeof(*mode_props));
vkGetDisplayModePropertiesKHR(gpu,
displays_props[display_index].display,
&mode_count, modes_props);
/* Get the planes count of the physical device. */
vkGetPhysicalDeviceDisplayPlanePropertiesKHR(gpu, &plane_count, NULL);
if (plane_count == 0) {
SDL_SetError("Vulkan can't find any planes.");
goto clean;
}
/* Get the props of the planes for the physical device. */
planes_props = SDL_malloc(sizeof(VkDisplayPlanePropertiesKHR) * plane_count);
vkGetPhysicalDeviceDisplayPlanePropertiesKHR(gpu, &plane_count, planes_props);
display,
&mode_count, mode_props);
/* Get a video mode equal to the window size among the predefined ones,
if possible.
@@ -369,10 +365,10 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
scanout a region bigger than the window (we would be reading past the
buffer, and Vulkan would give us a confusing VK_ERROR_SURFACE_LOST_KHR). */
for (i = 0; i < mode_count; i++) {
if (modes_props[i].parameters.visibleRegion.width == window->w &&
modes_props[i].parameters.visibleRegion.height == window->h)
if (mode_props[i].parameters.visibleRegion.width == window->w &&
mode_props[i].parameters.visibleRegion.height == window->h)
{
display_mode_props = modes_props[i];
display_mode_props = mode_props[i];
mode_found = SDL_TRUE;
break;
}
@@ -399,7 +395,7 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
display_mode_create_info.sType = VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR;
display_mode_create_info.parameters = new_mode_parameters;
result = vkCreateDisplayModeKHR(gpu,
displays_props[display_index].display,
display,
&display_mode_create_info,
NULL, &display_mode);
if (result != VK_SUCCESS) {
@@ -414,6 +410,78 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
goto clean;
}
/* Get the list of the physical device planes. */
vkGetPhysicalDeviceDisplayPlanePropertiesKHR(gpu, &plane_count, NULL);
if (plane_count == 0) {
SDL_SetError("Vulkan can't find any planes.");
goto clean;
}
plane_props = SDL_malloc(sizeof(VkDisplayPlanePropertiesKHR) * plane_count);
vkGetPhysicalDeviceDisplayPlanePropertiesKHR(gpu, &plane_count, plane_props);
/* Iterate on the list of planes of the physical device
to find a plane that matches these criteria:
-It must be compatible with the chosen display + mode.
-It isn't currently bound to another display.
-It supports per-pixel alpha, if possible. */
for (i = 0; i < plane_count; i++) {
uint32_t supported_displays_count = 0;
VkDisplayKHR* supported_displays;
/* See if the plane is compatible with the current display. */
vkGetDisplayPlaneSupportedDisplaysKHR(gpu, i, &supported_displays_count, NULL);
if (supported_displays_count == 0) {
/* This plane doesn't support any displays. Continue to the next plane. */
continue;
}
/* Get the list of displays supported by this plane. */
supported_displays = (VkDisplayKHR*)SDL_malloc(sizeof(VkDisplayKHR) * supported_displays_count);
vkGetDisplayPlaneSupportedDisplaysKHR(gpu, i,
&supported_displays_count, supported_displays);
/* The plane must be bound to the chosen display, or not in use.
If none of these is true, iterate to another plane. */
if (!((plane_props[i].currentDisplay == display) ||
(plane_props[i].currentDisplay == VK_NULL_HANDLE)))
continue;
/* Iterate the list of displays supported by this plane
in order to find out if the chosen display is among them. */
plane_supports_display = SDL_FALSE;
for (j = 0; j < supported_displays_count; j++) {
if (supported_displays[j] == display) {
plane_supports_display = SDL_TRUE;
break;
}
}
/* Free the list of displays supported by this plane. */
if (supported_displays) {
SDL_free(supported_displays);
}
/* If the display is not supported by this plane, iterate to the next plane. */
if (!plane_supports_display) {
continue;
}
/* Want a plane that supports the alpha mode we have chosen. */
vkGetDisplayPlaneCapabilitiesKHR(gpu, display_mode, i, &plane_caps);
if (plane_caps.supportedAlpha == alpha_mode) {
/* Yep, this plane is alright. */
plane = i;
break;
}
}
/* If we couldn't find an appropiate plane, error out. */
if (plane == UINT32_MAX) {
SDL_SetError("Vulkan couldn't find an appropiate plane.");
goto clean;
}
/********************************************/
/* Let's finally create the Vulkan surface! */
/********************************************/
@@ -424,11 +492,10 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
SDL_zero(display_plane_surface_create_info);
display_plane_surface_create_info.sType = VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR;
display_plane_surface_create_info.displayMode = display_mode;
/* For now, simply use the first plane. */
display_plane_surface_create_info.planeIndex = 0;
display_plane_surface_create_info.planeIndex = plane;
display_plane_surface_create_info.imageExtent = image_size;
display_plane_surface_create_info.transform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
display_plane_surface_create_info.alphaMode = VK_DISPLAY_PLANE_ALPHA_OPAQUE_BIT_KHR;
display_plane_surface_create_info.alphaMode = alpha_mode;
result = vkCreateDisplayPlaneSurfaceKHR(instance,
&display_plane_surface_create_info,
NULL,
@@ -445,14 +512,14 @@ SDL_bool KMSDRM_Vulkan_CreateSurface(_THIS,
clean:
if (physical_devices)
SDL_free (physical_devices);
if (displays_props)
SDL_free (displays_props);
if (display_props)
SDL_free (display_props);
if (device_props)
SDL_free (device_props);
if (planes_props)
SDL_free (planes_props);
if (modes_props)
SDL_free (modes_props);
if (plane_props)
SDL_free (plane_props);
if (mode_props)
SDL_free (mode_props);
return ret;
}

View File

@@ -27,7 +27,7 @@
#include "SDL_video.h"
#include "SDL_naclvideo.h"
#if SDL_LOADSO_DLOPEN
#ifdef HAVE_DLOPEN
#include "dlfcn.h"
#endif
@@ -45,7 +45,7 @@ NACL_GLES_LoadLibrary(_THIS, const char *path)
void *
NACL_GLES_GetProcAddress(_THIS, const char *proc)
{
#if SDL_LOADSO_DLOPEN
#ifdef HAVE_DLOPEN
return dlsym( 0 /* RTLD_DEFAULT */, proc);
#else
return NULL;

View File

@@ -66,7 +66,13 @@ OFFSCREEN_GL_LoadLibrary(_THIS, const char* path)
return ret;
}
/* driver_loaded gets incremented by SDL_GL_LoadLibrary when we return,
but SDL_EGL_InitializeOffscreen checks that we're loaded before then,
so temporarily bump it since we know that LoadLibraryOnly succeeded. */
_this->gl_config.driver_loaded++;
ret = SDL_EGL_InitializeOffscreen(_this, 0);
_this->gl_config.driver_loaded--;
if (ret != 0) {
return ret;
}

View File

@@ -302,10 +302,10 @@ static BOOL voUpdate(PVODATA pVOData, HWND hwnd, SDL_Rect *pSDLRects,
debug_os2("Not enough stack size");
return FALSE;
}
memset(pbLineMask, 0, pVOData->ulHeight);
SDL_memset(pbLineMask, 0, pVOData->ulHeight);
for ( ; ((LONG)cSDLRects) > 0; cSDLRects--, pSDLRects++) {
memset(&pbLineMask[pSDLRects->y], 1, pSDLRects->h);
SDL_memset(&pbLineMask[pSDLRects->y], 1, pSDLRects->h);
}
ulRC = DiveBlitImageLines(pVOData->hDive, pVOData->ulDIVEBufNum,

View File

@@ -57,8 +57,8 @@ static VOID _wmInitDlg(HWND hwnd, MSGBOXDLGDATA *pDlgData)
HWND hwnd; /* Button window handle. */
ULONG ulCX; /* Button width in dialog coordinates. */
} aButtons[32];
RECTL rectlItem;
HAB hab = WinQueryAnchorBlock(hwnd);
RECTL rectlItem;
HAB hab = WinQueryAnchorBlock(hwnd);
/* --- Align the buttons to the right/bottom. --- */
@@ -66,10 +66,10 @@ static VOID _wmInitDlg(HWND hwnd, MSGBOXDLGDATA *pDlgData)
hEnum = WinBeginEnumWindows(hwnd);
while ((hWndNext = WinGetNextWindow(hEnum)) != NULLHANDLE) {
if (WinQueryClassName(hWndNext, sizeof(acBuf), acBuf) == 0)
if (WinQueryClassName(hWndNext, sizeof(acBuf), acBuf) == 0) {
continue;
if (strcmp(acBuf, "#3") == 0) { /* Class name of button. */
}
if (SDL_strcmp(acBuf, "#3") == 0) { /* Class name of button. */
if (cButtons < sizeof(aButtons) / sizeof(struct _BUTTON)) {
aButtons[cButtons].hwnd = hWndNext;
cButtons++;
@@ -92,7 +92,7 @@ static VOID _wmInitDlg(HWND hwnd, MSGBOXDLGDATA *pDlgData)
/* Convert text size to dialog coordinates. */
WinMapDlgPoints(hwnd, &aptText[TXTBOX_TOPRIGHT], 1, FALSE);
/* Add vertical and horizontal space for button's frame (dialog coord.). */
if (aptText[TXTBOX_TOPRIGHT].x < 30) {/* Minimal button width. */
if (aptText[TXTBOX_TOPRIGHT].x < 30) { /* Minimal button width. */
aptText[TXTBOX_TOPRIGHT].x = 30;
} else {
aptText[TXTBOX_TOPRIGHT].x += 4;
@@ -176,7 +176,7 @@ static VOID _wmInitDlg(HWND hwnd, MSGBOXDLGDATA *pDlgData)
SWP_MOVE | SWP_SIZE);
}
MRESULT EXPENTRY DynDlgProc(HWND hwnd, USHORT message, MPARAM mp1, MPARAM mp2)
static MRESULT EXPENTRY DynDlgProc(HWND hwnd, USHORT message, MPARAM mp1, MPARAM mp2)
{
switch (message) {
case WM_INITDLG:
@@ -206,9 +206,9 @@ static HWND _makeDlg(const SDL_MessageBoxData *messageboxdata)
ULONG cSDLBtnData = messageboxdata->numbuttons;
PSZ pszTitle = OS2_UTF8ToSys((PSZ) messageboxdata->title);
ULONG cbTitle = (pszTitle == NULL)? 0 : strlen(pszTitle);
PSZ pszText = OS2_UTF8ToSys((PSZ) messageboxdata->message);
ULONG cbText = (pszText == NULL)? 0 : strlen(pszText);
ULONG cbTitle = (pszTitle == NULL)? 1 : (SDL_strlen(pszTitle) + 1);
PSZ pszText = OS2_UTF8ToSys((PSZ) messageboxdata->message);
ULONG cbText = (pszText == NULL)? 1 : (SDL_strlen(pszText) + 1);
PDLGTEMPLATE pTemplate;
ULONG cbTemplate;
@@ -218,28 +218,34 @@ static HWND _makeDlg(const SDL_MessageBoxData *messageboxdata)
PSZ pszBtnText;
ULONG cbBtnText;
HWND hwnd;
const SDL_MessageBoxColor* pSDLColors = (messageboxdata->colorScheme == NULL)?
NULL : messageboxdata->colorScheme->colors;
const SDL_MessageBoxColor* pSDLColor;
MSGBOXDLGDATA stDlgData;
/* Build a dialog tamplate in memory */
/* Size of template (cbTemplate). */
/* Size of template */
cbTemplate = sizeof(DLGTEMPLATE) + ((2 + cSDLBtnData) * sizeof(DLGTITEM)) +
sizeof(ULONG) + /* First item data - frame control data. */
cbTitle + 1 + /* First item data - frame title + ZERO. */
cbText + 1 + /* Second item data - ststic text + ZERO.*/
cbTitle + /* First item data - frame title + ZERO. */
cbText + /* Second item data - ststic text + ZERO.*/
3; /* Third item data - system icon Id. */
/* Button items datas - text for buttons. */
for (ulIdx = 0; ulIdx < cSDLBtnData; ulIdx++) {
pszBtnText = (PSZ)pSDLBtnData[ulIdx].text;
cbTemplate += (pszBtnText == NULL)? 1 : (strlen(pszBtnText) + 1);
cbTemplate += (pszBtnText == NULL)? 1 : (SDL_strlen(pszBtnText) + 1);
}
/* Presentation parameter space. */
if (pSDLColors != NULL)
cbTemplate += 26 /* PP for frame. */ + 26 /* PP for static text. */ +
if (pSDLColors != NULL) {
cbTemplate += 26 /* PP for frame. */ +
26 /* PP for static text. */ +
(48 * cSDLBtnData); /* PP for buttons. */
}
/* Allocate memory for the dialog template. */
pTemplate = (PDLGTEMPLATE) SDL_malloc(cbTemplate);
@@ -268,11 +274,11 @@ static HWND _makeDlg(const SDL_MessageBoxData *messageboxdata)
pDlgItem->cchClassName = 0;
pDlgItem->offClassName = (USHORT)WC_FRAME;
/* Length of text. */
pDlgItem->cchText = cbTitle + 1; /* +1 - trailing ZERO. */
pDlgItem->cchText = cbTitle;
pDlgItem->offText = pcDlgData - (PCHAR)pTemplate; /* Offset to title text. */
/* Copy text for the title into the dialog template. */
if (pszTitle != NULL) {
strcpy(pcDlgData, pszTitle);
SDL_memcpy(pcDlgData, pszTitle, cbTitle);
} else {
*pcDlgData = '\0';
}
@@ -322,13 +328,13 @@ static HWND _makeDlg(const SDL_MessageBoxData *messageboxdata)
pDlgItem->cchClassName = 0;
pDlgItem->offClassName = (USHORT)WC_STATIC;
pDlgItem->cchText = cbText + 1;
pDlgItem->cchText = cbText;
pDlgItem->offText = pcDlgData - (PCHAR)pTemplate; /* Offset to the text. */
/* Copy message text into the dialog template. */
if (pszText != NULL) {
strcpy(pcDlgData, pszText);
SDL_memcpy(pcDlgData, pszText, cbText);
} else {
*pcDlgData = '\0';
*pcDlgData = '\0';
}
pcDlgData += pDlgItem->cchText;
@@ -339,7 +345,7 @@ static HWND _makeDlg(const SDL_MessageBoxData *messageboxdata)
pDlgItem->cx = 147;
pDlgItem->cy = 62; /* It will be used. */
pDlgItem->id = IDD_TEXT_MESSAGE; /* an ID value */
pDlgItem->id = IDD_TEXT_MESSAGE; /* an ID value */
if (pSDLColors == NULL)
pDlgItem->offPresParams = 0;
else {
@@ -401,12 +407,12 @@ static HWND _makeDlg(const SDL_MessageBoxData *messageboxdata)
pDlgItem->offClassName = (USHORT)WC_BUTTON;
pszBtnText = OS2_UTF8ToSys((PSZ)pSDLBtnData[ulIdx].text);
cbBtnText = (pszBtnText == NULL)? 0 : strlen(pszBtnText);
pDlgItem->cchText = cbBtnText + 1;
cbBtnText = (pszBtnText == NULL)? 1 : (SDL_strlen(pszBtnText) + 1);
pDlgItem->cchText = cbBtnText;
pDlgItem->offText = pcDlgData - (PCHAR)pTemplate; /* Offset to the text. */
/* Copy text for the button into the dialog template. */
if (pszBtnText != NULL) {
strcpy(pcDlgData, pszBtnText);
SDL_memcpy(pcDlgData, pszBtnText, cbBtnText);
} else {
*pcDlgData = '\0';
}
@@ -430,7 +436,7 @@ static HWND _makeDlg(const SDL_MessageBoxData *messageboxdata)
pDlgItem->id = IDD_PB_FIRST + ulIdx; /* an ID value */
if (pSDLColors == NULL)
pDlgItem->offPresParams = 0;
pDlgItem->offPresParams = 0;
else {
/* Presentation parameter for the button - dialog colors. */
pDlgItem->offPresParams = pcDlgData - (PCHAR)pTemplate;

View File

@@ -133,7 +133,7 @@ static BOOL _getSDLPixelFormatData(SDL_PixelFormat *pSDLPixelFormat,
default:
/* printf("Unknown color encoding: %.4s\n", fccColorEncoding);*/
memset(pSDLPixelFormat, 0, sizeof(SDL_PixelFormat));
SDL_memset(pSDLPixelFormat, 0, sizeof(SDL_PixelFormat));
return FALSE;
}
@@ -403,7 +403,7 @@ static MRESULT _wmDrop(WINDATA *pWinData, PDRAGINFO pDragInfo)
pDragItem->hstrSourceName != NULLHANDLE) {
/* Get file name from the item. */
DrgQueryStrName(pDragItem->hstrContainerName, sizeof(acFName), acFName);
pcFName = strchr(acFName, '\0');
pcFName = SDL_strchr(acFName, '\0');
DrgQueryStrName(pDragItem->hstrSourceName,
sizeof(acFName) - (pcFName - acFName), pcFName);
@@ -428,7 +428,7 @@ static MRESULT _wmDrop(WINDATA *pWinData, PDRAGINFO pDragInfo)
return (MRESULT)FALSE;
}
MRESULT EXPENTRY wndFrameProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
static MRESULT EXPENTRY wndFrameProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
HWND hwndClient = WinQueryWindow(hwnd, QW_BOTTOM);
WINDATA * pWinData = (WINDATA *)WinQueryWindowULong(hwndClient, 0);
@@ -535,7 +535,7 @@ MRESULT EXPENTRY wndFrameProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
return pWinData->fnWndFrameProc(hwnd, msg, mp1, mp2);
}
MRESULT EXPENTRY wndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
static MRESULT EXPENTRY wndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
WINDATA *pWinData = (WINDATA *)WinQueryWindowULong(hwnd, 0);
@@ -589,7 +589,7 @@ MRESULT EXPENTRY wndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
WinQueryPointerPos(HWND_DESKTOP, &pointl);
WinMapWindowPoints(HWND_DESKTOP, pWinData->hwnd, &pointl, 1);
SDL_SendMouseMotion(pWinData->window, 0, 0,
pointl.x, pWinData->window->h - pointl.y - 1);
pointl.x, pWinData->window->h - pointl.y - 1);
} else {
if (SDL_GetKeyboardFocus() == pWinData->window)
SDL_SetKeyboardFocus(NULL);
@@ -691,7 +691,7 @@ MRESULT EXPENTRY wndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
}
/* SDL routnes.
/* SDL routines.
* ------------
*/
@@ -1343,9 +1343,9 @@ static int OS2_SetClipboardText(_THIS, const char *text)
debug_os2("Enter");
if (pszText == NULL)
return -1;
cbText = SDL_strlen(pszText);
cbText = SDL_strlen(pszText) + 1;
ulRC = DosAllocSharedMem((PPVOID)&pszClipboard, 0, cbText + 1,
ulRC = DosAllocSharedMem((PPVOID)&pszClipboard, 0, cbText,
PAG_COMMIT | PAG_READ | PAG_WRITE |
OBJ_GIVEABLE | OBJ_GETTABLE | OBJ_TILE);
if (ulRC != NO_ERROR) {
@@ -1354,7 +1354,7 @@ static int OS2_SetClipboardText(_THIS, const char *text)
return -1;
}
strcpy(pszClipboard, pszText);
SDL_memcpy(pszClipboard, pszText, cbText);
SDL_free(pszText);
if (!WinOpenClipbrd(pVData->hab)) {
@@ -1444,7 +1444,7 @@ static int OS2_VideoInit(_THIS)
return SDL_SetError("Window class not successfully registered.");
}
if (stricmp(_this->name, OS2DRIVER_NAME_VMAN) == 0)
if (SDL_strcasecmp(_this->name, OS2DRIVER_NAME_VMAN) == 0)
pVData->pOutput = &voVMan;
else
pVData->pOutput = &voDive;

View File

@@ -78,7 +78,7 @@ static HMODULE hmodVMan = NULLHANDLE;
static FNVMIENTRY *pfnVMIEntry = NULL;
static ULONG ulVRAMAddress = 0;
VOID APIENTRY ExitVMan(VOID)
static VOID APIENTRY ExitVMan(VOID)
{
if (ulVRAMAddress != 0 && hmodVMan != NULLHANDLE) {
pfnVMIEntry(0, VMI_CMD_TERMPROC, NULL, NULL);

View File

@@ -612,7 +612,7 @@ PND_gl_createcontext(_THIS, SDL_Window * window)
#ifdef WIZ_GLES_LITE
if( !hNativeWnd ) {
hNativeWnd = (NativeWindowType)malloc(16*1024);
hNativeWnd = (NativeWindowType)SDL_malloc(16*1024);
if(!hNativeWnd)
printf( "Error: Wiz framebuffer allocatation failed\n" );
@@ -819,7 +819,7 @@ PND_gl_deletecontext(_THIS, SDL_GLContext context)
#ifdef WIZ_GLES_LITE
if( hNativeWnd != 0 )
{
free(hNativeWnd);
SDL_free(hNativeWnd);
hNativeWnd = 0;
printf( "SDL: Wiz framebuffer released\n" );
}

View File

@@ -85,7 +85,7 @@ glGetConfig(EGLConfig *pconf, int *pformat)
}
// Allocate enough memory for all configurations.
egl_configs = malloc(egl_num_configs * sizeof(*egl_configs));
egl_configs = SDL_malloc(egl_num_configs * sizeof(*egl_configs));
if (egl_configs == NULL) {
return -1;
}
@@ -94,7 +94,7 @@ glGetConfig(EGLConfig *pconf, int *pformat)
rc = eglGetConfigs(egl_disp, egl_configs, egl_num_configs,
&egl_num_configs);
if (rc != EGL_TRUE) {
free(egl_configs);
SDL_free(egl_configs);
return -1;
}
@@ -119,7 +119,7 @@ glGetConfig(EGLConfig *pconf, int *pformat)
break;
}
free(egl_configs);
SDL_free(egl_configs);
*pconf = egl_conf;
*pformat = chooseFormat(egl_conf);

View File

@@ -0,0 +1,51 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#ifndef SDL_riscosdefs_h_
#define SDL_riscosdefs_h_
typedef struct sprite_area {
int size; /* +0 */
int count; /* +4 */
int start; /* +8 */
int end; /* +12 */
} sprite_area;
SDL_COMPILE_TIME_ASSERT(sprite_area, sizeof(sprite_area) == 16);
typedef struct sprite_header {
int next; /* +0 */
char name[12]; /* +4 */
int width; /* +16 */
int height; /* +20 */
int first_bit; /* +24 */
int last_bit; /* +28 */
int image_offset; /* +32 */
int mask_offset; /* +36 */
int mode; /* +40 */
} sprite_header;
SDL_COMPILE_TIME_ASSERT(sprite_header, sizeof(sprite_header) == 44);
#endif /* SDL_riscosdefs_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,185 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_RISCOS
#include "../../events/SDL_events_c.h"
#include "SDL_log.h"
#include "SDL_riscosvideo.h"
#include "SDL_riscosevents_c.h"
#include "scancodes_riscos.h"
#include <kernel.h>
#include <swis.h>
static SDL_Scancode
SDL_RISCOS_translate_keycode(int keycode)
{
SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN;
if (keycode < SDL_arraysize(riscos_scancode_table)) {
scancode = riscos_scancode_table[keycode];
if (scancode == SDL_SCANCODE_UNKNOWN) {
SDL_Log("The key you just pressed is not recognized by SDL: %d", keycode);
}
}
return scancode;
}
void
RISCOS_PollKeyboard(_THIS)
{
SDL_VideoData *driverdata = (SDL_VideoData *)_this->driverdata;
Uint8 key = 2;
int i;
/* Check for key releases */
for (i = 0; i < RISCOS_MAX_KEYS_PRESSED; i++) {
if (driverdata->key_pressed[i] != 255) {
if ((_kernel_osbyte(129, driverdata->key_pressed[i] ^ 0xff, 0xff) & 0xff) != 255) {
SDL_SendKeyboardKey(SDL_RELEASED, SDL_RISCOS_translate_keycode(driverdata->key_pressed[i]));
driverdata->key_pressed[i] = 255;
}
}
}
/* Check for key presses */
while (key < 0xff) {
SDL_bool already_pressed = SDL_FALSE;
key = _kernel_osbyte(121, key + 1, 0) & 0xff;
switch (key) {
case 255:
/* Ignore mouse keys */
case 9:
case 10:
case 11:
/* Ignore keys with multiple INKEY codes */
case 24:
case 40:
case 71:
case 87:
break;
default:
/* Do we already know of this key? */
for (i = 0; i < RISCOS_MAX_KEYS_PRESSED; i++) {
if (driverdata->key_pressed[i] == key) {
already_pressed = SDL_TRUE;
break;
}
}
if (!already_pressed) {
SDL_SendKeyboardKey(SDL_PRESSED, SDL_RISCOS_translate_keycode(key));
/* Record the press so we can detect release later. */
for (i = 0; i < RISCOS_MAX_KEYS_PRESSED; i++) {
if (driverdata->key_pressed[i] == 255) {
driverdata->key_pressed[i] = key;
break;
}
}
}
}
}
}
static const Uint8 mouse_button_map[] = {
SDL_BUTTON_RIGHT,
SDL_BUTTON_MIDDLE,
SDL_BUTTON_LEFT,
SDL_BUTTON_X1,
SDL_BUTTON_X2,
SDL_BUTTON_X2 + 1,
SDL_BUTTON_X2 + 2,
SDL_BUTTON_X2 + 3
};
void
RISCOS_PollMouse(_THIS)
{
SDL_VideoData *driverdata = (SDL_VideoData *)_this->driverdata;
SDL_Mouse *mouse = SDL_GetMouse();
SDL_Rect rect;
_kernel_swi_regs regs;
int i, x, y, buttons;
if (SDL_GetDisplayBounds(0, &rect) < 0) {
return;
}
_kernel_swi(OS_Mouse, &regs, &regs);
x = (regs.r[0] >> 1);
y = rect.h - (regs.r[1] >> 1);
buttons = regs.r[2];
if (mouse->x != x || mouse->y != y) {
SDL_SendMouseMotion(mouse->focus, mouse->mouseID, 0, x, y);
}
if (driverdata->last_mouse_buttons != buttons) {
for (i = 0; i < SDL_arraysize(mouse_button_map); i++) {
SDL_SendMouseButton(mouse->focus, mouse->mouseID, (buttons & (1 << i)) ? SDL_PRESSED : SDL_RELEASED, mouse_button_map[i]);
}
driverdata->last_mouse_buttons = buttons;
}
}
int
RISCOS_InitEvents(_THIS)
{
SDL_VideoData *driverdata = (SDL_VideoData *) _this->driverdata;
int i, status;
for (i = 0; i < RISCOS_MAX_KEYS_PRESSED; i++)
driverdata->key_pressed[i] = 255;
status = (_kernel_osbyte(202, 0, 255) & 0xFF);
SDL_ToggleModState(KMOD_NUM, (status & (1 << 2)) == 0);
SDL_ToggleModState(KMOD_CAPS, (status & (1 << 4)) == 0);
SDL_ToggleModState(KMOD_SCROLL, (status & (1 << 1)) != 0);
/* Disable escape. */
_kernel_osbyte(229, 1, 0);
return 0;
}
void
RISCOS_PumpEvents(_THIS)
{
RISCOS_PollMouse(_this);
RISCOS_PollKeyboard(_this);
}
void
RISCOS_QuitEvents(_THIS)
{
/* Re-enable escape. */
_kernel_osbyte(229, 0, 0);
}
#endif /* SDL_VIDEO_DRIVER_RISCOS */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,35 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_riscosevents_c_h_
#define SDL_riscosevents_c_h_
#include "../../SDL_internal.h"
#include "SDL_riscosvideo.h"
extern int RISCOS_InitEvents(_THIS);
extern void RISCOS_PumpEvents(_THIS);
extern void RISCOS_QuitEvents(_THIS);
#endif /* SDL_riscosevents_c_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,126 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_RISCOS
#include "../SDL_sysvideo.h"
#include "SDL_riscosframebuffer_c.h"
#include "SDL_riscosvideo.h"
#include "SDL_riscoswindow.h"
#include <kernel.h>
#include <swis.h>
int RISCOS_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch)
{
SDL_WindowData *driverdata = (SDL_WindowData *) window->driverdata;
const char *sprite_name = "display";
unsigned int sprite_mode;
_kernel_oserror *error;
_kernel_swi_regs regs;
SDL_DisplayMode mode;
int size;
/* Free the old framebuffer surface */
RISCOS_DestroyWindowFramebuffer(_this, window);
/* Create a new one */
SDL_GetCurrentDisplayMode(SDL_GetWindowDisplayIndex(window), &mode);
if ((SDL_ISPIXELFORMAT_PACKED(mode.format) || SDL_ISPIXELFORMAT_ARRAY(mode.format))) {
*format = mode.format;
sprite_mode = (unsigned int)mode.driverdata;
} else {
*format = SDL_PIXELFORMAT_BGR888;
sprite_mode = (1 | (90 << 1) | (90 << 14) | (6 << 27));
}
/* Calculate pitch */
*pitch = (((window->w * SDL_BYTESPERPIXEL(*format)) + 3) & ~3);
/* Allocate the sprite area */
size = sizeof(sprite_area) + sizeof(sprite_header) + ((*pitch) * window->h);
driverdata->fb_area = SDL_malloc(size);
if (!driverdata->fb_area) {
return SDL_OutOfMemory();
}
driverdata->fb_area->size = size;
driverdata->fb_area->count = 0;
driverdata->fb_area->start = 16;
driverdata->fb_area->end = 16;
/* Create the actual image */
regs.r[0] = 256+15;
regs.r[1] = (int)driverdata->fb_area;
regs.r[2] = (int)sprite_name;
regs.r[3] = 0;
regs.r[4] = window->w;
regs.r[5] = window->h;
regs.r[6] = sprite_mode;
error = _kernel_swi(OS_SpriteOp, &regs, &regs);
if (error != NULL) {
SDL_free(driverdata->fb_area);
return SDL_SetError("Unable to create sprite: %s (%i)", error->errmess, error->errnum);
}
driverdata->fb_sprite = (sprite_header *)(((Uint8 *)driverdata->fb_area) + driverdata->fb_area->start);
*pixels = ((Uint8 *)driverdata->fb_sprite) + driverdata->fb_sprite->image_offset;
return 0;
}
int RISCOS_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects)
{
SDL_WindowData *driverdata = (SDL_WindowData *) window->driverdata;
_kernel_swi_regs regs;
_kernel_oserror *error;
regs.r[0] = 512+52;
regs.r[1] = (int)driverdata->fb_area;
regs.r[2] = (int)driverdata->fb_sprite;
regs.r[3] = 0; /* window->x << 1; */
regs.r[4] = 0; /* window->y << 1; */
regs.r[5] = 0x50;
regs.r[6] = 0;
regs.r[7] = 0;
error = _kernel_swi(OS_SpriteOp, &regs, &regs);
if (error != NULL) {
return SDL_SetError("OS_SpriteOp 52 failed: %s (%i)", error->errmess, error->errnum);
}
return 0;
}
void RISCOS_DestroyWindowFramebuffer(_THIS, SDL_Window * window)
{
SDL_WindowData *driverdata = (SDL_WindowData *) window->driverdata;
if (driverdata->fb_area) {
SDL_free(driverdata->fb_area);
driverdata->fb_area = NULL;
}
driverdata->fb_sprite = NULL;
}
#endif /* SDL_VIDEO_DRIVER_RISCOS */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,33 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_riscosframebuffer_c_h_
#define SDL_riscosframebuffer_c_h_
#include "../../SDL_internal.h"
extern int RISCOS_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch);
extern int RISCOS_UpdateWindowFramebuffer(_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects);
extern void RISCOS_DestroyWindowFramebuffer(_THIS, SDL_Window * window);
#endif /* SDL_riscosframebuffer_c_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,68 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_RISCOS
#include "SDL_messagebox.h"
#include "SDL_riscosmessagebox.h"
#include <kernel.h>
#include <swis.h>
int
RISCOS_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
{
_kernel_swi_regs regs;
_kernel_oserror error;
char buttonstring[1024];
int i;
error.errnum = 0;
SDL_strlcpy(error.errmess, messageboxdata->message, 252);
regs.r[0] = (unsigned int)&error;
regs.r[1] = (1 << 8) | (1 << 4);
if (messageboxdata->flags == SDL_MESSAGEBOX_INFORMATION)
regs.r[1] |= (1 << 9);
else if (messageboxdata->flags == SDL_MESSAGEBOX_WARNING)
regs.r[1] |= (2 << 9);
regs.r[2] = (unsigned int)messageboxdata->title;
regs.r[3] = 0;
regs.r[4] = 0;
SDL_strlcpy(buttonstring, "" , 1024);
for (i = 0; i < messageboxdata->numbuttons; i++) {
SDL_strlcat(buttonstring, messageboxdata->buttons[i].text, 1024);
if (i + 1 < messageboxdata->numbuttons)
SDL_strlcat(buttonstring, ",", 1024);
}
regs.r[5] = (unsigned int)buttonstring;
_kernel_swi(Wimp_ReportError, &regs, &regs);
*buttonid = (regs.r[1] == 0) ? -1 : messageboxdata->buttons[regs.r[1] - 3].buttonid;
return 0;
}
#endif /* SDL_VIDEO_DRIVER_RISCOS */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,29 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_RISCOS
extern int RISCOS_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid);
#endif /* SDL_VIDEO_DRIVER_RISCOS */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,315 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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_RISCOS
#include "../SDL_sysvideo.h"
#include "SDL_riscosvideo.h"
#include "SDL_riscosmodes.h"
#include <kernel.h>
#include <swis.h>
enum {
MODE_FLAG_565 = 1 << 7,
MODE_FLAG_COLOUR_SPACE = 0xF << 12,
MODE_FLAG_TBGR = 0,
MODE_FLAG_TRGB = 1 << 14,
MODE_FLAG_ABGR = 1 << 15,
MODE_FLAG_ARGB = MODE_FLAG_TRGB | MODE_FLAG_ABGR
};
static const struct {
SDL_PixelFormatEnum pixel_format;
int modeflags, ncolour, log2bpp;
} mode_to_pixelformat[] = {
/* { SDL_PIXELFORMAT_INDEX1LSB, 0, 1, 0 }, */
/* { SDL_PIXELFORMAT_INDEX2LSB, 0, 3, 1 }, */
/* { SDL_PIXELFORMAT_INDEX4LSB, 0, 15, 2 }, */
/* { SDL_PIXELFORMAT_INDEX8, MODE_FLAG_565, 255, 3 }, */
{ SDL_PIXELFORMAT_XBGR1555, MODE_FLAG_TBGR, 65535, 4 },
{ SDL_PIXELFORMAT_XRGB1555, MODE_FLAG_TRGB, 65535, 4 },
{ SDL_PIXELFORMAT_ABGR1555, MODE_FLAG_ABGR, 65535, 4 },
{ SDL_PIXELFORMAT_ARGB1555, MODE_FLAG_ARGB, 65535, 4 },
{ SDL_PIXELFORMAT_XBGR4444, MODE_FLAG_TBGR, 4095, 4 },
{ SDL_PIXELFORMAT_XRGB4444, MODE_FLAG_TRGB, 4095, 4 },
{ SDL_PIXELFORMAT_ABGR4444, MODE_FLAG_ABGR, 4095, 4 },
{ SDL_PIXELFORMAT_ARGB4444, MODE_FLAG_ARGB, 4095, 4 },
{ SDL_PIXELFORMAT_BGR565, MODE_FLAG_TBGR | MODE_FLAG_565, 65535, 4 },
{ SDL_PIXELFORMAT_RGB565, MODE_FLAG_TRGB | MODE_FLAG_565, 65535, 4 },
{ SDL_PIXELFORMAT_BGR24, MODE_FLAG_TBGR, 16777215, 6 },
{ SDL_PIXELFORMAT_RGB24, MODE_FLAG_TRGB, 16777215, 6 },
{ SDL_PIXELFORMAT_XBGR8888, MODE_FLAG_TBGR, -1, 5 },
{ SDL_PIXELFORMAT_XRGB8888, MODE_FLAG_TRGB, -1, 5 },
{ SDL_PIXELFORMAT_ABGR8888, MODE_FLAG_ABGR, -1, 5 },
{ SDL_PIXELFORMAT_ARGB8888, MODE_FLAG_ARGB, -1, 5 }
};
static SDL_PixelFormatEnum
RISCOS_ModeToPixelFormat(int ncolour, int modeflags, int log2bpp)
{
int i;
for (i = 0; i < SDL_arraysize(mode_to_pixelformat); i++) {
if (log2bpp == mode_to_pixelformat[i].log2bpp &&
(ncolour == mode_to_pixelformat[i].ncolour || ncolour == 0) &&
(modeflags & (MODE_FLAG_565 | MODE_FLAG_COLOUR_SPACE)) == mode_to_pixelformat[i].modeflags) {
return mode_to_pixelformat[i].pixel_format;
}
}
return SDL_PIXELFORMAT_UNKNOWN;
}
static size_t
measure_mode_block(const int *block)
{
size_t blockSize = ((block[0] & 0xFF) == 3) ? 7 : 5;
while(block[blockSize] != -1) {
blockSize += 2;
}
blockSize++;
return blockSize * 4;
}
static int
read_mode_variable(int *block, int var)
{
_kernel_swi_regs regs;
regs.r[0] = (int)block;
regs.r[1] = var;
_kernel_swi(OS_ReadModeVariable, &regs, &regs);
return regs.r[2];
}
static SDL_bool
read_mode_block(int *block, SDL_DisplayMode *mode, SDL_bool extended)
{
int xres, yres, ncolour, modeflags, log2bpp, rate;
if ((block[0] & 0xFF) == 1) {
xres = block[1];
yres = block[2];
log2bpp = block[3];
rate = block[4];
ncolour = (1 << (1 << log2bpp)) - 1;
modeflags = MODE_FLAG_TBGR;
} else if ((block[0] & 0xFF) == 3) {
xres = block[1];
yres = block[2];
ncolour = block[3];
modeflags = block[4];
log2bpp = block[5];
rate = block[6];
} else {
return SDL_FALSE;
}
if (extended) {
xres = read_mode_variable(block, 11) + 1;
yres = read_mode_variable(block, 12) + 1;
log2bpp = read_mode_variable(block, 9);
ncolour = read_mode_variable(block, 3);
modeflags = read_mode_variable(block, 0);
}
mode->w = xres;
mode->h = yres;
mode->format = RISCOS_ModeToPixelFormat(ncolour, modeflags, log2bpp);
mode->refresh_rate = rate;
return SDL_TRUE;
}
static void *
convert_mode_block(const int *block)
{
int xres, yres, log2bpp, rate, ncolour = 0, modeflags = 0;
size_t pos = 0;
int *dst;
if ((block[0] & 0xFF) == 1) {
xres = block[1];
yres = block[2];
log2bpp = block[3];
rate = block[4];
} else if ((block[0] & 0xFF) == 3) {
xres = block[1];
yres = block[2];
ncolour = block[3];
modeflags = block[4];
log2bpp = block[5];
rate = block[6];
} else {
return NULL;
}
dst = SDL_malloc(40);
if (!dst) {
return NULL;
}
dst[pos++] = 1;
dst[pos++] = xres;
dst[pos++] = yres;
dst[pos++] = log2bpp;
dst[pos++] = rate;
if (ncolour != 0) {
dst[pos++] = 3;
dst[pos++] = ncolour;
}
if (modeflags != 0) {
dst[pos++] = 0;
dst[pos++] = modeflags;
}
dst[pos++] = -1;
return dst;
}
static void *
copy_memory(const void *src, size_t size, size_t alloc)
{
void *dst = SDL_malloc(alloc);
if (dst) {
SDL_memcpy(dst, src, size);
}
return dst;
}
int
RISCOS_InitModes(_THIS)
{
SDL_DisplayMode mode;
int *current_mode;
_kernel_swi_regs regs;
_kernel_oserror *error;
size_t size;
regs.r[0] = 1;
error = _kernel_swi(OS_ScreenMode, &regs, &regs);
if (error != NULL) {
return SDL_SetError("Unable to retrieve the current screen mode: %s (%i)", error->errmess, error->errnum);
}
current_mode = (int *)regs.r[1];
if (!read_mode_block(current_mode, &mode, SDL_TRUE)) {
return SDL_SetError("Unsupported mode block format %d", current_mode[0]);
}
size = measure_mode_block(current_mode);
mode.driverdata = copy_memory(current_mode, size, size);
if (!mode.driverdata) {
return SDL_OutOfMemory();
}
return SDL_AddBasicVideoDisplay(&mode);
}
void
RISCOS_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
{
SDL_DisplayMode mode;
_kernel_swi_regs regs;
_kernel_oserror *error;
void *block, *pos;
regs.r[0] = 2;
regs.r[2] = 0;
regs.r[6] = 0;
regs.r[7] = 0;
error = _kernel_swi(OS_ScreenMode, &regs, &regs);
if (error != NULL) {
SDL_SetError("Unable to enumerate screen modes: %s (%i)", error->errmess, error->errnum);
return;
}
block = SDL_malloc(-regs.r[7]);
if (!block) {
SDL_OutOfMemory();
return;
}
regs.r[6] = (int)block;
regs.r[7] = -regs.r[7];
error = _kernel_swi(OS_ScreenMode, &regs, &regs);
if (error != NULL) {
SDL_free(block);
SDL_SetError("Unable to enumerate screen modes: %s (%i)", error->errmess, error->errnum);
return;
}
for (pos = block; pos < (void *)regs.r[6]; pos += *((int *)pos)) {
if (!read_mode_block(pos + 4, &mode, SDL_FALSE)) {
continue;
}
if (mode.format == SDL_PIXELFORMAT_UNKNOWN)
continue;
mode.driverdata = convert_mode_block(pos + 4);
if (!mode.driverdata) {
SDL_OutOfMemory();
break;
}
if (!SDL_AddDisplayMode(display, &mode)) {
SDL_free(mode.driverdata);
}
}
SDL_free(block);
}
int
RISCOS_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
{
const char disable_cursor[] = { 23, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
_kernel_swi_regs regs;
_kernel_oserror *error;
int i;
regs.r[0] = 0;
regs.r[1] = (int)mode->driverdata;
error = _kernel_swi(OS_ScreenMode, &regs, &regs);
if (error != NULL) {
return SDL_SetError("Unable to set the current screen mode: %s (%i)", error->errmess, error->errnum);
}
/* Turn the text cursor off */
for (i = 0; i < SDL_arraysize(disable_cursor); i++) {
_kernel_oswrch(disable_cursor[i]);
}
/* Turn the mouse pointer on */
/* _kernel_osbyte(106, 1, 0); */
return 0;
}
#endif /* SDL_VIDEO_DRIVER_RISCOS */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,33 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#ifndef SDL_riscosmodes_h_
#define SDL_riscosmodes_h_
extern int RISCOS_InitModes(_THIS);
extern void RISCOS_GetDisplayModes(_THIS, SDL_VideoDisplay * display);
extern int RISCOS_SetDisplayMode(_THIS, SDL_VideoDisplay * display,
SDL_DisplayMode * mode);
#endif /* SDL_riscosmodes_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,124 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_RISCOS
#include "SDL_video.h"
#include "SDL_mouse.h"
#include "../SDL_sysvideo.h"
#include "../SDL_pixels_c.h"
#include "../../events/SDL_events_c.h"
#include "SDL_riscosvideo.h"
#include "SDL_riscosevents_c.h"
#include "SDL_riscosframebuffer_c.h"
#include "SDL_riscosmodes.h"
#include "SDL_riscoswindow.h"
#define RISCOSVID_DRIVER_NAME "riscos"
/* Initialization/Query functions */
static int RISCOS_VideoInit(_THIS);
static void RISCOS_VideoQuit(_THIS);
/* RISC OS driver bootstrap functions */
static void
RISCOS_DeleteDevice(SDL_VideoDevice * device)
{
SDL_free(device->driverdata);
SDL_free(device);
}
static SDL_VideoDevice *
RISCOS_CreateDevice(int devindex)
{
SDL_VideoDevice *device;
SDL_VideoData *phdata;
/* Initialize all variables that we clean on shutdown */
device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
if (!device) {
SDL_OutOfMemory();
return (0);
}
/* Initialize internal data */
phdata = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
if (phdata == NULL) {
SDL_OutOfMemory();
SDL_free(device);
return NULL;
}
device->driverdata = phdata;
/* Set the function pointers */
device->VideoInit = RISCOS_VideoInit;
device->VideoQuit = RISCOS_VideoQuit;
device->PumpEvents = RISCOS_PumpEvents;
device->GetDisplayModes = RISCOS_GetDisplayModes;
device->SetDisplayMode = RISCOS_SetDisplayMode;
device->CreateSDLWindow = RISCOS_CreateWindow;
device->DestroyWindow = RISCOS_DestroyWindow;
device->GetWindowWMInfo = RISCOS_GetWindowWMInfo;
device->CreateWindowFramebuffer = RISCOS_CreateWindowFramebuffer;
device->UpdateWindowFramebuffer = RISCOS_UpdateWindowFramebuffer;
device->DestroyWindowFramebuffer = RISCOS_DestroyWindowFramebuffer;
device->free = RISCOS_DeleteDevice;
return device;
}
VideoBootStrap RISCOS_bootstrap = {
RISCOSVID_DRIVER_NAME, "SDL RISC OS video driver",
RISCOS_CreateDevice
};
static int
RISCOS_VideoInit(_THIS)
{
if (RISCOS_InitEvents(_this) < 0) {
return -1;
}
if (RISCOS_InitModes(_this) < 0) {
return -1;
}
/* We're done! */
return 0;
}
static void
RISCOS_VideoQuit(_THIS)
{
RISCOS_QuitEvents(_this);
}
#endif /* SDL_VIDEO_DRIVER_RISCOS */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,38 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#ifndef SDL_riscosvideo_h_
#define SDL_riscosvideo_h_
#include "../SDL_sysvideo.h"
#define RISCOS_MAX_KEYS_PRESSED 6
typedef struct SDL_VideoData
{
int last_mouse_buttons;
Uint8 key_pressed[RISCOS_MAX_KEYS_PRESSED];
} SDL_VideoData;
#endif /* SDL_riscosvideo_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,78 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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_RISCOS
#include "SDL_version.h"
#include "SDL_syswm.h"
#include "../SDL_sysvideo.h"
#include "SDL_riscosvideo.h"
#include "SDL_riscoswindow.h"
int
RISCOS_CreateWindow(_THIS, SDL_Window * window)
{
SDL_WindowData *driverdata;
driverdata = (SDL_WindowData *) SDL_calloc(1, sizeof(*driverdata));
if (!driverdata) {
return SDL_OutOfMemory();
}
driverdata->window = window;
window->flags |= SDL_WINDOW_FULLSCREEN;
/* All done! */
window->driverdata = driverdata;
return 0;
}
void
RISCOS_DestroyWindow(_THIS, SDL_Window * window)
{
SDL_WindowData *driverdata = (SDL_WindowData *) window->driverdata;
if (!driverdata)
return;
SDL_free(driverdata);
window->driverdata = NULL;
}
SDL_bool
RISCOS_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info)
{
if (info->version.major == SDL_MAJOR_VERSION &&
info->version.minor == SDL_MINOR_VERSION) {
info->subsystem = SDL_SYSWM_RISCOS;
return SDL_TRUE;
} else {
SDL_SetError("Application not compiled with SDL %d.%d",
SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
return SDL_FALSE;
}
}
#endif /* SDL_VIDEO_DRIVER_RISCOS */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,42 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#ifndef SDL_riscoswindow_h_
#define SDL_riscoswindow_h_
#include "SDL_riscosdefs.h"
typedef struct
{
SDL_Window *window;
sprite_area *fb_area;
sprite_header *fb_sprite;
} SDL_WindowData;
extern int RISCOS_CreateWindow(_THIS, SDL_Window * window);
extern void RISCOS_DestroyWindow(_THIS, SDL_Window * window);
extern SDL_bool RISCOS_GetWindowWMInfo(_THIS, SDL_Window * window,
struct SDL_SysWMinfo *info);
#endif /* SDL_riscoswindow_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,158 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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_scancode.h"
/* RISC OS key code to SDL_Keycode mapping table
Sources:
- https://www.riscosopen.org/wiki/documentation/show/Keyboard Scan Codes
*/
/* *INDENT-OFF* */
static SDL_Scancode const riscos_scancode_table[] = {
/* 0 */ SDL_SCANCODE_UNKNOWN, /* Shift */
/* 1 */ SDL_SCANCODE_UNKNOWN, /* Ctrl */
/* 2 */ SDL_SCANCODE_UNKNOWN, /* Alt */
/* 3 */ SDL_SCANCODE_LSHIFT,
/* 4 */ SDL_SCANCODE_LCTRL,
/* 5 */ SDL_SCANCODE_LALT,
/* 6 */ SDL_SCANCODE_RSHIFT,
/* 7 */ SDL_SCANCODE_RCTRL,
/* 8 */ SDL_SCANCODE_RALT,
/* 9 */ SDL_SCANCODE_UNKNOWN, /* Left mouse */
/* 10 */ SDL_SCANCODE_UNKNOWN, /* Center mouse */
/* 11 */ SDL_SCANCODE_UNKNOWN, /* Right mouse */
/* 12 */ SDL_SCANCODE_UNKNOWN,
/* 13 */ SDL_SCANCODE_UNKNOWN,
/* 14 */ SDL_SCANCODE_UNKNOWN,
/* 15 */ SDL_SCANCODE_UNKNOWN,
/* 16 */ SDL_SCANCODE_Q,
/* 17 */ SDL_SCANCODE_3,
/* 18 */ SDL_SCANCODE_4,
/* 19 */ SDL_SCANCODE_5,
/* 20 */ SDL_SCANCODE_F4,
/* 21 */ SDL_SCANCODE_8,
/* 22 */ SDL_SCANCODE_F7,
/* 23 */ SDL_SCANCODE_MINUS,
/* 24 */ SDL_SCANCODE_6, /* Duplicate of 52 */
/* 25 */ SDL_SCANCODE_LEFT,
/* 26 */ SDL_SCANCODE_KP_6,
/* 27 */ SDL_SCANCODE_KP_7,
/* 28 */ SDL_SCANCODE_F11,
/* 29 */ SDL_SCANCODE_F12,
/* 30 */ SDL_SCANCODE_F10,
/* 31 */ SDL_SCANCODE_SCROLLLOCK,
/* 32 */ SDL_SCANCODE_PRINTSCREEN,
/* 33 */ SDL_SCANCODE_W,
/* 34 */ SDL_SCANCODE_E,
/* 35 */ SDL_SCANCODE_T,
/* 36 */ SDL_SCANCODE_7,
/* 37 */ SDL_SCANCODE_I,
/* 38 */ SDL_SCANCODE_9,
/* 39 */ SDL_SCANCODE_0,
/* 40 */ SDL_SCANCODE_MINUS, /* Duplicate of 23 */
/* 41 */ SDL_SCANCODE_DOWN,
/* 42 */ SDL_SCANCODE_KP_8,
/* 43 */ SDL_SCANCODE_KP_9,
/* 44 */ SDL_SCANCODE_PAUSE,
/* 45 */ SDL_SCANCODE_GRAVE,
/* 46 */ SDL_SCANCODE_CURRENCYUNIT,
/* 47 */ SDL_SCANCODE_BACKSPACE,
/* 48 */ SDL_SCANCODE_1,
/* 49 */ SDL_SCANCODE_2,
/* 50 */ SDL_SCANCODE_D,
/* 51 */ SDL_SCANCODE_R,
/* 52 */ SDL_SCANCODE_6,
/* 53 */ SDL_SCANCODE_U,
/* 54 */ SDL_SCANCODE_O,
/* 55 */ SDL_SCANCODE_P,
/* 56 */ SDL_SCANCODE_LEFTBRACKET,
/* 57 */ SDL_SCANCODE_UP,
/* 58 */ SDL_SCANCODE_KP_PLUS,
/* 59 */ SDL_SCANCODE_KP_MINUS,
/* 60 */ SDL_SCANCODE_KP_ENTER,
/* 61 */ SDL_SCANCODE_INSERT,
/* 62 */ SDL_SCANCODE_HOME,
/* 63 */ SDL_SCANCODE_PAGEUP,
/* 64 */ SDL_SCANCODE_CAPSLOCK,
/* 65 */ SDL_SCANCODE_A,
/* 66 */ SDL_SCANCODE_X,
/* 67 */ SDL_SCANCODE_F,
/* 68 */ SDL_SCANCODE_Y,
/* 69 */ SDL_SCANCODE_J,
/* 70 */ SDL_SCANCODE_K,
/* 71 */ SDL_SCANCODE_2, /* Duplicate of 49 */
/* 72 */ SDL_SCANCODE_SEMICOLON, /* Duplicate of 87 */
/* 73 */ SDL_SCANCODE_RETURN,
/* 74 */ SDL_SCANCODE_KP_DIVIDE,
/* 75 */ SDL_SCANCODE_UNKNOWN,
/* 76 */ SDL_SCANCODE_KP_PERIOD,
/* 77 */ SDL_SCANCODE_NUMLOCKCLEAR,
/* 78 */ SDL_SCANCODE_PAGEDOWN,
/* 79 */ SDL_SCANCODE_APOSTROPHE,
/* 80 */ SDL_SCANCODE_UNKNOWN,
/* 81 */ SDL_SCANCODE_S,
/* 82 */ SDL_SCANCODE_C,
/* 83 */ SDL_SCANCODE_G,
/* 84 */ SDL_SCANCODE_H,
/* 85 */ SDL_SCANCODE_N,
/* 86 */ SDL_SCANCODE_L,
/* 87 */ SDL_SCANCODE_SEMICOLON,
/* 88 */ SDL_SCANCODE_RIGHTBRACKET,
/* 89 */ SDL_SCANCODE_DELETE,
/* 90 */ SDL_SCANCODE_KP_HASH,
/* 91 */ SDL_SCANCODE_KP_MULTIPLY,
/* 92 */ SDL_SCANCODE_UNKNOWN,
/* 93 */ SDL_SCANCODE_EQUALS,
/* 94 */ SDL_SCANCODE_NONUSBACKSLASH,
/* 95 */ SDL_SCANCODE_UNKNOWN,
/* 96 */ SDL_SCANCODE_TAB,
/* 97 */ SDL_SCANCODE_Z,
/* 98 */ SDL_SCANCODE_SPACE,
/* 99 */ SDL_SCANCODE_V,
/* 100 */ SDL_SCANCODE_B,
/* 101 */ SDL_SCANCODE_M,
/* 102 */ SDL_SCANCODE_COMMA,
/* 103 */ SDL_SCANCODE_PERIOD,
/* 104 */ SDL_SCANCODE_SLASH,
/* 105 */ SDL_SCANCODE_END,
/* 106 */ SDL_SCANCODE_KP_0,
/* 107 */ SDL_SCANCODE_KP_1,
/* 108 */ SDL_SCANCODE_KP_3,
/* 109 */ SDL_SCANCODE_UNKNOWN,
/* 110 */ SDL_SCANCODE_UNKNOWN,
/* 111 */ SDL_SCANCODE_UNKNOWN,
/* 112 */ SDL_SCANCODE_ESCAPE,
/* 113 */ SDL_SCANCODE_F1,
/* 114 */ SDL_SCANCODE_F2,
/* 115 */ SDL_SCANCODE_F3,
/* 116 */ SDL_SCANCODE_F5,
/* 117 */ SDL_SCANCODE_F6,
/* 118 */ SDL_SCANCODE_F8,
/* 119 */ SDL_SCANCODE_F9,
/* 120 */ SDL_SCANCODE_BACKSLASH,
/* 121 */ SDL_SCANCODE_RIGHT,
/* 122 */ SDL_SCANCODE_KP_4,
/* 123 */ SDL_SCANCODE_KP_5,
/* 124 */ SDL_SCANCODE_KP_2,
/* 125 */ SDL_SCANCODE_LGUI,
/* 126 */ SDL_SCANCODE_RGUI,
/* 127 */ SDL_SCANCODE_MENU
};
/* *INDENT-ON* */

View File

@@ -24,9 +24,10 @@
#include "../../events/SDL_events_c.h"
#include "SDL_uikitvideo.h"
#include "SDL_uikitevents.h"
#include "SDL_uikitopengles.h"
#include "SDL_uikitvideo.h"
#include "SDL_uikitwindow.h"
#import <Foundation/Foundation.h>
@@ -184,20 +185,20 @@ static id mouse_connect_observer = nil;
static id mouse_disconnect_observer = nil;
static bool mouse_relative_mode = SDL_FALSE;
static void UpdateMouseGrab()
static void UpdatePointerLock()
{
SDL_VideoDevice *_this = SDL_GetVideoDevice();
SDL_Window *window;
for (window = _this->windows; window != NULL; window = window->next) {
SDL_UpdateWindowGrab(window);
UIKit_UpdatePointerLock(_this, window);
}
}
static int SetGCMouseRelativeMode(SDL_bool enabled)
{
mouse_relative_mode = enabled;
UpdateMouseGrab();
UpdatePointerLock();
return 0;
}
@@ -234,7 +235,9 @@ static void OnGCMouseConnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios(14
mouse.mouseInput.mouseMovedHandler = ^(GCMouseInput *mouse, float deltaX, float deltaY)
{
SDL_SendMouseMotion(SDL_GetMouseFocus(), mouseID, SDL_TRUE, (int)deltaX, -(int)deltaY);
if (SDL_GCMouseRelativeMode()) {
SDL_SendMouseMotion(SDL_GetMouseFocus(), mouseID, 1, (int)deltaX, -(int)deltaY);
}
};
dispatch_queue_t queue = dispatch_queue_create( "org.libsdl.input.mouse", DISPATCH_QUEUE_SERIAL );
@@ -243,7 +246,7 @@ static void OnGCMouseConnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios(14
++mice_connected;
UpdateMouseGrab();
UpdatePointerLock();
}
static void OnGCMouseDisconnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0))
@@ -260,7 +263,7 @@ static void OnGCMouseDisconnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios
button.pressedChangedHandler = nil;
}
UpdateMouseGrab();
UpdatePointerLock();
}
void SDL_InitGCMouse(void)
@@ -268,29 +271,37 @@ void SDL_InitGCMouse(void)
@autoreleasepool {
/* There is a bug where mouse accumulates duplicate deltas over time in iOS 14.0 */
if (@available(iOS 14.1, tvOS 14.1, *)) {
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
/* iOS will not send the new pointer touch events if you don't have this key,
* and we need them to differentiate between mouse events and real touch events.
*/
BOOL indirect_input_available = [[[[NSBundle mainBundle] infoDictionary] objectForKey:@"UIApplicationSupportsIndirectInputEvents"] boolValue];
if (indirect_input_available) {
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
mouse_connect_observer = [center addObserverForName:GCMouseDidConnectNotification
object:nil
queue:nil
usingBlock:^(NSNotification *note) {
GCMouse *mouse = note.object;
OnGCMouseConnected(mouse);
}];
mouse_connect_observer = [center addObserverForName:GCMouseDidConnectNotification
object:nil
queue:nil
usingBlock:^(NSNotification *note) {
GCMouse *mouse = note.object;
OnGCMouseConnected(mouse);
}];
mouse_disconnect_observer = [center addObserverForName:GCMouseDidDisconnectNotification
object:nil
queue:nil
usingBlock:^(NSNotification *note) {
GCMouse *mouse = note.object;
OnGCMouseDisconnected(mouse);
}];
mouse_disconnect_observer = [center addObserverForName:GCMouseDidDisconnectNotification
object:nil
queue:nil
usingBlock:^(NSNotification *note) {
GCMouse *mouse = note.object;
OnGCMouseDisconnected(mouse);
}];
for (GCMouse *mouse in [GCMouse mice]) {
OnGCMouseConnected(mouse);
for (GCMouse *mouse in [GCMouse mice]) {
OnGCMouseConnected(mouse);
}
SDL_GetMouse()->SetRelativeMouseMode = SetGCMouseRelativeMode;
} else {
NSLog(@"You need UIApplicationSupportsIndirectInputEvents in your Info.plist for mouse support");
}
SDL_GetMouse()->SetRelativeMouseMode = SetGCMouseRelativeMode;
}
}
}

View File

@@ -160,7 +160,7 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
#if !TARGET_OS_TV && defined(__IPHONE_13_4)
- (UIPointerRegion *)pointerInteraction:(UIPointerInteraction *)interaction regionForRequest:(UIPointerRegionRequest *)request defaultRegion:(UIPointerRegion *)defaultRegion API_AVAILABLE(ios(13.4)){
if (request != nil && !SDL_HasGCMouse()) {
if (request != nil && !SDL_GCMouseRelativeMode()) {
CGPoint origin = self.bounds.origin;
CGPoint point = request.location;

View File

@@ -250,14 +250,7 @@ SDL_HideHomeIndicatorHintChanged(void *userdata, const char *name, const char *o
- (BOOL)prefersPointerLocked
{
SDL_VideoDevice *_this = SDL_GetVideoDevice();
if (SDL_HasGCMouse() &&
(SDL_GCMouseRelativeMode() || _this->grabbed_window == window)) {
return YES;
} else {
return NO;
}
return SDL_GCMouseRelativeMode() ? YES : NO;
}
#endif /* !TARGET_OS_TV */

View File

@@ -34,6 +34,7 @@ extern void UIKit_RaiseWindow(_THIS, SDL_Window * window);
extern void UIKit_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered);
extern void UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
extern void UIKit_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
extern void UIKit_UpdatePointerLock(_THIS, SDL_Window * window);
extern void UIKit_DestroyWindow(_THIS, SDL_Window * window);
extern SDL_bool UIKit_GetWindowWMInfo(_THIS, SDL_Window * window,
struct SDL_SysWMinfo * info);

View File

@@ -322,8 +322,15 @@ UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display
void
UIKit_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
{
/* There really isn't a concept of window grab or cursor confinement on iOS */
}
void
UIKit_UpdatePointerLock(_THIS, SDL_Window * window)
{
#if !TARGET_OS_TV
#if defined(__IPHONE_14_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_14_0
@autoreleasepool {
SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
SDL_uikitviewcontroller *viewcontroller = data.viewcontroller;
@@ -331,6 +338,7 @@ UIKit_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
[viewcontroller setNeedsUpdateOfPrefersPointerLocked];
}
}
#endif /* defined(__IPHONE_14_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_14_0 */
#endif /* !TARGET_OS_TV */
}

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2021 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
@@ -74,7 +74,7 @@ int VITA_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, vo
&data->buffer_uid
);
// memset the buffer to black
// SDL_memset the buffer to black
SDL_memset(data->buffer, 0x0, SCREEN_W*SCREEN_H*4);
SDL_memset(&framebuf, 0x00, sizeof(SceDisplayFrameBuf));

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2021 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

103
externals/SDL/src/video/vita/SDL_vitagl_pvr.c vendored Executable file
View File

@@ -0,0 +1,103 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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_vitagl_pvr_c.h"
#define MAX_PATH 256 // vita limits are somehow wrong
int
VITA_GL_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_GL_CreateContext(_THIS, SDL_Window * window)
{
return SDL_EGL_CreateContext(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);
}
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);
}
}
int
VITA_GL_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: */

View File

@@ -0,0 +1,35 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2021 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_vitagl_c_h_
#define SDL_vitagl_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);
#endif /* SDL_vitagl_c_h_ */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2021 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
@@ -42,6 +42,9 @@ Uint8 lock_key_down = 0;
void
VITA_InitKeyboard(void)
{
#if defined(SDL_VIDEO_VITA_PVR)
sceSysmoduleLoadModule(SCE_SYSMODULE_IME); /** For PVR OSK Support **/
#endif
sceHidKeyboardEnumerate(&keyboard_hid_handle, 1);
}

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2021 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
@@ -42,9 +42,15 @@ struct{
float range;
} force_info[SCE_TOUCH_PORT_MAX_NUM];
char* disableFrontPoll = NULL;
char* disableBackPoll = NULL;
void
VITA_InitTouch(void)
{
disableFrontPoll = SDL_getenv("VITA_DISABLE_TOUCH_FRONT");
disableBackPoll = SDL_getenv("VITA_DISABLE_TOUCH_BACK");
sceTouchSetSamplingState(SCE_TOUCH_PORT_FRONT, SCE_TOUCH_SAMPLING_STATE_START);
sceTouchSetSamplingState(SCE_TOUCH_PORT_BACK, SCE_TOUCH_SAMPLING_STATE_START);
sceTouchEnableTouchForce(SCE_TOUCH_PORT_FRONT);
@@ -84,9 +90,13 @@ VITA_PollTouch(void)
if (Vita_Window == NULL)
return;
memcpy(touch_old, touch, sizeof(touch_old));
SDL_memcpy(touch_old, touch, sizeof(touch_old));
for(port = 0; port < SCE_TOUCH_PORT_MAX_NUM; port++) {
/** Skip polling of Touch Device if environment variable is set **/
if (((port == 0) && disableFrontPoll) || ((port == 1) && disableBackPoll)) {
continue;
}
sceTouchPeek(port, &touch[port], 1);
if (touch[port].reportNum > 0) {
for (int i = 0; i < touch[port].reportNum; i++)

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2021 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

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2021 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
@@ -33,15 +33,24 @@
#include "../../events/SDL_keyboard_c.h"
/* VITA declarations */
#include <psp2/kernel/processmgr.h>
#include "SDL_vitavideo.h"
#include "SDL_vitatouch.h"
#include "SDL_vitakeyboard.h"
#include "SDL_vitamouse_c.h"
#include "SDL_vitaframebuffer.h"
#if SDL_VIDEO_VITA_PIB
#include "SDL_vitagl_c.h"
#if defined(SDL_VIDEO_VITA_PIB)
#include "SDL_vitagl_c.h"
#elif defined(SDL_VIDEO_VITA_PVR)
#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
#include <psp2/ime_dialog.h>
SDL_Window *Vita_Window;
@@ -130,7 +139,7 @@ VITA_Create()
device->DestroyWindowFramebuffer = VITA_DestroyWindowFramebuffer;
*/
#if SDL_VIDEO_VITA_PIB
#if defined(SDL_VIDEO_VITA_PIB) || defined(SDL_VIDEO_VITA_PVR)
device->GL_LoadLibrary = VITA_GL_LoadLibrary;
device->GL_GetProcAddress = VITA_GL_GetProcAddress;
device->GL_UnloadLibrary = VITA_GL_UnloadLibrary;
@@ -166,11 +175,32 @@ VITA_VideoInit(_THIS)
{
SDL_VideoDisplay display;
SDL_DisplayMode current_mode;
#if defined(SDL_VIDEO_VITA_PVR)
char* res = SDL_getenv("VITA_RESOLUTION");
#endif
SDL_zero(current_mode);
current_mode.w = 960;
current_mode.h = 544;
#if defined(SDL_VIDEO_VITA_PVR)
if (res) {
/* 1088i for PSTV (Or Sharpscale) */
if (!SDL_strncmp(res, "1080", 4)) {
current_mode.w = 1920;
current_mode.h = 1088;
}
/* 725p for PSTV (Or Sharpscale) */
else if (!SDL_strncmp(res, "720", 3)) {
current_mode.w = 1280;
current_mode.h = 725;
}
}
/* 544p */
else {
#endif
current_mode.w = 960;
current_mode.h = 544;
#if defined(SDL_VIDEO_VITA_PVR)
}
#endif
current_mode.refresh_rate = 60;
/* 32 bpp for default */
@@ -213,6 +243,9 @@ int
VITA_CreateWindow(_THIS, SDL_Window * window)
{
SDL_WindowData *wdata;
#if defined(SDL_VIDEO_VITA_PVR)
Psp2NativeWindow win;
#endif
/* Allocate window internal data */
wdata = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData));
@@ -232,6 +265,32 @@ VITA_CreateWindow(_THIS, SDL_Window * window)
Vita_Window = window;
#if defined(SDL_VIDEO_VITA_PVR)
win.type = PSP2_DRAWABLE_TYPE_WINDOW;
win.numFlipBuffers = 2;
win.flipChainThrdAffinity = 0x20000;
/* 1088i for PSTV (Or Sharpscale) */
if (window->w == 1920) {
win.windowSize = PSP2_WINDOW_1920X1088;
}
/* 725p for PSTV (Or Sharpscale) */
else if (window->w == 1280) {
win.windowSize = PSP2_WINDOW_1280X725;
}
/* 544p */
else {
win.windowSize = PSP2_WINDOW_960X544;
}
if ((window->flags & SDL_WINDOW_OPENGL) != 0) {
wdata->egl_surface = SDL_EGL_CreateSurface(_this, &win);
if (wdata->egl_surface == EGL_NO_SURFACE) {
return SDL_SetError("Could not create GLES window surface");
}
}
#endif
// fix input, we need to find a better way
SDL_SetKeyboardFocus(window);
@@ -288,8 +347,8 @@ VITA_RestoreWindow(_THIS, SDL_Window * window)
void
VITA_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
{
}
void
VITA_DestroyWindow(_THIS, SDL_Window * window)
{
@@ -333,63 +392,6 @@ SDL_bool VITA_HasScreenKeyboardSupport(_THIS)
#define SCE_IME_LANGUAGE_ENGLISH_US SCE_IME_LANGUAGE_ENGLISH
#endif
void VITA_ShowScreenKeyboard(_THIS, SDL_Window *window)
{
SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
SceWChar16 *title = u"";
SceWChar16 *text = u"";
SceInt32 res;
SceImeDialogParam param;
sceImeDialogParamInit(&param);
param.supportedLanguages = SCE_IME_LANGUAGE_ENGLISH_US;
param.languagesForced = SCE_FALSE;
param.type = SCE_IME_TYPE_DEFAULT;
param.option = 0;
param.textBoxMode = SCE_IME_DIALOG_TEXTBOX_MODE_WITH_CLEAR;
param.maxTextLength = SCE_IME_DIALOG_MAX_TEXT_LENGTH;
param.title = title;
param.initialText = text;
param.inputTextBuffer = videodata->ime_buffer;
res = sceImeDialogInit(&param);
if (res < 0) {
SDL_SetError("Failed to init IME dialog");
return;
}
videodata->ime_active = SDL_TRUE;
}
void VITA_HideScreenKeyboard(_THIS, SDL_Window *window)
{
SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
SceCommonDialogStatus dialogStatus = sceImeDialogGetStatus();
switch (dialogStatus) {
default:
case SCE_COMMON_DIALOG_STATUS_NONE:
case SCE_COMMON_DIALOG_STATUS_RUNNING:
break;
case SCE_COMMON_DIALOG_STATUS_FINISHED:
sceImeDialogTerm();
break;
}
videodata->ime_active = SDL_FALSE;
}
SDL_bool VITA_IsScreenKeyboardShown(_THIS, SDL_Window *window)
{
SceCommonDialogStatus dialogStatus = sceImeDialogGetStatus();
return (dialogStatus == SCE_COMMON_DIALOG_STATUS_RUNNING);
}
static void utf16_to_utf8(const uint16_t *src, uint8_t *dst) {
int i;
for (i = 0; src[i]; i++) {
@@ -414,15 +416,157 @@ static void utf16_to_utf8(const uint16_t *src, uint8_t *dst) {
*dst = '\0';
}
void VITA_PumpEvents(_THIS)
#if defined (SDL_VIDEO_VITA_PVR)
SceWChar16 libime_out[SCE_IME_MAX_PREEDIT_LENGTH + SCE_IME_MAX_TEXT_LENGTH + 1];
char libime_initval[8] = { 1 };
SceImeCaret caret_rev;
void VITA_ImeEventHandler(void *arg, const SceImeEventData *e)
{
SDL_VideoData *videodata = (SDL_VideoData *)arg;
SDL_Scancode scancode;
uint8_t utf8_buffer[SCE_IME_MAX_TEXT_LENGTH];
switch (e->id) {
case SCE_IME_EVENT_UPDATE_TEXT:
if (e->param.text.caretIndex == 0) {
SDL_SendKeyboardKeyAutoRelease(SDL_SCANCODE_BACKSPACE);
sceImeSetText((SceWChar16 *)libime_initval, 4);
}
else {
scancode = SDL_GetScancodeFromKey(*(SceWChar16 *)&libime_out[1]);
if (scancode == SDL_SCANCODE_SPACE) {
SDL_SendKeyboardKeyAutoRelease(SDL_SCANCODE_SPACE);
}
else {
utf16_to_utf8((SceWChar16 *)&libime_out[1], utf8_buffer);
SDL_SendKeyboardText((const char*)utf8_buffer);
}
SDL_memset(&caret_rev, 0, sizeof(SceImeCaret));
SDL_memset(libime_out, 0, ((SCE_IME_MAX_PREEDIT_LENGTH + SCE_IME_MAX_TEXT_LENGTH + 1) * sizeof(SceWChar16)));
caret_rev.index = 1;
sceImeSetCaret(&caret_rev);
sceImeSetText((SceWChar16 *)libime_initval, 4);
}
break;
case SCE_IME_EVENT_PRESS_ENTER:
SDL_SendKeyboardKeyAutoRelease(SDL_SCANCODE_RETURN);
case SCE_IME_EVENT_PRESS_CLOSE:
sceImeClose();
videodata->ime_active = SDL_FALSE;
break;
}
}
#endif
void VITA_ShowScreenKeyboard(_THIS, SDL_Window *window)
{
SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
SceInt32 res;
#if defined(SDL_VIDEO_VITA_PVR)
SceUInt32 libime_work[SCE_IME_WORK_BUFFER_SIZE / sizeof(SceInt32)];
SceImeParam param;
sceImeParamInit(&param);
SDL_memset(libime_out, 0, ((SCE_IME_MAX_PREEDIT_LENGTH + SCE_IME_MAX_TEXT_LENGTH + 1) * sizeof(SceWChar16)));
param.supportedLanguages = SCE_IME_LANGUAGE_ENGLISH_US;
param.languagesForced = SCE_FALSE;
param.type = SCE_IME_TYPE_DEFAULT;
param.option = SCE_IME_OPTION_NO_ASSISTANCE;
param.inputTextBuffer = libime_out;
param.maxTextLength = SCE_IME_MAX_TEXT_LENGTH;
param.handler = VITA_ImeEventHandler;
param.filter = NULL;
param.initialText = (SceWChar16 *)libime_initval;
param.arg = videodata;
param.work = libime_work;
res = sceImeOpen(&param);
if (res < 0) {
SDL_SetError("Failed to init IME");
return;
}
#else
SceWChar16 *title = u"";
SceWChar16 *text = u"";
SceImeDialogParam param;
sceImeDialogParamInit(&param);
param.supportedLanguages = 0;
param.languagesForced = SCE_FALSE;
param.type = SCE_IME_TYPE_DEFAULT;
param.option = 0;
param.textBoxMode = SCE_IME_DIALOG_TEXTBOX_MODE_WITH_CLEAR;
param.maxTextLength = SCE_IME_DIALOG_MAX_TEXT_LENGTH;
param.title = title;
param.initialText = text;
param.inputTextBuffer = videodata->ime_buffer;
res = sceImeDialogInit(&param);
if (res < 0) {
SDL_SetError("Failed to init IME dialog");
return;
}
#endif
videodata->ime_active = SDL_TRUE;
}
void VITA_HideScreenKeyboard(_THIS, SDL_Window *window)
{
#if !defined(SDL_VIDEO_VITA_PVR)
SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
SceCommonDialogStatus dialogStatus = sceImeDialogGetStatus();
switch (dialogStatus) {
default:
case SCE_COMMON_DIALOG_STATUS_NONE:
case SCE_COMMON_DIALOG_STATUS_RUNNING:
break;
case SCE_COMMON_DIALOG_STATUS_FINISHED:
sceImeDialogTerm();
break;
}
videodata->ime_active = SDL_FALSE;
#endif
}
SDL_bool VITA_IsScreenKeyboardShown(_THIS, SDL_Window *window)
{
#if defined(SDL_VIDEO_VITA_PVR)
SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
return videodata->ime_active;
#else
SceCommonDialogStatus dialogStatus = sceImeDialogGetStatus();
return (dialogStatus == SCE_COMMON_DIALOG_STATUS_RUNNING);
#endif
}
void VITA_PumpEvents(_THIS)
{
#if !defined(SDL_VIDEO_VITA_PVR)
SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
#endif
if (_this->suspend_screensaver) {
// cancel all idle timers to prevent vita going to sleep
sceKernelPowerTick(SCE_KERNEL_POWER_TICK_DEFAULT);
}
VITA_PollTouch();
VITA_PollKeyboard();
VITA_PollMouse();
#if !defined(SDL_VIDEO_VITA_PVR)
if (videodata->ime_active == SDL_TRUE) {
// update IME status. Terminate, if finished
SceCommonDialogStatus dialogStatus = sceImeDialogGetStatus();
@@ -449,6 +593,7 @@ void VITA_PumpEvents(_THIS)
}
}
#endif
}
#endif /* SDL_VIDEO_DRIVER_VITA */

View File

@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2015 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2021 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
@@ -24,10 +24,12 @@
#include "../../SDL_internal.h"
#include "../SDL_sysvideo.h"
#include "../SDL_egl_c.h"
#include <psp2/types.h>
#include <psp2/display.h>
#include <psp2/ime_dialog.h>
#include <psp2/sysmodule.h>
typedef struct SDL_VideoData
{
@@ -36,7 +38,6 @@ typedef struct SDL_VideoData
SceWChar16 ime_buffer[SCE_IME_DIALOG_MAX_TEXT_LENGTH];
SDL_bool ime_active;
} SDL_VideoData;
@@ -51,7 +52,10 @@ typedef struct SDL_WindowData
SDL_bool uses_gles;
SceUID buffer_uid;
void* buffer;
#if defined(SDL_VIDEO_VITA_PVR)
EGLSurface egl_surface;
EGLContext egl_context;
#endif
} SDL_WindowData;
extern SDL_Window * Vita_Window;

View File

@@ -24,6 +24,7 @@
#include "SDL_waylanddatamanager.h"
#include "SDL_waylandevents_c.h"
#include "SDL_waylandclipboard.h"
int
Wayland_SetClipboardText(_THIS, const char *text)

View File

@@ -50,7 +50,7 @@ write_pipe(int fd, const void* buffer, size_t total_length, size_t *pos)
sigset_t old_sig_set;
struct timespec zerotime = {0};
ready = SDL_IOReady(fd, SDL_TRUE, PIPE_MS_TIMEOUT);
ready = SDL_IOReady(fd, SDL_IOR_WRITE, PIPE_MS_TIMEOUT);
sigemptyset(&sig_set);
sigaddset(&sig_set, SIGPIPE);
@@ -96,7 +96,7 @@ read_pipe(int fd, void** buffer, size_t* total_length, SDL_bool null_terminate)
ssize_t bytes_read = 0;
size_t pos = 0;
ready = SDL_IOReady(fd, SDL_FALSE, PIPE_MS_TIMEOUT);
ready = SDL_IOReady(fd, SDL_IOR_READ, PIPE_MS_TIMEOUT);
if (ready == 0) {
bytes_read = SDL_SetError("Pipe timeout");
@@ -396,8 +396,9 @@ Wayland_data_device_clear_selection(SDL_WaylandDataDevice *data_device)
if (data_device == NULL || data_device->data_device == NULL) {
status = SDL_SetError("Invalid Data Device");
} else if (data_device->selection_source != 0) {
} else if (data_device->selection_source != NULL) {
wl_data_device_set_selection(data_device->data_device, NULL, 0);
Wayland_data_source_destroy(data_device->selection_source);
data_device->selection_source = NULL;
}
return status;
@@ -444,6 +445,9 @@ Wayland_data_device_set_selection(SDL_WaylandDataDevice *data_device,
source->source,
data_device->selection_serial);
}
if (data_device->selection_source != NULL) {
Wayland_data_source_destroy(data_device->selection_source);
}
data_device->selection_source = source;
}
}

View File

@@ -140,6 +140,7 @@ void SDL_WAYLAND_UnloadSymbols(void);
#define libdecor_frame_is_floating (*WAYLAND_libdecor_frame_is_floating)
#define libdecor_frame_set_parent (*WAYLAND_libdecor_frame_set_parent)
#define libdecor_frame_get_xdg_surface (*WAYLAND_libdecor_frame_get_xdg_surface)
#define libdecor_frame_get_xdg_toplevel (*WAYLAND_libdecor_frame_get_xdg_toplevel)
#define libdecor_frame_map (*WAYLAND_libdecor_frame_map)
#define libdecor_state_new (*WAYLAND_libdecor_state_new)
#define libdecor_state_free (*WAYLAND_libdecor_state_free)

View File

@@ -58,8 +58,10 @@
#include <sys/mman.h>
#include <poll.h>
#include <unistd.h>
#include <errno.h>
#include <xkbcommon/xkbcommon.h>
#include <xkbcommon/xkbcommon-compose.h>
#include "../../events/imKStoUCS.h"
/* Weston uses a ratio of 10 units per scroll tick */
#define WAYLAND_WHEEL_AXIS_UNIT 10
@@ -168,12 +170,13 @@ touch_surface(SDL_TouchID id)
return NULL;
}
/* Returns the time till next repeat, or 0 if no key is down. */
static void
/* Returns SDL_TRUE if a key repeat event was due */
static SDL_bool
keyboard_repeat_handle(SDL_WaylandKeyboardRepeat* repeat_info, uint32_t now)
{
SDL_bool ret = SDL_FALSE;
if (!repeat_info->is_key_down || !repeat_info->is_initialized) {
return;
return ret;
}
while (repeat_info->next_repeat_ms <= now) {
if (repeat_info->scancode != SDL_SCANCODE_UNKNOWN) {
@@ -183,7 +186,9 @@ keyboard_repeat_handle(SDL_WaylandKeyboardRepeat* repeat_info, uint32_t now)
SDL_SendKeyboardText(repeat_info->text);
}
repeat_info->next_repeat_ms += 1000 / repeat_info->repeat_rate;
ret = SDL_TRUE;
}
return ret;
}
static void
@@ -210,6 +215,90 @@ keyboard_repeat_set(SDL_WaylandKeyboardRepeat* repeat_info,
}
}
void
Wayland_SendWakeupEvent(_THIS, SDL_Window *window)
{
SDL_VideoData *d = _this->driverdata;
/* TODO: Maybe use a pipe to avoid the compositor roundtrip? */
wl_display_sync(d->display);
WAYLAND_wl_display_flush(d->display);
}
int
Wayland_WaitEventTimeout(_THIS, int timeout)
{
SDL_VideoData *d = _this->driverdata;
struct SDL_WaylandInput *input = d->input;
SDL_bool key_repeat_active = SDL_FALSE;
WAYLAND_wl_display_flush(d->display);
#ifdef SDL_USE_IME
if (d->text_input_manager == NULL && SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE) {
SDL_IME_PumpEvents();
}
#endif
/* If key repeat is active, we'll need to cap our maximum wait time to handle repeats */
if (input && input->keyboard_repeat.is_initialized && input->keyboard_repeat.is_key_down) {
uint32_t now = SDL_GetTicks();
if (keyboard_repeat_handle(&input->keyboard_repeat, now)) {
/* A repeat key event was already due */
return 1;
} else {
uint32_t next_repeat_wait_time = (input->keyboard_repeat.next_repeat_ms - now) + 1;
if (timeout >= 0) {
timeout = SDL_min(timeout, next_repeat_wait_time);
} else {
timeout = next_repeat_wait_time;
}
key_repeat_active = SDL_TRUE;
}
}
/* wl_display_prepare_read() will return -1 if the default queue is not empty.
* If the default queue is empty, it will prepare us for our SDL_IOReady() call. */
if (WAYLAND_wl_display_prepare_read(d->display) == 0) {
/* Use SDL_IOR_NO_RETRY to ensure SIGINT will break us out of our wait */
int err = SDL_IOReady(WAYLAND_wl_display_get_fd(d->display), SDL_IOR_READ | SDL_IOR_NO_RETRY, timeout);
if (err > 0) {
/* There are new events available to read */
WAYLAND_wl_display_read_events(d->display);
WAYLAND_wl_display_dispatch_pending(d->display);
return 1;
} else if (err == 0) {
/* No events available within the timeout */
WAYLAND_wl_display_cancel_read(d->display);
/* If key repeat is active, we might have woken up to generate a key event */
if (key_repeat_active) {
uint32_t now = SDL_GetTicks();
if (keyboard_repeat_handle(&input->keyboard_repeat, now)) {
return 1;
}
}
return 0;
} else {
/* Error returned from poll()/select() */
WAYLAND_wl_display_cancel_read(d->display);
if (errno == EINTR) {
/* If the wait was interrupted by a signal, we may have generated a
* SDL_QUIT event. Let the caller know to call SDL_PumpEvents(). */
return 1;
} else {
return err;
}
}
} else {
/* We already had pending events */
WAYLAND_wl_display_dispatch_pending(d->display);
return 1;
}
}
void
Wayland_PumpEvents(_THIS)
{
@@ -230,11 +319,19 @@ Wayland_PumpEvents(_THIS)
keyboard_repeat_handle(&input->keyboard_repeat, now);
}
if (SDL_IOReady(WAYLAND_wl_display_get_fd(d->display), SDL_FALSE, 0)) {
err = WAYLAND_wl_display_dispatch(d->display);
} else {
err = WAYLAND_wl_display_dispatch_pending(d->display);
/* wl_display_prepare_read() will return -1 if the default queue is not empty.
* If the default queue is empty, it will prepare us for our SDL_IOReady() call. */
if (WAYLAND_wl_display_prepare_read(d->display) == 0) {
if (SDL_IOReady(WAYLAND_wl_display_get_fd(d->display), SDL_IOR_READ, 0) > 0) {
WAYLAND_wl_display_read_events(d->display);
} else {
WAYLAND_wl_display_cancel_read(d->display);
}
}
/* Dispatch any pre-existing pending events or new events we may have read */
err = WAYLAND_wl_display_dispatch_pending(d->display);
if (err == -1 && !d->display_disconnected) {
/* Something has failed with the Wayland connection -- for example,
* the compositor may have shut down and closed its end of the socket,
@@ -652,7 +749,8 @@ keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
uint32_t format, int fd, uint32_t size)
{
struct SDL_WaylandInput *input = data;
char *map_str, *locale;
char *map_str;
const char *locale;
if (!data) {
close(fd);
@@ -793,7 +891,7 @@ keyboard_input_get_text(char text[8], const struct SDL_WaylandInput *input, uint
}
#endif
if (WAYLAND_xkb_compose_state_feed(input->xkb.compose_state, sym) == XKB_COMPOSE_FEED_ACCEPTED) {
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:
*handled_by_ime = SDL_TRUE;
@@ -839,7 +937,7 @@ keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
}
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
if (has_text) {
if (has_text && !(SDL_GetModState() & KMOD_CTRL)) {
Wayland_data_device_set_serial(input->data_device, serial);
if (!handled_by_ime) {
SDL_SendKeyboardText(text);
@@ -870,7 +968,7 @@ Wayland_keymap_iter(struct xkb_keymap *keymap, xkb_keycode_t key, void *data)
}
if (WAYLAND_xkb_keymap_key_get_syms_by_level(keymap, key, sdlKeymap->layout, 0, &syms) > 0) {
uint32_t keycode = WAYLAND_xkb_keysym_to_utf32(syms[0]);
uint32_t keycode = SDL_KeySymToUcs4(syms[0]);
if (keycode) {
sdlKeymap->keymap[scancode] = keycode;
} else {
@@ -925,7 +1023,7 @@ keyboard_handle_repeat_info(void *data, struct wl_keyboard *wl_keyboard,
int32_t rate, int32_t delay)
{
struct SDL_WaylandInput *input = data;
input->keyboard_repeat.repeat_rate = SDL_max(0, SDL_min(rate, 1000));
input->keyboard_repeat.repeat_rate = SDL_clamp(rate, 0, 1000);
input->keyboard_repeat.repeat_delay = delay;
input->keyboard_repeat.is_initialized = SDL_TRUE;
}
@@ -1573,11 +1671,12 @@ lock_pointer_to_window(SDL_Window *window,
w->locked_pointer = locked_pointer;
}
static void pointer_confine_destroy(struct SDL_WaylandInput *input)
static void pointer_confine_destroy(SDL_Window *window)
{
if (input->confined_pointer) {
zwp_confined_pointer_v1_destroy(input->confined_pointer);
input->confined_pointer = NULL;
SDL_WindowData *w = window->driverdata;
if (w->confined_pointer) {
zwp_confined_pointer_v1_destroy(w->confined_pointer);
w->confined_pointer = NULL;
}
}
@@ -1599,7 +1698,8 @@ int Wayland_input_lock_pointer(struct SDL_WaylandInput *input)
/* If we have a pointer confine active, we must destroy it here because
* creating a locked pointer otherwise would be a protocol error. */
pointer_confine_destroy(input);
for (window = vd->windows; window; window = window->next)
pointer_confine_destroy(window);
if (!input->relative_pointer) {
relative_pointer =
@@ -1639,8 +1739,8 @@ int Wayland_input_unlock_pointer(struct SDL_WaylandInput *input)
d->relative_mouse_mode = 0;
if (input->confined_pointer_window)
Wayland_input_confine_pointer(input->confined_pointer_window, input);
for (window = vd->windows; window; window = window->next)
Wayland_input_confine_pointer(input, window);
return 0;
}
@@ -1662,11 +1762,12 @@ static const struct zwp_confined_pointer_v1_listener confined_pointer_listener =
confined_pointer_unconfined,
};
int Wayland_input_confine_pointer(SDL_Window *window, struct SDL_WaylandInput *input)
int Wayland_input_confine_pointer(struct SDL_WaylandInput *input, SDL_Window *window)
{
SDL_WindowData *w = window->driverdata;
SDL_VideoData *d = input->display;
struct zwp_confined_pointer_v1 *confined_pointer;
struct wl_region *confine_rect;
if (!d->pointer_constraints)
return -1;
@@ -1676,34 +1777,45 @@ int Wayland_input_confine_pointer(SDL_Window *window, struct SDL_WaylandInput *i
/* A confine may already be active, in which case we should destroy it and
* create a new one. */
if (input->confined_pointer)
Wayland_input_unconfine_pointer(input);
input->confined_pointer_window = window;
pointer_confine_destroy(window);
/* We cannot create a confine if the pointer is already locked. Defer until
* the pointer is unlocked. */
if (d->relative_mouse_mode)
return 0;
if (SDL_RectEmpty(&window->mouse_rect)) {
confine_rect = NULL;
} else {
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);
}
confined_pointer =
zwp_pointer_constraints_v1_confine_pointer(d->pointer_constraints,
w->surface,
input->pointer,
NULL,
confine_rect,
ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);
zwp_confined_pointer_v1_add_listener(confined_pointer,
&confined_pointer_listener,
window);
input->confined_pointer = confined_pointer;
if (confine_rect != NULL) {
wl_region_destroy(confine_rect);
}
w->confined_pointer = confined_pointer;
return 0;
}
int Wayland_input_unconfine_pointer(struct SDL_WaylandInput *input)
int Wayland_input_unconfine_pointer(struct SDL_WaylandInput *input, SDL_Window *window)
{
pointer_confine_destroy(input);
input->confined_pointer_window = NULL;
pointer_confine_destroy(window);
return 0;
}

View File

@@ -50,8 +50,6 @@ struct SDL_WaylandInput {
SDL_WaylandDataDevice *data_device;
SDL_WaylandTextInput *text_input;
struct zwp_relative_pointer_v1 *relative_pointer;
struct zwp_confined_pointer_v1 *confined_pointer;
SDL_Window *confined_pointer_window;
SDL_WindowData *pointer_focus;
SDL_WindowData *keyboard_focus;
uint32_t pointer_enter_serial;
@@ -83,6 +81,8 @@ struct SDL_WaylandInput {
};
extern void Wayland_PumpEvents(_THIS);
extern void Wayland_SendWakeupEvent(_THIS, SDL_Window *window);
extern int Wayland_WaitEventTimeout(_THIS, int timeout);
extern void Wayland_add_data_device_manager(SDL_VideoData *d, uint32_t id, uint32_t version);
extern void Wayland_add_text_input_manager(SDL_VideoData *d, uint32_t id, uint32_t version);
@@ -96,8 +96,8 @@ extern void Wayland_display_destroy_pointer_constraints(SDL_VideoData *d);
extern int Wayland_input_lock_pointer(struct SDL_WaylandInput *input);
extern int Wayland_input_unlock_pointer(struct SDL_WaylandInput *input);
extern int Wayland_input_confine_pointer(SDL_Window *window, struct SDL_WaylandInput *input);
extern int Wayland_input_unconfine_pointer(struct SDL_WaylandInput *input);
extern int Wayland_input_confine_pointer(struct SDL_WaylandInput *input, SDL_Window *window);
extern int Wayland_input_unconfine_pointer(struct SDL_WaylandInput *input, SDL_Window *window);
extern void Wayland_display_add_relative_pointer_manager(SDL_VideoData *d, uint32_t id);
extern void Wayland_display_destroy_relative_pointer_manager(SDL_VideoData *d);

View File

@@ -140,8 +140,13 @@ Wayland_SetTextInputRect(_THIS, SDL_Rect *rect)
SDL_bool
Wayland_HasScreenKeyboardSupport(_THIS)
{
/* In reality we just want to return true when the screen keyboard is the
* _only_ way to get text input. So, in addition to checking for the text
* input protocol, make sure we don't have any physical keyboards either.
*/
SDL_VideoData *driverdata = _this->driverdata;
return (driverdata->text_input_manager != NULL);
return (driverdata->input->keyboard == NULL &&
driverdata->text_input_manager != NULL);
}
#endif /* SDL_VIDEO_DRIVER_WAYLAND */

View File

@@ -31,6 +31,8 @@
#include <string.h> /* strerr */
#include <errno.h>
#include "SDL_waylandmessagebox.h"
#define MAX_BUTTONS 8 /* Maximum number of buttons supported */
int
@@ -186,7 +188,6 @@ Wayland_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
return SDL_SetError("Waiting on zenity failed: %s", strerror(errno));
}
}
return 0;
}
#endif /* SDL_VIDEO_DRIVER_WAYLAND */

View File

@@ -34,10 +34,11 @@
#include "SDL_mouse.h"
#include "../../events/SDL_mouse_c.h"
#include "SDL_waylandvideo.h"
#include "../SDL_pixels_c.h"
#include "SDL_waylandevents_c.h"
#include "wayland-cursor.h"
#include "SDL_waylandmouse.h"
typedef struct {
@@ -47,11 +48,120 @@ typedef struct {
int hot_x, hot_y;
int w, h;
/* Either a preloaded cursor, or one we created ourselves */
struct wl_cursor *cursor;
/* shm_data is non-NULL for custom cursors.
* When shm_data is NULL, system_cursor must be valid
*/
SDL_SystemCursor system_cursor;
void *shm_data;
} Wayland_CursorData;
static SDL_bool
wayland_get_system_cursor(SDL_VideoData *vdata, Wayland_CursorData *cdata, float *scale)
{
struct wl_cursor_theme *theme = NULL;
struct wl_cursor *cursor;
char *xcursor_size;
int size = 0;
SDL_Window *focus;
SDL_WindowData *focusdata;
int i;
/* FIXME: We need to be able to query the cursor size from the desktop at
* some point! For a while this was 32, but when testing on real desktops it
* seems like most of them default to 24. We'll need a protocol to get this
* for real, but for now this is a pretty safe bet.
* -flibit
*/
xcursor_size = SDL_getenv("XCURSOR_SIZE");
if (xcursor_size != NULL) {
size = SDL_atoi(xcursor_size);
}
if (size <= 0) {
size = 24;
}
/* First, find the appropriate theme based on the current scale... */
focus = SDL_GetMouse()->focus;
if (focus == NULL) {
/* Nothing to see here, bail. */
return SDL_FALSE;
}
focusdata = focus->driverdata;
*scale = focusdata->scale_factor;
size *= focusdata->scale_factor;
for (i = 0; i < vdata->num_cursor_themes; i += 1) {
if (vdata->cursor_themes[i].size == size) {
theme = vdata->cursor_themes[i].theme;
break;
}
}
if (theme == NULL) {
vdata->cursor_themes = SDL_realloc(vdata->cursor_themes,
sizeof(SDL_WaylandCursorTheme) * (vdata->num_cursor_themes + 1));
if (vdata->cursor_themes == NULL) {
SDL_OutOfMemory();
return SDL_FALSE;
}
theme = WAYLAND_wl_cursor_theme_load(SDL_getenv("XCURSOR_THEME"), size, vdata->shm);
vdata->cursor_themes[vdata->num_cursor_themes].size = size;
vdata->cursor_themes[vdata->num_cursor_themes++].theme = theme;
}
/* Next, find the cursor from the theme... */
switch(cdata->system_cursor)
{
case SDL_SYSTEM_CURSOR_ARROW:
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "left_ptr");
break;
case SDL_SYSTEM_CURSOR_IBEAM:
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "xterm");
break;
case SDL_SYSTEM_CURSOR_WAIT:
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "watch");
break;
case SDL_SYSTEM_CURSOR_CROSSHAIR:
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "hand1");
break;
case SDL_SYSTEM_CURSOR_WAITARROW:
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "watch");
break;
case SDL_SYSTEM_CURSOR_SIZENWSE:
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "hand1");
break;
case SDL_SYSTEM_CURSOR_SIZENESW:
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "hand1");
break;
case SDL_SYSTEM_CURSOR_SIZEWE:
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "hand1");
break;
case SDL_SYSTEM_CURSOR_SIZENS:
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "hand1");
break;
case SDL_SYSTEM_CURSOR_SIZEALL:
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "hand1");
break;
case SDL_SYSTEM_CURSOR_NO:
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "xterm");
break;
case SDL_SYSTEM_CURSOR_HAND:
cursor = WAYLAND_wl_cursor_theme_get_cursor(theme, "hand1");
break;
default:
SDL_assert(0);
return SDL_FALSE;
}
/* ... Set the cursor data, finally. */
cdata->buffer = WAYLAND_wl_cursor_image_get_buffer(cursor->images[0]);
cdata->hot_x = cursor->images[0]->hotspot_x;
cdata->hot_y = cursor->images[0]->hotspot_y;
cdata->w = cursor->images[0]->width;
cdata->h = cursor->images[0]->height;
return SDL_TRUE;
}
static int
wayland_create_tmp_file(off_t size)
{
@@ -158,10 +268,6 @@ Wayland_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
}
cursor->driverdata = (void *) data;
/* Assume ARGB8888 */
SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888);
SDL_assert(surface->pitch == surface->w * 4);
/* Allocate shared memory buffer for this cursor */
if (create_buffer_from_shm (data,
surface->w,
@@ -173,9 +279,10 @@ Wayland_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
return NULL;
}
SDL_memcpy(data->shm_data,
surface->pixels,
surface->h * surface->pitch);
/* Wayland requires premultiplied alpha for its surfaces. */
SDL_PremultiplyAlpha(surface->w, surface->h,
surface->format->format, surface->pixels, surface->pitch,
SDL_PIXELFORMAT_ARGB8888, data->shm_data, surface->w * 4);
data->surface = wl_compositor_create_surface(wd->compositor);
wl_surface_set_user_data(data->surface, NULL);
@@ -192,30 +299,30 @@ Wayland_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
}
static SDL_Cursor *
CreateCursorFromWlCursor(SDL_VideoData *d, struct wl_cursor *wlcursor)
Wayland_CreateSystemCursor(SDL_SystemCursor id)
{
SDL_VideoData *data = SDL_GetVideoDevice()->driverdata;
SDL_Cursor *cursor;
cursor = SDL_calloc(1, sizeof (*cursor));
if (cursor) {
Wayland_CursorData *data = SDL_calloc (1, sizeof (Wayland_CursorData));
if (!data) {
Wayland_CursorData *cdata = SDL_calloc (1, sizeof (Wayland_CursorData));
if (!cdata) {
SDL_OutOfMemory();
SDL_free(cursor);
return NULL;
}
cursor->driverdata = (void *) data;
cursor->driverdata = (void *) cdata;
data->buffer = WAYLAND_wl_cursor_image_get_buffer(wlcursor->images[0]);
data->surface = wl_compositor_create_surface(d->compositor);
wl_surface_set_user_data(data->surface, NULL);
data->hot_x = wlcursor->images[0]->hotspot_x;
data->hot_y = wlcursor->images[0]->hotspot_y;
data->w = wlcursor->images[0]->width;
data->h = wlcursor->images[0]->height;
data->cursor= wlcursor;
cdata->surface = wl_compositor_create_surface(data->compositor);
wl_surface_set_user_data(cdata->surface, NULL);
/* Note that we can't actually set any other cursor properties, as this
* is output-specific. See wayland_get_system_cursor for the rest!
*/
cdata->system_cursor = id;
} else {
SDL_OutOfMemory ();
SDL_OutOfMemory();
}
return cursor;
@@ -224,66 +331,7 @@ CreateCursorFromWlCursor(SDL_VideoData *d, struct wl_cursor *wlcursor)
static SDL_Cursor *
Wayland_CreateDefaultCursor()
{
SDL_VideoDevice *device = SDL_GetVideoDevice();
SDL_VideoData *data = device->driverdata;
return CreateCursorFromWlCursor (data,
WAYLAND_wl_cursor_theme_get_cursor(data->cursor_theme,
"left_ptr"));
}
static SDL_Cursor *
Wayland_CreateSystemCursor(SDL_SystemCursor id)
{
SDL_VideoDevice *vd = SDL_GetVideoDevice();
SDL_VideoData *d = vd->driverdata;
struct wl_cursor *cursor = NULL;
switch(id)
{
default:
SDL_assert(0);
return NULL;
case SDL_SYSTEM_CURSOR_ARROW:
cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "left_ptr");
break;
case SDL_SYSTEM_CURSOR_IBEAM:
cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "xterm");
break;
case SDL_SYSTEM_CURSOR_WAIT:
cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "watch");
break;
case SDL_SYSTEM_CURSOR_CROSSHAIR:
cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "hand1");
break;
case SDL_SYSTEM_CURSOR_WAITARROW:
cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "watch");
break;
case SDL_SYSTEM_CURSOR_SIZENWSE:
cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "hand1");
break;
case SDL_SYSTEM_CURSOR_SIZENESW:
cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "hand1");
break;
case SDL_SYSTEM_CURSOR_SIZEWE:
cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "hand1");
break;
case SDL_SYSTEM_CURSOR_SIZENS:
cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "hand1");
break;
case SDL_SYSTEM_CURSOR_SIZEALL:
cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "hand1");
break;
case SDL_SYSTEM_CURSOR_NO:
cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "xterm");
break;
case SDL_SYSTEM_CURSOR_HAND:
cursor = WAYLAND_wl_cursor_theme_get_cursor(d->cursor_theme, "hand1");
break;
}
return CreateCursorFromWlCursor(d, cursor);
return Wayland_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
}
static void
@@ -300,14 +348,14 @@ Wayland_FreeCursor(SDL_Cursor *cursor)
if (!d)
return;
if (d->buffer && !d->cursor)
if (d->buffer && d->shm_data)
wl_buffer_destroy(d->buffer);
if (d->surface)
wl_surface_destroy(d->surface);
/* Not sure what's meant to happen to shm_data */
SDL_free (cursor->driverdata);
SDL_free(cursor->driverdata);
SDL_free(cursor);
}
@@ -317,8 +365,8 @@ Wayland_ShowCursor(SDL_Cursor *cursor)
SDL_VideoDevice *vd = SDL_GetVideoDevice();
SDL_VideoData *d = vd->driverdata;
struct SDL_WaylandInput *input = d->input;
struct wl_pointer *pointer = d->pointer;
float scale = 1.0f;
if (!pointer)
return -1;
@@ -327,22 +375,26 @@ Wayland_ShowCursor(SDL_Cursor *cursor)
{
Wayland_CursorData *data = cursor->driverdata;
wl_pointer_set_cursor (pointer,
input->pointer_enter_serial,
data->surface,
data->hot_x,
data->hot_y);
/* TODO: High-DPI custom cursors? -flibit */
if (data->shm_data == NULL) {
if (!wayland_get_system_cursor(d, data, &scale)) {
return -1;
}
}
wl_surface_set_buffer_scale(data->surface, scale);
wl_pointer_set_cursor(pointer,
input->pointer_enter_serial,
data->surface,
data->hot_x / scale,
data->hot_y / scale);
wl_surface_attach(data->surface, data->buffer, 0, 0);
wl_surface_damage(data->surface, 0, 0, data->w, data->h);
wl_surface_commit(data->surface);
}
else
{
wl_pointer_set_cursor (pointer,
input->pointer_enter_serial,
NULL,
0,
0);
wl_pointer_set_cursor(pointer, input->pointer_enter_serial, NULL, 0, 0);
}
return 0;
@@ -389,10 +441,15 @@ Wayland_InitMouse(void)
}
void
Wayland_FiniMouse(void)
Wayland_FiniMouse(SDL_VideoData *data)
{
/* This effectively assumes that nobody else
* touches SDL_Mouse which is effectively
* a singleton */
int i;
for (i = 0; i < data->num_cursor_themes; i += 1) {
WAYLAND_wl_cursor_theme_destroy(data->cursor_themes[i].theme);
}
SDL_free(data->cursor_themes);
}
#endif /* SDL_VIDEO_DRIVER_WAYLAND */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -26,6 +26,6 @@
#if SDL_VIDEO_DRIVER_WAYLAND
extern void Wayland_InitMouse(void);
extern void Wayland_FiniMouse(void);
extern void Wayland_FiniMouse(SDL_VideoData *data);
#endif

View File

@@ -127,31 +127,43 @@ Wayland_GLES_SwapWindow(_THIS, SDL_Window *window)
/* Control swap interval ourselves. See comments on Wayland_GLES_SetSwapInterval */
if (swap_interval != 0) {
struct wl_display *display = ((SDL_VideoData *)_this->driverdata)->display;
SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
struct wl_display *display = videodata->display;
SDL_VideoDisplay *sdldisplay = SDL_GetDisplayForWindow(window);
const Uint32 max_wait = SDL_GetTicks() + (10000 / sdldisplay->current_mode.refresh_rate); /* ~10 frames, so we'll progress even if throttled to zero. */
/* ~10 frames (or 1 sec), so we'll progress even if throttled to zero. */
const Uint32 max_wait = SDL_GetTicks() + (sdldisplay->current_mode.refresh_rate ?
(10000 / sdldisplay->current_mode.refresh_rate) : 1000);
while (SDL_AtomicGet(&data->swap_interval_ready) == 0) {
Uint32 now;
/* !!! FIXME: this is just the crucial piece of Wayland_PumpEvents */
WAYLAND_wl_display_flush(display);
if (WAYLAND_wl_display_dispatch_pending(display) > 0) {
/* We dispatched some pending events. Check if the frame callback happened. */
/* wl_display_prepare_read_queue() will return -1 if the event queue is not empty.
* If the event queue is empty, it will prepare us for our SDL_IOReady() call. */
if (WAYLAND_wl_display_prepare_read_queue(display, data->frame_event_queue) != 0) {
/* We have some pending events. Check if the frame callback happened. */
WAYLAND_wl_display_dispatch_queue_pending(display, data->frame_event_queue);
continue;
}
/* Beyond this point, we must either call wl_display_cancel_read() or wl_display_read_events() */
now = SDL_GetTicks();
if (SDL_TICKS_PASSED(now, max_wait)) {
/* Timeout expired */
/* Timeout expired. Cancel the read. */
WAYLAND_wl_display_cancel_read(display);
break;
}
if (SDL_IOReady(WAYLAND_wl_display_get_fd(display), SDL_FALSE, max_wait - now) <= 0) {
/* Error or timeout expired without any events for us */
if (SDL_IOReady(WAYLAND_wl_display_get_fd(display), SDL_IOR_READ, max_wait - now) <= 0) {
/* Error or timeout expired without any events for us. Cancel the read. */
WAYLAND_wl_display_cancel_read(display);
break;
}
WAYLAND_wl_display_dispatch(display);
/* We have events. Read and dispatch them. */
WAYLAND_wl_display_read_events(display);
WAYLAND_wl_display_dispatch_queue_pending(display, data->frame_event_queue);
}
SDL_AtomicSet(&data->swap_interval_ready, 0);
}

View File

@@ -46,6 +46,8 @@ SDL_WAYLAND_SYM(uint32_t, wl_proxy_get_version, (struct wl_proxy *))
SDL_WAYLAND_SYM(uint32_t, wl_proxy_get_id, (struct wl_proxy *))
SDL_WAYLAND_SYM(const char *, wl_proxy_get_class, (struct wl_proxy *))
SDL_WAYLAND_SYM(void, wl_proxy_set_queue, (struct wl_proxy *, struct wl_event_queue *))
SDL_WAYLAND_SYM(void *, wl_proxy_create_wrapper, (void *))
SDL_WAYLAND_SYM(void, wl_proxy_wrapper_destroy, (void *))
SDL_WAYLAND_SYM(struct wl_display *, wl_display_connect, (const char *))
SDL_WAYLAND_SYM(struct wl_display *, wl_display_connect_to_fd, (int))
SDL_WAYLAND_SYM(void, wl_display_disconnect, (struct wl_display *))
@@ -54,10 +56,15 @@ SDL_WAYLAND_SYM(int, wl_display_dispatch, (struct wl_display *))
SDL_WAYLAND_SYM(int, wl_display_dispatch_queue, (struct wl_display *, struct wl_event_queue *))
SDL_WAYLAND_SYM(int, wl_display_dispatch_queue_pending, (struct wl_display *, struct wl_event_queue *))
SDL_WAYLAND_SYM(int, wl_display_dispatch_pending, (struct wl_display *))
SDL_WAYLAND_SYM(int, wl_display_prepare_read, (struct wl_display *))
SDL_WAYLAND_SYM(int, wl_display_prepare_read_queue, (struct wl_display *, struct wl_event_queue *))
SDL_WAYLAND_SYM(int, wl_display_read_events, (struct wl_display *))
SDL_WAYLAND_SYM(void, wl_display_cancel_read, (struct wl_display *))
SDL_WAYLAND_SYM(int, wl_display_get_error, (struct wl_display *))
SDL_WAYLAND_SYM(int, wl_display_flush, (struct wl_display *))
SDL_WAYLAND_SYM(int, wl_display_roundtrip, (struct wl_display *))
SDL_WAYLAND_SYM(struct wl_event_queue *, wl_display_create_queue, (struct wl_display *))
SDL_WAYLAND_SYM(void, wl_event_queue_destroy, (struct wl_event_queue *))
SDL_WAYLAND_SYM(void, wl_log_set_handler_client, (wl_log_func_t))
SDL_WAYLAND_SYM(void, wl_list_init, (struct wl_list *))
SDL_WAYLAND_SYM(void, wl_list_insert, (struct wl_list *, struct wl_list *) )
@@ -182,6 +189,7 @@ SDL_WAYLAND_SYM(bool, libdecor_frame_is_floating, (struct libdecor_frame *))
SDL_WAYLAND_SYM(void, libdecor_frame_set_parent, (struct libdecor_frame *,\
struct libdecor_frame *))
SDL_WAYLAND_SYM(struct xdg_surface *, libdecor_frame_get_xdg_surface, (struct libdecor_frame *))
SDL_WAYLAND_SYM(struct xdg_toplevel *, libdecor_frame_get_xdg_toplevel, (struct libdecor_frame *))
SDL_WAYLAND_SYM(void, libdecor_frame_map, (struct libdecor_frame *))
SDL_WAYLAND_SYM(struct libdecor_state *, libdecor_state_new, (int, int))
SDL_WAYLAND_SYM(void, libdecor_state_free, (struct libdecor_state *))

View File

@@ -169,6 +169,9 @@ Wayland_DeleteDevice(SDL_VideoDevice *device)
WAYLAND_wl_display_flush(data->display);
WAYLAND_wl_display_disconnect(data->display);
}
if (device->wakeup_lock) {
SDL_DestroyMutex(device->wakeup_lock);
}
SDL_free(data);
SDL_free(device);
SDL_WAYLAND_UnloadSymbols();
@@ -199,6 +202,7 @@ Wayland_CreateDevice(int devindex)
return NULL;
}
data->initializing = SDL_TRUE;
data->display = display;
/* Initialize all variables that we clean on shutdown */
@@ -212,6 +216,7 @@ Wayland_CreateDevice(int devindex)
}
device->driverdata = data;
device->wakeup_lock = SDL_CreateMutex();
/* Set the function pointers */
device->VideoInit = Wayland_VideoInit;
@@ -222,6 +227,8 @@ Wayland_CreateDevice(int devindex)
device->SuspendScreenSaver = Wayland_SuspendScreenSaver;
device->PumpEvents = Wayland_PumpEvents;
device->WaitEventTimeout = Wayland_WaitEventTimeout;
device->SendWakeupEvent = Wayland_SendWakeupEvent;
device->GL_SwapWindow = Wayland_GLES_SwapWindow;
device->GL_GetSwapInterval = Wayland_GLES_GetSwapInterval;
@@ -241,6 +248,7 @@ Wayland_CreateDevice(int devindex)
device->SetWindowFullscreen = Wayland_SetWindowFullscreen;
device->MaximizeWindow = Wayland_MaximizeWindow;
device->MinimizeWindow = Wayland_MinimizeWindow;
device->SetWindowMouseRect = Wayland_SetWindowMouseRect;
device->SetWindowMouseGrab = Wayland_SetWindowMouseGrab;
device->SetWindowKeyboardGrab = Wayland_SetWindowKeyboardGrab;
device->RestoreWindow = Wayland_RestoreWindow;
@@ -294,13 +302,60 @@ display_handle_geometry(void *data,
{
SDL_WaylandOutputData *driverdata = data;
SDL_VideoDisplay *display;
int i;
if (driverdata->done) {
/* Clear the wl_output ref so Reset doesn't free it */
display = SDL_GetDisplay(driverdata->index);
for (i = 0; i < display->num_display_modes; i += 1) {
display->display_modes[i].driverdata = NULL;
}
/* Okay, now it's safe to reset */
SDL_ResetDisplayModes(driverdata->index);
/* The display has officially started over. */
driverdata->done = SDL_FALSE;
}
driverdata->x = x;
driverdata->y = y;
driverdata->physical_width = physical_width;
driverdata->physical_height = physical_height;
driverdata->placeholder.name = SDL_strdup(model);
if (driverdata->index == -1) {
driverdata->placeholder.name = SDL_strdup(model);
}
driverdata->transform = transform;
#define TF_CASE(in, out) \
case WL_OUTPUT_TRANSFORM_##in: \
driverdata->orientation = SDL_ORIENTATION_##out; \
break;
if (driverdata->physical_width >= driverdata->physical_height) {
switch (transform) {
TF_CASE(NORMAL, LANDSCAPE)
TF_CASE(90, PORTRAIT)
TF_CASE(180, LANDSCAPE_FLIPPED)
TF_CASE(270, PORTRAIT_FLIPPED)
TF_CASE(FLIPPED, LANDSCAPE_FLIPPED)
TF_CASE(FLIPPED_90, PORTRAIT_FLIPPED)
TF_CASE(FLIPPED_180, LANDSCAPE)
TF_CASE(FLIPPED_270, PORTRAIT)
}
} else {
switch (transform) {
TF_CASE(NORMAL, PORTRAIT)
TF_CASE(90, LANDSCAPE)
TF_CASE(180, PORTRAIT_FLIPPED)
TF_CASE(270, LANDSCAPE_FLIPPED)
TF_CASE(FLIPPED, PORTRAIT_FLIPPED)
TF_CASE(FLIPPED_90, LANDSCAPE_FLIPPED)
TF_CASE(FLIPPED_180, PORTRAIT)
TF_CASE(FLIPPED_270, LANDSCAPE)
}
}
#undef TF_CASE
}
static void
@@ -315,6 +370,7 @@ display_handle_mode(void *data,
SDL_DisplayMode mode;
if (flags & WL_OUTPUT_MODE_CURRENT) {
/* Don't rotate this yet, handle_done will do it later */
driverdata->width = width;
driverdata->height = height;
driverdata->refresh = refresh;
@@ -337,7 +393,11 @@ display_handle_mode(void *data,
}
mode.refresh_rate = refresh / 1000; /* mHz to Hz */
mode.driverdata = driverdata->output;
SDL_AddDisplayMode(&driverdata->placeholder, &mode);
if (driverdata->index > -1) {
SDL_AddDisplayMode(SDL_GetDisplay(driverdata->index), &mode);
} else {
SDL_AddDisplayMode(&driverdata->placeholder, &mode);
}
}
static void
@@ -346,6 +406,7 @@ display_handle_done(void *data,
{
SDL_WaylandOutputData* driverdata = data;
SDL_DisplayMode mode;
SDL_VideoDisplay *dpy;
if (driverdata->done)
return;
@@ -385,13 +446,28 @@ display_handle_done(void *data,
}
mode.refresh_rate = driverdata->refresh / 1000; /* mHz to Hz */
mode.driverdata = driverdata->output;
SDL_AddDisplayMode(&driverdata->placeholder, &mode);
driverdata->placeholder.current_mode = mode;
driverdata->placeholder.desktop_mode = mode;
driverdata->placeholder.driverdata = driverdata;
SDL_AddVideoDisplay(&driverdata->placeholder, SDL_FALSE);
SDL_zero(driverdata->placeholder);
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);
if (driverdata->index == -1) {
/* First time getting display info, create the VideoDisplay */
SDL_bool send_event = driverdata->videodata->initializing ? SDL_FALSE : SDL_TRUE;
driverdata->placeholder.orientation = driverdata->orientation;
driverdata->placeholder.driverdata = driverdata;
driverdata->index = SDL_AddVideoDisplay(&driverdata->placeholder, send_event);
SDL_free(driverdata->placeholder.name);
SDL_zero(driverdata->placeholder);
} else {
SDL_SendDisplayEvent(dpy, SDL_DISPLAYEVENT_ORIENTATION, driverdata->orientation);
}
}
static void
@@ -423,13 +499,45 @@ Wayland_add_display(SDL_VideoData *d, uint32_t id)
}
data = SDL_malloc(sizeof *data);
SDL_zerop(data);
data->videodata = d;
data->output = output;
data->registry_id = id;
data->scale_factor = 1.0;
data->index = -1;
wl_output_add_listener(output, &output_listener, data);
SDL_WAYLAND_register_output(output);
}
static void
Wayland_free_display(uint32_t id)
{
int num_displays = SDL_GetNumVideoDisplays();
SDL_VideoDisplay *display;
SDL_WaylandOutputData *data;
int i;
for (i = 0; i < num_displays; i += 1) {
display = SDL_GetDisplay(i);
data = (SDL_WaylandOutputData *) display->driverdata;
if (data->registry_id == id) {
SDL_DelVideoDisplay(i);
wl_output_destroy(data->output);
SDL_free(data);
/* Update the index for all remaining displays */
num_displays -= 1;
for (; i < num_displays; i += 1) {
display = SDL_GetDisplay(i);
data = (SDL_WaylandOutputData *) display->driverdata;
data->index -= 1;
}
return;
}
}
}
#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
static void
windowmanager_hints(void *data, struct qt_windowmanager *qt_windowmanager,
@@ -494,7 +602,6 @@ display_handle_global(void *data, struct wl_registry *registry, uint32_t id,
xdg_wm_base_add_listener(d->shell.xdg, &shell_listener_xdg, NULL);
} else if (SDL_strcmp(interface, "wl_shm") == 0) {
d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
d->cursor_theme = WAYLAND_wl_cursor_theme_load(NULL, 32, d->shm);
} else if (SDL_strcmp(interface, "zwp_relative_pointer_manager_v1") == 0) {
Wayland_display_add_relative_pointer_manager(d, id);
} else if (SDL_strcmp(interface, "zwp_pointer_constraints_v1") == 0) {
@@ -505,7 +612,7 @@ display_handle_global(void *data, struct wl_registry *registry, uint32_t id,
d->idle_inhibit_manager = wl_registry_bind(d->registry, id, &zwp_idle_inhibit_manager_v1_interface, 1);
} else if (SDL_strcmp(interface, "xdg_activation_v1") == 0) {
d->activation_manager = wl_registry_bind(d->registry, id, &xdg_activation_v1_interface, 1);
} else if (strcmp(interface, "zwp_text_input_manager_v3") == 0) {
} else if (SDL_strcmp(interface, "zwp_text_input_manager_v3") == 0) {
Wayland_add_text_input_manager(d, id, version);
} else if (SDL_strcmp(interface, "wl_data_device_manager") == 0) {
Wayland_add_data_device_manager(d, id, version);
@@ -527,7 +634,11 @@ display_handle_global(void *data, struct wl_registry *registry, uint32_t id,
}
static void
display_remove_global(void *data, struct wl_registry *registry, uint32_t id) {}
display_remove_global(void *data, struct wl_registry *registry, uint32_t id)
{
/* We don't get an interface, just an ID, so assume it's a wl_output :shrug: */
Wayland_free_display(id);
}
static const struct wl_registry_listener registry_listener = {
display_handle_global,
@@ -579,6 +690,8 @@ Wayland_VideoInit(_THIS)
Wayland_InitKeyboard(_this);
data->initializing = SDL_FALSE;
return 0;
}
@@ -617,7 +730,7 @@ Wayland_VideoQuit(_THIS)
SDL_VideoData *data = _this->driverdata;
int i, j;
Wayland_FiniMouse ();
Wayland_FiniMouse(data);
for (i = 0; i < _this->num_displays; ++i) {
SDL_VideoDisplay *display = &_this->displays[i];
@@ -670,9 +783,6 @@ Wayland_VideoQuit(_THIS)
if (data->shm)
wl_shm_destroy(data->shm);
if (data->cursor_theme)
WAYLAND_wl_cursor_theme_destroy(data->cursor_theme);
if (data->shell.xdg)
xdg_wm_base_destroy(data->shell.xdg);

View File

@@ -42,12 +42,19 @@ struct qt_windowmanager;
#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
typedef struct {
struct wl_cursor_theme *theme;
int size;
} SDL_WaylandCursorTheme;
typedef struct {
SDL_bool initializing;
struct wl_display *display;
int display_disconnected;
struct wl_registry *registry;
struct wl_compositor *compositor;
struct wl_shm *shm;
struct wl_cursor_theme *cursor_theme;
SDL_WaylandCursorTheme *cursor_themes;
int num_cursor_themes;
struct wl_pointer *pointer;
struct {
struct xdg_wm_base *xdg;
@@ -83,11 +90,15 @@ typedef struct {
} SDL_VideoData;
typedef struct {
SDL_VideoData *videodata;
struct wl_output *output;
uint32_t registry_id;
float scale_factor;
int x, y, width, height, refresh, transform;
SDL_DisplayOrientation orientation;
int physical_width, physical_height;
float ddpi, hdpi, vdpi;
int index;
SDL_VideoDisplay placeholder;
SDL_bool done;
} SDL_WaylandOutputData;

View File

@@ -146,7 +146,7 @@ handle_surface_frame_done(void *data, struct wl_callback *cb, uint32_t time)
SDL_AtomicSet(&wind->swap_interval_ready, 1); /* mark window as ready to present again. */
/* 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->surface);
wind->frame_callback = wl_surface_frame(wind->frame_surface_wrapper);
wl_callback_destroy(cb);
wl_callback_add_listener(wind->frame_callback, &surface_frame_listener, data);
}
@@ -219,9 +219,15 @@ handle_configure_xdg_toplevel(void *data,
/* Foolishly do what the compositor says here. If it's wrong, don't
* blame us, we were explicitly instructed to do this.
*
* UPDATE: Nope, we can't actually do that, the compositor may give
* us a completely stateless, sizeless configure, with which we have
* to enforce our own state anyway.
*/
window->w = width;
window->h = height;
if (width != 0 && height != 0) {
window->w = width;
window->h = height;
}
/* This part is good though. */
if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
@@ -633,12 +639,21 @@ Wayland_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
#ifdef HAVE_LIBDECOR_H
if (viddata->shell.libdecor && data->shell_surface.libdecor.frame != NULL) {
info->info.wl.xdg_surface = libdecor_frame_get_xdg_surface(data->shell_surface.libdecor.frame);
if (version >= SDL_VERSIONNUM(2, 0, 17)) {
info->info.wl.xdg_toplevel = libdecor_frame_get_xdg_toplevel(data->shell_surface.libdecor.frame);
}
} else
#endif
if (viddata->shell.xdg && data->shell_surface.xdg.surface != NULL) {
info->info.wl.xdg_surface = data->shell_surface.xdg.surface;
if (version >= SDL_VERSIONNUM(2, 0, 17)) {
info->info.wl.xdg_toplevel = data->shell_surface.xdg.roleobj.toplevel;
}
} else {
info->info.wl.xdg_surface = NULL;
if (version >= SDL_VERSIONNUM(2, 0, 17)) {
info->info.wl.xdg_toplevel = NULL;
}
}
}
@@ -939,6 +954,17 @@ QtExtendedSurface_OnHintChanged(void *userdata, const char *name,
const char *oldValue, const char *newValue)
{
struct qt_extended_surface *qt_extended_surface = userdata;
int i;
static struct {
const char *name;
int32_t value;
} orientations[] = {
{ "portrait", QT_EXTENDED_SURFACE_ORIENTATION_PRIMARYORIENTATION },
{ "landscape", QT_EXTENDED_SURFACE_ORIENTATION_LANDSCAPEORIENTATION },
{ "inverted-portrait", QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDPORTRAITORIENTATION },
{ "inverted-landscape", QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDLANDSCAPEORIENTATION }
};
if (name == NULL) {
return;
@@ -948,14 +974,21 @@ QtExtendedSurface_OnHintChanged(void *userdata, const char *name,
int32_t orientation = QT_EXTENDED_SURFACE_ORIENTATION_PRIMARYORIENTATION;
if (newValue != NULL) {
if (SDL_strcmp(newValue, "portrait") == 0) {
orientation = QT_EXTENDED_SURFACE_ORIENTATION_PORTRAITORIENTATION;
} else if (SDL_strcmp(newValue, "landscape") == 0) {
orientation = QT_EXTENDED_SURFACE_ORIENTATION_LANDSCAPEORIENTATION;
} else if (SDL_strcmp(newValue, "inverted-portrait") == 0) {
orientation = QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDPORTRAITORIENTATION;
} else if (SDL_strcmp(newValue, "inverted-landscape") == 0) {
orientation = QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDLANDSCAPEORIENTATION;
const char *value_attempt = newValue;
while (value_attempt != NULL && *value_attempt != 0) {
const char *value_attempt_end = SDL_strchr(value_attempt, ',');
size_t value_attempt_len = (value_attempt_end != NULL) ? (value_attempt_end - value_attempt)
: SDL_strlen(value_attempt);
for (i = 0; i < SDL_arraysize(orientations); i += 1) {
if ((value_attempt_len == SDL_strlen(orientations[i].name)) &&
(SDL_strncasecmp(orientations[i].name, value_attempt, value_attempt_len) == 0)) {
orientation |= orientations[i].value;
break;
}
}
value_attempt = (value_attempt_end != NULL) ? (value_attempt_end + 1) : NULL;
}
}
@@ -1138,15 +1171,35 @@ Wayland_MinimizeWindow(_THIS, SDL_Window * window)
WAYLAND_wl_display_flush(viddata->display);
}
void
Wayland_SetWindowMouseRect(_THIS, SDL_Window *window)
{
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
/* This may look suspiciously like SetWindowGrab, despite SetMouseRect not
* implicitly doing a grab. And you're right! Wayland doesn't let us mess
* around with mouse focus whatsoever, so it just happens to be that the
* work that we can do in these two functions ends up being the same.
*
* Just know that this call lets you confine with a rect, SetWindowGrab
* lets you confine without a rect.
*/
if (SDL_RectEmpty(&window->mouse_rect) && !(window->flags & SDL_WINDOW_MOUSE_GRABBED)) {
Wayland_input_unconfine_pointer(data->input, window);
} else {
Wayland_input_confine_pointer(data->input, window);
}
}
void
Wayland_SetWindowMouseGrab(_THIS, SDL_Window *window, SDL_bool grabbed)
{
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
if (grabbed) {
Wayland_input_confine_pointer(window, data->input);
} else {
Wayland_input_unconfine_pointer(data->input);
Wayland_input_confine_pointer(data->input, window);
} else if (SDL_RectEmpty(&window->mouse_rect)) {
Wayland_input_unconfine_pointer(data->input, window);
}
}
@@ -1222,7 +1275,10 @@ int Wayland_CreateWindow(_THIS, SDL_Window *window)
* window isn't visible.
*/
if (window->flags & SDL_WINDOW_OPENGL) {
data->frame_callback = wl_surface_frame(data->surface);
data->frame_event_queue = WAYLAND_wl_display_create_queue(data->waylandData->display);
data->frame_surface_wrapper = WAYLAND_wl_proxy_create_wrapper(data->surface);
WAYLAND_wl_proxy_set_queue((struct wl_proxy *)data->frame_surface_wrapper, data->frame_event_queue);
data->frame_callback = wl_surface_frame(data->frame_surface_wrapper);
wl_callback_add_listener(data->frame_callback, &surface_frame_listener, data);
}
@@ -1462,6 +1518,8 @@ void Wayland_DestroyWindow(_THIS, SDL_Window *window)
SDL_free(wind->outputs);
if (wind->frame_callback) {
WAYLAND_wl_event_queue_destroy(wind->frame_event_queue);
WAYLAND_wl_proxy_wrapper_destroy(wind->frame_surface_wrapper);
wl_callback_destroy(wind->frame_callback);
}

View File

@@ -53,6 +53,8 @@ typedef struct {
SDL_VideoData *waylandData;
struct wl_surface *surface;
struct wl_callback *frame_callback;
struct wl_event_queue *frame_event_queue;
struct wl_surface *frame_surface_wrapper;
union {
#ifdef HAVE_LIBDECOR_H
SDL_libdecor_surface libdecor;
@@ -63,6 +65,7 @@ typedef struct {
struct SDL_WaylandInput *keyboard_device;
EGLSurface egl_surface;
struct zwp_locked_pointer_v1 *locked_pointer;
struct zwp_confined_pointer_v1 *confined_pointer;
struct zxdg_toplevel_decoration_v1 *server_decoration;
struct zwp_keyboard_shortcuts_inhibitor_v1 *key_inhibitor;
struct zwp_idle_inhibitor_v1 *idle_inhibitor;
@@ -91,6 +94,7 @@ extern void Wayland_SetWindowFullscreen(_THIS, SDL_Window * window,
SDL_bool fullscreen);
extern void Wayland_MaximizeWindow(_THIS, SDL_Window * window);
extern void Wayland_MinimizeWindow(_THIS, SDL_Window * window);
extern void Wayland_SetWindowMouseRect(_THIS, SDL_Window * window);
extern void Wayland_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
extern void Wayland_SetWindowKeyboardGrab(_THIS, SDL_Window *window, SDL_bool grabbed);
extern void Wayland_RestoreWindow(_THIS, SDL_Window * window);

View File

@@ -81,6 +81,16 @@
#define WM_UNICHAR 0x0109
#endif
#ifndef IS_HIGH_SURROGATE
#define IS_HIGH_SURROGATE(x) (((x) >= 0xd800) && ((x) <= 0xdbff))
#endif
#ifndef IS_LOW_SURROGATE
#define IS_LOW_SURROGATE(x) (((x) >= 0xdc00) && ((x) <= 0xdfff))
#endif
#ifndef IS_SURROGATE_PAIR
#define IS_SURROGATE_PAIR(h,l) (IS_HIGH_SURROGATE(h) && IS_LOW_SURROGATE(l))
#endif
static SDL_Scancode
VKeytoScancodeFallback(WPARAM vkey)
{
@@ -359,6 +369,76 @@ WIN_CheckAsyncMouseRelease(SDL_WindowData *data)
data->mouse_button_flags = 0;
}
static void
WIN_UpdateFocus(SDL_Window *window)
{
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) {
return;
}
if (has_focus) {
POINT cursorPos;
SDL_bool swapButtons = GetSystemMetrics(SM_SWAPBUTTON) != 0;
if (GetAsyncKeyState(VK_LBUTTON)) {
data->focus_click_pending |= !swapButtons ? SDL_BUTTON_LMASK : SDL_BUTTON_RMASK;
}
if (GetAsyncKeyState(VK_RBUTTON)) {
data->focus_click_pending |= !swapButtons ? SDL_BUTTON_RMASK : SDL_BUTTON_LMASK;
}
if (GetAsyncKeyState(VK_MBUTTON)) {
data->focus_click_pending |= SDL_BUTTON_MMASK;
}
if (GetAsyncKeyState(VK_XBUTTON1)) {
data->focus_click_pending |= SDL_BUTTON_X1MASK;
}
if (GetAsyncKeyState(VK_XBUTTON2)) {
data->focus_click_pending |= SDL_BUTTON_X2MASK;
}
SDL_SetKeyboardFocus(window);
/* In relative mode we are guaranteed to have mouse focus if we have keyboard focus */
if (!SDL_GetMouse()->relative_mode) {
GetCursorPos(&cursorPos);
ScreenToClient(hwnd, &cursorPos);
SDL_SendMouseMotion(window, 0, 0, cursorPos.x, cursorPos.y);
}
WIN_CheckAsyncMouseRelease(data);
WIN_UpdateClipCursor(window);
/*
* FIXME: Update keyboard state
*/
WIN_CheckClipboardUpdate(data->videodata);
SDL_ToggleModState(KMOD_CAPS, (GetKeyState(VK_CAPITAL) & 0x0001) != 0);
SDL_ToggleModState(KMOD_NUM, (GetKeyState(VK_NUMLOCK) & 0x0001) != 0);
SDL_ToggleModState(KMOD_SCROLL, (GetKeyState(VK_SCROLL) & 0x0001) != 0);
} else {
RECT rect;
data->in_window_deactivation = SDL_TRUE;
SDL_SetKeyboardFocus(NULL);
WIN_ResetDeadKeys();
if (GetClipCursor(&rect) && SDL_memcmp(&rect, &data->cursor_clipped_rect, sizeof(rect)) == 0) {
ClipCursor(NULL);
SDL_zero(data->cursor_clipped_rect);
}
data->in_window_deactivation = SDL_FALSE;
}
}
static BOOL
WIN_ConvertUTF32toUTF8(UINT32 codepoint, char * text)
{
@@ -386,17 +466,20 @@ WIN_ConvertUTF32toUTF8(UINT32 codepoint, char * text)
return SDL_TRUE;
}
static BOOL
WIN_ConvertUTF16toUTF8(UINT32 high_surrogate, UINT32 low_surrogate, char * text)
{
const UINT32 SURROGATE_OFFSET = 0x10000 - (0xD800 << 10) - 0xDC00;
const UINT32 codepoint = (high_surrogate << 10) + low_surrogate + SURROGATE_OFFSET;
return WIN_ConvertUTF32toUTF8(codepoint, text);
}
static SDL_bool
ShouldGenerateWindowCloseOnAltF4(void)
{
return !SDL_GetHintBoolean(SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4, SDL_FALSE);
}
/* Win10 "Fall Creators Update" introduced the bug that SetCursorPos() (as used by SDL_WarpMouseInWindow())
doesn't reliably generate WM_MOUSEMOVE events anymore (see #3931) which breaks relative mouse mode via warping.
This is used to implement a workaround.. */
static SDL_bool isWin10FCUorNewer = SDL_FALSE;
/* We want to generate mouse events from mouse and pen, and touch events from touchscreens */
#define MI_WP_SIGNATURE 0xFF515700
#define MI_WP_SIGNATURE_MASK 0xFFFFFF00
@@ -507,6 +590,30 @@ WIN_KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam)
return 1;
}
static void WIN_CheckICMProfileChanged(SDL_Window* window)
{
SDL_VideoDisplay* display = SDL_GetDisplayForWindow(window);
SDL_DisplayData* data = (SDL_DisplayData*)display->driverdata;
static WCHAR currentIcmFileName[MAX_PATH] = { '\0' };
WCHAR icmFileName[MAX_PATH];
HDC hdc;
SDL_bool succeeded;
DWORD fileNameSize = MAX_PATH;
hdc = CreateDCW(data->DeviceName, NULL, NULL, NULL);
if (hdc) {
succeeded = GetICMProfileW(hdc, &fileNameSize, icmFileName);
DeleteDC(hdc);
if (succeeded) {
if (SDL_wcsncmp(currentIcmFileName, icmFileName, fileNameSize)) {
SDL_wcslcpy(currentIcmFileName, icmFileName, fileNameSize);
SDL_SendWindowEvent(window, SDL_WINDOWEVENT_ICCPROF_CHANGED, 0, 0);
}
}
}
}
LRESULT CALLBACK
WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
@@ -567,77 +674,28 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
/* Don't immediately clip the cursor in case we're clicking minimize/maximize buttons */
data->skip_update_clipcursor = SDL_TRUE;
/* 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_CheckICMProfileChanged(data->window);
}
break;
case WM_ACTIVATE:
{
POINT cursorPos;
BOOL minimized;
minimized = HIWORD(wParam);
if (!minimized && (LOWORD(wParam) != WA_INACTIVE)) {
/* Don't mark the window as shown if it's activated before being shown */
if (!IsWindowVisible(hwnd)) {
break;
}
if (LOWORD(wParam) == WA_CLICKACTIVE) {
SDL_bool swapButtons = GetSystemMetrics(SM_SWAPBUTTON) != 0;
if (GetAsyncKeyState(VK_LBUTTON)) {
data->focus_click_pending |= !swapButtons ? SDL_BUTTON_LMASK : SDL_BUTTON_RMASK;
}
if (GetAsyncKeyState(VK_RBUTTON)) {
data->focus_click_pending |= !swapButtons ? SDL_BUTTON_RMASK : SDL_BUTTON_LMASK;
}
if (GetAsyncKeyState(VK_MBUTTON)) {
data->focus_click_pending |= SDL_BUTTON_MMASK;
}
if (GetAsyncKeyState(VK_XBUTTON1)) {
data->focus_click_pending |= SDL_BUTTON_X1MASK;
}
if (GetAsyncKeyState(VK_XBUTTON2)) {
data->focus_click_pending |= SDL_BUTTON_X2MASK;
}
}
SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_SHOWN, 0, 0);
if (SDL_GetKeyboardFocus() != data->window) {
SDL_SetKeyboardFocus(data->window);
}
GetCursorPos(&cursorPos);
ScreenToClient(hwnd, &cursorPos);
SDL_SendMouseMotion(data->window, 0, 0, cursorPos.x, cursorPos.y);
WIN_CheckAsyncMouseRelease(data);
WIN_UpdateClipCursor(data->window);
/*
* FIXME: Update keyboard state
*/
WIN_CheckClipboardUpdate(data->videodata);
SDL_ToggleModState(KMOD_CAPS, (GetKeyState(VK_CAPITAL) & 0x0001) != 0);
SDL_ToggleModState(KMOD_NUM, (GetKeyState(VK_NUMLOCK) & 0x0001) != 0);
} else {
RECT rect;
data->in_window_deactivation = SDL_TRUE;
if (SDL_GetKeyboardFocus() == data->window) {
SDL_SetKeyboardFocus(NULL);
WIN_ResetDeadKeys();
}
if (GetClipCursor(&rect) && SDL_memcmp(&rect, &data->cursor_clipped_rect, sizeof(rect)) == 0) {
ClipCursor(NULL);
SDL_zero(data->cursor_clipped_rect);
}
data->in_window_deactivation = SDL_FALSE;
}
/* Update the focus in case we changed focus to a child window and then away from the application */
WIN_UpdateFocus(data->window);
}
break;
case WM_SETFOCUS:
case WM_KILLFOCUS:
{
/* Update the focus in case it's changing between top-level windows in the same application */
WIN_UpdateFocus(data->window);
}
returnCode = 0;
break;
case WM_POINTERUPDATE:
@@ -649,29 +707,29 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
case WM_MOUSEMOVE:
{
SDL_Mouse *mouse = SDL_GetMouse();
if (!data->mouse_tracked) {
TRACKMOUSEEVENT trackMouseEvent;
trackMouseEvent.cbSize = sizeof(TRACKMOUSEEVENT);
trackMouseEvent.dwFlags = TME_LEAVE;
trackMouseEvent.hwndTrack = data->hwnd;
if (TrackMouseEvent(&trackMouseEvent)) {
data->mouse_tracked = SDL_TRUE;
}
}
if (!mouse->relative_mode || mouse->relative_mode_warp) {
/* Only generate mouse events for real mouse */
if (GetMouseMessageSource() != SDL_MOUSE_EVENT_SOURCE_TOUCH &&
lParam != data->last_pointer_update) {
SDL_SendMouseMotion(data->window, 0, 0, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
if (isWin10FCUorNewer && mouse->relative_mode_warp) {
/* To work around #3931, Win10 bug introduced in Fall Creators Update, where
SetCursorPos() (SDL_WarpMouseInWindow()) doesn't reliably generate mouse events anymore,
after each windows mouse event generate a fake event for the middle of the window
if relative_mode_warp is used */
int center_x = 0, center_y = 0;
SDL_GetWindowSize(data->window, &center_x, &center_y);
center_x /= 2;
center_y /= 2;
SDL_SendMouseMotion(data->window, 0, 0, center_x, center_y);
}
}
} else {
/* We still need to update focus */
SDL_SetMouseFocus(data->window);
}
}
/* don't break here, fall through to check the wParam like the button presses */
SDL_FALLTHROUGH;
case WM_LBUTTONUP:
case WM_RBUTTONUP:
case WM_MBUTTONUP:
@@ -701,13 +759,15 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
HRAWINPUT hRawInput = (HRAWINPUT)lParam;
RAWINPUT inp;
UINT size = sizeof(inp);
const SDL_bool isRelative = mouse->relative_mode || mouse->relative_mode_warp;
const SDL_bool isCapture = ((data->window->flags & SDL_WINDOW_MOUSE_CAPTURE) != 0);
if (!isRelative || mouse->focus != data->window) {
if (!isCapture) {
break;
}
/* We only use raw mouse input in relative mode */
if (!mouse->relative_mode || mouse->relative_mode_warp) {
break;
}
/* Relative mouse motion is delivered to the window with keyboard focus */
if (data->window != SDL_GetKeyboardFocus()) {
break;
}
GetRawInputData(hRawInput, RID_INPUT, &inp, &size, sizeof(RAWINPUTHEADER));
@@ -715,61 +775,93 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
/* Mouse data (ignoring synthetic mouse events generated for touchscreens) */
if (inp.header.dwType == RIM_TYPEMOUSE) {
SDL_MouseID mouseID;
RAWMOUSE* rawmouse;
if (SDL_GetNumTouchDevices() > 0 &&
(GetMouseMessageSource() == SDL_MOUSE_EVENT_SOURCE_TOUCH || (GetMessageExtraInfo() & 0x82) == 0x82)) {
break;
}
mouseID = (SDL_MouseID)(uintptr_t)inp.header.hDevice;
if (isRelative) {
RAWMOUSE* rawmouse = &inp.data.mouse;
/* We do all of our mouse state checking against mouse ID 0
* We would only use the actual hDevice if we were tracking
* all mouse motion independently, and never using mouse ID 0.
*/
mouseID = 0; /* (SDL_MouseID)(uintptr_t)inp.header.hDevice; */
rawmouse = &inp.data.mouse;
if ((rawmouse->usFlags & 0x01) == MOUSE_MOVE_RELATIVE) {
SDL_SendMouseMotion(data->window, mouseID, 1, (int)rawmouse->lLastX, (int)rawmouse->lLastY);
} else if (rawmouse->lLastX || rawmouse->lLastY) {
/* synthesize relative moves from the abs position */
static SDL_Point lastMousePoint;
SDL_bool virtual_desktop = (rawmouse->usFlags & MOUSE_VIRTUAL_DESKTOP) ? SDL_TRUE : SDL_FALSE;
int w = GetSystemMetrics(virtual_desktop ? SM_CXVIRTUALSCREEN : SM_CXSCREEN);
int h = GetSystemMetrics(virtual_desktop ? SM_CYVIRTUALSCREEN : SM_CYSCREEN);
int x = (int)(((float)rawmouse->lLastX / 65535.0f) * w);
int y = (int)(((float)rawmouse->lLastY / 65535.0f) * h);
if ((rawmouse->usFlags & 0x01) == MOUSE_MOVE_RELATIVE) {
SDL_SendMouseMotion(data->window, mouseID, 1, (int)rawmouse->lLastX, (int)rawmouse->lLastY);
} else if (rawmouse->lLastX || rawmouse->lLastY) {
/* This is absolute motion, either using a tablet or mouse over RDP
if (lastMousePoint.x == 0 && lastMousePoint.y == 0) {
lastMousePoint.x = x;
lastMousePoint.y = y;
Notes on how RDP appears to work, as of Windows 10 2004:
- SetCursorPos() calls are cached, with multiple calls coalesced into a single call that's sent to the RDP client. If the last call to SetCursorPos() has the same value as the last one that was sent to the client, it appears to be ignored and not sent. This means that we need to jitter the SetCursorPos() position slightly in order for the recentering to work correctly.
- User mouse motion is coalesced with SetCursorPos(), so the WM_INPUT positions we see will not necessarily match the positon we requested with SetCursorPos().
- SetCursorPos() outside of the bounds of the focus window appears not to do anything.
- SetCursorPos() while the cursor is NULL doesn't do anything
We handle this by creating a safe area within the application window, and when the mouse leaves that safe area, we warp back to the opposite side. Any single motion > 50% of the safe area is assumed to be a warp and ignored.
*/
SDL_bool remote_desktop = GetSystemMetrics(SM_REMOTESESSION) ? SDL_TRUE : SDL_FALSE;
SDL_bool virtual_desktop = (rawmouse->usFlags & MOUSE_VIRTUAL_DESKTOP) ? SDL_TRUE : SDL_FALSE;
SDL_bool normalized_coordinates = ((rawmouse->usFlags & 0x40) == 0) ? SDL_TRUE : SDL_FALSE;
int w = GetSystemMetrics(virtual_desktop ? SM_CXVIRTUALSCREEN : SM_CXSCREEN);
int h = GetSystemMetrics(virtual_desktop ? SM_CYVIRTUALSCREEN : SM_CYSCREEN);
int x = normalized_coordinates ? (int)(((float)rawmouse->lLastX / 65535.0f) * w) : (int)rawmouse->lLastX;
int y = normalized_coordinates ? (int)(((float)rawmouse->lLastY / 65535.0f) * h) : (int)rawmouse->lLastY;
int relX, relY;
/* Calculate relative motion */
if (data->last_raw_mouse_position.x == 0 && data->last_raw_mouse_position.y == 0) {
data->last_raw_mouse_position.x = x;
data->last_raw_mouse_position.y = y;
}
relX = (int)(x - data->last_raw_mouse_position.x);
relY = (int)(y - data->last_raw_mouse_position.y);
if (remote_desktop) {
if (!data->in_title_click && !data->focus_click_pending) {
static int wobble;
float floatX = (float)x / w;
float floatY = (float)y / h;
/* See if the mouse is at the edge of the screen, or in the RDP title bar area */
if (floatX <= 0.01f || floatX >= 0.99f || floatY <= 0.01f || floatY >= 0.99f || y < 32) {
/* Wobble the cursor position so it's not ignored if the last warp didn't have any effect */
RECT rect = data->cursor_clipped_rect;
int warpX = rect.left + ((rect.right - rect.left) / 2) + wobble;
int warpY = rect.top + ((rect.bottom - rect.top) / 2);
WIN_SetCursorPos(warpX, warpY);
++wobble;
if (wobble > 1) {
wobble = -1;
}
} else {
/* Send relative motion if we didn't warp last frame (had good position data)
We also sometimes get large deltas due to coalesced mouse motion and warping,
so ignore those.
*/
const int MAX_RELATIVE_MOTION = (h / 6);
if (SDL_abs(relX) < MAX_RELATIVE_MOTION &&
SDL_abs(relY) < MAX_RELATIVE_MOTION) {
SDL_SendMouseMotion(data->window, mouseID, 1, relX, relY);
}
}
}
} else {
const int MAXIMUM_TABLET_RELATIVE_MOTION = 32;
if (SDL_abs(relX) > MAXIMUM_TABLET_RELATIVE_MOTION ||
SDL_abs(relY) > MAXIMUM_TABLET_RELATIVE_MOTION) {
/* Ignore this motion, probably a pen lift and drop */
} else {
SDL_SendMouseMotion(data->window, mouseID, 1, relX, relY);
}
SDL_SendMouseMotion(data->window, mouseID, 1, (int)(x-lastMousePoint.x), (int)(y-lastMousePoint.y));
lastMousePoint.x = x;
lastMousePoint.y = y;
}
WIN_CheckRawMouseButtons(rawmouse->usButtonFlags, data, mouseID);
} else if (isCapture) {
/* we check for where Windows thinks the system cursor lives in this case, so we don't really lose mouse accel, etc. */
POINT pt;
RECT hwndRect;
HWND currentHnd;
GetCursorPos(&pt);
currentHnd = WindowFromPoint(pt);
ScreenToClient(hwnd, &pt);
GetClientRect(hwnd, &hwndRect);
/* if in the window, WM_MOUSEMOVE, etc, will cover it. */
if(currentHnd != hwnd || pt.x < 0 || pt.y < 0 || pt.x > hwndRect.right || pt.y > hwndRect.right) {
SDL_bool swapButtons = GetSystemMetrics(SM_SWAPBUTTON) != 0;
SDL_SendMouseMotion(data->window, mouseID, 0, (int)pt.x, (int)pt.y);
SDL_SendMouseButton(data->window, mouseID, GetAsyncKeyState(VK_LBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, !swapButtons ? SDL_BUTTON_LEFT : SDL_BUTTON_RIGHT);
SDL_SendMouseButton(data->window, mouseID, GetAsyncKeyState(VK_RBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, !swapButtons ? SDL_BUTTON_RIGHT : SDL_BUTTON_LEFT);
SDL_SendMouseButton(data->window, mouseID, GetAsyncKeyState(VK_MBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_MIDDLE);
SDL_SendMouseButton(data->window, mouseID, GetAsyncKeyState(VK_XBUTTON1) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_X1);
SDL_SendMouseButton(data->window, mouseID, GetAsyncKeyState(VK_XBUTTON2) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_X2);
}
} else {
SDL_assert(0 && "Shouldn't happen");
data->last_raw_mouse_position.x = x;
data->last_raw_mouse_position.y = y;
}
WIN_CheckRawMouseButtons(rawmouse->usButtonFlags, data, mouseID);
}
}
break;
@@ -786,10 +878,9 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
}
break;
#ifdef WM_MOUSELEAVE
case WM_MOUSELEAVE:
if (SDL_GetMouseFocus() == data->window && !SDL_GetMouse()->relative_mode && !(data->window->flags & SDL_WINDOW_MOUSE_CAPTURE)) {
if (!IsIconic(hwnd)) {
if (!(data->window->flags & SDL_WINDOW_MOUSE_CAPTURE)) {
if (SDL_GetMouseFocus() == data->window && !SDL_GetMouse()->relative_mode && !IsIconic(hwnd)) {
SDL_Mouse *mouse;
POINT cursorPos;
GetCursorPos(&cursorPos);
@@ -806,19 +897,16 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
}
}
}
/* When WM_MOUSELEAVE is fired we can be assured that the cursor has left the window */
SDL_SetMouseFocus(NULL);
}
/* When WM_MOUSELEAVE is fired we can be assured that the cursor has left the window.
Regardless of relative mode, it is important that mouse focus is reset as there is a potential
race condition when in the process of leaving/entering relative mode, resulting in focus never
being lost. This then causes a cascading failure where SDL_WINDOWEVENT_ENTER / SDL_WINDOWEVENT_LEAVE
can stop firing permanently, due to the focus being in the wrong state and TrackMouseEvent never
resubscribing. */
SDL_SetMouseFocus(NULL);
/* Once we get WM_MOUSELEAVE we're guaranteed that the window is no longer tracked */
data->mouse_tracked = SDL_FALSE;
returnCode = 0;
break;
#endif /* WM_MOUSELEAVE */
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
@@ -862,11 +950,36 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
case WM_UNICHAR:
if (wParam == UNICODE_NOCHAR) {
returnCode = 1;
break;
} else {
char text[5];
if (WIN_ConvertUTF32toUTF8((UINT32)wParam, text)) {
SDL_SendKeyboardText(text);
}
returnCode = 0;
}
/* otherwise fall through to below */
break;
case WM_CHAR:
{
/* When a user enters a Unicode code point defined in the Basic Multilingual Plane, Windows sends a WM_CHAR
message with the code point encoded as UTF-16. When a user enters a Unicode code point from a Supplementary
Plane, Windows sends the code point in two separate WM_CHAR messages: The first message includes the UTF-16
High Surrogate and the second the UTF-16 Low Surrogate. The High and Low Surrogates cannot be individually
converted to valid UTF-8, therefore, we must save the High Surrogate from the first WM_CHAR message and
concatenate it with the Low Surrogate from the second WM_CHAR message. At that point, we have a valid
UTF-16 surrogate pair ready to re-encode as UTF-8. */
if (IS_HIGH_SURROGATE(wParam)) {
data->high_surrogate = (WCHAR)wParam;
} else if (IS_SURROGATE_PAIR(data->high_surrogate, wParam)) {
/* The code point is in a Supplementary Plane.
Here wParam is the Low Surrogate. */
char text[5];
if (WIN_ConvertUTF16toUTF8((UINT32)data->high_surrogate, (UINT32)wParam, text)) {
SDL_SendKeyboardText(text);
}
data->high_surrogate = 0;
} else {
/* The code point is in the Basic Multilingual Plane.
It's numerically equal to UTF-32. */
char text[5];
if (WIN_ConvertUTF32toUTF8((UINT32)wParam, text)) {
SDL_SendKeyboardText(text);
@@ -1027,6 +1140,8 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
/* Forces a WM_PAINT event */
InvalidateRect(hwnd, NULL, FALSE);
WIN_CheckICMProfileChanged(data->window);
}
break;
@@ -1276,6 +1391,31 @@ static void WIN_UpdateClipCursorForWindows()
}
}
static void WIN_UpdateMouseCapture()
{
SDL_Window* focusWindow = SDL_GetKeyboardFocus();
if (focusWindow && (focusWindow->flags & SDL_WINDOW_MOUSE_CAPTURE)) {
SDL_WindowData *data = (SDL_WindowData *) focusWindow->driverdata;
if (!data->mouse_tracked) {
POINT pt;
if (GetCursorPos(&pt) && ScreenToClient(data->hwnd, &pt)) {
SDL_bool swapButtons = GetSystemMetrics(SM_SWAPBUTTON) != 0;
SDL_MouseID mouseID = SDL_GetMouse()->mouseID;
SDL_SendMouseMotion(data->window, mouseID, 0, (int)pt.x, (int)pt.y);
SDL_SendMouseButton(data->window, mouseID, GetAsyncKeyState(VK_LBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, !swapButtons ? SDL_BUTTON_LEFT : SDL_BUTTON_RIGHT);
SDL_SendMouseButton(data->window, mouseID, GetAsyncKeyState(VK_RBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, !swapButtons ? SDL_BUTTON_RIGHT : SDL_BUTTON_LEFT);
SDL_SendMouseButton(data->window, mouseID, GetAsyncKeyState(VK_MBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_MIDDLE);
SDL_SendMouseButton(data->window, mouseID, GetAsyncKeyState(VK_XBUTTON1) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_X1);
SDL_SendMouseButton(data->window, mouseID, GetAsyncKeyState(VK_XBUTTON2) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_X2);
}
}
}
}
/* A message hook called before TranslateMessage() */
static SDL_WindowsMessageHook g_WindowsMessageHook = NULL;
static void *g_WindowsMessageHookData = NULL;
@@ -1334,8 +1474,9 @@ WIN_PumpEvents(_THIS)
{
const Uint8 *keystate;
MSG msg;
DWORD start_ticks = GetTickCount();
DWORD end_ticks = GetTickCount() + 1;
int new_messages = 0;
SDL_Window *focusWindow;
if (g_WindowsEnableMessageLoop) {
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
@@ -1343,12 +1484,22 @@ WIN_PumpEvents(_THIS)
g_WindowsMessageHook(g_WindowsMessageHookData, msg.hwnd, msg.message, msg.wParam, msg.lParam);
}
/* Don't dispatch any mouse motion queued prior to or including the last mouse warp */
if (msg.message == WM_MOUSEMOVE && SDL_last_warp_time) {
if (!SDL_TICKS_PASSED(msg.time, (SDL_last_warp_time + 1))) {
continue;
}
/* This mouse message happened after the warp */
SDL_last_warp_time = 0;
}
/* Always translate the message in case it's a non-SDL window (e.g. with Qt integration) */
TranslateMessage(&msg);
DispatchMessage(&msg);
/* Make sure we don't busy loop here forever if there are lots of events coming in */
if (SDL_TICKS_PASSED(msg.time, start_ticks)) {
if (SDL_TICKS_PASSED(msg.time, end_ticks)) {
/* We might get a few new messages generated by the Steam overlay or other application hooks
In this case those messages will be processed before any pending input, so we want to continue after those messages.
(thanks to Peter Deayton for his investigation here)
@@ -1373,54 +1524,27 @@ WIN_PumpEvents(_THIS)
if ((keystate[SDL_SCANCODE_RSHIFT] == SDL_PRESSED) && !(GetKeyState(VK_RSHIFT) & 0x8000)) {
SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_RSHIFT);
}
/* The Windows key state gets lost when using Windows+Space or Windows+G shortcuts */
if ((keystate[SDL_SCANCODE_LGUI] == SDL_PRESSED) && !(GetKeyState(VK_LWIN) & 0x8000)) {
SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LGUI);
}
if ((keystate[SDL_SCANCODE_RGUI] == SDL_PRESSED) && !(GetKeyState(VK_RWIN) & 0x8000)) {
SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_RGUI);
/* The Windows key state gets lost when using Windows+Space or Windows+G shortcuts and
not grabbing the keyboard. Note: If we *are* grabbing the keyboard, GetKeyState()
will return inaccurate results for VK_LWIN and VK_RWIN but we don't need it anyway. */
focusWindow = SDL_GetKeyboardFocus();
if (!focusWindow || !(focusWindow->flags & SDL_WINDOW_KEYBOARD_GRABBED)) {
if ((keystate[SDL_SCANCODE_LGUI] == SDL_PRESSED) && !(GetKeyState(VK_LWIN) & 0x8000)) {
SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LGUI);
}
if ((keystate[SDL_SCANCODE_RGUI] == SDL_PRESSED) && !(GetKeyState(VK_RWIN) & 0x8000)) {
SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_RGUI);
}
}
/* Update the clipping rect in case someone else has stolen it */
WIN_UpdateClipCursorForWindows();
/* Update mouse capture */
WIN_UpdateMouseCapture();
}
/* to work around #3931, a bug introduced in Win10 Fall Creators Update (build nr. 16299)
we need to detect the windows version. this struct and the function below does that.
usually this struct and the corresponding function (RtlGetVersion) are in <Ntddk.h>
but here we just load it dynamically */
struct SDL_WIN_OSVERSIONINFOW {
ULONG dwOSVersionInfoSize;
ULONG dwMajorVersion;
ULONG dwMinorVersion;
ULONG dwBuildNumber;
ULONG dwPlatformId;
WCHAR szCSDVersion[128];
};
static SDL_bool
IsWin10FCUorNewer(void)
{
HMODULE handle = GetModuleHandle(TEXT("ntdll.dll"));
if (handle) {
typedef LONG(WINAPI* RtlGetVersionPtr)(struct SDL_WIN_OSVERSIONINFOW*);
RtlGetVersionPtr getVersionPtr = (RtlGetVersionPtr)GetProcAddress(handle, "RtlGetVersion");
if (getVersionPtr != NULL) {
struct SDL_WIN_OSVERSIONINFOW info;
SDL_zero(info);
info.dwOSVersionInfoSize = sizeof(info);
if (getVersionPtr(&info) == 0) { /* STATUS_SUCCESS == 0 */
if ((info.dwMajorVersion == 10 && info.dwMinorVersion == 0 && info.dwBuildNumber >= 16299) ||
(info.dwMajorVersion == 10 && info.dwMinorVersion > 0) ||
(info.dwMajorVersion > 10))
{
return SDL_TRUE;
}
}
}
}
return SDL_FALSE;
}
static int app_registered = 0;
LPTSTR SDL_Appname = NULL;
@@ -1429,7 +1553,7 @@ HINSTANCE SDL_Instance = NULL;
/* Register the class for this application */
int
SDL_RegisterApp(char *name, Uint32 style, void *hInst)
SDL_RegisterApp(const char *name, Uint32 style, void *hInst)
{
const char *hint;
WNDCLASSEX wcex;
@@ -1486,8 +1610,6 @@ SDL_RegisterApp(char *name, Uint32 style, void *hInst)
return SDL_SetError("Couldn't register application class");
}
isWin10FCUorNewer = IsWin10FCUorNewer();
app_registered = 1;
return 0;
}

View File

@@ -23,6 +23,7 @@
#if SDL_VIDEO_DRIVER_WINDOWS
#include "SDL_windowsvideo.h"
#include "SDL_hints.h"
#include "../../events/SDL_keyboard_c.h"
#include "../../events/scancodes_windows.h"
@@ -106,6 +107,7 @@ WIN_InitKeyboard(_THIS)
/* Are system caps/num/scroll lock active? Set our state to match. */
SDL_ToggleModState(KMOD_CAPS, (GetKeyState(VK_CAPITAL) & 0x0001) != 0);
SDL_ToggleModState(KMOD_NUM, (GetKeyState(VK_NUMLOCK) & 0x0001) != 0);
SDL_ToggleModState(KMOD_SCROLL, (GetKeyState(VK_SCROLL) & 0x0001) != 0);
}
void
@@ -244,15 +246,38 @@ WIN_SetTextInputRect(_THIS, SDL_Rect *rect)
himc = ImmGetContext(videodata->ime_hwnd_current);
if (himc)
{
COMPOSITIONFORM cf;
cf.ptCurrentPos.x = videodata->ime_rect.x;
cf.ptCurrentPos.y = videodata->ime_rect.y;
cf.dwStyle = CFS_FORCE_POSITION;
ImmSetCompositionWindow(himc, &cf);
COMPOSITIONFORM cof;
CANDIDATEFORM caf;
cof.dwStyle = CFS_RECT;
cof.ptCurrentPos.x = videodata->ime_rect.x;
cof.ptCurrentPos.y = videodata->ime_rect.y;
cof.rcArea.left = videodata->ime_rect.x;
cof.rcArea.right = videodata->ime_rect.x + videodata->ime_rect.w;
cof.rcArea.top = videodata->ime_rect.y;
cof.rcArea.bottom = videodata->ime_rect.y + videodata->ime_rect.h;
ImmSetCompositionWindow(himc, &cof);
caf.dwIndex = 0;
caf.dwStyle = CFS_EXCLUDE;
caf.ptCurrentPos.x = videodata->ime_rect.x;
caf.ptCurrentPos.y = videodata->ime_rect.y;
caf.rcArea.left = videodata->ime_rect.x;
caf.rcArea.right = videodata->ime_rect.x + videodata->ime_rect.w;
caf.rcArea.top = videodata->ime_rect.y;
caf.rcArea.bottom = videodata->ime_rect.y + videodata->ime_rect.h;
ImmSetCandidateWindow(himc, &caf);
ImmReleaseContext(videodata->ime_hwnd_current, himc);
}
}
static SDL_bool
WIN_ShouldShowNativeUI()
{
return SDL_GetHintBoolean(SDL_HINT_IME_SHOW_UI, SDL_FALSE);
}
#ifdef SDL_DISABLE_WINDOWS_IME
@@ -370,7 +395,10 @@ IME_Init(SDL_VideoData *videodata, HWND hwnd)
videodata->ime_available = SDL_TRUE;
IME_UpdateInputLocale(videodata);
IME_SetupAPI(videodata);
videodata->ime_uiless = UILess_SetupSinks(videodata);
if (WIN_ShouldShowNativeUI())
videodata->ime_uiless = SDL_FALSE;
else
videodata->ime_uiless = UILess_SetupSinks(videodata);
IME_UpdateInputLocale(videodata);
IME_Disable(videodata, hwnd);
}
@@ -735,13 +763,16 @@ IME_GetCompositionString(SDL_VideoData *videodata, HIMC himc, DWORD string)
length /= sizeof(videodata->ime_composition[0]);
videodata->ime_cursor = LOWORD(ImmGetCompositionStringW(himc, GCS_CURSORPOS, 0, 0));
if (videodata->ime_cursor < SDL_arraysize(videodata->ime_composition) && videodata->ime_composition[videodata->ime_cursor] == 0x3000) {
if (videodata->ime_cursor > 0 &&
videodata->ime_cursor < SDL_arraysize(videodata->ime_composition) &&
videodata->ime_composition[videodata->ime_cursor] == 0x3000) {
int i;
for (i = videodata->ime_cursor + 1; i < length; ++i)
videodata->ime_composition[i - 1] = videodata->ime_composition[i];
--length;
}
videodata->ime_composition[length] = 0;
}

View File

@@ -23,6 +23,7 @@
#if SDL_VIDEO_DRIVER_WINDOWS
#include "SDL_windowsvideo.h"
#include "../../events/SDL_displayevents_c.h"
/* Windows CE compatibility */
#ifndef CDS_FULLSCREEN
@@ -108,8 +109,50 @@ WIN_UpdateDisplayMode(_THIS, LPCWSTR deviceName, DWORD index, SDL_DisplayMode *
}
}
static SDL_DisplayOrientation
WIN_GetDisplayOrientation(DEVMODE *mode)
{
int width = mode->dmPelsWidth;
int height = mode->dmPelsHeight;
/* Use unrotated width/height to guess orientation */
if (mode->dmDisplayOrientation == DMDO_90 || mode->dmDisplayOrientation == DMDO_270) {
int temp = width;
width = height;
height = temp;
}
if (width >= height) {
switch (mode->dmDisplayOrientation) {
case DMDO_DEFAULT:
return SDL_ORIENTATION_LANDSCAPE;
case DMDO_90:
return SDL_ORIENTATION_PORTRAIT;
case DMDO_180:
return SDL_ORIENTATION_LANDSCAPE_FLIPPED;
case DMDO_270:
return SDL_ORIENTATION_PORTRAIT_FLIPPED;
default:
return SDL_ORIENTATION_UNKNOWN;
}
} else {
switch (mode->dmDisplayOrientation) {
case DMDO_DEFAULT:
return SDL_ORIENTATION_PORTRAIT;
case DMDO_90:
return SDL_ORIENTATION_LANDSCAPE_FLIPPED;
case DMDO_180:
return SDL_ORIENTATION_PORTRAIT_FLIPPED;
case DMDO_270:
return SDL_ORIENTATION_LANDSCAPE;
default:
return SDL_ORIENTATION_UNKNOWN;
}
}
}
static SDL_bool
WIN_GetDisplayMode(_THIS, LPCWSTR deviceName, DWORD index, SDL_DisplayMode * mode)
WIN_GetDisplayMode(_THIS, LPCWSTR deviceName, DWORD index, SDL_DisplayMode * mode, SDL_DisplayOrientation *orientation)
{
SDL_DisplayModeData *data;
DEVMODE devmode;
@@ -135,6 +178,11 @@ WIN_GetDisplayMode(_THIS, LPCWSTR deviceName, DWORD index, SDL_DisplayMode * mod
/* Fill in the mode information */
WIN_UpdateDisplayMode(_this, deviceName, index, mode);
if (orientation) {
*orientation = WIN_GetDisplayOrientation(&devmode);
}
return SDL_TRUE;
}
@@ -145,13 +193,14 @@ WIN_AddDisplay(_THIS, HMONITOR hMonitor, const MONITORINFOEXW *info, SDL_bool se
SDL_VideoDisplay display;
SDL_DisplayData *displaydata;
SDL_DisplayMode mode;
SDL_DisplayOrientation orientation;
DISPLAY_DEVICEW device;
#ifdef DEBUG_MODES
SDL_Log("Display: %s\n", WIN_StringToUTF8W(info->szDevice));
#endif
if (!WIN_GetDisplayMode(_this, info->szDevice, ENUM_CURRENT_SETTINGS, &mode)) {
if (!WIN_GetDisplayMode(_this, info->szDevice, ENUM_CURRENT_SETTINGS, &mode, &orientation)) {
return SDL_FALSE;
}
@@ -163,6 +212,13 @@ WIN_AddDisplay(_THIS, HMONITOR hMonitor, const MONITORINFOEXW *info, SDL_bool se
if (SDL_wcscmp(driverdata->DeviceName, info->szDevice) == 0) {
driverdata->MonitorHandle = hMonitor;
driverdata->IsValid = SDL_TRUE;
if (!_this->setting_display_mode) {
SDL_ResetDisplayModes(i);
SDL_SetCurrentDisplayMode(&_this->displays[i], &mode);
SDL_SetDesktopDisplayMode(&_this->displays[i], &mode);
SDL_SendDisplayEvent(&_this->displays[i], SDL_DISPLAYEVENT_ORIENTATION, orientation);
}
return SDL_FALSE;
}
}
@@ -183,6 +239,7 @@ WIN_AddDisplay(_THIS, HMONITOR hMonitor, const MONITORINFOEXW *info, SDL_bool se
}
display.desktop_mode = mode;
display.current_mode = mode;
display.orientation = orientation;
display.driverdata = displaydata;
SDL_AddVideoDisplay(&display, send_event);
SDL_free(display.name);
@@ -356,8 +413,8 @@ WIN_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
DWORD i;
SDL_DisplayMode mode;
for (i = 0;; ++i) {
if (!WIN_GetDisplayMode(_this, data->DeviceName, i, &mode)) {
for (i = 0; ; ++i) {
if (!WIN_GetDisplayMode(_this, data->DeviceName, i, &mode, NULL)) {
break;
}
if (SDL_ISPIXELFORMAT_INDEXED(mode.format)) {

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