mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-15 16:44:36 +00:00
update sdl to https://github.com/libsdl-org/SDL 22March 2022
This commit is contained in:
parent
ee4253c982
commit
2614274639
1225 changed files with 148950 additions and 51674 deletions
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -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;
|
||||
|
|
@ -1423,9 +1423,13 @@ SDL_RLESurface(SDL_Surface * surface)
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* If we don't have colorkey or blending, nothing to do... */
|
||||
flags = surface->map->info.flags;
|
||||
if (!(flags & (SDL_COPY_COLORKEY | SDL_COPY_BLEND))) {
|
||||
if (flags & SDL_COPY_COLORKEY) {
|
||||
/* ok */
|
||||
} else if ((flags & SDL_COPY_BLEND) && surface->format->Amask) {
|
||||
/* ok */
|
||||
} else {
|
||||
/* If we don't have colorkey or blending, nothing to do... */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -231,9 +231,7 @@ SDL_CalculateBlit(SDL_Surface * surface)
|
|||
if (map->identity && !(map->info.flags & ~SDL_COPY_RLE_DESIRED)) {
|
||||
blit = SDL_BlitCopy;
|
||||
} else if (surface->format->Rloss > 8 || dst->format->Rloss > 8) {
|
||||
/* Greater than 8 bits per channel not supported yet */
|
||||
SDL_InvalidateMap(map);
|
||||
return SDL_SetError("Blit combination not supported");
|
||||
blit = SDL_Blit_Slow;
|
||||
}
|
||||
#if SDL_HAVE_BLIT_0
|
||||
else if (surface->format->BitsPerPixel < 8 &&
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -27,6 +27,12 @@
|
|||
#include "SDL_endian.h"
|
||||
#include "SDL_surface.h"
|
||||
|
||||
/* pixman ARM blitters are 32 bit only : */
|
||||
#if defined(__aarch64__)||defined(_M_ARM64)
|
||||
#undef SDL_ARM_SIMD_BLITTERS
|
||||
#undef SDL_ARM_NEON_BLITTERS
|
||||
#endif
|
||||
|
||||
/* Table to do pixel byte expansion */
|
||||
extern Uint8* SDL_expand_byte[9];
|
||||
|
||||
|
|
@ -263,18 +269,18 @@ do { \
|
|||
{ \
|
||||
switch (bpp) { \
|
||||
case 1: { \
|
||||
Uint8 _Pixel; \
|
||||
Uint8 _pixel; \
|
||||
\
|
||||
PIXEL_FROM_RGB(_Pixel, fmt, r, g, b); \
|
||||
*((Uint8 *)(buf)) = _Pixel; \
|
||||
PIXEL_FROM_RGB(_pixel, fmt, r, g, b); \
|
||||
*((Uint8 *)(buf)) = _pixel; \
|
||||
} \
|
||||
break; \
|
||||
\
|
||||
case 2: { \
|
||||
Uint16 _Pixel; \
|
||||
Uint16 _pixel; \
|
||||
\
|
||||
PIXEL_FROM_RGB(_Pixel, fmt, r, g, b); \
|
||||
*((Uint16 *)(buf)) = _Pixel; \
|
||||
PIXEL_FROM_RGB(_pixel, fmt, r, g, b); \
|
||||
*((Uint16 *)(buf)) = _pixel; \
|
||||
} \
|
||||
break; \
|
||||
\
|
||||
|
|
@ -292,10 +298,10 @@ do { \
|
|||
break; \
|
||||
\
|
||||
case 4: { \
|
||||
Uint32 _Pixel; \
|
||||
Uint32 _pixel; \
|
||||
\
|
||||
PIXEL_FROM_RGB(_Pixel, fmt, r, g, b); \
|
||||
*((Uint32 *)(buf)) = _Pixel; \
|
||||
PIXEL_FROM_RGB(_pixel, fmt, r, g, b); \
|
||||
*((Uint32 *)(buf)) = _pixel; \
|
||||
} \
|
||||
break; \
|
||||
} \
|
||||
|
|
@ -473,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 ); \
|
||||
} \
|
||||
}
|
||||
|
|
@ -489,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); \
|
||||
} \
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -452,11 +452,94 @@ static const SDL_BlitFunc colorkey_blit[] = {
|
|||
(SDL_BlitFunc) NULL, BlitBto1Key, BlitBto2Key, BlitBto3Key, BlitBto4Key
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
Blit4bto4(SDL_BlitInfo * info)
|
||||
{
|
||||
int width = info->dst_w;
|
||||
int height = info->dst_h;
|
||||
Uint8 *src = info->src;
|
||||
Uint32 *dst = (Uint32 *) info->dst;
|
||||
int srcskip = info->src_skip;
|
||||
int dstskip = info->dst_skip;
|
||||
Uint32 *map = (Uint32 *) info->table;
|
||||
int c;
|
||||
|
||||
/* Set up some basic variables */
|
||||
srcskip += width - (width + 1) / 2;
|
||||
|
||||
while (height--) {
|
||||
Uint8 byte = 0, bit;
|
||||
for (c = 0; c < width; ++c) {
|
||||
if ((c & 0x1) == 0) {
|
||||
byte = *src++;
|
||||
}
|
||||
bit = (byte & 0xF0) >> 4;
|
||||
if (1) {
|
||||
*dst = map[bit];
|
||||
}
|
||||
byte <<= 4;
|
||||
dst++;
|
||||
}
|
||||
src += srcskip;
|
||||
dst = (Uint32 *) ((Uint8 *) dst + dstskip);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
Blit4bto4Key(SDL_BlitInfo * info)
|
||||
{
|
||||
int width = info->dst_w;
|
||||
int height = info->dst_h;
|
||||
Uint8 *src = info->src;
|
||||
Uint32 *dst = (Uint32 *) info->dst;
|
||||
int srcskip = info->src_skip;
|
||||
int dstskip = info->dst_skip;
|
||||
Uint32 ckey = info->colorkey;
|
||||
Uint32 *map = (Uint32 *) info->table;
|
||||
int c;
|
||||
|
||||
/* Set up some basic variables */
|
||||
srcskip += width - (width + 1) / 2;
|
||||
|
||||
while (height--) {
|
||||
Uint8 byte = 0, bit;
|
||||
for (c = 0; c < width; ++c) {
|
||||
if ((c & 0x1) == 0) {
|
||||
byte = *src++;
|
||||
}
|
||||
bit = (byte & 0xF0) >> 4;
|
||||
if (bit != ckey) {
|
||||
*dst = map[bit];
|
||||
}
|
||||
byte <<= 4;
|
||||
dst++;
|
||||
}
|
||||
src += srcskip;
|
||||
dst = (Uint32 *) ((Uint8 *) dst + dstskip);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_BlitFunc
|
||||
SDL_CalculateBlit0(SDL_Surface * surface)
|
||||
{
|
||||
int which;
|
||||
|
||||
/* 4bits to 32bits */
|
||||
if (surface->format->BitsPerPixel == 4) {
|
||||
if (surface->map->dst->format->BytesPerPixel == 4) {
|
||||
switch (surface->map->info.flags & ~SDL_COPY_RLE_MASK) {
|
||||
case 0:
|
||||
return Blit4bto4;
|
||||
|
||||
case SDL_COPY_COLORKEY:
|
||||
return Blit4bto4Key;
|
||||
}
|
||||
}
|
||||
/* We don't fully support 4-bit packed pixel modes */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (surface->format->BitsPerPixel != 1) {
|
||||
/* We don't support sub 8-bit packed pixel modes */
|
||||
return (SDL_BlitFunc) NULL;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -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
|
||||
|
|
@ -128,7 +128,7 @@ calc_swizzle32(const SDL_PixelFormat * srcfmt, const SDL_PixelFormat * dstfmt)
|
|||
* leave alpha with a zero mask, but we should still swizzle the bits.
|
||||
*/
|
||||
/* ARGB */
|
||||
const static const struct SDL_PixelFormat default_pixel_format = {
|
||||
static const struct SDL_PixelFormat default_pixel_format = {
|
||||
0, NULL, 0, 0,
|
||||
{0, 0},
|
||||
0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000,
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -2073,6 +2073,35 @@ Blit_RGB565_BGRA8888(SDL_BlitInfo * info)
|
|||
|
||||
#endif /* SDL_HAVE_BLIT_N_RGB565 */
|
||||
|
||||
/* RGB555->ARGB1555, and BGR555->ABGR1555, SET_ALPHA */
|
||||
static void
|
||||
Blit_RGB555_ARGB1555(SDL_BlitInfo * info)
|
||||
{
|
||||
int width = info->dst_w;
|
||||
int height = info->dst_h;
|
||||
Uint16 *src = (Uint16 *) info->src;
|
||||
int srcskip = info->src_skip;
|
||||
Uint16 *dst = (Uint16 *) info->dst;
|
||||
int dstskip = info->dst_skip;
|
||||
SDL_PixelFormat *dstfmt = info->dst_fmt;
|
||||
|
||||
Uint16 mask = ((Uint32)info->a >> dstfmt->Aloss) << dstfmt->Ashift;
|
||||
|
||||
while (height--) {
|
||||
/* *INDENT-OFF* */
|
||||
DUFFS_LOOP(
|
||||
{
|
||||
*dst = *src | mask;
|
||||
++dst;
|
||||
++src;
|
||||
},
|
||||
width);
|
||||
/* *INDENT-ON* */
|
||||
src = (Uint16 *) ((Uint8 *) src + srcskip);
|
||||
dst = (Uint16 *) ((Uint8 *) dst + dstskip);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
BlitNto1(SDL_BlitInfo * info)
|
||||
{
|
||||
|
|
@ -3259,6 +3288,10 @@ static const struct blit_table normal_blit_2[] = {
|
|||
{0x0000F800, 0x000007E0, 0x0000001F, 4, 0x0000FF00, 0x00FF0000, 0xFF000000,
|
||||
0, Blit_RGB565_BGRA8888, NO_ALPHA | COPY_ALPHA | SET_ALPHA},
|
||||
#endif
|
||||
{0x00007C00, 0x000003E0, 0x0000001F, 2, 0x00007C00, 0x000003E0, 0x0000001F,
|
||||
0, Blit_RGB555_ARGB1555, SET_ALPHA},
|
||||
{0x0000001F, 0x000003E0, 0x00007C00, 2, 0x0000001F, 0x000003E0, 0x00007C00,
|
||||
0, Blit_RGB555_ARGB1555, SET_ALPHA},
|
||||
|
||||
/* Default for 16-bit RGB source, used if no other blitter matches */
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, BlitNtoN, 0}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,7 +1,7 @@
|
|||
/* DO NOT EDIT! This file is generated by sdlgenblit.pl */
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -34,7 +34,7 @@ SDL_memcpySSE(Uint8 * dst, const Uint8 * src, int len)
|
|||
|
||||
__m128 values[4];
|
||||
for (i = len / 64; i--;) {
|
||||
_mm_prefetch(src, _MM_HINT_NTA);
|
||||
_mm_prefetch((const char *)src, _MM_HINT_NTA);
|
||||
values[0] = *(__m128 *) (src + 0);
|
||||
values[1] = *(__m128 *) (src + 16);
|
||||
values[2] = *(__m128 *) (src + 32);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -24,6 +24,21 @@
|
|||
#include "SDL_blit.h"
|
||||
#include "SDL_blit_slow.h"
|
||||
|
||||
#define FORMAT_ALPHA 0
|
||||
#define FORMAT_NO_ALPHA -1
|
||||
#define FORMAT_2101010 1
|
||||
#define FORMAT_HAS_ALPHA(format) format == 0
|
||||
#define FORMAT_HAS_NO_ALPHA(format) format < 0
|
||||
static int SDL_INLINE detect_format(SDL_PixelFormat *pf) {
|
||||
if (pf->format == SDL_PIXELFORMAT_ARGB2101010) {
|
||||
return FORMAT_2101010;
|
||||
} else if (pf->Amask) {
|
||||
return FORMAT_ALPHA;
|
||||
} else {
|
||||
return FORMAT_NO_ALPHA;
|
||||
}
|
||||
}
|
||||
|
||||
/* The ONE TRUE BLITTER
|
||||
* This puppy has to handle all the unoptimized cases - yes, it's slow.
|
||||
*/
|
||||
|
|
@ -40,47 +55,45 @@ SDL_Blit_Slow(SDL_BlitInfo * info)
|
|||
Uint32 dstpixel;
|
||||
Uint32 dstR, dstG, dstB, dstA;
|
||||
int srcy, srcx;
|
||||
int posy, posx;
|
||||
Uint32 posy, posx;
|
||||
int incy, incx;
|
||||
SDL_PixelFormat *src_fmt = info->src_fmt;
|
||||
SDL_PixelFormat *dst_fmt = info->dst_fmt;
|
||||
int srcbpp = src_fmt->BytesPerPixel;
|
||||
int dstbpp = dst_fmt->BytesPerPixel;
|
||||
int srcfmt_val;
|
||||
int dstfmt_val;
|
||||
Uint32 rgbmask = ~src_fmt->Amask;
|
||||
Uint32 ckey = info->colorkey & rgbmask;
|
||||
|
||||
srcy = 0;
|
||||
posy = 0;
|
||||
srcfmt_val = detect_format(src_fmt);
|
||||
dstfmt_val = detect_format(dst_fmt);
|
||||
|
||||
incy = (info->src_h << 16) / info->dst_h;
|
||||
incx = (info->src_w << 16) / info->dst_w;
|
||||
posy = incy / 2; /* start at the middle of pixel */
|
||||
|
||||
while (info->dst_h--) {
|
||||
Uint8 *src = 0;
|
||||
Uint8 *dst = info->dst;
|
||||
int n = info->dst_w;
|
||||
srcx = -1;
|
||||
posx = 0x10000L;
|
||||
while (posy >= 0x10000L) {
|
||||
++srcy;
|
||||
posy -= 0x10000L;
|
||||
}
|
||||
posx = incx / 2; /* start at the middle of pixel */
|
||||
srcy = posy >> 16;
|
||||
while (n--) {
|
||||
if (posx >= 0x10000L) {
|
||||
while (posx >= 0x10000L) {
|
||||
++srcx;
|
||||
posx -= 0x10000L;
|
||||
}
|
||||
src =
|
||||
(info->src + (srcy * info->src_pitch) + (srcx * srcbpp));
|
||||
}
|
||||
if (src_fmt->Amask) {
|
||||
DISEMBLE_RGBA(src, srcbpp, src_fmt, srcpixel, srcR, srcG,
|
||||
srcB, srcA);
|
||||
} else {
|
||||
DISEMBLE_RGB(src, srcbpp, src_fmt, srcpixel, srcR, srcG,
|
||||
srcB);
|
||||
srcx = posx >> 16;
|
||||
src = (info->src + (srcy * info->src_pitch) + (srcx * srcbpp));
|
||||
|
||||
if (FORMAT_HAS_ALPHA(srcfmt_val)) {
|
||||
DISEMBLE_RGBA(src, srcbpp, src_fmt, srcpixel, srcR, srcG, srcB, srcA);
|
||||
} else if (FORMAT_HAS_NO_ALPHA(srcfmt_val)) {
|
||||
DISEMBLE_RGB(src, srcbpp, src_fmt, srcpixel, srcR, srcG, srcB);
|
||||
srcA = 0xFF;
|
||||
} else {
|
||||
/* SDL_PIXELFORMAT_ARGB2101010 */
|
||||
srcpixel = *((Uint32 *)(src));
|
||||
RGBA_FROM_ARGB2101010(srcpixel, srcR, srcG, srcB, srcA);
|
||||
}
|
||||
|
||||
if (flags & SDL_COPY_COLORKEY) {
|
||||
/* srcpixel isn't set for 24 bpp */
|
||||
if (srcbpp == 3) {
|
||||
|
|
@ -93,13 +106,15 @@ SDL_Blit_Slow(SDL_BlitInfo * info)
|
|||
continue;
|
||||
}
|
||||
}
|
||||
if (dst_fmt->Amask) {
|
||||
DISEMBLE_RGBA(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG,
|
||||
dstB, dstA);
|
||||
} else {
|
||||
DISEMBLE_RGB(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG,
|
||||
dstB);
|
||||
if (FORMAT_HAS_ALPHA(dstfmt_val)) {
|
||||
DISEMBLE_RGBA(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, dstB, dstA);
|
||||
} else if (FORMAT_HAS_NO_ALPHA(dstfmt_val)) {
|
||||
DISEMBLE_RGB(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, dstB);
|
||||
dstA = 0xFF;
|
||||
} else {
|
||||
/* SDL_PIXELFORMAT_ARGB2101010 */
|
||||
dstpixel = *((Uint32 *)(dst));
|
||||
RGBA_FROM_ARGB2101010(dstpixel, dstR, dstG, dstB, dstA);
|
||||
}
|
||||
|
||||
if (flags & SDL_COPY_MODULATE_COLOR) {
|
||||
|
|
@ -162,10 +177,15 @@ SDL_Blit_Slow(SDL_BlitInfo * info)
|
|||
dstA = 255;
|
||||
break;
|
||||
}
|
||||
if (dst_fmt->Amask) {
|
||||
if (FORMAT_HAS_ALPHA(dstfmt_val)) {
|
||||
ASSEMBLE_RGBA(dst, dstbpp, dst_fmt, dstR, dstG, dstB, dstA);
|
||||
} else {
|
||||
} else if (FORMAT_HAS_NO_ALPHA(dstfmt_val)) {
|
||||
ASSEMBLE_RGB(dst, dstbpp, dst_fmt, dstR, dstG, dstB);
|
||||
} else {
|
||||
/* SDL_PIXELFORMAT_ARGB2101010 */
|
||||
Uint32 pixel;
|
||||
ARGB2101010_FROM_RGBA(pixel, dstR, dstG, dstB, dstA);
|
||||
*(Uint32 *)dst = pixel;
|
||||
}
|
||||
posx += incx;
|
||||
dst += dstbpp;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -53,7 +53,7 @@
|
|||
#define LCS_WINDOWS_COLOR_SPACE 0x57696E20
|
||||
#endif
|
||||
|
||||
static int readRlePixels(SDL_Surface * surface, SDL_RWops * src, int isRle8)
|
||||
static SDL_bool readRlePixels(SDL_Surface * surface, SDL_RWops * src, int isRle8)
|
||||
{
|
||||
/*
|
||||
| Sets the surface pixels from src. A bmp image is upside down.
|
||||
|
|
@ -70,14 +70,14 @@ static int readRlePixels(SDL_Surface * surface, SDL_RWops * src, int isRle8)
|
|||
#define COPY_PIXEL(x) spot = &bits[ofs++]; if(spot >= start && spot < end) *spot = (x)
|
||||
|
||||
for (;;) {
|
||||
if (!SDL_RWread(src, &ch, 1, 1)) return 1;
|
||||
if (!SDL_RWread(src, &ch, 1, 1)) return SDL_TRUE;
|
||||
/*
|
||||
| encoded mode starts with a run length, and then a byte
|
||||
| with two colour indexes to alternate between for the run
|
||||
*/
|
||||
if (ch) {
|
||||
Uint8 pixel;
|
||||
if (!SDL_RWread(src, &pixel, 1, 1)) return 1;
|
||||
if (!SDL_RWread(src, &pixel, 1, 1)) return SDL_TRUE;
|
||||
if (isRle8) { /* 256-color bitmap, compressed */
|
||||
do {
|
||||
COPY_PIXEL(pixel);
|
||||
|
|
@ -98,18 +98,18 @@ static int readRlePixels(SDL_Surface * surface, SDL_RWops * src, int isRle8)
|
|||
| a cursor move, or some absolute data.
|
||||
| zero tag may be absolute mode or an escape
|
||||
*/
|
||||
if (!SDL_RWread(src, &ch, 1, 1)) return 1;
|
||||
if (!SDL_RWread(src, &ch, 1, 1)) return SDL_TRUE;
|
||||
switch (ch) {
|
||||
case 0: /* end of line */
|
||||
ofs = 0;
|
||||
bits -= pitch; /* go to previous */
|
||||
break;
|
||||
case 1: /* end of bitmap */
|
||||
return 0; /* success! */
|
||||
return SDL_FALSE; /* success! */
|
||||
case 2: /* delta */
|
||||
if (!SDL_RWread(src, &ch, 1, 1)) return 1;
|
||||
if (!SDL_RWread(src, &ch, 1, 1)) return SDL_TRUE;
|
||||
ofs += ch;
|
||||
if (!SDL_RWread(src, &ch, 1, 1)) return 1;
|
||||
if (!SDL_RWread(src, &ch, 1, 1)) return SDL_TRUE;
|
||||
bits -= (ch * pitch);
|
||||
break;
|
||||
default: /* no compression */
|
||||
|
|
@ -117,14 +117,14 @@ static int readRlePixels(SDL_Surface * surface, SDL_RWops * src, int isRle8)
|
|||
needsPad = (ch & 1);
|
||||
do {
|
||||
Uint8 pixel;
|
||||
if (!SDL_RWread(src, &pixel, 1, 1)) return 1;
|
||||
if (!SDL_RWread(src, &pixel, 1, 1)) return SDL_TRUE;
|
||||
COPY_PIXEL(pixel);
|
||||
} while (--ch);
|
||||
} else {
|
||||
needsPad = (((ch+1)>>1) & 1); /* (ch+1)>>1: bytes size */
|
||||
for (;;) {
|
||||
Uint8 pixel;
|
||||
if (!SDL_RWread(src, &pixel, 1, 1)) return 1;
|
||||
if (!SDL_RWread(src, &pixel, 1, 1)) return SDL_TRUE;
|
||||
COPY_PIXEL(pixel >> 4);
|
||||
if (!--ch) break;
|
||||
COPY_PIXEL(pixel & 0x0F);
|
||||
|
|
@ -132,7 +132,7 @@ static int readRlePixels(SDL_Surface * surface, SDL_RWops * src, int isRle8)
|
|||
}
|
||||
}
|
||||
/* pad at even boundary */
|
||||
if (needsPad && !SDL_RWread(src, &ch, 1, 1)) return 1;
|
||||
if (needsPad && !SDL_RWread(src, &ch, 1, 1)) return SDL_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -213,12 +213,17 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc)
|
|||
surface = NULL;
|
||||
was_error = SDL_FALSE;
|
||||
if (src == NULL) {
|
||||
SDL_InvalidParamError("src");
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Read in the BMP file header */
|
||||
fp_offset = SDL_RWtell(src);
|
||||
if (fp_offset < 0) {
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
}
|
||||
SDL_ClearError();
|
||||
if (SDL_RWread(src, magic, 1, 2) != 2) {
|
||||
SDL_Error(SDL_EFREAD);
|
||||
|
|
@ -306,7 +311,7 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc)
|
|||
}
|
||||
}
|
||||
if (biWidth <= 0 || biHeight == 0) {
|
||||
SDL_SetError("BMP file with bad dimensions (%dx%d)", biWidth, biHeight);
|
||||
SDL_SetError("BMP file with bad dimensions (%" SDL_PRIs32 "x%" SDL_PRIs32 ")", biWidth, biHeight);
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -407,14 +412,20 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc)
|
|||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
| guich: always use 1<<bpp b/c some bitmaps can bring wrong information
|
||||
| for colorsUsed
|
||||
*/
|
||||
/* if (biClrUsed == 0) { */
|
||||
biClrUsed = 1 << biBitCount;
|
||||
/* } */
|
||||
if (biSize == 12) {
|
||||
if (biClrUsed == 0) {
|
||||
biClrUsed = 1 << biBitCount;
|
||||
}
|
||||
|
||||
if (biClrUsed > (Uint32)palette->ncolors) {
|
||||
biClrUsed = 1 << biBitCount; /* try forcing it? */
|
||||
if (biClrUsed > (Uint32)palette->ncolors) {
|
||||
SDL_SetError("Unsupported or incorrect biClrUsed field");
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (biSize == 12) {
|
||||
for (i = 0; i < (int) biClrUsed; ++i) {
|
||||
SDL_RWread(src, &palette->colors[i].b, 1, 1);
|
||||
SDL_RWread(src, &palette->colors[i].g, 1, 1);
|
||||
|
|
@ -445,8 +456,8 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc)
|
|||
goto done;
|
||||
}
|
||||
if ((biCompression == BI_RLE4) || (biCompression == BI_RLE8)) {
|
||||
was_error = (SDL_bool)readRlePixels(surface, src, biCompression == BI_RLE8);
|
||||
if (was_error) SDL_SetError("Error reading from BMP");
|
||||
was_error = readRlePixels(surface, src, biCompression == BI_RLE8);
|
||||
if (was_error) SDL_Error(SDL_EFREAD);
|
||||
goto done;
|
||||
}
|
||||
top = (Uint8 *)surface->pixels;
|
||||
|
|
@ -478,7 +489,7 @@ SDL_LoadBMP_RW(SDL_RWops * src, int freesrc)
|
|||
for (i = 0; i < surface->w; ++i) {
|
||||
if (i % (8 / ExpandBMP) == 0) {
|
||||
if (!SDL_RWread(src, &pixel, 1, 1)) {
|
||||
SDL_SetError("Error reading from BMP");
|
||||
SDL_Error(SDL_EFREAD);
|
||||
was_error = SDL_TRUE;
|
||||
goto done;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Simple DirectMedia Layer
|
||||
* Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
* Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -28,6 +28,10 @@
|
|||
#if SDL_VIDEO_DRIVER_ANDROID
|
||||
#include <android/native_window.h>
|
||||
#include "../core/android/SDL_android.h"
|
||||
#include "../video/android/SDL_androidvideo.h"
|
||||
#endif
|
||||
#if SDL_VIDEO_DRIVER_RPI
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "SDL_sysvideo.h"
|
||||
|
|
@ -42,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" )
|
||||
|
|
@ -73,6 +82,7 @@
|
|||
#define DEFAULT_OGL_ES "libGLESv1_CM.dylib" //???
|
||||
|
||||
#elif defined(__OpenBSD__)
|
||||
/* OpenBSD */
|
||||
#define DEFAULT_OGL "libGL.so"
|
||||
#define DEFAULT_EGL "libEGL.so"
|
||||
#define DEFAULT_OGL_ES2 "libGLESv2.so"
|
||||
|
|
@ -80,9 +90,10 @@
|
|||
#define DEFAULT_OGL_ES "libGLESv1_CM.so"
|
||||
|
||||
#else
|
||||
/* Desktop Linux */
|
||||
/* Desktop Linux/Unix-like */
|
||||
#define DEFAULT_OGL "libGL.so.1"
|
||||
#define DEFAULT_EGL "libEGL.so.1"
|
||||
#define ALT_OGL "libOpenGL.so.0"
|
||||
#define DEFAULT_OGL_ES2 "libGLESv2.so.2"
|
||||
#define DEFAULT_OGL_ES_PVR "libGLES_CM.so.1"
|
||||
#define DEFAULT_OGL_ES "libGLESv1_CM.so.1"
|
||||
|
|
@ -99,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
|
||||
|
|
@ -115,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;
|
||||
|
|
@ -237,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];
|
||||
|
|
@ -336,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) {
|
||||
|
|
@ -374,6 +384,12 @@ SDL_EGL_LoadLibraryOnly(_THIS, const char *egl_path)
|
|||
else {
|
||||
path = DEFAULT_OGL;
|
||||
egl_dll_handle = SDL_LoadObject(path);
|
||||
#ifdef ALT_OGL
|
||||
if (egl_dll_handle == NULL) {
|
||||
path = ALT_OGL;
|
||||
egl_dll_handle = SDL_LoadObject(path);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -416,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);
|
||||
|
|
@ -476,36 +495,40 @@ SDL_EGL_GetVersion(_THIS) {
|
|||
int
|
||||
SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_display, EGLenum platform)
|
||||
{
|
||||
int egl_version_major, egl_version_minor;
|
||||
int library_load_retcode = SDL_EGL_LoadLibraryOnly(_this, egl_path);
|
||||
if (library_load_retcode != 0) {
|
||||
return library_load_retcode;
|
||||
}
|
||||
|
||||
/* EGL 1.5 allows querying for client version with EGL_NO_DISPLAY */
|
||||
SDL_EGL_GetVersion(_this);
|
||||
|
||||
egl_version_major = _this->egl_data->egl_version_major;
|
||||
egl_version_minor = _this->egl_data->egl_version_minor;
|
||||
|
||||
if (egl_version_major == 1 && egl_version_minor == 5) {
|
||||
LOAD_FUNC(eglGetPlatformDisplay);
|
||||
}
|
||||
|
||||
_this->egl_data->egl_display = EGL_NO_DISPLAY;
|
||||
|
||||
#if !defined(__WINRT__)
|
||||
#if !defined(SDL_VIDEO_DRIVER_VITA)
|
||||
if (platform) {
|
||||
if (egl_version_major == 1 && egl_version_minor == 5) {
|
||||
_this->egl_data->egl_display = _this->egl_data->eglGetPlatformDisplay(platform, (void *)(size_t)native_display, NULL);
|
||||
/* EGL 1.5 allows querying for client version with EGL_NO_DISPLAY
|
||||
* --
|
||||
* Khronos doc: "EGL_BAD_DISPLAY is generated if display is not an EGL display connection, unless display is EGL_NO_DISPLAY and name is EGL_EXTENSIONS."
|
||||
* Therefore SDL_EGL_GetVersion() shouldn't work with uninitialized display.
|
||||
* - it actually doesn't work on Android that has 1.5 egl client
|
||||
* - it works on desktop X11 (using SDL_VIDEO_X11_FORCE_EGL=1) */
|
||||
SDL_EGL_GetVersion(_this);
|
||||
|
||||
if (_this->egl_data->egl_version_major == 1 && _this->egl_data->egl_version_minor == 5) {
|
||||
LOAD_FUNC(eglGetPlatformDisplay);
|
||||
}
|
||||
|
||||
if (_this->egl_data->eglGetPlatformDisplay) {
|
||||
_this->egl_data->egl_display = _this->egl_data->eglGetPlatformDisplay(platform, (void *)(uintptr_t)native_display, NULL);
|
||||
} else {
|
||||
if (SDL_EGL_HasExtension(_this, SDL_EGL_CLIENT_EXTENSION, "EGL_EXT_platform_base")) {
|
||||
_this->egl_data->eglGetPlatformDisplayEXT = SDL_EGL_GetProcAddress(_this, "eglGetPlatformDisplayEXT");
|
||||
if (_this->egl_data->eglGetPlatformDisplayEXT) {
|
||||
_this->egl_data->egl_display = _this->egl_data->eglGetPlatformDisplayEXT(platform, (void *)(size_t)native_display, NULL);
|
||||
_this->egl_data->egl_display = _this->egl_data->eglGetPlatformDisplayEXT(platform, (void *)(uintptr_t)native_display, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#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);
|
||||
|
|
@ -515,7 +538,7 @@ SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_displa
|
|||
*_this->gl_config.driver_path = '\0';
|
||||
return SDL_SetError("Could not get EGL display");
|
||||
}
|
||||
|
||||
|
||||
if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE) {
|
||||
_this->gl_config.driver_loaded = 0;
|
||||
*_this->gl_config.driver_path = '\0';
|
||||
|
|
@ -526,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;
|
||||
}
|
||||
|
|
@ -546,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.");
|
||||
}
|
||||
|
||||
|
|
@ -614,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;
|
||||
}
|
||||
|
|
@ -634,7 +657,8 @@ typedef struct {
|
|||
char const* name;
|
||||
} Attribute;
|
||||
|
||||
Attribute attributes[] = {
|
||||
static
|
||||
Attribute all_attributes[] = {
|
||||
ATTRIBUTE( EGL_BUFFER_SIZE ),
|
||||
ATTRIBUTE( EGL_ALPHA_SIZE ),
|
||||
ATTRIBUTE( EGL_BLUE_SIZE ),
|
||||
|
|
@ -674,31 +698,27 @@ Attribute attributes[] = {
|
|||
static void dumpconfig(_THIS, EGLConfig config)
|
||||
{
|
||||
int attr;
|
||||
for (attr = 0 ; attr<sizeof(attributes)/sizeof(Attribute) ; attr++) {
|
||||
for (attr = 0 ; attr<sizeof(all_attributes)/sizeof(Attribute) ; attr++) {
|
||||
EGLint value;
|
||||
_this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display, config, attributes[attr].attribute, &value);
|
||||
SDL_Log("\t%-32s: %10d (0x%08x)\n", attributes[attr].name, value, value);
|
||||
_this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display, config, all_attributes[attr].attribute, &value);
|
||||
SDL_Log("\t%-32s: %10d (0x%08x)\n", all_attributes[attr].name, value, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* DUMP_EGL_CONFIG */
|
||||
|
||||
int
|
||||
SDL_EGL_ChooseConfig(_THIS)
|
||||
static int
|
||||
SDL_EGL_PrivateChooseConfig(_THIS, SDL_bool set_config_caveat_none)
|
||||
{
|
||||
/* 64 seems nice. */
|
||||
/* 64 seems nice. */
|
||||
EGLint attribs[64];
|
||||
EGLint found_configs = 0, value;
|
||||
/* 128 seems even nicer here */
|
||||
EGLConfig configs[128];
|
||||
SDL_bool has_matching_format = SDL_FALSE;
|
||||
int i, j, best_bitdiff = -1, bitdiff;
|
||||
|
||||
if (!_this->egl_data) {
|
||||
/* The EGL library wasn't loaded, SDL_GetError() should have info */
|
||||
return -1;
|
||||
}
|
||||
|
||||
int i, j, best_bitdiff = -1, best_truecolor_bitdiff = -1;
|
||||
int truecolor_config_idx = -1;
|
||||
|
||||
/* Get a valid EGL configuration */
|
||||
i = 0;
|
||||
attribs[i++] = EGL_RED_SIZE;
|
||||
|
|
@ -707,30 +727,37 @@ SDL_EGL_ChooseConfig(_THIS)
|
|||
attribs[i++] = _this->gl_config.green_size;
|
||||
attribs[i++] = EGL_BLUE_SIZE;
|
||||
attribs[i++] = _this->gl_config.blue_size;
|
||||
|
||||
|
||||
if (set_config_caveat_none) {
|
||||
attribs[i++] = EGL_CONFIG_CAVEAT;
|
||||
attribs[i++] = EGL_NONE;
|
||||
}
|
||||
|
||||
if (_this->gl_config.alpha_size) {
|
||||
attribs[i++] = EGL_ALPHA_SIZE;
|
||||
attribs[i++] = _this->gl_config.alpha_size;
|
||||
}
|
||||
|
||||
|
||||
if (_this->gl_config.buffer_size) {
|
||||
attribs[i++] = EGL_BUFFER_SIZE;
|
||||
attribs[i++] = _this->gl_config.buffer_size;
|
||||
}
|
||||
|
||||
attribs[i++] = EGL_DEPTH_SIZE;
|
||||
attribs[i++] = _this->gl_config.depth_size;
|
||||
|
||||
|
||||
if (_this->gl_config.depth_size) {
|
||||
attribs[i++] = EGL_DEPTH_SIZE;
|
||||
attribs[i++] = _this->gl_config.depth_size;
|
||||
}
|
||||
|
||||
if (_this->gl_config.stencil_size) {
|
||||
attribs[i++] = EGL_STENCIL_SIZE;
|
||||
attribs[i++] = _this->gl_config.stencil_size;
|
||||
}
|
||||
|
||||
|
||||
if (_this->gl_config.multisamplebuffers) {
|
||||
attribs[i++] = EGL_SAMPLE_BUFFERS;
|
||||
attribs[i++] = _this->gl_config.multisamplebuffers;
|
||||
}
|
||||
|
||||
|
||||
if (_this->gl_config.multisamplesamples) {
|
||||
attribs[i++] = EGL_SAMPLES;
|
||||
attribs[i++] = _this->gl_config.multisamplesamples;
|
||||
|
|
@ -767,24 +794,28 @@ SDL_EGL_ChooseConfig(_THIS)
|
|||
|
||||
attribs[i++] = EGL_NONE;
|
||||
|
||||
SDL_assert(i < SDL_arraysize(attribs));
|
||||
|
||||
if (_this->egl_data->eglChooseConfig(_this->egl_data->egl_display,
|
||||
attribs,
|
||||
configs, SDL_arraysize(configs),
|
||||
&found_configs) == EGL_FALSE ||
|
||||
found_configs == 0) {
|
||||
return SDL_EGL_SetError("Couldn't find matching EGL config", "eglChooseConfig");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* first ensure that a found config has a matching format, or the function will fall through. */
|
||||
for (i = 0; i < found_configs; i++ ) {
|
||||
if (_this->egl_data->egl_required_visual_id)
|
||||
{
|
||||
if (_this->egl_data->egl_required_visual_id)
|
||||
{
|
||||
for (i = 0; i < found_configs; i++ ) {
|
||||
EGLint format;
|
||||
_this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display,
|
||||
configs[i],
|
||||
EGL_NATIVE_VISUAL_ID, &format);
|
||||
if (_this->egl_data->egl_required_visual_id == format)
|
||||
if (_this->egl_data->egl_required_visual_id == format) {
|
||||
has_matching_format = SDL_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -792,22 +823,35 @@ SDL_EGL_ChooseConfig(_THIS)
|
|||
/* From those, we select the one that matches our requirements more closely via a makeshift algorithm */
|
||||
|
||||
for (i = 0; i < found_configs; i++ ) {
|
||||
if (has_matching_format && _this->egl_data->egl_required_visual_id)
|
||||
{
|
||||
SDL_bool is_truecolor = SDL_FALSE;
|
||||
int bitdiff = 0;
|
||||
|
||||
if (has_matching_format && _this->egl_data->egl_required_visual_id) {
|
||||
EGLint format;
|
||||
_this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display,
|
||||
configs[i],
|
||||
configs[i],
|
||||
EGL_NATIVE_VISUAL_ID, &format);
|
||||
if (_this->egl_data->egl_required_visual_id != format)
|
||||
if (_this->egl_data->egl_required_visual_id != format) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
_this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display, configs[i], EGL_RED_SIZE, &value);
|
||||
if (value == 8) {
|
||||
_this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display, configs[i], EGL_GREEN_SIZE, &value);
|
||||
if (value == 8) {
|
||||
_this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display, configs[i], EGL_BLUE_SIZE, &value);
|
||||
if (value == 8) {
|
||||
is_truecolor = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bitdiff = 0;
|
||||
for (j = 0; j < SDL_arraysize(attribs) - 1; j += 2) {
|
||||
if (attribs[j] == EGL_NONE) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if ( attribs[j+1] != EGL_DONT_CARE && (
|
||||
attribs[j] == EGL_RED_SIZE ||
|
||||
attribs[j] == EGL_GREEN_SIZE ||
|
||||
|
|
@ -820,24 +864,70 @@ SDL_EGL_ChooseConfig(_THIS)
|
|||
}
|
||||
}
|
||||
|
||||
if (bitdiff < best_bitdiff || best_bitdiff == -1) {
|
||||
if ((bitdiff < best_bitdiff) || (best_bitdiff == -1)) {
|
||||
_this->egl_data->egl_config = configs[i];
|
||||
|
||||
best_bitdiff = bitdiff;
|
||||
}
|
||||
|
||||
if (bitdiff == 0) {
|
||||
break; /* we found an exact match! */
|
||||
if (is_truecolor && ((bitdiff < best_truecolor_bitdiff) || (best_truecolor_bitdiff == -1))) {
|
||||
truecolor_config_idx = i;
|
||||
best_truecolor_bitdiff = bitdiff;
|
||||
}
|
||||
}
|
||||
|
||||
#define FAVOR_TRUECOLOR 1
|
||||
#if FAVOR_TRUECOLOR
|
||||
/* Some apps request a low color depth, either because they _assume_
|
||||
they'll get a larger one but don't want to fail if only smaller ones
|
||||
are available, or they just never called SDL_GL_SetAttribute at all and
|
||||
got a tiny default. For these cases, a game that would otherwise run
|
||||
at 24-bit color might get dithered down to something smaller, which is
|
||||
worth avoiding. If the app requested <= 16 bit color and an exact 24-bit
|
||||
match is available, favor that. Otherwise, we look for the closest
|
||||
match. Note that while the API promises what you request _or better_,
|
||||
it's feasible this can be disastrous for performance for custom software
|
||||
on small hardware that all expected to actually get 16-bit color. In this
|
||||
case, turn off FAVOR_TRUECOLOR (and maybe send a patch to make this more
|
||||
flexible). */
|
||||
if ( ((_this->gl_config.red_size + _this->gl_config.blue_size + _this->gl_config.green_size) <= 16) ) {
|
||||
if (truecolor_config_idx != -1) {
|
||||
_this->egl_data->egl_config = configs[truecolor_config_idx];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DUMP_EGL_CONFIG
|
||||
dumpconfig(_this, _this->egl_data->egl_config);
|
||||
#endif
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
SDL_EGL_ChooseConfig(_THIS)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!_this->egl_data) {
|
||||
return SDL_SetError("EGL not initialized");
|
||||
}
|
||||
|
||||
/* Try with EGL_CONFIG_CAVEAT set to EGL_NONE, to avoid any EGL_SLOW_CONFIG or EGL_NON_CONFORMANT_CONFIG */
|
||||
ret = SDL_EGL_PrivateChooseConfig(_this, SDL_TRUE);
|
||||
if (ret == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Fallback with all configs */
|
||||
ret = SDL_EGL_PrivateChooseConfig(_this, SDL_FALSE);
|
||||
if (ret == 0) {
|
||||
SDL_Log("SDL_EGL_ChooseConfig: found a slow EGL config");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return SDL_EGL_SetError("Couldn't find matching EGL config", "eglChooseConfig");
|
||||
}
|
||||
|
||||
SDL_GLContext
|
||||
SDL_EGL_CreateContext(_THIS, EGLSurface egl_surface)
|
||||
{
|
||||
|
|
@ -852,7 +942,7 @@ SDL_EGL_CreateContext(_THIS, EGLSurface egl_surface)
|
|||
SDL_bool profile_es = (profile_mask == SDL_GL_CONTEXT_PROFILE_ES);
|
||||
|
||||
if (!_this->egl_data) {
|
||||
/* The EGL library wasn't loaded, SDL_GetError() should have info */
|
||||
SDL_SetError("EGL not initialized");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -922,27 +1012,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,
|
||||
|
|
@ -956,16 +1043,8 @@ SDL_EGL_CreateContext(_THIS, EGLSurface egl_surface)
|
|||
_this->egl_data->egl_swapinterval = 0;
|
||||
|
||||
if (SDL_EGL_MakeCurrent(_this, egl_surface, egl_context) < 0) {
|
||||
/* Save the SDL error set by SDL_EGL_MakeCurrent */
|
||||
char errorText[1024];
|
||||
SDL_strlcpy(errorText, SDL_GetError(), SDL_arraysize(errorText));
|
||||
|
||||
/* Delete the context, which may alter the value returned by SDL_GetError() */
|
||||
/* Delete the context */
|
||||
SDL_EGL_DeleteContext(_this, egl_context);
|
||||
|
||||
/* Restore the SDL error */
|
||||
SDL_SetError("%s", errorText);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -1008,9 +1087,23 @@ SDL_EGL_MakeCurrent(_THIS, EGLSurface egl_surface, SDL_GLContext context)
|
|||
EGLContext egl_context = (EGLContext) context;
|
||||
|
||||
if (!_this->egl_data) {
|
||||
return SDL_SetError("OpenGL not initialized");
|
||||
return SDL_SetError("EGL not initialized");
|
||||
}
|
||||
|
||||
|
||||
if (!_this->egl_data->eglMakeCurrent) {
|
||||
if (!egl_surface && !context) {
|
||||
/* Can't do the nothing there is to do? Probably trying to cleanup a failed startup, just return. */
|
||||
return 0;
|
||||
} else {
|
||||
return SDL_SetError("EGL not initialized"); /* something clearly went wrong somewhere. */
|
||||
}
|
||||
}
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
|
|
@ -1022,7 +1115,7 @@ SDL_EGL_MakeCurrent(_THIS, EGLSurface egl_surface, SDL_GLContext context)
|
|||
return SDL_EGL_SetError("Unable to make EGL context current", "eglMakeCurrent");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1034,6 +1127,13 @@ SDL_EGL_SetSwapInterval(_THIS, int interval)
|
|||
if (!_this->egl_data) {
|
||||
return SDL_SetError("EGL not initialized");
|
||||
}
|
||||
|
||||
/* FIXME: Revisit this check when EGL_EXT_swap_control_tear is published:
|
||||
* https://github.com/KhronosGroup/EGL-Registry/pull/113
|
||||
*/
|
||||
if (interval < 0) {
|
||||
return SDL_SetError("Late swap tearing currently unsupported");
|
||||
}
|
||||
|
||||
status = _this->egl_data->eglSwapInterval(_this->egl_data->egl_display, interval);
|
||||
if (status == EGL_TRUE) {
|
||||
|
|
@ -1083,8 +1183,12 @@ SDL_EGL_DeleteContext(_THIS, SDL_GLContext context)
|
|||
EGLSurface *
|
||||
SDL_EGL_CreateSurface(_THIS, NativeWindowType nw)
|
||||
{
|
||||
/* max 2 values plus terminator. */
|
||||
EGLint attribs[3];
|
||||
#if SDL_VIDEO_DRIVER_ANDROID
|
||||
EGLint format_wanted;
|
||||
EGLint format_got;
|
||||
#endif
|
||||
/* max 2 key+value pairs, plus terminator. */
|
||||
EGLint attribs[5];
|
||||
int attr = 0;
|
||||
|
||||
EGLSurface * surface;
|
||||
|
|
@ -1092,24 +1196,18 @@ SDL_EGL_CreateSurface(_THIS, NativeWindowType nw)
|
|||
if (SDL_EGL_ChooseConfig(_this) != 0) {
|
||||
return EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
|
||||
#if SDL_VIDEO_DRIVER_ANDROID
|
||||
{
|
||||
/* Android docs recommend doing this!
|
||||
* Ref: http://developer.android.com/reference/android/app/NativeActivity.html
|
||||
*/
|
||||
EGLint format;
|
||||
_this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display,
|
||||
_this->egl_data->egl_config,
|
||||
EGL_NATIVE_VISUAL_ID, &format);
|
||||
/* On Android, EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is
|
||||
* guaranteed to be accepted by ANativeWindow_setBuffersGeometry(). */
|
||||
_this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display,
|
||||
_this->egl_data->egl_config,
|
||||
EGL_NATIVE_VISUAL_ID, &format_wanted);
|
||||
|
||||
ANativeWindow_setBuffersGeometry(nw, 0, 0, format);
|
||||
/* Format based on selected egl config. */
|
||||
ANativeWindow_setBuffersGeometry(nw, 0, 0, format_wanted);
|
||||
#endif
|
||||
|
||||
/* Update SurfaceView holder format.
|
||||
* May triggers a sequence surfaceDestroyed(), surfaceCreated(), surfaceChanged(). */
|
||||
Android_JNI_SetSurfaceViewFormat(format);
|
||||
}
|
||||
#endif
|
||||
if (_this->gl_config.framebuffer_srgb_capable) {
|
||||
#ifdef EGL_KHR_gl_colorspace
|
||||
if (SDL_EGL_HasExtension(_this, SDL_EGL_DISPLAY_EXTENSION, "EGL_KHR_gl_colorspace")) {
|
||||
|
|
@ -1123,6 +1221,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(
|
||||
|
|
@ -1132,6 +1238,12 @@ SDL_EGL_CreateSurface(_THIS, NativeWindowType nw)
|
|||
if (surface == EGL_NO_SURFACE) {
|
||||
SDL_EGL_SetError("unable to create an EGL window surface", "eglCreateWindowSurface");
|
||||
}
|
||||
|
||||
#if SDL_VIDEO_DRIVER_ANDROID
|
||||
format_got = ANativeWindow_getFormat(nw);
|
||||
Android_SetFormat(format_wanted, format_got);
|
||||
#endif
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
#ifdef __SSE__
|
||||
/* *INDENT-OFF* */
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#define SSE_BEGIN \
|
||||
__m128 c128; \
|
||||
c128.m128_u32[0] = color; \
|
||||
|
|
@ -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;
|
||||
|
|
@ -238,7 +238,7 @@ int
|
|||
SDL_FillRect(SDL_Surface * dst, const SDL_Rect * rect, Uint32 color)
|
||||
{
|
||||
if (!dst) {
|
||||
return SDL_SetError("Passed NULL destination surface");
|
||||
return SDL_InvalidParamError("SDL_FillRect(): dst");
|
||||
}
|
||||
|
||||
/* If 'rect' == NULL, then fill the whole surface */
|
||||
|
|
@ -306,12 +306,7 @@ SDL_FillRects(SDL_Surface * dst, const SDL_Rect * rects, int count,
|
|||
int i;
|
||||
|
||||
if (!dst) {
|
||||
return SDL_SetError("Passed NULL destination surface");
|
||||
}
|
||||
|
||||
/* This function doesn't work on surfaces < 8 bpp */
|
||||
if (dst->format->BitsPerPixel < 8) {
|
||||
return SDL_SetError("SDL_FillRect(): Unsupported surface format");
|
||||
return SDL_InvalidParamError("SDL_FillRects(): dst");
|
||||
}
|
||||
|
||||
/* Nothing to do */
|
||||
|
|
@ -321,11 +316,28 @@ SDL_FillRects(SDL_Surface * dst, const SDL_Rect * rects, int count,
|
|||
|
||||
/* Perform software fill */
|
||||
if (!dst->pixels) {
|
||||
return SDL_SetError("SDL_FillRect(): You must lock the surface");
|
||||
return SDL_SetError("SDL_FillRects(): You must lock the surface");
|
||||
}
|
||||
|
||||
if (!rects) {
|
||||
return SDL_SetError("SDL_FillRects() passed NULL rects");
|
||||
return SDL_InvalidParamError("SDL_FillRects(): rects");
|
||||
}
|
||||
|
||||
/* This function doesn't usually work on surfaces < 8 bpp
|
||||
* Except: support for 4bits, when filling full size.
|
||||
*/
|
||||
if (dst->format->BitsPerPixel < 8) {
|
||||
if (count == 1) {
|
||||
const SDL_Rect *r = &rects[0];
|
||||
if (r->x == 0 && r->y == 0 && r->w == dst->w && r->w == dst->h) {
|
||||
if (dst->format->BitsPerPixel == 4) {
|
||||
Uint8 b = (((Uint8) color << 4) | (Uint8) color);
|
||||
SDL_memset(dst->pixels, b, dst->h * dst->pitch);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return SDL_SetError("SDL_FillRects(): Unsupported surface format");
|
||||
}
|
||||
|
||||
#if SDL_ARM_NEON_BLITTERS
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -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;
|
||||
|
|
@ -677,7 +677,7 @@ int
|
|||
SDL_SetPixelFormatPalette(SDL_PixelFormat * format, SDL_Palette *palette)
|
||||
{
|
||||
if (!format) {
|
||||
return SDL_SetError("SDL_SetPixelFormatPalette() passed NULL format");
|
||||
return SDL_InvalidParamError("SDL_SetPixelFormatPalette(): format");
|
||||
}
|
||||
|
||||
if (palette && palette->ncolors > (1 << format->BitsPerPixel)) {
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -947,7 +947,7 @@ Map1to1(SDL_Palette * src, SDL_Palette * dst, int *identical)
|
|||
}
|
||||
*identical = 0;
|
||||
}
|
||||
map = (Uint8 *) SDL_malloc(src->ncolors);
|
||||
map = (Uint8 *) SDL_calloc(256, sizeof(Uint8));
|
||||
if (map == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
return (NULL);
|
||||
|
|
@ -971,7 +971,7 @@ Map1toN(SDL_PixelFormat * src, Uint8 Rmod, Uint8 Gmod, Uint8 Bmod, Uint8 Amod,
|
|||
SDL_Palette *pal = src->palette;
|
||||
|
||||
bpp = ((dst->BytesPerPixel == 3) ? 4 : dst->BytesPerPixel);
|
||||
map = (Uint8 *) SDL_malloc(pal->ncolors * bpp);
|
||||
map = (Uint8 *) SDL_calloc(256, bpp);
|
||||
if (map == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
return (NULL);
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -23,447 +23,8 @@
|
|||
#include "SDL_rect.h"
|
||||
#include "SDL_rect_c.h"
|
||||
|
||||
SDL_bool
|
||||
SDL_HasIntersection(const SDL_Rect * A, const SDL_Rect * B)
|
||||
{
|
||||
int Amin, Amax, Bmin, Bmax;
|
||||
|
||||
if (!A) {
|
||||
SDL_InvalidParamError("A");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (!B) {
|
||||
SDL_InvalidParamError("B");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
/* Special cases for empty rects */
|
||||
if (SDL_RectEmpty(A) || SDL_RectEmpty(B)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
/* Horizontal intersection */
|
||||
Amin = A->x;
|
||||
Amax = Amin + A->w;
|
||||
Bmin = B->x;
|
||||
Bmax = Bmin + B->w;
|
||||
if (Bmin > Amin)
|
||||
Amin = Bmin;
|
||||
if (Bmax < Amax)
|
||||
Amax = Bmax;
|
||||
if (Amax <= Amin)
|
||||
return SDL_FALSE;
|
||||
|
||||
/* Vertical intersection */
|
||||
Amin = A->y;
|
||||
Amax = Amin + A->h;
|
||||
Bmin = B->y;
|
||||
Bmax = Bmin + B->h;
|
||||
if (Bmin > Amin)
|
||||
Amin = Bmin;
|
||||
if (Bmax < Amax)
|
||||
Amax = Bmax;
|
||||
if (Amax <= Amin)
|
||||
return SDL_FALSE;
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
SDL_bool
|
||||
SDL_IntersectRect(const SDL_Rect * A, const SDL_Rect * B, SDL_Rect * result)
|
||||
{
|
||||
int Amin, Amax, Bmin, Bmax;
|
||||
|
||||
if (!A) {
|
||||
SDL_InvalidParamError("A");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (!B) {
|
||||
SDL_InvalidParamError("B");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
SDL_InvalidParamError("result");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
/* Special cases for empty rects */
|
||||
if (SDL_RectEmpty(A) || SDL_RectEmpty(B)) {
|
||||
result->w = 0;
|
||||
result->h = 0;
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
/* Horizontal intersection */
|
||||
Amin = A->x;
|
||||
Amax = Amin + A->w;
|
||||
Bmin = B->x;
|
||||
Bmax = Bmin + B->w;
|
||||
if (Bmin > Amin)
|
||||
Amin = Bmin;
|
||||
result->x = Amin;
|
||||
if (Bmax < Amax)
|
||||
Amax = Bmax;
|
||||
result->w = Amax - Amin;
|
||||
|
||||
/* Vertical intersection */
|
||||
Amin = A->y;
|
||||
Amax = Amin + A->h;
|
||||
Bmin = B->y;
|
||||
Bmax = Bmin + B->h;
|
||||
if (Bmin > Amin)
|
||||
Amin = Bmin;
|
||||
result->y = Amin;
|
||||
if (Bmax < Amax)
|
||||
Amax = Bmax;
|
||||
result->h = Amax - Amin;
|
||||
|
||||
return !SDL_RectEmpty(result);
|
||||
}
|
||||
|
||||
void
|
||||
SDL_UnionRect(const SDL_Rect * A, const SDL_Rect * B, SDL_Rect * result)
|
||||
{
|
||||
int Amin, Amax, Bmin, Bmax;
|
||||
|
||||
if (!A) {
|
||||
SDL_InvalidParamError("A");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!B) {
|
||||
SDL_InvalidParamError("B");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
SDL_InvalidParamError("result");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Special cases for empty Rects */
|
||||
if (SDL_RectEmpty(A)) {
|
||||
if (SDL_RectEmpty(B)) {
|
||||
/* A and B empty */
|
||||
return;
|
||||
} else {
|
||||
/* A empty, B not empty */
|
||||
*result = *B;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (SDL_RectEmpty(B)) {
|
||||
/* A not empty, B empty */
|
||||
*result = *A;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Horizontal union */
|
||||
Amin = A->x;
|
||||
Amax = Amin + A->w;
|
||||
Bmin = B->x;
|
||||
Bmax = Bmin + B->w;
|
||||
if (Bmin < Amin)
|
||||
Amin = Bmin;
|
||||
result->x = Amin;
|
||||
if (Bmax > Amax)
|
||||
Amax = Bmax;
|
||||
result->w = Amax - Amin;
|
||||
|
||||
/* Vertical union */
|
||||
Amin = A->y;
|
||||
Amax = Amin + A->h;
|
||||
Bmin = B->y;
|
||||
Bmax = Bmin + B->h;
|
||||
if (Bmin < Amin)
|
||||
Amin = Bmin;
|
||||
result->y = Amin;
|
||||
if (Bmax > Amax)
|
||||
Amax = Bmax;
|
||||
result->h = Amax - Amin;
|
||||
}
|
||||
|
||||
SDL_bool
|
||||
SDL_EnclosePoints(const SDL_Point * points, int count, const SDL_Rect * clip,
|
||||
SDL_Rect * result)
|
||||
{
|
||||
int minx = 0;
|
||||
int miny = 0;
|
||||
int maxx = 0;
|
||||
int maxy = 0;
|
||||
int x, y, i;
|
||||
|
||||
if (!points) {
|
||||
SDL_InvalidParamError("points");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (count < 1) {
|
||||
SDL_InvalidParamError("count");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (clip) {
|
||||
SDL_bool added = SDL_FALSE;
|
||||
const int clip_minx = clip->x;
|
||||
const int clip_miny = clip->y;
|
||||
const int clip_maxx = clip->x+clip->w-1;
|
||||
const int clip_maxy = clip->y+clip->h-1;
|
||||
|
||||
/* Special case for empty rectangle */
|
||||
if (SDL_RectEmpty(clip)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; ++i) {
|
||||
x = points[i].x;
|
||||
y = points[i].y;
|
||||
|
||||
if (x < clip_minx || x > clip_maxx ||
|
||||
y < clip_miny || y > clip_maxy) {
|
||||
continue;
|
||||
}
|
||||
if (!added) {
|
||||
/* Special case: if no result was requested, we are done */
|
||||
if (result == NULL) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
/* First point added */
|
||||
minx = maxx = x;
|
||||
miny = maxy = y;
|
||||
added = SDL_TRUE;
|
||||
continue;
|
||||
}
|
||||
if (x < minx) {
|
||||
minx = x;
|
||||
} else if (x > maxx) {
|
||||
maxx = x;
|
||||
}
|
||||
if (y < miny) {
|
||||
miny = y;
|
||||
} else if (y > maxy) {
|
||||
maxy = y;
|
||||
}
|
||||
}
|
||||
if (!added) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
} else {
|
||||
/* Special case: if no result was requested, we are done */
|
||||
if (result == NULL) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
/* No clipping, always add the first point */
|
||||
minx = maxx = points[0].x;
|
||||
miny = maxy = points[0].y;
|
||||
|
||||
for (i = 1; i < count; ++i) {
|
||||
x = points[i].x;
|
||||
y = points[i].y;
|
||||
|
||||
if (x < minx) {
|
||||
minx = x;
|
||||
} else if (x > maxx) {
|
||||
maxx = x;
|
||||
}
|
||||
if (y < miny) {
|
||||
miny = y;
|
||||
} else if (y > maxy) {
|
||||
maxy = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result) {
|
||||
result->x = minx;
|
||||
result->y = miny;
|
||||
result->w = (maxx-minx)+1;
|
||||
result->h = (maxy-miny)+1;
|
||||
}
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
/* Use the Cohen-Sutherland algorithm for line clipping */
|
||||
#define CODE_BOTTOM 1
|
||||
#define CODE_TOP 2
|
||||
#define CODE_LEFT 4
|
||||
#define CODE_RIGHT 8
|
||||
|
||||
static int
|
||||
ComputeOutCode(const SDL_Rect * rect, int x, int y)
|
||||
{
|
||||
int code = 0;
|
||||
if (y < rect->y) {
|
||||
code |= CODE_TOP;
|
||||
} else if (y >= rect->y + rect->h) {
|
||||
code |= CODE_BOTTOM;
|
||||
}
|
||||
if (x < rect->x) {
|
||||
code |= CODE_LEFT;
|
||||
} else if (x >= rect->x + rect->w) {
|
||||
code |= CODE_RIGHT;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
SDL_bool
|
||||
SDL_IntersectRectAndLine(const SDL_Rect * rect, int *X1, int *Y1, int *X2,
|
||||
int *Y2)
|
||||
{
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int x1, y1;
|
||||
int x2, y2;
|
||||
int rectx1;
|
||||
int recty1;
|
||||
int rectx2;
|
||||
int recty2;
|
||||
int outcode1, outcode2;
|
||||
|
||||
if (!rect) {
|
||||
SDL_InvalidParamError("rect");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (!X1) {
|
||||
SDL_InvalidParamError("X1");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (!Y1) {
|
||||
SDL_InvalidParamError("Y1");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (!X2) {
|
||||
SDL_InvalidParamError("X2");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (!Y2) {
|
||||
SDL_InvalidParamError("Y2");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
/* Special case for empty rect */
|
||||
if (SDL_RectEmpty(rect)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
x1 = *X1;
|
||||
y1 = *Y1;
|
||||
x2 = *X2;
|
||||
y2 = *Y2;
|
||||
rectx1 = rect->x;
|
||||
recty1 = rect->y;
|
||||
rectx2 = rect->x + rect->w - 1;
|
||||
recty2 = rect->y + rect->h - 1;
|
||||
|
||||
/* Check to see if entire line is inside rect */
|
||||
if (x1 >= rectx1 && x1 <= rectx2 && x2 >= rectx1 && x2 <= rectx2 &&
|
||||
y1 >= recty1 && y1 <= recty2 && y2 >= recty1 && y2 <= recty2) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
/* Check to see if entire line is to one side of rect */
|
||||
if ((x1 < rectx1 && x2 < rectx1) || (x1 > rectx2 && x2 > rectx2) ||
|
||||
(y1 < recty1 && y2 < recty1) || (y1 > recty2 && y2 > recty2)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (y1 == y2) {
|
||||
/* Horizontal line, easy to clip */
|
||||
if (x1 < rectx1) {
|
||||
*X1 = rectx1;
|
||||
} else if (x1 > rectx2) {
|
||||
*X1 = rectx2;
|
||||
}
|
||||
if (x2 < rectx1) {
|
||||
*X2 = rectx1;
|
||||
} else if (x2 > rectx2) {
|
||||
*X2 = rectx2;
|
||||
}
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
if (x1 == x2) {
|
||||
/* Vertical line, easy to clip */
|
||||
if (y1 < recty1) {
|
||||
*Y1 = recty1;
|
||||
} else if (y1 > recty2) {
|
||||
*Y1 = recty2;
|
||||
}
|
||||
if (y2 < recty1) {
|
||||
*Y2 = recty1;
|
||||
} else if (y2 > recty2) {
|
||||
*Y2 = recty2;
|
||||
}
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
/* More complicated Cohen-Sutherland algorithm */
|
||||
outcode1 = ComputeOutCode(rect, x1, y1);
|
||||
outcode2 = ComputeOutCode(rect, x2, y2);
|
||||
while (outcode1 || outcode2) {
|
||||
if (outcode1 & outcode2) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (outcode1) {
|
||||
if (outcode1 & CODE_TOP) {
|
||||
y = recty1;
|
||||
x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
|
||||
} else if (outcode1 & CODE_BOTTOM) {
|
||||
y = recty2;
|
||||
x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
|
||||
} else if (outcode1 & CODE_LEFT) {
|
||||
x = rectx1;
|
||||
y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
|
||||
} else if (outcode1 & CODE_RIGHT) {
|
||||
x = rectx2;
|
||||
y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
|
||||
}
|
||||
x1 = x;
|
||||
y1 = y;
|
||||
outcode1 = ComputeOutCode(rect, x, y);
|
||||
} else {
|
||||
if (outcode2 & CODE_TOP) {
|
||||
y = recty1;
|
||||
x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
|
||||
} else if (outcode2 & CODE_BOTTOM) {
|
||||
y = recty2;
|
||||
x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
|
||||
} else if (outcode2 & CODE_LEFT) {
|
||||
/* If this assertion ever fires, here's the static analysis that warned about it:
|
||||
http://buildbot.libsdl.org/sdl-static-analysis/sdl-macosx-static-analysis/sdl-macosx-static-analysis-1101/report-b0d01a.html#EndPath */
|
||||
SDL_assert(x2 != x1); /* if equal: division by zero. */
|
||||
x = rectx1;
|
||||
y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
|
||||
} else if (outcode2 & CODE_RIGHT) {
|
||||
/* If this assertion ever fires, here's the static analysis that warned about it:
|
||||
http://buildbot.libsdl.org/sdl-static-analysis/sdl-macosx-static-analysis/sdl-macosx-static-analysis-1101/report-39b114.html#EndPath */
|
||||
SDL_assert(x2 != x1); /* if equal: division by zero. */
|
||||
x = rectx2;
|
||||
y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
|
||||
}
|
||||
x2 = x;
|
||||
y2 = y;
|
||||
outcode2 = ComputeOutCode(rect, x, y);
|
||||
}
|
||||
}
|
||||
*X1 = x1;
|
||||
*Y1 = y1;
|
||||
*X2 = x2;
|
||||
*Y2 = y2;
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
/* There's no float version of this at the moment, because it's not a public API
|
||||
and internally we only need the int version. */
|
||||
SDL_bool
|
||||
SDL_GetSpanEnclosingRect(int width, int height,
|
||||
int numrects, const SDL_Rect * rects, SDL_Rect *span)
|
||||
|
|
@ -475,24 +36,16 @@ SDL_GetSpanEnclosingRect(int width, int height,
|
|||
if (width < 1) {
|
||||
SDL_InvalidParamError("width");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (height < 1) {
|
||||
} else if (height < 1) {
|
||||
SDL_InvalidParamError("height");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (!rects) {
|
||||
} else if (!rects) {
|
||||
SDL_InvalidParamError("rects");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (!span) {
|
||||
} else if (!span) {
|
||||
SDL_InvalidParamError("span");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (numrects < 1) {
|
||||
} else if (numrects < 1) {
|
||||
SDL_InvalidParamError("numrects");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
|
@ -527,4 +80,36 @@ SDL_GetSpanEnclosingRect(int width, int height,
|
|||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* For use with the Cohen-Sutherland algorithm for line clipping, in SDL_rect_impl.h */
|
||||
#define CODE_BOTTOM 1
|
||||
#define CODE_TOP 2
|
||||
#define CODE_LEFT 4
|
||||
#define CODE_RIGHT 8
|
||||
|
||||
/* Same code twice, for float and int versions... */
|
||||
#define RECTTYPE SDL_Rect
|
||||
#define POINTTYPE SDL_Point
|
||||
#define SCALARTYPE int
|
||||
#define COMPUTEOUTCODE ComputeOutCode
|
||||
#define SDL_HASINTERSECTION SDL_HasIntersection
|
||||
#define SDL_INTERSECTRECT SDL_IntersectRect
|
||||
#define SDL_RECTEMPTY SDL_RectEmpty
|
||||
#define SDL_UNIONRECT SDL_UnionRect
|
||||
#define SDL_ENCLOSEPOINTS SDL_EnclosePoints
|
||||
#define SDL_INTERSECTRECTANDLINE SDL_IntersectRectAndLine
|
||||
#include "SDL_rect_impl.h"
|
||||
|
||||
#define RECTTYPE SDL_FRect
|
||||
#define POINTTYPE SDL_FPoint
|
||||
#define SCALARTYPE float
|
||||
#define COMPUTEOUTCODE ComputeOutCodeF
|
||||
#define SDL_HASINTERSECTION SDL_HasIntersectionF
|
||||
#define SDL_INTERSECTRECT SDL_IntersectFRect
|
||||
#define SDL_RECTEMPTY SDL_FRectEmpty
|
||||
#define SDL_UNIONRECT SDL_UnionFRect
|
||||
#define SDL_ENCLOSEPOINTS SDL_EncloseFPoints
|
||||
#define SDL_INTERSECTRECTANDLINE SDL_IntersectFRectAndLine
|
||||
#include "SDL_rect_impl.h"
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
444
Engine/lib/sdl/src/video/SDL_rect_impl.h
Normal file
444
Engine/lib/sdl/src/video/SDL_rect_impl.h
Normal file
|
|
@ -0,0 +1,444 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
/* This file is #included twice to support int and float versions with the same code. */
|
||||
|
||||
SDL_bool
|
||||
SDL_HASINTERSECTION(const RECTTYPE * A, const RECTTYPE * B)
|
||||
{
|
||||
SCALARTYPE Amin, Amax, Bmin, Bmax;
|
||||
|
||||
if (!A) {
|
||||
SDL_InvalidParamError("A");
|
||||
return SDL_FALSE;
|
||||
} else if (!B) {
|
||||
SDL_InvalidParamError("B");
|
||||
return SDL_FALSE;
|
||||
} else if (SDL_RECTEMPTY(A) || SDL_RECTEMPTY(B)) {
|
||||
return SDL_FALSE; /* Special cases for empty rects */
|
||||
}
|
||||
|
||||
/* Horizontal intersection */
|
||||
Amin = A->x;
|
||||
Amax = Amin + A->w;
|
||||
Bmin = B->x;
|
||||
Bmax = Bmin + B->w;
|
||||
if (Bmin > Amin) {
|
||||
Amin = Bmin;
|
||||
}
|
||||
if (Bmax < Amax) {
|
||||
Amax = Bmax;
|
||||
}
|
||||
if (Amax <= Amin) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
/* Vertical intersection */
|
||||
Amin = A->y;
|
||||
Amax = Amin + A->h;
|
||||
Bmin = B->y;
|
||||
Bmax = Bmin + B->h;
|
||||
if (Bmin > Amin) {
|
||||
Amin = Bmin;
|
||||
}
|
||||
if (Bmax < Amax) {
|
||||
Amax = Bmax;
|
||||
}
|
||||
if (Amax <= Amin) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
SDL_bool
|
||||
SDL_INTERSECTRECT(const RECTTYPE * A, const RECTTYPE * B, RECTTYPE * result)
|
||||
{
|
||||
SCALARTYPE Amin, Amax, Bmin, Bmax;
|
||||
|
||||
if (!A) {
|
||||
SDL_InvalidParamError("A");
|
||||
return SDL_FALSE;
|
||||
} else if (!B) {
|
||||
SDL_InvalidParamError("B");
|
||||
return SDL_FALSE;
|
||||
} else if (!result) {
|
||||
SDL_InvalidParamError("result");
|
||||
return SDL_FALSE;
|
||||
} else if (SDL_RECTEMPTY(A) || SDL_RECTEMPTY(B)) { /* Special cases for empty rects */
|
||||
result->w = 0;
|
||||
result->h = 0;
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
/* Horizontal intersection */
|
||||
Amin = A->x;
|
||||
Amax = Amin + A->w;
|
||||
Bmin = B->x;
|
||||
Bmax = Bmin + B->w;
|
||||
if (Bmin > Amin) {
|
||||
Amin = Bmin;
|
||||
}
|
||||
result->x = Amin;
|
||||
if (Bmax < Amax) {
|
||||
Amax = Bmax;
|
||||
}
|
||||
result->w = Amax - Amin;
|
||||
|
||||
/* Vertical intersection */
|
||||
Amin = A->y;
|
||||
Amax = Amin + A->h;
|
||||
Bmin = B->y;
|
||||
Bmax = Bmin + B->h;
|
||||
if (Bmin > Amin) {
|
||||
Amin = Bmin;
|
||||
}
|
||||
result->y = Amin;
|
||||
if (Bmax < Amax) {
|
||||
Amax = Bmax;
|
||||
}
|
||||
result->h = Amax - Amin;
|
||||
|
||||
return !SDL_RECTEMPTY(result);
|
||||
}
|
||||
|
||||
void
|
||||
SDL_UNIONRECT(const RECTTYPE * A, const RECTTYPE * B, RECTTYPE * result)
|
||||
{
|
||||
SCALARTYPE Amin, Amax, Bmin, Bmax;
|
||||
|
||||
if (!A) {
|
||||
SDL_InvalidParamError("A");
|
||||
return;
|
||||
} else if (!B) {
|
||||
SDL_InvalidParamError("B");
|
||||
return;
|
||||
} else if (!result) {
|
||||
SDL_InvalidParamError("result");
|
||||
return;
|
||||
} else if (SDL_RECTEMPTY(A)) { /* Special cases for empty Rects */
|
||||
if (SDL_RECTEMPTY(B)) { /* A and B empty */
|
||||
SDL_zerop(result);
|
||||
} else { /* A empty, B not empty */
|
||||
*result = *B;
|
||||
}
|
||||
return;
|
||||
} else if (SDL_RECTEMPTY(B)) { /* A not empty, B empty */
|
||||
*result = *A;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Horizontal union */
|
||||
Amin = A->x;
|
||||
Amax = Amin + A->w;
|
||||
Bmin = B->x;
|
||||
Bmax = Bmin + B->w;
|
||||
if (Bmin < Amin) {
|
||||
Amin = Bmin;
|
||||
}
|
||||
result->x = Amin;
|
||||
if (Bmax > Amax) {
|
||||
Amax = Bmax;
|
||||
}
|
||||
result->w = Amax - Amin;
|
||||
|
||||
/* Vertical union */
|
||||
Amin = A->y;
|
||||
Amax = Amin + A->h;
|
||||
Bmin = B->y;
|
||||
Bmax = Bmin + B->h;
|
||||
if (Bmin < Amin) {
|
||||
Amin = Bmin;
|
||||
}
|
||||
result->y = Amin;
|
||||
if (Bmax > Amax) {
|
||||
Amax = Bmax;
|
||||
}
|
||||
result->h = Amax - Amin;
|
||||
}
|
||||
|
||||
SDL_bool SDL_ENCLOSEPOINTS(const POINTTYPE * points, int count, const RECTTYPE * clip,
|
||||
RECTTYPE * result)
|
||||
{
|
||||
SCALARTYPE minx = 0;
|
||||
SCALARTYPE miny = 0;
|
||||
SCALARTYPE maxx = 0;
|
||||
SCALARTYPE maxy = 0;
|
||||
SCALARTYPE x, y;
|
||||
int i;
|
||||
|
||||
if (!points) {
|
||||
SDL_InvalidParamError("points");
|
||||
return SDL_FALSE;
|
||||
} else if (count < 1) {
|
||||
SDL_InvalidParamError("count");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (clip) {
|
||||
SDL_bool added = SDL_FALSE;
|
||||
const SCALARTYPE clip_minx = clip->x;
|
||||
const SCALARTYPE clip_miny = clip->y;
|
||||
const SCALARTYPE clip_maxx = clip->x+clip->w-1;
|
||||
const SCALARTYPE clip_maxy = clip->y+clip->h-1;
|
||||
|
||||
/* Special case for empty rectangle */
|
||||
if (SDL_RECTEMPTY(clip)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; ++i) {
|
||||
x = points[i].x;
|
||||
y = points[i].y;
|
||||
|
||||
if (x < clip_minx || x > clip_maxx ||
|
||||
y < clip_miny || y > clip_maxy) {
|
||||
continue;
|
||||
}
|
||||
if (!added) {
|
||||
/* Special case: if no result was requested, we are done */
|
||||
if (result == NULL) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
/* First point added */
|
||||
minx = maxx = x;
|
||||
miny = maxy = y;
|
||||
added = SDL_TRUE;
|
||||
continue;
|
||||
}
|
||||
if (x < minx) {
|
||||
minx = x;
|
||||
} else if (x > maxx) {
|
||||
maxx = x;
|
||||
}
|
||||
if (y < miny) {
|
||||
miny = y;
|
||||
} else if (y > maxy) {
|
||||
maxy = y;
|
||||
}
|
||||
}
|
||||
if (!added) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
} else {
|
||||
/* Special case: if no result was requested, we are done */
|
||||
if (result == NULL) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
/* No clipping, always add the first point */
|
||||
minx = maxx = points[0].x;
|
||||
miny = maxy = points[0].y;
|
||||
|
||||
for (i = 1; i < count; ++i) {
|
||||
x = points[i].x;
|
||||
y = points[i].y;
|
||||
|
||||
if (x < minx) {
|
||||
minx = x;
|
||||
} else if (x > maxx) {
|
||||
maxx = x;
|
||||
}
|
||||
if (y < miny) {
|
||||
miny = y;
|
||||
} else if (y > maxy) {
|
||||
maxy = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result) {
|
||||
result->x = minx;
|
||||
result->y = miny;
|
||||
result->w = (maxx-minx)+1;
|
||||
result->h = (maxy-miny)+1;
|
||||
}
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
/* Use the Cohen-Sutherland algorithm for line clipping */
|
||||
static int
|
||||
COMPUTEOUTCODE(const RECTTYPE * rect, SCALARTYPE x, SCALARTYPE y)
|
||||
{
|
||||
int code = 0;
|
||||
if (y < rect->y) {
|
||||
code |= CODE_TOP;
|
||||
} else if (y >= rect->y + rect->h) {
|
||||
code |= CODE_BOTTOM;
|
||||
}
|
||||
if (x < rect->x) {
|
||||
code |= CODE_LEFT;
|
||||
} else if (x >= rect->x + rect->w) {
|
||||
code |= CODE_RIGHT;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
SDL_bool
|
||||
SDL_INTERSECTRECTANDLINE(const RECTTYPE * rect, SCALARTYPE *X1, SCALARTYPE *Y1, SCALARTYPE *X2,
|
||||
SCALARTYPE *Y2)
|
||||
{
|
||||
SCALARTYPE x = 0;
|
||||
SCALARTYPE y = 0;
|
||||
SCALARTYPE x1, y1;
|
||||
SCALARTYPE x2, y2;
|
||||
SCALARTYPE rectx1;
|
||||
SCALARTYPE recty1;
|
||||
SCALARTYPE rectx2;
|
||||
SCALARTYPE recty2;
|
||||
int outcode1, outcode2;
|
||||
|
||||
if (!rect) {
|
||||
SDL_InvalidParamError("rect");
|
||||
return SDL_FALSE;
|
||||
} else if (!X1) {
|
||||
SDL_InvalidParamError("X1");
|
||||
return SDL_FALSE;
|
||||
} else if (!Y1) {
|
||||
SDL_InvalidParamError("Y1");
|
||||
return SDL_FALSE;
|
||||
} else if (!X2) {
|
||||
SDL_InvalidParamError("X2");
|
||||
return SDL_FALSE;
|
||||
} else if (!Y2) {
|
||||
SDL_InvalidParamError("Y2");
|
||||
return SDL_FALSE;
|
||||
} else if (SDL_RECTEMPTY(rect)) {
|
||||
return SDL_FALSE; /* Special case for empty rect */
|
||||
}
|
||||
|
||||
x1 = *X1;
|
||||
y1 = *Y1;
|
||||
x2 = *X2;
|
||||
y2 = *Y2;
|
||||
rectx1 = rect->x;
|
||||
recty1 = rect->y;
|
||||
rectx2 = rect->x + rect->w - 1;
|
||||
recty2 = rect->y + rect->h - 1;
|
||||
|
||||
/* Check to see if entire line is inside rect */
|
||||
if (x1 >= rectx1 && x1 <= rectx2 && x2 >= rectx1 && x2 <= rectx2 &&
|
||||
y1 >= recty1 && y1 <= recty2 && y2 >= recty1 && y2 <= recty2) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
/* Check to see if entire line is to one side of rect */
|
||||
if ((x1 < rectx1 && x2 < rectx1) || (x1 > rectx2 && x2 > rectx2) ||
|
||||
(y1 < recty1 && y2 < recty1) || (y1 > recty2 && y2 > recty2)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (y1 == y2) { /* Horizontal line, easy to clip */
|
||||
if (x1 < rectx1) {
|
||||
*X1 = rectx1;
|
||||
} else if (x1 > rectx2) {
|
||||
*X1 = rectx2;
|
||||
}
|
||||
if (x2 < rectx1) {
|
||||
*X2 = rectx1;
|
||||
} else if (x2 > rectx2) {
|
||||
*X2 = rectx2;
|
||||
}
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
if (x1 == x2) { /* Vertical line, easy to clip */
|
||||
if (y1 < recty1) {
|
||||
*Y1 = recty1;
|
||||
} else if (y1 > recty2) {
|
||||
*Y1 = recty2;
|
||||
}
|
||||
if (y2 < recty1) {
|
||||
*Y2 = recty1;
|
||||
} else if (y2 > recty2) {
|
||||
*Y2 = recty2;
|
||||
}
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
/* More complicated Cohen-Sutherland algorithm */
|
||||
outcode1 = COMPUTEOUTCODE(rect, x1, y1);
|
||||
outcode2 = COMPUTEOUTCODE(rect, x2, y2);
|
||||
while (outcode1 || outcode2) {
|
||||
if (outcode1 & outcode2) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
if (outcode1) {
|
||||
if (outcode1 & CODE_TOP) {
|
||||
y = recty1;
|
||||
x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
|
||||
} else if (outcode1 & CODE_BOTTOM) {
|
||||
y = recty2;
|
||||
x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
|
||||
} else if (outcode1 & CODE_LEFT) {
|
||||
x = rectx1;
|
||||
y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
|
||||
} else if (outcode1 & CODE_RIGHT) {
|
||||
x = rectx2;
|
||||
y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
|
||||
}
|
||||
x1 = x;
|
||||
y1 = y;
|
||||
outcode1 = COMPUTEOUTCODE(rect, x, y);
|
||||
} else {
|
||||
if (outcode2 & CODE_TOP) {
|
||||
y = recty1;
|
||||
x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
|
||||
} else if (outcode2 & CODE_BOTTOM) {
|
||||
y = recty2;
|
||||
x = x1 + ((x2 - x1) * (y - y1)) / (y2 - y1);
|
||||
} else if (outcode2 & CODE_LEFT) {
|
||||
/* If this assertion ever fires, here's the static analysis that warned about it:
|
||||
http://buildbot.libsdl.org/sdl-static-analysis/sdl-macosx-static-analysis/sdl-macosx-static-analysis-1101/report-b0d01a.html#EndPath */
|
||||
SDL_assert(x2 != x1); /* if equal: division by zero. */
|
||||
x = rectx1;
|
||||
y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
|
||||
} else if (outcode2 & CODE_RIGHT) {
|
||||
/* If this assertion ever fires, here's the static analysis that warned about it:
|
||||
http://buildbot.libsdl.org/sdl-static-analysis/sdl-macosx-static-analysis/sdl-macosx-static-analysis-1101/report-39b114.html#EndPath */
|
||||
SDL_assert(x2 != x1); /* if equal: division by zero. */
|
||||
x = rectx2;
|
||||
y = y1 + ((y2 - y1) * (x - x1)) / (x2 - x1);
|
||||
}
|
||||
x2 = x;
|
||||
y2 = y;
|
||||
outcode2 = COMPUTEOUTCODE(rect, x, y);
|
||||
}
|
||||
}
|
||||
*X1 = x1;
|
||||
*Y1 = y1;
|
||||
*X2 = x2;
|
||||
*Y2 = y2;
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
#undef RECTTYPE
|
||||
#undef POINTTYPE
|
||||
#undef SCALARTYPE
|
||||
#undef COMPUTEOUTCODE
|
||||
#undef SDL_HASINTERSECTION
|
||||
#undef SDL_INTERSECTRECT
|
||||
#undef SDL_RECTEMPTY
|
||||
#undef SDL_UNIONRECT
|
||||
#undef SDL_ENCLOSEPOINTS
|
||||
#undef SDL_INTERSECTRECTANDLINE
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -26,6 +26,7 @@
|
|||
#include "SDL_RLEaccel_c.h"
|
||||
#include "SDL_pixels_c.h"
|
||||
#include "SDL_yuv_c.h"
|
||||
#include "../render/SDL_sysrender.h"
|
||||
|
||||
|
||||
/* Check to make sure we can safely check multiplication of surface w and pitch and it won't overflow size_t */
|
||||
|
|
@ -218,7 +219,7 @@ int
|
|||
SDL_SetSurfacePalette(SDL_Surface * surface, SDL_Palette * palette)
|
||||
{
|
||||
if (!surface) {
|
||||
return SDL_SetError("SDL_SetSurfacePalette() passed a NULL surface");
|
||||
return SDL_InvalidParamError("SDL_SetSurfacePalette(): surface");
|
||||
}
|
||||
if (SDL_SetPixelFormatPalette(surface->format, palette) < 0) {
|
||||
return -1;
|
||||
|
|
@ -325,11 +326,12 @@ SDL_GetColorKey(SDL_Surface * surface, Uint32 * key)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* This is a fairly slow function to switch from colorkey to alpha */
|
||||
/* This is a fairly slow function to switch from colorkey to alpha
|
||||
NB: it doesn't handle bpp 1 or 3, because they have no alpha channel */
|
||||
static void
|
||||
SDL_ConvertColorkeyToAlpha(SDL_Surface * surface, SDL_bool ignore_alpha)
|
||||
{
|
||||
int x, y;
|
||||
int x, y, bpp;
|
||||
|
||||
if (!surface) {
|
||||
return;
|
||||
|
|
@ -340,82 +342,74 @@ SDL_ConvertColorkeyToAlpha(SDL_Surface * surface, SDL_bool ignore_alpha)
|
|||
return;
|
||||
}
|
||||
|
||||
bpp = surface->format->BytesPerPixel;
|
||||
|
||||
SDL_LockSurface(surface);
|
||||
|
||||
switch (surface->format->BytesPerPixel) {
|
||||
case 2:
|
||||
{
|
||||
Uint16 *row, *spot;
|
||||
Uint16 ckey = (Uint16) surface->map->info.colorkey;
|
||||
Uint16 mask = (Uint16) (~surface->format->Amask);
|
||||
if (bpp == 2) {
|
||||
Uint16 *row, *spot;
|
||||
Uint16 ckey = (Uint16) surface->map->info.colorkey;
|
||||
Uint16 mask = (Uint16) (~surface->format->Amask);
|
||||
|
||||
/* Ignore, or not, alpha in colorkey comparison */
|
||||
if (ignore_alpha) {
|
||||
ckey &= mask;
|
||||
row = (Uint16 *) surface->pixels;
|
||||
for (y = surface->h; y--;) {
|
||||
spot = row;
|
||||
for (x = surface->w; x--;) {
|
||||
if ((*spot & mask) == ckey) {
|
||||
*spot &= mask;
|
||||
}
|
||||
++spot;
|
||||
/* Ignore, or not, alpha in colorkey comparison */
|
||||
if (ignore_alpha) {
|
||||
ckey &= mask;
|
||||
row = (Uint16 *) surface->pixels;
|
||||
for (y = surface->h; y--;) {
|
||||
spot = row;
|
||||
for (x = surface->w; x--;) {
|
||||
if ((*spot & mask) == ckey) {
|
||||
*spot &= mask;
|
||||
}
|
||||
row += surface->pitch / 2;
|
||||
++spot;
|
||||
}
|
||||
} else {
|
||||
row = (Uint16 *) surface->pixels;
|
||||
for (y = surface->h; y--;) {
|
||||
spot = row;
|
||||
for (x = surface->w; x--;) {
|
||||
if (*spot == ckey) {
|
||||
*spot &= mask;
|
||||
}
|
||||
++spot;
|
||||
row += surface->pitch / 2;
|
||||
}
|
||||
} else {
|
||||
row = (Uint16 *) surface->pixels;
|
||||
for (y = surface->h; y--;) {
|
||||
spot = row;
|
||||
for (x = surface->w; x--;) {
|
||||
if (*spot == ckey) {
|
||||
*spot &= mask;
|
||||
}
|
||||
row += surface->pitch / 2;
|
||||
++spot;
|
||||
}
|
||||
row += surface->pitch / 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
/* FIXME */
|
||||
break;
|
||||
case 4:
|
||||
{
|
||||
Uint32 *row, *spot;
|
||||
Uint32 ckey = surface->map->info.colorkey;
|
||||
Uint32 mask = ~surface->format->Amask;
|
||||
} else if (bpp == 4) {
|
||||
Uint32 *row, *spot;
|
||||
Uint32 ckey = surface->map->info.colorkey;
|
||||
Uint32 mask = ~surface->format->Amask;
|
||||
|
||||
/* Ignore, or not, alpha in colorkey comparison */
|
||||
if (ignore_alpha) {
|
||||
ckey &= mask;
|
||||
row = (Uint32 *) surface->pixels;
|
||||
for (y = surface->h; y--;) {
|
||||
spot = row;
|
||||
for (x = surface->w; x--;) {
|
||||
if ((*spot & mask) == ckey) {
|
||||
*spot &= mask;
|
||||
}
|
||||
++spot;
|
||||
/* Ignore, or not, alpha in colorkey comparison */
|
||||
if (ignore_alpha) {
|
||||
ckey &= mask;
|
||||
row = (Uint32 *) surface->pixels;
|
||||
for (y = surface->h; y--;) {
|
||||
spot = row;
|
||||
for (x = surface->w; x--;) {
|
||||
if ((*spot & mask) == ckey) {
|
||||
*spot &= mask;
|
||||
}
|
||||
row += surface->pitch / 4;
|
||||
++spot;
|
||||
}
|
||||
} else {
|
||||
row = (Uint32 *) surface->pixels;
|
||||
for (y = surface->h; y--;) {
|
||||
spot = row;
|
||||
for (x = surface->w; x--;) {
|
||||
if (*spot == ckey) {
|
||||
*spot &= mask;
|
||||
}
|
||||
++spot;
|
||||
row += surface->pitch / 4;
|
||||
}
|
||||
} else {
|
||||
row = (Uint32 *) surface->pixels;
|
||||
for (y = surface->h; y--;) {
|
||||
spot = row;
|
||||
for (x = surface->w; x--;) {
|
||||
if (*spot == ckey) {
|
||||
*spot &= mask;
|
||||
}
|
||||
row += surface->pitch / 4;
|
||||
++spot;
|
||||
}
|
||||
row += surface->pitch / 4;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
SDL_UnlockSurface(surface);
|
||||
|
|
@ -652,7 +646,7 @@ SDL_UpperBlit(SDL_Surface * src, const SDL_Rect * srcrect,
|
|||
|
||||
/* Make sure the surfaces aren't locked */
|
||||
if (!src || !dst) {
|
||||
return SDL_SetError("SDL_UpperBlit: passed a NULL surface");
|
||||
return SDL_InvalidParamError("SDL_UpperBlit(): src/dst");
|
||||
}
|
||||
if (src->locked || dst->locked) {
|
||||
return SDL_SetError("Surfaces must not be locked during blit");
|
||||
|
|
@ -745,6 +739,14 @@ SDL_UpperBlit(SDL_Surface * src, const SDL_Rect * srcrect,
|
|||
int
|
||||
SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect,
|
||||
SDL_Surface * dst, SDL_Rect * dstrect)
|
||||
{
|
||||
return SDL_PrivateUpperBlitScaled(src, srcrect, dst, dstrect, SDL_ScaleModeNearest);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
SDL_PrivateUpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect,
|
||||
SDL_Surface * dst, SDL_Rect * dstrect, SDL_ScaleMode scaleMode)
|
||||
{
|
||||
double src_x0, src_y0, src_x1, src_y1;
|
||||
double dst_x0, dst_y0, dst_x1, dst_y1;
|
||||
|
|
@ -755,7 +757,7 @@ SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect,
|
|||
|
||||
/* Make sure the surfaces aren't locked */
|
||||
if (!src || !dst) {
|
||||
return SDL_SetError("SDL_UpperBlitScaled: passed a NULL surface");
|
||||
return SDL_InvalidParamError("SDL_UpperBlitScaled(): src/dst");
|
||||
}
|
||||
if (src->locked || dst->locked) {
|
||||
return SDL_SetError("Surfaces must not be locked during blit");
|
||||
|
|
@ -788,25 +790,25 @@ SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect,
|
|||
if (NULL == dstrect) {
|
||||
dst_x0 = 0;
|
||||
dst_y0 = 0;
|
||||
dst_x1 = dst_w - 1;
|
||||
dst_y1 = dst_h - 1;
|
||||
dst_x1 = dst_w;
|
||||
dst_y1 = dst_h;
|
||||
} else {
|
||||
dst_x0 = dstrect->x;
|
||||
dst_y0 = dstrect->y;
|
||||
dst_x1 = dst_x0 + dst_w - 1;
|
||||
dst_y1 = dst_y0 + dst_h - 1;
|
||||
dst_x1 = dst_x0 + dst_w;
|
||||
dst_y1 = dst_y0 + dst_h;
|
||||
}
|
||||
|
||||
if (NULL == srcrect) {
|
||||
src_x0 = 0;
|
||||
src_y0 = 0;
|
||||
src_x1 = src_w - 1;
|
||||
src_y1 = src_h - 1;
|
||||
src_x1 = src_w;
|
||||
src_y1 = src_h;
|
||||
} else {
|
||||
src_x0 = srcrect->x;
|
||||
src_y0 = srcrect->y;
|
||||
src_x1 = src_x0 + src_w - 1;
|
||||
src_y1 = src_y0 + src_h - 1;
|
||||
src_x1 = src_x0 + src_w;
|
||||
src_y1 = src_y0 + src_h;
|
||||
|
||||
/* Clip source rectangle to the source surface */
|
||||
|
||||
|
|
@ -815,9 +817,9 @@ SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect,
|
|||
src_x0 = 0;
|
||||
}
|
||||
|
||||
if (src_x1 >= src->w) {
|
||||
dst_x1 -= (src_x1 - src->w + 1) * scaling_w;
|
||||
src_x1 = src->w - 1;
|
||||
if (src_x1 > src->w) {
|
||||
dst_x1 -= (src_x1 - src->w) * scaling_w;
|
||||
src_x1 = src->w;
|
||||
}
|
||||
|
||||
if (src_y0 < 0) {
|
||||
|
|
@ -825,9 +827,9 @@ SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect,
|
|||
src_y0 = 0;
|
||||
}
|
||||
|
||||
if (src_y1 >= src->h) {
|
||||
dst_y1 -= (src_y1 - src->h + 1) * scaling_h;
|
||||
src_y1 = src->h - 1;
|
||||
if (src_y1 > src->h) {
|
||||
dst_y1 -= (src_y1 - src->h) * scaling_h;
|
||||
src_y1 = src->h;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -844,9 +846,9 @@ SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect,
|
|||
dst_x0 = 0;
|
||||
}
|
||||
|
||||
if (dst_x1 >= dst->clip_rect.w) {
|
||||
src_x1 -= (dst_x1 - dst->clip_rect.w + 1) / scaling_w;
|
||||
dst_x1 = dst->clip_rect.w - 1;
|
||||
if (dst_x1 > dst->clip_rect.w) {
|
||||
src_x1 -= (dst_x1 - dst->clip_rect.w) / scaling_w;
|
||||
dst_x1 = dst->clip_rect.w;
|
||||
}
|
||||
|
||||
if (dst_y0 < 0) {
|
||||
|
|
@ -854,9 +856,9 @@ SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect,
|
|||
dst_y0 = 0;
|
||||
}
|
||||
|
||||
if (dst_y1 >= dst->clip_rect.h) {
|
||||
src_y1 -= (dst_y1 - dst->clip_rect.h + 1) / scaling_h;
|
||||
dst_y1 = dst->clip_rect.h - 1;
|
||||
if (dst_y1 > dst->clip_rect.h) {
|
||||
src_y1 -= (dst_y1 - dst->clip_rect.h) / scaling_h;
|
||||
dst_y1 = dst->clip_rect.h;
|
||||
}
|
||||
|
||||
/* Translate back to surface coordinates */
|
||||
|
|
@ -865,23 +867,32 @@ SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect,
|
|||
dst_y0 += dst->clip_rect.y;
|
||||
dst_y1 += dst->clip_rect.y;
|
||||
|
||||
final_src.x = (int)SDL_floor(src_x0 + 0.5);
|
||||
final_src.y = (int)SDL_floor(src_y0 + 0.5);
|
||||
final_src.w = (int)SDL_floor(src_x1 + 1 + 0.5) - (int)SDL_floor(src_x0 + 0.5);
|
||||
final_src.h = (int)SDL_floor(src_y1 + 1 + 0.5) - (int)SDL_floor(src_y0 + 0.5);
|
||||
final_src.x = (int)SDL_round(src_x0);
|
||||
final_src.y = (int)SDL_round(src_y0);
|
||||
final_src.w = (int)SDL_round(src_x1 - src_x0);
|
||||
final_src.h = (int)SDL_round(src_y1 - src_y0);
|
||||
|
||||
final_dst.x = (int)SDL_floor(dst_x0 + 0.5);
|
||||
final_dst.y = (int)SDL_floor(dst_y0 + 0.5);
|
||||
final_dst.w = (int)SDL_floor(dst_x1 - dst_x0 + 1.5);
|
||||
final_dst.h = (int)SDL_floor(dst_y1 - dst_y0 + 1.5);
|
||||
final_dst.x = (int)SDL_round(dst_x0);
|
||||
final_dst.y = (int)SDL_round(dst_y0);
|
||||
final_dst.w = (int)SDL_round(dst_x1 - dst_x0);
|
||||
final_dst.h = (int)SDL_round(dst_y1 - dst_y0);
|
||||
|
||||
if (final_dst.w < 0)
|
||||
final_dst.w = 0;
|
||||
if (final_dst.h < 0)
|
||||
final_dst.h = 0;
|
||||
/* Clip again */
|
||||
{
|
||||
SDL_Rect tmp;
|
||||
tmp.x = 0;
|
||||
tmp.y = 0;
|
||||
tmp.w = src->w;
|
||||
tmp.h = src->h;
|
||||
SDL_IntersectRect(&tmp, &final_src, &final_src);
|
||||
}
|
||||
|
||||
if (dstrect)
|
||||
/* Clip again */
|
||||
SDL_IntersectRect(&dst->clip_rect, &final_dst, &final_dst);
|
||||
|
||||
if (dstrect) {
|
||||
*dstrect = final_dst;
|
||||
}
|
||||
|
||||
if (final_dst.w == 0 || final_dst.h == 0 ||
|
||||
final_src.w <= 0 || final_src.h <= 0) {
|
||||
|
|
@ -889,7 +900,7 @@ SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect,
|
|||
return 0;
|
||||
}
|
||||
|
||||
return SDL_LowerBlitScaled(src, &final_src, dst, &final_dst);
|
||||
return SDL_PrivateLowerBlitScaled(src, &final_src, dst, &final_dst, scaleMode);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -899,6 +910,13 @@ SDL_UpperBlitScaled(SDL_Surface * src, const SDL_Rect * srcrect,
|
|||
int
|
||||
SDL_LowerBlitScaled(SDL_Surface * src, SDL_Rect * srcrect,
|
||||
SDL_Surface * dst, SDL_Rect * dstrect)
|
||||
{
|
||||
return SDL_PrivateLowerBlitScaled(src, srcrect, dst, dstrect, SDL_ScaleModeNearest);
|
||||
}
|
||||
|
||||
int
|
||||
SDL_PrivateLowerBlitScaled(SDL_Surface * src, SDL_Rect * srcrect,
|
||||
SDL_Surface * dst, SDL_Rect * dstrect, SDL_ScaleMode scaleMode)
|
||||
{
|
||||
static const Uint32 complex_copy_flags = (
|
||||
SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA |
|
||||
|
|
@ -906,17 +924,103 @@ SDL_LowerBlitScaled(SDL_Surface * src, SDL_Rect * srcrect,
|
|||
SDL_COPY_COLORKEY
|
||||
);
|
||||
|
||||
if (srcrect->w > SDL_MAX_UINT16 || srcrect->h > SDL_MAX_UINT16 ||
|
||||
dstrect->w > SDL_MAX_UINT16 || dstrect->h > SDL_MAX_UINT16) {
|
||||
return SDL_SetError("Size too large for scaling");
|
||||
}
|
||||
|
||||
if (!(src->map->info.flags & SDL_COPY_NEAREST)) {
|
||||
src->map->info.flags |= SDL_COPY_NEAREST;
|
||||
SDL_InvalidateMap(src->map);
|
||||
}
|
||||
|
||||
if ( !(src->map->info.flags & complex_copy_flags) &&
|
||||
src->format->format == dst->format->format &&
|
||||
!SDL_ISPIXELFORMAT_INDEXED(src->format->format) ) {
|
||||
return SDL_SoftStretch( src, srcrect, dst, dstrect );
|
||||
if (scaleMode == SDL_ScaleModeNearest) {
|
||||
if ( !(src->map->info.flags & complex_copy_flags) &&
|
||||
src->format->format == dst->format->format &&
|
||||
!SDL_ISPIXELFORMAT_INDEXED(src->format->format) ) {
|
||||
return SDL_SoftStretch( src, srcrect, dst, dstrect );
|
||||
} else {
|
||||
return SDL_LowerBlit( src, srcrect, dst, dstrect );
|
||||
}
|
||||
} else {
|
||||
return SDL_LowerBlit( src, srcrect, dst, dstrect );
|
||||
if ( !(src->map->info.flags & complex_copy_flags) &&
|
||||
src->format->format == dst->format->format &&
|
||||
!SDL_ISPIXELFORMAT_INDEXED(src->format->format) &&
|
||||
src->format->BytesPerPixel == 4 &&
|
||||
src->format->format != SDL_PIXELFORMAT_ARGB2101010) {
|
||||
/* fast path */
|
||||
return SDL_SoftStretchLinear(src, srcrect, dst, dstrect);
|
||||
} else {
|
||||
/* Use intermediate surface(s) */
|
||||
SDL_Surface *tmp1 = NULL;
|
||||
int ret;
|
||||
SDL_Rect srcrect2;
|
||||
int is_complex_copy_flags = (src->map->info.flags & complex_copy_flags);
|
||||
|
||||
Uint32 flags;
|
||||
Uint8 r, g, b;
|
||||
Uint8 alpha;
|
||||
SDL_BlendMode blendMode;
|
||||
|
||||
/* Save source infos */
|
||||
flags = src->flags;
|
||||
SDL_GetSurfaceColorMod(src, &r, &g, &b);
|
||||
SDL_GetSurfaceAlphaMod(src, &alpha);
|
||||
SDL_GetSurfaceBlendMode(src, &blendMode);
|
||||
srcrect2.x = srcrect->x;
|
||||
srcrect2.y = srcrect->y;
|
||||
srcrect2.w = srcrect->w;
|
||||
srcrect2.h = srcrect->h;
|
||||
|
||||
/* Change source format if not appropriate for scaling */
|
||||
if (src->format->BytesPerPixel != 4 || src->format->format == SDL_PIXELFORMAT_ARGB2101010) {
|
||||
SDL_Rect tmprect;
|
||||
int fmt;
|
||||
tmprect.x = 0;
|
||||
tmprect.y = 0;
|
||||
tmprect.w = src->w;
|
||||
tmprect.h = src->h;
|
||||
if (dst->format->BytesPerPixel == 4 && dst->format->format != SDL_PIXELFORMAT_ARGB2101010) {
|
||||
fmt = dst->format->format;
|
||||
} else {
|
||||
fmt = SDL_PIXELFORMAT_ARGB8888;
|
||||
}
|
||||
tmp1 = SDL_CreateRGBSurfaceWithFormat(flags, src->w, src->h, 0, fmt);
|
||||
SDL_LowerBlit(src, srcrect, tmp1, &tmprect);
|
||||
|
||||
|
||||
srcrect2.x = 0;
|
||||
srcrect2.y = 0;
|
||||
SDL_SetSurfaceColorMod(tmp1, r, g, b);
|
||||
SDL_SetSurfaceAlphaMod(tmp1, alpha);
|
||||
SDL_SetSurfaceBlendMode(tmp1, blendMode);
|
||||
|
||||
src = tmp1;
|
||||
}
|
||||
|
||||
/* Intermediate scaling */
|
||||
if (is_complex_copy_flags || src->format->format != dst->format->format) {
|
||||
SDL_Rect tmprect;
|
||||
SDL_Surface *tmp2 = SDL_CreateRGBSurfaceWithFormat(flags, dstrect->w, dstrect->h, 0, src->format->format);
|
||||
SDL_SoftStretchLinear(src, &srcrect2, tmp2, NULL);
|
||||
|
||||
SDL_SetSurfaceColorMod(tmp2, r, g, b);
|
||||
SDL_SetSurfaceAlphaMod(tmp2, alpha);
|
||||
SDL_SetSurfaceBlendMode(tmp2, blendMode);
|
||||
|
||||
tmprect.x = 0;
|
||||
tmprect.y = 0;
|
||||
tmprect.w = dstrect->w;
|
||||
tmprect.h = dstrect->h;
|
||||
ret = SDL_LowerBlit(tmp2, &tmprect, dst, dstrect);
|
||||
SDL_FreeSurface(tmp2);
|
||||
} else {
|
||||
ret = SDL_SoftStretchLinear(src, &srcrect2, dst, dstrect);
|
||||
}
|
||||
|
||||
SDL_FreeSurface(tmp1);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -988,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");
|
||||
|
|
@ -1069,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;
|
||||
}
|
||||
|
|
@ -1097,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);
|
||||
|
|
@ -1275,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");
|
||||
}
|
||||
|
|
@ -1293,8 +1404,7 @@ int SDL_ConvertPixels(int width, int height,
|
|||
}
|
||||
#else
|
||||
if (SDL_ISPIXELFORMAT_FOURCC(src_format) || SDL_ISPIXELFORMAT_FOURCC(dst_format)) {
|
||||
SDL_SetError("SDL not built with YUV support");
|
||||
return -1;
|
||||
return SDL_SetError("SDL not built with YUV support");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -1334,6 +1444,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.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -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;
|
||||
|
|
@ -229,15 +232,20 @@ struct SDL_VideoDevice
|
|||
void (*RestoreWindow) (_THIS, SDL_Window * window);
|
||||
void (*SetWindowBordered) (_THIS, SDL_Window * window, SDL_bool bordered);
|
||||
void (*SetWindowResizable) (_THIS, SDL_Window * window, SDL_bool resizable);
|
||||
void (*SetWindowAlwaysOnTop) (_THIS, SDL_Window * window, SDL_bool on_top);
|
||||
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 (*SetWindowGrab) (_THIS, SDL_Window * window, SDL_bool grabbed);
|
||||
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);
|
||||
int (*CreateWindowFramebuffer) (_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch);
|
||||
int (*UpdateWindowFramebuffer) (_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects);
|
||||
void (*DestroyWindowFramebuffer) (_THIS, SDL_Window * window);
|
||||
void (*OnWindowEnter) (_THIS, SDL_Window * window);
|
||||
int (*FlashWindow) (_THIS, SDL_Window * window, SDL_FlashOperation operation);
|
||||
|
||||
/* * * */
|
||||
/*
|
||||
|
|
@ -288,6 +296,8 @@ struct SDL_VideoDevice
|
|||
/*
|
||||
* Event manager functions
|
||||
*/
|
||||
int (*WaitEventTimeout) (_THIS, int timeout);
|
||||
void (*SendWakeupEvent) (_THIS, SDL_Window *window);
|
||||
void (*PumpEvents) (_THIS);
|
||||
|
||||
/* Suspend the screensaver */
|
||||
|
|
@ -297,6 +307,8 @@ struct SDL_VideoDevice
|
|||
void (*StartTextInput) (_THIS);
|
||||
void (*StopTextInput) (_THIS);
|
||||
void (*SetTextInputRect) (_THIS, SDL_Rect *rect);
|
||||
void (*ClearComposition) (_THIS);
|
||||
SDL_bool (*IsTextInputShown) (_THIS);
|
||||
|
||||
/* Screen keyboard */
|
||||
SDL_bool (*HasScreenKeyboardSupport) (_THIS);
|
||||
|
|
@ -320,8 +332,11 @@ struct SDL_VideoDevice
|
|||
|
||||
/* * * */
|
||||
/* Data common to all drivers */
|
||||
SDL_bool checked_texture_framebuffer;
|
||||
SDL_bool is_dummy;
|
||||
SDL_bool suspend_screensaver;
|
||||
SDL_Window *wakeup_window;
|
||||
SDL_mutex *wakeup_lock; /* Initialized only if WaitEventTimeout/SendWakeupEvent are supported */
|
||||
int num_displays;
|
||||
SDL_VideoDisplay *displays;
|
||||
SDL_Window *windows;
|
||||
|
|
@ -329,6 +344,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 */
|
||||
|
|
@ -427,6 +443,8 @@ extern VideoBootStrap PND_bootstrap;
|
|||
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;
|
||||
|
|
@ -445,6 +463,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);
|
||||
|
|
@ -458,6 +479,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);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -25,12 +25,10 @@
|
|||
|
||||
#include "SDL_stdinc.h"
|
||||
|
||||
#if defined(SDL_LOADSO_DISABLED)
|
||||
#undef SDL_VIDEO_VULKAN
|
||||
#define SDL_VIDEO_VULKAN 0
|
||||
#endif
|
||||
|
||||
#if SDL_VIDEO_VULKAN
|
||||
#if SDL_LOADSO_DISABLED || SDL_LOADSO_DUMMY
|
||||
#error You should not be here.
|
||||
#endif
|
||||
|
||||
#if SDL_VIDEO_DRIVER_ANDROID
|
||||
#define VK_USE_PLATFORM_ANDROID_KHR
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -23,97 +23,97 @@
|
|||
#include "SDL_vulkan_internal.h"
|
||||
#include "SDL_error.h"
|
||||
|
||||
/* !!! FIXME: this file doesn't match coding standards for SDL (brace position, etc). */
|
||||
|
||||
#if SDL_VIDEO_VULKAN
|
||||
|
||||
const char *SDL_Vulkan_GetResultString(VkResult result)
|
||||
{
|
||||
switch((int)result)
|
||||
{
|
||||
case VK_SUCCESS:
|
||||
return "VK_SUCCESS";
|
||||
case VK_NOT_READY:
|
||||
return "VK_NOT_READY";
|
||||
case VK_TIMEOUT:
|
||||
return "VK_TIMEOUT";
|
||||
case VK_EVENT_SET:
|
||||
return "VK_EVENT_SET";
|
||||
case VK_EVENT_RESET:
|
||||
return "VK_EVENT_RESET";
|
||||
case VK_INCOMPLETE:
|
||||
return "VK_INCOMPLETE";
|
||||
case VK_ERROR_OUT_OF_HOST_MEMORY:
|
||||
return "VK_ERROR_OUT_OF_HOST_MEMORY";
|
||||
case VK_ERROR_OUT_OF_DEVICE_MEMORY:
|
||||
return "VK_ERROR_OUT_OF_DEVICE_MEMORY";
|
||||
case VK_ERROR_INITIALIZATION_FAILED:
|
||||
return "VK_ERROR_INITIALIZATION_FAILED";
|
||||
case VK_ERROR_DEVICE_LOST:
|
||||
return "VK_ERROR_DEVICE_LOST";
|
||||
case VK_ERROR_MEMORY_MAP_FAILED:
|
||||
return "VK_ERROR_MEMORY_MAP_FAILED";
|
||||
case VK_ERROR_LAYER_NOT_PRESENT:
|
||||
return "VK_ERROR_LAYER_NOT_PRESENT";
|
||||
case VK_ERROR_EXTENSION_NOT_PRESENT:
|
||||
return "VK_ERROR_EXTENSION_NOT_PRESENT";
|
||||
case VK_ERROR_FEATURE_NOT_PRESENT:
|
||||
return "VK_ERROR_FEATURE_NOT_PRESENT";
|
||||
case VK_ERROR_INCOMPATIBLE_DRIVER:
|
||||
return "VK_ERROR_INCOMPATIBLE_DRIVER";
|
||||
case VK_ERROR_TOO_MANY_OBJECTS:
|
||||
return "VK_ERROR_TOO_MANY_OBJECTS";
|
||||
case VK_ERROR_FORMAT_NOT_SUPPORTED:
|
||||
return "VK_ERROR_FORMAT_NOT_SUPPORTED";
|
||||
case VK_ERROR_FRAGMENTED_POOL:
|
||||
return "VK_ERROR_FRAGMENTED_POOL";
|
||||
case VK_ERROR_UNKNOWN:
|
||||
return "VK_ERROR_UNKNOWN";
|
||||
case VK_ERROR_OUT_OF_POOL_MEMORY:
|
||||
return "VK_ERROR_OUT_OF_POOL_MEMORY";
|
||||
case VK_ERROR_INVALID_EXTERNAL_HANDLE:
|
||||
return "VK_ERROR_INVALID_EXTERNAL_HANDLE";
|
||||
case VK_ERROR_FRAGMENTATION:
|
||||
return "VK_ERROR_FRAGMENTATION";
|
||||
case VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS:
|
||||
return "VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS";
|
||||
case VK_ERROR_SURFACE_LOST_KHR:
|
||||
return "VK_ERROR_SURFACE_LOST_KHR";
|
||||
case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR:
|
||||
return "VK_ERROR_NATIVE_WINDOW_IN_USE_KHR";
|
||||
case VK_SUBOPTIMAL_KHR:
|
||||
return "VK_SUBOPTIMAL_KHR";
|
||||
case VK_ERROR_OUT_OF_DATE_KHR:
|
||||
return "VK_ERROR_OUT_OF_DATE_KHR";
|
||||
case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR:
|
||||
return "VK_ERROR_INCOMPATIBLE_DISPLAY_KHR";
|
||||
case VK_ERROR_VALIDATION_FAILED_EXT:
|
||||
return "VK_ERROR_VALIDATION_FAILED_EXT";
|
||||
case VK_ERROR_INVALID_SHADER_NV:
|
||||
return "VK_ERROR_INVALID_SHADER_NV";
|
||||
case VK_ERROR_INCOMPATIBLE_VERSION_KHR:
|
||||
return "VK_ERROR_INCOMPATIBLE_VERSION_KHR";
|
||||
case VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT:
|
||||
return "VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT";
|
||||
case VK_ERROR_NOT_PERMITTED_EXT:
|
||||
return "VK_ERROR_NOT_PERMITTED_EXT";
|
||||
case VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT:
|
||||
return "VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT";
|
||||
case VK_THREAD_IDLE_KHR:
|
||||
return "VK_THREAD_IDLE_KHR";
|
||||
case VK_THREAD_DONE_KHR:
|
||||
return "VK_THREAD_DONE_KHR";
|
||||
case VK_OPERATION_DEFERRED_KHR:
|
||||
return "VK_OPERATION_DEFERRED_KHR";
|
||||
case VK_OPERATION_NOT_DEFERRED_KHR:
|
||||
return "VK_OPERATION_NOT_DEFERRED_KHR";
|
||||
case VK_PIPELINE_COMPILE_REQUIRED_EXT:
|
||||
return "VK_PIPELINE_COMPILE_REQUIRED_EXT";
|
||||
default:
|
||||
break;
|
||||
switch ((int)result) {
|
||||
case VK_SUCCESS:
|
||||
return "VK_SUCCESS";
|
||||
case VK_NOT_READY:
|
||||
return "VK_NOT_READY";
|
||||
case VK_TIMEOUT:
|
||||
return "VK_TIMEOUT";
|
||||
case VK_EVENT_SET:
|
||||
return "VK_EVENT_SET";
|
||||
case VK_EVENT_RESET:
|
||||
return "VK_EVENT_RESET";
|
||||
case VK_INCOMPLETE:
|
||||
return "VK_INCOMPLETE";
|
||||
case VK_ERROR_OUT_OF_HOST_MEMORY:
|
||||
return "VK_ERROR_OUT_OF_HOST_MEMORY";
|
||||
case VK_ERROR_OUT_OF_DEVICE_MEMORY:
|
||||
return "VK_ERROR_OUT_OF_DEVICE_MEMORY";
|
||||
case VK_ERROR_INITIALIZATION_FAILED:
|
||||
return "VK_ERROR_INITIALIZATION_FAILED";
|
||||
case VK_ERROR_DEVICE_LOST:
|
||||
return "VK_ERROR_DEVICE_LOST";
|
||||
case VK_ERROR_MEMORY_MAP_FAILED:
|
||||
return "VK_ERROR_MEMORY_MAP_FAILED";
|
||||
case VK_ERROR_LAYER_NOT_PRESENT:
|
||||
return "VK_ERROR_LAYER_NOT_PRESENT";
|
||||
case VK_ERROR_EXTENSION_NOT_PRESENT:
|
||||
return "VK_ERROR_EXTENSION_NOT_PRESENT";
|
||||
case VK_ERROR_FEATURE_NOT_PRESENT:
|
||||
return "VK_ERROR_FEATURE_NOT_PRESENT";
|
||||
case VK_ERROR_INCOMPATIBLE_DRIVER:
|
||||
return "VK_ERROR_INCOMPATIBLE_DRIVER";
|
||||
case VK_ERROR_TOO_MANY_OBJECTS:
|
||||
return "VK_ERROR_TOO_MANY_OBJECTS";
|
||||
case VK_ERROR_FORMAT_NOT_SUPPORTED:
|
||||
return "VK_ERROR_FORMAT_NOT_SUPPORTED";
|
||||
case VK_ERROR_FRAGMENTED_POOL:
|
||||
return "VK_ERROR_FRAGMENTED_POOL";
|
||||
case VK_ERROR_UNKNOWN:
|
||||
return "VK_ERROR_UNKNOWN";
|
||||
case VK_ERROR_OUT_OF_POOL_MEMORY:
|
||||
return "VK_ERROR_OUT_OF_POOL_MEMORY";
|
||||
case VK_ERROR_INVALID_EXTERNAL_HANDLE:
|
||||
return "VK_ERROR_INVALID_EXTERNAL_HANDLE";
|
||||
case VK_ERROR_FRAGMENTATION:
|
||||
return "VK_ERROR_FRAGMENTATION";
|
||||
case VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS:
|
||||
return "VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS";
|
||||
case VK_ERROR_SURFACE_LOST_KHR:
|
||||
return "VK_ERROR_SURFACE_LOST_KHR";
|
||||
case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR:
|
||||
return "VK_ERROR_NATIVE_WINDOW_IN_USE_KHR";
|
||||
case VK_SUBOPTIMAL_KHR:
|
||||
return "VK_SUBOPTIMAL_KHR";
|
||||
case VK_ERROR_OUT_OF_DATE_KHR:
|
||||
return "VK_ERROR_OUT_OF_DATE_KHR";
|
||||
case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR:
|
||||
return "VK_ERROR_INCOMPATIBLE_DISPLAY_KHR";
|
||||
case VK_ERROR_VALIDATION_FAILED_EXT:
|
||||
return "VK_ERROR_VALIDATION_FAILED_EXT";
|
||||
case VK_ERROR_INVALID_SHADER_NV:
|
||||
return "VK_ERROR_INVALID_SHADER_NV";
|
||||
#if VK_HEADER_VERSION >= 135 && VK_HEADER_VERSION < 162
|
||||
case VK_ERROR_INCOMPATIBLE_VERSION_KHR:
|
||||
return "VK_ERROR_INCOMPATIBLE_VERSION_KHR";
|
||||
#endif
|
||||
case VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT:
|
||||
return "VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT";
|
||||
case VK_ERROR_NOT_PERMITTED_EXT:
|
||||
return "VK_ERROR_NOT_PERMITTED_EXT";
|
||||
case VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT:
|
||||
return "VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT";
|
||||
case VK_THREAD_IDLE_KHR:
|
||||
return "VK_THREAD_IDLE_KHR";
|
||||
case VK_THREAD_DONE_KHR:
|
||||
return "VK_THREAD_DONE_KHR";
|
||||
case VK_OPERATION_DEFERRED_KHR:
|
||||
return "VK_OPERATION_DEFERRED_KHR";
|
||||
case VK_OPERATION_NOT_DEFERRED_KHR:
|
||||
return "VK_OPERATION_NOT_DEFERRED_KHR";
|
||||
case VK_PIPELINE_COMPILE_REQUIRED_EXT:
|
||||
return "VK_PIPELINE_COMPILE_REQUIRED_EXT";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(result < 0)
|
||||
if (result < 0) {
|
||||
return "VK_ERROR_<Unknown>";
|
||||
}
|
||||
return "VK_<Unknown>";
|
||||
}
|
||||
|
||||
|
|
@ -124,11 +124,9 @@ VkExtensionProperties *SDL_Vulkan_CreateInstanceExtensionsList(
|
|||
Uint32 count = 0;
|
||||
VkResult result = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL);
|
||||
VkExtensionProperties *retval;
|
||||
if(result == VK_ERROR_INCOMPATIBLE_DRIVER)
|
||||
{
|
||||
/* Avoid the ERR_MAX_STRLEN limit by passing part of the message
|
||||
* as a string argument.
|
||||
*/
|
||||
|
||||
if (result == VK_ERROR_INCOMPATIBLE_DRIVER) {
|
||||
/* Avoid the ERR_MAX_STRLEN limit by passing part of the message as a string argument. */
|
||||
SDL_SetError(
|
||||
"You probably don't have a working Vulkan driver installed. %s %s %s(%d)",
|
||||
"Getting Vulkan extensions failed:",
|
||||
|
|
@ -136,9 +134,7 @@ VkExtensionProperties *SDL_Vulkan_CreateInstanceExtensionsList(
|
|||
SDL_Vulkan_GetResultString(result),
|
||||
(int)result);
|
||||
return NULL;
|
||||
}
|
||||
else if(result != VK_SUCCESS)
|
||||
{
|
||||
} else if (result != VK_SUCCESS) {
|
||||
SDL_SetError(
|
||||
"Getting Vulkan extensions failed: vkEnumerateInstanceExtensionProperties returned "
|
||||
"%s(%d)",
|
||||
|
|
@ -146,22 +142,20 @@ VkExtensionProperties *SDL_Vulkan_CreateInstanceExtensionsList(
|
|||
(int)result);
|
||||
return NULL;
|
||||
}
|
||||
if(count == 0)
|
||||
{
|
||||
|
||||
if (count == 0) {
|
||||
retval = SDL_calloc(1, sizeof(VkExtensionProperties)); // so we can return non-null
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
retval = SDL_calloc(count, sizeof(VkExtensionProperties));
|
||||
}
|
||||
if(!retval)
|
||||
{
|
||||
|
||||
if (!retval) {
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = vkEnumerateInstanceExtensionProperties(NULL, &count, retval);
|
||||
if(result != VK_SUCCESS)
|
||||
{
|
||||
if (result != VK_SUCCESS) {
|
||||
SDL_SetError(
|
||||
"Getting Vulkan extensions failed: vkEnumerateInstanceExtensionProperties returned "
|
||||
"%s(%d)",
|
||||
|
|
@ -186,6 +180,7 @@ SDL_bool SDL_Vulkan_GetInstanceExtensions_Helper(unsigned *userCount,
|
|||
SDL_SetError("Output array for SDL_Vulkan_GetInstanceExtensions needs to be at least %d big", nameCount);
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
for (i = 0; i < nameCount; i++) {
|
||||
userNames[i] = names[i];
|
||||
}
|
||||
|
|
@ -226,55 +221,47 @@ SDL_bool SDL_Vulkan_Display_CreateSurface(void *vkGetInstanceProcAddr_,
|
|||
const char *chosenDisplayId;
|
||||
int displayId = 0; /* Counting from physical device 0, display 0 */
|
||||
|
||||
if(!vkEnumeratePhysicalDevices ||
|
||||
if (!vkEnumeratePhysicalDevices ||
|
||||
!vkGetPhysicalDeviceDisplayPropertiesKHR ||
|
||||
!vkGetDisplayModePropertiesKHR ||
|
||||
!vkGetPhysicalDeviceDisplayPlanePropertiesKHR ||
|
||||
!vkGetDisplayPlaneCapabilitiesKHR ||
|
||||
!vkGetDisplayPlaneSupportedDisplaysKHR ||
|
||||
!vkCreateDisplayPlaneSurfaceKHR)
|
||||
{
|
||||
SDL_SetError(VK_KHR_DISPLAY_EXTENSION_NAME
|
||||
" extension is not enabled in the Vulkan instance.");
|
||||
!vkCreateDisplayPlaneSurfaceKHR) {
|
||||
SDL_SetError(VK_KHR_DISPLAY_EXTENSION_NAME " extension is not enabled in the Vulkan instance.");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((chosenDisplayId = SDL_getenv("SDL_VULKAN_DISPLAY")) != NULL)
|
||||
{
|
||||
if ((chosenDisplayId = SDL_getenv("SDL_VULKAN_DISPLAY")) != NULL) {
|
||||
displayId = SDL_atoi(chosenDisplayId);
|
||||
}
|
||||
|
||||
/* Enumerate physical devices */
|
||||
result =
|
||||
vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, NULL);
|
||||
if(result != VK_SUCCESS)
|
||||
{
|
||||
result = vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, NULL);
|
||||
if (result != VK_SUCCESS) {
|
||||
SDL_SetError("Could not enumerate Vulkan physical devices");
|
||||
goto error;
|
||||
}
|
||||
if(physicalDeviceCount == 0)
|
||||
{
|
||||
|
||||
if (physicalDeviceCount == 0) {
|
||||
SDL_SetError("No Vulkan physical devices");
|
||||
goto error;
|
||||
}
|
||||
|
||||
physicalDevices = SDL_malloc(sizeof(VkPhysicalDevice) * physicalDeviceCount);
|
||||
if(!physicalDevices)
|
||||
{
|
||||
if (!physicalDevices) {
|
||||
SDL_OutOfMemory();
|
||||
goto error;
|
||||
}
|
||||
result =
|
||||
vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, physicalDevices);
|
||||
if(result != VK_SUCCESS)
|
||||
{
|
||||
|
||||
result = vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, physicalDevices);
|
||||
if (result != VK_SUCCESS) {
|
||||
SDL_SetError("Error enumerating physical devices");
|
||||
goto error;
|
||||
}
|
||||
|
||||
for(physicalDeviceIndex = 0; physicalDeviceIndex < physicalDeviceCount;
|
||||
physicalDeviceIndex++)
|
||||
{
|
||||
VkPhysicalDevice physicalDevice = physicalDevices[physicalDeviceIndex];
|
||||
for (physicalDeviceIndex = 0; physicalDeviceIndex < physicalDeviceCount; physicalDeviceIndex++) {
|
||||
VkPhysicalDevice physicalDevice = physicalDevices[physicalDeviceIndex];
|
||||
uint32_t displayPropertiesCount = 0;
|
||||
VkDisplayPropertiesKHR *displayProperties = NULL;
|
||||
uint32_t displayModePropertiesCount = 0;
|
||||
|
|
@ -290,32 +277,27 @@ SDL_bool SDL_Vulkan_Display_CreateSurface(void *vkGetInstanceProcAddr_,
|
|||
VkDisplayPlaneCapabilitiesKHR planeCaps;
|
||||
|
||||
/* Get information about the physical displays */
|
||||
result =
|
||||
vkGetPhysicalDeviceDisplayPropertiesKHR(physicalDevice, &displayPropertiesCount, NULL);
|
||||
if (result != VK_SUCCESS || displayPropertiesCount == 0)
|
||||
{
|
||||
result = vkGetPhysicalDeviceDisplayPropertiesKHR(physicalDevice, &displayPropertiesCount, NULL);
|
||||
if (result != VK_SUCCESS || displayPropertiesCount == 0) {
|
||||
/* This device has no physical device display properties, move on to next. */
|
||||
continue;
|
||||
}
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "vulkandisplay: Number of display properties for device %u: %u",
|
||||
physicalDeviceIndex, displayPropertiesCount);
|
||||
|
||||
if ( (displayId < 0) || (((uint32_t) displayId) >= displayPropertiesCount) )
|
||||
{
|
||||
if (displayId < 0 || (uint32_t) displayId >= displayPropertiesCount) {
|
||||
/* Display id specified was higher than number of available displays, move to next physical device. */
|
||||
displayId -= displayPropertiesCount;
|
||||
continue;
|
||||
}
|
||||
|
||||
displayProperties = SDL_malloc(sizeof(VkDisplayPropertiesKHR) * displayPropertiesCount);
|
||||
if(!displayProperties)
|
||||
{
|
||||
if (!displayProperties) {
|
||||
SDL_OutOfMemory();
|
||||
goto error;
|
||||
}
|
||||
|
||||
result =
|
||||
vkGetPhysicalDeviceDisplayPropertiesKHR(physicalDevice, &displayPropertiesCount, displayProperties);
|
||||
result = vkGetPhysicalDeviceDisplayPropertiesKHR(physicalDevice, &displayPropertiesCount, displayProperties);
|
||||
if (result != VK_SUCCESS || displayPropertiesCount == 0) {
|
||||
SDL_free(displayProperties);
|
||||
SDL_SetError("Error enumerating physical device displays");
|
||||
|
|
@ -331,8 +313,7 @@ SDL_bool SDL_Vulkan_Display_CreateSurface(void *vkGetInstanceProcAddr_,
|
|||
displayProperties = NULL;
|
||||
|
||||
/* Get display mode properties for the chosen display */
|
||||
result =
|
||||
vkGetDisplayModePropertiesKHR(physicalDevice, display, &displayModePropertiesCount, NULL);
|
||||
result = vkGetDisplayModePropertiesKHR(physicalDevice, display, &displayModePropertiesCount, NULL);
|
||||
if (result != VK_SUCCESS || displayModePropertiesCount == 0)
|
||||
{
|
||||
SDL_SetError("Error enumerating display modes");
|
||||
|
|
@ -341,14 +322,12 @@ SDL_bool SDL_Vulkan_Display_CreateSurface(void *vkGetInstanceProcAddr_,
|
|||
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "vulkandisplay: Number of display modes: %u", displayModePropertiesCount);
|
||||
|
||||
displayModeProperties = SDL_malloc(sizeof(VkDisplayModePropertiesKHR) * displayModePropertiesCount);
|
||||
if(!displayModeProperties)
|
||||
{
|
||||
if (!displayModeProperties) {
|
||||
SDL_OutOfMemory();
|
||||
goto error;
|
||||
}
|
||||
|
||||
result =
|
||||
vkGetDisplayModePropertiesKHR(physicalDevice, display, &displayModePropertiesCount, displayModeProperties);
|
||||
result = vkGetDisplayModePropertiesKHR(physicalDevice, display, &displayModePropertiesCount, displayModeProperties);
|
||||
if (result != VK_SUCCESS || displayModePropertiesCount == 0) {
|
||||
SDL_SetError("Error enumerating display modes");
|
||||
SDL_free(displayModeProperties);
|
||||
|
|
@ -356,18 +335,16 @@ SDL_bool SDL_Vulkan_Display_CreateSurface(void *vkGetInstanceProcAddr_,
|
|||
}
|
||||
|
||||
/* Try to find a display mode that matches the native resolution */
|
||||
for (i = 0; i < displayModePropertiesCount; ++i)
|
||||
{
|
||||
for (i = 0; i < displayModePropertiesCount; ++i) {
|
||||
if (displayModeProperties[i].parameters.visibleRegion.width == extent.width &&
|
||||
displayModeProperties[i].parameters.visibleRegion.height == extent.height &&
|
||||
displayModeProperties[i].parameters.refreshRate > refreshRate)
|
||||
{
|
||||
displayModeProperties[i].parameters.refreshRate > refreshRate) {
|
||||
bestMatchIndex = i;
|
||||
refreshRate = displayModeProperties[i].parameters.refreshRate;
|
||||
}
|
||||
}
|
||||
if (bestMatchIndex < 0)
|
||||
{
|
||||
|
||||
if (bestMatchIndex < 0) {
|
||||
SDL_SetError("Found no matching display mode");
|
||||
SDL_free(displayModeProperties);
|
||||
goto error;
|
||||
|
|
@ -384,62 +361,53 @@ SDL_bool SDL_Vulkan_Display_CreateSurface(void *vkGetInstanceProcAddr_,
|
|||
displayModeProperties = NULL;
|
||||
|
||||
/* Try to find a plane index that supports our display */
|
||||
result =
|
||||
vkGetPhysicalDeviceDisplayPlanePropertiesKHR(physicalDevice, &displayPlanePropertiesCount, NULL);
|
||||
if (result != VK_SUCCESS || displayPlanePropertiesCount == 0)
|
||||
{
|
||||
result = vkGetPhysicalDeviceDisplayPlanePropertiesKHR(physicalDevice, &displayPlanePropertiesCount, NULL);
|
||||
if (result != VK_SUCCESS || displayPlanePropertiesCount == 0) {
|
||||
SDL_SetError("Error enumerating display planes");
|
||||
goto error;
|
||||
}
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "vulkandisplay: Number of display planes: %u", displayPlanePropertiesCount);
|
||||
|
||||
displayPlaneProperties = SDL_malloc(sizeof(VkDisplayPlanePropertiesKHR) * displayPlanePropertiesCount);
|
||||
if(!displayPlaneProperties)
|
||||
{
|
||||
if (!displayPlaneProperties) {
|
||||
SDL_OutOfMemory();
|
||||
goto error;
|
||||
}
|
||||
|
||||
result =
|
||||
vkGetPhysicalDeviceDisplayPlanePropertiesKHR(physicalDevice, &displayPlanePropertiesCount, displayPlaneProperties);
|
||||
if (result != VK_SUCCESS || displayPlanePropertiesCount == 0)
|
||||
{
|
||||
result = vkGetPhysicalDeviceDisplayPlanePropertiesKHR(physicalDevice, &displayPlanePropertiesCount, displayPlaneProperties);
|
||||
if (result != VK_SUCCESS || displayPlanePropertiesCount == 0) {
|
||||
SDL_SetError("Error enumerating display plane properties");
|
||||
SDL_free(displayPlaneProperties);
|
||||
goto error;
|
||||
}
|
||||
|
||||
for (i = 0; i < displayPlanePropertiesCount; ++i)
|
||||
{
|
||||
for (i = 0; i < displayPlanePropertiesCount; ++i) {
|
||||
uint32_t planeSupportedDisplaysCount = 0;
|
||||
VkDisplayKHR *planeSupportedDisplays = NULL;
|
||||
uint32_t j;
|
||||
|
||||
/* Check if plane is attached to a display, if not, continue. */
|
||||
if (displayPlaneProperties[i].currentDisplay == VK_NULL_HANDLE)
|
||||
if (displayPlaneProperties[i].currentDisplay == VK_NULL_HANDLE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check supported displays for this plane. */
|
||||
result =
|
||||
vkGetDisplayPlaneSupportedDisplaysKHR(physicalDevice, i, &planeSupportedDisplaysCount, NULL);
|
||||
if (result != VK_SUCCESS || planeSupportedDisplaysCount == 0)
|
||||
{
|
||||
result = vkGetDisplayPlaneSupportedDisplaysKHR(physicalDevice, i, &planeSupportedDisplaysCount, NULL);
|
||||
if (result != VK_SUCCESS || planeSupportedDisplaysCount == 0) {
|
||||
continue; /* No supported displays, on to next plane. */
|
||||
}
|
||||
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "vulkandisplay: Number of supported displays for plane %u: %u", i, planeSupportedDisplaysCount);
|
||||
|
||||
planeSupportedDisplays = SDL_malloc(sizeof(VkDisplayKHR) * planeSupportedDisplaysCount);
|
||||
if(!planeSupportedDisplays)
|
||||
{
|
||||
if (!planeSupportedDisplays) {
|
||||
SDL_free(displayPlaneProperties);
|
||||
SDL_OutOfMemory();
|
||||
goto error;
|
||||
}
|
||||
|
||||
result =
|
||||
vkGetDisplayPlaneSupportedDisplaysKHR(physicalDevice, i, &planeSupportedDisplaysCount, planeSupportedDisplays);
|
||||
if (result != VK_SUCCESS || planeSupportedDisplaysCount == 0)
|
||||
{
|
||||
result = vkGetDisplayPlaneSupportedDisplaysKHR(physicalDevice, i, &planeSupportedDisplaysCount, planeSupportedDisplays);
|
||||
if (result != VK_SUCCESS || planeSupportedDisplaysCount == 0) {
|
||||
SDL_SetError("Error enumerating supported displays, or no supported displays");
|
||||
SDL_free(planeSupportedDisplays);
|
||||
SDL_free(displayPlaneProperties);
|
||||
|
|
@ -447,20 +415,19 @@ SDL_bool SDL_Vulkan_Display_CreateSurface(void *vkGetInstanceProcAddr_,
|
|||
}
|
||||
|
||||
for (j = 0; j < planeSupportedDisplaysCount && planeSupportedDisplays[j] != display; ++j)
|
||||
;
|
||||
{
|
||||
}
|
||||
|
||||
SDL_free(planeSupportedDisplays);
|
||||
planeSupportedDisplays = NULL;
|
||||
|
||||
if (j == planeSupportedDisplaysCount)
|
||||
{
|
||||
if (j == planeSupportedDisplaysCount) {
|
||||
/* This display is not supported for this plane, move on. */
|
||||
continue;
|
||||
}
|
||||
|
||||
result = vkGetDisplayPlaneCapabilitiesKHR(physicalDevice, createInfo.displayMode, i, &planeCaps);
|
||||
if (result != VK_SUCCESS)
|
||||
{
|
||||
if (result != VK_SUCCESS) {
|
||||
SDL_SetError("Error getting display plane capabilities");
|
||||
SDL_free(displayPlaneProperties);
|
||||
goto error;
|
||||
|
|
@ -468,8 +435,7 @@ SDL_bool SDL_Vulkan_Display_CreateSurface(void *vkGetInstanceProcAddr_,
|
|||
|
||||
/* Check if plane fulfills extent requirements. */
|
||||
if (extent.width >= planeCaps.minDstExtent.width && extent.height >= planeCaps.minDstExtent.height &&
|
||||
extent.width <= planeCaps.maxDstExtent.width && extent.height <= planeCaps.maxDstExtent.height)
|
||||
{
|
||||
extent.width <= planeCaps.maxDstExtent.width && extent.height <= planeCaps.maxDstExtent.height) {
|
||||
/* If it does, choose this plane. */
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "vulkandisplay: Choosing plane %d, minimum extent %dx%d maximum extent %dx%d", i,
|
||||
planeCaps.minDstExtent.width, planeCaps.minDstExtent.height,
|
||||
|
|
@ -479,8 +445,7 @@ SDL_bool SDL_Vulkan_Display_CreateSurface(void *vkGetInstanceProcAddr_,
|
|||
}
|
||||
}
|
||||
|
||||
if (planeIndex < 0)
|
||||
{
|
||||
if (planeIndex < 0) {
|
||||
SDL_SetError("No plane supports the selected resolution");
|
||||
SDL_free(displayPlaneProperties);
|
||||
goto error;
|
||||
|
|
@ -509,8 +474,7 @@ SDL_bool SDL_Vulkan_Display_CreateSurface(void *vkGetInstanceProcAddr_,
|
|||
SDL_free(physicalDevices);
|
||||
physicalDevices = NULL;
|
||||
|
||||
if (physicalDeviceIndex == physicalDeviceCount)
|
||||
{
|
||||
if (physicalDeviceIndex == physicalDeviceCount) {
|
||||
SDL_SetError("No usable displays found or requested display out of range");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
|
@ -519,16 +483,14 @@ SDL_bool SDL_Vulkan_Display_CreateSurface(void *vkGetInstanceProcAddr_,
|
|||
createInfo.transform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
|
||||
createInfo.globalAlpha = 1.0f;
|
||||
|
||||
result = vkCreateDisplayPlaneSurfaceKHR(instance, &createInfo,
|
||||
NULL, surface);
|
||||
if(result != VK_SUCCESS)
|
||||
{
|
||||
SDL_SetError("vkCreateDisplayPlaneSurfaceKHR failed: %s",
|
||||
SDL_Vulkan_GetResultString(result));
|
||||
result = vkCreateDisplayPlaneSurfaceKHR(instance, &createInfo, NULL, surface);
|
||||
if (result != VK_SUCCESS) {
|
||||
SDL_SetError("vkCreateDisplayPlaneSurfaceKHR failed: %s", SDL_Vulkan_GetResultString(result));
|
||||
return SDL_FALSE;
|
||||
}
|
||||
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "vulkandisplay: Created surface");
|
||||
return SDL_TRUE;
|
||||
|
||||
error:
|
||||
SDL_free(physicalDevices);
|
||||
return SDL_FALSE;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -48,6 +48,18 @@ static void openslES_ResumeDevices(void) {}
|
|||
static void openslES_PauseDevices(void) {}
|
||||
#endif
|
||||
|
||||
#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
|
||||
|
||||
|
||||
|
||||
/* Number of 'type' events in the event queue */
|
||||
static int
|
||||
SDL_NumberOfEvents(Uint32 type)
|
||||
|
|
@ -55,6 +67,7 @@ SDL_NumberOfEvents(Uint32 type)
|
|||
return SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, type, type);
|
||||
}
|
||||
|
||||
#if SDL_VIDEO_OPENGL_EGL
|
||||
static void
|
||||
android_egl_context_restore(SDL_Window *window)
|
||||
{
|
||||
|
|
@ -84,7 +97,7 @@ android_egl_context_backup(SDL_Window *window)
|
|||
data->backup_done = 1;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Android_ResumeSem and Android_PauseSem are signaled from Java_org_libsdl_app_SDLActivity_nativePause and Java_org_libsdl_app_SDLActivity_nativeResume
|
||||
|
|
@ -101,15 +114,18 @@ Android_PumpEvents_Blocking(_THIS)
|
|||
if (videodata->isPaused) {
|
||||
SDL_bool isContextExternal = SDL_IsVideoContextExternal();
|
||||
|
||||
#if SDL_VIDEO_OPENGL_EGL
|
||||
/* Make sure this is the last thing we do before pausing */
|
||||
if (!isContextExternal) {
|
||||
SDL_LockMutex(Android_ActivityMutex);
|
||||
android_egl_context_backup(Android_Window);
|
||||
SDL_UnlockMutex(Android_ActivityMutex);
|
||||
}
|
||||
#endif
|
||||
|
||||
ANDROIDAUDIO_PauseDevices();
|
||||
openslES_PauseDevices();
|
||||
aaudio_PauseDevices();
|
||||
|
||||
if (SDL_SemWait(Android_ResumeSem) == 0) {
|
||||
|
||||
|
|
@ -122,13 +138,16 @@ Android_PumpEvents_Blocking(_THIS)
|
|||
|
||||
ANDROIDAUDIO_ResumeDevices();
|
||||
openslES_ResumeDevices();
|
||||
aaudio_ResumeDevices();
|
||||
|
||||
/* Restore the GL Context from here, as this operation is thread dependent */
|
||||
#if SDL_VIDEO_OPENGL_EGL
|
||||
if (!isContextExternal && !SDL_HasEvent(SDL_QUIT)) {
|
||||
SDL_LockMutex(Android_ActivityMutex);
|
||||
android_egl_context_restore(Android_Window);
|
||||
SDL_UnlockMutex(Android_ActivityMutex);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Make sure SW Keyboard is restored when an app becomes foreground */
|
||||
if (SDL_IsTextInputActive()) {
|
||||
|
|
@ -156,6 +175,11 @@ Android_PumpEvents_Blocking(_THIS)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( aaudio_DetectBrokenPlayState() ) {
|
||||
aaudio_PauseDevices();
|
||||
aaudio_ResumeDevices();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -169,15 +193,18 @@ Android_PumpEvents_NonBlocking(_THIS)
|
|||
SDL_bool isContextExternal = SDL_IsVideoContextExternal();
|
||||
if (backup_context) {
|
||||
|
||||
#if SDL_VIDEO_OPENGL_EGL
|
||||
if (!isContextExternal) {
|
||||
SDL_LockMutex(Android_ActivityMutex);
|
||||
android_egl_context_backup(Android_Window);
|
||||
SDL_UnlockMutex(Android_ActivityMutex);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (videodata->pauseAudio) {
|
||||
ANDROIDAUDIO_PauseDevices();
|
||||
openslES_PauseDevices();
|
||||
aaudio_PauseDevices();
|
||||
}
|
||||
|
||||
backup_context = 0;
|
||||
|
|
@ -196,14 +223,17 @@ Android_PumpEvents_NonBlocking(_THIS)
|
|||
if (videodata->pauseAudio) {
|
||||
ANDROIDAUDIO_ResumeDevices();
|
||||
openslES_ResumeDevices();
|
||||
aaudio_ResumeDevices();
|
||||
}
|
||||
|
||||
#if SDL_VIDEO_OPENGL_EGL
|
||||
/* Restore the GL Context from here, as this operation is thread dependent */
|
||||
if (!isContextExternal && !SDL_HasEvent(SDL_QUIT)) {
|
||||
SDL_LockMutex(Android_ActivityMutex);
|
||||
android_egl_context_restore(Android_Window);
|
||||
SDL_UnlockMutex(Android_ActivityMutex);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Make sure SW Keyboard is restored when an app becomes foreground */
|
||||
if (SDL_IsTextInputActive()) {
|
||||
|
|
@ -232,6 +262,11 @@ Android_PumpEvents_NonBlocking(_THIS)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( aaudio_DetectBrokenPlayState() ) {
|
||||
aaudio_PauseDevices();
|
||||
aaudio_ResumeDevices();
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_ANDROID */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
#if SDL_VIDEO_DRIVER_ANDROID
|
||||
#if SDL_VIDEO_DRIVER_ANDROID && SDL_VIDEO_OPENGL_EGL
|
||||
|
||||
/* Android SDL video driver implementation */
|
||||
|
||||
|
|
@ -69,7 +69,7 @@ Android_GLES_SwapWindow(_THIS, SDL_Window * window)
|
|||
|
||||
/* The following two calls existed in the original Java code
|
||||
* If you happen to have a device that's affected by their removal,
|
||||
* please report to Bugzilla. -- Gabriel
|
||||
* please report to our bug tracker. -- Gabriel
|
||||
*/
|
||||
|
||||
/*_this->egl_data->eglWaitNative(EGL_CORE_NATIVE_ENGINE);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -113,6 +113,10 @@ Android_CreateSystemCursor(SDL_SystemCursor id)
|
|||
static void
|
||||
Android_FreeCursor(SDL_Cursor * cursor)
|
||||
{
|
||||
SDL_AndroidCursorData *data = (SDL_AndroidCursorData*) cursor->driverdata;
|
||||
if (data->custom_cursor != 0) {
|
||||
Android_JNI_DestroyCustomCursor(data->custom_cursor);
|
||||
}
|
||||
SDL_free(cursor->driverdata);
|
||||
SDL_free(cursor);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -64,7 +64,7 @@ int Android_SurfaceWidth = 0;
|
|||
int Android_SurfaceHeight = 0;
|
||||
static int Android_DeviceWidth = 0;
|
||||
static int Android_DeviceHeight = 0;
|
||||
static Uint32 Android_ScreenFormat = SDL_PIXELFORMAT_UNKNOWN;
|
||||
static Uint32 Android_ScreenFormat = SDL_PIXELFORMAT_RGB565; /* Default SurfaceView format, in case this is queried before being filled */
|
||||
static int Android_ScreenRate = 0;
|
||||
SDL_sem *Android_PauseSem = NULL;
|
||||
SDL_sem *Android_ResumeSem = NULL;
|
||||
|
|
@ -128,6 +128,7 @@ Android_CreateDevice(int devindex)
|
|||
device->free = Android_DeleteDevice;
|
||||
|
||||
/* GL pointers */
|
||||
#if SDL_VIDEO_OPENGL_EGL
|
||||
device->GL_LoadLibrary = Android_GLES_LoadLibrary;
|
||||
device->GL_GetProcAddress = Android_GLES_GetProcAddress;
|
||||
device->GL_UnloadLibrary = Android_GLES_UnloadLibrary;
|
||||
|
|
@ -137,6 +138,7 @@ Android_CreateDevice(int devindex)
|
|||
device->GL_GetSwapInterval = Android_GLES_GetSwapInterval;
|
||||
device->GL_SwapWindow = Android_GLES_SwapWindow;
|
||||
device->GL_DeleteContext = Android_GLES_DeleteContext;
|
||||
#endif
|
||||
|
||||
#if SDL_VIDEO_VULKAN
|
||||
device->Vulkan_LoadLibrary = Android_Vulkan_LoadLibrary;
|
||||
|
|
@ -194,7 +196,7 @@ Android_VideoInit(_THIS)
|
|||
return -1;
|
||||
}
|
||||
display = SDL_GetDisplay(display_index);
|
||||
display->orientation = Android_JNI_GetDisplayOrientation();
|
||||
display->orientation = Android_JNI_GetDisplayOrientation();
|
||||
|
||||
SDL_AddDisplayMode(&_this->displays[0], &mode);
|
||||
|
||||
|
|
@ -222,16 +224,54 @@ Android_GetDisplayDPI(_THIS, SDL_VideoDisplay *display, float *ddpi, float *hdpi
|
|||
}
|
||||
|
||||
void
|
||||
Android_SetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, Uint32 format, float rate)
|
||||
Android_SetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, float rate)
|
||||
{
|
||||
Android_SurfaceWidth = surfaceWidth;
|
||||
Android_SurfaceHeight = surfaceHeight;
|
||||
Android_DeviceWidth = deviceWidth;
|
||||
Android_DeviceHeight = deviceHeight;
|
||||
Android_ScreenFormat = format;
|
||||
Android_ScreenRate = (int)rate;
|
||||
}
|
||||
|
||||
static
|
||||
Uint32 format_to_pixelFormat(int format) {
|
||||
Uint32 pf;
|
||||
if (format == AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM) { /* 1 */
|
||||
pf = SDL_PIXELFORMAT_RGBA8888;
|
||||
} else if (format == AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM) { /* 2 */
|
||||
pf = SDL_PIXELFORMAT_RGBX8888;
|
||||
} else if (format == AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM) { /* 3 */
|
||||
pf = SDL_PIXELFORMAT_RGB24;
|
||||
} else if (format == AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM) { /* 4*/
|
||||
pf = SDL_PIXELFORMAT_RGB565;
|
||||
} else if (format == 5) {
|
||||
pf = SDL_PIXELFORMAT_BGRA8888;
|
||||
} else if (format == 6) {
|
||||
pf = SDL_PIXELFORMAT_RGBA5551;
|
||||
} else if (format == 7) {
|
||||
pf = SDL_PIXELFORMAT_RGBA4444;
|
||||
} else {
|
||||
pf = SDL_PIXELFORMAT_UNKNOWN;
|
||||
}
|
||||
return pf;
|
||||
}
|
||||
|
||||
void
|
||||
Android_SetFormat(int format_wanted, int format_got)
|
||||
{
|
||||
Uint32 pf_wanted;
|
||||
Uint32 pf_got;
|
||||
|
||||
pf_wanted = format_to_pixelFormat(format_wanted);
|
||||
pf_got = format_to_pixelFormat(format_got);
|
||||
|
||||
Android_ScreenFormat = pf_got;
|
||||
|
||||
SDL_Log("pixel format wanted %s (%d), got %s (%d)",
|
||||
SDL_GetPixelFormatName(pf_wanted), format_wanted,
|
||||
SDL_GetPixelFormatName(pf_got), format_got);
|
||||
}
|
||||
|
||||
void Android_SendResize(SDL_Window *window)
|
||||
{
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -28,7 +28,8 @@
|
|||
#include "../SDL_sysvideo.h"
|
||||
|
||||
/* Called by the JNI layer when the screen changes size or format */
|
||||
extern void Android_SetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, Uint32 format, float rate);
|
||||
extern void Android_SetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, float rate);
|
||||
extern void Android_SetFormat(int format_wanted, int format_got);
|
||||
extern void Android_SendResize(SDL_Window *window);
|
||||
|
||||
/* Private display data */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -81,6 +81,7 @@ Android_CreateWindow(_THIS, SDL_Window * window)
|
|||
|
||||
/* Do not create EGLSurface for Vulkan window since it will then make the window
|
||||
incompatible with vkCreateAndroidSurfaceKHR */
|
||||
#if SDL_VIDEO_OPENGL_EGL
|
||||
if ((window->flags & SDL_WINDOW_OPENGL) != 0) {
|
||||
data->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) data->native_window);
|
||||
|
||||
|
|
@ -91,6 +92,7 @@ Android_CreateWindow(_THIS, SDL_Window * window)
|
|||
goto endfunction;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
window->driverdata = data;
|
||||
Android_Window = window;
|
||||
|
|
@ -175,9 +177,13 @@ Android_DestroyWindow(_THIS, SDL_Window *window)
|
|||
|
||||
if (window->driverdata) {
|
||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
|
||||
#if SDL_VIDEO_OPENGL_EGL
|
||||
if (data->egl_surface != EGL_NO_SURFACE) {
|
||||
SDL_EGL_DestroySurface(_this, data->egl_surface);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (data->native_window) {
|
||||
ANativeWindow_release(data->native_window);
|
||||
}
|
||||
|
|
@ -198,7 +204,11 @@ Android_GetWindowWMInfo(_THIS, SDL_Window *window, SDL_SysWMinfo *info)
|
|||
info->version.minor == SDL_MINOR_VERSION) {
|
||||
info->subsystem = SDL_SYSWM_ANDROID;
|
||||
info->info.android.window = data->native_window;
|
||||
|
||||
#if SDL_VIDEO_OPENGL_EGL
|
||||
info->info.android.surface = data->egl_surface;
|
||||
#endif
|
||||
|
||||
return SDL_TRUE;
|
||||
} else {
|
||||
SDL_SetError("Application not compiled with SDL %d.%d",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -37,8 +37,10 @@ extern SDL_Window *Android_Window;
|
|||
|
||||
typedef struct
|
||||
{
|
||||
#if SDL_VIDEO_OPENGL_EGL
|
||||
EGLSurface egl_surface;
|
||||
EGLContext egl_context; /* We use this to preserve the context when losing focus */
|
||||
#endif
|
||||
SDL_bool backup_done;
|
||||
ANativeWindow *native_window;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -32,10 +32,14 @@ Cocoa_SetClipboardText(_THIS, const char *text)
|
|||
SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;
|
||||
NSPasteboard *pasteboard;
|
||||
NSString *format = NSPasteboardTypeString;
|
||||
NSString *nsstr = [NSString stringWithUTF8String:text];
|
||||
if (nsstr == nil) {
|
||||
return SDL_SetError("Couldn't create NSString; is your string data in UTF-8 format?");
|
||||
}
|
||||
|
||||
pasteboard = [NSPasteboard generalPasteboard];
|
||||
data->clipboard_count = [pasteboard declareTypes:[NSArray arrayWithObject:format] owner:nil];
|
||||
[pasteboard setString:[NSString stringWithUTF8String:text] forType:format];
|
||||
[pasteboard setString:nsstr forType:format];
|
||||
|
||||
return 0;
|
||||
}}
|
||||
|
|
@ -61,7 +65,7 @@ Cocoa_GetClipboardText(_THIS)
|
|||
} else {
|
||||
utf8 = [string UTF8String];
|
||||
}
|
||||
text = SDL_strdup(utf8);
|
||||
text = SDL_strdup(utf8 ? utf8 : "");
|
||||
} else {
|
||||
text = SDL_strdup("");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -25,6 +25,8 @@
|
|||
|
||||
extern void Cocoa_RegisterApp(void);
|
||||
extern void Cocoa_PumpEvents(_THIS);
|
||||
extern int Cocoa_WaitEventTimeout(_THIS, int timeout);
|
||||
extern void Cocoa_SendWakeupEvent(_THIS, SDL_Window *window);
|
||||
extern void Cocoa_SuspendScreenSaver(_THIS);
|
||||
|
||||
#endif /* SDL_cocoaevents_h_ */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -35,6 +35,24 @@
|
|||
#ifndef NSAppKitVersionNumber10_8
|
||||
#define NSAppKitVersionNumber10_8 1187
|
||||
#endif
|
||||
#ifndef MAC_OS_X_VERSION_10_12
|
||||
#define NSEventTypeApplicationDefined NSApplicationDefined
|
||||
#endif
|
||||
|
||||
static SDL_Window *FindSDLWindowForNSWindow(NSWindow *win)
|
||||
{
|
||||
SDL_Window *sdlwindow = NULL;
|
||||
SDL_VideoDevice *device = SDL_GetVideoDevice();
|
||||
if (device && device->windows) {
|
||||
for (sdlwindow = device->windows; sdlwindow; sdlwindow = sdlwindow->next) {
|
||||
NSWindow *nswindow = ((SDL_WindowData *) sdlwindow->driverdata)->nswindow;
|
||||
if (win == nswindow)
|
||||
return sdlwindow;
|
||||
}
|
||||
}
|
||||
|
||||
return sdlwindow;
|
||||
}
|
||||
|
||||
@interface SDLApplication : NSApplication
|
||||
|
||||
|
|
@ -158,6 +176,13 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent)
|
|||
[center removeObserver:self name:NSApplicationDidBecomeActiveNotification object:nil];
|
||||
[center removeObserver:self name:NSCurrentLocaleDidChangeNotification object:nil];
|
||||
|
||||
/* Remove our URL event handler only if we set it */
|
||||
if ([NSApp delegate] == self) {
|
||||
[[NSAppleEventManager sharedAppleEventManager]
|
||||
removeEventHandlerForEventClass:kInternetEventClass
|
||||
andEventID:kAEGetURL];
|
||||
}
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
|
@ -169,6 +194,10 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent)
|
|||
return;
|
||||
}
|
||||
|
||||
/* Don't do anything if this was not an SDL window that was closed */
|
||||
if (FindSDLWindowForNSWindow(win) == NULL)
|
||||
return;
|
||||
|
||||
/* HACK: Make the next window in the z-order key when the key window is
|
||||
* closed. The custom event loop and/or windowing code we have seems to
|
||||
* prevent the normal behavior: https://bugzilla.libsdl.org/show_bug.cgi?id=1825
|
||||
|
|
@ -213,6 +242,13 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent)
|
|||
return;
|
||||
}
|
||||
|
||||
/* Don't do anything if the application already has a key window
|
||||
* that is not an SDL window.
|
||||
*/
|
||||
if ([NSApp keyWindow] && FindSDLWindowForNSWindow([NSApp keyWindow]) == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_VideoDevice *device = SDL_GetVideoDevice();
|
||||
if (device && device->windows) {
|
||||
SDL_Window *window = device->windows;
|
||||
|
|
@ -262,12 +298,6 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent)
|
|||
[NSApp activateIgnoringOtherApps:YES];
|
||||
}
|
||||
|
||||
[[NSAppleEventManager sharedAppleEventManager]
|
||||
setEventHandler:self
|
||||
andSelector:@selector(handleURLEvent:withReplyEvent:)
|
||||
forEventClass:kInternetEventClass
|
||||
andEventID:kAEGetURL];
|
||||
|
||||
/* If we call this before NSApp activation, macOS might print a complaint
|
||||
* about ApplePersistenceIgnoreState. */
|
||||
[SDLApplication registerUserDefaults];
|
||||
|
|
@ -469,6 +499,15 @@ Cocoa_RegisterApp(void)
|
|||
* termination into SDL_Quit, and we can't handle application:openFile:
|
||||
*/
|
||||
if (![NSApp delegate]) {
|
||||
/* Only register the URL event handler if we are being set as the
|
||||
* app delegate to avoid replacing any existing event handler.
|
||||
*/
|
||||
[[NSAppleEventManager sharedAppleEventManager]
|
||||
setEventHandler:appDelegate
|
||||
andSelector:@selector(handleURLEvent:withReplyEvent:)
|
||||
forEventClass:kInternetEventClass
|
||||
andEventID:kAEGetURL];
|
||||
|
||||
[(NSApplication *)NSApp setDelegate:appDelegate];
|
||||
} else {
|
||||
appDelegate->seenFirstActivate = YES;
|
||||
|
|
@ -476,9 +515,8 @@ Cocoa_RegisterApp(void)
|
|||
}
|
||||
}}
|
||||
|
||||
void
|
||||
Cocoa_PumpEvents(_THIS)
|
||||
{ @autoreleasepool
|
||||
int
|
||||
Cocoa_PumpEventsUntilDate(_THIS, NSDate *expiration, bool accumulate)
|
||||
{
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
|
||||
/* Update activity every 30 seconds to prevent screensaver */
|
||||
|
|
@ -494,9 +532,9 @@ Cocoa_PumpEvents(_THIS)
|
|||
#endif
|
||||
|
||||
for ( ; ; ) {
|
||||
NSEvent *event = [NSApp nextEventMatchingMask:NSEventMaskAny untilDate:[NSDate distantPast] inMode:NSDefaultRunLoopMode dequeue:YES ];
|
||||
NSEvent *event = [NSApp nextEventMatchingMask:NSEventMaskAny untilDate:expiration inMode:NSDefaultRunLoopMode dequeue:YES ];
|
||||
if ( event == nil ) {
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!s_bShouldHandleEventsInSDLApplication) {
|
||||
|
|
@ -505,7 +543,52 @@ Cocoa_PumpEvents(_THIS)
|
|||
|
||||
// Pass events down to SDLApplication to be handled in sendEvent:
|
||||
[NSApp sendEvent:event];
|
||||
if ( !accumulate) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
Cocoa_WaitEventTimeout(_THIS, int timeout)
|
||||
{ @autoreleasepool
|
||||
{
|
||||
if (timeout > 0) {
|
||||
NSDate *limitDate = [NSDate dateWithTimeIntervalSinceNow: (double) timeout / 1000.0];
|
||||
return Cocoa_PumpEventsUntilDate(_this, limitDate, false);
|
||||
} else if (timeout == 0) {
|
||||
return Cocoa_PumpEventsUntilDate(_this, [NSDate distantPast], false);
|
||||
} else {
|
||||
while (Cocoa_PumpEventsUntilDate(_this, [NSDate distantFuture], false) == 0) {
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}}
|
||||
|
||||
void
|
||||
Cocoa_PumpEvents(_THIS)
|
||||
{ @autoreleasepool
|
||||
{
|
||||
Cocoa_PumpEventsUntilDate(_this, [NSDate distantPast], true);
|
||||
}}
|
||||
|
||||
void Cocoa_SendWakeupEvent(_THIS, SDL_Window *window)
|
||||
{ @autoreleasepool
|
||||
{
|
||||
NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
|
||||
|
||||
NSEvent* event = [NSEvent otherEventWithType: NSEventTypeApplicationDefined
|
||||
location: NSMakePoint(0,0)
|
||||
modifierFlags: 0
|
||||
timestamp: 0.0
|
||||
windowNumber: nswindow.windowNumber
|
||||
context: nil
|
||||
subtype: 0
|
||||
data1: 0
|
||||
data2: 0];
|
||||
|
||||
[NSApp postEvent: event atStart: YES];
|
||||
}}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -31,6 +31,8 @@ extern void Cocoa_StartTextInput(_THIS);
|
|||
extern void Cocoa_StopTextInput(_THIS);
|
||||
extern void Cocoa_SetTextInputRect(_THIS, SDL_Rect *rect);
|
||||
|
||||
extern void Cocoa_SetWindowKeyboardGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
|
||||
|
||||
#endif /* SDL_cocoakeyboard_h_ */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -602,6 +602,23 @@ Cocoa_QuitKeyboard(_THIS)
|
|||
{
|
||||
}
|
||||
|
||||
typedef int CGSConnection;
|
||||
typedef enum {
|
||||
CGSGlobalHotKeyEnable = 0,
|
||||
CGSGlobalHotKeyDisable = 1,
|
||||
} CGSGlobalHotKeyOperatingMode;
|
||||
|
||||
extern CGSConnection _CGSDefaultConnection(void);
|
||||
extern CGError CGSSetGlobalHotKeyOperatingMode(CGSConnection connection, CGSGlobalHotKeyOperatingMode mode);
|
||||
|
||||
void
|
||||
Cocoa_SetWindowKeyboardGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
|
||||
{
|
||||
#if SDL_MAC_NO_SANDBOX
|
||||
CGSSetGlobalHotKeyOperatingMode(_CGSDefaultConnection(), grabbed ? CGSGlobalHotKeyDisable : CGSGlobalHotKeyEnable);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_COCOA */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -89,10 +89,8 @@
|
|||
@end
|
||||
|
||||
|
||||
/* Display a Cocoa message box */
|
||||
int
|
||||
Cocoa_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
|
||||
{ @autoreleasepool
|
||||
static void
|
||||
Cocoa_ShowMessageBoxImpl(const SDL_MessageBoxData *messageboxdata, int *buttonid, int *returnValue)
|
||||
{
|
||||
Cocoa_RegisterApp();
|
||||
|
||||
|
|
@ -133,11 +131,8 @@ Cocoa_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
|
|||
|
||||
SDLMessageBoxPresenter* presenter = [[[SDLMessageBoxPresenter alloc] initWithParentWindow:messageboxdata->window] autorelease];
|
||||
|
||||
[presenter performSelectorOnMainThread:@selector(showAlert:)
|
||||
withObject:alert
|
||||
waitUntilDone:YES];
|
||||
[presenter showAlert:alert];
|
||||
|
||||
int returnValue = 0;
|
||||
NSInteger clicked = presenter->clicked;
|
||||
if (clicked >= NSAlertFirstButtonReturn) {
|
||||
clicked -= NSAlertFirstButtonReturn;
|
||||
|
|
@ -145,10 +140,24 @@ Cocoa_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
|
|||
clicked = messageboxdata->numbuttons - 1 - clicked;
|
||||
}
|
||||
*buttonid = buttons[clicked].buttonid;
|
||||
*returnValue = 0;
|
||||
} else {
|
||||
returnValue = SDL_SetError("Did not get a valid `clicked button' id: %ld", (long)clicked);
|
||||
*returnValue = SDL_SetError("Did not get a valid `clicked button' id: %ld", (long)clicked);
|
||||
}
|
||||
}
|
||||
|
||||
/* Display a Cocoa message box */
|
||||
int
|
||||
Cocoa_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
|
||||
{ @autoreleasepool
|
||||
{
|
||||
__block int returnValue = 0;
|
||||
|
||||
if ([NSThread isMainThread]) {
|
||||
Cocoa_ShowMessageBoxImpl(messageboxdata, buttonid, &returnValue);
|
||||
} else {
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{ Cocoa_ShowMessageBoxImpl(messageboxdata, buttonid, &returnValue); });
|
||||
}
|
||||
return returnValue;
|
||||
}}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -39,7 +39,6 @@
|
|||
#import <Metal/Metal.h>
|
||||
#import <QuartzCore/CAMetalLayer.h>
|
||||
|
||||
#define METALVIEW_TAG 255
|
||||
|
||||
@interface SDL_cocoametalview : NSView
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -31,6 +31,8 @@
|
|||
#if SDL_VIDEO_DRIVER_COCOA && (SDL_VIDEO_VULKAN || SDL_VIDEO_METAL)
|
||||
|
||||
#include "SDL_events.h"
|
||||
#include "SDL_syswm.h"
|
||||
|
||||
|
||||
static int SDLCALL
|
||||
SDL_MetalViewEventWatch(void *userdata, SDL_Event *event)
|
||||
|
|
@ -103,7 +105,7 @@ SDL_MetalViewEventWatch(void *userdata, SDL_Event *event)
|
|||
|
||||
- (NSInteger)tag
|
||||
{
|
||||
return METALVIEW_TAG;
|
||||
return SDL_METALVIEW_TAG;
|
||||
}
|
||||
|
||||
- (void)updateDrawableSize
|
||||
|
|
@ -172,8 +174,8 @@ void
|
|||
Cocoa_Metal_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h)
|
||||
{ @autoreleasepool {
|
||||
SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
|
||||
NSView *view = data->nswindow.contentView;
|
||||
SDL_cocoametalview* metalview = [view viewWithTag:METALVIEW_TAG];
|
||||
NSView *contentView = data->sdlContentView;
|
||||
SDL_cocoametalview* metalview = [contentView viewWithTag:SDL_METALVIEW_TAG];
|
||||
if (metalview) {
|
||||
CAMetalLayer *layer = (CAMetalLayer*)metalview.layer;
|
||||
SDL_assert(layer != NULL);
|
||||
|
|
@ -184,7 +186,21 @@ Cocoa_Metal_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h)
|
|||
*h = layer.drawableSize.height;
|
||||
}
|
||||
} else {
|
||||
SDL_GetWindowSize(window, w, h);
|
||||
/* Fall back to the viewport size. */
|
||||
NSRect viewport = [contentView bounds];
|
||||
if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
|
||||
/* This gives us the correct viewport for a Retina-enabled view, only
|
||||
* supported on 10.7+. */
|
||||
if ([contentView respondsToSelector:@selector(convertRectToBacking:)]) {
|
||||
viewport = [contentView convertRectToBacking:viewport];
|
||||
}
|
||||
}
|
||||
if (w) {
|
||||
*w = viewport.size.width;
|
||||
}
|
||||
if (h) {
|
||||
*h = viewport.size.height;
|
||||
}
|
||||
}
|
||||
}}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -40,6 +40,9 @@
|
|||
#ifndef MAC_OS_X_VERSION_10_13
|
||||
#define NSAppKitVersionNumber10_12 1504
|
||||
#endif
|
||||
#if (IOGRAPHICSTYPES_REV < 40)
|
||||
#define kDisplayModeNativeFlag 0x02000000
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
|
|
@ -162,7 +165,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 +181,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 +380,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);
|
||||
|
|
@ -452,28 +457,68 @@ Cocoa_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdp
|
|||
/* we need the backingScaleFactor for Retina displays, which is only exposed through NSScreen, not CGDisplay, afaik, so find our screen... */
|
||||
CGFloat scaleFactor = 1.0f;
|
||||
NSArray *screens = [NSScreen screens];
|
||||
NSSize displayNativeSize;
|
||||
displayNativeSize.width = (int) CGDisplayPixelsWide(data->display);
|
||||
displayNativeSize.height = (int) CGDisplayPixelsHigh(data->display);
|
||||
|
||||
for (NSScreen *screen in screens) {
|
||||
const CGDirectDisplayID dpyid = (const CGDirectDisplayID ) [[[screen deviceDescription] objectForKey:@"NSScreenNumber"] unsignedIntValue];
|
||||
if (dpyid == data->display) {
|
||||
if ([screen respondsToSelector:@selector(backingScaleFactor)]) { // Mac OS X 10.7 and later
|
||||
#ifdef MAC_OS_X_VERSION_10_8
|
||||
/* Neither CGDisplayScreenSize(description's NSScreenNumber) nor [NSScreen backingScaleFactor] can calculate the correct dpi in macOS. E.g. backingScaleFactor is always 2 in all display modes for rMBP 16" */
|
||||
if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_7) {
|
||||
CFStringRef dmKeys[1] = { kCGDisplayShowDuplicateLowResolutionModes };
|
||||
CFBooleanRef dmValues[1] = { kCFBooleanTrue };
|
||||
CFDictionaryRef dmOptions = CFDictionaryCreate(kCFAllocatorDefault, (const void**) dmKeys, (const void**) dmValues, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks );
|
||||
CFArrayRef allDisplayModes = CGDisplayCopyAllDisplayModes(dpyid, dmOptions);
|
||||
CFIndex n = CFArrayGetCount(allDisplayModes);
|
||||
for(CFIndex i = 0; i < n; ++i) {
|
||||
CGDisplayModeRef m = (CGDisplayModeRef)CFArrayGetValueAtIndex(allDisplayModes, i);
|
||||
CGFloat width = CGDisplayModeGetPixelWidth(m);
|
||||
CGFloat height = CGDisplayModeGetPixelHeight(m);
|
||||
CGFloat HiDPIWidth = CGDisplayModeGetWidth(m);
|
||||
|
||||
//Only check 1x mode
|
||||
if(width == HiDPIWidth) {
|
||||
if (CGDisplayModeGetIOFlags(m) & kDisplayModeNativeFlag) {
|
||||
displayNativeSize.width = width;
|
||||
displayNativeSize.height = height;
|
||||
break;
|
||||
}
|
||||
|
||||
//Get the largest size even if kDisplayModeNativeFlag is not present e.g. iMac 27-Inch with 5K Retina
|
||||
if(width > displayNativeSize.width) {
|
||||
displayNativeSize.width = width;
|
||||
displayNativeSize.height = height;
|
||||
}
|
||||
}
|
||||
}
|
||||
CFRelease(allDisplayModes);
|
||||
CFRelease(dmOptions);
|
||||
} else
|
||||
#endif
|
||||
if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) {
|
||||
// fallback for 10.7
|
||||
scaleFactor = [screen backingScaleFactor];
|
||||
displayNativeSize.width = displayNativeSize.width * scaleFactor;
|
||||
displayNativeSize.height = displayNativeSize.height * scaleFactor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const CGSize displaySize = CGDisplayScreenSize(data->display);
|
||||
const int pixelWidth = (int) CGDisplayPixelsWide(data->display);
|
||||
const int pixelHeight = (int) CGDisplayPixelsHigh(data->display);
|
||||
const int pixelWidth = displayNativeSize.width;
|
||||
const int pixelHeight = displayNativeSize.height;
|
||||
|
||||
if (ddpi) {
|
||||
*ddpi = (SDL_ComputeDiagonalDPI(pixelWidth, pixelHeight, displaySize.width / MM_IN_INCH, displaySize.height / MM_IN_INCH)) * scaleFactor;
|
||||
*ddpi = (SDL_ComputeDiagonalDPI(pixelWidth, pixelHeight, displaySize.width / MM_IN_INCH, displaySize.height / MM_IN_INCH));
|
||||
}
|
||||
if (hdpi) {
|
||||
*hdpi = (pixelWidth * MM_IN_INCH / displaySize.width) * scaleFactor;
|
||||
*hdpi = (pixelWidth * MM_IN_INCH / displaySize.width);
|
||||
}
|
||||
if (vdpi) {
|
||||
*vdpi = (pixelHeight * MM_IN_INCH / displaySize.height) * scaleFactor;
|
||||
*vdpi = (pixelHeight * MM_IN_INCH / displaySize.height);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -499,7 +544,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 +591,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);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -40,7 +40,6 @@ typedef struct {
|
|||
/* What location we last saw the cursor move to. */
|
||||
CGFloat lastMoveX;
|
||||
CGFloat lastMoveY;
|
||||
void *tapdata;
|
||||
} SDL_MouseData;
|
||||
|
||||
@interface NSCursor (InvisibleCursor)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -24,7 +24,6 @@
|
|||
|
||||
#include "SDL_events.h"
|
||||
#include "SDL_cocoamouse.h"
|
||||
#include "SDL_cocoamousetap.h"
|
||||
#include "SDL_cocoavideo.h"
|
||||
|
||||
#include "../../events/SDL_mouse_c.h"
|
||||
|
|
@ -216,8 +215,8 @@ Cocoa_WarpMouseGlobal(int x, int y)
|
|||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
if (mouse->focus) {
|
||||
SDL_WindowData *data = (SDL_WindowData *) mouse->focus->driverdata;
|
||||
if ([data->listener isMoving]) {
|
||||
DLog("Postponing warp, window being moved.");
|
||||
if ([data->listener isMovingOrFocusClickPending]) {
|
||||
DLog("Postponing warp, window being moved or focused.");
|
||||
[data->listener setPendingMoveX:x Y:y];
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -254,7 +253,7 @@ Cocoa_WarpMouseGlobal(int x, int y)
|
|||
static void
|
||||
Cocoa_WarpMouse(SDL_Window * window, int x, int y)
|
||||
{
|
||||
Cocoa_WarpMouseGlobal(x + window->x, y + window->y);
|
||||
Cocoa_WarpMouseGlobal(window->x + x, window->y + y);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -263,16 +262,16 @@ Cocoa_SetRelativeMouseMode(SDL_bool enabled)
|
|||
/* We will re-apply the relative mode when the window gets focus, if it
|
||||
* doesn't have focus right now.
|
||||
*/
|
||||
SDL_Window *window = SDL_GetMouseFocus();
|
||||
SDL_Window *window = SDL_GetKeyboardFocus();
|
||||
if (!window) {
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We will re-apply the relative mode when the window finishes being moved,
|
||||
* if it is being moved right now.
|
||||
*/
|
||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
if ([data->listener isMoving]) {
|
||||
if ([data->listener isMovingOrFocusClickPending]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -348,14 +347,40 @@ Cocoa_InitMouse(_THIS)
|
|||
|
||||
SDL_SetDefaultCursor(Cocoa_CreateDefaultCursor());
|
||||
|
||||
Cocoa_InitMouseEventTap(driverdata);
|
||||
|
||||
const NSPoint location = [NSEvent mouseLocation];
|
||||
driverdata->lastMoveX = location.x;
|
||||
driverdata->lastMoveY = location.y;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
Cocoa_HandleTitleButtonEvent(_THIS, NSEvent *event)
|
||||
{
|
||||
SDL_Window *window;
|
||||
NSWindow *nswindow = [event window];
|
||||
|
||||
for (window = _this->windows; window; window = window->next) {
|
||||
SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
|
||||
if (data && data->nswindow == nswindow) {
|
||||
switch ([event type]) {
|
||||
case NSEventTypeLeftMouseDown:
|
||||
case NSEventTypeRightMouseDown:
|
||||
case NSEventTypeOtherMouseDown:
|
||||
[data->listener setFocusClickPending:[event buttonNumber]];
|
||||
break;
|
||||
case NSEventTypeLeftMouseUp:
|
||||
case NSEventTypeRightMouseUp:
|
||||
case NSEventTypeOtherMouseUp:
|
||||
[data->listener clearFocusClickPending:[event buttonNumber]];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Cocoa_HandleMouseEvent(_THIS, NSEvent *event)
|
||||
{
|
||||
|
|
@ -366,6 +391,21 @@ Cocoa_HandleMouseEvent(_THIS, NSEvent *event)
|
|||
case NSEventTypeOtherMouseDragged:
|
||||
break;
|
||||
|
||||
case NSEventTypeLeftMouseDown:
|
||||
case NSEventTypeLeftMouseUp:
|
||||
case NSEventTypeRightMouseDown:
|
||||
case NSEventTypeRightMouseUp:
|
||||
case NSEventTypeOtherMouseDown:
|
||||
case NSEventTypeOtherMouseUp:
|
||||
if ([event window]) {
|
||||
NSRect windowRect = [[[event window] contentView] frame];
|
||||
if (!NSMouseInRect([event locationInWindow], windowRect, NO)) {
|
||||
Cocoa_HandleTitleButtonEvent(_this, event);
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
default:
|
||||
/* Ignore any other events. */
|
||||
return;
|
||||
|
|
@ -433,15 +473,19 @@ Cocoa_HandleMouseWheel(SDL_Window *window, NSEvent *event)
|
|||
}
|
||||
}
|
||||
|
||||
if (x > 0) {
|
||||
x = SDL_ceil(x);
|
||||
} else if (x < 0) {
|
||||
x = SDL_floor(x);
|
||||
}
|
||||
if (y > 0) {
|
||||
y = SDL_ceil(y);
|
||||
} else if (y < 0) {
|
||||
y = SDL_floor(y);
|
||||
/* For discrete scroll events from conventional mice, always send a full tick.
|
||||
For continuous scroll events from trackpads, send fractional deltas for smoother scrolling. */
|
||||
if (![event respondsToSelector:@selector(hasPreciseScrollingDeltas)] || ![event hasPreciseScrollingDeltas]) {
|
||||
if (x > 0) {
|
||||
x = SDL_ceil(x);
|
||||
} else if (x < 0) {
|
||||
x = SDL_floor(x);
|
||||
}
|
||||
if (y > 0) {
|
||||
y = SDL_ceil(y);
|
||||
} else if (y < 0) {
|
||||
y = SDL_floor(y);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_SendMouseWheel(window, mouseID, x, y, direction);
|
||||
|
|
@ -467,8 +511,6 @@ Cocoa_QuitMouse(_THIS)
|
|||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
if (mouse) {
|
||||
if (mouse->driverdata) {
|
||||
Cocoa_QuitMouseEventTap(((SDL_MouseData*)mouse->driverdata));
|
||||
|
||||
SDL_free(mouse->driverdata);
|
||||
mouse->driverdata = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,286 +0,0 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 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_COCOA
|
||||
|
||||
#include "SDL_cocoamousetap.h"
|
||||
|
||||
/* Event taps are forbidden in the Mac App Store, so we can only enable this
|
||||
* code if your app doesn't need to ship through the app store.
|
||||
* This code makes it so that a grabbed cursor cannot "leak" a mouse click
|
||||
* past the edge of the window if moving the cursor too fast.
|
||||
*/
|
||||
#if SDL_MAC_NO_SANDBOX
|
||||
|
||||
#include "SDL_keyboard.h"
|
||||
#include "SDL_cocoavideo.h"
|
||||
#include "../../thread/SDL_systhread.h"
|
||||
|
||||
#include "../../events/SDL_mouse_c.h"
|
||||
|
||||
typedef struct {
|
||||
CFMachPortRef tap;
|
||||
CFRunLoopRef runloop;
|
||||
CFRunLoopSourceRef runloopSource;
|
||||
SDL_Thread *thread;
|
||||
SDL_sem *runloopStartedSemaphore;
|
||||
} SDL_MouseEventTapData;
|
||||
|
||||
static const CGEventMask movementEventsMask =
|
||||
CGEventMaskBit(kCGEventLeftMouseDragged)
|
||||
| CGEventMaskBit(kCGEventRightMouseDragged)
|
||||
| CGEventMaskBit(kCGEventMouseMoved);
|
||||
|
||||
static const CGEventMask allGrabbedEventsMask =
|
||||
CGEventMaskBit(kCGEventLeftMouseDown) | CGEventMaskBit(kCGEventLeftMouseUp)
|
||||
| CGEventMaskBit(kCGEventRightMouseDown) | CGEventMaskBit(kCGEventRightMouseUp)
|
||||
| CGEventMaskBit(kCGEventOtherMouseDown) | CGEventMaskBit(kCGEventOtherMouseUp)
|
||||
| CGEventMaskBit(kCGEventLeftMouseDragged) | CGEventMaskBit(kCGEventRightMouseDragged)
|
||||
| CGEventMaskBit(kCGEventMouseMoved);
|
||||
|
||||
static CGEventRef
|
||||
Cocoa_MouseTapCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon)
|
||||
{
|
||||
SDL_MouseEventTapData *tapdata = (SDL_MouseEventTapData*)refcon;
|
||||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
SDL_Window *window = SDL_GetKeyboardFocus();
|
||||
NSWindow *nswindow;
|
||||
NSRect windowRect;
|
||||
CGPoint eventLocation;
|
||||
|
||||
switch (type) {
|
||||
case kCGEventTapDisabledByTimeout:
|
||||
{
|
||||
CGEventTapEnable(tapdata->tap, true);
|
||||
return NULL;
|
||||
}
|
||||
case kCGEventTapDisabledByUserInput:
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (!window || !mouse) {
|
||||
return event;
|
||||
}
|
||||
|
||||
if (mouse->relative_mode) {
|
||||
return event;
|
||||
}
|
||||
|
||||
if (!(window->flags & SDL_WINDOW_INPUT_GRABBED)) {
|
||||
return event;
|
||||
}
|
||||
|
||||
/* This is the same coordinate system as Cocoa uses. */
|
||||
nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
|
||||
eventLocation = CGEventGetUnflippedLocation(event);
|
||||
windowRect = [nswindow contentRectForFrameRect:[nswindow frame]];
|
||||
|
||||
if (!NSMouseInRect(NSPointFromCGPoint(eventLocation), windowRect, NO)) {
|
||||
|
||||
/* This is in CGs global screenspace coordinate system, which has a
|
||||
* flipped Y.
|
||||
*/
|
||||
CGPoint newLocation = CGEventGetLocation(event);
|
||||
|
||||
if (eventLocation.x < NSMinX(windowRect)) {
|
||||
newLocation.x = NSMinX(windowRect);
|
||||
} else if (eventLocation.x >= NSMaxX(windowRect)) {
|
||||
newLocation.x = NSMaxX(windowRect) - 1.0;
|
||||
}
|
||||
|
||||
if (eventLocation.y <= NSMinY(windowRect)) {
|
||||
newLocation.y -= (NSMinY(windowRect) - eventLocation.y + 1);
|
||||
} else if (eventLocation.y > NSMaxY(windowRect)) {
|
||||
newLocation.y += (eventLocation.y - NSMaxY(windowRect));
|
||||
}
|
||||
|
||||
CGWarpMouseCursorPosition(newLocation);
|
||||
CGAssociateMouseAndMouseCursorPosition(YES);
|
||||
|
||||
if ((CGEventMaskBit(type) & movementEventsMask) == 0) {
|
||||
/* For click events, we just constrain the event to the window, so
|
||||
* no other app receives the click event. We can't due the same to
|
||||
* movement events, since they mean that our warp cursor above
|
||||
* behaves strangely.
|
||||
*/
|
||||
CGEventSetLocation(event, newLocation);
|
||||
}
|
||||
}
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
static void
|
||||
SemaphorePostCallback(CFRunLoopTimerRef timer, void *info)
|
||||
{
|
||||
SDL_SemPost((SDL_sem*)info);
|
||||
}
|
||||
|
||||
static int
|
||||
Cocoa_MouseTapThread(void *data)
|
||||
{
|
||||
SDL_MouseEventTapData *tapdata = (SDL_MouseEventTapData*)data;
|
||||
|
||||
/* Tap was created on main thread but we own it now. */
|
||||
CFMachPortRef eventTap = tapdata->tap;
|
||||
if (eventTap) {
|
||||
/* Try to create a runloop source we can schedule. */
|
||||
CFRunLoopSourceRef runloopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);
|
||||
if (runloopSource) {
|
||||
tapdata->runloopSource = runloopSource;
|
||||
} else {
|
||||
CFRelease(eventTap);
|
||||
SDL_SemPost(tapdata->runloopStartedSemaphore);
|
||||
/* TODO: Both here and in the return below, set some state in
|
||||
* tapdata to indicate that initialization failed, which we should
|
||||
* check in InitMouseEventTap, after we move the semaphore check
|
||||
* from Quit to Init.
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
SDL_SemPost(tapdata->runloopStartedSemaphore);
|
||||
return 1;
|
||||
}
|
||||
|
||||
tapdata->runloop = CFRunLoopGetCurrent();
|
||||
CFRunLoopAddSource(tapdata->runloop, tapdata->runloopSource, kCFRunLoopCommonModes);
|
||||
CFRunLoopTimerContext context = {.info = tapdata->runloopStartedSemaphore};
|
||||
/* We signal the runloop started semaphore *after* the run loop has started, indicating it's safe to CFRunLoopStop it. */
|
||||
CFRunLoopTimerRef timer = CFRunLoopTimerCreate(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent(), 0, 0, 0, &SemaphorePostCallback, &context);
|
||||
CFRunLoopAddTimer(tapdata->runloop, timer, kCFRunLoopCommonModes);
|
||||
CFRelease(timer);
|
||||
|
||||
/* Run the event loop to handle events in the event tap. */
|
||||
CFRunLoopRun();
|
||||
/* Make sure this is signaled so that SDL_QuitMouseEventTap knows it can safely SDL_WaitThread for us. */
|
||||
if (SDL_SemValue(tapdata->runloopStartedSemaphore) < 1) {
|
||||
SDL_SemPost(tapdata->runloopStartedSemaphore);
|
||||
}
|
||||
CFRunLoopRemoveSource(tapdata->runloop, tapdata->runloopSource, kCFRunLoopCommonModes);
|
||||
|
||||
/* Clean up. */
|
||||
CGEventTapEnable(tapdata->tap, false);
|
||||
CFRelease(tapdata->runloopSource);
|
||||
CFRelease(tapdata->tap);
|
||||
tapdata->runloopSource = NULL;
|
||||
tapdata->tap = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
Cocoa_InitMouseEventTap(SDL_MouseData* driverdata)
|
||||
{
|
||||
SDL_MouseEventTapData *tapdata;
|
||||
driverdata->tapdata = SDL_calloc(1, sizeof(SDL_MouseEventTapData));
|
||||
tapdata = (SDL_MouseEventTapData*)driverdata->tapdata;
|
||||
|
||||
tapdata->runloopStartedSemaphore = SDL_CreateSemaphore(0);
|
||||
if (tapdata->runloopStartedSemaphore) {
|
||||
tapdata->tap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap,
|
||||
kCGEventTapOptionDefault, allGrabbedEventsMask,
|
||||
&Cocoa_MouseTapCallback, tapdata);
|
||||
if (tapdata->tap) {
|
||||
/* Tap starts disabled, until app requests mouse grab */
|
||||
CGEventTapEnable(tapdata->tap, false);
|
||||
tapdata->thread = SDL_CreateThreadInternal(&Cocoa_MouseTapThread, "Event Tap Loop", 512 * 1024, tapdata);
|
||||
if (tapdata->thread) {
|
||||
/* Success - early out. Ownership transferred to thread. */
|
||||
return;
|
||||
}
|
||||
CFRelease(tapdata->tap);
|
||||
}
|
||||
SDL_DestroySemaphore(tapdata->runloopStartedSemaphore);
|
||||
}
|
||||
SDL_free(driverdata->tapdata);
|
||||
driverdata->tapdata = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
Cocoa_EnableMouseEventTap(SDL_MouseData *driverdata, SDL_bool enabled)
|
||||
{
|
||||
SDL_MouseEventTapData *tapdata = (SDL_MouseEventTapData*)driverdata->tapdata;
|
||||
if (tapdata && tapdata->tap)
|
||||
{
|
||||
CGEventTapEnable(tapdata->tap, !!enabled);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Cocoa_QuitMouseEventTap(SDL_MouseData *driverdata)
|
||||
{
|
||||
SDL_MouseEventTapData *tapdata = (SDL_MouseEventTapData*)driverdata->tapdata;
|
||||
int status;
|
||||
|
||||
if (tapdata == NULL) {
|
||||
/* event tap was already cleaned up (possibly due to CGEventTapCreate
|
||||
* returning null.)
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
/* Ensure that the runloop has been started first.
|
||||
* TODO: Move this to InitMouseEventTap, check for error conditions that can
|
||||
* happen in Cocoa_MouseTapThread, and fall back to the non-EventTap way of
|
||||
* grabbing the mouse if it fails to Init.
|
||||
*/
|
||||
status = SDL_SemWaitTimeout(tapdata->runloopStartedSemaphore, 5000);
|
||||
if (status > -1) {
|
||||
/* Then stop it, which will cause Cocoa_MouseTapThread to return. */
|
||||
CFRunLoopStop(tapdata->runloop);
|
||||
/* And then wait for Cocoa_MouseTapThread to finish cleaning up. It
|
||||
* releases some of the pointers in tapdata. */
|
||||
SDL_WaitThread(tapdata->thread, &status);
|
||||
}
|
||||
|
||||
SDL_free(driverdata->tapdata);
|
||||
driverdata->tapdata = NULL;
|
||||
}
|
||||
|
||||
#else /* SDL_MAC_NO_SANDBOX */
|
||||
|
||||
void
|
||||
Cocoa_InitMouseEventTap(SDL_MouseData *unused)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Cocoa_EnableMouseEventTap(SDL_MouseData *driverdata, SDL_bool enabled)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Cocoa_QuitMouseEventTap(SDL_MouseData *driverdata)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* !SDL_MAC_NO_SANDBOX */
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_COCOA */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -135,7 +135,7 @@
|
|||
if ([NSThread isMainThread]) {
|
||||
[super update];
|
||||
} else {
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{ [super update]; });
|
||||
dispatch_async(dispatch_get_main_queue(), ^{ [super update]; });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -109,7 +109,10 @@ Cocoa_GLES_SetupWindow(_THIS, SDL_Window * window)
|
|||
|
||||
|
||||
if (_this->egl_data == NULL) {
|
||||
/* !!! FIXME: commenting out this assertion is (I think) incorrect; figure out why driver_loaded is wrong for ANGLE instead. --ryan. */
|
||||
#if 0 /* When hint SDL_HINT_OPENGL_ES_DRIVER is set to "1" (e.g. for ANGLE support), _this->gl_config.driver_loaded can be 1, while the below lines function. */
|
||||
SDL_assert(!_this->gl_config.driver_loaded);
|
||||
#endif
|
||||
if (SDL_EGL_LoadLibrary(_this, NULL, EGL_DEFAULT_DISPLAY, 0) < 0) {
|
||||
SDL_EGL_UnloadLibrary(_this);
|
||||
return -1;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -38,6 +38,9 @@ static void Cocoa_VideoQuit(_THIS);
|
|||
static void
|
||||
Cocoa_DeleteDevice(SDL_VideoDevice * device)
|
||||
{
|
||||
if (device->wakeup_lock) {
|
||||
SDL_DestroyMutex(device->wakeup_lock);
|
||||
}
|
||||
SDL_free(device->driverdata);
|
||||
SDL_free(device);
|
||||
}
|
||||
|
|
@ -63,6 +66,7 @@ Cocoa_CreateDevice(int devindex)
|
|||
return NULL;
|
||||
}
|
||||
device->driverdata = data;
|
||||
device->wakeup_lock = SDL_CreateMutex();
|
||||
|
||||
/* Set the function pointers */
|
||||
device->VideoInit = Cocoa_VideoInit;
|
||||
|
|
@ -73,6 +77,8 @@ Cocoa_CreateDevice(int devindex)
|
|||
device->GetDisplayModes = Cocoa_GetDisplayModes;
|
||||
device->SetDisplayMode = Cocoa_SetDisplayMode;
|
||||
device->PumpEvents = Cocoa_PumpEvents;
|
||||
device->WaitEventTimeout = Cocoa_WaitEventTimeout;
|
||||
device->SendWakeupEvent = Cocoa_SendWakeupEvent;
|
||||
device->SuspendScreenSaver = Cocoa_SuspendScreenSaver;
|
||||
|
||||
device->CreateSDLWindow = Cocoa_CreateWindow;
|
||||
|
|
@ -92,14 +98,19 @@ Cocoa_CreateDevice(int devindex)
|
|||
device->RestoreWindow = Cocoa_RestoreWindow;
|
||||
device->SetWindowBordered = Cocoa_SetWindowBordered;
|
||||
device->SetWindowResizable = Cocoa_SetWindowResizable;
|
||||
device->SetWindowAlwaysOnTop = Cocoa_SetWindowAlwaysOnTop;
|
||||
device->SetWindowFullscreen = Cocoa_SetWindowFullscreen;
|
||||
device->SetWindowGammaRamp = Cocoa_SetWindowGammaRamp;
|
||||
device->GetWindowGammaRamp = Cocoa_GetWindowGammaRamp;
|
||||
device->SetWindowGrab = Cocoa_SetWindowGrab;
|
||||
device->GetWindowICCProfile = Cocoa_GetWindowICCProfile;
|
||||
device->SetWindowMouseRect = Cocoa_SetWindowMouseRect;
|
||||
device->SetWindowMouseGrab = Cocoa_SetWindowMouseGrab;
|
||||
device->SetWindowKeyboardGrab = Cocoa_SetWindowKeyboardGrab;
|
||||
device->DestroyWindow = Cocoa_DestroyWindow;
|
||||
device->GetWindowWMInfo = Cocoa_GetWindowWMInfo;
|
||||
device->SetWindowHitTest = Cocoa_SetWindowHitTest;
|
||||
device->AcceptDragAndDrop = Cocoa_AcceptDragAndDrop;
|
||||
device->FlashWindow = Cocoa_FlashWindow;
|
||||
|
||||
device->shape_driver.CreateShaper = Cocoa_CreateShaper;
|
||||
device->shape_driver.SetWindowShape = Cocoa_SetWindowShape;
|
||||
|
|
@ -260,7 +271,10 @@ Cocoa_CreateImage(SDL_Surface * surface)
|
|||
|
||||
void SDL_NSLog(const char *text)
|
||||
{
|
||||
NSLog(@"%s", text);
|
||||
@autoreleasepool {
|
||||
NSString *str = [NSString stringWithUTF8String:text];
|
||||
NSLog(@"%@", str);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_DRIVER_COCOA */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -48,6 +48,7 @@ typedef enum
|
|||
BOOL inFullscreenTransition;
|
||||
PendingWindowOperation pendingWindowOperation;
|
||||
BOOL isMoving;
|
||||
NSInteger focusClickPending;
|
||||
int pendingWindowWarpX, pendingWindowWarpY;
|
||||
BOOL isDragAreaRunning;
|
||||
}
|
||||
|
|
@ -62,8 +63,12 @@ typedef enum
|
|||
-(void) close;
|
||||
|
||||
-(BOOL) isMoving;
|
||||
-(BOOL) isMovingOrFocusClickPending;
|
||||
-(void) setFocusClickPending:(NSInteger) button;
|
||||
-(void) clearFocusClickPending:(NSInteger) button;
|
||||
-(void) setPendingMoveX:(int)x Y:(int)y;
|
||||
-(void) windowDidFinishMoving;
|
||||
-(void) onMovingOrFocusClickPendingStateCleared;
|
||||
|
||||
/* Window delegate functionality */
|
||||
-(BOOL) windowShouldClose:(id) sender;
|
||||
|
|
@ -75,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;
|
||||
|
|
@ -117,6 +123,7 @@ struct SDL_WindowData
|
|||
NSMutableArray *nscontexts;
|
||||
SDL_bool created;
|
||||
SDL_bool inWindowFullscreenTransition;
|
||||
NSInteger flash_request;
|
||||
Cocoa_WindowListener *listener;
|
||||
struct SDL_VideoData *videodata;
|
||||
#if SDL_VIDEO_OPENGL_EGL
|
||||
|
|
@ -142,14 +149,18 @@ extern void Cocoa_MinimizeWindow(_THIS, SDL_Window * window);
|
|||
extern void Cocoa_RestoreWindow(_THIS, SDL_Window * window);
|
||||
extern void Cocoa_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered);
|
||||
extern void Cocoa_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable);
|
||||
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_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
|
||||
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);
|
||||
extern int Cocoa_SetWindowHitTest(SDL_Window *window, SDL_bool enabled);
|
||||
extern void Cocoa_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept);
|
||||
extern int Cocoa_FlashWindow(_THIS, SDL_Window * window, SDL_FlashOperation operation);
|
||||
|
||||
#endif /* SDL_cocoawindow_h_ */
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -38,7 +38,6 @@
|
|||
#include "SDL_cocoavideo.h"
|
||||
#include "SDL_cocoashape.h"
|
||||
#include "SDL_cocoamouse.h"
|
||||
#include "SDL_cocoamousetap.h"
|
||||
#include "SDL_cocoaopengl.h"
|
||||
#include "SDL_cocoaopengles.h"
|
||||
|
||||
|
|
@ -56,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 */
|
||||
|
|
@ -161,6 +172,16 @@
|
|||
SDL_assert([desiredType isEqualToString:NSFilenamesPboardType]);
|
||||
NSArray *array = [pasteboard propertyListForType:@"NSFilenamesPboardType"];
|
||||
|
||||
/* Code addon to update the mouse location */
|
||||
NSPoint point = [sender draggingLocation];
|
||||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
int x = (int)point.x;
|
||||
int y = (int)(sdlwindow->h - point.y);
|
||||
if (x >= 0 && x < sdlwindow->w && y >= 0 && y < sdlwindow->h) {
|
||||
SDL_SendMouseMotion(sdlwindow, mouse->mouseID, 0, x, y);
|
||||
}
|
||||
/* Code addon to update the mouse location */
|
||||
|
||||
for (NSString *path in array) {
|
||||
NSURL *fileURL = [NSURL fileURLWithPath:path];
|
||||
NSNumber *isAlias = nil;
|
||||
|
|
@ -313,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
|
||||
|
||||
|
|
@ -331,6 +465,7 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
|
|||
pendingWindowOperation = PENDING_OPERATION_NONE;
|
||||
isMoving = NO;
|
||||
isDragAreaRunning = NO;
|
||||
pendingWindowWarpX = pendingWindowWarpY = INT_MAX;
|
||||
|
||||
center = [NSNotificationCenter defaultCenter];
|
||||
|
||||
|
|
@ -343,6 +478,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];
|
||||
|
|
@ -474,6 +610,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];
|
||||
|
|
@ -499,6 +636,26 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
|
|||
return isMoving;
|
||||
}
|
||||
|
||||
- (BOOL)isMovingOrFocusClickPending
|
||||
{
|
||||
return isMoving || (focusClickPending != 0);
|
||||
}
|
||||
|
||||
-(void) setFocusClickPending:(NSInteger) button
|
||||
{
|
||||
focusClickPending |= (1 << button);
|
||||
}
|
||||
|
||||
-(void) clearFocusClickPending:(NSInteger) button
|
||||
{
|
||||
if ((focusClickPending & (1 << button)) != 0) {
|
||||
focusClickPending &= ~(1 << button);
|
||||
if (focusClickPending == 0) {
|
||||
[self onMovingOrFocusClickPendingStateCleared];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-(void) setPendingMoveX:(int)x Y:(int)y
|
||||
{
|
||||
pendingWindowWarpX = x;
|
||||
|
|
@ -507,16 +664,39 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
|
|||
|
||||
- (void)windowDidFinishMoving
|
||||
{
|
||||
if ([self isMoving]) {
|
||||
if (isMoving) {
|
||||
isMoving = NO;
|
||||
[self onMovingOrFocusClickPendingStateCleared];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)onMovingOrFocusClickPendingStateCleared
|
||||
{
|
||||
if (![self isMovingOrFocusClickPending]) {
|
||||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
if (pendingWindowWarpX != INT_MAX && pendingWindowWarpY != INT_MAX) {
|
||||
mouse->WarpMouseGlobal(pendingWindowWarpX, pendingWindowWarpY);
|
||||
pendingWindowWarpX = pendingWindowWarpY = INT_MAX;
|
||||
}
|
||||
if (mouse->relative_mode && !mouse->relative_mode_warp && mouse->focus == _data->window) {
|
||||
/* Move the cursor to the nearest point in the window */
|
||||
{
|
||||
int x, y;
|
||||
CGPoint cgpoint;
|
||||
|
||||
SDL_GetMouseState(&x, &y);
|
||||
cgpoint.x = _data->window->x + x;
|
||||
cgpoint.y = _data->window->y + y;
|
||||
|
||||
Cocoa_HandleMouseWarp(cgpoint.x, cgpoint.y);
|
||||
|
||||
DLog("Returning cursor to (%g, %g)", cgpoint.x, cgpoint.y);
|
||||
CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cgpoint);
|
||||
}
|
||||
|
||||
mouse->SetRelativeMouseMode(SDL_TRUE);
|
||||
} else {
|
||||
Cocoa_UpdateClipCursor(_data->window);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -615,6 +795,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);
|
||||
}
|
||||
|
||||
|
|
@ -632,7 +816,7 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
|
|||
/* This needs to be done before restoring the relative mouse mode. */
|
||||
SDL_SetKeyboardFocus(window);
|
||||
|
||||
if (mouse->relative_mode && !mouse->relative_mode_warp && ![self isMoving]) {
|
||||
if (mouse->relative_mode && !mouse->relative_mode_warp && ![self isMovingOrFocusClickPending]) {
|
||||
mouse->SetRelativeMouseMode(SDL_TRUE);
|
||||
}
|
||||
|
||||
|
|
@ -700,6 +884,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;
|
||||
|
|
@ -962,16 +1151,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]) {
|
||||
|
|
@ -1008,9 +1224,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
|
||||
|
|
@ -1025,14 +1239,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);
|
||||
|
|
@ -1059,9 +1271,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
|
||||
|
|
@ -1099,34 +1309,15 @@ SetWindowStyle(SDL_Window * window, NSUInteger style)
|
|||
x = (int)point.x;
|
||||
y = (int)(window->h - point.y);
|
||||
|
||||
if (window->flags & SDL_WINDOW_INPUT_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;
|
||||
}
|
||||
|
||||
#if !SDL_MAC_NO_SANDBOX
|
||||
CGPoint cgpoint;
|
||||
|
||||
/* When SDL_MAC_NO_SANDBOX is set, this is handled by
|
||||
* SDL_cocoamousetap.m.
|
||||
*/
|
||||
|
||||
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);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1157,7 +1348,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];
|
||||
|
|
@ -1208,7 +1410,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];
|
||||
|
|
@ -1403,7 +1616,10 @@ SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, NSView *nsview,
|
|||
{
|
||||
unsigned long style = [nswindow styleMask];
|
||||
|
||||
if (style == NSWindowStyleMaskBorderless) {
|
||||
/* NSWindowStyleMaskBorderless is zero, and it's possible to be
|
||||
Resizeable _and_ borderless, so we can't do a simple bitwise AND
|
||||
of NSWindowStyleMaskBorderless here. */
|
||||
if ((style & ~NSWindowStyleMaskResizable) == NSWindowStyleMaskBorderless) {
|
||||
window->flags |= SDL_WINDOW_BORDERLESS;
|
||||
} else {
|
||||
window->flags &= ~SDL_WINDOW_BORDERLESS;
|
||||
|
|
@ -1804,11 +2020,33 @@ Cocoa_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable)
|
|||
*/
|
||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
Cocoa_WindowListener *listener = data->listener;
|
||||
NSWindow *nswindow = data->nswindow;
|
||||
SDL_VideoData *videodata = ((SDL_WindowData *) window->driverdata)->videodata;
|
||||
if (![listener isInFullscreenSpace]) {
|
||||
SetWindowStyle(window, GetWindowStyle(window));
|
||||
}
|
||||
if (videodata->allow_spaces) {
|
||||
if (resizable) {
|
||||
/* resizable windows are Spaces-friendly: they get the "go fullscreen" toggle button on their titlebar. */
|
||||
[nswindow setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
|
||||
} else {
|
||||
[nswindow setCollectionBehavior:NSWindowCollectionBehaviorManaged];
|
||||
}
|
||||
}
|
||||
}}
|
||||
|
||||
void
|
||||
Cocoa_SetWindowAlwaysOnTop(_THIS, SDL_Window * window, SDL_bool on_top)
|
||||
{ @autoreleasepool
|
||||
{
|
||||
NSWindow *nswindow = ((SDL_WindowData *) window->driverdata)->nswindow;
|
||||
if (on_top) {
|
||||
[nswindow setLevel:NSFloatingWindowLevel];
|
||||
} else {
|
||||
[nswindow setLevel:kCGNormalWindowLevel];
|
||||
}
|
||||
}}
|
||||
|
||||
void
|
||||
Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
|
||||
{ @autoreleasepool
|
||||
|
|
@ -1923,6 +2161,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)
|
||||
{
|
||||
|
|
@ -1948,30 +2222,19 @@ Cocoa_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp)
|
|||
}
|
||||
|
||||
void
|
||||
Cocoa_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
|
||||
Cocoa_SetWindowMouseRect(_THIS, SDL_Window * window)
|
||||
{
|
||||
Cocoa_UpdateClipCursor(window);
|
||||
}
|
||||
|
||||
void
|
||||
Cocoa_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
|
||||
{
|
||||
SDL_Mouse *mouse = SDL_GetMouse();
|
||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
|
||||
/* Enable or disable the event tap as necessary */
|
||||
Cocoa_EnableMouseEventTap(mouse->driverdata, grabbed);
|
||||
Cocoa_UpdateClipCursor(window);
|
||||
|
||||
/* Move the cursor to the nearest point in the window */
|
||||
if (grabbed && data && ![data->listener isMoving]) {
|
||||
int x, y;
|
||||
CGPoint cgpoint;
|
||||
|
||||
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! */
|
||||
|
|
@ -2103,6 +2366,34 @@ Cocoa_AcceptDragAndDrop(SDL_Window * window, SDL_bool accept)
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
Cocoa_FlashWindow(_THIS, SDL_Window *window, SDL_FlashOperation operation)
|
||||
{ @autoreleasepool
|
||||
{
|
||||
/* Note that this is app-wide and not window-specific! */
|
||||
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
|
||||
|
||||
if (data->flash_request) {
|
||||
[NSApp cancelUserAttentionRequest:data->flash_request];
|
||||
data->flash_request = 0;
|
||||
}
|
||||
|
||||
switch (operation) {
|
||||
case SDL_FLASH_CANCEL:
|
||||
/* Canceled above */
|
||||
break;
|
||||
case SDL_FLASH_BRIEFLY:
|
||||
data->flash_request = [NSApp requestUserAttention:NSInformationalRequest];
|
||||
break;
|
||||
case SDL_FLASH_UNTIL_FOCUSED:
|
||||
data->flash_request = [NSApp requestUserAttention:NSCriticalRequest];
|
||||
break;
|
||||
default:
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
return 0;
|
||||
}}
|
||||
|
||||
int
|
||||
Cocoa_SetWindowOpacity(_THIS, SDL_Window * window, float opacity)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -287,9 +287,8 @@ WMPos(DFB_WindowData * p, int x, int y)
|
|||
int
|
||||
DirectFB_WM_ProcessEvent(_THIS, SDL_Window * window, DFBWindowEvent * evt)
|
||||
{
|
||||
SDL_DFB_DEVICEDATA(_this);
|
||||
SDL_DFB_WINDOWDATA(window);
|
||||
DFB_WindowData *gwindata = ((devdata->grabbed_window) ? (DFB_WindowData *) ((devdata->grabbed_window)->driverdata) : NULL);
|
||||
SDL_Window *grabbed_window = SDL_GetGrabbedWindow();
|
||||
IDirectFBWindow *dfbwin = windata->dfbwin;
|
||||
DFBWindowOptions wopts;
|
||||
|
||||
|
|
@ -324,12 +323,12 @@ 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 (gwindata != NULL)
|
||||
SDL_DFB_CHECK(gwindata->dfbwin->UngrabPointer(gwindata->dfbwin));
|
||||
SDL_DFB_CHECK(dfbwin->GrabPointer(dfbwin));
|
||||
if (grabbed_window != NULL)
|
||||
DirectFB_SetWindowMouseGrab(_this, grabbed_window, SDL_FALSE);
|
||||
DirectFB_SetWindowMouseGrab(_this, window, SDL_TRUE);
|
||||
windata->wm_lastx = evt->cx;
|
||||
windata->wm_lasty = evt->cy;
|
||||
}
|
||||
|
|
@ -359,9 +358,9 @@ DirectFB_WM_ProcessEvent(_THIS, SDL_Window * window, DFBWindowEvent * evt)
|
|||
SDL_DFB_CHECK(dfbwin->Resize(dfbwin, cw + dx, ch + dy));
|
||||
}
|
||||
}
|
||||
SDL_DFB_CHECK(dfbwin->UngrabPointer(dfbwin));
|
||||
if (gwindata != NULL)
|
||||
SDL_DFB_CHECK(gwindata->dfbwin->GrabPointer(gwindata->dfbwin));
|
||||
DirectFB_SetWindowMouseGrab(_this, window, SDL_FALSE);
|
||||
if (grabbed_window != NULL)
|
||||
DirectFB_SetWindowMouseGrab(_this, grabbed_window, SDL_TRUE);
|
||||
windata->wm_grab = WM_POS_NONE;
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -212,7 +212,7 @@ ProcessWindowEvent(_THIS, SDL_Window *sdlwin, DFBWindowEvent * evt)
|
|||
case DWET_MOTION:
|
||||
if (ClientXY(windata, &evt->x, &evt->y)) {
|
||||
if (!devdata->use_linux_input) {
|
||||
if (!(sdlwin->flags & SDL_WINDOW_INPUT_GRABBED))
|
||||
if (!(sdlwin->flags & SDL_WINDOW_MOUSE_GRABBED))
|
||||
SDL_SendMouseMotion_ex(sdlwin, devdata->mouse_id[0], 0,
|
||||
evt->x, evt->y, 0);
|
||||
} else {
|
||||
|
|
@ -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);
|
||||
|
|
@ -312,15 +312,16 @@ ProcessInputEvent(_THIS, DFBInputEvent * ievt)
|
|||
int kbd_idx;
|
||||
Uint32 unicode;
|
||||
char text[SDL_TEXTINPUTEVENT_TEXT_SIZE];
|
||||
SDL_Window* grabbed_window = SDL_GetGrabbedWindow();
|
||||
|
||||
if (!devdata->use_linux_input) {
|
||||
if (ievt->type == DIET_AXISMOTION) {
|
||||
if ((devdata->grabbed_window != NULL) && (ievt->flags & DIEF_AXISREL)) {
|
||||
if ((grabbed_window != NULL) && (ievt->flags & DIEF_AXISREL)) {
|
||||
if (ievt->axis == DIAI_X)
|
||||
SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1,
|
||||
SDL_SendMouseMotion_ex(grabbed_window, ievt->device_id, 1,
|
||||
ievt->axisrel, 0, 0);
|
||||
else if (ievt->axis == DIAI_Y)
|
||||
SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1, 0,
|
||||
SDL_SendMouseMotion_ex(grabbed_window, ievt->device_id, 1, 0,
|
||||
ievt->axisrel, 0);
|
||||
}
|
||||
}
|
||||
|
|
@ -339,7 +340,7 @@ ProcessInputEvent(_THIS, DFBInputEvent * ievt)
|
|||
SDL_Mouse *mouse = SDL_GetMouse(ievt->device_id);
|
||||
SDL_Window *window = SDL_GetWindowFromID(mouse->focus);
|
||||
#else
|
||||
SDL_Window *window = devdata->grabbed_window;
|
||||
SDL_Window *window = grabbed_window;
|
||||
#endif
|
||||
if (window) {
|
||||
DFB_WindowData *windata =
|
||||
|
|
@ -359,10 +360,10 @@ ProcessInputEvent(_THIS, DFBInputEvent * ievt)
|
|||
}
|
||||
} else if (ievt->flags & DIEF_AXISREL) {
|
||||
if (ievt->axis == DIAI_X)
|
||||
SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1,
|
||||
SDL_SendMouseMotion_ex(grabbed_window, ievt->device_id, 1,
|
||||
ievt->axisrel, 0, 0);
|
||||
else if (ievt->axis == DIAI_Y)
|
||||
SDL_SendMouseMotion_ex(devdata->grabbed_window, ievt->device_id, 1, 0,
|
||||
SDL_SendMouseMotion_ex(grabbed_window, ievt->device_id, 1, 0,
|
||||
ievt->axisrel, 0);
|
||||
}
|
||||
break;
|
||||
|
|
@ -386,19 +387,19 @@ ProcessInputEvent(_THIS, DFBInputEvent * ievt)
|
|||
break;
|
||||
case DIET_BUTTONPRESS:
|
||||
if (ievt->buttons & DIBM_LEFT)
|
||||
SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_PRESSED, 1);
|
||||
SDL_SendMouseButton_ex(grabbed_window, ievt->device_id, SDL_PRESSED, 1);
|
||||
if (ievt->buttons & DIBM_MIDDLE)
|
||||
SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_PRESSED, 2);
|
||||
SDL_SendMouseButton_ex(grabbed_window, ievt->device_id, SDL_PRESSED, 2);
|
||||
if (ievt->buttons & DIBM_RIGHT)
|
||||
SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_PRESSED, 3);
|
||||
SDL_SendMouseButton_ex(grabbed_window, ievt->device_id, SDL_PRESSED, 3);
|
||||
break;
|
||||
case DIET_BUTTONRELEASE:
|
||||
if (!(ievt->buttons & DIBM_LEFT))
|
||||
SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_RELEASED, 1);
|
||||
SDL_SendMouseButton_ex(grabbed_window, ievt->device_id, SDL_RELEASED, 1);
|
||||
if (!(ievt->buttons & DIBM_MIDDLE))
|
||||
SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_RELEASED, 2);
|
||||
SDL_SendMouseButton_ex(grabbed_window, ievt->device_id, SDL_RELEASED, 2);
|
||||
if (!(ievt->buttons & DIBM_RIGHT))
|
||||
SDL_SendMouseButton_ex(devdata->grabbed_window, ievt->device_id, SDL_RELEASED, 3);
|
||||
SDL_SendMouseButton_ex(grabbed_window, ievt->device_id, SDL_RELEASED, 3);
|
||||
break;
|
||||
default:
|
||||
break; /* please gcc */
|
||||
|
|
@ -682,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);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -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 SDL_Color *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;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -113,7 +113,8 @@ DirectFB_CreateDevice(int devindex)
|
|||
device->MaximizeWindow = DirectFB_MaximizeWindow;
|
||||
device->MinimizeWindow = DirectFB_MinimizeWindow;
|
||||
device->RestoreWindow = DirectFB_RestoreWindow;
|
||||
device->SetWindowGrab = DirectFB_SetWindowGrab;
|
||||
device->SetWindowMouseGrab = DirectFB_SetWindowMouseGrab;
|
||||
device->SetWindowKeyboardGrab = DirectFB_SetWindowKeyboardGrab;
|
||||
device->DestroyWindow = DirectFB_DestroyWindow;
|
||||
device->GetWindowWMInfo = DirectFB_GetWindowWMInfo;
|
||||
|
||||
|
|
@ -200,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;
|
||||
}
|
||||
|
|
@ -260,7 +261,6 @@ DirectFB_VideoInit(_THIS)
|
|||
|
||||
devdata->dfb = dfb;
|
||||
devdata->firstwin = NULL;
|
||||
devdata->grabbed_window = NULL;
|
||||
|
||||
_this->driverdata = devdata;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
@ -153,10 +153,6 @@ struct _DFB_DeviceData
|
|||
int use_linux_input;
|
||||
int has_own_wm;
|
||||
|
||||
|
||||
/* window grab */
|
||||
SDL_Window *grabbed_window;
|
||||
|
||||
/* global events */
|
||||
IDirectFBEventBuffer *events;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue